private BitStream HandleStandardCommand(SdCardCommand command, uint arg)
        {
            this.Log(LogLevel.Noisy, "Handling as a standard command: {0}", command);
            switch (command)
            {
            case SdCardCommand.GoIdleState_CMD0:
                GoToIdle();
                return(spiMode
                        ? GenerateR1Response()
                        : BitStream.Empty); // no response in SD mode

            case SdCardCommand.SendCardIdentification_CMD2:
            {
                if (spiMode)
                {
                    // this command is not supported in the SPI mode
                    break;
                }

                state = SDCardState.Identification;

                return(CardIdentification);
            }

            case SdCardCommand.SendRelativeAddress_CMD3:
            {
                if (spiMode)
                {
                    // this command is not supported in the SPI mode
                    break;
                }

                state = SDCardState.Standby;

                var status = CardStatus.AsUInt32();
                return(BitHelper.BitConcatenator.New()
                       .StackAbove(status, 13, 0)
                       .StackAbove(status, 1, 19)
                       .StackAbove(status, 2, 22)
                       .StackAbove(CardAddress, 16, 0)
                       .Bits);
            }

            case SdCardCommand.SelectDeselectCard_CMD7:
            {
                if (spiMode)
                {
                    // this command is not supported in the SPI mode
                    break;
                }

                // this is a toggle command:
                // Select is used to start a transfer;
                // Deselct is used to abort the active transfer
                switch (state)
                {
                case SDCardState.Standby:
                    state = SDCardState.Transfer;
                    break;

                case SDCardState.Transfer:
                case SDCardState.Programming:
                    state = SDCardState.Standby;
                    break;
                }

                return(CardStatus);
            }

            case SdCardCommand.SendInterfaceConditionCommand_CMD8:
                return(spiMode
                        ? GenerateR7Response()
                        : CardStatus);

            case SdCardCommand.SendCardSpecificData_CMD9:
                return(spiMode
                        ? GenerateR1Response()
                        : CardSpecificData);

            case SdCardCommand.StopTransmission_CMD12:
                readContext.Reset();
                writeContext.Reset();

                switch (state)
                {
                case SDCardState.SendingData:
                    state = SDCardState.Transfer;
                    break;

                case SDCardState.ReceivingData:
                    state = SDCardState.Programming;
                    break;
                }

                return(spiMode
                        ? GenerateR1Response()
                        : CardStatus);

            case SdCardCommand.SendStatus_CMD13:
                return(spiMode
                        ? GenerateR2Response()
                        : CardStatus);

            case SdCardCommand.SetBlockLength_CMD16:
                blockLengthInBytes = arg;
                return(spiMode
                        ? GenerateR1Response()
                        : CardStatus);

            case SdCardCommand.ReadSingleBlock_CMD17:
                readContext.BytesLeft = blockLengthInBytes;
                readContext.Offset    = highCapacityMode
                        ? arg * blockLengthInBytes
                        : arg;

                state = SDCardState.SendingData;

                return(spiMode
                        ? GenerateR1Response()
                       .Append(BlockBeginIndicator)
                       .Append(ReadData(blockLengthInBytes))      // the actual data
                        : CardStatus);

            case SdCardCommand.ReadMultipleBlocks_CMD18:
                if (spiMode)
                {
                    this.Log(LogLevel.Warning, "Reading Multiple Blocks is currently not supported in the SPI mode by this model");
                    // TODO: implement it
                    break;
                }

                state = SDCardState.SendingData;

                readContext.Offset = highCapacityMode
                        ? arg * blockLengthInBytes
                        : arg;

                return(CardStatus);

            case SdCardCommand.WriteSingleBlock_CMD24:
                if (spiMode)
                {
                    this.Log(LogLevel.Warning, "Writing is currently not supported in the SPI mode by this model");
                    // TODO: implement it
                    break;
                }

                state = SDCardState.ReceivingData;

                writeContext.BytesLeft = blockLengthInBytes;
                writeContext.Offset    = highCapacityMode
                        ? arg * blockLengthInBytes
                        : arg;

                return(CardStatus);

            case SdCardCommand.AppCommand_CMD55:
                treatNextCommandAsAppCommand = true;
                return(spiMode
                        ? GenerateR1Response()
                        : CardStatus);

            case SdCardCommand.ReadOperationConditionRegister_CMD58:
                return(spiMode
                        ? GenerateR3Response()
                        : BitStream.Empty);
            }

            this.Log(LogLevel.Warning, "Unsupported command: {0}. Ignoring it", command);
            return(spiMode
                ? GenerateR1Response(illegalCommand: true)
                : BitStream.Empty);
        }
Beispiel #2
0
        private BitStream HandleStandardCommand(SdCardCommand command, uint arg)
        {
            this.Log(LogLevel.Debug, "Handling as a standard command: {0}", command);
            switch (command)
            {
            case SdCardCommand.GoIdleState_CMD0:
                Reset();
                return(BitStream.Empty);

            case SdCardCommand.SendCardIdentification_CMD2:
                return(CardIdentification);

            case SdCardCommand.SendRelativeAddress_CMD3:
            {
                var status = CardStatus.AsUInt32();
                return(BitHelper.BitConcatenator.New()
                       .StackAbove(status, 13, 0)
                       .StackAbove(status, 1, 19)
                       .StackAbove(status, 2, 22)
                       .StackAbove(CardAddress, 16, 0)
                       .Bits);
            }

            case SdCardCommand.SelectDeselectCard_CMD7:
                return(CardStatus);

            case SdCardCommand.SendCardSpecificData_CMD9:
                return(CardSpecificData);

            case SdCardCommand.StopTransmission_CMD12:
                readContext.Reset();
                writeContext.Reset();
                return(CardStatus);

            case SdCardCommand.SendStatus_CMD13:
                return(CardStatus);

            case SdCardCommand.SetBlockLength_CMD16:
                blockLengthInBytes = arg;
                return(CardStatus);

            case SdCardCommand.ReadSingleBlock_CMD17:
                readContext.Offset    = arg;
                readContext.BytesLeft = blockLengthInBytes;
                return(CardStatus);

            case SdCardCommand.ReadMultipleBlocks_CMD18:
                readContext.Offset = arg;
                return(CardStatus);

            case SdCardCommand.WriteSingleBlock_CMD24:
                writeContext.Offset    = arg;
                writeContext.BytesLeft = blockLengthInBytes;
                return(CardStatus);

            case SdCardCommand.AppCommand_CMD55:
                treatNextCommandAsAppCommand = true;
                return(CardStatus);

            default:
                this.Log(LogLevel.Warning, "Unsupported command: {0}. Ignoring it", command);
                return(BitStream.Empty);
            }
        }