Exemplo n.º 1
0
        public void Reset()
        {
            currState    = SdState.IDLE;
            argCnt       = 0;
            cmd          = SdCommand.INVALID;
            dataBlockLen = 512;
            dataCnt      = 0;

            csdCnt = 0;
            cidCnt = 0;
            ocrCnt = 0;
            r7_Cnt = 0;

            appCmd = false;
            wrPos  = UInt32.MaxValue;
        }
Exemplo n.º 2
0
        private SdState GetRespondType()
        {
            if (!appCmd)
            {
                switch (cmd)
                {
                case SdCommand.APP_CMD:
                    appCmd = true;
                    return(SdState.R1);

                case SdCommand.GO_IDLE_STATE:
                case SdCommand.SEND_OP_COND:
                case SdCommand.SET_BLOCKLEN:
                case SdCommand.READ_SINGLE_BLOCK:
                case SdCommand.READ_MULTIPLE_BLOCK:
                case SdCommand.CRC_ON_OFF:
                case SdCommand.STOP_TRANSMISSION:
                case SdCommand.SEND_CSD:
                case SdCommand.SEND_CID:
                    return(SdState.R1);

                case SdCommand.READ_OCR:
                    return(SdState.R3);

                case SdCommand.SEND_IF_COND:
                    return(SdState.R7);

                case SdCommand.WRITE_BLOCK:
                    return(SdState.RD_DATA_SIG);

                case SdCommand.WRITE_MULTIPLE_BLOCK:
                    return(SdState.RD_DATA_SIG_MUL);
                }
            }
            else
            {
                appCmd = false;
                switch (cmd)
                {
                case SdCommand.SD_SEND_OP_COND:
                    return(SdState.R1);
                }
            }

            cmd = SdCommand.INVALID;
            return(SdState.R1);
        }
Exemplo n.º 3
0
        public byte Rd()
        {
            if (fstream == null)
            {
                return(0xFF);
            }

            switch (cmd)
            {
            case SdCommand.GO_IDLE_STATE:
                if (currState == SdState.R1)
                {
                    //            Cmd = CMD.INVALID;
                    currState = SdState.IDLE;
                    return(1);
                }
                break;

            case SdCommand.SEND_OP_COND:
                if (currState == SdState.R1)
                {
                    //            Cmd = CMD.INVALID;
                    currState = SdState.IDLE;
                    return(0);
                }
                break;

            case SdCommand.SET_BLOCKLEN:
                if (currState == SdState.R1)
                {
                    //            Cmd = CMD.INVALID;
                    currState = SdState.IDLE;
                    return(0);
                }
                break;

            case SdCommand.SEND_IF_COND:
                if (currState == SdState.R7)
                {
                    switch (r7_Cnt++)
                    {
                    case 0: return(0x01);        // R1

                    case 1: return(0x00);

                    case 2: return(0x00);

                    case 3: return(0x01);

                    default:
                        currState = SdState.IDLE;
                        r7_Cnt    = 0;
                        return((byte)(arg & 0xFF));        // echo-back
                    }
                }
                break;

            case SdCommand.READ_OCR:
                if (currState == SdState.R3)
                {
                    switch (ocrCnt++)
                    {
                    case 0: return(0x00);        // R1

                    case 1: return(0x80);

                    case 2: return(0xFF);

                    case 3: return(0x80);

                    default:
                        currState = SdState.IDLE;
                        ocrCnt    = 0;
                        return(0x00);
                    }
                }
                break;

            case SdCommand.APP_CMD:
                if (currState == SdState.R1)
                {
                    currState = SdState.IDLE;
                    return(0);
                }
                break;

            case SdCommand.SD_SEND_OP_COND:
                if (currState == SdState.R1)
                {
                    currState = SdState.IDLE;
                    return(0);
                }
                break;

            case SdCommand.CRC_ON_OFF:
                if (currState == SdState.R1)
                {
                    currState = SdState.IDLE;
                    return(0);
                }
                break;

            case SdCommand.STOP_TRANSMISSION:
                switch (currState)
                {
                case SdState.R1:
                    dataCnt   = 0;
                    currState = SdState.R1b;
                    return(0);

                case SdState.R1b:
                    currState = SdState.IDLE;
                    return(0xFF);
                }
                break;

            case SdCommand.READ_SINGLE_BLOCK:
                switch (currState)
                {
                case SdState.R1:
                    currState = SdState.DELAY_S;
                    return(0);

                case SdState.DELAY_S:
                    currState = SdState.STARTBLOCK;
                    return(0xFF);

                case SdState.STARTBLOCK:
                    currState = SdState.WR_DATA;
                    dataCnt   = 0;
                    return(0xFE);

                case SdState.WR_DATA:
                {
                    byte Val = buff[dataCnt++];
                    if (dataCnt == dataBlockLen)
                    {
                        dataCnt   = 0;
                        currState = SdState.WR_CRC16_1;
                    }
                    return(Val);
                }

                case SdState.WR_CRC16_1:
                    currState = SdState.WR_CRC16_2;
                    return(0xFF);        // crc

                case SdState.WR_CRC16_2:
                    currState = SdState.IDLE;
                    cmd       = SdCommand.INVALID;
                    return(0xFF);        // crc
                }
                //        Cmd = CMD.INVALID;
                break;

            case SdCommand.READ_MULTIPLE_BLOCK:
                switch (currState)
                {
                case SdState.R1:
                    currState = SdState.DELAY_S;
                    return(0);

                case SdState.DELAY_S:
                    currState = SdState.STARTBLOCK;
                    return(0xFF);

                case SdState.STARTBLOCK:
                    currState = SdState.IDLE;
                    dataCnt   = 0;
                    return(0xFE);

                case SdState.IDLE:
                {
                    if (dataCnt < dataBlockLen)
                    {
                        byte Val = buff[dataCnt++];
                        if (dataCnt == dataBlockLen)
                        {
                            fstream.Read(buff, 0, dataBlockLen);
                        }
                        return(Val);
                    }
                    else if (dataCnt > (dataBlockLen + 8))
                    {
                        dataCnt = 0;
                        return(0xFE);            // next startblock
                    }
                    else
                    {
                        dataCnt++;
                        return(0xFF);            // crc & pause
                    }
                }
                }
                break;

            case SdCommand.SEND_CSD:
                switch (currState)
                {
                case SdState.R1:
                    currState = SdState.DELAY_S;
                    return(0);

                case SdState.DELAY_S:
                    currState = SdState.STARTBLOCK;
                    return(0xFF);

                case SdState.STARTBLOCK:
                    currState = SdState.WR_DATA;
                    return(0xFE);

                case SdState.WR_DATA:
                {
                    byte Val = csd[csdCnt++];
                    if (csdCnt == 16)
                    {
                        csdCnt    = 0;
                        currState = SdState.IDLE;
                        cmd       = SdCommand.INVALID;
                    }
                    return(Val);
                }
                }
                //        Cmd = CMD.INVALID;
                break;

            case SdCommand.SEND_CID:
                switch (currState)
                {
                case SdState.R1:
                    currState = SdState.DELAY_S;
                    return(0);

                case SdState.DELAY_S:
                    currState = SdState.STARTBLOCK;
                    return(0xFF);

                case SdState.STARTBLOCK:
                    currState = SdState.WR_DATA;
                    return(0xFE);

                case SdState.WR_DATA:
                {
                    byte Val = cid[cidCnt++];
                    if (cidCnt == 16)
                    {
                        cidCnt    = 0;
                        currState = SdState.IDLE;
                        cmd       = SdCommand.INVALID;
                    }
                    return(Val);
                }
                }
                //        Cmd = CMD.INVALID;
                break;

            case SdCommand.WRITE_BLOCK:
                //        printf(__FUNCTION__" cmd=0x%X, St=0x%X\n", Cmd, CurrState);
                switch (currState)
                {
                case SdState.R1:
                    currState = SdState.RD_DATA_SIG;
                    return(0xFE);

                case SdState.WR_DATA_RESP:
                {
                    currState = SdState.IDLE;
                    byte Resp = (((byte)SdStatus.DATA_ACCEPTED) << 1) | 1;
                    return(Resp);
                }
                }
                break;

            case SdCommand.WRITE_MULTIPLE_BLOCK:
                switch (currState)
                {
                case SdState.R1:
                    currState = SdState.RD_DATA_SIG_MUL;
                    return(0xFE);

                case SdState.WR_DATA_RESP:
                {
                    currState = SdState.RD_DATA_SIG_MUL;
                    byte Resp = (((byte)SdStatus.DATA_ACCEPTED) << 1) | 1;
                    return(Resp);
                }
                }
                break;
            }

            if (currState == SdState.R1) // CMD.INVALID
            {
                currState = SdState.IDLE;
                return(0x05);
            }

            return(0xFF);
        }
Exemplo n.º 4
0
        public void Wr(byte val)
        {
            SdState NextState = SdState.IDLE;

            if (fstream == null)
            {
                return;
            }

            switch (currState)
            {
            case SdState.IDLE:
            {
                if ((val & 0xC0) != 0x40)
                {
                    break;
                }

                cmd = (SdCommand)(val & 0x3F);
                if (!appCmd)
                {
                    switch (cmd)
                    {
                    case SdCommand.SEND_CSD:
                        csdCnt = 0;
                        break;

                    case SdCommand.SEND_CID:
                        cidCnt = 0;
                        break;

                    case SdCommand.READ_OCR:
                        ocrCnt = 0;
                        break;

                    case SdCommand.SEND_IF_COND:
                        r7_Cnt = 0;
                        break;
                    }
                }
                NextState = SdState.RD_ARG;
                argCnt    = 0;
            }
            break;

            case SdState.RD_ARG:
                NextState = SdState.RD_ARG;
                SetByte(ref arg, 3 - argCnt++, val);

                if (argCnt == 4)
                {
                    if (!appCmd)
                    {
                        switch (cmd)
                        {
                        case SdCommand.SET_BLOCKLEN:
                            if (arg <= 4096)
                            {
                                dataBlockLen = (int)arg;
                            }
                            break;

                        case SdCommand.READ_SINGLE_BLOCK:
                            fstream.Seek(arg, SeekOrigin.Begin);
                            fstream.Read(buff, 0, dataBlockLen);

                            break;

                        case SdCommand.READ_MULTIPLE_BLOCK:

                            fstream.Seek(arg, SeekOrigin.Begin);
                            fstream.Read(buff, 0, dataBlockLen);
                            break;

                        case SdCommand.WRITE_BLOCK:

                            break;

                        case SdCommand.WRITE_MULTIPLE_BLOCK:
                            wrPos = arg;

                            break;
                        }
                    }

                    NextState = SdState.RD_CRC;
                    argCnt    = 0;
                }
                break;

            case SdState.RD_CRC:

                NextState = GetRespondType();
                break;

            case SdState.RD_DATA_SIG:
                if (val == 0xFE)     // Проверка сигнатуры данных
                {
                    dataCnt   = 0;
                    NextState = SdState.RD_DATA;
                }
                else
                {
                    NextState = SdState.RD_DATA_SIG;
                }
                break;

            case SdState.RD_DATA_SIG_MUL:
                switch (val)
                {
                case 0xFC:         // Проверка сигнатуры данных

                    dataCnt   = 0;
                    NextState = SdState.RD_DATA_MUL;
                    break;

                case 0xFD:         // Окончание передачи

                    dataCnt   = 0;
                    NextState = SdState.IDLE;
                    break;

                default:
                    NextState = SdState.RD_DATA_SIG_MUL;
                    break;
                }
                break;

            case SdState.RD_DATA:     // Прием данных в буфер
            {
                buff[dataCnt++] = val;
                NextState       = SdState.RD_DATA;
                if (dataCnt == dataBlockLen)         // Запись данных в SD карту
                {
                    dataCnt = 0;
                    fstream.Seek(arg, SeekOrigin.Begin);
                    fstream.Write(buff, 0, dataBlockLen);


                    NextState = SdState.WR_DATA_RESP;
                }
            }
            break;

            case SdState.RD_DATA_MUL:     // Прием данных в буфер
            {
                buff[dataCnt++] = val;
                NextState       = SdState.RD_DATA_MUL;
                if (dataCnt == dataBlockLen)         // Запись данных в SD карту
                {
                    dataCnt = 0;

                    fstream.Seek(wrPos, SeekOrigin.Begin);
                    fstream.Write(buff, 0, dataBlockLen);


                    wrPos    += (uint)dataBlockLen;
                    NextState = SdState.RD_DATA_SIG_MUL;
                }
            }
            break;

            case SdState.RD_CRC16_1:     // Чтение старшего байта CRC16
                NextState = SdState.RD_CRC16_2;
                break;

            case SdState.RD_CRC16_2:     // Чтение младшего байта CRC16
                NextState = SdState.WR_DATA_RESP;
                break;

            default:
                return;
            }
            currState = NextState;
        }