Subversion Repositories pentevo

Rev

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