sdnative.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059
  1. #include <arm/NXP/LPC17xx/LPC17xx.h>
  2. #include <stdio.h>
  3. #include "config.h"
  4. #include "crc.h"
  5. #include "crc16.h"
  6. #include "diskio.h"
  7. #include "spi.h"
  8. #include "timer.h"
  9. #include "uart.h"
  10. #include "led.h"
  11. #include "sdnative.h"
  12. #include "fileops.h"
  13. #include "bits.h"
  14. #include "fpga_spi.h"
  15. #define MAX_CARDS 1
  16. // SD/MMC commands
  17. #define GO_IDLE_STATE 0
  18. #define SEND_OP_COND 1
  19. #define ALL_SEND_CID 2
  20. #define SEND_RELATIVE_ADDR 3
  21. #define SWITCH_FUNC 6
  22. #define SELECT_CARD 7
  23. #define SEND_IF_COND 8
  24. #define SEND_CSD 9
  25. #define SEND_CID 10
  26. #define STOP_TRANSMISSION 12
  27. #define SEND_STATUS 13
  28. #define GO_INACTIVE_STATE 15
  29. #define SET_BLOCKLEN 16
  30. #define READ_SINGLE_BLOCK 17
  31. #define READ_MULTIPLE_BLOCK 18
  32. #define WRITE_BLOCK 24
  33. #define WRITE_MULTIPLE_BLOCK 25
  34. #define PROGRAM_CSD 27
  35. #define SET_WRITE_PROT 28
  36. #define CLR_WRITE_PROT 29
  37. #define SEND_WRITE_PROT 30
  38. #define ERASE_WR_BLK_STAR_ADDR 32
  39. #define ERASE_WR_BLK_END_ADDR 33
  40. #define ERASE 38
  41. #define LOCK_UNLOCK 42
  42. #define APP_CMD 55
  43. #define GEN_CMD 56
  44. #define READ_OCR 58
  45. #define CRC_ON_OFF 59
  46. // SD ACMDs
  47. #define SD_SET_BUS_WIDTH 6
  48. #define SD_STATUS 13
  49. #define SD_SEND_NUM_WR_BLOCKS 22
  50. #define SD_SET_WR_BLK_ERASE_COUNT 23
  51. #define SD_SEND_OP_COND 41
  52. #define SD_SET_CLR_CARD_DETECT 42
  53. #define SD_SEND_SCR 51
  54. // R1 status bits
  55. #define STATUS_IN_IDLE 1
  56. #define STATUS_ERASE_RESET 2
  57. #define STATUS_ILLEGAL_COMMAND 4
  58. #define STATUS_CRC_ERROR 8
  59. #define STATUS_ERASE_SEQ_ERROR 16
  60. #define STATUS_ADDRESS_ERROR 32
  61. #define STATUS_PARAMETER_ERROR 64
  62. /* Card types - cardtype == 0 is MMC */
  63. #define CARD_SD (1<<0)
  64. #define CARD_SDHC (1<<1)
  65. /*
  66. Rev.A Rev.C
  67. 1 DAT3/SS P0.6 P2.3
  68. 2 CMD/DI P0.9 P0.9
  69. 5 Clock P0.7 P0.7
  70. 7 DAT0/DO P0.8 P2.0
  71. 8 DAT1/IRQ P1.14 P2.1
  72. 9 DAT2/NC P1.15 P2.2
  73. */
  74. /* SD init procedure
  75. =================
  76. - initial clock frequency: ~100kHz
  77. - cycle the clock for at least 74 cycles (some more may be safer)
  78. - send CMD0
  79. - send CMD8 (SEND_OP_COND); if no response -> HCS=0; else HCS=1
  80. - send ACMD41 until OCR[31] (busy) becomes 1 (means: ready)
  81. - if OCR[30] (CCS) set -> SDHC; else SDSC
  82. - send CMD2 (read CID) (maybe log some stuff from the CID)
  83. - send CMD3 (read RCA), store RCA
  84. == end of initialisation ==
  85. - send CMD9 (read CSD) with RCA, maybe do sth with TRAN_SPEED
  86. - send CMD7 with RCA, select card, put card in tran
  87. - maybe send CMD13 with RCA to check state (tran)
  88. - send ACMD51 with RCA to read SCR (maybe, to check 4bit support)
  89. - increase clock speed
  90. - send ACMD6 with RCA to set 4bit bus width
  91. - send transfer cmds
  92. */
  93. /*
  94. static CMD payloads. (no CRC calc required)
  95. - CMD0: 0x40 0x00 0x00 0x00 0x00 0x95
  96. - CMD8: 0x48 0x00 0x00 0x01 0xaa 0x87
  97. - CMD2: 0x42 0x00 0x00 0x00 0x00 0x4d
  98. - CMD3: 0x43 0x00 0x00 0x00 0x00 0x21
  99. - CMD55: 0x77 0x00 0x00 0x00 0x00 0x65
  100. */
  101. uint8_t cmd[6]={0,0,0,0,0,0};
  102. uint8_t rsp[17];
  103. uint8_t csd[17];
  104. uint8_t cid[17];
  105. uint8_t ccs=0;
  106. uint32_t rca;
  107. enum trans_state { TRANS_NONE = 0, TRANS_READ, TRANS_WRITE, TRANS_MID };
  108. enum cmd_state { CMD_RSP = 0, CMD_RSPDAT, CMD_DAT };
  109. int during_blocktrans = TRANS_NONE;
  110. uint32_t last_block = 0;
  111. uint16_t last_offset = 0;
  112. volatile int sd_changed;
  113. /**
  114. * getbits - read value from bit buffer
  115. * @buffer: pointer to the data buffer
  116. * @start : index of the first bit in the value
  117. * @bits : number of bits in the value
  118. *
  119. * This function returns a value from the memory region passed as
  120. * buffer, starting with bit "start" and "bits" bit long. The buffer
  121. * is assumed to be MSB first, passing 0 for start will read starting
  122. * from the highest-value bit of the first byte of the buffer.
  123. */
  124. static uint32_t getbits(void *buffer, uint16_t start, int8_t bits) {
  125. uint8_t *buf = buffer;
  126. uint32_t result = 0;
  127. if ((start % 8) != 0) {
  128. /* Unaligned start */
  129. result += buf[start / 8] & (0xff >> (start % 8));
  130. bits -= 8 - (start % 8);
  131. start += 8 - (start % 8);
  132. }
  133. while (bits >= 8) {
  134. result = (result << 8) + buf[start / 8];
  135. start += 8;
  136. bits -= 8;
  137. }
  138. if (bits > 0) {
  139. result = result << bits;
  140. result = result + (buf[start / 8] >> (8-bits));
  141. } else if (bits < 0) {
  142. /* Fraction of a single byte */
  143. result = result >> -bits;
  144. }
  145. return result;
  146. }
  147. void sdn_checkinit(BYTE drv) {
  148. if(disk_state == DISK_CHANGED) {
  149. disk_initialize(drv);
  150. }
  151. }
  152. uint8_t* sdn_getcid() {
  153. sdn_checkinit(0);
  154. return cid;
  155. }
  156. static inline void wiggle_slow_pos(uint16_t times) {
  157. while(times--) {
  158. delay_us(2);
  159. BITBAND(SD_CLKREG->FIOSET, SD_CLKPIN) = 1;
  160. delay_us(2);
  161. BITBAND(SD_CLKREG->FIOCLR, SD_CLKPIN) = 1;
  162. }
  163. }
  164. static inline void wiggle_slow_neg(uint16_t times) {
  165. while(times--) {
  166. delay_us(2);
  167. BITBAND(SD_CLKREG->FIOCLR, SD_CLKPIN) = 1;
  168. delay_us(2);
  169. BITBAND(SD_CLKREG->FIOSET, SD_CLKPIN) = 1;
  170. }
  171. }
  172. static inline void wiggle_fast_pos(uint16_t times) {
  173. while(times--) {
  174. BITBAND(SD_CLKREG->FIOSET, SD_CLKPIN) = 1;
  175. BITBAND(SD_CLKREG->FIOCLR, SD_CLKPIN) = 1;
  176. }
  177. }
  178. static inline void wiggle_fast_neg(uint16_t times) {
  179. while(times--) {
  180. BITBAND(SD_CLKREG->FIOCLR, SD_CLKPIN) = 1;
  181. BITBAND(SD_CLKREG->FIOSET, SD_CLKPIN) = 1;
  182. }
  183. }
  184. static inline void wiggle_fast_neg1(void) {
  185. BITBAND(SD_CLKREG->FIOCLR, SD_CLKPIN) = 1;
  186. BITBAND(SD_CLKREG->FIOSET, SD_CLKPIN) = 1;
  187. }
  188. static inline void wiggle_fast_pos1(void) {
  189. BITBAND(SD_CLKREG->FIOSET, SD_CLKPIN) = 1;
  190. BITBAND(SD_CLKREG->FIOCLR, SD_CLKPIN) = 1;
  191. }
  192. int get_and_check_datacrc(uint8_t *buf) {
  193. uint16_t crc0=0, crc1=0, crc2=0, crc3=0;
  194. uint16_t sdcrc0=0, sdcrc1=0, sdcrc2=0, sdcrc3=0;
  195. uint8_t d0=0, d1=0, d2=0, d3=0;
  196. uint8_t datdata;
  197. uint16_t datcnt;
  198. /* get crcs from card */
  199. for (datcnt=0; datcnt < 16; datcnt++) {
  200. datdata = SD_DAT;
  201. wiggle_fast_neg1();
  202. sdcrc0 = ((sdcrc0 << 1) & 0xfffe) | ((datdata >> 3) & 0x0001);
  203. sdcrc1 = ((sdcrc1 << 1) & 0xfffe) | ((datdata >> 2) & 0x0001);
  204. sdcrc2 = ((sdcrc2 << 1) & 0xfffe) | ((datdata >> 1) & 0x0001);
  205. sdcrc3 = ((sdcrc3 << 1) & 0xfffe) | ((datdata >> 0) & 0x0001);
  206. }
  207. wiggle_fast_neg1();
  208. /* calc crcs from data */
  209. for (datcnt=0; datcnt < 512; datcnt++) {
  210. d0 = ((d0 << 2) & 0xfc) | ((buf[datcnt] >> 6) & 0x02) | ((buf[datcnt] >> 3) & 0x01) ;
  211. d1 = ((d1 << 2) & 0xfc) | ((buf[datcnt] >> 5) & 0x02) | ((buf[datcnt] >> 2) & 0x01) ;
  212. d2 = ((d2 << 2) & 0xfc) | ((buf[datcnt] >> 4) & 0x02) | ((buf[datcnt] >> 1) & 0x01) ;
  213. d3 = ((d3 << 2) & 0xfc) | ((buf[datcnt] >> 3) & 0x02) | ((buf[datcnt] >> 0) & 0x01) ;
  214. if((datcnt % 4) == 3) {
  215. crc0 = crc_xmodem_update(crc0, d0);
  216. crc1 = crc_xmodem_update(crc1, d1);
  217. crc2 = crc_xmodem_update(crc2, d2);
  218. crc3 = crc_xmodem_update(crc3, d3);
  219. }
  220. }
  221. if((crc0 != sdcrc0) || (crc1 != sdcrc1) || (crc2 != sdcrc2) || (crc3 != sdcrc3)) {
  222. printf("CRC mismatch\nSDCRC CRC\n %04x %04x\n %04x %04x\n %04x %04x\n %04x %04x\n", sdcrc0, crc0, sdcrc1, crc1, sdcrc2, crc2, sdcrc3, crc3);
  223. return 1;
  224. }
  225. return 0;
  226. }
  227. static inline void wait_busy(void) {
  228. while(!(BITBAND(SD_DAT0REG->FIOPIN, SD_DAT0PIN))) {
  229. wiggle_fast_neg1();
  230. }
  231. wiggle_fast_neg(4);
  232. }
  233. /*
  234. send_command_slow
  235. send SD command and put response in rsp.
  236. returns length of response or 0 if there was no response
  237. */
  238. int send_command_slow(uint8_t* cmd, uint8_t* rsp){
  239. uint8_t shift, i=6;
  240. int rsplen;
  241. uint8_t cmdno = *cmd & 0x3f;
  242. wiggle_slow_pos(5);
  243. switch(*cmd & 0x3f) {
  244. case 0:
  245. rsplen = 0;
  246. break;
  247. case 2:
  248. case 9:
  249. case 10:
  250. rsplen = 17;
  251. break;
  252. default:
  253. rsplen = 6;
  254. }
  255. /* send command */
  256. BITBAND(SD_CMDREG->FIODIR, SD_CMDPIN) = 1;
  257. while(i--) {
  258. shift = 8;
  259. do {
  260. shift--;
  261. uint8_t data = *cmd;
  262. *cmd<<=1;
  263. if(data&0x80) {
  264. BITBAND(SD_CMDREG->FIOSET, SD_CMDPIN) = 1;
  265. } else {
  266. BITBAND(SD_CMDREG->FIOCLR, SD_CMDPIN) = 1;
  267. }
  268. wiggle_slow_pos(1);
  269. } while (shift);
  270. cmd++;
  271. }
  272. wiggle_slow_pos(1);
  273. BITBAND(SD_CMDREG->FIODIR, SD_CMDPIN) = 0;
  274. if(rsplen) {
  275. uint16_t timeout=1000;
  276. while((BITBAND(SD_CMDREG->FIOPIN, SD_CMDPIN)) && --timeout) {
  277. wiggle_slow_neg(1);
  278. }
  279. if(!timeout) {
  280. printf("CMD%d timed out\n", cmdno);
  281. return 0; /* no response within timeout */
  282. }
  283. i=rsplen;
  284. while(i--) {
  285. shift = 8;
  286. uint8_t data=0;
  287. do {
  288. shift--;
  289. data |= (BITBAND(SD_CMDREG->FIOPIN, SD_CMDPIN)) << shift;
  290. wiggle_slow_neg(1);
  291. } while (shift);
  292. *rsp=data;
  293. rsp++;
  294. }
  295. }
  296. return rsplen;
  297. }
  298. /*
  299. send_command_fast
  300. send SD command and put response in rsp.
  301. returns length of response or 0 if there was no response
  302. */
  303. int send_command_fast(uint8_t* cmd, uint8_t* rsp, uint8_t* buf){
  304. uint8_t datshift=8, cmdshift, i=6;
  305. uint8_t cmdno = *cmd & 0x3f;
  306. int rsplen, dat=0, waitbusy=0, datcnt=512, j=0;
  307. static int state=CMD_RSP;
  308. wiggle_fast_pos(9); /* give the card >=8 cycles after last command */
  309. DBG_SD printf("send_command_fast: sending CMD%d; payload=%02x%02x%02x%02x%02x%02x...\n", cmdno, cmd[0], cmd[1], cmd[2], cmd[3], cmd[4], cmd[5]);
  310. switch(*cmd & 0x3f) {
  311. case 0:
  312. rsplen = 0;
  313. break;
  314. case 2:
  315. case 9:
  316. case 10:
  317. rsplen = 17;
  318. break;
  319. case 12:
  320. rsplen = 6;
  321. waitbusy = 1;
  322. break;
  323. case 13:
  324. case 17:
  325. case 18:
  326. dat = 1;
  327. default:
  328. rsplen = 6;
  329. }
  330. if(dat && (buf==NULL)) {
  331. printf("send_command_fast error: buf is null but data transfer expected.\n");
  332. return 0;
  333. }
  334. /* send command */
  335. BITBAND(SD_CMDREG->FIODIR, SD_CMDPIN) = 1;
  336. while(i--) {
  337. uint8_t data = *cmd;
  338. cmdshift = 8;
  339. do {
  340. cmdshift--;
  341. if(data&0x80) {
  342. BITBAND(SD_CMDREG->FIOSET, SD_CMDPIN) = 1;
  343. } else {
  344. BITBAND(SD_CMDREG->FIOCLR, SD_CMDPIN) = 1;
  345. }
  346. data<<=1;
  347. wiggle_fast_pos1();
  348. } while (cmdshift);
  349. cmd++;
  350. }
  351. wiggle_fast_pos1();
  352. BITBAND(SD_CMDREG->FIODIR, SD_CMDPIN) = 0;
  353. if(rsplen) {
  354. uint32_t timeout=2000000;
  355. /* wait for response */
  356. while((BITBAND(SD_CMDREG->FIOPIN, SD_CMDPIN)) && --timeout) {
  357. wiggle_fast_neg1();
  358. }
  359. if(!timeout) {
  360. printf("CMD%d timed out\n", cmdno);
  361. return 0; /* no response within timeout */
  362. }
  363. i=rsplen;
  364. uint8_t cmddata=0, datdata=0;
  365. while(i--) { /* process response */
  366. cmdshift = 8;
  367. do {
  368. if(dat) {
  369. if(!(BITBAND(SD_DAT0REG->FIOPIN, SD_DAT0PIN))) {
  370. printf("data start during response\n");
  371. j=datcnt;
  372. state=CMD_RSPDAT;
  373. break;
  374. }
  375. }
  376. cmdshift--;
  377. cmddata |= (BITBAND(SD_CMDREG->FIOPIN, SD_CMDPIN)) << cmdshift;
  378. wiggle_fast_neg1();
  379. } while (cmdshift);
  380. if(state==CMD_RSPDAT)break;
  381. *rsp=cmddata;
  382. cmddata=0;
  383. rsp++;
  384. }
  385. if(state==CMD_RSPDAT) { /* process response+data */
  386. int startbit=1;
  387. DBG_SD printf("processing rsp+data cmdshift=%d i=%d j=%d\n", cmdshift, i, j);
  388. datshift=8;
  389. while(1) {
  390. cmdshift--;
  391. cmddata |= (BITBAND(SD_CMDREG->FIOPIN, SD_CMDPIN)) << cmdshift;
  392. if(!cmdshift) {
  393. cmdshift=8;
  394. *rsp=cmddata;
  395. cmddata=0;
  396. rsp++;
  397. i--;
  398. if(!i) {
  399. DBG_SD printf("response end\n");
  400. if(j) state=CMD_DAT; /* response over, remaining data */
  401. break;
  402. }
  403. }
  404. if(!startbit) {
  405. datshift-=4;
  406. datdata |= SD_DAT << datshift;
  407. if(!datshift) {
  408. datshift=8;
  409. *buf=datdata;
  410. datdata=0;
  411. buf++;
  412. j--;
  413. if(!j) break;
  414. }
  415. }
  416. startbit=0;
  417. wiggle_fast_neg1();
  418. }
  419. }
  420. if(dat && state != CMD_DAT) { /* response ended before data */
  421. BITBAND(SD_CMDREG->FIODIR, SD_CMDPIN) = 1;
  422. state=CMD_DAT;
  423. j=datcnt;
  424. datshift=8;
  425. timeout=2000000;
  426. DBG_SD printf("response over, waiting for data...\n");
  427. /* wait for data start bit on DAT0 */
  428. while((BITBAND(SD_DAT0REG->FIOPIN, SD_DAT0PIN)) && --timeout) {
  429. wiggle_fast_neg1();
  430. }
  431. //printf("%ld\n", timeout);
  432. DBG_SD if(!timeout) printf("timed out!\n");
  433. wiggle_fast_neg1(); /* eat the start bit */
  434. if(sd_offload) {
  435. if(sd_offload_partial) {
  436. if(sd_offload_partial_start != 0) {
  437. if(during_blocktrans == TRANS_MID) sd_offload_partial_start |= 0x8000;
  438. }
  439. if(sd_offload_partial_end != 512) {
  440. sd_offload_partial_end |= 0x8000;
  441. }
  442. DBG_SD printf("new partial %d - %d\n", sd_offload_partial_start, sd_offload_partial_end);
  443. fpga_set_sddma_range(sd_offload_partial_start, sd_offload_partial_end);
  444. fpga_sddma(sd_offload_tgt, 1);
  445. // sd_offload_partial=0;
  446. last_offset=sd_offload_partial_end;
  447. } else {
  448. fpga_sddma(sd_offload_tgt, 0);
  449. last_offset=0;
  450. }
  451. state=CMD_RSP;
  452. return rsplen;
  453. }
  454. }
  455. if(state==CMD_DAT) { /* transfer rest of data */
  456. DBG_SD printf("remaining data: %d\n", j);
  457. if(datshift==8) {
  458. while(1) {
  459. datdata |= SD_DAT << 4;
  460. wiggle_fast_neg1();
  461. datdata |= SD_DAT;
  462. wiggle_fast_neg1();
  463. *buf=datdata;
  464. datdata=0;
  465. buf++;
  466. j--;
  467. if(!j) break;
  468. }
  469. } else {
  470. while(1) {
  471. datshift-=4;
  472. datdata |= SD_DAT << datshift;
  473. if(!datshift) {
  474. datshift=8;
  475. *buf=datdata;
  476. datdata=0;
  477. buf++;
  478. j--;
  479. if(!j) break;
  480. }
  481. wiggle_fast_neg1();
  482. }
  483. }
  484. }
  485. if(dat) {
  486. #ifdef CONFIG_SD_DATACRC
  487. if(get_and_check_datacrc(buf-512)) {
  488. return CRC_ERROR;
  489. }
  490. #else
  491. /* eat the crcs */
  492. wiggle_fast_neg(17);
  493. #endif
  494. }
  495. if(waitbusy) {
  496. DBG_SD printf("waitbusy after send_cmd\n");
  497. wait_busy();
  498. }
  499. state=CMD_RSP;
  500. }
  501. rsp-=rsplen;
  502. DBG_SD printf("send_command_fast: CMD%d response: %02x%02x%02x%02x%02x%02x\n", cmdno, rsp[0], rsp[1], rsp[2], rsp[3], rsp[4], rsp[5]);
  503. BITBAND(SD_CMDREG->FIODIR, SD_CMDPIN) = 1;
  504. return rsplen;
  505. }
  506. static inline void make_crc7(uint8_t* cmd) {
  507. cmd[5]=crc7update(0, cmd[0]);
  508. cmd[5]=crc7update(cmd[5], cmd[1]);
  509. cmd[5]=crc7update(cmd[5], cmd[2]);
  510. cmd[5]=crc7update(cmd[5], cmd[3]);
  511. cmd[5]=crc7update(cmd[5], cmd[4]);
  512. cmd[5]=(cmd[5] << 1) | 1;
  513. }
  514. int cmd_slow(uint8_t cmd, uint32_t param, uint8_t crc, uint8_t* dat, uint8_t* rsp) {
  515. uint8_t cmdbuf[6];
  516. cmdbuf[0] = 0x40 | cmd;
  517. cmdbuf[1] = param >> 24;
  518. cmdbuf[2] = param >> 16;
  519. cmdbuf[3] = param >> 8;
  520. cmdbuf[4] = param;
  521. if(!crc) {
  522. make_crc7(cmdbuf);
  523. } else {
  524. cmdbuf[5] = crc;
  525. }
  526. return send_command_slow(cmdbuf, rsp);
  527. }
  528. int acmd_slow(uint8_t cmd, uint32_t param, uint8_t crc, uint8_t* dat, uint8_t* rsp) {
  529. if(!(cmd_slow(APP_CMD, rca, 0, NULL, rsp))) {
  530. return 0;
  531. }
  532. return cmd_slow(cmd, param, crc, dat, rsp);
  533. }
  534. int cmd_fast(uint8_t cmd, uint32_t param, uint8_t crc, uint8_t* dat, uint8_t* rsp) {
  535. uint8_t cmdbuf[6];
  536. cmdbuf[0] = 0x40 | cmd;
  537. cmdbuf[1] = param >> 24;
  538. cmdbuf[2] = param >> 16;
  539. cmdbuf[3] = param >> 8;
  540. cmdbuf[4] = param;
  541. if(!crc) {
  542. make_crc7(cmdbuf);
  543. } else {
  544. cmdbuf[5] = crc;
  545. }
  546. return send_command_fast(cmdbuf, rsp, dat);
  547. }
  548. int acmd_fast(uint8_t cmd, uint32_t param, uint8_t crc, uint8_t* dat, uint8_t* rsp) {
  549. if(!(cmd_fast(APP_CMD, rca, 0, NULL, rsp))) {
  550. return 0;
  551. }
  552. return cmd_fast(cmd, param, crc, dat, rsp);
  553. }
  554. int stream_datablock(uint8_t *buf) {
  555. // uint8_t datshift=8;
  556. int j=512;
  557. uint8_t datdata=0;
  558. uint32_t timeout=1000000;
  559. DBG_SD printf("stream_datablock: wait for ready...\n");
  560. if(during_blocktrans != TRANS_MID) {
  561. while((BITBAND(SD_DAT0REG->FIOPIN, SD_DAT0PIN)) && --timeout) {
  562. wiggle_fast_neg1();
  563. }
  564. DBG_SD if(!timeout) printf("timeout!\n");
  565. wiggle_fast_neg1(); /* eat the start bit */
  566. }
  567. if(sd_offload) {
  568. if(sd_offload_partial) {
  569. if(sd_offload_partial_start != 0) {
  570. if(during_blocktrans == TRANS_MID) sd_offload_partial_start |= 0x8000;
  571. }
  572. if(sd_offload_partial_end != 512) {
  573. sd_offload_partial_end |= 0x8000;
  574. }
  575. DBG_SD printf("str partial %d - %d\n", sd_offload_partial_start, sd_offload_partial_end);
  576. fpga_set_sddma_range(sd_offload_partial_start, sd_offload_partial_end);
  577. fpga_sddma(sd_offload_tgt, 1);
  578. } else {
  579. fpga_sddma(sd_offload_tgt, 0);
  580. }
  581. } else {
  582. while(1) {
  583. datdata = SD_DAT << 4;
  584. wiggle_fast_neg1();
  585. datdata |= SD_DAT;
  586. wiggle_fast_neg1();
  587. *buf=datdata;
  588. buf++;
  589. j--;
  590. if(!j) break;
  591. }
  592. #ifdef CONFIG_SD_DATACRC
  593. return get_and_check_datacrc(buf-512);
  594. #else
  595. /* eat the crcs */
  596. wiggle_fast_neg(17);
  597. #endif
  598. }
  599. return 0;
  600. }
  601. void send_datablock(uint8_t *buf) {
  602. uint16_t crc0=0, crc1=0, crc2=0, crc3=0, cnt=512;
  603. uint8_t dat0=0, dat1=0, dat2=0, dat3=0, crcshift, datshift;
  604. wiggle_fast_pos1();
  605. BITBAND(SD_DAT0REG->FIODIR, SD_DAT0PIN) = 1;
  606. BITBAND(SD_DAT1REG->FIODIR, SD_DAT1PIN) = 1;
  607. BITBAND(SD_DAT2REG->FIODIR, SD_DAT2PIN) = 1;
  608. BITBAND(SD_DAT3REG->FIODIR, SD_DAT3PIN) = 1;
  609. BITBAND(SD_DAT0REG->FIOCLR, SD_DAT0PIN) = 1;
  610. BITBAND(SD_DAT1REG->FIOCLR, SD_DAT1PIN) = 1;
  611. BITBAND(SD_DAT2REG->FIOCLR, SD_DAT2PIN) = 1;
  612. BITBAND(SD_DAT3REG->FIOCLR, SD_DAT3PIN) = 1;
  613. wiggle_fast_pos1(); /* send start bit to card */
  614. crcshift=8;
  615. while(cnt--) {
  616. datshift=8;
  617. do {
  618. datshift-=4;
  619. /* if(((*buf)>>datshift) & 0x8) {
  620. BITBAND(SD_DAT3REG->FIOSET, SD_DAT3PIN) = 1;
  621. } else {
  622. BITBAND(SD_DAT3REG->FIOCLR, SD_DAT3PIN) = 1;
  623. }
  624. if(((*buf)>>datshift) & 0x4) {
  625. BITBAND(SD_DAT2REG->FIOSET, SD_DAT2PIN) = 1;
  626. } else {
  627. BITBAND(SD_DAT2REG->FIOCLR, SD_DAT2PIN) = 1;
  628. }
  629. if(((*buf)>>datshift) & 0x2){
  630. BITBAND(SD_DAT1REG->FIOSET, SD_DAT1PIN) = 1;
  631. } else {
  632. BITBAND(SD_DAT1REG->FIOCLR, SD_DAT1PIN) = 1;
  633. }
  634. if(((*buf)>>datshift) & 0x1){
  635. BITBAND(SD_DAT0REG->FIOSET, SD_DAT0PIN) = 1;
  636. } else {
  637. BITBAND(SD_DAT0REG->FIOCLR, SD_DAT0PIN) = 1;
  638. }*/
  639. SD_DAT0REG->FIOPIN0 = (*buf) >> datshift;
  640. wiggle_fast_pos1();
  641. } while (datshift);
  642. crcshift-=2;
  643. dat0 |= (((*buf)&0x01) | (((*buf)&0x10) >> 3)) << crcshift;
  644. dat1 |= ((((*buf)&0x02) >> 1) | (((*buf)&0x20) >> 4)) << crcshift;
  645. dat2 |= ((((*buf)&0x04) >> 2) | (((*buf)&0x40) >> 5)) << crcshift;
  646. dat3 |= ((((*buf)&0x08) >> 3) | (((*buf)&0x80) >> 6)) << crcshift;
  647. if(!crcshift) {
  648. crc0 = crc_xmodem_update(crc0, dat0);
  649. crc1 = crc_xmodem_update(crc1, dat1);
  650. crc2 = crc_xmodem_update(crc2, dat2);
  651. crc3 = crc_xmodem_update(crc3, dat3);
  652. crcshift=8;
  653. dat0=0;
  654. dat1=0;
  655. dat2=0;
  656. dat3=0;
  657. }
  658. buf++;
  659. }
  660. // printf("crc0=%04x crc1=%04x crc2=%04x crc3=%04x ", crc0, crc1, crc2, crc3);
  661. /* send crcs */
  662. datshift=16;
  663. do {
  664. datshift--;
  665. if((crc0 >> datshift) & 1) {
  666. BITBAND(SD_DAT0REG->FIOSET, SD_DAT0PIN) = 1;
  667. } else {
  668. BITBAND(SD_DAT0REG->FIOCLR, SD_DAT0PIN) = 1;
  669. }
  670. if((crc1 >> datshift) & 1) {
  671. BITBAND(SD_DAT1REG->FIOSET, SD_DAT1PIN) = 1;
  672. } else {
  673. BITBAND(SD_DAT1REG->FIOCLR, SD_DAT1PIN) = 1;
  674. }
  675. if((crc2 >> datshift) & 1) {
  676. BITBAND(SD_DAT2REG->FIOSET, SD_DAT2PIN) = 1;
  677. } else {
  678. BITBAND(SD_DAT2REG->FIOCLR, SD_DAT2PIN) = 1;
  679. }
  680. if((crc3 >> datshift) & 1) {
  681. BITBAND(SD_DAT3REG->FIOSET, SD_DAT3PIN) = 1;
  682. } else {
  683. BITBAND(SD_DAT3REG->FIOCLR, SD_DAT3PIN) = 1;
  684. }
  685. wiggle_fast_pos1();
  686. } while(datshift);
  687. /* send end bit */
  688. BITBAND(SD_DAT0REG->FIOSET, SD_DAT0PIN) = 1;
  689. BITBAND(SD_DAT1REG->FIOSET, SD_DAT1PIN) = 1;
  690. BITBAND(SD_DAT2REG->FIOSET, SD_DAT2PIN) = 1;
  691. BITBAND(SD_DAT3REG->FIOSET, SD_DAT3PIN) = 1;
  692. wiggle_fast_pos1();
  693. BITBAND(SD_DAT0REG->FIODIR, SD_DAT0PIN) = 0;
  694. BITBAND(SD_DAT1REG->FIODIR, SD_DAT1PIN) = 0;
  695. BITBAND(SD_DAT2REG->FIODIR, SD_DAT2PIN) = 0;
  696. BITBAND(SD_DAT3REG->FIODIR, SD_DAT3PIN) = 0;
  697. wiggle_fast_neg(3);
  698. dat0=0;
  699. datshift=4;
  700. do {
  701. datshift--;
  702. dat0 |= ((BITBAND(SD_DAT0REG->FIOPIN, SD_DAT0PIN)) << datshift);
  703. wiggle_fast_neg1();
  704. } while (datshift);
  705. DBG_SD printf("crc %02x\n", dat0);
  706. if((dat0 & 7) != 2) {
  707. printf("crc error! %02x\n", dat0);
  708. while(1);
  709. }
  710. if(dat0 & 8) {
  711. printf("missing start bit in CRC status response...\n");
  712. }
  713. wiggle_fast_neg(2);
  714. wait_busy();
  715. }
  716. void read_block(uint32_t address, uint8_t *buf) {
  717. DBG_SD printf("read_block addr=%08lx last_addr=%08lx offld=%d/%d offst=%04x offed=%04x last_off=%04x\n", address, last_block, sd_offload, sd_offload_partial, sd_offload_partial_start, sd_offload_partial_end, last_offset);
  718. if(during_blocktrans == TRANS_READ && (last_block == address-1)) {
  719. //uart_putc('r');
  720. #ifdef CONFIG_SD_DATACRC
  721. int cmd_res;
  722. if((cmd_res = stream_datablock(buf)) == CRC_ERROR) {
  723. while(cmd_res == CRC_ERROR) {
  724. cmd_fast(STOP_TRANSMISSION, 0, 0x61, NULL, rsp);
  725. cmd_res = cmd_fast(READ_MULTIPLE_BLOCK, address, 0, buf, rsp);
  726. }
  727. }
  728. #else
  729. stream_datablock(buf);
  730. #endif
  731. last_block = address;
  732. last_offset = sd_offload_partial_end & 0x1ff;
  733. if(sd_offload_partial && sd_offload_partial_end != 512) {
  734. during_blocktrans = TRANS_MID;
  735. }
  736. sd_offload_partial = 0;
  737. } else if (during_blocktrans == TRANS_MID
  738. && last_block == address
  739. && last_offset == sd_offload_partial_start
  740. && sd_offload_partial) {
  741. sd_offload_partial_start |= 0x8000;
  742. stream_datablock(buf);
  743. during_blocktrans = TRANS_READ;
  744. last_offset = sd_offload_partial_end & 0x1ff;
  745. sd_offload_partial = 0;
  746. } else {
  747. if(during_blocktrans) {
  748. // uart_putc('_');
  749. //printf("nonseq read (%lx -> %lx), restarting transmission\n", last_block, address);
  750. /* send STOP_TRANSMISSION to end an open READ/WRITE_MULTIPLE_BLOCK */
  751. cmd_fast(STOP_TRANSMISSION, 0, 0x61, NULL, rsp);
  752. }
  753. during_blocktrans = TRANS_READ;
  754. last_block = address;
  755. if(!ccs) {
  756. address <<= 9;
  757. }
  758. #ifdef CONFIG_SD_DATACRC
  759. while(1) {
  760. if(cmd_fast(READ_MULTIPLE_BLOCK, address, 0, buf, rsp) != CRC_ERROR) break;
  761. cmd_fast(STOP_TRANSMISSION, 0, 0x61, NULL, rsp);
  762. };
  763. #else
  764. cmd_fast(READ_MULTIPLE_BLOCK, address, 0, buf, rsp);
  765. #endif
  766. sd_offload_partial = 0;
  767. }
  768. // printf("trans state = %d\n", during_blocktrans);
  769. }
  770. void write_block(uint32_t address, uint8_t* buf) {
  771. if(during_blocktrans == TRANS_WRITE && (last_block == address-1)) {
  772. wait_busy();
  773. send_datablock(buf);
  774. last_block=address;
  775. } else {
  776. if(during_blocktrans) {
  777. /* send STOP_TRANSMISSION to end an open READ/WRITE_MULTIPLE_BLOCK */
  778. cmd_fast(STOP_TRANSMISSION, 0, 0x61, NULL, rsp);
  779. }
  780. wait_busy();
  781. last_block=address;
  782. if(!ccs) {
  783. address <<= 9;
  784. }
  785. /* only send cmd & get response */
  786. cmd_fast(WRITE_MULTIPLE_BLOCK, address, 0, NULL, rsp);
  787. DBG_SD printf("write_block: CMD25 response = %02x%02x%02x%02x%02x%02x\n", rsp[0], rsp[1], rsp[2], rsp[3], rsp[4], rsp[5]);
  788. wiggle_fast_pos(8);
  789. send_datablock(buf);
  790. during_blocktrans = TRANS_WRITE;
  791. }
  792. }
  793. //
  794. // Public functions
  795. //
  796. DRESULT sdn_read(BYTE drv, BYTE *buffer, DWORD sector, BYTE count) {
  797. uint8_t sec;
  798. if(drv >= MAX_CARDS) {
  799. return RES_PARERR;
  800. }
  801. readled(1);
  802. for(sec=0; sec<count; sec++) {
  803. read_block(sector+sec, buffer);
  804. buffer+=512;
  805. }
  806. readled(0);
  807. return RES_OK;
  808. }
  809. DRESULT disk_read(BYTE drv, BYTE *buffer, DWORD sector, BYTE count) __attribute__ ((weak, alias("sdn_read")));
  810. DRESULT sdn_initialize(BYTE drv) {
  811. uint8_t rsp[17]; /* space for response */
  812. int rsplen;
  813. uint8_t hcs=0;
  814. rca = 0;
  815. if(drv>=MAX_CARDS) {
  816. return STA_NOINIT|STA_NODISK;
  817. }
  818. if(sdn_status(drv) & STA_NODISK) {
  819. return STA_NOINIT|STA_NODISK;
  820. }
  821. /* if the card is sending data from before a reset we try to deselect it
  822. prior to initialization */
  823. for(rsplen=0; rsplen<2042; rsplen++) {
  824. if(!(BITBAND(SD_DAT3REG->FIOPIN, SD_DAT3PIN))) {
  825. printf("card seems to be sending data, attempting deselect\n");
  826. cmd_slow(SELECT_CARD, 0, 0, NULL, rsp);
  827. }
  828. wiggle_slow_neg(1);
  829. }
  830. printf("sd_init start\n");
  831. BITBAND(SD_DAT3REG->FIODIR, SD_DAT3PIN) = 1;
  832. BITBAND(SD_DAT3REG->FIOSET, SD_DAT3PIN) = 1;
  833. cmd_slow(GO_IDLE_STATE, 0, 0x95, NULL, rsp);
  834. if((rsplen=cmd_slow(SEND_IF_COND, 0x000001aa, 0x87, NULL, rsp))) {
  835. DBG_SD printf("CMD8 response:\n");
  836. DBG_SD uart_trace(rsp, 0, rsplen);
  837. hcs=1;
  838. }
  839. while(1) {
  840. if(!(acmd_slow(SD_SEND_OP_COND, (hcs << 30) | 0xfc0000, 0, NULL, rsp))) {
  841. printf("ACMD41 no response!\n");
  842. }
  843. if(rsp[1]&0x80) break;
  844. }
  845. BITBAND(SD_DAT3REG->FIODIR, SD_DAT3PIN) = 0;
  846. BITBAND(SD_DAT3REG->FIOCLR, SD_DAT3PIN) = 1;
  847. ccs = (rsp[1]>>6) & 1; /* SDHC/XC */
  848. cmd_slow(ALL_SEND_CID, 0, 0x4d, NULL, rsp);
  849. if(cmd_slow(SEND_RELATIVE_ADDR, 0, 0x21, NULL, rsp)) {
  850. rca=(rsp[1]<<24) | (rsp[2]<<16);
  851. printf("RCA: %04lx\n", rca>>16);
  852. } else {
  853. printf("CMD3 no response!\n");
  854. rca=0;
  855. }
  856. /* record CSD for getinfo */
  857. cmd_slow(SEND_CSD, rca, 0, NULL, csd);
  858. /* record CID */
  859. cmd_slow(SEND_CID, rca, 0, NULL, cid);
  860. /* select the card */
  861. if(cmd_slow(SELECT_CARD, rca, 0, NULL, rsp)) {
  862. printf("card selected!\n");
  863. } else {
  864. printf("CMD7 no response!\n");
  865. }
  866. /* get card status */
  867. cmd_slow(SEND_STATUS, rca, 0, NULL, rsp);
  868. /* set bus width */
  869. acmd_slow(SD_SET_BUS_WIDTH, 0x2, 0, NULL, rsp);
  870. /* set block length */
  871. cmd_slow(SET_BLOCKLEN, 0x200, 0, NULL, rsp);
  872. printf("SD init complete. SDHC/XC=%d\n", ccs);
  873. disk_state = DISK_OK;
  874. during_blocktrans = TRANS_NONE;
  875. return sdn_status(drv);
  876. }
  877. DSTATUS disk_initialize(BYTE drv) __attribute__ ((weak, alias("sdn_initialize")));
  878. void sdn_init(void) {
  879. /* enable GPIO interrupt on SD detect pin, both edges */
  880. /* NVIC_EnableIRQ(EINT3_IRQn);
  881. SD_DT_INT_SETUP(); */
  882. /* disconnect SSP1 */
  883. LPC_PINCON->PINSEL0 &= ~(BV(13) | BV(15) | BV(17) | BV(19));
  884. /* prepare GPIOs */
  885. BITBAND(SD_DAT3REG->FIODIR, SD_DAT3PIN) = 0;
  886. BITBAND(SD_DAT2REG->FIODIR, SD_DAT2PIN) = 0;
  887. BITBAND(SD_DAT1REG->FIODIR, SD_DAT1PIN) = 0;
  888. BITBAND(SD_DAT0REG->FIODIR, SD_DAT0PIN) = 0;
  889. BITBAND(SD_CLKREG->FIODIR, SD_CLKPIN) = 1;
  890. BITBAND(SD_CMDREG->FIODIR, SD_CMDPIN) = 1;
  891. BITBAND(SD_CMDREG->FIOPIN, SD_CMDPIN) = 1;
  892. LPC_GPIO2->FIOPIN0 = 0x00;
  893. LPC_GPIO2->FIOMASK0 = ~0xf;
  894. }
  895. void disk_init(void) __attribute__ ((weak, alias("sdn_init")));
  896. DSTATUS sdn_status(BYTE drv) {
  897. if (SDCARD_DETECT) {
  898. if (SDCARD_WP) {
  899. return STA_PROTECT;
  900. } else {
  901. return RES_OK;
  902. }
  903. } else {
  904. return STA_NOINIT|STA_NODISK;
  905. }
  906. }
  907. DSTATUS disk_status(BYTE drv) __attribute__ ((weak, alias("sdn_status")));
  908. DRESULT sdn_getinfo(BYTE drv, BYTE page, void *buffer) {
  909. uint32_t capacity;
  910. if (drv >= MAX_CARDS) {
  911. return RES_NOTRDY;
  912. }
  913. if (sdn_status(drv) & STA_NODISK) {
  914. return RES_NOTRDY;
  915. }
  916. if (page != 0) {
  917. return RES_ERROR;
  918. }
  919. if (ccs) {
  920. /* Special CSD for SDHC cards */
  921. capacity = (1 + getbits(csd,127-69+8,22)) * 1024;
  922. } else {
  923. /* Assume that MMC-CSD 1.0/1.1/1.2 and SD-CSD 1.1 are the same... */
  924. uint8_t exponent = 2 + getbits(csd, 127-49+8, 3);
  925. capacity = 1 + getbits(csd, 127-73+8, 12);
  926. exponent += getbits(csd, 127-83+8,4) - 9;
  927. while (exponent--) capacity *= 2;
  928. }
  929. diskinfo0_t *di = buffer;
  930. di->validbytes = sizeof(diskinfo0_t);
  931. di->disktype = DISK_TYPE_SD;
  932. di->sectorsize = 2;
  933. di->sectorcount = capacity;
  934. printf("card capacity: %lu sectors\n", capacity);
  935. return RES_OK;
  936. }
  937. DRESULT disk_getinfo(BYTE drv, BYTE page, void *buffer) __attribute__ ((weak, alias("sdn_getinfo")));
  938. DRESULT sdn_write(BYTE drv, const BYTE *buffer, DWORD sector, BYTE count) {
  939. uint8_t sec;
  940. uint8_t *buf = (uint8_t*)buffer;
  941. if(drv >= MAX_CARDS) {
  942. return RES_NOTRDY;
  943. }
  944. if (sdn_status(drv) & STA_NODISK) {
  945. return RES_NOTRDY;
  946. }
  947. writeled(1);
  948. for(sec=0; sec<count; sec++) {
  949. write_block(sector+sec, buf);
  950. buf+=512;
  951. }
  952. writeled(0);
  953. return RES_OK;
  954. }
  955. DRESULT disk_write(BYTE drv, const BYTE *buffer, DWORD sector, BYTE count) __attribute__ ((weak, alias("sdn_write")));
  956. /* Detect changes of SD card 0 */
  957. void sdn_changed() {
  958. if (sd_changed) {
  959. printf("ch ");
  960. if(SDCARD_DETECT) {
  961. disk_state = DISK_CHANGED;
  962. } else {
  963. disk_state = DISK_REMOVED;
  964. }
  965. sd_changed = 0;
  966. }
  967. }