Subversion Repositories pentevo

Rev

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

  1. #include <avr/io.h>
  2. #include <string.h>
  3. #include "diskio.h"
  4.  
  5. #define LOGENABLE
  6.  
  7. #ifdef LOGENABLE
  8. void rs232_transmit(BYTE data);
  9. void to_log(char* ptr);
  10. #define TO_LOG  to_log
  11. #define RS232_TRANSMIT rs232_transmit
  12. #else
  13. #define TO_LOG(_a)
  14. #define RS232_TRANSMIT(_a)
  15. #endif
  16.  
  17. #define CS_HIGH {PORTF |= 0b00100000;spi_io(0xff);}
  18. #define CS_LOW  PORTF &= 0b11011111;
  19.  
  20. BYTE spi_io(BYTE spi){
  21.                 BYTE i=8;
  22.                 register BYTE portf = PORTF;
  23.                 do{
  24.                         portf &= 0b11101111;
  25.                         PORTF = portf;
  26.                         if(spi&0x80) {
  27.                                 portf |= 0b10000000;
  28.                         }else{
  29.                                 portf &= 0b01111111;
  30.                         }
  31.                         PORTF = portf;
  32.                         spi=spi<<1;
  33.                         if(PINF & 0x40) {
  34.                                 spi |= 1;
  35.                         }
  36.                         portf |= 0b00010000;
  37.                         PORTF = portf;
  38.                 }while(--i);
  39.         return spi;
  40. }
  41.  
  42. const BYTE CMD00[] = {0X40,0X00,0X00,0X00,0X00,0X95};
  43. const BYTE CMD08[] = {0X48,0X00,0X00,0X01,0XAA,0X87};
  44. const BYTE CMD16[] = {0X50,0X00,0X00,0X02,0X00,0XFF};
  45.  
  46. #define CMD_17  0X51            //READ_SINGLE_BLOCK
  47. #define CMD_24  0X58            //WRITE_BLOCK
  48. #define CMD_55  0X77            //APP_CMD
  49. #define CMD_58  0X7A            //READ_OCR
  50. #define CMD_59  0X7B            //CRC_ON_OFF
  51. #define ACMD_41 0X69            //SD_SEND_OP_COND
  52.  
  53. /*
  54. CMD_09          EQU 0X49        ;SEND_CSD
  55. CMD_12          EQU 0X4C        ;STOP_TRANSMISSION
  56. CMD_17          EQU 0X51        ;READ_SINGLE_BLOCK
  57. CMD_18          EQU 0X52        ;READ_MULTIPLE_BLOCK
  58. CMD_24          EQU 0X58        ;WRITE_BLOCK
  59. CMD_25          EQU 0X59        ;WRITE_MULTIPLE_BLOCK
  60. CMD_55          EQU 0X77        ;APP_CMD
  61. CMD_58          EQU 0X7A        ;READ_OCR
  62. CMD_59          EQU 0X7B        ;CRC_ON_OFF
  63. ACMD_41         EQU 0X69        ;SD_SEND_OP_COND
  64. */
  65.  
  66. static BYTE sd_blsize           = 0xff;
  67. static BYTE writep_status       = 0x00;
  68.  
  69. void outcom(const BYTE * cmd){
  70.         BYTE i = 6;
  71.         CS_LOW
  72.         do{
  73.                 spi_io(*cmd);
  74.                 cmd++;
  75.         }while(--i);
  76. }
  77.  
  78. void out_com(BYTE cmd){
  79.         CS_LOW
  80.         spi_io(0xff);
  81.         spi_io(0xff);
  82.         spi_io(cmd);
  83.         spi_io(0x00);
  84.         spi_io(0x00);
  85.         spi_io(0x00);
  86.         spi_io(0x00);
  87.         spi_io(0xff);
  88. }
  89.  
  90. BYTE in_oout(void){
  91.         BYTE res;
  92.         BYTE i = 33;
  93.         do{
  94.                 res = spi_io(0xff);
  95.                 if(res != 0xff) break;
  96.         }while(--i);
  97.         return res;
  98. }
  99.  
  100. BYTE disk_initialize(void){
  101.         if(writep_status) disk_writep(0, 0);
  102.         CS_HIGH
  103.         UINT i = 64;
  104.         BYTE res;
  105.         while (--i){
  106.                 spi_io(0xff);
  107.         }
  108.         i = 1024;
  109.         do{
  110.                 outcom(CMD00);
  111.                 res = in_oout() - 1;
  112.                 CS_HIGH
  113.                 if(res == 0x00) break;
  114.         }while(--i);
  115.         if(res){
  116.                 TO_LOG(" (CMD00 error) ");
  117.                 return 1;
  118.         }
  119.         outcom(CMD08);
  120.         res = in_oout();
  121.         spi_io(0xff);
  122.         spi_io(0xff);
  123.         spi_io(0xff);
  124.         spi_io(0xff);
  125.         if(res & 0b00000100){
  126.                 res = 0x00;
  127.         }else{
  128.                 res = 0x40;
  129.         }
  130.         i = 10000;
  131.         do{
  132.                 CS_HIGH
  133.                 out_com(CMD_55);
  134.                 in_oout();
  135.                 spi_io(0xff);
  136.                 spi_io(0xff);
  137.                 spi_io(0xff);
  138.                 spi_io(0xff);
  139.                 spi_io(ACMD_41);
  140.                 spi_io(res);
  141.                 spi_io(0x00);
  142.                 spi_io(0x00);
  143.                 spi_io(0x00);
  144.                 spi_io(0xff);
  145.                 if(in_oout()==0x00) break;
  146.         }while(--i);
  147.         if(i == 0) {
  148.                 TO_LOG(" (ACMD_41 error) ");
  149.                 return 1;
  150.         }
  151.        
  152.         i = 1024;
  153.         do{
  154.                 out_com(CMD_59);
  155.                 if(in_oout()==0x00) break;
  156.         }while(--i);
  157.         if(i == 0) {
  158.                 TO_LOG(" (CMD_59 error) ");
  159.                 return 1;
  160.         }
  161.        
  162.         i = 1024;
  163.         do{
  164.                 outcom(CMD16);
  165.                 if(in_oout()==0x00) break;
  166.         }while(--i);
  167.         if(i == 0) {
  168.                 TO_LOG(" (CMD16 error) ");
  169.                 return 1;
  170.         }
  171.         out_com(CMD_58);
  172.         in_oout();
  173.         sd_blsize = spi_io(0xff) & 0x40;
  174.         spi_io(0xff);
  175.         spi_io(0xff);
  176.         spi_io(0xff);
  177.        
  178.         CS_HIGH
  179.         return 0x00;
  180. }
  181.  
  182. DRESULT disk_readp (BYTE* buff, DWORD sector, UINT offset, UINT count){
  183.         static DWORD c_sector = 0xffffffffl;
  184.         static BYTE cache[512];
  185.         if(sd_blsize == 0xff) return RES_NOTRDY;
  186.         if(writep_status) return RES_ERROR;
  187.         if(c_sector != sector){
  188.                 BYTE* c;
  189.                 if(count == 512){
  190.                         c = buff;
  191.                 }else{
  192.                         c = cache;
  193.                         c_sector = sector;
  194.                 }
  195.                 UINT i;
  196.                         CS_LOW
  197.                         spi_io(0xff);
  198.                         spi_io(0xff);
  199.                         spi_io(0xff);
  200.                         spi_io(0xff);
  201.                         if(sd_blsize == 0x00) sector *= 512;
  202.                         spi_io(CMD_17);
  203.                         spi_io(((BYTE*) &sector)[3]);
  204.                         spi_io(((BYTE*) &sector)[2]);
  205.                         spi_io(((BYTE*) &sector)[1]);
  206.                         spi_io(((BYTE*) &sector)[0]);
  207.                         spi_io(0xff);
  208.                         while((i = in_oout())!=0xfe){
  209.                                 //todo убрать вечный цикл!!!
  210.                         }
  211.                 i = 512;
  212.                 while(i--){
  213.                         (*c++) = spi_io(0xff);
  214.                 }
  215.                 spi_io(0xff);
  216.                 CS_HIGH
  217.                 if(count == 512) return RES_OK;
  218.         }
  219.         memcpy(buff, cache + offset, count);
  220.         return RES_OK;
  221. }
  222. /*
  223. DRESULT disk_readp (BYTE* buff, DWORD sector, UINT offset, UINT count){
  224.         if(sd_blsize == 0xff) return RES_NOTRDY;
  225.         if(writep_status) return RES_ERROR;
  226.         UINT skip = 512 + 2 - offset - count;
  227.         CS_LOW
  228.         spi_io(0xff);
  229.         spi_io(0xff);
  230.         if(sd_blsize == 0x00) sector *= 512;
  231.         spi_io(CMD_17);
  232.         spi_io(((BYTE*) &sector)[3]);
  233.         spi_io(((BYTE*) &sector)[2]);
  234.         spi_io(((BYTE*) &sector)[1]);
  235.         spi_io(((BYTE*) &sector)[0]);
  236.         spi_io(0xff);
  237.         while(in_oout()!=0xfe);
  238.         while(offset--) spi_io(0xff);
  239.         while(count--){
  240.                 (*buff++) = spi_io(0xff);
  241.         }
  242.         while(skip--) spi_io(0xff);
  243.         spi_io(0xff);
  244.         CS_HIGH
  245.         return 0x00;
  246. }
  247. */
  248.  
  249. DRESULT disk_writep (const BYTE* buff, DWORD sc){
  250.         static WORD wr_cnt;
  251.         if(sd_blsize == 0xff) return RES_NOTRDY;
  252.        
  253.         if (!buff) {
  254.                 if (sc) {
  255.                         CS_LOW
  256.                         spi_io(0xff);
  257.                         spi_io(0xff);
  258.                         if(sd_blsize == 0x00) sc *= 512;
  259.                         spi_io(CMD_24);
  260.                         spi_io(((BYTE*) &sc)[3]);
  261.                         spi_io(((BYTE*) &sc)[2]);
  262.                         spi_io(((BYTE*) &sc)[1]);
  263.                         spi_io(((BYTE*) &sc)[0]);
  264.                         spi_io(0xff);
  265.                         if(in_oout() != 0X00) return RES_ERROR;
  266.                         spi_io(0xff);
  267.                         spi_io(0xfe);
  268.                        
  269.                         writep_status=1;
  270.                         wr_cnt = 512;
  271.                 } else {
  272.                         // Finalize write process
  273.                         if(writep_status == 0) return RES_NOTRDY;
  274.                         while(wr_cnt--){
  275.                                 spi_io(0x00);
  276.                         }
  277.                         in_oout();
  278.                         while(spi_io(0xff) != 0xff);
  279.                         writep_status = 0x00;
  280.                         CS_HIGH
  281.                 }
  282.         } else {
  283.                 if(writep_status == 0) return RES_NOTRDY;
  284.                 wr_cnt -= (WORD)sc;
  285.                         while(sc--){
  286.                                 spi_io(*buff++);
  287.                         }
  288.         }
  289.         return RES_OK;
  290. }
  291.  
  292.  
  293.  
  294.