APM:Libraries
sd.c
Go to the documentation of this file.
1 #pragma GCC optimize ("O2")
2 
3 
4 /*
5 (c) 2017 night_ghost@ykoctpa.ru
6 
7  SD card and Dataflash low-level driver
8 
9 
10 */
11 
12 #include "sd.h"
13 #include "../diskio.h"
14 #include "../ff.h"
15 #include <stdlib.h>
16 #include <stdint.h>
17 #include <syscalls.h>
18 
19 
20 #define CS_HIGH() spi_chipSelectHigh()
21 #define CS_LOW() spi_chipSelectLow(1)
22 #define MMC_CD spi_detect() /* Card detect (yes:true, no:false, default:true) */
23 #define MMC_WP 0 /* Write protected (yes:true, no:false, default:false) */
24 
25 
26 
27 /*--------------------------------------------------------------------------
28 
29  Module Private Functions
30 
31 ---------------------------------------------------------------------------*/
32 
33 
34 /* MMC/SD command */
35 #define CMD0 (0) /* GO_IDLE_STATE */
36 #define CMD1 (1) /* SEND_OP_COND (MMC) */
37 #define ACMD41 (0x80+41) /* SEND_OP_COND (SDC) */
38 #define CMD8 (8) /* SEND_IF_COND */
39 #define CMD9 (9) /* SEND_CSD */
40 #define CMD10 (10) /* SEND_CID */
41 #define CMD12 (12) /* STOP_TRANSMISSION */
42 #define CMD13 (13) /* Get_STATUS */
43 #define ACMD13 (0x80+13) /* SD_STATUS (SDC) */
44 #define CMD16 (16) /* SET_BLOCKLEN */
45 #define CMD17 (17) /* READ_SINGLE_BLOCK */
46 #define CMD18 (18) /* READ_MULTIPLE_BLOCK */
47 #define CMD23 (23) /* SET_BLOCK_COUNT (MMC) */
48 #define ACMD23 (0x80+23) /* SET_WR_BLK_ERASE_COUNT (SDC) */
49 #define CMD24 (24) /* WRITE_BLOCK */
50 #define CMD25 (25) /* WRITE_MULTIPLE_BLOCK */
51 #define CMD32 (32) /* ERASE_ER_BLK_START */
52 #define CMD33 (33) /* ERASE_ER_BLK_END */
53 #define CMD38 (38) /* ERASE */
54 #define CMD55 (55) /* APP_CMD */
55 #define CMD58 (58) /* READ_OCR */
56 
57 
58 static inline uint32_t micros() { return timer_get_count32(TIMER5); }
59 
60 static inline uint32_t millis() { return systick_uptime(); }
61 
62 typedef uint8_t (*spi_WaitFunc)(uint8_t b);
63 
64 // utility function
65 extern uint8_t spi_spiSend(uint8_t b);
66 extern uint8_t spi_spiRecv(void);
67 extern uint8_t spi_spiXchg(uint8_t b);
68 extern void spi_spiTransfer(const uint8_t *send, uint32_t send_len, uint8_t *recv, uint32_t recv_len);
69 extern void spi_chipSelectHigh(void);
70 extern bool spi_chipSelectLow(bool take_sem);
71 extern void spi_yield();
72 extern uint8_t spi_waitFor(uint8_t out, spi_WaitFunc cb, uint32_t dly);
73 extern uint8_t spi_detect();
74 extern uint32_t get_fattime ();
75 
76 
77 static volatile DSTATUS Stat = STA_NOINIT; /* Physical drive status */
78 
79 static volatile uint16_t Timer1, Timer2; /* 1kHz decrement timer stopped at zero (disk_timerproc()) */
80 static uint32_t sd_max_sectors=0;
81 
82 
83 
84 extern int printf(const char *msg, ...);
85 
86 #if defined(BOARD_SDCARD_CS_PIN)
87 
88 #define WAIT_IN_ISR
89 
90 static uint8_t CardType; /* Card type flags */
91 static uint8_t no_CMD13 = 0;
92 static uint8_t csd[16]; // for DMA reads
93 
94 static int8_t xmit_datablock(const uint8_t *buff, uint8_t token);
95 
96 
97 uint8_t sd_get_type() {
98  return CardType;
99 }
100 
101 /*-----------------------------------------------------------------------*/
102 /* SPI controls (Platform dependent) */
103 /*-----------------------------------------------------------------------*/
104 
105 /* Initialize MMC interface */
106 
107 
108 /* Exchange a byte */
109 static inline
110 uint8_t xchg_spi (
111  uint8_t dat /* Data to send */
112 )
113 {
114  return spi_spiXchg(dat);
115 }
116 
117 static inline
118 uint8_t rcvr_spi(){
119  return xchg_spi(0xFF);
120 }
121 
122 /* Receive multiple byte */
123 static inline
124 void rcvr_spi_multi (
125  uint8_t *buff, /* Pointer to data buffer */
126  uint16_t btr /* Number of bytes to receive (even number) */
127 ){
128  spi_spiTransfer(NULL,0, buff, btr);
129 }
130 
131 
132 /* Send multiple byte */
133 static inline
134 void xmit_spi_multi (
135  const uint8_t *buff, /* Pointer to the data */
136  uint16_t btx /* Number of bytes to send (even number) */
137 )
138 {
139  spi_spiTransfer(buff, btx, NULL, 0);
140 }
141 
142 /*
143 void power_on(void){ // Power on the SD-Card Socket if hardware allows
144 }
145 
146 void power_off(void){
147 }
148 */
149 
150 
151 
152 /*-----------------------------------------------------------------------*/
153 /* Wait for card ready */
154 /*-----------------------------------------------------------------------*/
155 
156 // TODO: remove all active waiting by transferring check to callback
157 
158 static uint8_t wait_ff(uint8_t b){
159  return b==0xff;
160 }
161 
162 static
163 int wait_ready ( /* 1:Ready, 0:Timeout */
164  uint16_t wt /* Timeout [ms] */
165 )
166 {
167  uint8_t d;
168 
169 
170 #if defined(WAIT_IN_ISR)
171  d=spi_waitFor(0xFF,wait_ff,wt*1000);
172 
173  return d == 0xFF;
174 #else
175 
176  Timer2 = wt;
177  do {
178  d = xchg_spi(0xFF);
179  spi_yield(); /* This loop takes a time. Insert rot_rdq() here for multitask envilonment. */
180  } while (d != 0xFF && Timer2); /* Wait for card goes ready or timeout */
181 
182  if(d == 0xFF) {
183  return 1;
184  }
185  return 0;
186 #endif
187 }
188 
189 
190 
191 /*-----------------------------------------------------------------------*/
192 /* Deselect card and release SPI */
193 /*-----------------------------------------------------------------------*/
194 
195 static
196 void deselect_cs (void)
197 {
198  CS_HIGH(); /* Set CS# high */
199  xchg_spi(0xFF); /* Dummy clock (force DO hi-z for multiple slave SPI) */
200 }
201 
202 
203 
204 /*-----------------------------------------------------------------------*/
205 /* Select card and wait for ready */
206 /*-----------------------------------------------------------------------*/
207 
208 static
209 int select_cs (void) /* 1:OK, 0:Timeout */
210 {
211  if(!CS_LOW()) { /* take semaphore and Set CS# low */
212  return 0;
213  }
214  xchg_spi(0xFF); /* Dummy clock (force DO enabled) */
215  if (wait_ready(500)) return 1; /* Wait for card ready */
216 
217  deselect_cs();
218  return 0; /* Timeout */
219 }
220 
221 
222 
223 /*-----------------------------------------------------------------------*/
224 /* Receive a data packet from the MMC */
225 /*-----------------------------------------------------------------------*/
226 
227 static uint8_t wait_noFF(uint8_t b){
228  return b!=0xff;
229 }
230 
231 
232 static
233 int8_t rcvr_datablock ( /* 1:OK, 0:Error */
234  uint8_t *buff, /* Data buffer */
235  uint16_t btr /* Data block length (byte) */
236 )
237 {
238  uint8_t ret=0;
239 
240 #if defined(WAIT_IN_ISR)
241  ret=spi_waitFor(0xff, wait_noFF, 200000);
242 
243  if(ret != 0xFE) goto done; // Function fails if invalid DataStart token or timeout
244 #else
245  uint8_t token;
246 
247  Timer1 = 200;
248  do { /* Wait for DataStart token in timeout of 200ms */
249  token = xchg_spi(0xFF);
250  spi_yield(); /* This loop will take a time. Insert rot_rdq() here for multitask environment. */
251  } while ((token == 0xFF) && Timer1);
252 
253  if(token != 0xFE) {
254  goto done; /* Function fails if invalid DataStart token or timeout */
255  }
256 #endif
257  rcvr_spi_multi(buff, btr); /* Store trailing data to the buffer */
258  xchg_spi(0xFF); xchg_spi(0xFF); /* Discard CRC */
259 
260  ret=1; /* Function succeeded */
261 done:
262  return ret;
263 }
264 
265 
266 
267 /*-----------------------------------------------------------------------*/
268 /* Send a data packet to the MMC */
269 /*-----------------------------------------------------------------------*/
270 
271 static int8_t xmit_datablock ( /* 1:OK, 0:Failed */
272  const uint8_t *buff, /* Ponter to 512 byte data to be sent */
273  uint8_t token /* Token */
274 )
275 {
276  uint8_t resp;
277 
278 
279  if (!wait_ready(500)) return 0; /* Wait for card ready */
280 
281  xchg_spi(token); /* Send token */
282  if (token != 0xFD) { /* Send data if token is other than StopTran */
283  xmit_spi_multi(buff, 512); /* Data */
284  xchg_spi(0xFF); xchg_spi(0xFF); /* Dummy CRC */
285 
286  resp = xchg_spi(0xFF); /* Receive data resp */
287  if ((resp & 0x1F) != 0x05) {
288  return 0; /* Function fails if the data packet was not accepted */
289  }
290  }
291  return 1;
292 }
293 
294 
295 /*-----------------------------------------------------------------------*/
296 /* Send a command packet to the MMC */
297 /*-----------------------------------------------------------------------*/
298 static uint8_t buf[6]; // to use DMA
299 
300 static uint8_t wait_0x80(uint8_t b){
301  return (b & 0x80)==0;
302 }
303 
304 
305 static
306 uint8_t send_cmd ( /* Return value: R1 resp (bit7==1:Failed to send) */
307  uint8_t cmd, /* Command index */
308  uint32_t arg /* Argument */
309 )
310 {
311  uint8_t crc, res;
312 
313 
314  if (cmd & 0x80) { /* Send a CMD55 prior to ACMD<n> */
315  cmd &= 0x7F;
316  res = send_cmd(CMD55, 0);
317  if (res > 1) {
318  return res;
319  }
320  }
321 
322  /* Select the card and wait for ready except to stop multiple block read */
323  if (cmd != CMD12) {
324  deselect_cs();
325 // spi_yield(); // sync quant so no interrupts when receiving answer
326  if (!select_cs()) {
327  return 0xFF;
328  }
329  }
330 
331  crc = 0x01; /* Dummy CRC + Stop */
332  if (cmd == CMD0) crc = 0x95; /* Valid CRC for CMD0(0) */
333  if (cmd == CMD8) crc = 0x87; /* Valid CRC for CMD8(0x1AA) */
334 
335 
336  /* Send command packet */
337  buf[0] = 0x40 | cmd; /* Start + command index */
338  buf[1] = (uint8_t)(arg >> 24); /* Argument[31..24] */
339  buf[2] = (uint8_t)(arg >> 16); /* Argument[23..16] */
340  buf[3] = (uint8_t)(arg >> 8); /* Argument[15..8] */
341  buf[4] = (uint8_t)arg; /* Argument[7..0] */
342  buf[5] = crc; /* CRC + Stop */
343 
344  xmit_spi_multi(buf, 6); // entire command in one packet
345 
346  /* Receive command resp */
347  if (cmd == CMD12) xchg_spi(0xFF); /* Discard following one byte when CMD12 */
348 
349 #if defined(WAIT_IN_ISR)
350  res=spi_waitFor(0xff, wait_0x80, 20000);
351 
352  return res;
353 
354 #else
355 
356  uint8_t n = 255; /* Wait for response (10 bytes max) */
357  do {
358  res = xchg_spi(0xFF);
359  spi_yield(); /* This loop will take a time. Insert rot_rdq() here for multitask environment. */
360  } while ((res & 0x80) && --n);
361 
362  return res; /* Return received response */
363 #endif
364 }
365 
366 
367 
368 /*--------------------------------------------------------------------------
369 
370  Public Functions
371 
372 ---------------------------------------------------------------------------*/
373 
374 
375 /*-----------------------------------------------------------------------*/
376 /* Initialize disk drive */
377 /*-----------------------------------------------------------------------*/
378 
380  uint8_t n, cmd, ty, ocr[4] ;
381 
382  if (Stat & STA_NODISK) return Stat; /* Is card existing in the soket? */
383  if(!(Stat & STA_NOINIT) ) return Stat; // already done
384 
385 
386  ty = 0;
387  n = send_cmd(CMD0, 0);
388  if (n == 1 || n==0) { /* Put the card SPI/Idle state */
389  Timer1 = 5000;
390  n=send_cmd(CMD8, 0x1AA); /* Initialization timeout = 5 sec */
391  if((n&4) == 0) rcvr_spi_multi(ocr, 4); /* Get 32 bit return value of R7 resp if not illegal command */
392  if (n == 1) { /* SDv2? */
393  if (ocr[2] == 0x01 && ocr[3] == 0xAA) { /* Is the card supports vcc of 2.7-3.6V? and did echoing */
394  while(Timer1){ /* Wait for end of initialization with ACMD41(HCS) */
395  n = send_cmd(ACMD41, 1UL << 30);
396  if(n==0) break;
397  }
398  if (Timer1){
399  n = send_cmd(CMD58, 0);
400  if((n&4) == 0) rcvr_spi_multi(ocr, 4); /* Get 32 bit return value of R7 resp if not illegal command */
401  if( n <= 1) { /* Check CCS bit in the OCR */
402  ty = (ocr[0] & 0x40) ? CT_SD2 | CT_BLOCK : CT_SD2; /* Card id SDv2 */
403  } else {
404  printf("\nSD CMD58 failed!\n");
405  }
406  }else{
407  printf("\nSD timeout!\n");
408  }
409  }
410  } else { /* Not SDv2 card */
411  if (send_cmd(ACMD41, 0) <= 1) { /* SDv1 or MMC? */
412  ty = CT_SD1; cmd = ACMD41; /* SDv1 (ACMD41(0)) */
413  } else {
414  ty = CT_MMC; cmd = CMD1; /* MMCv3 (CMD1(0)) */
415  }
416  while(Timer1) { /* Wait for end of initialization */
417  n=send_cmd(cmd, 0);
418  if(n==0) break;
419  }
420 
421  if (Timer1){
422  if(send_cmd(CMD16, 512) != 0) { /* Set block length: 512 */
423  ty = 0;
424  printf("\nSD CMD16 failed!\n");
425  }
426  } else {
427  ty = 0;
428  printf("\nSD timeout!\n");
429  }
430  }
431  } else {
432  ty=0;
433  }
434  CardType = ty; /* Card type */
435 
436  if (ty) { /* OK */
437  Stat &= ~STA_NOINIT; /* Clear STA_NOINIT flag */
438  uint8_t i;
439  for(i=0;i<15;i++){ // 15 tries to get size
441  if(sd_max_sectors!=0) break;
442  }
443  } else { /* Failed */
444  Stat = STA_NOINIT;
445  }
446 
447  deselect_cs();
448 
449  return Stat;
450 }
451 
452 static uint8_t restart_card(){
453  Stat = STA_NOINIT;
454 
455  sd_initialize();
456 
457  if(!(Stat & STA_NOINIT) ) return true; // OK
458  return false;
459 }
460 
461 uint8_t sd_getSectorCount(uint32_t *ptr){
462  uint32_t csize;
463 
464  if ((send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16)) {
465  if ((csd[0] >> 6) == 1) { /* SDC ver 2.00 */
466  csize = csd[9] + ((uint16_t)csd[8] << 8) + ((uint32_t)(csd[7] & 63) << 16) + 1;
467  *ptr = csize << 10;
468  } else { /* SDC ver 1.XX or MMC ver 3 */
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);
472  }
473 
474  return RES_OK;
475  }
476  return RES_ERROR;
477 
478 }
479 
480 /*-----------------------------------------------------------------------*/
481 /* Get disk status */
482 /*-----------------------------------------------------------------------*/
483 
484 DSTATUS sd_status (){
485 
486  return Stat; /* Return disk status */
487 }
488 
489 uint8_t sd_get_state(){
490  if(!no_CMD13) {
491  if(send_cmd(CMD13, 0)<=1){
492  uint8_t ret = xchg_spi(0xFF);
493  return ret;
494  }
495 
496  no_CMD13=1;
497  }
498 
499  return 0; // CMD13 not supported so all OK
500 
501 /*
502 7 - out of range / CSD overwrite
503 6 • Erase param: An invalid selection for erase, sectors or groups.
504 5 • Write protect violation: The command tried to write a write-protected block.
505 4 • Card ECC failed: Card internal ECC was applied but failed to correct the data.
506 3 • CC error: Internal card controller error.
507 2 • Error: A general or an unknown error occurred during the operation.
508 1 • Write protect erase skip | lock/unlock command failed: This status bit has two functions over-
509 loaded. It is set when the host attempts to erase a write-protected sector or makes a sequence or
510 password errors during card lock/unlock operation.
511 0 • Card is locked: Set when the card is locked by the user. Reset when it is unlocked.
512 
513 */
514 
515 }
516 
517 
518 /*-----------------------------------------------------------------------*/
519 /* Read sector(s) */
520 /*-----------------------------------------------------------------------*/
521 
522 static bool single_sector_card=false;
523 
524 
526  uint8_t *buff, /* Pointer to the data buffer to store read data */
527  uint32_t sector, /* Start sector number (LBA) */
528  uint16_t count /* Number of sectors to read (1..128) */
529 )
530 {
531  uint8_t ret;
532  uint16_t sectorInc=1;
533 
534  if (!count) return RES_PARERR; /* Check parameter */
535  if (Stat & STA_NOINIT) return RES_NOTRDY; /* Check if drive is ready */
536 
537  if(sd_max_sectors && sector > sd_max_sectors) return RES_PARERR; /* Check parameter */
538 
539  if (!(CardType & CT_BLOCK)) {
540  sectorInc = 512;
541  sector *= sectorInc; /* LBA to BA conversion (byte addressing cards) */
542  }
543 
544 
545  if (count == 1) { /* Single sector read */
546  if (( (ret=send_cmd(CMD17, sector)) == 0) /* READ_SINGLE_BLOCK */
547  && rcvr_datablock(buff, 512)) {
548  count = 0;
549  }
550 
551  } else { /* Multiple sector read */
552  if(single_sector_card) {
553  do {
554  if ((ret=send_cmd(CMD17, sector)) == 0){ /* READ_SINGLE_BLOCK */
555  if(rcvr_datablock(buff, 512)) {
556  buff += 512;
557  sector += sectorInc;
558  } else {
559  break;
560  }
561  } else {
562  break;
563  }
564  deselect_cs();
565  spi_yield();
566  } while(--count);
567 
568  } else {
569 // send_cmd(CMD23, count);
570  if (CardType & CT_SDC) send_cmd(ACMD23, count); /* Predefine number of sectors */
571 
572  uint16_t got=0;
573  if ((ret=send_cmd(CMD18, sector)) == 0) { /* READ_MULTIPLE_BLOCK */
574  do {
575  if (!rcvr_datablock(buff, 512)) {
576  break;
577  }
578  got++;
579  buff += 512;
580  } while (--count);
581  if(got) send_cmd(CMD12, 0); /* STOP_TRANSMISSION */
582 
583  }
584  if(count) { // readed only 1 block or none
585  single_sector_card=true;
586  sector+=got*sectorInc;
587  restart_card();
588  return sd_read(buff, sector/sectorInc, count); // read remaining in single sector mode
589  }
590  }
591  }
592  deselect_cs();
593  if(count==0) return RES_OK; /* Return result */
594  Stat = STA_NOINIT;
595  return RES_ERROR;
596 }
597 
598 
599 
600 /*-----------------------------------------------------------------------*/
601 /* Write sector(s) */
602 /*-----------------------------------------------------------------------*/
603 
605  const uint8_t *buff, /* Ponter to the data to write */
606  uint32_t sector, /* Start sector number (LBA) */
607  uint16_t count /* Number of sectors to write (1..128) */
608 )
609 {
610  if (!count) return RES_PARERR; /* Check parameter */
611  if (Stat & STA_NOINIT) return RES_NOTRDY; /* Check drive status */
612  if (Stat & STA_PROTECT) return RES_WRPRT; /* Check write protect */
613  if(sd_max_sectors && sector > sd_max_sectors) return RES_PARERR; /* Check parameter */
614 
615  uint16_t sectorInc = 1;
616 
617 
618  if (!(CardType & CT_BLOCK)){
619  sectorInc = 512;
620  sector *= sectorInc; /* LBA ==> BA conversion (byte addressing cards) */
621  }
622 
623  if (count == 1) { /* Single sector write */
624  if (send_cmd(CMD24, sector) == 0) { /* WRITE_BLOCK */
625  if( xmit_datablock(buff, 0xFE)) {
626  count = 0;
627  }
628  }
629  }
630  else {
631  if(single_sector_card) {
632  do {
633  if ((send_cmd(CMD24, sector) == 0) /* WRITE_BLOCK */
634  && xmit_datablock(buff, 0xFE)) {
635  sector+=sectorInc;
636  buff += 512;
637  } else break; // error
638  } while(--count);
639  } else {
640  /* Multiple sector write */
641  if (CardType & CT_SDC) send_cmd(ACMD23, count); /* Predefine number of sectors */
642  uint32_t sent=0;
643  if (send_cmd(CMD25, sector) == 0) { /* WRITE_MULTIPLE_BLOCK */
644  do {
645  if (!xmit_datablock(buff, 0xFC)) break;
646  buff += 512;
647  sent++;
648  } while (--count);
649  if (!xmit_datablock(0, 0xFD)) count = 1; /* STOP_TRAN token */
650  }
651  if(count) {
652  single_sector_card=true;
653  sector+=sent*sectorInc;
654  restart_card();
655  return sd_write(buff, sector/sectorInc, count); // write remaining in single sector mode
656  }
657  }
658  }
659 
660  if(count) {
661  deselect_cs();
662  Stat = STA_NOINIT;
663  return RES_ERROR;
664  }
665 
666  uint8_t ret = sd_get_state(); // reset errors
667 
668  deselect_cs();
669 
670  if(ret) return RES_ERROR;
671 
672  return RES_OK; /* Return result */
673 }
674 
675 
676 /*-----------------------------------------------------------------------*/
677 /* Miscellaneous drive controls other than data read/write */
678 /*-----------------------------------------------------------------------*/
679 
681  uint8_t cmd, /* Control command code */
682  void *buff /* Pointer to the conrtol data */
683 )
684 {
685  DRESULT res;
686  uint8_t n;
687  uint32_t *dp, st, ed;
688 
689  uint8_t *ptr = (uint8_t *)buff;
690 
691  res = RES_ERROR;
692 
693  if (cmd== CTRL_POWER){
694 
695  switch (*ptr) {
696  case 0: // Sub control code == 0 (POWER_OFF)
697 // if (SD_PRESENT())
698 // power_off(); // Power off
699  res = RES_OK;
700  break;
701  case 1: // Sub control code == 1 (POWER_ON)
702 // power_on(); // Power on
703  res = RES_OK;
704  break;
705  case 2: // Sub control code == 2 (POWER_GET)
706  *(ptr + 1) = (uint8_t) MMC_CD;
707  break;
708  default:
709  res = RES_PARERR;
710  break;
711  }
712 
713  } else {
714 
715  if (Stat & STA_NOINIT) return RES_NOTRDY; /* Check if drive is ready */
716 
717  switch (cmd) {
718  case CTRL_SYNC : /* Wait for end of internal write process of the drive */
719  if (select_cs()) res = RES_OK;
720  break;
721 
722  case GET_SECTOR_COUNT : /* Get drive capacity in unit of sector (uint32_t) */
723  res=sd_getSectorCount((uint32_t*)buff);
724  break;
725 
726  case GET_BLOCK_SIZE : /* Get erase block size in unit of sector (uint32_t) */
727  if (CardType & CT_SD2) { /* SDC ver 2.00 */
728  if (send_cmd(ACMD13, 0) == 0) { /* Read SD status */
729  xchg_spi(0xFF);
730  if (rcvr_datablock(csd, 16)) { /* Read partial block */
731  for (n = 64 - 16; n; n--) xchg_spi(0xFF); /* Purge trailing data */
732  *(uint32_t*)buff = 16UL << (csd[10] >> 4);
733  res = RES_OK;
734  }
735  }
736  } else { /* SDC ver 1.XX or MMC */
737  if ((send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16)) { /* Read CSD */
738  if (CardType & CT_SD1) { /* SDC ver 1.XX */
739  *(uint32_t*)buff = (((csd[10] & 63) << 1) + ((uint16_t)(csd[11] & 128) >> 7) + 1) << ((csd[13] >> 6) - 1);
740  } else { /* MMC */
741  *(uint32_t*)buff = ((uint16_t)((csd[10] & 124) >> 2) + 1) * (((csd[11] & 3) << 3) + ((csd[11] & 224) >> 5) + 1);
742  }
743  res = RES_OK;
744  }
745  }
746  break;
747 
748  case CTRL_TRIM : /* Erase a block of sectors (used when _USE_ERASE == 1) */
749  if (!(CardType & CT_SDC)) break; /* Check if the card is SDC */
750  if (sd_ioctl(MMC_GET_CSD, csd)) break; /* Get CSD */
751  if (!(csd[0] >> 6) && !(csd[10] & 0x40)) break; /* Check if sector erase can be applied to the card */
752  dp = buff; st = dp[0]; ed = dp[1]; /* Load sector block */
753  if (!(CardType & CT_BLOCK)) {
754  st *= 512; ed *= 512;
755  }
756  if (send_cmd(CMD32, st) == 0 && send_cmd(CMD33, ed) == 0 && send_cmd(CMD38, 0) == 0 && wait_ready(30000)) { /* Erase sector block */
757  res = RES_OK; /* FatFs does not check result of this command */
758  }
759  break;
760 /*
761  case MMC_GET_TYPE: // Get card type flags (1 byte)
762  *ptr = g_card_type;
763  res = RES_OK;
764  break;
765 */
766  case MMC_GET_CSD: /* Receive CSD as a data block (16 bytes) */
767  if (send_cmd(CMD9, 0) == 0 /* READ_CSD */
768  && rcvr_datablock(ptr, 16))
769  res = RES_OK;
770  break;
771 
772  case MMC_GET_CID: /* Receive CID as a data block (16 bytes) */
773  if (send_cmd(CMD10, 0) == 0 /* READ_CID */
774  && rcvr_datablock(ptr, 16)){
775 /*
776  sdcard.manufacturerID = cid[0];
777  sdcard.oemID = (cid[1] << 8) | cid[2];
778  sdcard.productName[0] = cid[3];
779  sdcard.productName[1] = cid[4];
780  sdcard.productName[2] = cid[5];
781  sdcard.productName[3] = cid[6];
782  sdcard.productName[4] = cid[7];
783  sdcard.productRevisionMajor = cid[8] >> 4;
784  sdcard.productRevisionMinor = cid[8] & 0x0F;
785  sdcard.productSerial = (cid[9] << 24) | (cid[10] << 16) | (cid[11] << 8) | cid[12];
786  sdcard.productionYear = (((cid[13] & 0x0F) << 4) | (cid[14] >> 4)) + 2000;
787  sdcard.productionMonth = cid[14] & 0x0F;
788 */
789  res = RES_OK;
790  }
791  break;
792 
793  case MMC_GET_OCR: /* Receive OCR as an R3 resp (4 bytes) */
794  if (send_cmd(CMD58, 0) == 0) { /* READ_OCR */
795  // for (n = 4; n; n--) *ptr++ = rcvr_spi();
796  rcvr_spi_multi(ptr, 4);
797  res = RES_OK;
798  }
799  break;
800 
801  case MMC_GET_SDSTAT: /* Receive SD status as a data block (64 bytes) */
802  if (send_cmd(ACMD13, 0) == 0) { /* SD_STATUS */
803  rcvr_spi();
804  if (rcvr_datablock(ptr, 64))
805  res = RES_OK;
806  }
807  break;
808 
809  default:
810  res = RES_PARERR;
811  }
812 
813  deselect_cs();
814  }
815  return res;
816 }
817 
818 
819 /*-----------------------------------------------------------------------*/
820 /* Device timer function */
821 /*-----------------------------------------------------------------------*/
822 /* This function must be called from timer interrupt routine in period
823 / of 1 ms to generate card control timing.
824 */
825 
826 void sd_timerproc (void)
827 {
828  uint16_t n;
829  uint8_t s;
830 
831 
832  n = Timer1; /* 1kHz decrement timer stopped at 0 */
833  if (n) Timer1 = --n;
834  n = Timer2;
835  if (n) Timer2 = --n;
836 
837  s = Stat;
838  if (MMC_WP) { /* Write protected */
839  s |= STA_PROTECT;
840  } else { /* Write enabled */
841  s &= ~STA_PROTECT;
842  }
843  if (MMC_CD) { /* Card is in socket */
844  s &= ~STA_NODISK;
845  } else { /* Socket empty */
846  s |= (STA_NODISK | STA_NOINIT);
847  }
848  Stat = s;
849 }
850 
851 
852 #elif defined(BOARD_DATAFLASH_FATFS)
853 
854 // emulate SD card on board's dataflash
855 
856 // flash size
857 #define DF_NUM_PAGES 0x1f00
858 #define DF_PAGE_SIZE 256L
859 
860 #define DF_RESET BOARD_DATAFLASH_CS_PIN
861 
862 //Winbond M25P16 Serial Flash Embedded Memory 16 Mb, 3V
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
871 
872 #define JEDEC_WREAR 0xC5
873 #define JEDEC_ENTER_4B_MODE 0xB7
874 
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
878 
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
887 
888 //#define expect_memorytype 0x20
889 //#define expect_capacity 0x15
890 
891 #define MAX_ERASE_SIZE 16384
892 
893 static bool flash_died=false;
894 static uint8_t df_manufacturer;
895 static uint16_t df_device;
896 static uint32_t erase_size = BOARD_DATAFLASH_ERASE_SIZE;
897 static uint8_t addr_cmd_length = 4;
898 static uint8_t addr_cmd_start = 1;
899 static bool addr_4bit = 0;
900 
901  #if BOARD_DATAFLASH_ERASE_SIZE >= 65536
902  static uint8_t erase_cmd=JEDEC_PAGE_ERASE;
903  #else
904  static uint8_t erase_cmd=JEDEC_SECTOR_ERASE;
905  #endif
906 
907 #pragma pack(push,1)
908 static struct {
909  uint8_t cmd[5]; // for DMA transfer
910  uint8_t sector[DF_PAGE_SIZE]; // we ALWAYS can use DMA!
911 } buf;
912 #pragma pack(pop)
913 
914 
915 //[ task management for USB MSC mode
916 void hal_set_task_active(void * handle);
918 void *hal_register_task(voidFuncPtr task, uint32_t stack);
919 void hal_set_task_priority(void * handle, uint8_t prio);
920 bool hal_is_armed();
921 //]
922 
923 #define FLASH_ERASE_QUEUE_SIZE 16
924 
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;
928 typedef struct {
929  uint32_t b;
930  uint32_t e;
931 } fe_item;
932 
933 static fe_item flash_erase_queue[FLASH_ERASE_QUEUE_SIZE] IN_CCM;
934 static void * _flash_erase_task IN_CCM;
935 
936 static void sd_flash_eraser();
937 
938 
939 
940 static bool chip_is_clear=false;
941 
942 uint8_t sd_get_type() {
943  return 0;
944 }
945 
946 /*-----------------------------------------------------------------------*/
947 /* SPI controls (Platform dependent) */
948 /*-----------------------------------------------------------------------*/
949 
950 /* Initialize MMC interface */
951 
952 
953 /* Exchange a byte */
954 static inline uint8_t spi_write(
955  uint8_t dat /* Data to send */
956 )
957 {
958  return spi_spiXchg(dat);
959 }
960 
961 static inline uint8_t spi_read(){
962  return spi_spiXchg(0xFF);
963 }
964 
965 /* Receive multiple byte */
966 static inline void read_spi_multi (
967  uint8_t *buff, /* Pointer to data buffer */
968  uint16_t btr /* Number of bytes to receive (even number) */
969 ){
970 
971  spi_spiTransfer(NULL,0, buff, btr);
972 }
973 
974 
975 /* Send multiple byte */
976 static inline void write_spi_multi (
977  const uint8_t *buff, /* Pointer to the data */
978  uint16_t btx /* Number of bytes to send (even number) */
979 )
980 {
981 
982  spi_spiTransfer(buff, btx,NULL, 0);
983 }
984 
985 
986 static inline
987 void cs_release (void)
988 {
989  CS_HIGH(); /* Set CS# high */
990 }
991 
992 
993 
994 
995 static
996 bool cs_assert(void) /* 1:OK, 0:Timeout */
997 {
998  if(!CS_LOW()) { /* take semaphore and Set CS# low */
999  return 0;
1000  }
1001  return 1;
1002 }
1003 
1004 
1005 
1006 // This function is mainly to test the device
1007 static void ReadManufacturerID()
1008 {
1009  // activate dataflash command decoder
1010  if (!cs_assert()) return;
1011 
1012  // Read manufacturer and ID command...
1013  buf.cmd[0] = JEDEC_DEVICE_ID;
1014 
1015  spi_spiTransfer(buf.cmd, 1, buf.cmd, addr_cmd_length);
1016 
1017  df_manufacturer = buf.cmd[0];
1018  df_device = (buf.cmd[1] << 8) | buf.cmd[2]; //capacity
1019 
1020  // release SPI bus for use by other sensors
1021  cs_release();
1022 }
1023 
1024 
1025 // Read the status register
1026 static uint8_t ReadStatusReg()
1027 {
1028  uint8_t tmp;
1029 
1030  if (!cs_assert()) return JEDEC_STATUS_BUSY;
1031 
1032  // Read status command
1033  buf.cmd[0] = JEDEC_READ_STATUS;
1034 
1035  spi_spiTransfer(buf.cmd, 1, &buf.cmd[1], 1);
1036  tmp = buf.cmd[1];
1037 
1038  cs_release();
1039  return tmp;
1040 }
1041 
1042 static uint8_t ReadStatus()
1043 {
1044  // We only want to extract the READY/BUSY bit
1045  uint8_t status = ReadStatusReg();
1046 
1047  return status & JEDEC_STATUS_BUSY;
1048 }
1049 
1050 /*-----------------------------------------------------------------------*/
1051 // Wait for dataflash
1052 /*-----------------------------------------------------------------------*/
1053 
1054 static int wait_ready ( /* 1:Ready, 0:Timeout */
1055  uint16_t wt /* Timeout [ms] */
1056 )
1057 {
1058  if(flash_died) return 0;
1059 
1060  Timer2 = wt;
1061  do {
1062  if(ReadStatus()==0) return 1; //ready
1063 
1064  spi_yield(); /* This loop takes a time. Insert rot_rdq() here for multitask envilonment. */
1065  } while(Timer2); /* Wait for card goes ready or timeout */
1066 
1067  flash_died = true;
1068 
1069  return 0;
1070 }
1071 
1072 
1073 
1074 
1075 
1076 
1077 static void Flash_Jedec_WriteEnable(void){
1078  if (!wait_ready(500)) return; /* Wait for card ready */
1079 
1080  if (!cs_assert()) return;
1081  spi_write(JEDEC_WRITE_ENABLE);
1082  cs_release();
1083 }
1084 
1085 
1086 static void Flash_Enter4B_Mode(){
1087  if (!wait_ready(500)) return; /* Wait for card ready */
1088 
1089  if (!cs_assert()) return;
1090  spi_write(JEDEC_ENTER_4B_MODE);
1091  cs_release();
1092 }
1093 
1094 
1095 static bool read_page( uint8_t *ptr, uint32_t pageNum){
1096  uint32_t PageAdr = pageNum * DF_PAGE_SIZE;
1097 
1098  if (!wait_ready(500)) return 0; /* Wait for card ready */
1099 
1100  if (!cs_assert()) return 0;
1101 
1102  {
1103  uint8_t i = 0;
1104 
1105  buf.cmd[i++] = JEDEC_READ_DATA;
1106  if(addr_4bit) {
1107  buf.cmd[i++] = (PageAdr >> 24) & 0xff;
1108  }
1109  buf.cmd[i++] = (PageAdr >> 16) & 0xff;
1110  buf.cmd[i++] = (PageAdr >> 8) & 0xff;
1111  buf.cmd[i++] = (PageAdr >> 0) & 0xff;
1112  }
1113 
1114  spi_spiTransfer(&buf.cmd[0], addr_cmd_length, buf.sector, DF_PAGE_SIZE);
1115 
1116  cs_release();
1117 
1118  uint16_t i;
1119  for(i=0; i<DF_PAGE_SIZE;i++){
1120  ptr[i] = ~buf.sector[i]; // let filesystem will be inverted, this allows extend files without having to Read-Modify-Write on FAT
1121  } // original: 0xFF is clear and 0 can be programmed any time
1122  // inverted: 0 is clear and 1 can be programmed any time
1123  // to mark cluster as used it should be set 1 in the FAT. Also new entries in dirs can be created without RMW
1124  return 1;
1125 }
1126 
1127 
1128 static bool write_page(const uint8_t *ptr, uint32_t pageNum){
1129  uint32_t PageAdr = pageNum * DF_PAGE_SIZE;
1130 
1131  {
1132  uint16_t i;
1133  for(i=0; i<DF_PAGE_SIZE;i++){
1134  buf.sector[i] = ~ptr[i]; // let filesystem will be inverted, this allows extend files without having to Read-Modify-Write on FAT
1135  }
1136  }
1137 
1138  Flash_Jedec_WriteEnable();
1139 
1140  if (!cs_assert()) return 0;
1141 
1142  uint8_t i = addr_cmd_start;
1143 
1144  buf.cmd[i++] = JEDEC_PAGE_WRITE;
1145  if(addr_4bit) {
1146  buf.cmd[i++] = (PageAdr >> 24) & 0xff;
1147  }
1148  buf.cmd[i++] = (PageAdr >> 16) & 0xff;
1149  buf.cmd[i++] = (PageAdr >> 8) & 0xff;
1150  buf.cmd[i++] = (PageAdr >> 0) & 0xff;
1151 
1152 #if 0
1153  write_spi_multi(&buf.cmd[addr_cmd_start], addr_cmd_length);
1154  write_spi_multi(buf.sector, DF_PAGE_SIZE);
1155 #else
1156  write_spi_multi(&buf.cmd[addr_cmd_start], addr_cmd_length + DF_PAGE_SIZE);
1157 #endif
1158  cs_release();
1159  return 1;
1160 }
1161 
1162 static bool erase_page(uint16_t pageNum)
1163 {
1164 
1165  Flash_Jedec_WriteEnable();
1166 
1167  uint32_t PageAdr = pageNum * DF_PAGE_SIZE;
1168 
1169  uint8_t i=0;
1170  buf.cmd[i++] = erase_cmd;
1171  if(addr_4bit) {
1172  buf.cmd[i++] = (PageAdr >> 24) & 0xff;
1173  }
1174  buf.cmd[i++] = (PageAdr >> 16) & 0xff;
1175  buf.cmd[i++] = (PageAdr >> 8) & 0xff;
1176  buf.cmd[i++] = (PageAdr >> 0) & 0xff;
1177 
1178  if (!cs_assert()) return 0;
1179  write_spi_multi(buf.cmd, addr_cmd_length);
1180  cs_release();
1181  return 1;
1182 }
1183 
1184 static void ChipErase()
1185 {
1186 
1187  buf.cmd[0] = JEDEC_BULK_ERASE;
1188 
1189  Flash_Jedec_WriteEnable();
1190 
1191  if (!cs_assert()) return;
1192 
1193  write_spi_multi(buf.cmd, 1);
1194 
1195  chip_is_clear=true;
1196 
1197  cs_release();
1198 }
1199 
1200 uint8_t sd_getSectorCount(uint32_t *ptr){
1201 
1202  uint8_t capacity = df_device & 0xFF;
1203  uint8_t memtype = (df_device>>8) & 0xFF;
1204  uint32_t size=0;
1205 
1206  const char * mfg=NULL;
1207 
1208  switch(df_manufacturer){
1209  case 0xEF: // Winbond Serial Flash
1210  if (memtype == 0x40) {
1211  mfg="Winbond";
1212  size = (1 << ((capacity & 0x0f) + 8));
1213 /*
1214  const uint8_t _capID[11] = {0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x43};
1215  const uint32_t _memSize[11] = {64L*K, 128L*K, 256L*K, 512L*K, 1L*M, 2L*M, 4L*M, 8L*M, 16L*M, 32L*M, 8L*M}; megabytes
1216  const uint32_t _memSize[11] = {64L*K, 128L*K, 256L*K, 512L*K, 1L*M, 2L*M, 4L*M, 8L*M, 16L*M, 32L*M, 8L*M}; megabytes
1217 */
1218  erase_size=4096;
1219  erase_cmd=JEDEC_SECTOR_ERASE;
1220  }
1221  break;
1222  case 0xbf: // SST
1223  if (memtype == 0x25) {
1224  mfg="Microchip";
1225  size = (1 << ((capacity & 0x07) + 12));
1226  }
1227  break;
1228 
1229  case 0x20: // micron
1230  if (memtype == 0xba){// JEDEC_ID_MICRON_N25Q128 0x20ba18
1231  mfg="Micron";
1232  size = (1 << ((capacity & 0x0f) + 8));
1233  erase_size=4096;
1234  erase_cmd=JEDEC_SECTOR_ERASE;
1235  } else if(memtype==0x20) { // JEDEC_ID_MICRON_M25P16 0x202015
1236  mfg="Micron";
1237  size = (1 << ((capacity & 0x0f) + 8));
1238  }
1239  break;
1240 
1241  case 0xC2: //JEDEC_ID_MACRONIX_MX25L6406E 0xC22017
1242  if (memtype == 0x20) {
1243  mfg="MACRONIX";
1244  size = (1 << ((capacity & 0x0f) + 8));
1245  erase_size=4096;
1246  erase_cmd=JEDEC_SECTOR_ERASE;
1247  }
1248  break;
1249 
1250  case 0x9D: // ISSI
1251  if (memtype == 0x40 || memtype == 0x30) {
1252  mfg = "ISSI";
1253  size = (1 << ((capacity & 0x0f) + 8));
1254  }
1255  break;
1256 
1257  default:
1258  break;
1259  }
1260 
1261  if(mfg && size) {
1262  printf("%s SPI Flash found sectors=%ld\n", mfg, size);
1263  } else {
1264  printf("unknown Flash! mfg=%x type=%x cap=%x\n ",df_manufacturer, memtype, capacity);
1265  size = BOARD_DATAFLASH_PAGES; // as defined
1266  }
1267 
1268  if(size>65537) {
1269  addr_cmd_length = 5;
1270  addr_cmd_start = 0;
1271  addr_4bit = true;
1272  Flash_Enter4B_Mode();
1273  }
1274 
1275  if(erase_size > MAX_ERASE_SIZE) size -= (erase_size/DF_PAGE_SIZE); // reserve for RMW ops
1276 
1277  *ptr = size / (FAT_SECTOR_SIZE/DF_PAGE_SIZE); // in 512b blocks
1278 
1279  return RES_OK;
1280 
1281 }
1282 
1283 /*--------------------------------------------------------------------------
1284 
1285  Public Functions
1286 
1287 ---------------------------------------------------------------------------*/
1288 
1289 
1290 /*-----------------------------------------------------------------------*/
1291 /* Initialize disk drive */
1292 /*-----------------------------------------------------------------------*/
1293 
1295  static bool initialized=0;
1296 
1297  if(initialized) return Stat;
1298 
1299  ReadManufacturerID();
1300 
1302 
1303  initialized=1;
1304 
1305  Stat=0;
1306  return Stat;
1307 }
1308 
1309 
1310 /*-----------------------------------------------------------------------*/
1311 /* Get disk status */
1312 /*-----------------------------------------------------------------------*/
1313 
1314 DSTATUS sd_status (){
1315 
1316  return Stat; /* Return disk status */
1317 }
1318 
1319 
1320 /*-----------------------------------------------------------------------*/
1321 /* Read sector(s) */
1322 /*-----------------------------------------------------------------------*/
1323 
1324 DRESULT sd_read (
1325  uint8_t *buff, /* Pointer to the data buffer to store read data */
1326  uint32_t sector, /* Start sector number (LBA) */
1327  uint16_t count /* Number of sectors to read (1..128) */
1328 )
1329 {
1330 
1331  if (!count) return RES_PARERR; /* Check parameter */
1332  if (Stat & STA_NOINIT) return RES_NOTRDY; /* Check if drive is ready */
1333  if(sector > sd_max_sectors) return RES_PARERR; /* Check parameter */
1334 
1335  count *= FAT_SECTOR_SIZE/DF_PAGE_SIZE; // 256bytes page from 512byte sector
1336  sector *= FAT_SECTOR_SIZE/DF_PAGE_SIZE;
1337 
1338 
1339  do {
1340  if(!read_page(buff, sector)) break;
1341  buff += DF_PAGE_SIZE;
1342  sector += 1;
1343  } while(--count);
1344 
1345  return count ? RES_ERROR : RES_OK; /* Return result */
1346 }
1347 
1348 
1349 
1350 /*-----------------------------------------------------------------------*/
1351 /* Write sector(s) */
1352 /*-----------------------------------------------------------------------*/
1353 
1354 
1355 bool sd_move_block(uint32_t sec_from, uint32_t sec_to, const uint8_t *buff, uint32_t sec, uint16_t count);
1356 
1357 /*
1358  в системе нет памяти, а выполнять Read-Modify-Write для флешки как-то надо. придется использовать свободный блок
1359  флеши для буфферизации. Ресурс это конечно уменьшит, зато быстрее перепаяют на нормальную :)
1360  по-уму надо читать FAT и выбирать случайный свободный кластер, но использование для этого функций самой FatFs
1361  приводит к смещению окна в неожиданное время, например когда запись вызывается для сброса измененных структур FAT
1362 
1363 */
1364 bool sd_move_block(uint32_t sec_from, uint32_t sec_to, const uint8_t *buff, uint32_t sec, uint16_t count){
1365 
1366  if(!erase_page(sec_to)) return RES_ERROR;
1367 
1368  uint8_t *sbuffer = malloc(DF_PAGE_SIZE); // read just the needed sector, not in stack for not in CCM
1369  if(!sbuffer) return false;
1370 
1371  uint16_t cnt;
1372 
1373  for(cnt=erase_size/DF_PAGE_SIZE; cnt>0; cnt--){
1374  if(buff && sec_from >= sec && sec_from < (sec + count) ) { // if replacement data fit to sector
1375  memcpy(sbuffer, buff, DF_PAGE_SIZE); // will use it
1376  buff+=DF_PAGE_SIZE;
1377  } else { // read from source
1378  if(!read_page(sbuffer, sec_from)) break;
1379  }
1380  if(!write_page(sbuffer, sec_to)) break;
1381  sec_from++;
1382  sec_to++;
1383  }
1384 
1385  free(sbuffer);
1386 
1387  return cnt==0;
1388 }
1389 
1390 
1391 DRESULT sd_write (
1392  const uint8_t *buff, /* Ponter to the data to write */
1393  uint32_t sector, /* Start sector number (LBA) */
1394  uint16_t count /* Number of sectors to write (1..128) */
1395 )
1396 {
1397  if (!count) return RES_PARERR; /* Check parameter */
1398  if (Stat & STA_NOINIT) return RES_NOTRDY; /* Check drive status */
1399  if(sector > sd_max_sectors) return RES_PARERR; /* Check parameter */
1400 
1401 
1402  uint16_t pos = sector % erase_size/FAT_SECTOR_SIZE; // number of sector in erase block
1403  if( pos == 0 && count >= erase_size/FAT_SECTOR_SIZE){ // begin of erase block - write full cluster
1404  count *= FAT_SECTOR_SIZE/DF_PAGE_SIZE; // 256bytes page from 512byte sector
1405  sector *= FAT_SECTOR_SIZE/DF_PAGE_SIZE;
1406  if(!erase_page(sector)) return RES_ERROR;
1407  do {
1408  if(!write_page(buff, sector)) break;
1409  buff += DF_PAGE_SIZE;
1410  sector += 1;
1411  } while(--count);
1412 
1413  } else { // read-modify-write
1414  uint8_t *ptr;
1415  bool need_erase = false; // check for free space for write
1416 
1417  {
1418  uint8_t *sbuffer = malloc(FAT_SECTOR_SIZE*count); // read just the needed sectors
1419  if(!sbuffer) return RES_ERROR; // no memory at all
1420 
1421  ptr = sbuffer;
1422 
1423  uint32_t r_sector = sector;
1424  uint16_t r_count = count;
1425 
1426  r_sector *= FAT_SECTOR_SIZE/DF_PAGE_SIZE;
1427  r_count *= FAT_SECTOR_SIZE/DF_PAGE_SIZE; // read data will be rewritten
1428 
1429  do {
1430  if(!read_page(ptr, r_sector)) break;
1431  ptr += DF_PAGE_SIZE;
1432  r_sector += 1;
1433  } while(--r_count);
1434 
1435 
1436  const uint8_t *pp;
1437  for(ptr = sbuffer, pp=buff; ptr < sbuffer+FAT_SECTOR_SIZE*count;ptr++,pp++){
1438 // if(~*ptr & *pp){ // у нас не должно быть нулей там где нужна 1
1439  // filesystem is inverted, so - у нас не должно быть 1 там где нужен 0
1440  // пример: чистая FF - инверсия 00, можно писАть любой байт
1441  // считали F0 - инверсия 0F - можно писАть *0
1442  if(*ptr & *pp){
1443  need_erase=true;
1444  break;
1445  }
1446  }
1447  free(sbuffer);// don't need more
1448  }
1449 
1450  if(need_erase){// write do dirty block
1451 
1452  uint8_t *cluster = malloc(erase_size);
1453  if(!cluster) { // we can try to allocate up to 64K so absense of memory should not be error!
1454  if(erase_size <= MAX_ERASE_SIZE) return RES_ERROR; // we have no reserved page
1455 
1456  // we can use any free sector of flash as buffer, too
1457  uint32_t fr_sec = sd_max_sectors * (FAT_SECTOR_SIZE/DF_PAGE_SIZE); // the last page
1458 
1459  // read data from beginning of erase block up to part that will be rewritten
1460  uint32_t r_sector = (sector * (FAT_SECTOR_SIZE/DF_PAGE_SIZE)) & ~(erase_size/DF_PAGE_SIZE - 1);
1461 
1462  // move data to sectors of free block
1463  if(!sd_move_block(r_sector, fr_sec, NULL, 0, 0)) return RES_ERROR;
1464  // move back with inserting of data to write
1465  if(!sd_move_block(fr_sec, r_sector, buff, sector * (FAT_SECTOR_SIZE/DF_PAGE_SIZE), count * (FAT_SECTOR_SIZE/DF_PAGE_SIZE))) return RES_ERROR; // move back
1466  count=0; // all OK
1467 
1468 
1469  } else { // we have enough memory for cluster buffer
1470 
1471  ptr = cluster;
1472 
1473  // read data from beginning of erase block up to part that will be rewritten
1474  uint32_t r_sector = (sector * (FAT_SECTOR_SIZE/DF_PAGE_SIZE)) & ~(erase_size/DF_PAGE_SIZE - 1);
1475  uint32_t w_sector = r_sector;
1476  uint16_t r_count = erase_size/DF_PAGE_SIZE; // read full page
1477  do {
1478  if(r_sector >= sector * (FAT_SECTOR_SIZE/DF_PAGE_SIZE)) break;
1479  if(!read_page(ptr, r_sector)) break;
1480  ptr += DF_PAGE_SIZE;
1481  r_sector += 1;
1482  } while(--r_count);
1483 
1484  // Yes I know that we could to go out from the buffer end - but this used only for FAT_FS which writes FAT per one sector
1485 // memcpy(cluster+FAT_SECTOR_SIZE*pos, (uint8_t *)buff, FAT_SECTOR_SIZE*count); // insert sectors to write to right place
1486  memcpy(ptr, (uint8_t *)buff, FAT_SECTOR_SIZE*count); // insert sectors to write to right place
1487 
1488  // skip part that will be rewritten
1489  r_count -= (FAT_SECTOR_SIZE/DF_PAGE_SIZE) * count;
1490  r_sector += (FAT_SECTOR_SIZE/DF_PAGE_SIZE) * count;
1491  ptr += FAT_SECTOR_SIZE * count;
1492 
1493  // read the tail
1494  while(r_count) {
1495  if(!read_page(ptr, r_sector)) break;
1496  ptr += DF_PAGE_SIZE;
1497  r_sector += 1;
1498  --r_count;
1499  };
1500 
1501  if(r_count) return RES_ERROR;
1502 
1503  // erase page
1504  if(!erase_page(w_sector)) return RES_ERROR;
1505 
1506  ptr = cluster;
1507  uint16_t w_count = erase_size/DF_PAGE_SIZE;
1508  do {
1509  if(!write_page(ptr, w_sector)) break;
1510  ptr += DF_PAGE_SIZE;
1511  w_sector += 1;
1512  } while(--w_count);
1513 
1514  count = w_count;
1515 
1516  free(cluster);
1517  }
1518 
1519  } else { // block is ready to write - just write needed part
1520  count *= FAT_SECTOR_SIZE/DF_PAGE_SIZE; // 256bytes page from 512byte sector
1521  sector *= FAT_SECTOR_SIZE/DF_PAGE_SIZE;
1522  do {
1523  if(!write_page(buff, sector)) break;
1524  buff += DF_PAGE_SIZE;
1525  sector += 1;
1526  } while(--count);
1527  }
1528  }
1529 
1530 
1531  return count ? RES_ERROR : RES_OK; /* Return result */
1532 }
1533 
1534 
1535 /*-----------------------------------------------------------------------*/
1536 /* Miscellaneous drive controls other than data read/write */
1537 /*-----------------------------------------------------------------------*/
1538 
1539 static inline void enqueue_flash_erase(uint32_t from, uint32_t to){
1540 
1541  int16_t new_wp = fe_write_ptr+1;
1542  if(new_wp >= FLASH_ERASE_QUEUE_SIZE) { // move write pointer
1543  new_wp=0; // ring
1544  }
1545  while(new_wp == fe_read_ptr) hal_yield(0); // buffer overflow
1546 
1547  flash_erase_queue[fe_write_ptr].b = from;
1548  flash_erase_queue[fe_write_ptr].e = to;
1549 
1550  fe_write_ptr=new_wp; // move forward
1551 
1552  hal_set_task_active(_flash_erase_task);
1553 }
1554 
1555 
1556 DRESULT sd_ioctl (
1557  uint8_t ctl, /* Control command code */
1558  void *buff /* Pointer to the conrtol data */
1559 )
1560 {
1561  DRESULT res;
1562 
1563  uint8_t *ptr = (uint8_t *)buff;
1564 
1565  res = RES_ERROR;
1566 
1567  if (ctl== CTRL_POWER){
1568 
1569  switch (*ptr) {
1570  case 0: // Sub control code == 0 (POWER_OFF)
1571  res = RES_OK;
1572  break;
1573  case 1: // Sub control code == 1 (POWER_ON)
1574  res = RES_OK;
1575  break;
1576  case 2: // Sub control code == 2 (POWER_GET)
1577  *(ptr + 1) = (uint8_t) MMC_CD;
1578  break;
1579  default:
1580  res = RES_PARERR;
1581  break;
1582  }
1583 
1584  } else {
1585 
1586  if (Stat & STA_NOINIT) return RES_NOTRDY; /* Check if drive is ready */
1587 
1588  switch (ctl) {
1589  case CTRL_SYNC : /* Wait for end of internal write process of the drive */
1590  res = RES_OK;
1591  break;
1592 
1593  case GET_SECTOR_COUNT : /* Get drive capacity in unit of sector (uint32_t ) */
1594  *(uint32_t *)buff = sd_max_sectors;
1595  res = RES_OK;
1596  break;
1597 
1598  case GET_BLOCK_SIZE : /* Get erase block size in unit of FAT sector (uint32_t ) */
1599  *(uint32_t *)buff = erase_size/FAT_SECTOR_SIZE;
1600  res = RES_OK;
1601  break;
1602 
1603  case GET_SECTOR_SIZE:
1604  *(uint32_t *)buff = FAT_SECTOR_SIZE; // always
1605  res = RES_OK;
1606  break;
1607 
1608  case CTRL_TRIM : { /* Erase a block of sectors (used when _USE_TRIM == 1) */
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;
1612 
1613  if(start_sector>=sd_max_sectors || end_sector>=sd_max_sectors) return RES_PARERR;
1614  if(chip_is_clear) { // just after full erase
1615  res = RES_OK;
1616  chip_is_clear=false;
1617  return res;
1618  }
1619 
1620  if(hal_is_armed()) return RES_OK;
1621 
1622 #if 0 // in separate thread
1623 
1624  erase_page(start_sector * (FAT_SECTOR_SIZE/DF_PAGE_SIZE)); // clear 1st sector of DataFlash
1625 
1626  enqueue_flash_erase(start_sector+(erase_size/DF_PAGE_SIZE), end_sector); //and enqueue
1627 #else
1628  uint32_t sector;
1629  for(sector=start_sector; sector <= end_sector;sector++){
1630  uint32_t df_sect = sector * (FAT_SECTOR_SIZE/DF_PAGE_SIZE); // sector in DataFlash
1631  block = df_sect / (erase_size/DF_PAGE_SIZE); // number of EraseBlock
1632  if(last_block!=block){
1633  last_block=block;
1634  if(!erase_page(df_sect)) return RES_ERROR;
1635  putch('.');
1636  extern void digitalToggle(uint8_t pin);
1637 
1639  }
1640  }
1641 #endif
1642  res = RES_OK;
1643 
1644  } break;
1645 
1646  case CTRL_FORMAT:{
1647  ChipErase();
1648  res = RES_OK;
1649  } break;
1650 
1651  default:
1652  res = RES_PARERR;
1653  }
1654 
1655  }
1656  return res;
1657 }
1658 
1659 
1660 /*-----------------------------------------------------------------------*/
1661 /* Device timer function */
1662 /*-----------------------------------------------------------------------*/
1663 /* This function must be called from timer interrupt routine in period
1664 / of 1 ms to generate card control timing.
1665 */
1666 
1667 void sd_timerproc (void)
1668 {
1669  uint16_t n;
1670 
1671  n = Timer1; /* 1kHz decrement timer stopped at 0 */
1672  if (n) Timer1 = --n;
1673  n = Timer2;
1674  if (n) Timer2 = --n;
1675 }
1676 
1677 
1678 
1679 #endif //defined(BOARD_DATAFLASH_FATFS)
#define CT_SDC
Definition: sd.h:44
void(* voidFuncPtr)(void)
Definition: hal_types.h:16
#define GET_BLOCK_SIZE
Definition: diskio.h:53
#define TIMER5
Definition: timer.h:613
void putch(unsigned char c)
Definition: system.cpp:139
uint8_t spi_detect()
#define STA_NOINIT
Definition: diskio.h:42
int printf(const char *msg,...)
Definition: stdio.c:113
#define ACMD13
Definition: sd.c:43
#define CMD13
Definition: sd.c:42
#define CTRL_FORMAT
Definition: diskio.h:60
#define JEDEC_PAGE_WRITE
#define STA_PROTECT
Definition: diskio.h:44
#define DF_PAGE_SIZE
#define MMC_GET_SDSTAT
Definition: diskio.h:67
static volatile uint16_t Timer2
Definition: sd.c:79
#define HAL_GPIO_A_LED_PIN
Definition: chibios.h:9
static uint32_t micros()
Definition: sd.c:58
static uint64_t systick_uptime(void)
Returns the system uptime, in milliseconds.
Definition: systick.h:44
uint8_t(* spi_WaitFunc)(uint8_t b)
Definition: sd.c:62
void hal_set_task_priority(void *handle, uint8_t prio)
Definition: Scheduler.cpp:1440
#define CMD38
Definition: sd.c:53
#define JEDEC_STATUS_BUSY
void * hal_register_task(voidFuncPtr task, uint32_t stack)
Definition: Scheduler.cpp:1441
DRESULT sd_write(const uint8_t *buff, uint32_t sector, uint16_t count)
#define CMD10
Definition: sd.c:40
#define CMD9
Definition: sd.c:39
#define BOARD_DATAFLASH_PAGES
Definition: board.h:138
#define FAT_SECTOR_SIZE
Definition: sd.h:14
#define CMD16
Definition: sd.c:44
#define CMD55
Definition: sd.c:54
static volatile uint16_t Timer1
Definition: sd.c:79
#define CMD58
Definition: sd.c:55
void digitalToggle(uint8_t pin)
Definition: GPIO.cpp:183
DRESULT sd_read(uint8_t *buff, uint32_t sector, uint16_t count)
#define JEDEC_WRITE_ENABLE
#define GET_SECTOR_COUNT
Definition: diskio.h:51
#define BOARD_DATAFLASH_ERASE_SIZE
Definition: board.h:139
DRESULT sd_ioctl(uint8_t cmd, void *buff)
#define JEDEC_READ_DATA
DSTATUS sd_status()
#define CS_LOW()
Definition: sd.c:21
#define CMD12
Definition: sd.c:41
#define MMC_GET_CSD
Definition: diskio.h:64
BYTE DSTATUS
Definition: diskio.h:17
DRESULT
Definition: diskio.h:20
#define CT_SD1
Definition: sd.h:42
DSTATUS sd_initialize()
#define CMD18
Definition: sd.c:46
uint8_t spi_waitFor(uint8_t out, spi_WaitFunc cb, uint32_t dly)
bool hal_is_armed()
Definition: Scheduler.cpp:1446
void sd_timerproc()
bool spi_chipSelectLow(bool take_sem)
void hal_set_task_active(void *handle)
Definition: Scheduler.cpp:1438
Definition: diskio.h:21
#define JEDEC_SECTOR_ERASE
#define IN_CCM
Definition: AP_HAL_F4Light.h:9
static volatile DSTATUS Stat
Definition: sd.c:77
uint8_t spi_spiRecv(void)
#define CMD1
Definition: sd.c:36
#define CTRL_POWER
Definition: diskio.h:57
#define JEDEC_BULK_ERASE
#define CMD24
Definition: sd.c:49
#define CMD32
Definition: sd.c:51
#define JEDEC_PAGE_ERASE
#define ACMD41
Definition: sd.c:37
uint8_t sd_get_type()
uint8_t sd_getSectorCount(uint32_t *ptr)
void spi_chipSelectHigh(void)
void * malloc(size_t size)
Definition: malloc.c:61
void hal_context_switch_isr()
Definition: Scheduler.cpp:1439
#define NULL
Definition: hal_types.h:59
#define MMC_WP
Definition: sd.c:23
#define CT_SD2
Definition: sd.h:43
#define CS_HIGH()
Definition: sd.c:20
#define CTRL_TRIM
Definition: diskio.h:54
void free(void *ptr)
Definition: malloc.c:81
uint8_t spi_spiSend(uint8_t b)
#define CMD25
Definition: sd.c:50
#define GET_SECTOR_SIZE
Definition: diskio.h:52
#define CMD17
Definition: sd.c:45
#define CMD8
Definition: sd.c:38
static uint32_t sd_max_sectors
Definition: sd.c:80
#define CTRL_SYNC
Definition: diskio.h:50
#define CMD33
Definition: sd.c:52
#define JEDEC_READ_STATUS
uint32_t get_fattime()
void spi_spiTransfer(const uint8_t *send, uint32_t send_len, uint8_t *recv, uint32_t recv_len)
#define ACMD23
Definition: sd.c:48
void enqueue_flash_erase(uint32_t from, uint32_t to)
uint8_t spi_spiXchg(uint8_t b)
#define CMD0
Definition: sd.c:35
#define JEDEC_DEVICE_ID
static int8_t pin
Definition: AnalogIn.cpp:15
#define STA_NODISK
Definition: diskio.h:43
#define MMC_CD
Definition: sd.c:22
uint8_t sd_get_state()
static INLINE uint32_t timer_get_count32(const timer_dev *dev)
Definition: timer.h:706
static uint32_t millis()
Definition: sd.c:60
#define MMC_GET_CID
Definition: diskio.h:65
#define CT_MMC
Definition: sd.h:41
#define MMC_GET_OCR
Definition: diskio.h:66
#define CT_BLOCK
Definition: sd.h:45
void hal_yield(uint16_t ttw)
Definition: Scheduler.cpp:1430
void spi_yield()