Subversion Repositories pentevo

Rev

Rev 1161 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  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. //      if(a)
  257. //      {
  258. //              printf("SDCARD: %s, cpu=%p\n", ifname, &cpu);
  259. //              a=0;
  260. //      }
  261.  
  262.     switch(Cmd)
  263.     {
  264.     case CMD_GO_IDLE_STATE:
  265.         if (CurrState == ST_R1)
  266.         {
  267. //            Cmd = CMD_INVALID;
  268.             CurrState = ST_IDLE;
  269.             return 1;
  270.         }
  271.     break;
  272.     case CMD_SEND_OP_COND:
  273.         if (CurrState == ST_R1)
  274.         {
  275. //            Cmd = CMD_INVALID;
  276.             CurrState = ST_IDLE;
  277.             return 0;
  278.         }
  279.     break;
  280.     case CMD_SET_BLOCKLEN:
  281.         if (CurrState == ST_R1)
  282.         {
  283. //            Cmd = CMD_INVALID;
  284.             CurrState = ST_IDLE;
  285.             return 0;
  286.         }
  287.     break;
  288.     case CMD_SEND_IF_COND:
  289.         if (CurrState == ST_R7)
  290.         {
  291.             switch (R7_Cnt++)
  292.             {
  293.              case 0: return 0x01; // R1
  294.              case 1: return 0x00;
  295.              case 2: return 0x00;
  296.              case 3: return 0x01;
  297.              default:
  298.                 CurrState = ST_IDLE;
  299.                 R7_Cnt = 0;
  300.                 return ArgArr[0]; // echo-back
  301.             }
  302.         }
  303.     break;
  304.  
  305.     case CMD_READ_OCR:
  306.         if (CurrState == ST_R3)
  307.         {
  308.             switch (OcrCnt++)
  309.             {
  310.              case 0: return 0x00; // R1
  311.              case 1: return 0x80;
  312.              case 2: return 0xFF;
  313.              case 3: return 0x80;
  314.              default:
  315.                 CurrState = ST_IDLE;
  316.                 OcrCnt = 0;
  317.                 return 0x00;
  318.             }
  319.         }
  320.     break;
  321.  
  322.     case CMD_APP_CMD:
  323.         if (CurrState == ST_R1)
  324.         {
  325.             CurrState = ST_IDLE;
  326.             return 0;
  327.         }
  328.     break;
  329.  
  330.     case CMD_SD_SEND_OP_COND:
  331.         if (CurrState == ST_R1)
  332.         {
  333.             CurrState = ST_IDLE;
  334.             return 0;
  335.         }
  336.     break;
  337.  
  338.     case CMD_CRC_ON_OFF:
  339.         if (CurrState == ST_R1)
  340.         {
  341.             CurrState = ST_IDLE;
  342.             return 0;
  343.         }
  344.     break;
  345.  
  346.     case CMD_STOP_TRANSMISSION:
  347.         switch(CurrState)
  348.         {
  349.         case ST_R1:
  350.             DataCnt = 0;
  351.             CurrState = ST_IDLE;
  352.             return 0;
  353.         case ST_R1b:
  354.             DataCnt = 0;
  355.             CurrState = ST_R1;
  356.             return 0x7F;
  357.                 case ST_RD_ARG:
  358.                 case ST_RD_CRC:
  359.             return 0;
  360.         }
  361.     break;
  362.  
  363.     case CMD_READ_SINGLE_BLOCK:
  364.         switch(CurrState)
  365.         {
  366.           unsigned int cpu_dt;
  367.  
  368.           case ST_R1:
  369.               CurrState = ST_DELAY_S;
  370.               InitialCPUt = cpu.t;
  371.               return 0;
  372.  
  373.           case ST_DELAY_S:
  374.               cpu_dt = cpu.t - InitialCPUt;
  375.               if (cpu_dt < 0)
  376.                 cpu_dt += conf.frame;
  377.               if (cpu_dt >= conf.sd_delay)
  378.                 CurrState = ST_STARTBLOCK;
  379.               return 0xFF;
  380.  
  381.           case ST_STARTBLOCK:
  382.               CurrState = ST_WR_DATA;
  383.               DataCnt = 0;
  384.               return 0xFE;
  385.  
  386.           case ST_WR_DATA:
  387.           {
  388.               u8 Val = Buf[DataCnt++];
  389.               if (DataCnt == DataBlockLen)
  390.               {
  391.                 DataCnt = 0;
  392.                 CurrState = ST_WR_CRC16_1;
  393.               }
  394.               return Val;
  395.           }
  396.  
  397.           case ST_WR_CRC16_1:
  398.               CurrState = ST_WR_CRC16_2;
  399.               return 0xFF; // crc
  400.           case ST_WR_CRC16_2:
  401.               CurrState = ST_IDLE;
  402.               Cmd = CMD_INVALID;
  403.               return 0xFF; // crc
  404.         }
  405. //        Cmd = CMD_INVALID;
  406.     break;
  407.  
  408.     case CMD_READ_MULTIPLE_BLOCK:
  409.         switch(CurrState)
  410.         {
  411.           unsigned int cpu_dt;
  412.  
  413.           case ST_R1:
  414.               CurrState = ST_DELAY_S;
  415.               InitialCPUt = cpu.t;
  416.               return 0;
  417.  
  418.           case ST_DELAY_S:
  419.               cpu_dt = cpu.t - InitialCPUt;
  420.               if (cpu_dt < 0)
  421.                 cpu_dt += conf.frame;
  422.               if (cpu_dt >= conf.sd_delay)
  423.                 CurrState = ST_STARTBLOCK;
  424.               return 0xFF;
  425.  
  426.           case ST_STARTBLOCK:
  427.               CurrState = ST_IDLE;
  428.               DataCnt = 0;
  429.               return 0xFE;
  430.  
  431.           case ST_IDLE:
  432.           {
  433.               if (DataCnt<DataBlockLen)
  434.               {
  435.                 u8 Val = Buf[DataCnt++];
  436.                 if (DataCnt == DataBlockLen)
  437.                     fread(Buf, DataBlockLen, 1, Image);
  438.                 return Val;
  439.               }
  440.               else if (DataCnt>(DataBlockLen+8))
  441.               {
  442.                 DataCnt=0;
  443.                 return 0xFE; // next startblock
  444.               }
  445.               else
  446.               {
  447.                 DataCnt++;
  448.                 return 0xFF; // crc & pause
  449.               }
  450.           }
  451.  
  452. /*
  453.         case ST_R1:
  454.             CurrState = ST_WR_DATA_SIG;
  455.             return 0;
  456.         case ST_WR_DATA_SIG:
  457.             CurrState = ST_IDLE;
  458.             DataCnt = 0;
  459.             return 0xFE;
  460.         case ST_IDLE:
  461.         {
  462.             u8 Val = Buf[DataCnt++];
  463.             if (DataCnt == DataBlockLen)
  464.             {
  465.                 DataCnt = 0;
  466.                 fread(Buf, DataBlockLen, 1, Image);
  467.                 CurrState = ST_WR_CRC16_1;
  468.             }
  469.             return Val;
  470.         }
  471.         case ST_WR_CRC16_1:
  472.             CurrState = ST_WR_CRC16_2;
  473.             return 0xFF;
  474.         case ST_WR_CRC16_2:
  475.             CurrState = ST_WR_DATA_SIG;
  476.             return 0xFF;
  477. */
  478.         }
  479.     break;
  480.  
  481.     case CMD_SEND_CSD:
  482.         switch(CurrState)
  483.         {
  484.         case ST_R1:
  485.             CurrState = ST_DELAY_S;
  486.             return 0;
  487.         case ST_DELAY_S:
  488.             CurrState = ST_STARTBLOCK;
  489.             return 0xFF;
  490.         case ST_STARTBLOCK:
  491.             CurrState = ST_WR_DATA;
  492.             return 0xFE;
  493.         case ST_WR_DATA:
  494.         {
  495.             u8 Val = Csd[CsdCnt++];
  496.             if (CsdCnt == 16)
  497.             {
  498.                 CsdCnt = 0;
  499.                 CurrState = ST_IDLE;
  500.                 Cmd = CMD_INVALID;
  501.             }
  502.             return Val;
  503.         }
  504.         }
  505. //        Cmd = CMD_INVALID;
  506.     break;
  507.  
  508.     case CMD_SEND_CID:
  509.         switch(CurrState)
  510.         {
  511.         case ST_R1:
  512.             CurrState = ST_DELAY_S;
  513.             return 0;
  514.         case ST_DELAY_S:
  515.             CurrState = ST_STARTBLOCK;
  516.             return 0xFF;
  517.         case ST_STARTBLOCK:
  518.             CurrState = ST_WR_DATA;
  519.             return 0xFE;
  520.         case ST_WR_DATA:
  521.         {
  522.             u8 Val = Cid[CidCnt++];
  523.             if (CidCnt == 16)
  524.             {
  525.                 CidCnt = 0;
  526.                 CurrState = ST_IDLE;
  527.                 Cmd = CMD_INVALID;
  528.             }
  529.             return Val;
  530.         }
  531.         }
  532. //        Cmd = CMD_INVALID;
  533.     break;
  534.  
  535.     case CMD_WRITE_BLOCK:
  536. //        printf(__FUNCTION__" cmd=0x%X, St=0x%X\n", Cmd, CurrState);
  537.         switch(CurrState)
  538.         {
  539.         case ST_R1:
  540.             CurrState = ST_RD_DATA_SIG;
  541.             return 0x00;
  542.  
  543.         case ST_WR_DATA_RESP:
  544.         {
  545.             CurrState = ST_IDLE;
  546.             u8 Resp = ((STAT_DATA_ACCEPTED) << 1) | 1;
  547.             return Resp;
  548.         }
  549.         }
  550.     break;
  551.  
  552.     case CMD_WRITE_MULTIPLE_BLOCK:
  553.         switch(CurrState)
  554.         {
  555.         case ST_R1:
  556.             CurrState = ST_RD_DATA_SIG_MUL;
  557.             return 0x00;    // !!! check this !!!
  558.         case ST_WR_DATA_RESP:
  559.         {
  560.             CurrState = ST_RD_DATA_SIG_MUL;
  561.             u8 Resp = ((STAT_DATA_ACCEPTED) << 1) | 1;
  562.             return Resp;
  563.         }
  564.         }
  565.     break;
  566.     }
  567.  
  568.     if (CurrState == ST_R1) // CMD_INVALID
  569.     {
  570.         CurrState = ST_IDLE;
  571.         return 0x05;
  572.     }
  573.  
  574.     return 0xFF;
  575. }
  576.  
  577. //-----------------------------------------------------------------------------
  578.  
  579. TSdCard::TState TSdCard::GetRespondType()
  580. {
  581.     if (!AppCmd)
  582.     {
  583.         switch(Cmd)
  584.         {
  585.         case CMD_APP_CMD:
  586.             AppCmd = true;
  587.             return ST_R1;
  588.         case CMD_GO_IDLE_STATE:
  589.         case CMD_SEND_OP_COND:
  590.         case CMD_SET_BLOCKLEN:
  591.         case CMD_READ_SINGLE_BLOCK:
  592.         case CMD_READ_MULTIPLE_BLOCK:
  593.         case CMD_CRC_ON_OFF:
  594.         case CMD_SEND_CSD:
  595.         case CMD_SEND_CID:
  596.             return ST_R1;
  597.         case CMD_READ_OCR:
  598.             return ST_R3;
  599.         case CMD_SEND_IF_COND:
  600.             return ST_R7;
  601.         case CMD_STOP_TRANSMISSION:
  602.             return ST_R1b;
  603.  
  604.         case CMD_WRITE_BLOCK:
  605.         case CMD_WRITE_MULTIPLE_BLOCK:
  606.             return ST_R1;
  607.         }
  608.     }
  609.     else
  610.     {
  611.         AppCmd = false;
  612.         switch(Cmd)
  613.         {
  614.             case CMD_SD_SEND_OP_COND:
  615.                 return ST_R1;
  616.         }
  617.     }
  618.  
  619.     Cmd = CMD_INVALID;
  620.     return ST_R1;
  621.     //return ST_IDLE;
  622. }
  623.  
  624. //-----------------------------------------------------------------------------
  625.  
  626.  
  627. void TSdCard::Open(const char *Name)
  628. {
  629. //    printf(__FUNCTION__"\n");
  630.     assert(!Image);
  631.     Image = fopen(Name, "r+b");
  632.     if(!Image)
  633.     {
  634.         if(Name[0])
  635.         {
  636.             errmsg("can't find SD card image `%s'", Name);
  637.         }
  638.         return;
  639.     }
  640.     ImageSize = u32(_filelengthi64(fileno(Image)) / (512 * 1024)) - 1;
  641.     UpdateCsdImageSize();
  642. }
  643.  
  644. //-----------------------------------------------------------------------------
  645.  
  646. void TSdCard::Close()
  647. {
  648.     if (Image)
  649.     {
  650.         fclose(Image);
  651.         Image = 0;
  652.     }
  653. }
  654.  
  655. //-----------------------------------------------------------------------------
  656.  
  657. TSdCard SdCard("ngs.sdcard");
  658.  
  659. //-----------------------------------------------------------------------------
  660.