1 #pragma GCC optimize ("O2")    13 #include "../diskio.h"    20 #define CS_HIGH()   spi_chipSelectHigh()    21 #define CS_LOW()    spi_chipSelectLow(1)    22 #define MMC_CD      spi_detect()     37 #define ACMD41  (0x80+41)       43 #define ACMD13  (0x80+13)       48 #define ACMD23  (0x80+23)       68 extern void spi_spiTransfer(
const uint8_t *send, uint32_t send_len,  uint8_t *recv, uint32_t recv_len);
    84 extern int printf(
const char *msg, ...);
    86 #if defined(BOARD_SDCARD_CS_PIN)    90 static uint8_t CardType;            
    91 static uint8_t no_CMD13 = 0;
    92 static uint8_t csd[16]; 
    94 static int8_t xmit_datablock(
const uint8_t *buff,   uint8_t token);
   119     return xchg_spi(0xFF);
   124 void rcvr_spi_multi (
   134 void xmit_spi_multi (
   158 static uint8_t wait_ff(uint8_t b){
   170 #if defined(WAIT_IN_ISR)   180     } 
while (d != 0xFF && 
Timer2);  
   196 void deselect_cs (
void)
   215     if (wait_ready(500)) 
return 1;  
   227 static uint8_t wait_noFF(uint8_t b){
   233 int8_t rcvr_datablock ( 
   240 #if defined(WAIT_IN_ISR)   243         if(ret != 0xFE) 
goto done;      
   249             token = xchg_spi(0xFF);
   251     } 
while ((token == 0xFF) && 
Timer1);
   257     rcvr_spi_multi(buff, btr);      
   258     xchg_spi(0xFF); xchg_spi(0xFF);     
   271 static int8_t xmit_datablock (          
   279     if (!wait_ready(500)) 
return 0;     
   283         xmit_spi_multi(buff, 512);      
   284         xchg_spi(0xFF); xchg_spi(0xFF); 
   286         resp = xchg_spi(0xFF);      
   287         if ((resp & 0x1F) != 0x05) {
   298 static uint8_t buf[6]; 
   300 static uint8_t wait_0x80(uint8_t b){
   301     return (b & 0x80)==0;
   316         res = send_cmd(
CMD55, 0);
   332     if (cmd == 
CMD0) crc = 0x95;        
   333     if (cmd == 
CMD8) crc = 0x87;        
   338     buf[1] = (uint8_t)(arg >> 24);      
   339     buf[2] = (uint8_t)(arg >> 16);      
   340     buf[3] = (uint8_t)(arg >> 8);       
   341     buf[4] = (uint8_t)arg;          
   344         xmit_spi_multi(buf, 6);         
   347     if (cmd == 
CMD12) xchg_spi(0xFF);   
   349 #if defined(WAIT_IN_ISR)   358         res = xchg_spi(0xFF);
   360     } 
while ((res & 0x80) && --n);
   380     uint8_t n, cmd, ty, ocr[4] ;
   387     n = send_cmd(
CMD0, 0);
   388     if (n == 1 || n==0) {                           
   390         n=send_cmd(
CMD8, 0x1AA);                        
   391         if((n&4) == 0) rcvr_spi_multi(ocr, 4);              
   393         if (ocr[2] == 0x01 && ocr[3] == 0xAA) {     
   395                 n = send_cmd(
ACMD41, 1UL << 30);
   399                 n = send_cmd(
CMD58, 0);
   400                 if((n&4) == 0) rcvr_spi_multi(ocr, 4); 
   404                     printf(
"\nSD CMD58 failed!\n");
   407                 printf(
"\nSD timeout!\n");
   411         if (send_cmd(
ACMD41, 0) <= 1)   {   
   422             if(send_cmd(
CMD16, 512) != 0) { 
   424                 printf(
"\nSD CMD16 failed!\n");
   428             printf(
"\nSD timeout!\n");
   452 static uint8_t restart_card(){
   457     if(!(
Stat & STA_NOINIT) )  
return true; 
   464     if ((send_cmd(
CMD9, 0) == 0) && rcvr_datablock(csd, 16)) {
   465         if ((csd[0] >> 6) == 1) {   
   466         csize = csd[9] + ((uint16_t)csd[8] << 8) + ((uint32_t)(csd[7] & 63) << 16) + 1;
   469         uint8_t n = (csd[5] & 15) + ((csd[10] & 128) >> 7) + ((csd[9] & 3) << 1) + 2;
   470         csize = (csd[8] >> 6) + ((uint16_t)csd[7] << 2) + ((uint16_t)(csd[6] & 3) << 10) + 1;
   471         *ptr = csize << (n - 9);
   491         if(send_cmd(
CMD13, 0)<=1){
   492             uint8_t ret = xchg_spi(0xFF);
   522 static bool single_sector_card=
false;
   532         uint16_t sectorInc=1;
   546         if (( (ret=send_cmd(
CMD17, sector)) == 0)   
   547             && rcvr_datablock(buff, 512)) {
   552         if(single_sector_card) {
   554             if ((ret=send_cmd(
CMD17, sector)) == 0){    
   555             if(rcvr_datablock(buff, 512)) {
   573                 if ((ret=send_cmd(
CMD18, sector)) == 0) {   
   575                 if (!rcvr_datablock(buff, 512)) {
   581             if(got) send_cmd(
CMD12, 0);             
   585             single_sector_card=
true;
   586             sector+=got*sectorInc;
   588             return sd_read(buff, sector/sectorInc, count); 
   593         if(count==0) 
return  RES_OK;    
   615         uint16_t sectorInc = 1;
   618     if (!(CardType & CT_BLOCK)){
   624         if (send_cmd(
CMD24, sector) == 0) { 
   625             if( xmit_datablock(buff, 0xFE)) {
   631         if(single_sector_card) {
   633                 if ((send_cmd(
CMD24, sector) == 0)  
   634             && xmit_datablock(buff, 0xFE)) {
   641         if (CardType & CT_SDC) send_cmd(
ACMD23, count); 
   643         if (send_cmd(
CMD25, sector) == 0) { 
   645             if (!xmit_datablock(buff, 0xFC)) 
break;
   649             if (!xmit_datablock(0, 0xFD)) count = 1;    
   652             single_sector_card=
true;
   653                 sector+=sent*sectorInc;
   655             return sd_write(buff, sector/sectorInc, count); 
   687     uint32_t *dp, st, ed;
   689     uint8_t *ptr = (uint8_t *)buff;
   706              *(ptr + 1) = (uint8_t) 
MMC_CD;
   719         if (select_cs()) res = 
RES_OK;
   728             if (send_cmd(
ACMD13, 0) == 0) { 
   730             if (rcvr_datablock(csd, 16)) {              
   731                 for (n = 64 - 16; n; n--) xchg_spi(0xFF);   
   732                 *(uint32_t*)buff = 16UL << (csd[10] >> 4);
   737             if ((send_cmd(
CMD9, 0) == 0) && rcvr_datablock(csd, 16)) {  
   739                 *(uint32_t*)buff = (((csd[10] & 63) << 1) + ((uint16_t)(csd[11] & 128) >> 7) + 1) << ((csd[13] >> 6) - 1);
   741                 *(uint32_t*)buff = ((uint16_t)((csd[10] & 124) >> 2) + 1) * (((csd[11] & 3) << 3) + ((csd[11] & 224) >> 5) + 1);
   749         if (!(CardType & CT_SDC)) 
break;        
   751         if (!(csd[0] >> 6) && !(csd[10] & 0x40)) 
break; 
   752         dp = buff; st = dp[0]; ed = dp[1];      
   753         if (!(CardType & CT_BLOCK)) {
   754             st *= 512; ed *= 512;
   756         if (send_cmd(
CMD32, st) == 0 && send_cmd(
CMD33, ed) == 0 && send_cmd(
CMD38, 0) == 0 && wait_ready(30000)) { 
   767              if (send_cmd(
CMD9, 0) == 0 
   768              && rcvr_datablock(ptr, 16))
   773             if (send_cmd(
CMD10, 0) == 0 
   774             && rcvr_datablock(ptr, 16)){
   794              if (send_cmd(
CMD58, 0) == 0) { 
   796                  rcvr_spi_multi(ptr, 4);
   802              if (send_cmd(
ACMD13, 0) == 0) { 
   804                  if (rcvr_datablock(ptr, 64))
   852 #elif defined(BOARD_DATAFLASH_FATFS)   857 #define DF_NUM_PAGES 0x1f00   858 #define DF_PAGE_SIZE 256L   860 #define DF_RESET BOARD_DATAFLASH_CS_PIN    863 #define JEDEC_WRITE_ENABLE           0x06   864 #define JEDEC_WRITE_DISABLE          0x04   865 #define JEDEC_READ_STATUS            0x05   866 #define JEDEC_WRITE_STATUS           0x01   867 #define JEDEC_READ_DATA              0x03   868 #define JEDEC_FAST_READ              0x0b   869 #define JEDEC_DEVICE_ID              0x9F   870 #define JEDEC_PAGE_WRITE             0x02   872 #define JEDEC_WREAR                  0xC5   873 #define JEDEC_ENTER_4B_MODE          0xB7   875 #define JEDEC_BULK_ERASE             0xC7 // full chip erase   876 #define JEDEC_SECTOR_ERASE           0x20 // 4k erase   877 #define JEDEC_PAGE_ERASE             0xD8 // 64K erase   879 #define JEDEC_STATUS_BUSY            0x01   880 #define JEDEC_STATUS_WRITEPROTECT    0x02   881 #define JEDEC_STATUS_BP0             0x04   882 #define JEDEC_STATUS_BP1             0x08   883 #define JEDEC_STATUS_BP2             0x10   884 #define JEDEC_STATUS_TP              0x20   885 #define JEDEC_STATUS_SEC             0x40   886 #define JEDEC_STATUS_SRP0            0x80   891 #define MAX_ERASE_SIZE 16384   893 static bool flash_died=
false;
   894 static uint8_t df_manufacturer;
   895 static uint16_t df_device;
   897 static uint8_t addr_cmd_length = 4;
   898 static uint8_t addr_cmd_start = 1;
   899 static bool  addr_4bit = 0;
   901  #if BOARD_DATAFLASH_ERASE_SIZE  >= 65536   923 #define FLASH_ERASE_QUEUE_SIZE 16   925 static void *_flash_erase_task 
IN_CCM;
   926 static volatile uint16_t fe_read_ptr 
IN_CCM;
   927 static volatile uint16_t fe_write_ptr 
IN_CCM;
   933 static fe_item flash_erase_queue[FLASH_ERASE_QUEUE_SIZE] 
IN_CCM;
   934 static void * _flash_erase_task 
IN_CCM;
   936 static void sd_flash_eraser();
   940 static bool chip_is_clear=
false;
   954 static inline uint8_t spi_write(
   961 static inline uint8_t spi_read(){
   966 static inline void read_spi_multi (
   976 static inline void write_spi_multi (
   987 void cs_release (
void)
  1007 static void ReadManufacturerID()
  1010     if (!cs_assert()) 
return;
  1017     df_manufacturer =  buf.cmd[0];
  1018     df_device       = (buf.cmd[1] << 8) | buf.cmd[2]; 
  1026 static uint8_t ReadStatusReg()
  1042 static uint8_t ReadStatus()
  1045     uint8_t status = ReadStatusReg();
  1054 static int wait_ready ( 
  1058     if(flash_died) 
return 0;
  1062         if(ReadStatus()==0) 
return 1; 
  1077 static void Flash_Jedec_WriteEnable(
void){ 
  1078     if (!wait_ready(500)) 
return;  
  1080     if (!cs_assert()) 
return;
  1086 static void Flash_Enter4B_Mode(){ 
  1087     if (!wait_ready(500)) 
return;  
  1089     if (!cs_assert()) 
return;
  1090     spi_write(JEDEC_ENTER_4B_MODE);
  1095 static bool read_page( uint8_t *ptr, uint32_t pageNum){
  1098     if (!wait_ready(500)) 
return 0;  
  1100     if (!cs_assert()) 
return 0;
  1107             buf.cmd[i++] = (PageAdr >> 24) & 0xff;
  1109         buf.cmd[i++] = (PageAdr >> 16) & 0xff;
  1110         buf.cmd[i++] = (PageAdr >>  8) & 0xff;
  1111         buf.cmd[i++] = (PageAdr >>  0) & 0xff;
  1114     spi_spiTransfer(&buf.cmd[0], addr_cmd_length, buf.sector, DF_PAGE_SIZE);
  1120         ptr[i] = ~buf.sector[i];    
  1128 static bool write_page(
const uint8_t *ptr, uint32_t pageNum){
  1134             buf.sector[i] = ~ptr[i];       
  1138     Flash_Jedec_WriteEnable();
  1140     if (!cs_assert()) 
return 0;
  1142     uint8_t i = addr_cmd_start;
  1146         buf.cmd[i++] = (PageAdr >> 24) & 0xff;
  1148     buf.cmd[i++] = (PageAdr >> 16) & 0xff;
  1149     buf.cmd[i++] = (PageAdr >>  8) & 0xff;
  1150     buf.cmd[i++] = (PageAdr >>  0) & 0xff;
  1153     write_spi_multi(&buf.cmd[addr_cmd_start], addr_cmd_length);
  1154     write_spi_multi(buf.sector, DF_PAGE_SIZE);
  1156     write_spi_multi(&buf.cmd[addr_cmd_start], addr_cmd_length + DF_PAGE_SIZE);
  1162 static bool erase_page(uint16_t pageNum)
  1165     Flash_Jedec_WriteEnable();
  1170     buf.cmd[i++] = erase_cmd;
  1172         buf.cmd[i++] = (PageAdr >> 24) & 0xff;
  1174     buf.cmd[i++] = (PageAdr >> 16) & 0xff;
  1175     buf.cmd[i++] = (PageAdr >>  8) & 0xff;
  1176     buf.cmd[i++] = (PageAdr >>  0) & 0xff;
  1178     if (!cs_assert()) 
return 0;
  1179     write_spi_multi(buf.cmd, addr_cmd_length);
  1184 static void ChipErase()
  1189     Flash_Jedec_WriteEnable();
  1191     if (!cs_assert()) 
return;
  1193     write_spi_multi(buf.cmd, 1);    
  1202     uint8_t capacity = df_device & 0xFF;
  1203     uint8_t memtype =  (df_device>>8) & 0xFF;
  1206     const char * mfg=
NULL;
  1208     switch(df_manufacturer){
  1210         if (memtype == 0x40) {
  1212             size = (1 << ((capacity & 0x0f) + 8));
  1223         if (memtype == 0x25) {
  1225             size = (1 << ((capacity & 0x07) + 12));
  1230         if (memtype == 0xba){
  1232             size = (1 << ((capacity & 0x0f) + 8));
  1235         } 
else if(memtype==0x20) {  
  1237             size = (1 << ((capacity & 0x0f) + 8));
  1242         if (memtype == 0x20) { 
  1244             size = (1 << ((capacity & 0x0f) + 8));
  1251         if (memtype == 0x40 || memtype == 0x30) {
  1253             size      = (1 << ((capacity & 0x0f) + 8));
  1262         printf(
"%s SPI Flash found sectors=%ld\n", mfg, size);
  1264         printf(
"unknown Flash! mfg=%x type=%x cap=%x\n ",df_manufacturer, memtype, capacity);
  1269         addr_cmd_length = 5;
  1272         Flash_Enter4B_Mode();
  1275     if(erase_size > MAX_ERASE_SIZE)   size -= (erase_size/
DF_PAGE_SIZE); 
  1295     static bool initialized=0;
  1297     if(initialized) 
return Stat;
  1299     ReadManufacturerID();
  1340         if(!read_page(buff, sector)) 
break;
  1355 bool sd_move_block(uint32_t sec_from, uint32_t sec_to, 
const uint8_t *buff, uint32_t sec, uint16_t count);
  1364 bool sd_move_block(uint32_t sec_from, uint32_t sec_to, 
const uint8_t *buff, uint32_t sec, uint16_t count){
  1366     if(!erase_page(sec_to)) 
return RES_ERROR;
  1368     uint8_t *sbuffer = 
malloc(DF_PAGE_SIZE); 
  1369     if(!sbuffer) 
return false;
  1373     for(cnt=erase_size/DF_PAGE_SIZE; cnt>0; cnt--){
  1374         if(buff && sec_from >= sec && sec_from < (sec + count) ) { 
  1375             memcpy(sbuffer, buff, DF_PAGE_SIZE);       
  1378             if(!read_page(sbuffer, sec_from)) 
break;
  1380         if(!write_page(sbuffer, sec_to)) 
break;
  1392     const uint8_t *buff,    
  1406             if(!erase_page(sector)) 
return RES_ERROR;
  1408                 if(!write_page(buff, sector)) 
break;
  1415             bool need_erase = 
false; 
  1423                 uint32_t r_sector = sector;
  1424                 uint16_t r_count  = 
count;
  1430                 if(!read_page(ptr, r_sector)) 
break;
  1452                 uint8_t *cluster = 
malloc(erase_size);
  1454                     if(erase_size <= MAX_ERASE_SIZE) 
return RES_ERROR; 
  1463                     if(!sd_move_block(r_sector, fr_sec, 
NULL, 0, 0)) 
return RES_ERROR; 
  1475                     uint32_t w_sector = r_sector;
  1479                     if(!read_page(ptr, r_sector)) 
break;
  1495                     if(!read_page(ptr, r_sector)) 
break;
  1504                     if(!erase_page(w_sector)) 
return RES_ERROR;
  1509                         if(!write_page(ptr, w_sector)) 
break;
  1523                 if(!write_page(buff, sector)) 
break;
  1541     int16_t new_wp = fe_write_ptr+1;
  1542     if(new_wp >= FLASH_ERASE_QUEUE_SIZE) { 
  1545     while(new_wp == fe_read_ptr) 
hal_yield(0); 
  1547     flash_erase_queue[fe_write_ptr].b = from;
  1548     flash_erase_queue[fe_write_ptr].e = to;
  1550     fe_write_ptr=new_wp; 
  1563     uint8_t *ptr = (uint8_t *)buff;
  1577              *(ptr + 1) = (uint8_t) 
MMC_CD;
  1609         uint32_t  start_sector = ((uint32_t  *)buff)[0];
  1610         uint32_t  end_sector   = ((uint32_t  *)buff)[1];
  1611         uint32_t  block, last_block=-1;
  1616                 chip_is_clear=
false;
  1622 #if 0 // in separate thread  1629         for(sector=start_sector; sector <= end_sector;sector++){
  1632                 if(last_block!=block){
  1634                     if(!erase_page(df_sect)) 
return RES_ERROR;                    
  1679 #endif //defined(BOARD_DATAFLASH_FATFS) 
void(* voidFuncPtr)(void)
 
void putch(unsigned char c)
 
int printf(const char *msg,...)
 
static volatile uint16_t Timer2
 
#define HAL_GPIO_A_LED_PIN
 
static uint64_t systick_uptime(void)
Returns the system uptime, in milliseconds. 
 
uint8_t(* spi_WaitFunc)(uint8_t b)
 
void hal_set_task_priority(void *handle, uint8_t prio)
 
#define JEDEC_STATUS_BUSY
 
void * hal_register_task(voidFuncPtr task, uint32_t stack)
 
DRESULT sd_write(const uint8_t *buff, uint32_t sector, uint16_t count)
 
#define BOARD_DATAFLASH_PAGES
 
static volatile uint16_t Timer1
 
void digitalToggle(uint8_t pin)
 
DRESULT sd_read(uint8_t *buff, uint32_t sector, uint16_t count)
 
#define JEDEC_WRITE_ENABLE
 
#define BOARD_DATAFLASH_ERASE_SIZE
 
DRESULT sd_ioctl(uint8_t cmd, void *buff)
 
uint8_t spi_waitFor(uint8_t out, spi_WaitFunc cb, uint32_t dly)
 
bool spi_chipSelectLow(bool take_sem)
 
void hal_set_task_active(void *handle)
 
#define JEDEC_SECTOR_ERASE
 
static volatile DSTATUS Stat
 
uint8_t spi_spiRecv(void)
 
uint8_t sd_getSectorCount(uint32_t *ptr)
 
void spi_chipSelectHigh(void)
 
void * malloc(size_t size)
 
void hal_context_switch_isr()
 
uint8_t spi_spiSend(uint8_t b)
 
static uint32_t sd_max_sectors
 
#define JEDEC_READ_STATUS
 
void spi_spiTransfer(const uint8_t *send, uint32_t send_len, uint8_t *recv, uint32_t recv_len)
 
void enqueue_flash_erase(uint32_t from, uint32_t to)
 
uint8_t spi_spiXchg(uint8_t b)
 
static INLINE uint32_t timer_get_count32(const timer_dev *dev)
 
void hal_yield(uint16_t ttw)