Subversion Repositories pentevo

Rev

Rev 916 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  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.                 if(res == 0x00) break;
  113.         }while(--i);
  114.         if(res){
  115.                 TO_LOG(" (CMD00 error) ");
  116.                 return 1;
  117.         }
  118.         outcom(CMD08);
  119.         res = in_oout();
  120.         spi_io(0xff);
  121.         spi_io(0xff);
  122.         spi_io(0xff);
  123.         spi_io(0xff);
  124.         if(res & 0b00000100){
  125.                 res = 0x00;
  126.         }else{
  127.                 res = 0x40;
  128.         }
  129.         i = 10000;
  130.         do{
  131.                 out_com(CMD_55);
  132.                 in_oout();
  133.                 spi_io(0xff);
  134.                 spi_io(0xff);
  135.                 spi_io(0xff);
  136.                 spi_io(0xff);
  137.                 spi_io(ACMD_41);
  138.                 spi_io(res);
  139.                 spi_io(0x00);
  140.                 spi_io(0x00);
  141.                 spi_io(0x00);
  142.                 spi_io(0xff);
  143.                 if(in_oout()==0x00) break;
  144.         }while(--i);
  145.         if(i == 0) {
  146.                 TO_LOG(" (ACMD_41 error) ");
  147.                 return 1;
  148.         }
  149.        
  150.         i = 1024;
  151.         do{
  152.                 out_com(CMD_59);
  153.                 if(in_oout()==0x00) break;
  154.         }while(--i);
  155.         if(i == 0) {
  156.                 TO_LOG(" (CMD_59 error) ");
  157.                 return 1;
  158.         }
  159.        
  160.         i = 1024;
  161.         do{
  162.                 outcom(CMD16);
  163.                 if(in_oout()==0x00) break;
  164.         }while(--i);
  165.         if(i == 0) {
  166.                 TO_LOG(" (CMD16 error) ");
  167.                 return 1;
  168.         }
  169.         out_com(CMD_58);
  170.         in_oout();
  171.         sd_blsize = spi_io(0xff) & 0x40;
  172.         spi_io(0xff);
  173.         spi_io(0xff);
  174.         spi_io(0xff);
  175.        
  176.         CS_HIGH
  177.         return 0x00;
  178. }
  179.  
  180. DRESULT disk_readp (BYTE* buff, DWORD sector, UINT offset, UINT count){
  181.         static DWORD c_sector = 0xffffffffl;
  182.         static BYTE cache[512];
  183.         if(sd_blsize == 0xff) return RES_NOTRDY;
  184.         if(writep_status) return RES_ERROR;
  185.         if(c_sector != sector){
  186.                 BYTE* c;
  187.                 if(count == 512){
  188.                         c = buff;
  189.                 }else{
  190.                         c = cache;
  191.                         c_sector = sector;
  192.                 }
  193.                 UINT i;
  194.                         CS_LOW
  195.                         spi_io(0xff);
  196.                         spi_io(0xff);
  197.                         spi_io(0xff);
  198.                         spi_io(0xff);
  199.                         if(sd_blsize == 0x00) sector *= 512;
  200.                         spi_io(CMD_17);
  201.                         spi_io(((BYTE*) &sector)[3]);
  202.                         spi_io(((BYTE*) &sector)[2]);
  203.                         spi_io(((BYTE*) &sector)[1]);
  204.                         spi_io(((BYTE*) &sector)[0]);
  205.                         spi_io(0xff);
  206.                         while((i = in_oout())!=0xfe){
  207.                                 //todo убрать вечный цикл!!!
  208.                         }
  209.                 i = 512;
  210.                 while(i--){
  211.                         (*c++) = spi_io(0xff);
  212.                 }
  213.                 spi_io(0xff);
  214.                 CS_HIGH
  215.                 if(count == 512) return RES_OK;
  216.         }
  217.         memcpy(buff, cache + offset, count);
  218.         return RES_OK;
  219. }
  220. /*
  221. DRESULT disk_readp (BYTE* buff, DWORD sector, UINT offset, UINT count){
  222.         if(sd_blsize == 0xff) return RES_NOTRDY;
  223.         if(writep_status) return RES_ERROR;
  224.         UINT skip = 512 + 2 - offset - count;
  225.         CS_LOW
  226.         spi_io(0xff);
  227.         spi_io(0xff);
  228.         if(sd_blsize == 0x00) sector *= 512;
  229.         spi_io(CMD_17);
  230.         spi_io(((BYTE*) &sector)[3]);
  231.         spi_io(((BYTE*) &sector)[2]);
  232.         spi_io(((BYTE*) &sector)[1]);
  233.         spi_io(((BYTE*) &sector)[0]);
  234.         spi_io(0xff);
  235.         while(in_oout()!=0xfe);
  236.         while(offset--) spi_io(0xff);
  237.         while(count--){
  238.                 (*buff++) = spi_io(0xff);
  239.         }
  240.         while(skip--) spi_io(0xff);
  241.         spi_io(0xff);
  242.         CS_HIGH
  243.         return 0x00;
  244. }
  245. */
  246.  
  247. DRESULT disk_writep (const BYTE* buff, DWORD sc){
  248.         static WORD wr_cnt;
  249.         if(sd_blsize == 0xff) return RES_NOTRDY;
  250.        
  251.         if (!buff) {
  252.                 if (sc) {
  253.                         CS_LOW
  254.                         spi_io(0xff);
  255.                         spi_io(0xff);
  256.                         if(sd_blsize == 0x00) sc *= 512;
  257.                         spi_io(CMD_24);
  258.                         spi_io(((BYTE*) &sc)[3]);
  259.                         spi_io(((BYTE*) &sc)[2]);
  260.                         spi_io(((BYTE*) &sc)[1]);
  261.                         spi_io(((BYTE*) &sc)[0]);
  262.                         spi_io(0xff);
  263.                         if(in_oout() != 0X00) return RES_ERROR;
  264.                         spi_io(0xff);
  265.                         spi_io(0xfe);
  266.                        
  267.                         writep_status=1;
  268.                         wr_cnt = 512;
  269.                 } else {
  270.                         // Finalize write process
  271.                         if(writep_status == 0) return RES_NOTRDY;
  272.                         while(wr_cnt--){
  273.                                 spi_io(0x00);
  274.                         }
  275.                         in_oout();
  276.                         while(spi_io(0xff) != 0xff);
  277.                         writep_status = 0x00;
  278.                         CS_HIGH
  279.                 }
  280.         } else {
  281.                 if(writep_status == 0) return RES_NOTRDY;
  282.                 wr_cnt -= (WORD)sc;
  283.                         while(sc--){
  284.                                 spi_io(*buff++);
  285.                         }
  286.         }
  287.         return RES_OK;
  288. }
  289.  
  290.  
  291.  
  292.