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)