PlatformIO package of the Teensy core framework compatible with GCC 10 & C++20
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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