Subversion Repositories pentevo

Rev

Rev 1134 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed | ?url?

  1. #include "std.h"
  2.  
  3. #include <io.h>
  4.  
  5. #include "emul.h"
  6. #include "vars.h"
  7. #include "sdcard.h"
  8.  
  9. #include "util.h"
  10.  
  11. //-----------------------------------------------------------------------------
  12.  
  13. void TSdCard::Reset()
  14. {
  15. //    printf(__FUNCTION__"\n");
  16.  
  17.     CurrState = ST_IDLE;
  18.     ArgCnt = 0;
  19.     Cmd = CMD_INVALID;
  20.     DataBlockLen = 512;
  21.     DataCnt = 0;
  22.  
  23.     CsdCnt = 0;
  24.     //memset(Csd, 0, sizeof(Csd));
  25.     Csd[0] = (1 << 6); // CSD structure (SDHC)
  26.     Csd[1] = 0xE;  // TACC
  27.     Csd[2] = 0x00; // NSAC
  28.     Csd[3] = 0x32; // TRAN_SPEED
  29.     Csd[4] = 0x5B; // CCC x1x11011
  30.     Csd[5] = 0x59; // CCC 0101 | READ_BL_LEN 9
  31.     Csd[6] = 0x00; // READ_BL_PARTIAL | WRITE_BLK_MISALIGN | READ_BLK_MISALIGN | DSR_IMP
  32.  
  33.     UpdateCsdImageSize();
  34.  
  35.     Csd[10] = (1 << 6) | (0x3F << 1); // ERASE_BLK_EN | SECTOR_SIZE
  36.     Csd[11] = (1 << 7); // SECTOR_SIZE | WP_GRP_SIZE
  37.     Csd[12] = (2 << 2) | 2; // R2W_FACTOR | WRITE_BL_LEN 9
  38.     Csd[13] = (1 << 6); // WRITE_BL_LEN 9 | WRITE_BL_PARTIAL
  39.     Csd[14] = 0x00; // FILE_FORMAT_GRP | COPY | PERM_WRITE_PROTECT | TMP_WRITE_PROTECT | FILE_FORMAT
  40.     Csd[15] = 1; // CRC | 1
  41.  
  42.     CidCnt = 0;
  43.     memset(Cid, 0, sizeof(Cid));
  44.  
  45.     // OEM/Application ID (OID)
  46.     Cid[1] = 'U';
  47.     Cid[2] = 'S';
  48.  
  49.     // Product Name (PNM)
  50.     Cid[3] = 'U';
  51.     Cid[4] = 'S';
  52.     Cid[5] = '0' + (VER_HL / 10) % 10;
  53.     Cid[6] = '0' + VER_HL % 10;
  54.     Cid[7] = '0' + VER_A % 10;
  55.  
  56.     Cid[8] = 0x10; // Product Revision (PRV) (BCD)
  57.     Cid[14] = 0x04; // Manufacture Date Code (MDT)
  58.     Cid[15] = 1; // CRC7 | 1
  59.  
  60.     OcrCnt = 0;
  61.  
  62.     R7_Cnt = 0;
  63.  
  64.     AppCmd = false;
  65. }
  66.  
  67. void TSdCard::UpdateCsdImageSize()
  68. {
  69.     Csd[7] = (ImageSize >> 16) & 0x3F; // C_SIZE
  70.     Csd[8] = (ImageSize >> 8) & 0xFF; // C_SIZE
  71.     Csd[9] = ImageSize & 0xFF; // C_SIZE
  72. }
  73. //-----------------------------------------------------------------------------
  74.  
  75. void TSdCard::Wr(u8 Val)
  76. {
  77.     static u32 WrPos = -1U;
  78.     TState NextState = ST_IDLE;
  79. //    printf(__FUNCTION__" Val = %X\n", Val);
  80.  
  81.     if (!Image)
  82.         return;
  83.  
  84.     switch(CurrState)
  85.     {
  86.         case ST_IDLE:
  87.         //case ST_WR_DATA_SIG:
  88.         {
  89.             if ((Val & 0xC0) != 0x40) // start=0, transm=1
  90.                break;
  91.  
  92.             Cmd = TCmd(Val & 0x3F);
  93.             if (!AppCmd)
  94.             {
  95.                 switch(Cmd) // Check commands
  96.                 {
  97.  
  98.                 case CMD_SEND_CSD:
  99.                     CsdCnt = 0;
  100.                 break;
  101.  
  102.                 case CMD_SEND_CID:
  103.                     CidCnt = 0;
  104.                 break;
  105.  
  106.                 case CMD_READ_OCR:
  107.                     OcrCnt = 0;
  108.                 break;
  109.  
  110.                 case CMD_SEND_IF_COND:
  111.                     R7_Cnt = 0;
  112.                 //break;
  113.  
  114.                 //case CMD_APP_CMD:
  115.                 //    AppCmd = true;
  116.                 }
  117.             }
  118.             NextState = ST_RD_ARG;
  119.             ArgCnt = 0;
  120.         }
  121.         break;
  122.  
  123.         case ST_RD_ARG:
  124.             NextState = ST_RD_ARG;
  125.             ArgArr[3 - ArgCnt++] = Val;
  126.  
  127. //            printf(__FUNCTION__" ST_RD_ARG val=0x%X\n", Val);
  128.             if (ArgCnt == 4)
  129.             {
  130.                 if (!AppCmd)
  131.                 {
  132.                     switch(Cmd)
  133.                     {
  134.                     case CMD_SET_BLOCKLEN:
  135.                         if (Arg<=4096)  DataBlockLen = Arg;
  136.                     break;
  137.  
  138.                     case CMD_READ_SINGLE_BLOCK:
  139. //                        printf(__FUNCTION__" CMD_READ_SINGLE_BLOCK, Addr = 0x%X\n", Arg);
  140.                         fseek(Image, long(Arg), SEEK_SET);
  141.                         fread(Buf, DataBlockLen, 1, Image);
  142.                     break;
  143.  
  144.                     case CMD_READ_MULTIPLE_BLOCK:
  145. //                        printf(__FUNCTION__" CMD_READ_MULTIPLE_BLOCK, Addr = 0x%X\n", Arg);
  146.                         fseek(Image, long(Arg), SEEK_SET);
  147.                         fread(Buf, DataBlockLen, 1, Image);
  148.                     break;
  149.  
  150.                     case CMD_WRITE_BLOCK:
  151. //                        printf(__FUNCTION__" CMD_WRITE_BLOCK, Addr = 0x%X\n", Arg);
  152.                     break;
  153.  
  154.                     case CMD_WRITE_MULTIPLE_BLOCK:
  155.                         WrPos = Arg;
  156. //                        printf(__FUNCTION__" CMD_WRITE_MULTIPLE_BLOCK, Addr = 0x%X\n", Arg);
  157.                     break;
  158.                     }
  159.                 }
  160.  
  161.                 NextState = ST_RD_CRC;
  162.                 ArgCnt = 0;
  163.             }
  164.         break;
  165.  
  166.         case ST_RD_CRC:
  167. //            printf(__FUNCTION__" ST_RD_CRC val=0x%X\n", Val);
  168.             NextState = GetRespondType();
  169.         break;
  170.  
  171.         case ST_RD_DATA_SIG:
  172.             if (Val==0xFE) // ╧ЁютхЁър ёшуэрЄєЁ√ фрээ√ї
  173.             {
  174.                 DataCnt = 0;
  175.                 NextState = ST_RD_DATA;
  176.             }
  177.             else
  178.                 NextState = ST_RD_DATA_SIG;
  179.         break;
  180.  
  181.         case ST_RD_DATA_SIG_MUL:
  182.             switch(Val)
  183.             {
  184.             case 0xFC: // ╧ЁютхЁър ёшуэрЄєЁ√ фрээ√ї
  185. //                printf(__FUNCTION__" ST_RD_DATA_SIG_MUL, Start\n");
  186.                 DataCnt = 0;
  187.                 NextState = ST_RD_DATA_MUL;
  188.             break;
  189.             case 0xFD: // ╬ъюэўрэшх яхЁхфрўш
  190. //                printf(__FUNCTION__" ST_RD_DATA_SIG_MUL, Stop\n");
  191.                 DataCnt = 0;
  192.                 NextState = ST_IDLE;
  193.             break;
  194.             default:
  195.                 NextState = ST_RD_DATA_SIG_MUL;
  196.             }
  197.         break;
  198.  
  199.         case ST_RD_DATA: // ╧Ёшхь фрээ√ї т сєЇхЁ
  200.         {
  201. //            printf(__FUNCTION__" ST_RD_DATA, Addr = 0x%X, Idx=%d\n", Arg, DataCnt);
  202.             Buf[DataCnt++] = Val;
  203.             NextState = ST_RD_DATA;
  204.             if (DataCnt == DataBlockLen) // ╟ряшё№ фрээ√ї т SD ърЁЄє
  205.             {
  206.                 DataCnt = 0;
  207. //                printf(__FUNCTION__" ST_RD_DATA, Addr = 0x%X, write to disk\n", Arg);
  208.                 fseek(Image, long(Arg), SEEK_SET);
  209.                 fwrite(Buf, DataBlockLen, 1, Image);
  210.                 NextState = ST_RD_CRC16_1;
  211.             }
  212.         }
  213.         break;
  214.  
  215.         case ST_RD_DATA_MUL: // ╧Ёшхь фрээ√ї т сєЇхЁ
  216.         {
  217. //            printf(__FUNCTION__" ST_RD_DATA_MUL, Addr = 0x%X, Idx=%d\n", WrPos, DataCnt);
  218.             Buf[DataCnt++] = Val;
  219.             NextState = ST_RD_DATA_MUL;
  220.             if (DataCnt == DataBlockLen) // ╟ряшё№ фрээ√ї т SD ърЁЄє
  221.             {
  222.                 DataCnt = 0;
  223. //                printf(__FUNCTION__" ST_RD_DATA_MUL, Addr = 0x%X, write to disk\n", WrPos);
  224.                 fseek(Image, long(WrPos), SEEK_SET);
  225.                 fwrite(Buf, DataBlockLen, 1, Image);
  226.                 WrPos += DataBlockLen;
  227.                 NextState = ST_RD_CRC16_1;
  228.             }
  229.         }
  230.         break;
  231.  
  232.         case ST_RD_CRC16_1: // ╫Єхэшх ёЄрЁ°хую срщЄр CRC16
  233.             NextState = ST_RD_CRC16_2;
  234.         break;
  235.  
  236.         case ST_RD_CRC16_2: // ╫Єхэшх ьырф°хую срщЄр CRC16
  237.             NextState = ST_WR_DATA_RESP;
  238.         break;
  239.  
  240.         default:
  241. //            printf(__FUNCTION__" St=0x%X,  val=0x%X\n", CurrState, Val);
  242.             return;
  243.     }
  244.  
  245.     CurrState = NextState;
  246. }
  247.  
  248. //-----------------------------------------------------------------------------
  249.  
  250. u8 TSdCard::Rd()
  251. {
  252. //    printf(__FUNCTION__" cmd=0x%X, St=0x%X\n", Cmd, CurrState);
  253.     if (!Image)
  254.         return 0xFF;
  255.  
  256.     switch(Cmd)
  257.     {
  258.     case CMD_GO_IDLE_STATE:
  259.         if (CurrState == ST_R1)
  260.         {
  261. //            Cmd = CMD_INVALID;
  262.             CurrState = ST_IDLE;
  263.             return 1;
  264.         }
  265.     break;
  266.     case CMD_SEND_OP_COND:
  267.         if (CurrState == ST_R1)
  268.         {
  269. //            Cmd = CMD_INVALID;
  270.             CurrState = ST_IDLE;
  271.             return 0;
  272.         }
  273.     break;
  274.     case CMD_SET_BLOCKLEN:
  275.         if (CurrState == ST_R1)
  276.         {
  277. //            Cmd = CMD_INVALID;
  278.             CurrState = ST_IDLE;
  279.             return 0;
  280.         }
  281.     break;
  282.     case CMD_SEND_IF_COND:
  283.         if (CurrState == ST_R7)
  284.         {
  285.             switch (R7_Cnt++)
  286.             {
  287.              case 0: return 0x01; // R1
  288.              case 1: return 0x00;
  289.              case 2: return 0x00;
  290.              case 3: return 0x01;
  291.              default:
  292.                 CurrState = ST_IDLE;
  293.                 R7_Cnt = 0;
  294.                 return ArgArr[0]; // echo-back
  295.             }
  296.         }
  297.     break;
  298.  
  299.     case CMD_READ_OCR:
  300.         if (CurrState == ST_R3)
  301.         {
  302.             switch (OcrCnt++)
  303.             {
  304.              case 0: return 0x00; // R1
  305.              case 1: return 0x80;
  306.              case 2: return 0xFF;
  307.              case 3: return 0x80;
  308.              default:
  309.                 CurrState = ST_IDLE;
  310.                 OcrCnt = 0;
  311.                 return 0x00;
  312.             }
  313.         }
  314.     break;
  315.  
  316.     case CMD_APP_CMD:
  317.         if (CurrState == ST_R1)
  318.         {
  319.             CurrState = ST_IDLE;
  320.             return 0;
  321.         }
  322.     break;
  323.  
  324.     case CMD_SD_SEND_OP_COND:
  325.         if (CurrState == ST_R1)
  326.         {
  327.             CurrState = ST_IDLE;
  328.             return 0;
  329.         }
  330.     break;
  331.  
  332.     case CMD_CRC_ON_OFF:
  333.         if (CurrState == ST_R1)
  334.         {
  335.             CurrState = ST_IDLE;
  336.             return 0;
  337.         }
  338.     break;
  339.  
  340.     case CMD_STOP_TRANSMISSION:
  341.         switch(CurrState)
  342.         {
  343.         case ST_R1:
  344.             DataCnt = 0;
  345.             CurrState = ST_IDLE;
  346.             return 0;
  347.         case ST_R1b:
  348.             DataCnt = 0;
  349.             CurrState = ST_R1;
  350.             return 0x7F;
  351.                 case ST_RD_ARG:
  352.                 case ST_RD_CRC:
  353.             return 0;
  354.         }
  355.     break;
  356.  
  357.     case CMD_READ_SINGLE_BLOCK:
  358.         switch(CurrState)
  359.         {
  360.           unsigned int cpu_dt;
  361.  
  362.           case ST_R1:
  363.               CurrState = ST_DELAY_S;
  364.               InitialCPUt = cpu.t;
  365.               return 0;
  366.  
  367.           case ST_DELAY_S:
  368.               cpu_dt = cpu.t - InitialCPUt;
  369.               if (cpu_dt < 0)
  370.                 cpu_dt += conf.frame;
  371.               if (cpu_dt >= conf.sd_delay)
  372.                 CurrState = ST_STARTBLOCK;
  373.               return 0xFF;
  374.  
  375.           case ST_STARTBLOCK:
  376.               CurrState = ST_WR_DATA;
  377.               DataCnt = 0;
  378.               return 0xFE;
  379.  
  380.           case ST_WR_DATA:
  381.           {
  382.               u8 Val = Buf[DataCnt++];
  383.               if (DataCnt == DataBlockLen)
  384.               {
  385.                 DataCnt = 0;
  386.                 CurrState = ST_WR_CRC16_1;
  387.               }
  388.               return Val;
  389.           }
  390.  
  391.           case ST_WR_CRC16_1:
  392.               CurrState = ST_WR_CRC16_2;
  393.               return 0xFF; // crc
  394.           case ST_WR_CRC16_2:
  395.               CurrState = ST_IDLE;
  396.               Cmd = CMD_INVALID;
  397.               return 0xFF; // crc
  398.         }
  399. //        Cmd = CMD_INVALID;
  400.     break;
  401.  
  402.     case CMD_READ_MULTIPLE_BLOCK:
  403.         switch(CurrState)
  404.         {
  405.           unsigned int cpu_dt;
  406.  
  407.           case ST_R1:
  408.               CurrState = ST_DELAY_S;
  409.               InitialCPUt = cpu.t;
  410.               return 0;
  411.  
  412.           case ST_DELAY_S:
  413.               cpu_dt = cpu.t - InitialCPUt;
  414.               if (cpu_dt < 0)
  415.                 cpu_dt += conf.frame;
  416.               if (cpu_dt >= conf.sd_delay)
  417.                 CurrState = ST_STARTBLOCK;
  418.               return 0xFF;
  419.  
  420.           case ST_STARTBLOCK:
  421.               CurrState = ST_IDLE;
  422.               DataCnt = 0;
  423.               return 0xFE;
  424.  
  425.           case ST_IDLE:
  426.           {
  427.               if (DataCnt<DataBlockLen)
  428.               {
  429.                 u8 Val = Buf[DataCnt++];
  430.                 if (DataCnt == DataBlockLen)
  431.                     fread(Buf, DataBlockLen, 1, Image);
  432.                 return Val;
  433.               }
  434.               else if (DataCnt>(DataBlockLen+8))
  435.               {
  436.                 DataCnt=0;
  437.                 return 0xFE; // next startblock
  438.               }
  439.               else
  440.               {
  441.                 DataCnt++;
  442.                 return 0xFF; // crc & pause
  443.               }
  444.           }
  445.  
  446. /*
  447.         case ST_R1:
  448.             CurrState = ST_WR_DATA_SIG;
  449.             return 0;
  450.         case ST_WR_DATA_SIG:
  451.             CurrState = ST_IDLE;
  452.             DataCnt = 0;
  453.             return 0xFE;
  454.         case ST_IDLE:
  455.         {
  456.             u8 Val = Buf[DataCnt++];
  457.             if (DataCnt == DataBlockLen)
  458.             {
  459.                 DataCnt = 0;
  460.                 fread(Buf, DataBlockLen, 1, Image);
  461.                 CurrState = ST_WR_CRC16_1;
  462.             }
  463.             return Val;
  464.         }
  465.         case ST_WR_CRC16_1:
  466.             CurrState = ST_WR_CRC16_2;
  467.             return 0xFF;
  468.         case ST_WR_CRC16_2:
  469.             CurrState = ST_WR_DATA_SIG;
  470.             return 0xFF;
  471. */
  472.         }
  473.     break;
  474.  
  475.     case CMD_SEND_CSD:
  476.         switch(CurrState)
  477.         {
  478.         case ST_R1:
  479.             CurrState = ST_DELAY_S;
  480.             return 0;
  481.         case ST_DELAY_S:
  482.             CurrState = ST_STARTBLOCK;
  483.             return 0xFF;
  484.         case ST_STARTBLOCK:
  485.             CurrState = ST_WR_DATA;
  486.             return 0xFE;
  487.         case ST_WR_DATA:
  488.         {
  489.             u8 Val = Csd[CsdCnt++];
  490.             if (CsdCnt == 16)
  491.             {
  492.                 CsdCnt = 0;
  493.                 CurrState = ST_IDLE;
  494.                 Cmd = CMD_INVALID;
  495.             }
  496.             return Val;
  497.         }
  498.         }
  499. //        Cmd = CMD_INVALID;
  500.     break;
  501.  
  502.     case CMD_SEND_CID:
  503.         switch(CurrState)
  504.         {
  505.         case ST_R1:
  506.             CurrState = ST_DELAY_S;
  507.             return 0;
  508.         case ST_DELAY_S:
  509.             CurrState = ST_STARTBLOCK;
  510.             return 0xFF;
  511.         case ST_STARTBLOCK:
  512.             CurrState = ST_WR_DATA;
  513.             return 0xFE;
  514.         case ST_WR_DATA:
  515.         {
  516.             u8 Val = Cid[CidCnt++];
  517.             if (CidCnt == 16)
  518.             {
  519.                 CidCnt = 0;
  520.                 CurrState = ST_IDLE;
  521.                 Cmd = CMD_INVALID;
  522.             }
  523.             return Val;
  524.         }
  525.         }
  526. //        Cmd = CMD_INVALID;
  527.     break;
  528.  
  529.     case CMD_WRITE_BLOCK:
  530. //        printf(__FUNCTION__" cmd=0x%X, St=0x%X\n", Cmd, CurrState);
  531.         switch(CurrState)
  532.         {
  533.         case ST_R1:
  534.             CurrState = ST_RD_DATA_SIG;
  535.             return 0x00;
  536.  
  537.         case ST_WR_DATA_RESP:
  538.         {
  539.             CurrState = ST_IDLE;
  540.             u8 Resp = ((STAT_DATA_ACCEPTED) << 1) | 1;
  541.             return Resp;
  542.         }
  543.         }
  544.     break;
  545.  
  546.     case CMD_WRITE_MULTIPLE_BLOCK:
  547.         switch(CurrState)
  548.         {
  549.         case ST_R1:
  550.             CurrState = ST_RD_DATA_SIG_MUL;
  551.             return 0x00;    // !!! check this !!!
  552.         case ST_WR_DATA_RESP:
  553.         {
  554.             CurrState = ST_RD_DATA_SIG_MUL;
  555.             u8 Resp = ((STAT_DATA_ACCEPTED) << 1) | 1;
  556.             return Resp;
  557.         }
  558.         }
  559.     break;
  560.     }
  561.  
  562.     if (CurrState == ST_R1) // CMD_INVALID
  563.     {
  564.         CurrState = ST_IDLE;
  565.         return 0x05;
  566.     }
  567.  
  568.     return 0xFF;
  569. }
  570.  
  571. //-----------------------------------------------------------------------------
  572.  
  573. TSdCard::TState TSdCard::GetRespondType()
  574. {
  575.     if (!AppCmd)
  576.     {
  577.         switch(Cmd)
  578.         {
  579.         case CMD_APP_CMD:
  580.             AppCmd = true;
  581.             return ST_R1;
  582.         case CMD_GO_IDLE_STATE:
  583.         case CMD_SEND_OP_COND:
  584.         case CMD_SET_BLOCKLEN:
  585.         case CMD_READ_SINGLE_BLOCK:
  586.         case CMD_READ_MULTIPLE_BLOCK:
  587.         case CMD_CRC_ON_OFF:
  588.         case CMD_SEND_CSD:
  589.         case CMD_SEND_CID:
  590.             return ST_R1;
  591.         case CMD_READ_OCR:
  592.             return ST_R3;
  593.         case CMD_SEND_IF_COND:
  594.             return ST_R7;
  595.         case CMD_STOP_TRANSMISSION:
  596.             return ST_R1b;
  597.  
  598.         case CMD_WRITE_BLOCK:
  599.         case CMD_WRITE_MULTIPLE_BLOCK:
  600.             return ST_R1;
  601.         }
  602.     }
  603.     else
  604.     {
  605.         AppCmd = false;
  606.         switch(Cmd)
  607.         {
  608.             case CMD_SD_SEND_OP_COND:
  609.                 return ST_R1;
  610.         }
  611.     }
  612.  
  613.     Cmd = CMD_INVALID;
  614.     return ST_R1;
  615.     //return ST_IDLE;
  616. }
  617.  
  618. //-----------------------------------------------------------------------------
  619.  
  620.  
  621. void TSdCard::Open(const char *Name)
  622. {
  623. //    printf(__FUNCTION__"\n");
  624.     assert(!Image);
  625.     Image = fopen(Name, "r+b");
  626.     if(!Image)
  627.     {
  628.         if(Name[0])
  629.         {
  630.             errmsg("can't find SD card image `%s'", Name);
  631.         }
  632.         return;
  633.     }
  634.     ImageSize = u32(_filelengthi64(fileno(Image)) / (512 * 1024)) - 1;
  635.     UpdateCsdImageSize();
  636. }
  637.  
  638. //-----------------------------------------------------------------------------
  639.  
  640. void TSdCard::Close()
  641. {
  642.     if (Image)
  643.     {
  644.         fclose(Image);
  645.         Image = 0;
  646.     }
  647. }
  648.  
  649. //-----------------------------------------------------------------------------
  650.  
  651. TSdCard SdCard;
  652.  
  653. //-----------------------------------------------------------------------------
  654.