Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285
  1. // adapted for Arduino SD library by Paul Stoffregen
  2. // following code is modified by Walter Zimmer from
  3. // from version provided by
  4. // Petr Gargulak (NXP Employee)
  5. //https://community.nxp.com/servlet/JiveServlet/download/339474-1-263510/SDHC_K60_Baremetal.ZIP
  6. //see also
  7. //https://community.nxp.com/thread/99202
  8. #if defined(__MK64FX512__) || defined(__MK66FX1M0__) || defined(__IMXRT1052__)
  9. #include "core_pins.h" // include calls to kinetis.h or imxrt.h
  10. #include "usb_serial.h" // for Serial
  11. #include "NXP_SDHC.h"
  12. // Missing in Teensyduino 1.30
  13. #ifndef MPU_CESR_VLD_MASK
  14. #define MPU_CESR_VLD_MASK 0x1u
  15. #endif
  16. /******************************************************************************
  17. Constants
  18. ******************************************************************************/
  19. enum {
  20. SDHC_RESULT_OK = 0, /* 0: Successful */
  21. SDHC_RESULT_ERROR, /* 1: R/W Error */
  22. SDHC_RESULT_WRPRT, /* 2: Write Protected */
  23. SDHC_RESULT_NOT_READY, /* 3: Not Ready */
  24. SDHC_RESULT_PARERR, /* 4: Invalid Parameter */
  25. SDHC_RESULT_NO_RESPONSE /* 5: No Response */ // from old diskio.h
  26. };
  27. /*void print_result(int n)
  28. {
  29. switch (n) {
  30. case SDHC_RESULT_OK: serial_print("OK\n"); break;
  31. case SDHC_RESULT_ERROR: serial_print("R/W Error\n"); break;
  32. case SDHC_RESULT_WRPRT: serial_print("Write Protect\n"); break;
  33. case SDHC_RESULT_NOT_READY: serial_print("Not Ready\n"); break;
  34. case SDHC_RESULT_PARERR: serial_print("Invalid Param\n"); break;
  35. case SDHC_RESULT_NO_RESPONSE: serial_print("No Response\n"); break;
  36. default: serial_print("Unknown result\n");
  37. }
  38. }*/
  39. #define IO_SDHC_ATTRIBS (IO_DEV_ATTR_READ | IO_DEV_ATTR_REMOVE | IO_DEV_ATTR_SEEK | IO_DEV_ATTR_WRITE | IO_DEV_ATTR_BLOCK_MODE)
  40. #define SDHC_XFERTYP_RSPTYP_NO (0x00)
  41. #define SDHC_XFERTYP_RSPTYP_136 (0x01)
  42. #define SDHC_XFERTYP_RSPTYP_48 (0x02)
  43. #define SDHC_XFERTYP_RSPTYP_48BUSY (0x03)
  44. #define SDHC_XFERTYP_CMDTYP_ABORT (0x03)
  45. #define SDHC_PROCTL_EMODE_INVARIANT (0x02)
  46. #define SDHC_PROCTL_DTW_1BIT (0x00)
  47. #define SDHC_PROCTL_DTW_4BIT (0x01)
  48. #define SDHC_PROCTL_DTW_8BIT (0x10)
  49. #define SDHC_INITIALIZATION_MAX_CNT 100000
  50. /* SDHC commands */
  51. #define SDHC_CMD0 (0)
  52. #define SDHC_CMD1 (1)
  53. #define SDHC_CMD2 (2)
  54. #define SDHC_CMD3 (3)
  55. #define SDHC_CMD4 (4)
  56. #define SDHC_CMD5 (5)
  57. #define SDHC_CMD6 (6)
  58. #define SDHC_CMD7 (7)
  59. #define SDHC_CMD8 (8)
  60. #define SDHC_CMD9 (9)
  61. #define SDHC_CMD10 (10)
  62. #define SDHC_CMD11 (11)
  63. #define SDHC_CMD12 (12)
  64. #define SDHC_CMD13 (13)
  65. #define SDHC_CMD15 (15)
  66. #define SDHC_CMD16 (16)
  67. #define SDHC_CMD17 (17)
  68. #define SDHC_CMD18 (18)
  69. #define SDHC_CMD20 (20)
  70. #define SDHC_CMD24 (24)
  71. #define SDHC_CMD25 (25)
  72. #define SDHC_CMD26 (26)
  73. #define SDHC_CMD27 (27)
  74. #define SDHC_CMD28 (28)
  75. #define SDHC_CMD29 (29)
  76. #define SDHC_CMD30 (30)
  77. #define SDHC_CMD32 (32)
  78. #define SDHC_CMD33 (33)
  79. #define SDHC_CMD34 (34)
  80. #define SDHC_CMD35 (35)
  81. #define SDHC_CMD36 (36)
  82. #define SDHC_CMD37 (37)
  83. #define SDHC_CMD38 (38)
  84. #define SDHC_CMD39 (39)
  85. #define SDHC_CMD40 (40)
  86. #define SDHC_CMD42 (42)
  87. #define SDHC_CMD52 (52)
  88. #define SDHC_CMD53 (53)
  89. #define SDHC_CMD55 (55)
  90. #define SDHC_CMD56 (56)
  91. #define SDHC_CMD59 (59)
  92. #define SDHC_CMD60 (60)
  93. #define SDHC_CMD61 (61)
  94. #define SDHC_ACMD6 (0x40 + 6)
  95. #define SDHC_ACMD13 (0x40 + 13)
  96. #define SDHC_ACMD22 (0x40 + 22)
  97. #define SDHC_ACMD23 (0x40 + 23)
  98. #define SDHC_ACMD41 (0x40 + 41)
  99. #define SDHC_ACMD42 (0x40 + 42)
  100. #define SDHC_ACMD51 (0x40 + 51)
  101. #define SDHC_FIFO_BUFFER_SIZE 16
  102. #define SDHC_BLOCK_SIZE 512
  103. #if defined(__IMXRT1052__)
  104. #define MAKE_REG_MASK(m,s) (((uint32_t)(((uint32_t)(m) << s))))
  105. #define MAKE_REG_GET(x,m,s) (((uint32_t)(((uint32_t)(x)>>s) & m)))
  106. #define MAKE_REG_SET(x,m,s) (((uint32_t)(((uint32_t)(x) & m) << s)))
  107. #define SDHC_BLKATTR_BLKSIZE_MASK MAKE_REG_MASK(0x1FFF,0) //uint32_t)(((n) & 0x1FFF)<<0) // Transfer Block Size Mask
  108. #define SDHC_BLKATTR_BLKSIZE(n) MAKE_REG_SET(n,0x1FFF,0) //uint32_t)(((n) & 0x1FFF)<<0) // Transfer Block Size
  109. #define SDHC_BLKATTR_BLKCNT_MASK MAKE_REG_MASK(0x1FFF,16) //((uint32_t)0x1FFF<<16)
  110. #define SDHC_BLKATTR_BLKCNT(n) MAKE_REG_SET(n,0x1FFF,16) //(uint32_t)(((n) & 0x1FFF)<<16) // Blocks Count For Current Transfer
  111. #define SDHC_XFERTYP_CMDINX(n) MAKE_REG_SET(n,0x3F,24) //(uint32_t)(((n) & 0x3F)<<24)// Command Index
  112. #define SDHC_XFERTYP_CMDTYP(n) MAKE_REG_SET(n,0x3,22) //(uint32_t)(((n) & 0x3)<<22) // Command Type
  113. #define SDHC_XFERTYP_DPSEL MAKE_REG_MASK(0x1,21) //((uint32_t)0x00200000) // Data Present Select
  114. #define SDHC_XFERTYP_CICEN MAKE_REG_MASK(0x1,20) //((uint32_t)0x00100000) // Command Index Check Enable
  115. #define SDHC_XFERTYP_CCCEN MAKE_REG_MASK(0x1,19) //((uint32_t)0x00080000) // Command CRC Check Enable
  116. #define SDHC_XFERTYP_RSPTYP(n) MAKE_REG_SET(n,0x3,16) //(uint32_t)(((n) & 0x3)<<16) // Response Type Select
  117. #define SDHC_XFERTYP_MSBSEL MAKE_REG_MASK(0x1,5) //((uint32_t)0x00000020) // Multi/Single Block Select
  118. #define SDHC_XFERTYP_DTDSEL MAKE_REG_MASK(0x1,4) //((uint32_t)0x00000010) // Data Transfer Direction Select
  119. #define SDHC_XFERTYP_AC12EN MAKE_REG_MASK(0x1,2) //((uint32_t)0x00000004) // Auto CMD12 Enable
  120. #define SDHC_XFERTYP_BCEN MAKE_REG_MASK(0x1,1) //((uint32_t)0x00000002) // Block Count Enable
  121. #define SDHC_XFERTYP_DMAEN MAKE_REG_MASK(0x3,0) //((uint32_t)0x00000001) // DMA Enable
  122. #define SDHC_PRSSTAT_DLSL_MASK MAKE_REG_MASK(0xFF,24) //((uint32_t)0xFF000000) // DAT Line Signal Level
  123. #define SDHC_PRSSTAT_CLSL MAKE_REG_MASK(0x1,23) //((uint32_t)0x00800000) // CMD Line Signal Level
  124. #define SDHC_PRSSTAT_WPSPL MAKE_REG_MASK(0x1,19) //
  125. #define SDHC_PRSSTAT_CDPL MAKE_REG_MASK(0x1,18) //
  126. #define SDHC_PRSSTAT_CINS MAKE_REG_MASK(0x1,16) //((uint32_t)0x00010000) // Card Inserted
  127. #define SDHC_PRSSTAT_TSCD MAKE_REG_MASK(0x1,15)
  128. #define SDHC_PRSSTAT_RTR MAKE_REG_MASK(0x1,12)
  129. #define SDHC_PRSSTAT_BREN MAKE_REG_MASK(0x1,11) //((uint32_t)0x00000800) // Buffer Read Enable
  130. #define SDHC_PRSSTAT_BWEN MAKE_REG_MASK(0x1,10) //((uint32_t)0x00000400) // Buffer Write Enable
  131. #define SDHC_PRSSTAT_RTA MAKE_REG_MASK(0x1,9) //((uint32_t)0x00000200) // Read Transfer Active
  132. #define SDHC_PRSSTAT_WTA MAKE_REG_MASK(0x1,8) //((uint32_t)0x00000100) // Write Transfer Active
  133. #define SDHC_PRSSTAT_SDOFF MAKE_REG_MASK(0x1,7) //((uint32_t)0x00000080) // SD Clock Gated Off Internally
  134. #define SDHC_PRSSTAT_PEROFF MAKE_REG_MASK(0x1,6) //((uint32_t)0x00000040) // SDHC clock Gated Off Internally
  135. #define SDHC_PRSSTAT_HCKOFF MAKE_REG_MASK(0x1,5) //((uint32_t)0x00000020) // System Clock Gated Off Internally
  136. #define SDHC_PRSSTAT_IPGOFF MAKE_REG_MASK(0x1,4) //((uint32_t)0x00000010) // Bus Clock Gated Off Internally
  137. #define SDHC_PRSSTAT_SDSTB MAKE_REG_MASK(0x1,3) //((uint32_t)0x00000008) // SD Clock Stable
  138. #define SDHC_PRSSTAT_DLA MAKE_REG_MASK(0x1,2) //((uint32_t)0x00000004) // Data Line Active
  139. #define SDHC_PRSSTAT_CDIHB MAKE_REG_MASK(0x1,1) //((uint32_t)0x00000002) // Command Inhibit (DAT)
  140. #define SDHC_PRSSTAT_CIHB MAKE_REG_MASK(0x1,0) //((uint32_t)0x00000001) // Command Inhibit (CMD)
  141. #define SDHC_PROTCT_NONEXACT_BLKRD MAKE_REG_MASK(0x1,30) //
  142. #define SDHC_PROTCT_BURST_LENEN(n) MAKE_REG_SET(n,0x7,12) //
  143. #define SDHC_PROCTL_WECRM MAKE_REG_MASK(0x1,26) //((uint32_t)0x04000000) // Wakeup Event Enable On SD Card Removal
  144. #define SDHC_PROCTL_WECINS MAKE_REG_MASK(0x1,25) //((uint32_t)0x02000000) // Wakeup Event Enable On SD Card Insertion
  145. #define SDHC_PROCTL_WECINT MAKE_REG_MASK(0x1,24) //((uint32_t)0x01000000) // Wakeup Event Enable On Card Interrupt
  146. #define SDHC_PROCTL_RD_DONE_NOBLK MAKE_REG_MASK(0x1,20) //
  147. #define SDHC_PROCTL_IABG MAKE_REG_MASK(0x1,19) //((uint32_t)0x00080000) // Interrupt At Block Gap
  148. #define SDHC_PROCTL_RWCTL MAKE_REG_MASK(0x1,18) //((uint32_t)0x00040000) // Read Wait Control
  149. #define SDHC_PROCTL_CREQ MAKE_REG_MASK(0x1,17) //((uint32_t)0x00020000) // Continue Request
  150. #define SDHC_PROCTL_SABGREQ MAKE_REG_MASK(0x1,16) //((uint32_t)0x00010000) // Stop At Block Gap Request
  151. #define SDHC_PROCTL_DMAS(n) MAKE_REG_SET(n,0x3,8) //(uint32_t)(((n) & 0x3)<<8) // DMA Select
  152. #define SDHC_PROCTL_CDSS MAKE_REG_MASK(0x1,7) //((uint32_t)0x00000080) // Card Detect Signal Selection
  153. #define SDHC_PROCTL_CDTL MAKE_REG_MASK(0x1,6) //((uint32_t)0x00000040) // Card Detect Test Level
  154. #define SDHC_PROCTL_EMODE(n) MAKE_REG_SET(n,0x3,4) //(uint32_t)(((n) & 0x3)<<4) // Endian Mode
  155. #define SDHC_PROCTL_EMODE_MASK MAKE_REG_MASK(0x3,4) //(uint32_t)((0x3)<<4) // Endian Mode
  156. #define SDHC_PROCTL_D3CD MAKE_REG_MASK(0x1,3) //((uint32_t)0x00000008) // DAT3 As Card Detection Pin
  157. #define SDHC_PROCTL_DTW(n) MAKE_REG_SET(n,0x3,1) //(uint32_t)(((n) & 0x3)<<1) // Data Transfer Width, 0=1bit, 1=4bit, 2=8bit
  158. #define SDHC_PROCTL_DTW_MASK MAKE_REG_MASK(0x3,1) //((uint32_t)0x00000006)
  159. #define SDHC_PROCTL_LCTL MAKE_REG_MASK(0x1,0) //((uint32_t)0x00000001) // LED Control
  160. #define SDHC_SYSCTL_RSTT MAKE_REG_MASK(0x1,28) //
  161. #define SDHC_SYSCTL_INITA MAKE_REG_MASK(0x1,27) //((uint32_t)0x08000000) // Initialization Active
  162. #define SDHC_SYSCTL_RSTD MAKE_REG_MASK(0x1,26) //((uint32_t)0x04000000) // Software Reset For DAT Line
  163. #define SDHC_SYSCTL_RSTC MAKE_REG_MASK(0x1,25) //((uint32_t)0x02000000) // Software Reset For CMD Line
  164. #define SDHC_SYSCTL_RSTA MAKE_REG_MASK(0x1,24) //((uint32_t)0x01000000) // Software Reset For ALL
  165. #define SDHC_SYSCTL_DTOCV(n) MAKE_REG_SET(n,0xF,16) //(uint32_t)(((n) & 0xF)<<16) // Data Timeout Counter Value
  166. #define SDHC_SYSCTL_DTOCV_MASK MAKE_REG_MASK(0xF,16) //((uint32_t)0x000F0000)
  167. #define SDHC_SYSCTL_SDCLKFS(n) MAKE_REG_SET(n,0xFF,8) //(uint32_t)(((n) & 0xFF)<<8) // SDCLK Frequency Select
  168. #define SDHC_SYSCTL_SDCLKFS_MASK MAKE_REG_MASK(0xFF,8) //((uint32_t)0x0000FF00)
  169. #define SDHC_SYSCTL_DVS(n) MAKE_REG_SET(n,0xF,4) //(uint32_t)(((n) & 0xF)<<4) // Divisor
  170. #define SDHC_SYSCTL_DVS_MASK MAKE_REG_MASK(0xF,4) //((uint32_t)0x000000F0)
  171. #define SDHC_SYSCTL_SDCLKEN ((uint32_t)0x00000008) // SD Clock Enable
  172. #define SDHC_SYSCTL_PEREN ((uint32_t)0x00000004) // Peripheral Clock Enable
  173. #define SDHC_SYSCTL_HCKEN ((uint32_t)0x00000002) // System Clock Enable
  174. #define SDHC_SYSCTL_IPGEN ((uint32_t)0x00000001) // IPG Clock Enable
  175. #define SDHC_IRQSTAT_DMAE MAKE_REG_MASK(0x1,28) //((uint32_t)0x10000000) // DMA Error
  176. #define SDHC_IRQSTAT_TNE MAKE_REG_MASK(0x1,26) //
  177. #define SDHC_IRQSTAT_AC12E MAKE_REG_MASK(0x1,24) //((uint32_t)0x01000000) // Auto CMD12 Error
  178. #define SDHC_IRQSTAT_DEBE MAKE_REG_MASK(0x1,22) //((uint32_t)0x00400000) // Data End Bit Error
  179. #define SDHC_IRQSTAT_DCE MAKE_REG_MASK(0x1,21) //((uint32_t)0x00200000) // Data CRC Error
  180. #define SDHC_IRQSTAT_DTOE MAKE_REG_MASK(0x1,20) //((uint32_t)0x00100000) // Data Timeout Error
  181. #define SDHC_IRQSTAT_CIE MAKE_REG_MASK(0x1,19) //((uint32_t)0x00080000) // Command Index Error
  182. #define SDHC_IRQSTAT_CEBE MAKE_REG_MASK(0x1,18) //((uint32_t)0x00040000) // Command End Bit Error
  183. #define SDHC_IRQSTAT_CCE MAKE_REG_MASK(0x1,17) //((uint32_t)0x00020000) // Command CRC Error
  184. #define SDHC_IRQSTAT_CTOE MAKE_REG_MASK(0x1,16) //((uint32_t)0x00010000) // Command Timeout Error
  185. #define SDHC_IRQSTAT_TP MAKE_REG_MASK(0x1,14) //
  186. #define SDHC_IRQSTAT_RTE MAKE_REG_MASK(0x1,12) //
  187. #define SDHC_IRQSTAT_CINT MAKE_REG_MASK(0x1,8) //((uint32_t)0x00000100) // Card Interrupt
  188. #define SDHC_IRQSTAT_CRM MAKE_REG_MASK(0x1,7) //((uint32_t)0x00000080) // Card Removal
  189. #define SDHC_IRQSTAT_CINS MAKE_REG_MASK(0x1,6) //((uint32_t)0x00000040) // Card Insertion
  190. #define SDHC_IRQSTAT_BRR MAKE_REG_MASK(0x1,5) //((uint32_t)0x00000020) // Buffer Read Ready
  191. #define SDHC_IRQSTAT_BWR MAKE_REG_MASK(0x1,4) //((uint32_t)0x00000010) // Buffer Write Ready
  192. #define SDHC_IRQSTAT_DINT MAKE_REG_MASK(0x1,3) //((uint32_t)0x00000008) // DMA Interrupt
  193. #define SDHC_IRQSTAT_BGE MAKE_REG_MASK(0x1,2) //((uint32_t)0x00000004) // Block Gap Event
  194. #define SDHC_IRQSTAT_TC MAKE_REG_MASK(0x1,1) //((uint32_t)0x00000002) // Transfer Complete
  195. #define SDHC_IRQSTAT_CC MAKE_REG_MASK(0x1,0) //((uint32_t)0x00000001) // Command Complete
  196. #define SDHC_IRQSTATEN_DMAESEN MAKE_REG_MASK(0x1,28) //((uint32_t)0x10000000) // DMA Error Status Enable
  197. #define SDHC_IRQSTATEN_TNESEN MAKE_REG_MASK(0x1,26) //
  198. #define SDHC_IRQSTATEN_AC12ESEN MAKE_REG_MASK(0x1,24) //((uint32_t)0x01000000) // Auto CMD12 Error Status Enable
  199. #define SDHC_IRQSTATEN_DEBESEN MAKE_REG_MASK(0x1,22) //((uint32_t)0x00400000) // Data End Bit Error Status Enable
  200. #define SDHC_IRQSTATEN_DCESEN MAKE_REG_MASK(0x1,21) //((uint32_t)0x00200000) // Data CRC Error Status Enable
  201. #define SDHC_IRQSTATEN_DTOESEN MAKE_REG_MASK(0x1,20) //((uint32_t)0x00100000) // Data Timeout Error Status Enable
  202. #define SDHC_IRQSTATEN_CIESEN MAKE_REG_MASK(0x1,19) //((uint32_t)0x00080000) // Command Index Error Status Enable
  203. #define SDHC_IRQSTATEN_CEBESEN MAKE_REG_MASK(0x1,18) //((uint32_t)0x00040000) // Command End Bit Error Status Enable
  204. #define SDHC_IRQSTATEN_CCESEN MAKE_REG_MASK(0x1,17) //((uint32_t)0x00020000) // Command CRC Error Status Enable
  205. #define SDHC_IRQSTATEN_CTOESEN MAKE_REG_MASK(0x1,16) //((uint32_t)0x00010000) // Command Timeout Error Status Enable
  206. #define SDHC_IRQSTATEN_TPSEN MAKE_REG_MASK(0x1,14) //
  207. #define SDHC_IRQSTATEN_RTESEN MAKE_REG_MASK(0x1,12) //
  208. #define SDHC_IRQSTATEN_CINTSEN MAKE_REG_MASK(0x1,8) //((uint32_t)0x00000100) // Card Interrupt Status Enable
  209. #define SDHC_IRQSTATEN_CRMSEN MAKE_REG_MASK(0x1,7) //((uint32_t)0x00000080) // Card Removal Status Enable
  210. #define SDHC_IRQSTATEN_CINSEN MAKE_REG_MASK(0x1,6) //((uint32_t)0x00000040) // Card Insertion Status Enable
  211. #define SDHC_IRQSTATEN_BRRSEN MAKE_REG_MASK(0x1,5) //((uint32_t)0x00000020) // Buffer Read Ready Status Enable
  212. #define SDHC_IRQSTATEN_BWRSEN MAKE_REG_MASK(0x1,4) //((uint32_t)0x00000010) // Buffer Write Ready Status Enable
  213. #define SDHC_IRQSTATEN_DINTSEN MAKE_REG_MASK(0x1,3) //((uint32_t)0x00000008) // DMA Interrupt Status Enable
  214. #define SDHC_IRQSTATEN_BGESEN MAKE_REG_MASK(0x1,2) //((uint32_t)0x00000004) // Block Gap Event Status Enable
  215. #define SDHC_IRQSTATEN_TCSEN MAKE_REG_MASK(0x1,1) //((uint32_t)0x00000002) // Transfer Complete Status Enable
  216. #define SDHC_IRQSTATEN_CCSEN MAKE_REG_MASK(0x1,0) //((uint32_t)0x00000001) // Command Complete Status Enable
  217. #define SDHC_IRQSIGEN_DMAEIEN MAKE_REG_MASK(0x1,28) //((uint32_t)0x10000000) // DMA Error Interrupt Enable
  218. #define SDHC_IRQSIGEN_TNEIEN MAKE_REG_MASK(0x1,26) //
  219. #define SDHC_IRQSIGEN_AC12EIEN MAKE_REG_MASK(0x1,24) //((uint32_t)0x01000000) // Auto CMD12 Error Interrupt Enable
  220. #define SDHC_IRQSIGEN_DEBEIEN MAKE_REG_MASK(0x1,22) //((uint32_t)0x00400000) // Data End Bit Error Interrupt Enable
  221. #define SDHC_IRQSIGEN_DCEIEN MAKE_REG_MASK(0x1,21) //((uint32_t)0x00200000) // Data CRC Error Interrupt Enable
  222. #define SDHC_IRQSIGEN_DTOEIEN MAKE_REG_MASK(0x1,20) //((uint32_t)0x00100000) // Data Timeout Error Interrupt Enable
  223. #define SDHC_IRQSIGEN_CIEIEN MAKE_REG_MASK(0x1,19) //((uint32_t)0x00080000) // Command Index Error Interrupt Enable
  224. #define SDHC_IRQSIGEN_CEBEIEN MAKE_REG_MASK(0x1,18) //((uint32_t)0x00040000) // Command End Bit Error Interrupt Enable
  225. #define SDHC_IRQSIGEN_CCEIEN MAKE_REG_MASK(0x1,17) //((uint32_t)0x00020000) // Command CRC Error Interrupt Enable
  226. #define SDHC_IRQSIGEN_CTOEIEN MAKE_REG_MASK(0x1,16) //((uint32_t)0x00010000) // Command Timeout Error Interrupt Enable
  227. #define SDHC_IRQSIGEN_TPIEN MAKE_REG_MASK(0x1,14) //
  228. #define SDHC_IRQSIGEN_RTEIEN MAKE_REG_MASK(0x1,12) //
  229. #define SDHC_IRQSIGEN_CINTIEN MAKE_REG_MASK(0x1,8) //((uint32_t)0x00000100) // Card Interrupt Interrupt Enable
  230. #define SDHC_IRQSIGEN_CRMIEN MAKE_REG_MASK(0x1,7) //((uint32_t)0x00000080) // Card Removal Interrupt Enable
  231. #define SDHC_IRQSIGEN_CINSIEN MAKE_REG_MASK(0x1,6) //((uint32_t)0x00000040) // Card Insertion Interrupt Enable
  232. #define SDHC_IRQSIGEN_BRRIEN MAKE_REG_MASK(0x1,5) //((uint32_t)0x00000020) // Buffer Read Ready Interrupt Enable
  233. #define SDHC_IRQSIGEN_BWRIEN MAKE_REG_MASK(0x1,4) //((uint32_t)0x00000010) // Buffer Write Ready Interrupt Enable
  234. #define SDHC_IRQSIGEN_DINTIEN MAKE_REG_MASK(0x1,3) //((uint32_t)0x00000008) // DMA Interrupt Interrupt Enable
  235. #define SDHC_IRQSIGEN_BGEIEN MAKE_REG_MASK(0x1,2) //((uint32_t)0x00000004) // Block Gap Event Interrupt Enable
  236. #define SDHC_IRQSIGEN_TCIEN MAKE_REG_MASK(0x1,1) //((uint32_t)0x00000002) // Transfer Complete Interrupt Enable
  237. #define SDHC_IRQSIGEN_CCIEN MAKE_REG_MASK(0x1,0) //((uint32_t)0x00000001) // Command Complete Interrupt Enable
  238. #define SDHC_AC12ERR_SMPLCLK_SEL MAKE_REG_MASK(0x1,23) //
  239. #define SDHC_AC12ERR_EXEC_TUNING MAKE_REG_MASK(0x1,22) //
  240. #define SDHC_AC12ERR_CNIBAC12E MAKE_REG_MASK(0x1,7) //((uint32_t)0x00000080) // Command Not Issued By Auto CMD12 Error
  241. #define SDHC_AC12ERR_AC12IE MAKE_REG_MASK(0x1,4) //((uint32_t)0x00000010) // Auto CMD12 Index Error
  242. #define SDHC_AC12ERR_AC12CE MAKE_REG_MASK(0x1,3) //((uint32_t)0x00000008) // Auto CMD12 CRC Error
  243. #define SDHC_AC12ERR_AC12EBE MAKE_REG_MASK(0x1,2) //((uint32_t)0x00000004) // Auto CMD12 End Bit Error
  244. #define SDHC_AC12ERR_AC12TOE MAKE_REG_MASK(0x1,1) //((uint32_t)0x00000002) // Auto CMD12 Timeout Error
  245. #define SDHC_AC12ERR_AC12NE MAKE_REG_MASK(0x1,0) //((uint32_t)0x00000001) // Auto CMD12 Not Executed
  246. #define SDHC_HTCAPBLT_VS18 MAKE_REG_MASK(0x1,26) //
  247. #define SDHC_HTCAPBLT_VS30 MAKE_REG_MASK(0x1,25) //
  248. #define SDHC_HTCAPBLT_VS33 MAKE_REG_MASK(0x1,24) //
  249. #define SDHC_HTCAPBLT_SRS MAKE_REG_MASK(0x1,23) //
  250. #define SDHC_HTCAPBLT_DMAS MAKE_REG_MASK(0x1,22) //
  251. #define SDHC_HTCAPBLT_HSS MAKE_REG_MASK(0x1,21) //
  252. #define SDHC_HTCAPBLT_ADMAS MAKE_REG_MASK(0x1,20) //
  253. #define SDHC_HTCAPBLT_MBL_VAL MAKE_REG_GET((USDHC1_HOST_CTRL_CAP),0x7,16) //
  254. #define SDHC_HTCAPBLT_RETUN_MODE MAKE_REG_GET((USDHC1_HOST_CTRL_CAP),0x3,14) //
  255. #define SDHC_HTCAPBLT_TUNE_SDR50 MAKE_REG_MASK(0x1,13) //
  256. #define SDHC_HTCAPBLT_TIME_RETUN(n) MAKE_REG_SET(n,0xF,8) //
  257. #define SDHC_WML_WR_BRSTLEN_MASK MAKE_REG_MASK(0x1F,24) //
  258. #define SDHC_WML_RD_BRSTLEN_MASK MAKE_REG_MASK(0x1F,8) //
  259. #define SDHC_WML_WR_WML_MASK MAKE_REG_MASK(0xFF,16) //
  260. #define SDHC_WML_RD_WML_MASK MAKE_REG_MASK(0xFF,0) //
  261. #define SDHC_WML_WR_BRSTLEN(n) MAKE_REG_SET(n,0x1F,24) //(uint32_t)(((n) & 0x7F)<<16) // Write Burst Len
  262. #define SDHC_WML_RD_BRSTLEN(n) MAKE_REG_SET(n,0x1F,8) //(uint32_t)(((n) & 0x7F)<<0) // Read Burst Len
  263. #define SDHC_WML_WR_WML(n) MAKE_REG_SET(n,0xFF,16) //(uint32_t)(((n) & 0x7F)<<16) // Write Watermark Level
  264. #define SDHC_WML_RD_WML(n) MAKE_REG_SET(n,0xFF,0) //(uint32_t)(((n) & 0x7F)<<0) // Read Watermark Level
  265. #define SDHC_WML_WRWML(n) MAKE_REG_SET(n,0xFF,16) //(uint32_t)(((n) & 0x7F)<<16) // Write Watermark Level
  266. #define SDHC_WML_RDWML(n) MAKE_REG_SET(n,0xFF,0) //(uint32_t)(((n) & 0x7F)<<0) // Read Watermark Level
  267. #define SDHC_MIX_CTRL_DMAEN MAKE_REG_MASK(0x1,0) //
  268. #define SDHC_MIX_CTRL_BCEN MAKE_REG_MASK(0x1,1) //
  269. #define SDHC_MIX_CTRL_AC12EN MAKE_REG_MASK(0x1,2) //
  270. #define SDHC_MIX_CTRL_DDR_EN MAKE_REG_MASK(0x1,3) //
  271. #define SDHC_MIX_CTRL_DTDSEL MAKE_REG_MASK(0x1,4) //
  272. #define SDHC_MIX_CTRL_MSBSEL MAKE_REG_MASK(0x1,5) //
  273. #define SDHC_MIX_CTRL_NIBBLE_POS MAKE_REG_MASK(0x1,6) //
  274. #define SDHC_MIX_CTRL_AC23EN MAKE_REG_MASK(0x1,7) //
  275. #define SDHC_FEVT_CINT MAKE_REG_MASK(0x1,31) //((uint32_t)0x80000000) // Force Event Card Interrupt
  276. #define SDHC_FEVT_DMAE MAKE_REG_MASK(0x1,28) //((uint32_t)0x10000000) // Force Event DMA Error
  277. #define SDHC_FEVT_AC12E MAKE_REG_MASK(0x1,24) //((uint32_t)0x01000000) // Force Event Auto CMD12 Error
  278. #define SDHC_FEVT_DEBE MAKE_REG_MASK(0x1,22) //((uint32_t)0x00400000) // Force Event Data End Bit Error
  279. #define SDHC_FEVT_DCE MAKE_REG_MASK(0x1,21) //((uint32_t)0x00200000) // Force Event Data CRC Error
  280. #define SDHC_FEVT_DTOE MAKE_REG_MASK(0x1,20) //((uint32_t)0x00100000) // Force Event Data Timeout Error
  281. #define SDHC_FEVT_CIE MAKE_REG_MASK(0x1,19) //((uint32_t)0x00080000) // Force Event Command Index Error
  282. #define SDHC_FEVT_CEBE MAKE_REG_MASK(0x1,18) //((uint32_t)0x00040000) // Force Event Command End Bit Error
  283. #define SDHC_FEVT_CCE MAKE_REG_MASK(0x1,17) //((uint32_t)0x00020000) // Force Event Command CRC Error
  284. #define SDHC_FEVT_CTOE MAKE_REG_MASK(0x1,16) //((uint32_t)0x00010000) // Force Event Command Timeout Error
  285. #define SDHC_FEVT_CNIBAC12E MAKE_REG_MASK(0x1,7) //((uint32_t)0x00000080) // Force Event Command Not Executed By Auto Command 12 Error
  286. #define SDHC_FEVT_AC12IE MAKE_REG_MASK(0x1,4) //((uint32_t)0x00000010) // Force Event Auto Command 12 Index Error
  287. #define SDHC_FEVT_AC12EBE MAKE_REG_MASK(0x1,3) //((uint32_t)0x00000008) // Force Event Auto Command 12 End Bit Error
  288. #define SDHC_FEVT_AC12CE MAKE_REG_MASK(0x1,2) //((uint32_t)0x00000004) // Force Event Auto Command 12 CRC Error
  289. #define SDHC_FEVT_AC12TOE MAKE_REG_MASK(0x1,1) //((uint32_t)0x00000002) // Force Event Auto Command 12 Time Out Error
  290. #define SDHC_FEVT_AC12NE MAKE_REG_MASK(0x1,0) //((uint32_t)0x00000001) // Force Event Auto Command 12 Not Executed
  291. #define SDHC_ADMAES_ADMADCE MAKE_REG_MASK(0x1,3) //((uint32_t)0x00000008)
  292. #define SDHC_ADMAES_ADMALME MAKE_REG_MASK(0x1,2) //((uint32_t)0x00000004)
  293. #define SDHC_ADMAES_ADMAES_MASK MAKE_REG_MASK(0x3,0) //((uint32_t)0x00000003)
  294. #define SDHC_MMCBOOT_BOOTBLKCNT(n) MAKE_REG_MASK(0xFF,16) //(uint32_t)(((n) & 0xFFF)<<16) // stop at block gap value of automatic mode
  295. #define SDHC_MMCBOOT_AUTOSABGEN MAKE_REG_MASK(0x1,7) //((uint32_t)0x00000080) // enable auto stop at block gap function
  296. #define SDHC_MMCBOOT_BOOTEN MAKE_REG_MASK(0x1,6) //((uint32_t)0x00000040) // Boot Mode Enable
  297. #define SDHC_MMCBOOT_BOOTMODE MAKE_REG_MASK(0x1,5) //((uint32_t)0x00000020) // Boot Mode Select
  298. #define SDHC_MMCBOOT_BOOTACK MAKE_REG_MASK(0x1,4) //((uint32_t)0x00000010) // Boot Ack Mode Select
  299. #define SDHC_MMCBOOT_DTOCVACK(n) MAKE_REG_MASK(0xF,0) //(uint32_t)(((n) & 0xF)<<0) // Boot ACK Time Out Counter Value
  300. //#define SDHC_HOSTVER (*(volatile uint32_t *)0x400B10FC) // Host Controller Version
  301. #define CCM_ANALOG_PFD_528_PFD0_FRAC_MASK 0x3f
  302. #define CCM_ANALOG_PFD_528_PFD0_FRAC(n) ((n) & CCM_ANALOG_PFD_528_PFD0_FRAC_MASK)
  303. #define CCM_ANALOG_PFD_528_PFD1_FRAC_MASK (0x3f<<8)
  304. #define CCM_ANALOG_PFD_528_PFD1_FRAC(n) (((n)<<8) & CCM_ANALOG_PFD_528_PFD1_FRAC_MASK)
  305. #define CCM_ANALOG_PFD_528_PFD2_FRAC_MASK (0x3f<<16)
  306. #define CCM_ANALOG_PFD_528_PFD2_FRAC(n) (((n)<<16) & CCM_ANALOG_PFD_528_PFD2_FRAC_MASK)
  307. #define CCM_ANALOG_PFD_528_PFD3_FRAC_MASK ((0x3f<<24)
  308. #define CCM_ANALOG_PFD_528_PFD3_FRAC(n) (((n)<<24) & CCM_ANALOG_PFD_528_PFD3_FRAC_MASK)
  309. #define SDHC_DSADDR (USDHC1_DS_ADDR ) // DMA System Address register
  310. #define SDHC_BLKATTR (USDHC1_BLK_ATT) // Block Attributes register
  311. #define SDHC_CMDARG (USDHC1_CMD_ARG) // Command Argument register
  312. #define SDHC_XFERTYP (USDHC1_CMD_XFR_TYP) // Transfer Type register
  313. #define SDHC_CMDRSP0 (USDHC1_CMD_RSP0) // Command Response 0
  314. #define SDHC_CMDRSP1 (USDHC1_CMD_RSP1) // Command Response 1
  315. #define SDHC_CMDRSP2 (USDHC1_CMD_RSP2) // Command Response 2
  316. #define SDHC_CMDRSP3 (USDHC1_CMD_RSP3) // Command Response 3
  317. #define SDHC_DATPORT (USDHC1_DATA_BUFF_ACC_PORT) // Buffer Data Port register
  318. #define SDHC_PRSSTAT (USDHC1_PRES_STATE) // Present State register
  319. #define SDHC_PROCTL (USDHC1_PROT_CTRL) // Protocol Control register
  320. #define SDHC_SYSCTL (USDHC1_SYS_CTRL) // System Control register
  321. #define SDHC_IRQSTAT (USDHC1_INT_STATUS) // Interrupt Status register
  322. #define SDHC_IRQSTATEN (USDHC1_INT_STATUS_EN) // Interrupt Status Enable register
  323. #define SDHC_IRQSIGEN (USDHC1_INT_SIGNAL_EN) // Interrupt Signal Enable register
  324. #define SDHC_AC12ERR (USDHC1_AUTOCMD12_ERR_STATUS) // Auto CMD12 Error Status Register
  325. #define SDHC_HTCAPBLT (USDHC1_HOST_CTRL_CAP) // Host Controller Capabilities
  326. #define SDHC_WML (USDHC1_WTMK_LVL) // Watermark Level Register
  327. #define SDHC_MIX_CTRL (USDHC1_MIX_CTRL) // Mixer Control
  328. #define SDHC_FEVT (USDHC1_FORCE_EVENT) // Force Event register
  329. #define SDHC_ADMAES (USDHC1_ADMA_ERR_STATUS) // ADMA Error Status register
  330. #define SDHC_ADSADDR (USDHC1_ADMA_SYS_ADDR) // ADMA System Addressregister
  331. #define SDHC_VENDOR (USDHC1_VEND_SPEC) // Vendor Specific register
  332. #define SDHC_MMCBOOT (USDHC1_MMC_BOOT) // MMC Boot register
  333. #define SDHC_VENDOR2 (USDHC2_VEND_SPEC2) // Vendor Specific2 register
  334. //
  335. #define IRQ_SDHC IRQ_SDHC1
  336. #define SDHC_MAX_DVS (0xF + 1U)
  337. #define SDHC_MAX_CLKFS (0xFF + 1U)
  338. #define SDHC_PREV_DVS(x) ((x) -= 1U)
  339. #define SDHC_PREV_CLKFS(x, y) ((x) >>= (y))
  340. #define CCM_CSCDR1_USDHC1_CLK_PODF_MASK (0x7<<11)
  341. #define CCM_CSCDR1_USDHC1_CLK_PODF(n) (((n)&0x7)<<11)
  342. #define IOMUXC_SW_PAD_CTL_PAD_SRE ((0x1<)<0)
  343. #define IOMUXC_SW_PAD_CTL_PAD_PKE ((0x1)<<12)
  344. #define IOMUXC_SW_PAD_CTL_PAD_PUE ((0x1)<<13)
  345. #define IOMUXC_SW_PAD_CTL_PAD_HYS ((0x1)<<16)
  346. #define IOMUXC_SW_PAD_CTL_PAD_SPEED(n) (((n)&0x3)<<6)
  347. #define IOMUXC_SW_PAD_CTL_PAD_PUS(n) (((n)&0x3)<<14)
  348. #define IOMUXC_SW_PAD_CTL_PAD_PUS_MASK ((0x3)<<14)
  349. #define IOMUXC_SW_PAD_CTL_PAD_DSE(n) (((n)&0x7)<<3)
  350. #define IOMUXC_SW_PAD_CTL_PAD_DSE_MASK ((0x7)<<3)
  351. #endif
  352. #define SDHC_IRQSIGEN_DMA_MASK (SDHC_IRQSIGEN_TCIEN | SDHC_IRQSIGEN_DINTIEN | SDHC_IRQSIGEN_DMAEIEN)
  353. #define CARD_STATUS_READY_FOR_DATA (1UL << 8)
  354. /******************************************************************************
  355. Types
  356. ******************************************************************************/
  357. typedef struct {
  358. uint8_t status;
  359. uint8_t highCapacity;
  360. uint8_t version2;
  361. uint8_t tranSpeed;
  362. uint32_t address;
  363. uint32_t numBlocks;
  364. uint32_t lastCardStatus;
  365. } SD_CARD_DESCRIPTOR;
  366. /******************************************************************************
  367. Global functions
  368. ******************************************************************************/
  369. /******************************************************************************
  370. Private variables
  371. ******************************************************************************/
  372. static SD_CARD_DESCRIPTOR sdCardDesc;
  373. static volatile uint32_t dmaDone=0;
  374. //
  375. /******************************************************************************
  376. Forward declaration of private functions
  377. ******************************************************************************/
  378. static void sdhc_setSdclk(uint32_t kHzMax);
  379. static uint8_t SDHC_Init(void);
  380. static void SDHC_InitGPIO(void);
  381. static void SDHC_ReleaseGPIO(void);
  382. static void SDHC_SetClock(uint32_t sysctl);
  383. static uint32_t SDHC_WaitStatus(uint32_t mask);
  384. static int SDHC_ReadBlock(uint32_t* pData);
  385. static int SDHC_WriteBlock(const uint32_t* pData);
  386. static int SDHC_CMD_Do(uint32_t xfertyp);
  387. static int SDHC_CMD0_GoToIdle(void);
  388. static int SDHC_CMD2_Identify(void);
  389. static int SDHC_CMD3_GetAddress(void);
  390. static int SDHC_ACMD6_SetBusWidth(uint32_t address, uint32_t width);
  391. static int SDHC_CMD7_SelectCard(uint32_t address);
  392. static int SDHC_CMD8_SetInterface(uint32_t cond);
  393. static int SDHC_CMD9_GetParameters(uint32_t address);
  394. static int SDHC_CMD12_StopTransfer(void);
  395. static int SDHC_CMD12_StopTransferWaitForBusy(void);
  396. static int SDHC_CMD16_SetBlockSize(uint32_t block_size);
  397. static int SDHC_CMD17_ReadBlock(uint32_t sector);
  398. static int SDHC_CMD24_WriteBlock(uint32_t sector);
  399. static int SDHC_ACMD41_SendOperationCond(uint32_t cond);
  400. /******************************************************************************
  401. Public functions
  402. ******************************************************************************/
  403. uint8_t SDHC_CardGetType(void)
  404. {
  405. if (sdCardDesc.status) return 0;
  406. if (sdCardDesc.version2 == 0) return 1; // SD_CARD_TYPE_SD1
  407. if (sdCardDesc.highCapacity == 0) return 2; // SD_CARD_TYPE_SD2
  408. return 3; // SD_CARD_TYPE_SDHC
  409. }
  410. //-----------------------------------------------------------------------------
  411. // initialize the SDHC Controller and SD Card
  412. // returns status of initialization(OK, nonInit, noCard, CardProtected)
  413. uint8_t SDHC_CardInit(void)
  414. {
  415. uint8_t resS;
  416. int resR;
  417. resS = SDHC_Init();
  418. sdCardDesc.status = resS;
  419. sdCardDesc.address = 0;
  420. sdCardDesc.highCapacity = 0;
  421. sdCardDesc.version2 = 0;
  422. sdCardDesc.numBlocks = 0;
  423. if (resS) return resS;
  424. SDHC_IRQSIGEN = 0;
  425. resR = SDHC_CMD0_GoToIdle();
  426. if (resR) { return sdCardDesc.status = SDHC_STATUS_NOINIT;}
  427. resR = SDHC_CMD8_SetInterface(0x000001AA); // 3.3V and AA check pattern
  428. if (resR == SDHC_RESULT_OK)
  429. { if (SDHC_CMDRSP0 != 0x000001AA) return sdCardDesc.status = SDHC_STATUS_NOINIT;
  430. sdCardDesc.highCapacity = 1;
  431. }
  432. else if (resR == SDHC_RESULT_NO_RESPONSE)
  433. { // version 1 cards do not respond to CMD8
  434. }
  435. else return sdCardDesc.status = SDHC_STATUS_NOINIT;
  436. if (SDHC_ACMD41_SendOperationCond(0)) return sdCardDesc.status = SDHC_STATUS_NOINIT;
  437. if (SDHC_CMDRSP0 & 0x300000) {
  438. uint32_t condition = 0x00300000;
  439. if (sdCardDesc.highCapacity) condition |= 0x40000000;
  440. //
  441. uint32_t ii = 0;
  442. do {
  443. ii++;
  444. if (SDHC_ACMD41_SendOperationCond(condition)) {
  445. resS = SDHC_STATUS_NOINIT;
  446. break;
  447. }
  448. } while ((!(SDHC_CMDRSP0 & 0x80000000)) && (ii < SDHC_INITIALIZATION_MAX_CNT));
  449. if (resS) return resS;
  450. if ((ii >= SDHC_INITIALIZATION_MAX_CNT) || (!(SDHC_CMDRSP0 & 0x40000000)))
  451. sdCardDesc.highCapacity = 0;
  452. }
  453. // Card identify
  454. if (SDHC_CMD2_Identify()) return sdCardDesc.status = SDHC_STATUS_NOINIT;
  455. // Get card address
  456. if (SDHC_CMD3_GetAddress()) return sdCardDesc.status = SDHC_STATUS_NOINIT;
  457. sdCardDesc.address = SDHC_CMDRSP0 & 0xFFFF0000;
  458. // Get card parameters
  459. if (SDHC_CMD9_GetParameters(sdCardDesc.address)) return sdCardDesc.status = SDHC_STATUS_NOINIT;
  460. if (!(SDHC_CMDRSP3 & 0x00C00000)) {
  461. uint32_t read_bl_len, c_size, c_size_mult;
  462. read_bl_len = (SDHC_CMDRSP2 >> 8) & 0x0F;
  463. c_size = SDHC_CMDRSP2 & 0x03;
  464. c_size = (c_size << 10) | (SDHC_CMDRSP1 >> 22);
  465. c_size_mult = (SDHC_CMDRSP1 >> 7) & 0x07;
  466. sdCardDesc.numBlocks = (c_size + 1) * (1 << (c_size_mult + 2)) * (1 << (read_bl_len - 9));
  467. } else {
  468. uint32_t c_size;
  469. sdCardDesc.version2 = 1;
  470. c_size = (SDHC_CMDRSP1 >> 8) & 0x003FFFFF;
  471. sdCardDesc.numBlocks = (c_size + 1) << 10;
  472. }
  473. // Select card
  474. if (SDHC_CMD7_SelectCard(sdCardDesc.address)) return sdCardDesc.status = SDHC_STATUS_NOINIT;
  475. // Set Block Size to 512
  476. // Block Size in SDHC Controller is already set to 512 by SDHC_Init();
  477. // Set 512 Block size in SD card
  478. if (SDHC_CMD16_SetBlockSize(SDHC_BLOCK_SIZE)) return sdCardDesc.status = SDHC_STATUS_NOINIT;
  479. // Set 4 bit data bus width
  480. if (SDHC_ACMD6_SetBusWidth(sdCardDesc.address, 2)) return sdCardDesc.status = SDHC_STATUS_NOINIT;
  481. // Set Data bus width also in SDHC controller
  482. SDHC_PROCTL &= ~SDHC_PROCTL_DTW_MASK;
  483. SDHC_PROCTL |= SDHC_PROCTL_DTW(SDHC_PROCTL_DTW_4BIT);
  484. // De-Init GPIO
  485. SDHC_ReleaseGPIO();
  486. // Set the SDHC default baud rate
  487. sdhc_setSdclk(25000);
  488. // SDHC_SetClock(SDHC_SYSCTL_25MHZ);
  489. // TODO: use CMD6 and CMD9 to detect if card supports 50 MHz
  490. // then use CMD4 to configure card to high speed mode,
  491. // and SDHC_SetClock() for 50 MHz config
  492. // Init GPIO
  493. SDHC_InitGPIO();
  494. return sdCardDesc.status;
  495. }
  496. //-----------------------------------------------------------------------------
  497. // FUNCTION: SDHC_CardReadBlock (disk_read)
  498. // SCOPE: SDHC public related function
  499. // DESCRIPTION: Function read block to disk
  500. //
  501. // PARAMETERS: buff - pointer on buffer where read data should be stored
  502. // sector - index of sector
  503. //
  504. // RETURNS: result of operation
  505. //-----------------------------------------------------------------------------
  506. int SDHC_CardReadBlock(void * buff, uint32_t sector)
  507. {
  508. int result=0;
  509. uint32_t* pData = (uint32_t*)buff;
  510. // Serial.print("Sector: "); Serial.println(sector); Serial.flush();
  511. // Check if this is ready
  512. if (sdCardDesc.status != 0) return SDHC_RESULT_NOT_READY;
  513. while ((SDHC_PRSSTAT & SDHC_PRSSTAT_CIHB) || (SDHC_PRSSTAT & SDHC_PRSSTAT_CDIHB));
  514. // Convert LBA to BYTE address if needed
  515. if (!sdCardDesc.highCapacity) sector *= 512;
  516. // clear status
  517. SDHC_IRQSTAT = SDHC_IRQSTAT;
  518. // use dma: disabling polling
  519. uint32_t irqstat = SDHC_IRQSTATEN;
  520. irqstat &= ~(SDHC_IRQSTATEN_BRRSEN | SDHC_IRQSTATEN_BWRSEN | SDHC_IRQSTATEN_CCSEN) ;
  521. irqstat &= ~(SDHC_IRQSTATEN_DCESEN | SDHC_IRQSTATEN_CCESEN) ;
  522. // enable status
  523. irqstat |= SDHC_IRQSTATEN_DMAESEN | SDHC_IRQSTATEN_DINTSEN | SDHC_IRQSTATEN_TCSEN ;
  524. SDHC_IRQSTATEN = irqstat;
  525. uint32_t sigen = SDHC_IRQSIGEN;
  526. sigen |= SDHC_IRQSIGEN_DMA_MASK ;
  527. SDHC_SYSCTL |= SDHC_SYSCTL_HCKEN;
  528. #if defined(__IMXRT1052__)
  529. SDHC_MIX_CTRL |= SDHC_MIX_CTRL_DTDSEL ; // read
  530. SDHC_MIX_CTRL |= SDHC_MIX_CTRL_DMAEN ; // DMA
  531. #endif
  532. uint32_t xfertyp = SDHC_XFERTYP_CMDINX(SDHC_CMD17) | SDHC_XFERTYP_RSPTYP(SDHC_XFERTYP_RSPTYP_48) | SDHC_XFERTYP_DPSEL
  533. | SDHC_XFERTYP_DTDSEL | SDHC_XFERTYP_DMAEN;
  534. dmaDone=0;
  535. SDHC_DSADDR = (uint32_t)buff;
  536. SDHC_CMDARG = sector;
  537. SDHC_BLKATTR = SDHC_BLKATTR_BLKCNT(1) | SDHC_BLKATTR_BLKSIZE(512);
  538. SDHC_IRQSIGEN = sigen;
  539. SDHC_XFERTYP = xfertyp;
  540. //
  541. while(!dmaDone);
  542. SDHC_IRQSTAT &= (SDHC_IRQSTAT_CC | SDHC_IRQSTAT_TC);
  543. return result;
  544. }
  545. //-----------------------------------------------------------------------------
  546. // FUNCTION: SDHC_CardWriteBlock (disk_write)
  547. // SCOPE: SDHC public related function
  548. // DESCRIPTION: Function write block to disk
  549. //
  550. // PARAMETERS: buff - pointer on buffer where is stored data
  551. // sector - index of sector
  552. //
  553. // RETURNS: result of operation
  554. //-----------------------------------------------------------------------------
  555. int SDHC_CardWriteBlock(const void * buff, uint32_t sector)
  556. {
  557. int result=0;
  558. const uint32_t *pData = (const uint32_t *)buff;
  559. // Check if this is ready
  560. if (sdCardDesc.status != 0) return SDHC_RESULT_NOT_READY;
  561. while ((SDHC_PRSSTAT & SDHC_PRSSTAT_CIHB) || (SDHC_PRSSTAT & SDHC_PRSSTAT_CDIHB)) ;
  562. // Convert LBA to uint8_t address if needed
  563. if (!sdCardDesc.highCapacity) sector *= 512;
  564. // clear status
  565. SDHC_IRQSTAT = SDHC_IRQSTAT;
  566. uint32_t irqstat = SDHC_IRQSTATEN;
  567. // use dma: disabling polling
  568. irqstat &= ~(SDHC_IRQSTATEN_BRRSEN | SDHC_IRQSTATEN_BWRSEN | SDHC_IRQSTATEN_CCSEN) ;
  569. irqstat &= ~(SDHC_IRQSTATEN_DCESEN | SDHC_IRQSTATEN_CCESEN) ;
  570. // enable status
  571. irqstat |= /*SDHC_IRQSTATEN_DCESEN | SDHC_IRQSTATEN_CCESEN | */SDHC_IRQSTATEN_DMAESEN ;
  572. irqstat |= SDHC_IRQSTATEN_DINTSEN | SDHC_IRQSTATEN_TCSEN ;
  573. SDHC_IRQSTATEN = irqstat;
  574. uint32_t sigen = SDHC_IRQSIGEN;
  575. sigen |= SDHC_IRQSIGEN_DMA_MASK ;
  576. SDHC_SYSCTL |= SDHC_SYSCTL_HCKEN;
  577. #if defined(__IMXRT1052__)
  578. SDHC_MIX_CTRL &= ~ SDHC_MIX_CTRL_DTDSEL; // write
  579. SDHC_MIX_CTRL |= SDHC_MIX_CTRL_DMAEN ; //DMA
  580. #endif
  581. uint32_t xfertyp = SDHC_XFERTYP_CMDINX(SDHC_CMD24) | SDHC_XFERTYP_RSPTYP(SDHC_XFERTYP_RSPTYP_48) | SDHC_XFERTYP_DPSEL
  582. | SDHC_XFERTYP_DMAEN;
  583. dmaDone=0;
  584. SDHC_DSADDR = (uint32_t)buff;
  585. SDHC_CMDARG = sector;
  586. SDHC_BLKATTR = SDHC_BLKATTR_BLKCNT(1) | SDHC_BLKATTR_BLKSIZE(512);
  587. SDHC_IRQSIGEN = sigen;
  588. SDHC_XFERTYP = xfertyp;
  589. //
  590. while(!dmaDone);
  591. SDHC_IRQSTAT &= (SDHC_IRQSTAT_CC | SDHC_IRQSTAT_TC);
  592. while(SDHC_PRSSTAT & SDHC_PRSSTAT_DLA);
  593. //check for uSD status
  594. do
  595. { while ((SDHC_PRSSTAT & SDHC_PRSSTAT_CIHB) || (SDHC_PRSSTAT & SDHC_PRSSTAT_CDIHB)) ;
  596. SDHC_IRQSTATEN |= SDHC_IRQSTATEN_CCSEN;
  597. SDHC_IRQSTAT=SDHC_IRQSTAT;
  598. // CMD13 to check uSD status
  599. xfertyp = (SDHC_XFERTYP_CMDINX(SDHC_CMD13) | SDHC_XFERTYP_RSPTYP(SDHC_XFERTYP_RSPTYP_48));
  600. //
  601. SDHC_CMDARG = sdCardDesc.address;
  602. SDHC_XFERTYP = xfertyp;
  603. while(!(SDHC_IRQSTAT & SDHC_IRQSTAT_CC)); SDHC_IRQSTAT &= SDHC_IRQSTAT_CC;
  604. } while(SDHC_CMDRSP0 & 0x200); // while data?
  605. // } while(!(SDHC_CMDRSP0 & CARD_STATUS_READY_FOR_DATA ));
  606. return result;
  607. }
  608. /******************************************************************************
  609. Private functions
  610. ******************************************************************************/
  611. #if defined(__MK64FX512__) || defined(__MK66FX1M0__)
  612. // initialize the SDHC Controller signals
  613. static void SDHC_InitGPIO(void)
  614. {
  615. PORTE_PCR0 = PORT_PCR_MUX(4) | PORT_PCR_PS | PORT_PCR_PE | PORT_PCR_DSE; /* SDHC.D1 */
  616. PORTE_PCR1 = PORT_PCR_MUX(4) | PORT_PCR_PS | PORT_PCR_PE | PORT_PCR_DSE; /* SDHC.D0 */
  617. PORTE_PCR2 = PORT_PCR_MUX(4) | PORT_PCR_DSE; /* SDHC.CLK */
  618. PORTE_PCR3 = PORT_PCR_MUX(4) | PORT_PCR_PS | PORT_PCR_PE | PORT_PCR_DSE; /* SDHC.CMD */
  619. PORTE_PCR4 = PORT_PCR_MUX(4) | PORT_PCR_PS | PORT_PCR_PE | PORT_PCR_DSE; /* SDHC.D3 */
  620. PORTE_PCR5 = PORT_PCR_MUX(4) | PORT_PCR_PS | PORT_PCR_PE | PORT_PCR_DSE; /* SDHC.D2 */
  621. }
  622. // release the SDHC Controller signals
  623. static void SDHC_ReleaseGPIO(void)
  624. {
  625. PORTE_PCR0 = PORT_PCR_MUX(1) | PORT_PCR_PE | PORT_PCR_PS; /* PULLUP SDHC.D1 */
  626. PORTE_PCR1 = PORT_PCR_MUX(1) | PORT_PCR_PE | PORT_PCR_PS; /* PULLUP SDHC.D0 */
  627. PORTE_PCR2 = 0; /* SDHC.CLK */
  628. PORTE_PCR3 = PORT_PCR_MUX(1) | PORT_PCR_PE | PORT_PCR_PS; /* PULLUP SDHC.CMD */
  629. PORTE_PCR4 = PORT_PCR_MUX(1) | PORT_PCR_PE | PORT_PCR_PS; /* PULLUP SDHC.D3 */
  630. PORTE_PCR5 = PORT_PCR_MUX(1) | PORT_PCR_PE | PORT_PCR_PS; /* PULLUP SDHC.D2 */
  631. }
  632. void initClock()
  633. {
  634. #ifdef HAS_KINETIS_MPU
  635. // Allow SDHC Bus Master access.
  636. MPU_RGDAAC0 |= 0x0C000000;
  637. #endif
  638. // Enable SDHC clock.
  639. SIM_SCGC3 |= SIM_SCGC3_SDHC;
  640. }
  641. uint32_t sdhcClock()
  642. { return F_CPU;
  643. }
  644. #else
  645. static void SDHC_InitGPIO(void)
  646. {
  647. { //T4
  648. IOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B0_04 = 0; //DAT2
  649. IOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B0_05 = 0; //DAT3
  650. IOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B0_00 = 0; //CMD
  651. //3.3V
  652. IOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B0_01 = 0; //CLK
  653. //GND
  654. IOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B0_02 = 0; //DAT0
  655. IOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B0_03 = 0; //DAT1
  656. const uint32_t CLOCK_MASK = IOMUXC_SW_PAD_CTL_PAD_PKE |
  657. IOMUXC_SW_PAD_CTL_PAD_DSE(1) |
  658. IOMUXC_SW_PAD_CTL_PAD_SPEED(2);
  659. const uint32_t DATA_MASK = CLOCK_MASK |
  660. (IOMUXC_SW_PAD_CTL_PAD_PUE | IOMUXC_SW_PAD_CTL_PAD_PUS(1));
  661. IOMUXC_SW_PAD_CTL_PAD_GPIO_SD_B0_04 = DATA_MASK;
  662. IOMUXC_SW_PAD_CTL_PAD_GPIO_SD_B0_05 = DATA_MASK;
  663. IOMUXC_SW_PAD_CTL_PAD_GPIO_SD_B0_00 = DATA_MASK;
  664. IOMUXC_SW_PAD_CTL_PAD_GPIO_SD_B0_01 = CLOCK_MASK;
  665. IOMUXC_SW_PAD_CTL_PAD_GPIO_SD_B0_02 = DATA_MASK;
  666. IOMUXC_SW_PAD_CTL_PAD_GPIO_SD_B0_03 = DATA_MASK;
  667. }
  668. }
  669. static void SDHC_ReleaseGPIO(void)
  670. {
  671. IOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B0_04 = 5; //GPIO3_IO16
  672. IOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B0_05 = 5; //GPIO3_IO17
  673. IOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B0_00 = 5; //GPIO3_IO12
  674. //3.3V
  675. IOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B0_01 = 5; //GPIO3_IO13
  676. //GND
  677. IOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B0_02 = 5; //GPIO3_IO14
  678. IOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B0_03 = 5; //GPIO3_IO15
  679. }
  680. void initClock()
  681. {
  682. /* set PDF_528 PLL2PFD0 */
  683. CCM_ANALOG_PFD_528 |= (1 << 7);
  684. CCM_ANALOG_PFD_528 &= ~(0x3F << 0);
  685. CCM_ANALOG_PFD_528 |= ((24) & 0x3F << 0); // 12 - 35
  686. CCM_ANALOG_PFD_528 &= ~(1 << 7);
  687. /* Enable USDHC clock. */
  688. CCM_CCGR6 |= CCM_CCGR6_USDHC1(CCM_CCGR_ON);
  689. CCM_CSCDR1 &= ~(CCM_CSCDR1_USDHC1_CLK_PODF_MASK);
  690. //
  691. // CCM_CSCMR1 &= ~(CCM_CSCMR1_USDHC1_CLK_SEL); // PLL2PFD2
  692. CCM_CSCMR1 |= CCM_CSCMR1_USDHC1_CLK_SEL; // PLL2PFD0
  693. CCM_CSCDR1 |= CCM_CSCDR1_USDHC1_CLK_PODF((7)); // &0x7
  694. // for testing
  695. CCM_CCOSR = CCM_CCOSR_CLKO1_EN | CCM_CCOSR_CLKO1_DIV(7) | CCM_CCOSR_CLKO1_SEL(1); //(1: SYS_PLL/2)
  696. IOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B0_04 = 6; //CCM_CLKO1 (0 is USDHC1_DAT2)
  697. // for testing
  698. CCM_CCOSR |= (CCM_CCOSR_CLKO2_EN | CCM_CCOSR_CLKO2_DIV(7) | CCM_CCOSR_CLKO2_SEL(3)); //(3: usdhc1_clk_root))
  699. IOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B0_05 = 6; //CCM_CLKO2 (0 is USDHC1_DAT3)
  700. }
  701. uint32_t sdhcClock()
  702. {
  703. uint32_t divider = ((CCM_CSCDR1 >> 11) & 0x7) + 1;
  704. uint32_t PLL2PFD0 = (528000000U * 3) / ((CCM_ANALOG_PFD_528 & 0x3F) / 6) / divider;
  705. return PLL2PFD0;
  706. }
  707. #endif
  708. /* //may be useful for debugging
  709. static void printRegs()
  710. {
  711. // Serial.print("DS_ADDR: "); Serial.println(SDHC_DSADDR,HEX); // DMA System Address register
  712. Serial.print("BLK_ATT: "); Serial.println(SDHC_BLKATTR,HEX); // Block Attributes register
  713. // Serial.print("CMD_ARG: "); Serial.println(SDHC_CMDARG,HEX); // Command Argument register
  714. // Serial.print("CMD_XFR_TYP: "); Serial.println(SDHC_XFERTYP,HEX); // Transfer Type register
  715. // Serial.print("CMD_RSP0: "); Serial.println(SDHC_CMDRSP0,HEX); // Command Response 0
  716. // Serial.print("CMD_RSP1: "); Serial.println(SDHC_CMDRSP1,HEX); // Command Response 1
  717. // Serial.print("CMD_RSP2: "); Serial.println(SDHC_CMDRSP2,HEX); // Command Response 2
  718. // Serial.print("CMD_RSP3: "); Serial.println(SDHC_CMDRSP3,HEX); // Command Response 3
  719. // Serial.print("DATA_BUFF_ACC_POR: "); Serial.println(SDHC_DATPORT,HEX); // Buffer Data Port register
  720. Serial.print("PRES_STATE: "); Serial.println(SDHC_PRSSTAT,HEX); // Present State register
  721. Serial.print("PROT_CTRL: "); Serial.println(SDHC_PROCTL,HEX); // Protocol Control register
  722. Serial.print("SYS_CTRL: "); Serial.println(SDHC_SYSCTL,HEX); // System Control register
  723. Serial.print("INT_STATUS: "); Serial.println(SDHC_IRQSTAT,HEX); // Interrupt Status register
  724. Serial.print("INT_STATUS_EN: "); Serial.println(SDHC_IRQSTATEN,HEX); // Interrupt Status Enable register
  725. Serial.print("INT_SIGNAL_EN: "); Serial.println(SDHC_IRQSIGEN,HEX); // Interrupt Signal Enable register
  726. // Serial.print("AUTOCMD12_ERR_STATUS: "); Serial.println(SDHC_AC12ERR,HEX); // Auto CMD12 Error Status Register
  727. Serial.print("HOST_CTRL_CAP: "); Serial.println(SDHC_HTCAPBLT,HEX); // Host Controller Capabilities
  728. Serial.print("WTMK_LVL: "); Serial.println(SDHC_WML,HEX); // Watermark Level Register
  729. #if defined(__IMXRT1052__)
  730. Serial.print("MIX_CTRL: "); Serial.println(SDHC_MIX_CTRL,HEX); // Mixer Control
  731. #endif
  732. // Serial.print("FORCE_EVENT: "); Serial.println(SDHC_FEVT,HEX); // Force Event register
  733. // Serial.print("ADMA_ERR_STATUS: "); Serial.println(SDHC_ADMAES,HEX); // ADMA Error Status register
  734. // Serial.print("ADMA_SYS_ADDR: "); Serial.println(SDHC_ADSADDR,HEX); // ADMA System Addressregister
  735. Serial.print("VEND_SPEC: "); Serial.println(SDHC_VENDOR,HEX); // Vendor Specific register
  736. // Serial.print("MMC_BOOT: "); Serial.println(SDHC_MMCBOOT,HEX); // MMC Boot register
  737. #if defined(__IMXRT1052__)
  738. Serial.print("VEND_SPEC2: "); Serial.println(SDHC_VENDOR2,HEX); // Vendor Specific2 register
  739. #endif
  740. }
  741. */
  742. static void sdhc_setSdclk(uint32_t kHzMax) {
  743. const uint32_t DVS_LIMIT = 0X10;
  744. const uint32_t SDCLKFS_LIMIT = 0X100;
  745. uint32_t dvs = 1;
  746. uint32_t sdclkfs = 1;
  747. uint32_t maxSdclk = 1000 * kHzMax;
  748. // uint32_t f_pll = F_CPU;
  749. uint32_t f_pll = sdhcClock();
  750. while ((f_pll / (sdclkfs * DVS_LIMIT) > maxSdclk) && (sdclkfs < SDCLKFS_LIMIT)) {
  751. sdclkfs <<= 1;
  752. }
  753. while ((f_pll / (sdclkfs * dvs) > maxSdclk) && (dvs < DVS_LIMIT)) {
  754. dvs++;
  755. }
  756. uint32_t m_sdClkKhz = f_pll / (1000 * sdclkfs * dvs);
  757. sdclkfs >>= 1;
  758. dvs--;
  759. #if defined(__MK64FX512__) || defined(__MK66FX1M0__)
  760. // Disable SDHC clock.
  761. SDHC_SYSCTL &= ~SDHC_SYSCTL_SDCLKEN;
  762. #endif
  763. // Change dividers.
  764. uint32_t sysctl = SDHC_SYSCTL & ~(SDHC_SYSCTL_DTOCV_MASK
  765. | SDHC_SYSCTL_DVS_MASK | SDHC_SYSCTL_SDCLKFS_MASK);
  766. SDHC_SYSCTL = sysctl | SDHC_SYSCTL_DTOCV(0x0E) | SDHC_SYSCTL_DVS(dvs)
  767. | SDHC_SYSCTL_SDCLKFS(sdclkfs);
  768. // Wait until the SDHC clock is stable.
  769. while (!(SDHC_PRSSTAT & SDHC_PRSSTAT_SDSTB)) { }
  770. #if defined(__MK64FX512__) || defined(__MK66FX1M0__)
  771. // Enable the SDHC clock.
  772. SDHC_SYSCTL |= SDHC_SYSCTL_SDCLKEN;
  773. #endif
  774. // Serial.printf("setSdclk: %d %d : %x %x\n\r", f_pll, m_sdClkKhz, sdclkfs, dvs);
  775. }
  776. void sdhc_isr(void)
  777. { SDHC_IRQSIGEN &= ~SDHC_IRQSIGEN_DMA_MASK;
  778. //
  779. // Serial.print("IRQ1: "); Serial.println(SDHC_IRQSTAT,HEX);
  780. while(!(SDHC_IRQSTAT & SDHC_IRQSTAT_TC));// SDHC_IRQSTAT &= ~SDHC_IRQSTAT_TC;
  781. #if defined(__IMXRT1052__)
  782. SDHC_MIX_CTRL &= ~(SDHC_MIX_CTRL_AC23EN | SDHC_MIX_CTRL_DMAEN) ;
  783. #endif
  784. // for T3.6, seems not to hurt for T4
  785. if(SDHC_SYSCTL & SDHC_SYSCTL_HCKEN) SDHC_SYSCTL &= ~SDHC_SYSCTL_HCKEN;
  786. SDHC_PROCTL &= ~SDHC_PROCTL_D3CD; SDHC_PROCTL |= SDHC_PROCTL_D3CD;
  787. dmaDone=1;
  788. }
  789. // initialize the SDHC Controller
  790. // returns status of initialization(OK, nonInit, noCard, CardProtected)
  791. static uint8_t SDHC_Init(void)
  792. {
  793. initClock();
  794. // De-init GPIO - to prevent unwanted clocks on bus
  795. SDHC_ReleaseGPIO();
  796. #if defined (__IMXRT1052__)
  797. SDHC_SYSCTL |= 0xF;
  798. SDHC_MIX_CTRL |= 0x80000000;
  799. #endif
  800. /* Reset SDHC */
  801. SDHC_SYSCTL |= SDHC_SYSCTL_RSTA | SDHC_SYSCTL_SDCLKFS(0x80);
  802. while (SDHC_SYSCTL & SDHC_SYSCTL_RSTA) ; // wait
  803. /* Set the SDHC initial baud rate divider and start */
  804. sdhc_setSdclk(400);
  805. /* Poll inhibit bits */
  806. while (SDHC_PRSSTAT & (SDHC_PRSSTAT_CIHB | SDHC_PRSSTAT_CDIHB)) ;
  807. /* Init GPIO again */
  808. SDHC_InitGPIO();
  809. /* Initial values */ // to do - Check values
  810. SDHC_BLKATTR = SDHC_BLKATTR_BLKCNT(1) | SDHC_BLKATTR_BLKSIZE(512);
  811. SDHC_PROCTL &= ~SDHC_PROCTL_DMAS(3); // clear ADMA
  812. SDHC_PROCTL |= SDHC_PROCTL_D3CD;
  813. // SDHC_PROCTL = SDHC_PROCTL_EMODE(SDHC_PROCTL_EMODE_INVARIANT) | SDHC_PROCTL_D3CD;
  814. // SDHC_WML |= SDHC_WML_RDWML(SDHC_FIFO_BUFFER_SIZE) | SDHC_WML_WRWML(SDHC_FIFO_BUFFER_SIZE);
  815. #if defined(__IMXRT1052__)
  816. SDHC_VENDOR = 0x2000F801; // (1<<29 | 0x1F<<11 | 1);
  817. SDHC_VENDOR2 &= ~(1<<12); //switch off ACMD23 sharing SDMA
  818. #endif
  819. /* Enable requests */
  820. // clear interrupt status
  821. SDHC_IRQSTAT = SDHC_IRQSTAT;
  822. SDHC_IRQSTATEN = //SDHC_IRQSTAT_CRM | SDHC_IRQSTATEN_CIESEN |
  823. SDHC_IRQSTATEN_TCSEN | SDHC_IRQSTATEN_CCSEN;
  824. attachInterruptVector(IRQ_SDHC, sdhc_isr);
  825. NVIC_SET_PRIORITY(IRQ_SDHC, 6 * 16);
  826. NVIC_ENABLE_IRQ(IRQ_SDHC);
  827. // initial clocks... SD spec says only 74 clocks are needed, but if Teensy rebooted
  828. // while the card was in middle of an operation, thousands of clock cycles can be
  829. // needed to get the card to complete a prior command and return to a usable state.
  830. for (int ii = 0; ii < 500; ii++) {
  831. SDHC_SYSCTL |= SDHC_SYSCTL_INITA;
  832. while (SDHC_SYSCTL & SDHC_SYSCTL_INITA) ;
  833. }
  834. // to do - check if this needed
  835. SDHC_IRQSTAT |= SDHC_IRQSTAT_CRM;
  836. // Check card
  837. if (SDHC_PRSSTAT & SDHC_PRSSTAT_CINS) {
  838. return 0;
  839. } else {
  840. return SDHC_STATUS_NODISK;
  841. }
  842. }
  843. /******************************************************************************
  844. Private SD Card functions
  845. ******************************************************************************/
  846. // waits for status bits sets
  847. static uint32_t SDHC_WaitStatus(uint32_t mask)
  848. {
  849. uint32_t result;
  850. uint32_t timeout = 1 << 24;
  851. do
  852. { result = SDHC_IRQSTAT & mask;
  853. timeout--;
  854. } while (!result && (timeout));
  855. if (timeout) return result;
  856. return 0;
  857. }
  858. //-----------------------------------------------------------------------------------
  859. // sends the command to SDcard
  860. static int SDHC_CMD_Do(uint32_t xfertyp)
  861. {
  862. // Card removal check preparation
  863. SDHC_IRQSTAT |= SDHC_IRQSTAT_CRM;
  864. // Wait for cmd line idle // to do timeout PRSSTAT[CDIHB] and the PRSSTAT[CIHB]
  865. while ((SDHC_PRSSTAT & SDHC_PRSSTAT_CIHB) || (SDHC_PRSSTAT & SDHC_PRSSTAT_CDIHB)) { };
  866. SDHC_XFERTYP = xfertyp;
  867. /* Wait for response */
  868. const uint32_t mask = SDHC_IRQSTAT_CIE | SDHC_IRQSTAT_CEBE | SDHC_IRQSTAT_CCE | SDHC_IRQSTAT_CC;
  869. if (SDHC_WaitStatus(mask) != SDHC_IRQSTAT_CC)
  870. { SDHC_IRQSTAT |= mask;
  871. return SDHC_RESULT_ERROR;
  872. }
  873. /* Check card removal */
  874. if (SDHC_IRQSTAT & SDHC_IRQSTAT_CRM) {
  875. SDHC_IRQSTAT |= SDHC_IRQSTAT_CTOE | SDHC_IRQSTAT_CC;
  876. return SDHC_RESULT_NOT_READY;
  877. }
  878. /* Get response, if available */
  879. if (SDHC_IRQSTAT & SDHC_IRQSTAT_CTOE)
  880. { SDHC_IRQSTAT |= SDHC_IRQSTAT_CTOE | SDHC_IRQSTAT_CC;
  881. return SDHC_RESULT_NO_RESPONSE;
  882. }
  883. SDHC_IRQSTAT |= SDHC_IRQSTAT_CC;
  884. return SDHC_RESULT_OK;
  885. }
  886. // sends CMD0 to put SDCARD to idle
  887. static int SDHC_CMD0_GoToIdle(void)
  888. {
  889. uint32_t xfertyp;
  890. int result;
  891. SDHC_CMDARG = 0;
  892. xfertyp = (SDHC_XFERTYP_CMDINX(SDHC_CMD0) | SDHC_XFERTYP_RSPTYP(SDHC_XFERTYP_RSPTYP_NO));
  893. result = SDHC_CMD_Do(xfertyp);
  894. if (result == SDHC_RESULT_OK) { (void)SDHC_CMDRSP0; }
  895. return result;
  896. }
  897. // sends CMD2 to identify card
  898. static int SDHC_CMD2_Identify(void)
  899. {
  900. uint32_t xfertyp;
  901. int result;
  902. SDHC_CMDARG = 0;
  903. xfertyp = (SDHC_XFERTYP_CMDINX(SDHC_CMD2) | SDHC_XFERTYP_CCCEN
  904. | SDHC_XFERTYP_RSPTYP(SDHC_XFERTYP_RSPTYP_136));
  905. result = SDHC_CMD_Do(xfertyp);
  906. if (result == SDHC_RESULT_OK) { (void)SDHC_CMDRSP0; }
  907. return result;
  908. }
  909. // sends CMD 3 to get address
  910. static int SDHC_CMD3_GetAddress(void)
  911. {
  912. uint32_t xfertyp;
  913. int result;
  914. SDHC_CMDARG = 0;
  915. xfertyp = (SDHC_XFERTYP_CMDINX(SDHC_CMD3) | SDHC_XFERTYP_CICEN |
  916. SDHC_XFERTYP_CCCEN | SDHC_XFERTYP_RSPTYP(SDHC_XFERTYP_RSPTYP_48));
  917. result = SDHC_CMD_Do(xfertyp);
  918. if (result == SDHC_RESULT_OK) { (void)SDHC_CMDRSP0; }
  919. return result;
  920. }
  921. // sends ACMD6 to set bus width
  922. static int SDHC_ACMD6_SetBusWidth(uint32_t address, uint32_t width)
  923. {
  924. uint32_t xfertyp;
  925. int result;
  926. SDHC_CMDARG = address;
  927. // first send CMD 55 Application specific command
  928. xfertyp = (SDHC_XFERTYP_CMDINX(SDHC_CMD55) | SDHC_XFERTYP_CICEN |
  929. SDHC_XFERTYP_CCCEN | SDHC_XFERTYP_RSPTYP(SDHC_XFERTYP_RSPTYP_48));
  930. result = SDHC_CMD_Do(xfertyp);
  931. if (result == SDHC_RESULT_OK) { (void)SDHC_CMDRSP0;} else { return result; }
  932. SDHC_CMDARG = width;
  933. // Send CMD6
  934. xfertyp = (SDHC_XFERTYP_CMDINX(SDHC_CMD6) | SDHC_XFERTYP_CICEN |
  935. SDHC_XFERTYP_CCCEN | SDHC_XFERTYP_RSPTYP(SDHC_XFERTYP_RSPTYP_48));
  936. result = SDHC_CMD_Do(xfertyp);
  937. if (result == SDHC_RESULT_OK) { (void)SDHC_CMDRSP0; }
  938. return result;
  939. }
  940. // sends CMD 7 to select card
  941. static int SDHC_CMD7_SelectCard(uint32_t address)
  942. {
  943. uint32_t xfertyp;
  944. int result;
  945. SDHC_CMDARG = address;
  946. xfertyp = (SDHC_XFERTYP_CMDINX(SDHC_CMD7) | SDHC_XFERTYP_CICEN |
  947. SDHC_XFERTYP_CCCEN | SDHC_XFERTYP_RSPTYP(SDHC_XFERTYP_RSPTYP_48BUSY));
  948. result = SDHC_CMD_Do(xfertyp);
  949. if (result == SDHC_RESULT_OK) {(void)SDHC_CMDRSP0; }
  950. return result;
  951. }
  952. // CMD8 to send interface condition
  953. static int SDHC_CMD8_SetInterface(uint32_t cond)
  954. {
  955. uint32_t xfertyp;
  956. int result;
  957. SDHC_CMDARG = cond;
  958. xfertyp = (SDHC_XFERTYP_CMDINX(SDHC_CMD8) | SDHC_XFERTYP_CICEN |
  959. SDHC_XFERTYP_CCCEN | SDHC_XFERTYP_RSPTYP(SDHC_XFERTYP_RSPTYP_48));
  960. result = SDHC_CMD_Do(xfertyp);
  961. if (result == SDHC_RESULT_OK) { (void)SDHC_CMDRSP0; }
  962. return result;
  963. }
  964. // sends CMD 9 to get interface condition
  965. static int SDHC_CMD9_GetParameters(uint32_t address)
  966. {
  967. uint32_t xfertyp;
  968. int result;
  969. SDHC_CMDARG = address;
  970. xfertyp = (SDHC_XFERTYP_CMDINX(SDHC_CMD9) | SDHC_XFERTYP_CCCEN |
  971. SDHC_XFERTYP_RSPTYP(SDHC_XFERTYP_RSPTYP_136));
  972. result = SDHC_CMD_Do(xfertyp);
  973. if (result == SDHC_RESULT_OK) {
  974. //(void)SDHC_CMDRSP0;
  975. sdCardDesc.tranSpeed = SDHC_CMDRSP2 >> 24;
  976. }
  977. return result;
  978. }
  979. // sends CMD12 to stop transfer
  980. static int SDHC_CMD12_StopTransfer(void)
  981. {
  982. uint32_t xfertyp;
  983. int result;
  984. SDHC_CMDARG = 0;
  985. xfertyp = (SDHC_XFERTYP_CMDINX(SDHC_CMD12) | SDHC_XFERTYP_CMDTYP(SDHC_XFERTYP_CMDTYP_ABORT) |
  986. SDHC_XFERTYP_CICEN | SDHC_XFERTYP_CCCEN | SDHC_XFERTYP_RSPTYP(SDHC_XFERTYP_RSPTYP_48BUSY));
  987. result = SDHC_CMD_Do(xfertyp);
  988. if (result == SDHC_RESULT_OK) { }
  989. return result;
  990. }
  991. // sends CMD12 to stop transfer and first waits to ready SDCArd
  992. static int SDHC_CMD12_StopTransferWaitForBusy(void)
  993. {
  994. uint32_t timeOut = 1000;
  995. int result;
  996. do {
  997. result = SDHC_CMD12_StopTransfer();
  998. timeOut--;
  999. } while (timeOut && (SDHC_PRSSTAT & SDHC_PRSSTAT_DLA) && result == SDHC_RESULT_OK);
  1000. if (result != SDHC_RESULT_OK) return result;
  1001. if (!timeOut) return SDHC_RESULT_NO_RESPONSE;
  1002. return SDHC_RESULT_OK;
  1003. }
  1004. // sends CMD16 to set block size
  1005. static int SDHC_CMD16_SetBlockSize(uint32_t block_size)
  1006. {
  1007. uint32_t xfertyp;
  1008. int result;
  1009. SDHC_CMDARG = block_size;
  1010. xfertyp = (SDHC_XFERTYP_CMDINX(SDHC_CMD16) | SDHC_XFERTYP_CICEN |
  1011. SDHC_XFERTYP_CCCEN | SDHC_XFERTYP_RSPTYP(SDHC_XFERTYP_RSPTYP_48));
  1012. result = SDHC_CMD_Do(xfertyp);
  1013. if (result == SDHC_RESULT_OK) { (void)SDHC_CMDRSP0; }
  1014. return result;
  1015. }
  1016. // sends CMD17 to read one block
  1017. static int SDHC_CMD17_ReadBlock(uint32_t sector)
  1018. {
  1019. uint32_t xfertyp;
  1020. int result;
  1021. SDHC_CMDARG = sector;
  1022. SDHC_BLKATTR = SDHC_BLKATTR_BLKCNT(1) | 512;
  1023. xfertyp = (SDHC_XFERTYP_CMDINX(SDHC_CMD17) | SDHC_XFERTYP_CICEN |
  1024. SDHC_XFERTYP_CCCEN | SDHC_XFERTYP_RSPTYP(SDHC_XFERTYP_RSPTYP_48) |
  1025. SDHC_XFERTYP_DTDSEL | SDHC_XFERTYP_DPSEL);
  1026. result = SDHC_CMD_Do(xfertyp);
  1027. if (result == SDHC_RESULT_OK) { ( void)SDHC_CMDRSP0; }
  1028. return result;
  1029. }
  1030. // sends CMD24 to write one block
  1031. static int SDHC_CMD24_WriteBlock(uint32_t sector)
  1032. {
  1033. uint32_t xfertyp;
  1034. int result;
  1035. SDHC_CMDARG = sector;
  1036. SDHC_BLKATTR = SDHC_BLKATTR_BLKCNT(1) | 512;
  1037. xfertyp = (SDHC_XFERTYP_CMDINX(SDHC_CMD24) | SDHC_XFERTYP_CICEN |
  1038. SDHC_XFERTYP_CCCEN | SDHC_XFERTYP_RSPTYP(SDHC_XFERTYP_RSPTYP_48) |
  1039. SDHC_XFERTYP_DPSEL);
  1040. result = SDHC_CMD_Do(xfertyp);
  1041. if (result == SDHC_RESULT_OK) { (void)SDHC_CMDRSP0; }
  1042. return result;
  1043. }
  1044. // ACMD 41 to send operation condition
  1045. static int SDHC_ACMD41_SendOperationCond(uint32_t cond)
  1046. {
  1047. uint32_t xfertyp;
  1048. int result;
  1049. SDHC_CMDARG = 0;
  1050. // first send CMD 55 Application specific command
  1051. xfertyp = (SDHC_XFERTYP_CMDINX(SDHC_CMD55) | SDHC_XFERTYP_CICEN |
  1052. SDHC_XFERTYP_CCCEN | SDHC_XFERTYP_RSPTYP(SDHC_XFERTYP_RSPTYP_48));
  1053. result = SDHC_CMD_Do(xfertyp);
  1054. if (result == SDHC_RESULT_OK) { (void)SDHC_CMDRSP0; } else { return result; }
  1055. SDHC_CMDARG = cond;
  1056. // Send 41CMD
  1057. xfertyp = (SDHC_XFERTYP_CMDINX(SDHC_ACMD41) | SDHC_XFERTYP_RSPTYP(SDHC_XFERTYP_RSPTYP_48));
  1058. result = SDHC_CMD_Do(xfertyp);
  1059. if (result == SDHC_RESULT_OK) { (void)SDHC_CMDRSP0; }
  1060. return result;
  1061. }
  1062. #endif // __MK64FX512__ or __MK66FX1M0__ or __IMXRT1052__