Sd.Mod 83 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237
  1. MODULE Sd;
  2. (**
  3. AUTHOR Timothée Martiel, 2015
  4. PURPOSE SD Card Host Controller Driver
  5. *)
  6. IMPORT
  7. SYSTEM,
  8. SdEnvironment;
  9. CONST
  10. BlockSize * = 512;
  11. InitialClockFrequency * = 400000; (* Hz *)
  12. (* Commands *) (*! Do not change values *)
  13. CMD_GO_IDLE_STATE * = 0; (** CMD0 bc [31:0] stuff bits - *)
  14. CMD_ALL_SEND_CID * = 2; (** CMD2 bcr [31:0] stuff bits R2 *)
  15. CMD_SEND_RELATIVE_ADDR * = 3; (** CMD3 bcr [31:0] stuff bits R6 *)
  16. CMD_SET_DSR * = 4; (** CMD4 bc [31:16] DSR [15:0] stuff bits - *)
  17. CMD_IO_SEND_OP_COND * = 5; (** CMD5 ?? [31:25] stuff bits [24] switch 1.8V request [23:0] I/O OCR R4 *)
  18. CMD_SWITCH_FUNC * = 6; (** CMD6 adtc [31] Mode 0:Check function 1:Switch function [30:24] reserved (All '0') [23:20] reserved for function group 6 (0h or Fh) [19:16] reserved for function group 5 (0h or Fh) [15:12] function group 4 for current limit [11:8] funciton group 3 for drive strength [7:4] function group 2 for command system [3:0] function group 1 for access mode R1 *)
  19. CMD_SELECT_DESELECT_CARD * = 7; (** CMD7 ac [31:16] RCA [15:0] stuff bits R1b (only from the selected card) *)
  20. CMD_SEND_IF_COND * = 8; (** CMD8 bcr [31:12] reserved bits [11:8] supply voltage(VHS) [7:0]check pattern R7 *)
  21. CMD_SEND_CSD * = 9; (** CMD9 ac [31:16] RCA [15:0] stuff bits R2 *)
  22. CMD_SEND_CID * = 10; (** CMD10 ac [31:16] RCA [15:0] stuff bits R2 *)
  23. CMD_VOLTAGE_SWITCH * = 11; (** CMD11 ac [31:0] reserved bits (all 0) R1 *)
  24. CMD_STOP_TRANSMISSION * = 12; (** CMD12 ac [31:0] stuff bits R1b *)
  25. CMD_SEND_STATUS * = 13; (** CMD13 ac [31:16] RCA [15:0] stuff bits R1 *)
  26. CMD_GO_INACTIVE_STATE * = 15; (** CMD15 ac [31:16] RCA [15:0] reserved bits - *)
  27. CMD_SET_BLOCKLEN * = 16; (** CMD16 ac [31:0] block length R1 *)
  28. CMD_READ_SINGLE_BLOCK * = 17; (** CMD17 adtc [31:0] data address2 R1 *)
  29. CMD_READ_MULTIPLE_BLOCK * = 18; (** CMD18 adtc [31:0] data address2 R1 *)
  30. CMD_SEND_TUNING_BLOCK * = 19; (** CMD19 adtc [31:0] reserved bits (all 0) R1 *)
  31. CMD_SPEED_CLASS_CONTROL * = 20; (** CMD20 ac [31:28]Speed Class Control [27:0] Reserved (all-0) R1b *)
  32. CMD_SET_BLOCK_COUNT * = 23; (** CMD23 ac [31:0] Block Count R1 *)
  33. CMD_WRITE_BLOCK * = 24; (** CMD24 adtc [31:0] data address2 R1 *)
  34. CMD_WRITE_MULTIPLE_BLOCK * = 25; (** CMD25 adtc [31:0] data address2 R1 *)
  35. CMD_PROGRAM_CSD * = 27; (** CMD27 adtc [31:0] stuff bits R1 *)
  36. CMD_SET_WRITE_PROT * = 28; (** CMD28 ac [31:0] data address2 R1b *)
  37. CMD_CLR_WRITE_PROT * = 29; (** CMD29 ac [31:0] data address2 R1b *)
  38. CMD_SEND_WRITE_PROT * = 30; (** CMD30 adtc [31:0] write protect data address2 R1 *)
  39. CMD_ERASE_WR_BLK_START * = 32; (** CMD32 ac [31:0] data address1 R1 *)
  40. CMD_ERASE_WR_BLK_END * = 33; (** CMD33 ac [31:0] data address1 R1 *)
  41. CMD_ERASE * = 38; (** CMD38 ac [31:0] stuff bits R1b *)
  42. CMD_LOCK_UNLOCK * = 42; (** CMD42 adtc [31:0] Reserved bits (Set all 0) R1 *)
  43. CMD_APP_CMD * = 55; (** CMD55 ac [31:16] RCA [15:0] stuff bits R1 *)
  44. CMD_GEN_CMD * = 56; (** CMD56 adtc [31:1] stuff bits. [0] RD/WR R1 *)
  45. (** Application Commands *) (*! Do Not Change Values *)
  46. ACMD_SET_BUS_WIDTH * = 6; (** ACMD6 ac [31:2] stuff bits [1:0] bus width R1 *)
  47. ACMD_SD_STATUS * = 13; (** ACMD13 adtc [31:0] stuff bits R1 *)
  48. ACMD_SEND_NUM_WR_BLOCKS * = 22; (** ACMD22 adtc [31:0] stuff bits R1 *)
  49. ACMD_SET_WR_BLK_ERASE_COUNT * = 23; (** ACMD23 ac [31:23] stuff bits [22:0] Number of blocks R1 *)
  50. ACMD_SD_SEND_OP_COND * = 41; (** ACMD41 bcr [31]reserved bit [30] HCS(OCR[30]) [29] reserved for eSD [28] XPC [27:25] reserved bits [24] S18R [23:0] VDD Voltage Window(OCR[23:0]) R3 *)
  51. ACMD_SET_CLR_CARD_DETECT * = 42; (** ACMD42 ac [31:1] stuff bits [0] set_cd R1 *)
  52. ACMD_SEND_SCR * = 51; (** ACMD51 adtc [31:0] stuff bits R1 *)
  53. (** Errors *)
  54. ErrorNone * = 0;
  55. ErrorCmdTimeout * = 1;
  56. ErrorCmdCrc * = 2;
  57. ErrorDatTimeout * = 3;
  58. ErrorDatCrc * = 4;
  59. ErrorNoCard * = 5;
  60. ErrorCard * = 6;
  61. ErrorUnrecoverable * = 7;
  62. ErrorInvalidParameters * = 8;
  63. (** Card Versions *)
  64. Version1 * = 0; (** v1.00 or v1.01 *)
  65. Version1p1 * = 1; (** v1.10 *)
  66. Version2 * = 2; (** v2.00 *)
  67. Version3 * = 3; (** v3.00 *)
  68. (** Card Type *)
  69. TypeNone * = 0;
  70. TypeSDSC * = 1;
  71. TypeSDHC * = 2;
  72. TypeSDXC * = 3;
  73. (** Card Events *)
  74. OnInitialization * = 0;
  75. OnRemoval * = 1;
  76. OnReadComplete * = 2;
  77. OnWriteComplete * = 3;
  78. (** Command Record Flags *)
  79. FlagData * = 0;
  80. FlagRead * = 1;
  81. FlagAutoCmd12 * = 2;
  82. FlagAutoCmd23 * = 3;
  83. FlagMultipleBlockTx * = 4;
  84. FlagCountBlocks * = 5;
  85. FlagUseDma * = 6;
  86. FlagAbort * = 7;
  87. FlagApplicationCmd * = 8;
  88. FlagIgnoreIllegalCmd * = 9;
  89. (** Response Types *) (*! Do not change values *)
  90. ResponseNone * = -1;
  91. ResponseR1 * = 0;
  92. ResponseR1b * = 1;
  93. ResponseR2 * = 2;
  94. ResponseR3 * = 3;
  95. ResponseR4 * = 4;
  96. ResponseR5 * = 5;
  97. ResponseR5b * = 6;
  98. ResponseR6 * = 7;
  99. ResponseR7 * = 8;
  100. (** Card States *)
  101. CardIdle = 0;
  102. CardReady = 1;
  103. CardIdentification = 2;
  104. CardStandby = 3;
  105. CardTransfer = 4;
  106. CardData = 5;
  107. CardReceive = 6;
  108. CardProgram = 7;
  109. CardDisabled = 8;
  110. (** Operation modes *)
  111. OpCpu = 0;
  112. OpSdma = 1;
  113. OpAdma = 2;
  114. (* Present State bits *)
  115. PresentState_CommandInhibitCmd = 0;
  116. PresentState_CommandInhibitDat = 1;
  117. PresentState_DatLineActive = 2;
  118. PresentState_RetuningRequest = 3;
  119. PresentState_WriteTransferActive = 8;
  120. PresentState_ReadTransferActive = 9;
  121. PresentState_BufferWriteEnable = 10;
  122. PresentState_BufferReadEnable = 11;
  123. PresentState_CardInserted = 16;
  124. PresentState_CardStateStable = 17;
  125. PresentState_CardDetectPinLevel = 18;
  126. PresentState_WriteProtectSwitchPinLevel = 19;
  127. PresentState_CmdLineSignalLevel = 24;
  128. PresentState_DatLineSignalLevelOfs = 20;
  129. PresentState_DatLineSignalLevelMask = {20 .. 23};
  130. (* Interrupt Status, Status Enable, Signal Enable bits *)
  131. Interrupt_Normal_CommandComplete = 0;
  132. Interrupt_Normal_TransferComplete = 1;
  133. Interrupt_Normal_BlockGapEvent = 2;
  134. Interrupt_Normal_DmaInterrupt = 3;
  135. Interrupt_Normal_BufferWriteReady = 4;
  136. Interrupt_Normal_BufferReadReady = 5;
  137. Interrupt_Normal_CardInsertion = 6;
  138. Interrupt_Normal_CardRemoval = 7;
  139. Interrupt_Normal_CardInterrupt = 8;
  140. Interrupt_Normal_IntA = 9;
  141. Interrupt_Normal_IntB = 10;
  142. Interrupt_Normal_IntC = 11;
  143. Interrupt_Normal_RetuningEvent = 12;
  144. Interrupt_Normal_ErrorInterrupt = 15;
  145. Interrupt_Error_CommandTimeout = 16;
  146. Interrupt_Error_CommandCrc = 17;
  147. Interrupt_Error_CommandEndBit = 18;
  148. Interrupt_Error_CommandIndex = 19;
  149. Interrupt_Error_DataTimeout = 20;
  150. Interrupt_Error_DataCrc = 21;
  151. Interrupt_Error_DataEndBit = 22;
  152. Interrupt_Error_CurrentLimit = 23;
  153. Interrupt_Error_AutoCmd12 = 24;
  154. Interrupt_Error_Adma = 25;
  155. Interrupt_Error_Tuning = 26;
  156. Interrupt_Normal_All = {Interrupt_Normal_CommandComplete, Interrupt_Normal_TransferComplete, Interrupt_Normal_BlockGapEvent, Interrupt_Normal_DmaInterrupt,
  157. Interrupt_Normal_BufferWriteReady, Interrupt_Normal_BufferReadReady, Interrupt_Normal_CardInsertion, Interrupt_Normal_CardRemoval,
  158. Interrupt_Normal_CardInterrupt, Interrupt_Normal_IntA, Interrupt_Normal_IntB, Interrupt_Normal_IntC, Interrupt_Normal_RetuningEvent,
  159. Interrupt_Normal_ErrorInterrupt};
  160. Interrupt_Error_All = {Interrupt_Error_CommandTimeout, Interrupt_Error_CommandCrc, Interrupt_Error_CommandEndBit,
  161. Interrupt_Error_CommandIndex, Interrupt_Error_DataTimeout, Interrupt_Error_DataCrc, Interrupt_Error_DataEndBit, Interrupt_Error_CurrentLimit,
  162. Interrupt_Error_AutoCmd12, Interrupt_Error_Adma, Interrupt_Error_Tuning};
  163. Interrupt_All = Interrupt_Normal_All + Interrupt_Error_All;
  164. (* Transfer Mode Register bits *)
  165. TransferMode_DmaEnable = 0;
  166. TransferMode_BlockCountEnable = 1;
  167. TransferMode_AutoCmdOfs = 2;
  168. TransferMode_AutoCmdMask = {2 .. 3};
  169. TransferMode_DataTxDirection = 4;
  170. TransferMode_MultipleBlocks = 5;
  171. TransferMode_AutoCmd_None = {};
  172. TransferMode_AutoCmd_Cmd12 = {2};
  173. TransferMode_AutoCmd_Cmd23 = {3};
  174. (* Command Register bits *)
  175. Command_ResponseTypeOffset = 0;
  176. Command_CrcCheckEnable = 3;
  177. Command_IndexCheckEnable = 4;
  178. Command_DataPresent = 5;
  179. Command_CommandTypeOffset = 6;
  180. Command_CommandTypeMask = {6 .. 7};
  181. Command_CommandIndexOffset = 8;
  182. Command_CommandIndexMask = {8 .. 13};
  183. Command_ResponseType_None = 0;
  184. Command_ResponseType_136b = 1;
  185. Command_ResponseType_48b = 2;
  186. Command_ResponseType_48bBusy = 3;
  187. (* Capabilities Register *)
  188. (* Low Word *)
  189. Capabilities_TimeoutClockFrequencyOfs = 0;
  190. Capabilities_TimeoutClockFrequencyMask = {0 .. 5};
  191. Capabilities_TimeoutClockUnit = 7;
  192. Capabilities_BaseClockFreqSdOfs = 8;
  193. Capabilities_BaseClockFreqSdMask = {8 .. 15};
  194. Capabilities_MaxBlockLenOfs = 16;
  195. Capabilities_MaxBlockLenMask = {16 .. 17};
  196. Capabilities_8BitEmbedded = 18;
  197. Capabilities_ADMA2 = 19;
  198. Capabilities_HighSpeed = 21;
  199. Capabilities_SDMA = 22;
  200. Capabilities_SuspendResume = 23;
  201. Capabilities_Voltage33 = 24;
  202. Capabilities_Voltage30 = 25;
  203. Capabilities_Voltage18 = 26;
  204. Capabilities_64BitBus = 28;
  205. Capabilities_AsyncInterrupt = 29;
  206. Capabilities_SlotTypeOfs = 30;
  207. Capabilities_SlotTypeMask = {30 .. 31};
  208. (* High Word *)
  209. Capabilities_SDR50 = 0;
  210. Capabilities_SDR104 = 1;
  211. Capabilities_DDR50 = 2;
  212. Capabilities_DriverTypeA = 4;
  213. Capabilities_DriverTypeC = 5;
  214. Capabilities_DriverTypeD = 6;
  215. Capabilities_TimerCountRetuningOfs = 8;
  216. Capabilities_TimerCountRetuningMask = {8 .. 11};
  217. Capabilities_TuningSDR50 = 13;
  218. Capabilities_RetuningModesOfs = 14;
  219. Capabilities_RetuningModesMask = {14 .. 15};
  220. Capabilities_ClockMultiplierOfs = 16;
  221. Capabilities_ClockMultiplierMask = {16 .. 23};
  222. (* Patterns *)
  223. Capabilities_SlotType_Removable = {};
  224. Capabilities_SlotType_Embedded = {30};
  225. Capabilities_SlotType_SharedBus = {31};
  226. (* Host Control 1 register values *)
  227. HostControl1_LedControl = 0;
  228. HostControl1_DataWidthTransfer = 1;
  229. HostControl1_HighSpeedEnable = 2;
  230. HostControl1_DmaSelectOfs = 3;
  231. HostControl1_DmaSelectMask = {3 .. 4};
  232. HostControl1_ExtendedDataTxWidth = 5;
  233. HostControl1_CardDetectTestLevel = 6;
  234. HostControl1_CardDetectSignalSelection = 7;
  235. HostControl1_DmaSelect_Sdma = {};
  236. HostControl1_DmaSelect_32Adma = {4};
  237. (* SoftwareReset register values *)
  238. SoftwareResetAll = 1;
  239. SoftwareResetCmd = 2;
  240. SoftwareResetDat = 4;
  241. (* Clock Control register values *)
  242. ClockControl_InternalClockEnable = 0;
  243. ClockControl_InternalClockState = 1;
  244. ClockControl_SdClockEnable = 2;
  245. ClockControl_ClockGeneratorSelect = 5;
  246. ClockControl_SdClockFreqUpperOfs = 6;
  247. ClockControl_SdClockFreqUpperMask = {6, 7};
  248. ClockControl_SdClockFreqOfs = 8;
  249. ClockControl_SdClockFreqMask = {8 .. 15};
  250. (* Power Control register values *)
  251. PowerControl_SDBusPower = 0;
  252. PowerControl_SDBusVoltageOfs = 1;
  253. PowerControl_SDBusVoltageMask = {1 .. 3};
  254. PowerControl_SDBusVoltage_18 = {1, 3};
  255. PowerControl_SDBusVoltage_30 = {2, 3};
  256. PowerControl_SDBusVoltage_33 = {1, 2, 3};
  257. (* Host Controller Version *)
  258. HostControllerVersion_SpecificationMask = {0 .. 7};
  259. HostControllerVersion_VendorOfs = 8;
  260. HostControllerVersion_VendorMask = {8 .. 15};
  261. (* Card Status register -- R1 *)
  262. CardStatus_AkeSpecError = 3;
  263. CardStatus_AppCmd = 5;
  264. CardStatus_ReadyForData = 8;
  265. CardStatus_CurrentStateOffset = 9;
  266. CardStatus_CurrentStateMask = {9 .. 12};
  267. CardStatus_EraseReset = 13;
  268. CardStatus_CardEccDisable = 14;
  269. CardStatus_WpEraseSkip = 15;
  270. CardStatus_CsdOverwrite = 16;
  271. CardStatus_Error = 19;
  272. CardStatus_CcError = 20;
  273. CardStatus_CardEccFailed = 21;
  274. CardStatus_IllegalCommand = 22;
  275. CardStatus_ComCrcError = 23;
  276. CardStatus_LockUnlockFailed = 24;
  277. CardStatus_CardIsLocked = 25;
  278. CardStatus_WpViolation = 26;
  279. CardStatus_EraseParam = 27;
  280. CardStatus_EraseSeqError = 28;
  281. CardStatus_BlockLenError = 29;
  282. CardStatus_AddressError = 30;
  283. CardStatus_OutOfRange = 31;
  284. (* OCR Registers *)
  285. CardOcr_Vdd27_28 = 15;
  286. CardOcr_Vdd28_29 = 16;
  287. CardOcr_Vdd29_30 = 17;
  288. CardOcr_Vdd30_31 = 18;
  289. CardOcr_Vdd31_32 = 19;
  290. CardOcr_Vdd32_33 = 20;
  291. CardOcr_Vdd33_34 = 21;
  292. CardOcr_Vdd34_35 = 22;
  293. CardOcr_Vdd35_36 = 23;
  294. CardOcr_S18A = 24;
  295. CardOcr_CardCapacityStatus = 30;
  296. CardOcr_PowerUpStatus = 31;
  297. (* CSD Register. This excludes the CRC7 of the specifications. *)
  298. CardCsd_FileFormatOfs = 2;
  299. CardCsd_FileFormatWidth = 2;
  300. CardCsd_TmpWriteProtect = 4;
  301. CardCsd_PermWriteProtect = 5;
  302. CardCsd_Copy = 6;
  303. CardCsd_FileFormatGrp = 7;
  304. CardCsd_WriteBlPartial = 13;
  305. CardCsd_WriteBlLenOfs = 14;
  306. CardCsd_WriteBlLenWidth = 4;
  307. CardCsd_R2wFactorOfs = 18;
  308. CardCsd_R2wFactorWidth = 3;
  309. CardCsd_WpGrpEnable = 23;
  310. CardCsd_WpGrpSizeOfs = 24;
  311. CardCsd_WpGrpSizeWidth = 7;
  312. CardCsd_SectorSizeOfs = 31;
  313. CardCsd_SectorSizeWidth = 7;
  314. CardCsd_EraseBlkEn = 38;
  315. CardCsd_CSizeMultOfs1 = 39; (** V1 *)
  316. CardCsd_CSizeMultWidth1 = 3; (** V1 *)
  317. CardCsd_VddWCurrMaxOfs1 = 42; (** V1 *)
  318. CardCsd_VddWCurrMaxWidth1 = 3; (** V1 *)
  319. CardCsd_VddWCurrMinOfs1 = 45; (** V1 *)
  320. CardCsd_VddWCurrMinWidth1 = 3; (** V1 *)
  321. CardCsd_VddRCurrMaxOfs1 = 48; (** V1 *)
  322. CardCsd_VddRCurrMaxWidth1 = 3; (** V1 *)
  323. CardCsd_VddRCurrMinOfs1 = 51; (** V1 *)
  324. CardCsd_VdddRCurrMaxWidth1 = 3; (** V1 *)
  325. CardCsd_CSizeOfs1 = 54; (** V1 *)
  326. CardCsd_CSizeWidth1 = 12; (** V1 *)
  327. CardCsd_CSizeOfs2 = 40; (** V2 *)
  328. CardCsd_CSizeWidth2 = 22; (** V2 *)
  329. CardCsd_DsrImp = 68;
  330. CardCsd_ReadBlkMisalign = 69;
  331. CardCsd_WriteBlkMisalign = 70;
  332. CardCsd_ReadBlPartial = 71;
  333. CardCsd_ReadBlLenOfs = 72;
  334. CardCsd_ReadBlLenWidth = 4;
  335. CardCsd_CccOfs = 76;
  336. CardCsd_CccWidth = 12;
  337. CardCsd_TranSpeedOfs = 88;
  338. CardCsd_TranSpeedWidth = 8;
  339. CardCsd_NsacOfs = 96;
  340. CardCsd_NsacWidth = 8;
  341. CardCsd_TaacOfs = 104;
  342. CardCsd_TaacWidth = 8;
  343. CardCsd_CsdStructureOfs = 118;
  344. CardCsd_CsdStructureWidth = 2;
  345. (* SCR Register *)
  346. CardScr_CommandSupportOfs = 32;
  347. CardScr_CommandSupportWidth = 2;
  348. CardScr_ExtendedSecurityOfs = 43;
  349. CardScr_ExtendedSecurityWidth = 4;
  350. CardScr_SpecV3 = 47;
  351. CardScr_SdBusWidthsOfs = 48;
  352. CardScr_SdBusWidthsWidth = 4;
  353. CardScr_SecurityOfs = 52;
  354. CardScr_SecurityWidth = 3;
  355. CardScr_DataStateAfterErase = 55;
  356. CardScr_SdSpecVersionOfs = 56;
  357. CardScr_SdSpecVersionWidth = 4;
  358. CardScr_StructureOfs = 60;
  359. CardScr_StructureWidth = 4;
  360. (* SCR register fields values *)
  361. CardScr_SdBusWidths_1 = 0;
  362. CardScr_SdBusWidths_4 = 2;
  363. (* Transfer options *)
  364. TxDma = TRUE; (** Use DMA for transfers on all hosts that support it *)
  365. TxBufferSize = 4096; (** Buffer size used for DMA transfers *)
  366. TxBufferAlign = 32; (** Alignment requirement on DMA buffer: here cache line size of ARM *)
  367. (* Multi-threading *)
  368. Synchronize * = FALSE; (** Do we need to take care of concurrency? *)
  369. (* Tracing options for debugging *)
  370. TraceCmd = FALSE;
  371. Trace = FALSE;
  372. TYPE
  373. (** Interface for data command execute method of host controller *)
  374. CommandExecuter * = PROCEDURE (CONST command: Command; VAR data: ARRAY OF CHAR; ofs, len: LONGINT; VAR result: LONGINT): BOOLEAN;
  375. (**
  376. SD Host controller descriptor.
  377. *)
  378. HostController * = POINTER TO HostControllerDesc;
  379. HostControllerDesc * = RECORD
  380. baseFrequency -, (** Base hc clock frequency *)
  381. frequency -, (** Bus frequency *)
  382. timeoutFreq, (** Timeout clock frequency *)
  383. state -, (** HC state *)
  384. version -: LONGINT; (** Specifications version *)
  385. execute -: CommandExecuter; (** Method to execute command with data transmission *)
  386. opmode, (** Host controller operation mode for data transfers *)
  387. lastRca: LONGINT; (** Last RCA selected by the controller. *)
  388. acquire *, release *: PROCEDURE {DELEGATE};
  389. handle: EventHandler; (** Card event handler *)
  390. handlerParam: ANY; (** Parameter of the eventHandler *)
  391. regs: HcRegisters; (** Memory-mapped I/O registers *)
  392. cards: Card; (** List of cards on this HC *)
  393. next: HostController; (** Linked list of controllers for interrupt handling *)
  394. dmaBuf: POINTER TO ARRAY OF CHAR;
  395. dmaBufAdr: ADDRESS;
  396. desc: ARRAY 5 OF HUGEINT; (** DMA descriptor *)
  397. descOfs: LONGINT;
  398. END;
  399. (**
  400. Command record.
  401. This record type is used to describe a command and its result.
  402. To execute a command, fill in the fields 'hc', 'command', 'argument', 'responseType'.
  403. If the command uses the DAT line or is an application command, setup then necessary flags.
  404. If the command is an application command, you also need to specify the RCA for CMD55.
  405. After command execution, you can read the command response in the 'response' field. Use the
  406. 'GetR*' procedures to extract all information from this field in a convenient way.
  407. *)
  408. Command * = RECORD
  409. hc *: HostController; (** Host controller on which the command is executed *)
  410. rca *, (** Optional RCA parameter. Required only for ACMDs *)
  411. command *, (** Command number *)
  412. argument *, (** Command argument *)
  413. responseType *: LONGINT; (** Response type *)
  414. flags *: SET; (** Command flags *)
  415. response *: ARRAY 4 OF LONGINT; (** Response *)
  416. END;
  417. (** Card descriptor *)
  418. Card * = POINTER TO CardDesc;
  419. CardDesc * = RECORD
  420. state -, (** Card state. Currently not used *)
  421. (*type -, (** Type of card. One of 'Type*' constants *)*)
  422. rca -: LONGINT; (** Card RCA *)
  423. cid: ARRAY 4 OF LONGINT; (** Raw CID *)
  424. csd -: Csd; (** CSD *)
  425. scr -: Scr; (** SCR *)
  426. ocr: SET; (** Raw OCR *)
  427. hc -: HostController; (** Host controller on which the card is attached *)
  428. next: Card; (** Internal linked list of cards attached to the same HC *)
  429. acquire *, release *: PROCEDURE {DELEGATE};
  430. END;
  431. (* Card Registers *)
  432. Csd * = RECORD
  433. (* Card properties *)
  434. capacity *: HUGEINT; (** Card capacity in bytes *)
  435. sectorSize *: LONGINT; (** Size of a sector in bytes *)
  436. commandClasses *: SET; (** Command classes supported by the card *)
  437. (* Timing info *)
  438. r2w *: LONGINT; (** Read to write time factor = read time / write time *)
  439. taac *: REAL; (** Asynchronous access time, in s *)
  440. nsac *: LONGINT; (** Worst-case clock dependent access time, in clock cycles *)
  441. txSpeed *: LONGINT; (** Max transfer speed in bit/s *)
  442. END;
  443. (** SCR register *)
  444. Scr * = RECORD
  445. version *, (** Card physical spec. version: one of Version* *)
  446. security *: LONGINT; (** Card security type: one of Type* *)
  447. busWidth *: SET; (** Bus widths supported by the card *)
  448. END;
  449. (** SWITCH_FUNC returned status *)
  450. SwitchFuncStatus * = RECORD
  451. current *: LONGINT; (** Current for specified config *)
  452. functionGroups *: ARRAY 6 OF SET; (** Supported function in each group *)
  453. functionStatus *: ARRAY 6 OF LONGINT; (** Function status *)
  454. END;
  455. (** Card event handler. 'card' is the card for which an event is reported (can be a new card object) and 'event' is one of 'On*' constants *)
  456. EventHandler * = PROCEDURE {DELEGATE} (card: Card; event: LONGINT; param: ANY);
  457. (** Host controller registers *)
  458. HcRegisters = POINTER {UNSAFE,UNTRACED} TO RECORD
  459. SDMASystemAddress {ALIGNED(1)}: LONGINT; (** offset = 0H *)
  460. BlockSize {ALIGNED(1)}, (** offset = 4H *)
  461. BlockCount {ALIGNED(1)}: INTEGER; (** offset = 6H *)
  462. Argument1 {ALIGNED(1)}: LONGINT; (** offset = 8H *)
  463. TransferMode {ALIGNED(1)}, (** offset = 0CH *)
  464. Command {ALIGNED(1)}: INTEGER; (** offset = 0EH *)
  465. Response {ALIGNED(1)}: ARRAY 4 OF LONGINT; (** offset = 10H *)
  466. BufferData {ALIGNED(1)}: LONGINT;
  467. PresentState {ALIGNED(1)}: SET;
  468. HostControl1 {ALIGNED(1)},
  469. PowerControl {ALIGNED(1)},
  470. BlockGapControl {ALIGNED(1)},
  471. WakeupControl {ALIGNED(1)}: SHORTINT;
  472. ClockControl {ALIGNED(1)}: INTEGER;
  473. TimeoutControl {ALIGNED(1)},
  474. SoftwareReset {ALIGNED(1)}: SHORTINT;
  475. InterruptStatus {ALIGNED(1)},
  476. InterruptStatusEnable {ALIGNED(1)},
  477. InterruptSignalEnable {ALIGNED(1)}: SET;
  478. AutoCmdErrorStatus {ALIGNED(1)},
  479. HostControl2 {ALIGNED(1)}: INTEGER;
  480. Capabilities {ALIGNED(1)}: ARRAY 2 OF SET;
  481. MaximumCurrentCapabilities {ALIGNED(1)}: HUGEINT;
  482. ForceEventAutoCmdErrorStatus {ALIGNED(1)},
  483. ForceEventErrorInterruptStatus {ALIGNED(1)}: INTEGER;
  484. AdmaErrorStatus {ALIGNED(1)}: SHORTINT;
  485. padding0 {ALIGNED(1)}: ARRAY 3 OF SHORTINT;
  486. AdmaSystemAddress {ALIGNED(1)}: HUGEINT;
  487. PresetValues {ALIGNED(1)}: ARRAY 8 OF INTEGER;
  488. padding1 {ALIGNED(1)}: ARRAY 28 OF LONGINT;
  489. SharedBusControl {ALIGNED(1)}: LONGINT;
  490. padding2 {ALIGNED(1)}: ARRAY 6 OF LONGINT;
  491. SlotInterruptStatus {ALIGNED(1)},
  492. HostControllerVersion {ALIGNED(1)}: INTEGER;
  493. END;
  494. VAR
  495. (** List of all host controllers *)
  496. hcs: HostController;
  497. (* ==================== Host Controller (Low-Level) Interface ==================== *)
  498. (**
  499. Create an host controller descriptor and initializes it with the given info.
  500. 'baseAddress' is the base address of the IO registers.
  501. 'extClockFreq' is an optional external clock frequency. It is used iff the host controller has no information about its clock frequency.
  502. 'handler' is the event handler and 'param' is user parameter.
  503. *)
  504. PROCEDURE New * (baseAddress: ADDRESS; extClockFreq: LONGINT; handler: EventHandler; param: ANY): HostController;
  505. VAR
  506. hc: HostController;
  507. val, result: LONGINT;
  508. BEGIN
  509. NEW(hc);
  510. hc.regs := baseAddress;
  511. hc.handle := handler;
  512. IF ~Reset(hc, TRUE, TRUE) THEN RETURN NIL END;
  513. hc.baseFrequency := LSH(SYSTEM.VAL(LONGINT, hc.regs.Capabilities[0] * Capabilities_BaseClockFreqSdMask), -Capabilities_BaseClockFreqSdOfs);
  514. IF hc.baseFrequency = 0 THEN
  515. hc.baseFrequency := extClockFreq
  516. END;
  517. hc.timeoutFreq := LSH(SYSTEM.VAL(LONGINT, hc.regs.Capabilities[0] * Capabilities_TimeoutClockFrequencyMask), -Capabilities_TimeoutClockFrequencyOfs) * 1000;
  518. IF Capabilities_TimeoutClockUnit IN hc.regs.Capabilities[0] THEN hc.timeoutFreq := hc.timeoutFreq * 1000 END;
  519. IF hc.timeoutFreq = 0 THEN hc.timeoutFreq := extClockFreq END;
  520. SetBusClock(hc, InitialClockFrequency);
  521. SetTimeout(hc, 10);
  522. (* Power select 3.3V bus voltage *)
  523. hc.regs.PowerControl := SYSTEM.VAL(SHORTINT, PowerControl_SDBusVoltage_33 + {PowerControl_SDBusPower});
  524. (* Enable All Interrupts *)
  525. hc.regs.InterruptStatusEnable := Interrupt_All;
  526. hc.regs.InterruptSignalEnable := {Interrupt_Normal_CardInsertion, Interrupt_Normal_CardRemoval};
  527. hc.regs.BlockGapControl := 0;
  528. val := LONGINT(hc.regs.HostControllerVersion);
  529. hc.version := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, val) * HostControllerVersion_SpecificationMask) + 1;
  530. IF Trace THEN
  531. SdEnvironment.String("[SD] New Host Controller v");
  532. SdEnvironment.Int(hc.version, 0);
  533. SdEnvironment.String(" at ");
  534. SdEnvironment.Address(baseAddress);
  535. SdEnvironment.Ln;
  536. END;
  537. IF Synchronize THEN SdEnvironment.GetLock(hc.acquire, hc.release) END;
  538. (* Select method according to DMA support *)
  539. IF TxDma THEN
  540. IF (Capabilities_ADMA2 IN hc.regs.Capabilities[0]) THEN
  541. hc.execute := ExecuteAdmaCommand;
  542. hc.opmode := OpAdma;
  543. INC(hc.regs.HostControl1, 10H);
  544. NEW(hc.dmaBuf, TxBufferSize + TxBufferAlign);
  545. hc.dmaBufAdr := ADDRESSOF(hc.dmaBuf[0]) + (TxBufferAlign) - ADDRESSOF(hc.dmaBuf[0]) MOD (TxBufferAlign);
  546. hc.descOfs := (TxBufferAlign - ADDRESSOF(hc.desc[0]) MOD TxBufferAlign) DIV SIZEOF(HUGEINT);
  547. ASSERT(hc.dmaBufAdr MOD TxBufferAlign = 0);
  548. (*! NOT IMPLEMENTED YET *)(*ELSIF (Capabilities_SDMA IN hc.regs.Capabilities[0]) THEN
  549. SdEnvironment.String("[SD] Host Controller uses SDMA");
  550. SdEnvironment.Ln;
  551. hc.execute := ExecuteAdmaCommand;
  552. hc.opmode := OpSdma*)
  553. ELSE
  554. hc.execute := ExecuteDataCommand;
  555. hc.opmode := OpCpu
  556. END
  557. ELSE
  558. hc.execute := ExecuteDataCommand;
  559. hc.opmode := OpCpu
  560. END;
  561. (* If there is a card already, initialize it *)
  562. IF (PresentState_CardInserted IN hc.regs.PresentState) & (PresentState_CardStateStable IN hc.regs.PresentState) THEN
  563. NEW(hc.cards);
  564. IF InitCard(hc, hc.cards, result) & (hc.handle # NIL) THEN
  565. hc.handle(hc.cards, OnInitialization, hc.handlerParam)
  566. ELSIF hc.handle # NIL THEN
  567. SdEnvironment.String("[SD] Could not initialize inserted card: error ");
  568. SdEnvironment.Int(result, 0);
  569. SdEnvironment.Ln
  570. END
  571. END;
  572. hc.next := hcs;
  573. hcs := hc;
  574. RETURN hc
  575. END New;
  576. (**
  577. Execute the command 'command', without data transfer. If you need data transfer, use 'ExecuteDataCommand'.
  578. Performs all necessary steps for executing a command:
  579. o Runs CMD55 if command is an application command
  580. o Execute the command
  581. o Wait for response
  582. *)
  583. PROCEDURE ExecuteCommand * (VAR command: Command; VAR result: LONGINT): BOOLEAN;
  584. VAR
  585. status, r1: SET;
  586. BEGIN
  587. IF Synchronize THEN command.hc.acquire END;
  588. result := ErrorNone;
  589. (* Check Parameters *)
  590. IF {FlagData, FlagRead, FlagAutoCmd12, FlagAutoCmd23, FlagMultipleBlockTx, FlagCountBlocks, FlagUseDma} * command.flags # {} THEN
  591. result := ErrorInvalidParameters;
  592. IF Synchronize THEN command.hc.release END;
  593. RETURN FALSE
  594. END;
  595. (*IF ~Reset(command.hc, TRUE, FALSE) THEN
  596. result := ErrorCard;
  597. IF Synchronize THEN command.hc.release END;
  598. RETURN FALSE
  599. END;*)
  600. IF (FlagApplicationCmd IN command.flags) THEN
  601. IF ~StartCommand(command.hc, CMD_APP_CMD, LSH(command.rca, 16), ResponseR1, FlagRead IN command.flags, FALSE, FALSE, FALSE, status, result) THEN
  602. IF Synchronize THEN command.hc.release END;
  603. RETURN FALSE
  604. END;
  605. r1 := GetR1(command);
  606. IF Trace THEN PrintCardStatus(r1) END;
  607. IF ~(FlagIgnoreIllegalCmd IN command.flags) & (CardStatus_Error IN r1) THEN
  608. result := ErrorCard;
  609. IF Synchronize THEN command.hc.release END;
  610. RETURN FALSE
  611. END
  612. END;
  613. IF ~StartCommand(
  614. command.hc, command.command, command.argument, command.responseType, FlagRead IN command.flags, FALSE,
  615. FALSE (*command.responseType = ResponseR1b*), FlagAbort IN command.flags, status, result) THEN
  616. IF Synchronize THEN command.hc.release END;
  617. RETURN FALSE
  618. END;
  619. GetResponse(command.hc, command.responseType, command.response);
  620. IF command.command = CMD_SELECT_DESELECT_CARD THEN
  621. command.hc.lastRca := LSH(command.argument, -16)
  622. ELSIF command.command = CMD_GO_IDLE_STATE THEN
  623. command.hc.lastRca := 0
  624. END;
  625. IF Synchronize THEN command.hc.release END;
  626. RETURN TRUE
  627. END ExecuteCommand;
  628. (**
  629. Execute command with data transfer using CPU.
  630. Data is read from/written to [data[ofs], data[ofs + len]).
  631. *)
  632. PROCEDURE ExecuteDataCommand (CONST command: Command; VAR data: ARRAY OF CHAR; ofs, len: LONGINT; VAR result: LONGINT): BOOLEAN;
  633. TYPE
  634. DataBytes = ARRAY 4 OF CHAR;
  635. VAR
  636. tmp: DataBytes;
  637. i, stepLen: LONGINT;
  638. hc: HostController;
  639. r1, status: SET;
  640. BEGIN
  641. ASSERT(ofs + len <= LEN(data), 7);
  642. result := ErrorNone;
  643. IF ~(FlagData IN command.flags) THEN
  644. result := ErrorInvalidParameters;
  645. RETURN FALSE
  646. END;
  647. hc := command.hc;
  648. IF Synchronize THEN hc.acquire END;
  649. (* Set timeout *)
  650. (*SetTimeout(hc, 2);*)
  651. (*IF (*~Reset(hc, TRUE, FALSE) OR*) ~Reset(hc, FALSE, TRUE) THEN
  652. result := ErrorCard;
  653. IF Synchronize THEN hc.release END;
  654. RETURN FALSE
  655. END;*)
  656. IF (FlagApplicationCmd IN command.flags) THEN
  657. IF ~StartCommand(hc, CMD_APP_CMD, LSH(command.rca, 16), ResponseR1, FlagRead IN command.flags, FALSE, FALSE, FALSE, status, result) THEN
  658. IF Synchronize THEN hc.release END;
  659. RETURN FALSE
  660. END;
  661. r1 := SYSTEM.VAL(SET, command.response[0]);
  662. IF CardStatus_Error IN r1 THEN
  663. IF Synchronize THEN hc.release END;
  664. RETURN FALSE
  665. END;
  666. IF Trace THEN
  667. SdEnvironment.String("[SD] CMD55 Status:");
  668. SdEnvironment.Ln;
  669. PrintCardStatus(r1)
  670. END
  671. END;
  672. (* 1 *)
  673. IF ~(FlagApplicationCmd IN command.flags) &
  674. ((command.command = CMD_READ_SINGLE_BLOCK) OR (command.command = CMD_READ_MULTIPLE_BLOCK) OR
  675. (command.command = CMD_WRITE_BLOCK) OR (command.command = CMD_WRITE_MULTIPLE_BLOCK) OR
  676. (command.command = 53)(* SDIO Command *)) THEN
  677. IF len <= BlockSize THEN
  678. hc.regs.BlockSize := INTEGER(len);
  679. hc.regs.BlockCount := 1
  680. ELSE
  681. hc.regs.BlockSize := BlockSize;
  682. hc.regs.BlockCount := INTEGER(len DIV BlockSize)
  683. END;
  684. IF Trace THEN
  685. SdEnvironment.String("[SD] ");
  686. IF FlagRead IN command.flags THEN SdEnvironment.String("Read")
  687. ELSE SdEnvironment.String("Write") END;
  688. SdEnvironment.String(" parameters:"); SdEnvironment.Ln;
  689. SdEnvironment.String("[SD] Block Size = "); SdEnvironment.Int(hc.regs.BlockSize, 0); SdEnvironment.Ln;
  690. SdEnvironment.String("[SD] Block Count = "); SdEnvironment.Int(hc.regs.BlockCount, 0); SdEnvironment.Ln;
  691. SdEnvironment.String("[SD] CMD"); SdEnvironment.Int(command.command, 0); SdEnvironment.Ln;
  692. SdEnvironment.String("[SD] Argument = "); SdEnvironment.Address(command.argument); SdEnvironment.Ln
  693. END
  694. END;
  695. (* 3 - 8 *)
  696. (*IF (hc.regs.BlockSize < BlockSize) THEN
  697. IF ~StartCommand(hc, CMD_SET_BLOCKLEN, hc.regs.BlockSize, ResponseR1, FALSE, FALSE, result) THEN
  698. RETURN FALSE
  699. END
  700. END;*)
  701. IF ~StartCommand(hc, command.command, command.argument, ResponseR1, FlagRead IN command.flags, FALSE, TRUE, FALSE, status, result) THEN RETURN FALSE END;
  702. r1 := SYSTEM.VAL(SET, command.response[0]);
  703. IF CardStatus_Error IN r1 THEN
  704. IF Synchronize THEN hc.release END;
  705. RETURN FALSE
  706. END;
  707. IF Trace THEN PrintCardStatus(r1) END;
  708. WHILE len > 0 DO
  709. (* 14 *)
  710. IF FlagRead IN command.flags THEN
  711. REPEAT UNTIL (Interrupt_Normal_BufferReadReady IN hc.regs.InterruptStatus) OR (Interrupt_Normal_ErrorInterrupt IN hc.regs.InterruptStatus)
  712. ELSE
  713. REPEAT UNTIL (Interrupt_Normal_BufferWriteReady IN hc.regs.InterruptStatus) OR (Interrupt_Normal_ErrorInterrupt IN hc.regs.InterruptStatus)
  714. END;
  715. IF Interrupt_Normal_ErrorInterrupt IN hc.regs.InterruptStatus THEN
  716. IF ErrorRecovery(hc, result, status) THEN END;
  717. IF Interrupt_Error_DataTimeout IN status THEN
  718. result := ErrorDatTimeout
  719. ELSIF Interrupt_Error_DataCrc IN status THEN
  720. result := ErrorDatCrc
  721. ELSIF Interrupt_Error_DataEndBit IN status THEN
  722. result := ErrorCard
  723. END;
  724. IF Synchronize THEN hc.release END;
  725. RETURN FALSE
  726. END;
  727. (* 15 *)
  728. INCL(hc.regs.InterruptStatus, Interrupt_Normal_BufferReadReady);
  729. (* 16 *)
  730. stepLen := MIN(BlockSize, len);
  731. IF FlagRead IN command.flags THEN
  732. FOR i := 0 TO stepLen - 1 BY 4 DO
  733. SYSTEM.PUT32(ADDRESSOF(data[ofs + i]), hc.regs.BufferData);
  734. (*SYSTEM.VAL(LONGINT, tmp) := hc.regs.BufferData;
  735. SYSTEM.VAL(DataBytes, data[ofs + i]) := tmp*)
  736. END
  737. ELSE
  738. FOR i := 0 TO stepLen - 1 BY 4 DO
  739. tmp := SYSTEM.VAL(DataBytes, data[ofs + i]);
  740. hc.regs.BufferData := SYSTEM.VAL(LONGINT, tmp);
  741. END
  742. END;
  743. (* 17 *)
  744. INC(ofs, stepLen);
  745. DEC(len, stepLen)
  746. END;
  747. (* 18 -> Not infinite block *)
  748. REPEAT UNTIL Interrupt_Normal_TransferComplete IN hc.regs.InterruptStatus;
  749. (* 19 *)
  750. INCL(hc.regs.InterruptStatus, Interrupt_Normal_TransferComplete);
  751. (*DEC(hc.regs.ClockControl, LSH(1, ClockControl_SdClockEnable));
  752. hc.regs.SoftwareReset := SYSTEM.VAL(SHORTINT, {SoftwareResetCmd, SoftwareResetDat});
  753. REPEAT UNTIL hc.regs.SoftwareReset = 0;
  754. INC(hc.regs.ClockControl, LSH(1, ClockControl_SdClockEnable));*)
  755. IF Synchronize THEN hc.release END;
  756. RETURN Reset(hc, TRUE, FALSE) & Reset(hc, FALSE, TRUE)
  757. END ExecuteDataCommand;
  758. (**
  759. Execute Command with data transfers using ADMA
  760. *)
  761. PROCEDURE ExecuteAdmaCommand (CONST command: Command; VAR data: ARRAY OF CHAR; ofs, len: LONGINT; VAR result: LONGINT): BOOLEAN;
  762. TYPE
  763. QWord = ARRAY 2 OF ADDRESS;
  764. VAR
  765. (*!DBG*)t: HUGEINT;
  766. hc: HostController;
  767. desc: HUGEINT;
  768. r1, status: SET;
  769. address: ADDRESS;
  770. BEGIN
  771. hc := command.hc;
  772. (* Setup descriptor *)
  773. address := (*command.hc.dmaBufAdr*)ADDRESSOF(data[ofs]);
  774. SYSTEM.VAL(QWord, desc)[1] := address;
  775. SYSTEM.VAL(QWord, desc)[0] := LSH(len, 16) + 27H;
  776. hc.desc[hc.descOfs] := desc;
  777. SdEnvironment.FlushDCacheRange(ADDRESSOF(hc.desc[hc.descOfs]), 8);
  778. (*IF ~(FlagRead IN command.flags) THEN
  779. SYSTEM.MOVE(ADDRESSOF(data[ofs]), address, len);
  780. END;*)
  781. SdEnvironment.FlushDCacheRange(address, len);
  782. IF Synchronize THEN hc.acquire END;
  783. SetTimeout(hc, 10);
  784. IF ~Reset(hc, TRUE, FALSE) OR ~Reset(hc, FALSE, TRUE) THEN
  785. result := ErrorCard;
  786. IF Synchronize THEN hc.release END;
  787. RETURN FALSE
  788. END;
  789. (* 1 *)
  790. hc.regs.AdmaSystemAddress := ADDRESSOF(hc.desc[hc.descOfs]);
  791. IF (FlagApplicationCmd IN command.flags) THEN
  792. IF ~StartCommand(command.hc, CMD_APP_CMD, LSH(command.rca, 16), ResponseR1, FlagRead IN command.flags, FALSE, FALSE, FALSE, status, result) THEN
  793. IF Synchronize THEN hc.release END;
  794. RETURN FALSE
  795. END;
  796. r1 := SYSTEM.VAL(SET, command.response[0]);
  797. IF Trace THEN
  798. SdEnvironment.String("[SD] CMD55 Status:");
  799. SdEnvironment.Ln;
  800. PrintCardStatus(r1)
  801. END;
  802. IF CardStatus_Error IN r1 THEN
  803. result := ErrorCard;
  804. IF Synchronize THEN hc.release END;
  805. RETURN FALSE
  806. END
  807. END;
  808. (* 2-3 *)
  809. IF FlagData IN command.flags(*((command.command = CMD_READ_SINGLE_BLOCK) OR (command.command = CMD_READ_MULTIPLE_BLOCK) OR
  810. (command.command = CMD_WRITE_BLOCK) OR (command.command = CMD_WRITE_MULTIPLE_BLOCK) OR
  811. (command.command = 53)(* SDIO Command *))*) THEN
  812. IF len <= BlockSize THEN
  813. hc.regs.BlockSize := INTEGER(len);
  814. hc.regs.BlockCount := 1
  815. ELSE
  816. hc.regs.BlockSize := BlockSize;
  817. hc.regs.BlockCount := INTEGER(len DIV BlockSize)
  818. END;
  819. IF Trace THEN
  820. SdEnvironment.String("[SD] ");
  821. IF FlagRead IN command.flags THEN SdEnvironment.String("Read")
  822. ELSE SdEnvironment.String("Write") END;
  823. SdEnvironment.String(" parameters:"); SdEnvironment.Ln;
  824. SdEnvironment.String("[SD] Block Size = "); SdEnvironment.Int(hc.regs.BlockSize, 0); SdEnvironment.Ln;
  825. SdEnvironment.String("[SD] Block Count = "); SdEnvironment.Int(hc.regs.BlockCount, 0); SdEnvironment.Ln;
  826. SdEnvironment.String("[SD] CMD"); SdEnvironment.Int(command.command, 0); SdEnvironment.Ln;
  827. SdEnvironment.String("[SD] Argument = "); SdEnvironment.Address(command.argument); SdEnvironment.Ln
  828. END
  829. END;
  830. IF ~StartCommand(command.hc, command.command, command.argument, command.responseType, FlagRead IN command.flags, TRUE, TRUE, FALSE, status, result) THEN
  831. IF Synchronize THEN hc.release END;
  832. RETURN FALSE
  833. END;
  834. r1 := SYSTEM.VAL(SET, command.response[0]);
  835. IF CardStatus_Error IN r1 THEN
  836. result := ErrorCard;
  837. IF Synchronize THEN hc.release END;
  838. RETURN FALSE
  839. END;
  840. IF Trace THEN PrintCardStatus(r1) END;
  841. WHILE ~((Interrupt_Normal_TransferComplete IN status) OR (Interrupt_Normal_ErrorInterrupt IN status)) DO
  842. status := hc.regs.InterruptStatus
  843. END;
  844. IF Interrupt_Normal_ErrorInterrupt IN status THEN
  845. IF ErrorRecovery(hc, result, status) THEN END;
  846. IF Interrupt_Error_DataTimeout IN status THEN
  847. result := ErrorDatTimeout
  848. ELSIF Interrupt_Error_DataCrc IN status THEN
  849. result := ErrorDatCrc
  850. ELSIF Interrupt_Error_DataEndBit IN status THEN
  851. result := ErrorCard
  852. END;
  853. IF Synchronize THEN hc.release END;
  854. RETURN FALSE
  855. END;
  856. hc.regs.InterruptStatus := status;
  857. IF FlagRead IN command.flags THEN
  858. SdEnvironment.InvalidateDCacheRange(address, len);
  859. (*SYSTEM.MOVE(address, ADDRESSOF(data[ofs]), len)*)
  860. END;
  861. IF Synchronize THEN hc.release END;
  862. RETURN TRUE
  863. END ExecuteAdmaCommand;
  864. (** Read response R1 or R1b from command record *)
  865. PROCEDURE GetR1 * (CONST command: Command): SET;
  866. VAR
  867. idx: LONGINT;
  868. BEGIN
  869. idx := 0;
  870. (*IF (FlagAutoCmd12 IN command.flags) OR (FlagAutoCmd23 IN command.flags) THEN
  871. idx := 3
  872. END;*)
  873. RETURN SYSTEM.VAL(SET, command.response[idx])
  874. END GetR1;
  875. (** Read response R2 from command record *)
  876. PROCEDURE GetR2 * (CONST command: Command; VAR response: ARRAY OF LONGINT);
  877. VAR
  878. i: LONGINT;
  879. BEGIN
  880. FOR i := 0 TO 3 DO
  881. response[i] := command.response[i]
  882. END
  883. END GetR2;
  884. (** Read response R3 from command record *)
  885. PROCEDURE GetR3 * (CONST command: Command): LONGINT;
  886. BEGIN
  887. RETURN command.response[0]
  888. END GetR3;
  889. (** Read response R4 from command record *)
  890. PROCEDURE GetR4 * (CONST command: Command): LONGINT;
  891. BEGIN
  892. RETURN command.response[0]
  893. END GetR4;
  894. (** Read response R5 from command record *)
  895. PROCEDURE GetR5 * (CONST command: Command): LONGINT;
  896. BEGIN
  897. RETURN command.response[0]
  898. END GetR5;
  899. (** Read response R6 from command record *)
  900. PROCEDURE GetR6 * (CONST command: Command): LONGINT;
  901. BEGIN
  902. RETURN command.response[0]
  903. END GetR6;
  904. (** Read response R7 from command record *)
  905. PROCEDURE GetR7 * (CONST command: Command): LONGINT;
  906. BEGIN
  907. RETURN command.response[0]
  908. END GetR7;
  909. PROCEDURE SetEventHandler * (hc: HostController; handler: EventHandler; param: ANY);
  910. BEGIN
  911. hc.handle := handler;
  912. hc.handlerParam := param
  913. END SetEventHandler;
  914. (* ==================== Card (High-Level) Interface ==================== *)
  915. (** Write 'data[ofs, ofs + len)' to 'card', starting at block 'firstBlock'. *)
  916. PROCEDURE Write * (card: Card; firstBlock, len: LONGINT; VAR data: ARRAY OF CHAR; ofs: LONGINT; VAR result: LONGINT): BOOLEAN;
  917. VAR
  918. command: Command;
  919. ret: BOOLEAN;
  920. r1: SET;
  921. BEGIN
  922. IF Synchronize THEN card.acquire END;
  923. IF ~SelectCard(card, result) THEN
  924. IF Synchronize THEN card.release END;
  925. RETURN FALSE
  926. END;
  927. command.hc := card.hc;
  928. command.argument := firstBlock;
  929. command.responseType := ResponseR1;
  930. command.flags := {FlagData};
  931. command.rca := card.rca;
  932. IF len > BlockSize THEN
  933. INCL(command.flags, FlagMultipleBlockTx);
  934. INCL(command.flags, FlagCountBlocks);
  935. INCL(command.flags, FlagAutoCmd12);
  936. command.command := CMD_WRITE_MULTIPLE_BLOCK
  937. ELSE
  938. command.command := CMD_WRITE_BLOCK
  939. END;
  940. ret := command.hc.execute(command, data, ofs, len, result);
  941. IF Synchronize THEN card.release END;
  942. RETURN ret
  943. (*IF command.hc.execute(command, data, ofs, len, result) & ~(CardStatus_Error IN GetR1(command)) THEN
  944. command.flags := {};
  945. command.argument := 0;
  946. command.command := CMD_SEND_STATUS;
  947. command.responseType := ResponseR1;
  948. REPEAT
  949. IF ~ExecuteCommand(command, result) THEN RETURN FALSE END;
  950. r1 := GetR1(command);
  951. IF CardStatus_Error IN r1 THEN RETURN FALSE END
  952. UNTIL CardStatus_ReadyForData IN r1;
  953. RETURN TRUE
  954. ELSE
  955. RETURN FALSE
  956. END*)
  957. END Write;
  958. (** Read 'len' bytes starting from 'firstBlock' of 'card' to 'data[ofs, ofs + len)' *)
  959. PROCEDURE Read * (card: Card; firstBlock, len: LONGINT; VAR data: ARRAY OF CHAR; ofs: LONGINT; VAR result: LONGINT): BOOLEAN;
  960. VAR
  961. command: Command;
  962. ret: BOOLEAN;
  963. BEGIN
  964. IF Synchronize THEN card.acquire END;
  965. IF ~SelectCard(card, result) THEN
  966. IF Synchronize THEN card.release END;
  967. RETURN FALSE
  968. END;
  969. command.hc := card.hc;
  970. command.argument := firstBlock;
  971. command.responseType := ResponseR1;
  972. command.flags := {FlagData, FlagRead};
  973. command.rca := card.rca;
  974. IF len > BlockSize THEN
  975. INCL(command.flags, FlagMultipleBlockTx);
  976. INCL(command.flags, FlagCountBlocks);
  977. INCL(command.flags, FlagAutoCmd12);
  978. command.command := CMD_READ_MULTIPLE_BLOCK
  979. ELSE
  980. command.command := CMD_READ_SINGLE_BLOCK
  981. END;
  982. ret := command.hc.execute(command, data, ofs, len, result) & ~(CardStatus_Error IN GetR1(command));
  983. IF Synchronize THEN card.release END;
  984. RETURN ret
  985. END Read;
  986. PROCEDURE Erase * (card: Card; block, num: LONGINT; VAR result: LONGINT): BOOLEAN;
  987. VAR
  988. command: Command;
  989. r1: SET;
  990. BEGIN
  991. command.hc := card.hc;
  992. command.flags := {};
  993. command.rca := card.rca;
  994. command.responseType := ResponseR1;
  995. command.argument := block;
  996. command.command := CMD_ERASE_WR_BLK_START;
  997. IF ~ExecuteCommand(command, result) & (CardStatus_Error IN GetR1(command)) THEN RETURN FALSE END;
  998. command.argument := block + num - 1;
  999. command.command := CMD_ERASE_WR_BLK_END;
  1000. IF ~ExecuteCommand(command, result) & (CardStatus_Error IN GetR1(command)) THEN RETURN FALSE END;
  1001. command.argument := 0;
  1002. command.command := CMD_ERASE;
  1003. command.responseType := ResponseR1b;
  1004. IF ~ExecuteCommand(command, result) & (CardStatus_Error IN GetR1(command)) THEN RETURN FALSE END;
  1005. (*WHILE 20 IN card.hc.regs.PresentState DO END;*)
  1006. command.command := CMD_SEND_STATUS;
  1007. command.responseType := ResponseR1;
  1008. REPEAT
  1009. IF ~ExecuteCommand(command, result) THEN RETURN FALSE END;
  1010. r1 := GetR1(command);
  1011. IF CardStatus_Error IN r1 THEN RETURN FALSE END
  1012. UNTIL CardStatus_ReadyForData IN r1;
  1013. RETURN TRUE
  1014. END Erase;
  1015. PROCEDURE Reset (hc: HostController; cmd, dat: BOOLEAN): BOOLEAN;
  1016. VAR
  1017. val: SHORTINT;
  1018. BEGIN
  1019. IF cmd & dat THEN
  1020. val := SoftwareResetAll
  1021. ELSIF cmd THEN
  1022. val := SoftwareResetCmd
  1023. ELSIF dat THEN
  1024. val := SoftwareResetDat
  1025. ELSE
  1026. RETURN FALSE
  1027. END;
  1028. hc.regs.SoftwareReset := val;
  1029. REPEAT
  1030. UNTIL hc.regs.SoftwareReset # val;
  1031. RETURN TRUE
  1032. END Reset;
  1033. PROCEDURE SetBusClock (hc: HostController; freq: LONGINT);
  1034. VAR
  1035. divisor, d, val: LONGINT;
  1036. BEGIN
  1037. hc.regs.ClockControl := 0;
  1038. divisor := hc.baseFrequency DIV freq;
  1039. IF divisor = 0 THEN
  1040. (* requested freq is higher that base freq *)
  1041. divisor := 1
  1042. END;
  1043. IF hc.baseFrequency DIV divisor > freq THEN INC(divisor) END;
  1044. val := 0;
  1045. ASSERT(divisor > 0);
  1046. d := divisor;
  1047. WHILE d # 1 DO
  1048. d := d DIV 2;
  1049. INC(val)
  1050. END;
  1051. IF val >= 8 THEN val := 7 END;
  1052. ASSERT(val < 8);
  1053. (*val := divisor * 2;*)
  1054. hc.regs.ClockControl := INTEGER(LSH(LSH(LONGINT(1), val), 8) + SYSTEM.VAL(INTEGER, {ClockControl_InternalClockEnable}));
  1055. hc.frequency := hc.baseFrequency DIV (LSH(LONGINT(1), val));
  1056. REPEAT val := hc.regs.ClockControl UNTIL ClockControl_InternalClockState IN SYSTEM.VAL(SET, val);
  1057. val := hc.regs.ClockControl;
  1058. hc.regs.ClockControl := SYSTEM.VAL(INTEGER, SYSTEM.VAL(SET, val) + {ClockControl_SdClockEnable});
  1059. IF Trace THEN
  1060. SdEnvironment.String("[SD] Selecting Bus Clock Frequency: ");
  1061. SdEnvironment.Int(hc.frequency, 0);
  1062. SdEnvironment.Ln
  1063. END;
  1064. (*SetTimeout(hc, 10); (* 100ms *)*)
  1065. END SetBusClock;
  1066. PROCEDURE SetTimeout (hc: HostController; timeoutFreq: LONGINT);
  1067. VAR
  1068. ratio, val: LONGINT;
  1069. BEGIN
  1070. ratio := hc.frequency DIV timeoutFreq DIV 8192;
  1071. val := 0;
  1072. REPEAT
  1073. INC(val);
  1074. ratio := ratio DIV 2
  1075. UNTIL ratio = 0;
  1076. hc.regs.TimeoutControl := SYSTEM.VAL(SHORTINT, val);
  1077. END SetTimeout;
  1078. PROCEDURE SetBusWidth (hc: HostController; rca, width: LONGINT; VAR result: LONGINT): BOOLEAN;
  1079. VAR
  1080. command: Command;
  1081. val: LONGINT;
  1082. BEGIN
  1083. (* 1 *)
  1084. (*EXCL(hc.regs.InterruptStatusEnable, Interrupt_Normal_CardInterrupt);*)
  1085. (* 2: driver supports SD cards only *)
  1086. (* 3: not implemented *)
  1087. (* 4 *)
  1088. command.command := ACMD_SET_BUS_WIDTH;
  1089. CASE width OF
  1090. 1: command.argument := 0
  1091. |4: command.argument := 2
  1092. END;
  1093. command.hc := hc;
  1094. command.rca := rca;
  1095. command.flags := {FlagApplicationCmd};
  1096. command.responseType := ResponseR1;
  1097. IF ~ExecuteCommand(command, result) THEN RETURN FALSE END;
  1098. (* 5 *)
  1099. val := hc.regs.HostControl1;
  1100. CASE width OF
  1101. 1: EXCL(SYSTEM.VAL(SET, val), HostControl1_DataWidthTransfer)
  1102. |4: INCL(SYSTEM.VAL(SET, val), HostControl1_DataWidthTransfer)
  1103. END;
  1104. hc.regs.HostControl1 := SHORTINT(val);
  1105. (* 6: SD card only *)
  1106. (* 8 *)
  1107. (*INCL(hc.regs.InterruptStatusEnable, Interrupt_Normal_CardInterrupt);*)
  1108. RETURN TRUE
  1109. END SetBusWidth;
  1110. PROCEDURE HandleInterrupt * (hc: HostController);
  1111. VAR
  1112. card: Card;
  1113. result: LONGINT;
  1114. BEGIN
  1115. IF Trace THEN SdEnvironment.String("[SD] Interrupt: "); SdEnvironment.Set(hc.regs.InterruptStatus); SdEnvironment.Ln END;
  1116. IF Interrupt_Normal_CardInsertion IN hc.regs.InterruptStatus THEN
  1117. IF Trace THEN SdEnvironment.String("[SD] Card Insertion"); SdEnvironment.Ln END;
  1118. NEW(card);
  1119. IF InitCard(hc, card, result) & (hc.handle # NIL) THEN
  1120. hc.handle(card, OnInitialization, hc.handlerParam)
  1121. ELSIF Trace THEN
  1122. SdEnvironment.String("[SD] Could not initialize card");
  1123. SdEnvironment.Ln
  1124. END
  1125. ELSIF Interrupt_Normal_CardRemoval IN hc.regs.InterruptStatus THEN
  1126. IF Trace THEN SdEnvironment.String("[SD] Card Removal"); SdEnvironment.Ln END;
  1127. card := hc.cards;
  1128. IF hc.handle #NIL THEN hc.handle(card, OnRemoval, hc.handlerParam) END;
  1129. hc.cards := hc.cards.next
  1130. END;
  1131. hc.regs.InterruptStatus := hc.regs.InterruptStatus
  1132. END HandleInterrupt;
  1133. PROCEDURE InitCard * (hc: HostController; card: Card; VAR result: LONGINT): BOOLEAN;
  1134. VAR
  1135. csd: ARRAY 4 OF LONGINT;
  1136. response: LONGINT;
  1137. status: SET;
  1138. f8, sdio: BOOLEAN;
  1139. command: Command;
  1140. i: LONGINT;
  1141. BEGIN
  1142. SetBusClock(hc, 400000);
  1143. FOR response := 0 TO 10000000 DO END;
  1144. command.hc := hc;
  1145. (* 1 *)
  1146. command.command := CMD_GO_IDLE_STATE;
  1147. command.argument := 0;
  1148. command.responseType := ResponseNone;
  1149. command.flags := {};
  1150. IF ~ExecuteCommand(command, result) THEN RETURN FALSE END;
  1151. (* 2 *)
  1152. command.command := CMD_SEND_IF_COND;
  1153. command.argument := 1AAH;
  1154. command.responseType := ResponseR7;
  1155. command.flags := {};
  1156. IF ~ExecuteCommand(command, result) THEN RETURN FALSE END;
  1157. (* 3 *)
  1158. response := GetR7(command);
  1159. IF response # 1AAH THEN
  1160. result := ErrorCard;
  1161. RETURN FALSE
  1162. END;
  1163. f8 := TRUE;
  1164. (* 5 *)
  1165. command.command := CMD_IO_SEND_OP_COND;
  1166. command.argument := 0;
  1167. command.responseType := ResponseR4;
  1168. command.flags := {};
  1169. IF ~ExecuteCommand(command, result) & (result = ErrorCmdTimeout) THEN
  1170. sdio := FALSE;
  1171. result := ErrorNone;
  1172. ELSIF result # ErrorNone THEN
  1173. RETURN FALSE
  1174. ELSE
  1175. sdio := TRUE;
  1176. END;
  1177. IF Trace THEN SdEnvironment.String("[SD] Card is SDIO: "); SdEnvironment.Boolean(sdio); SdEnvironment.Ln END;
  1178. (* 6 *)
  1179. IF sdio THEN
  1180. (*! NOT IMPLEMENTED YET *)
  1181. HALT(100);
  1182. (* 7 *)
  1183. (*IF ~StartCommand(hc, CMD_IO_SEND_OP_COND, 800H, ResponseR4, FALSE, FALSE, res) THEN
  1184. RETURN FALSE
  1185. END;
  1186. RETURN TRUE*)
  1187. END;
  1188. (* A *)
  1189. (* 12 & 19 *)
  1190. command.command := ACMD_SD_SEND_OP_COND;
  1191. command.argument := 0;
  1192. command.responseType := ResponseR3;
  1193. command.flags := {FlagApplicationCmd, FlagIgnoreIllegalCmd};
  1194. (*IF ~StartCommand(hc, CMD_APP_CMD, 0, ResponseR1, FALSE, FALSE, res) THEN
  1195. RETURN FALSE
  1196. END;
  1197. IF CardStatus_Error IN Response1(hc) THEN RETURN FALSE END;*)
  1198. IF ~ExecuteCommand(command, result) THEN RETURN FALSE END;
  1199. response := GetR3(command);
  1200. IF Trace THEN
  1201. SdEnvironment.String("[SD] VDD: Ranges Supported by Card:"); SdEnvironment.Ln;
  1202. IF CardOcr_Vdd27_28 IN SYSTEM.VAL(SET, response) THEN SdEnvironment.String("[SD] 2.7 - 2.8 V"); SdEnvironment.Ln END;
  1203. IF CardOcr_Vdd28_29 IN SYSTEM.VAL(SET, response) THEN SdEnvironment.String("[SD] 2.8 - 2.9 V"); SdEnvironment.Ln END;
  1204. IF CardOcr_Vdd29_30 IN SYSTEM.VAL(SET, response) THEN SdEnvironment.String("[SD] 2.9 - 3.0 V"); SdEnvironment.Ln END;
  1205. IF CardOcr_Vdd30_31 IN SYSTEM.VAL(SET, response) THEN SdEnvironment.String("[SD] 3.0 - 3.1 V"); SdEnvironment.Ln END;
  1206. IF CardOcr_Vdd31_32 IN SYSTEM.VAL(SET, response) THEN SdEnvironment.String("[SD] 3.1 - 3.2 V"); SdEnvironment.Ln END;
  1207. IF CardOcr_Vdd32_33 IN SYSTEM.VAL(SET, response) THEN SdEnvironment.String("[SD] 3.2 - 3.3 V"); SdEnvironment.Ln END;
  1208. IF CardOcr_Vdd33_34 IN SYSTEM.VAL(SET, response) THEN SdEnvironment.String("[SD] 3.3 - 3.4 V"); SdEnvironment.Ln END;
  1209. IF CardOcr_Vdd34_35 IN SYSTEM.VAL(SET, response) THEN SdEnvironment.String("[SD] 3.4 - 3.5 V"); SdEnvironment.Ln END;
  1210. IF CardOcr_Vdd35_36 IN SYSTEM.VAL(SET, response) THEN SdEnvironment.String("[SD] 3.5 - 3.6 V"); SdEnvironment.Ln END
  1211. END;
  1212. status := {30};
  1213. IF Capabilities_Voltage30 IN hc.regs.Capabilities[0] THEN
  1214. IF Trace THEN SdEnvironment.String("[SD] Selecting 3.0 V"); SdEnvironment.Ln END;
  1215. INCL(status, CardOcr_Vdd30_31)
  1216. ELSIF Capabilities_Voltage33 IN hc.regs.Capabilities[0] THEN
  1217. IF Trace THEN SdEnvironment.String("[SD] Selecting 3.3 V"); SdEnvironment.Ln END;
  1218. INCL(status, CardOcr_Vdd32_33)
  1219. END;
  1220. command.command := ACMD_SD_SEND_OP_COND;
  1221. command.argument := SYSTEM.VAL(LONGINT, status);
  1222. command.responseType := ResponseR3;
  1223. command.flags := {FlagApplicationCmd, FlagIgnoreIllegalCmd};
  1224. REPEAT
  1225. IF ~ExecuteCommand(command, result) THEN RETURN FALSE END;
  1226. status := SYSTEM.VAL(SET, GetR3(command));
  1227. UNTIL (CardOcr_PowerUpStatus IN status);
  1228. IF Trace & (CardOcr_S18A IN status) THEN
  1229. SdEnvironment.String("[SD] Card supports 1.8V");
  1230. SdEnvironment.Ln
  1231. END;
  1232. IF f8 & (CardOcr_CardCapacityStatus IN status) THEN
  1233. IF Trace THEN SdEnvironment.String("[SD] Card: SDHC or SDXC") END;
  1234. card.scr.security := TypeSDHC
  1235. ELSIF f8 THEN
  1236. IF Trace THEN SdEnvironment.String("[SD] Card: SDSC v2 or v3") END;
  1237. card.scr.security := TypeSDSC
  1238. ELSE
  1239. IF Trace THEN SdEnvironment.String("[SD] Card: SDSC v1.0 or v1.1") END;
  1240. card.scr.security := TypeSDSC
  1241. END;
  1242. IF Trace THEN SdEnvironment.Ln END;
  1243. (* 32 *)
  1244. command.command := CMD_ALL_SEND_CID;
  1245. command.argument := 0;
  1246. command.responseType := ResponseR2;
  1247. command.flags := {};
  1248. IF ~ExecuteCommand(command, result) THEN RETURN FALSE END;
  1249. GetR2(command, card.cid);
  1250. (* 33 *)
  1251. command.command := CMD_SEND_RELATIVE_ADDR;
  1252. command.argument := 0;
  1253. command.responseType := ResponseR6;
  1254. command.flags := {};
  1255. REPEAT
  1256. IF ~ExecuteCommand(command, result) THEN RETURN FALSE END;
  1257. card.rca := LSH(GetR6(command), -16)
  1258. UNTIL card.rca # 0;
  1259. IF Trace THEN SdEnvironment.String("[SD] New Card with RCA: "); SdEnvironment.Hex(card.rca, -4); SdEnvironment.Ln END;
  1260. status := SYSTEM.VAL(SET, GetR6(command));
  1261. status := status * {0 .. 15};
  1262. (* status is a modified CardStatus: reform corresponding card status *)
  1263. IF 15 IN status THEN EXCL(status, 15); INCL(status, 23) END;
  1264. IF 14 IN status THEN EXCL(status, 14); INCL(status, 22) END;
  1265. IF 13 IN status THEN EXCL(status, 13); INCL(status, 19) END;
  1266. IF Trace THEN PrintCardStatus(status) END;
  1267. card.hc := hc;
  1268. card.next := hc.cards;
  1269. hc.cards := card;
  1270. IF Synchronize THEN SdEnvironment.GetLock(card.acquire, card.release) END;
  1271. (* Get Additional card registers: CSD *)
  1272. command.command := CMD_SEND_CSD;
  1273. command.argument := LSH(card.rca, 16);
  1274. command.responseType := ResponseR2;
  1275. command.flags := {};
  1276. IF ~ExecuteCommand(command, result) THEN RETURN FALSE END;
  1277. GetR2(command, csd);
  1278. GetCsd(csd, card.csd);
  1279. IF Trace THEN
  1280. SdEnvironment.String("[SD] Card Capacity: "); SdEnvironment.Int(card.csd.capacity, 0); SdEnvironment.String(" B"); SdEnvironment.Ln;
  1281. SdEnvironment.String("[SD] Bus frequency: "); SdEnvironment.Int(card.csd.txSpeed, 0); SdEnvironment.String(" Hz"); SdEnvironment.Ln
  1282. END;
  1283. SetBusClock(hc, card.csd.txSpeed);
  1284. IF ~ReadScr(card, result) THEN RETURN FALSE END;
  1285. IF CardScr_SdBusWidths_4 IN card.scr.busWidth THEN
  1286. IF Trace THEN
  1287. SdEnvironment.String("[SD] Changing bus width to 4 bits");
  1288. SdEnvironment.Ln
  1289. END;
  1290. IF ~SetBusWidth(card.hc, card.rca, 4, result) THEN RETURN FALSE END;
  1291. IF Trace THEN
  1292. SdEnvironment.String("[SD] Bus width changed");
  1293. SdEnvironment.Ln
  1294. END
  1295. END;
  1296. IF (card.scr.version >= Version1p1) & SelectSpeedMode(card, TRUE, result) THEN
  1297. (*! Assume card supports 50 MHz clock rate *)
  1298. SetBusClock(hc, 50000000)
  1299. END;
  1300. (*FOR i := 0 TO 10000000H DO END;*)
  1301. (*IF ~Reset(card.hc, TRUE, FALSE) THEN RETURN FALSE END;*)
  1302. (*TRACE('RESET done');*)
  1303. (*FOR i := 0 TO 10000000H DO END;*)
  1304. (* Get Additional card registers: CSD *)
  1305. (*command.command := CMD_SEND_CSD;
  1306. command.argument := LSH(card.rca, 16);
  1307. command.responseType := ResponseR2;
  1308. command.flags := {};
  1309. IF ~ExecuteCommand(command, result) THEN RETURN FALSE END;
  1310. TRACE('command succeeded');
  1311. GetR2(command, csd);
  1312. GetCsd(csd, card.csd);
  1313. IF Trace THEN
  1314. SdEnvironment.String("[SD] Card Capacity: "); SdEnvironment.Int(card.csd.capacity, 0); SdEnvironment.String(" B"); SdEnvironment.Ln;
  1315. SdEnvironment.String("[SD] Bus frequency: "); SdEnvironment.Int(card.csd.txSpeed, 0); SdEnvironment.String(" Hz"); SdEnvironment.Ln
  1316. END;
  1317. TRACE(card.csd.txSpeed);
  1318. SetBusClock(hc, card.csd.txSpeed);*)
  1319. RETURN TRUE
  1320. END InitCard;
  1321. PROCEDURE ReadScr (card: Card; VAR result: LONGINT): BOOLEAN;
  1322. VAR
  1323. command: Command;
  1324. scr: ARRAY 8 OF CHAR;
  1325. BEGIN
  1326. IF ~SelectCard(card, result) THEN RETURN FALSE END;
  1327. (* Get Card Register: SCR *)
  1328. command.hc := card.hc;
  1329. command.command := ACMD_SEND_SCR;
  1330. command.argument := 0;
  1331. command.responseType := ResponseR1;
  1332. command.flags := {FlagApplicationCmd, FlagData, FlagRead};
  1333. command.rca := card.rca;
  1334. IF ~card.hc.execute(command, scr, 0, 8, result) THEN RETURN FALSE END;
  1335. IF CardStatus_Error IN GetR1(command) THEN result := ErrorCard; RETURN FALSE END;
  1336. GetScr(scr, card.scr);
  1337. RETURN TRUE
  1338. END ReadScr;
  1339. PROCEDURE SwitchFunc (card: Card; switch: BOOLEAN; funcs: ARRAY 6 OF LONGINT; VAR sts: SwitchFuncStatus; VAR res: LONGINT): BOOLEAN;
  1340. VAR
  1341. status: ARRAY 64 OF CHAR;
  1342. command: Command;
  1343. PROCEDURE GetStatus (CONST status: ARRAY OF CHAR; VAR sts: SwitchFuncStatus);
  1344. VAR
  1345. i: LONGINT;
  1346. BEGIN
  1347. sts.current := LONGINT(ORD(status[0])) * 100H + LONGINT(ORD(status[1]));
  1348. FOR i := 0 TO 5 DO
  1349. sts.functionGroups[i] := SYSTEM.VAL(SET, LONGINT(ORD(status[2 + 2 * (5 - i)])) * 100H + LONGINT(ORD(status[1 + 2 + 2 * (5 - i)])))
  1350. END;
  1351. FOR i := 0 TO 5 BY 2 DO
  1352. sts.functionStatus[i] := ORD(status[14 + 2 - i DIV 2]) MOD 10H;
  1353. sts.functionStatus[i + 1] := ORD(status[14 + 2 - i DIV 2]) DIV 10H
  1354. END;
  1355. END GetStatus;
  1356. BEGIN
  1357. IF ~SelectCard(card, res) THEN RETURN FALSE END;
  1358. command.hc := card.hc;
  1359. command.command := CMD_SWITCH_FUNC;
  1360. command.responseType := ResponseR1;
  1361. command.argument := (funcs[0] MOD 10H) + 10H * (funcs[1] MOD 10H) + 100H * (funcs[2] MOD 10H) + 1000H * (funcs[3] MOD 10H) + 10000H * (funcs[4] MOD 10H) + 100000H * (funcs[5] MOD 10H);
  1362. IF switch THEN INCL(SYSTEM.VAL(SET, command.argument), 31) END;
  1363. command.flags := {FlagRead, FlagData};
  1364. IF ~card.hc.execute(command, status, 0, 64, res) THEN RETURN FALSE END;
  1365. GetStatus(status, sts);
  1366. RETURN TRUE
  1367. END SwitchFunc;
  1368. PROCEDURE PrintSwitchFuncStatus(CONST status: SwitchFuncStatus);
  1369. VAR
  1370. i: LONGINT;
  1371. BEGIN
  1372. IF Trace THEN
  1373. SdEnvironment.String("Switch Func Status");
  1374. SdEnvironment.Ln;
  1375. SdEnvironment.String("Current = ");
  1376. IF status.current = 0 THEN
  1377. SdEnvironment.String("ERROR")
  1378. ELSE
  1379. SdEnvironment.Int(status.current, 0);
  1380. SdEnvironment.String(" mA");
  1381. SdEnvironment.Ln
  1382. END;
  1383. FOR i := 0 TO 5 DO
  1384. SdEnvironment.String("Function Group #");
  1385. SdEnvironment.Int(i, 0);
  1386. SdEnvironment.String(": functions = ");
  1387. SdEnvironment.Set(status.functionGroups[i]);
  1388. SdEnvironment.String(", status = ");
  1389. CASE status.functionStatus[i] OF
  1390. 0: SdEnvironment.String("switchable")
  1391. |1: SdEnvironment.String("switched")
  1392. |0FH: SdEnvironment.String("ERROR")
  1393. END;
  1394. SdEnvironment.Ln
  1395. END
  1396. END
  1397. END PrintSwitchFuncStatus;
  1398. PROCEDURE SelectSpeedMode(card: Card; high: BOOLEAN; VAR res: LONGINT): BOOLEAN;
  1399. VAR
  1400. funcs: ARRAY 6 OF LONGINT;
  1401. status: SwitchFuncStatus;
  1402. BEGIN
  1403. funcs[0] := 1;
  1404. IF ~SwitchFunc(card, FALSE, funcs, status, res) THEN RETURN FALSE END;
  1405. PrintSwitchFuncStatus(status);
  1406. IF ~(1 IN status.functionGroups[0]) THEN
  1407. SdEnvironment.String("[SD] HIGH-SPEED MODE NOT SUPPORTED");
  1408. SdEnvironment.Ln;
  1409. RETURN TRUE
  1410. END;
  1411. IF ~SwitchFunc(card, TRUE, funcs, status, res) THEN RETURN FALSE END;
  1412. PrintSwitchFuncStatus(status);
  1413. RETURN TRUE
  1414. END SelectSpeedMode;
  1415. (** Sends CMD7 if necessary to select the given card *)
  1416. PROCEDURE SelectCard (card: Card; VAR result: LONGINT): BOOLEAN;
  1417. VAR
  1418. command: Command;
  1419. status: SET;
  1420. BEGIN
  1421. IF card.hc.lastRca = card.rca THEN
  1422. IF Trace THEN
  1423. SdEnvironment.String("[SD] Card Already Selected");
  1424. SdEnvironment.Ln
  1425. END;
  1426. RETURN TRUE
  1427. END;
  1428. IF Trace THEN SdEnvironment.String("[SD] Selecting Card "); SdEnvironment.Int(card.rca, 0); SdEnvironment.Ln END;
  1429. command.hc := card.hc;
  1430. command.command := CMD_SELECT_DESELECT_CARD;
  1431. command.argument := LSH(card.rca, 16);
  1432. command.responseType := ResponseR1b;
  1433. IF ~ExecuteCommand(command, result) THEN RETURN FALSE END;
  1434. status := GetR1(command);
  1435. IF CardStatus_Error IN status THEN result := ErrorCard; RETURN FALSE END;
  1436. RETURN TRUE
  1437. END SelectCard;
  1438. (** Get the response registers in 'response' *)
  1439. PROCEDURE GetResponse (hc: HostController; responseType: LONGINT; VAR response: ARRAY 4 OF LONGINT);
  1440. BEGIN
  1441. response := hc.regs.Response
  1442. END GetResponse;
  1443. (** Issue an SD Card Transaction. [Simplified specs. 3.7.1.1 pp. 106-108] *)
  1444. PROCEDURE StartCommand (hc: HostController; cmd, argument, responseType: LONGINT; read, dma, busy, abort: BOOLEAN; VAR status: SET; VAR result: LONGINT): BOOLEAN;
  1445. VAR
  1446. reg: LONGINT;
  1447. flags, txFlags: SET;
  1448. BEGIN
  1449. IF TraceCmd THEN
  1450. SdEnvironment.String("[SD] Sending Command CMD"); SdEnvironment.Int(cmd, 0); SdEnvironment.Ln;
  1451. SdEnvironment.String("[SD] Argument: "); SdEnvironment.Hex(argument, -8); SdEnvironment.Ln
  1452. END;
  1453. (* 1 *)
  1454. WHILE PresentState_CommandInhibitCmd IN hc.regs.PresentState DO END;
  1455. (* 2 *)
  1456. IF busy THEN
  1457. (* 3 *)
  1458. IF ~abort THEN
  1459. (* 4 *)
  1460. WHILE PresentState_CommandInhibitDat IN hc.regs.PresentState DO END
  1461. END
  1462. END;
  1463. (* 5 *)
  1464. hc.regs.Argument1 := argument;
  1465. (* 6 *)
  1466. (* The response type determines the response-type and CRC/Index checks enabling *)
  1467. CASE responseType OF
  1468. ResponseNone:
  1469. reg := Command_ResponseType_None;
  1470. IF TraceCmd THEN
  1471. SdEnvironment.String("[SD] No Response Expected");
  1472. SdEnvironment.Ln
  1473. END
  1474. |ResponseR1, ResponseR5, ResponseR6, ResponseR7:
  1475. reg := Command_ResponseType_48b;
  1476. flags := {Command_CrcCheckEnable, Command_IndexCheckEnable};
  1477. IF TraceCmd THEN
  1478. SdEnvironment.String("[SD] 48 Bit Response"); SdEnvironment.Ln;
  1479. SdEnvironment.String("[SD] Enabling CRC Check and Index Check"); SdEnvironment.Ln
  1480. END
  1481. |ResponseR3, ResponseR4:
  1482. reg := Command_ResponseType_48b;
  1483. IF TraceCmd THEN SdEnvironment.String("[SD] 48 Bit Response"); SdEnvironment.Ln END
  1484. |ResponseR1b, ResponseR5b:
  1485. reg := Command_ResponseType_48bBusy;
  1486. flags := {Command_CrcCheckEnable, Command_IndexCheckEnable};
  1487. IF TraceCmd THEN
  1488. SdEnvironment.String("[SD] 48 Bit Response"); SdEnvironment.Ln;
  1489. SdEnvironment.String("[SD] Enabling Index Check"); SdEnvironment.Ln
  1490. END
  1491. |ResponseR2:
  1492. reg := Command_ResponseType_136b;
  1493. flags := {Command_CrcCheckEnable};
  1494. IF TraceCmd THEN
  1495. SdEnvironment.String("[SD] 136 Bit Response"); SdEnvironment.Ln;
  1496. SdEnvironment.String("[SD] Enabling Command CRC Check"); SdEnvironment.Ln
  1497. END
  1498. END;
  1499. (* Command determines data-enable *)
  1500. IF busy THEN
  1501. INCL(flags, Command_DataPresent);
  1502. IF TraceCmd THEN SdEnvironment.String("[SD] Using DAT Line"); SdEnvironment.Ln END;
  1503. txFlags := {};
  1504. IF (*(cmd = CMD_READ_SINGLE_BLOCK) OR (cmd = CMD_READ_MULTIPLE_BLOCK) OR (cmd = ACMD_SEND_SCR)*) read THEN
  1505. IF TraceCmd THEN SdEnvironment.String("[SD] Data Read"); SdEnvironment.Ln END;
  1506. INCL(txFlags, TransferMode_DataTxDirection)
  1507. ELSIF TraceCmd THEN
  1508. SdEnvironment.String("[SD] Data Write");
  1509. SdEnvironment.Ln
  1510. END;
  1511. IF (cmd = CMD_READ_MULTIPLE_BLOCK) OR (cmd = CMD_WRITE_MULTIPLE_BLOCK) THEN
  1512. IF TraceCmd THEN SdEnvironment.String("[SD] Multiple blocks: using Auto CMD12 & activating block count"); SdEnvironment.Ln END;
  1513. txFlags := txFlags + TransferMode_AutoCmd_Cmd12 + {TransferMode_MultipleBlocks, TransferMode_BlockCountEnable}
  1514. ELSIF TraceCmd THEN
  1515. SdEnvironment.String("[SD] Single Block");
  1516. SdEnvironment.Ln
  1517. END;
  1518. IF dma THEN INCL(txFlags, TransferMode_DmaEnable) END;
  1519. hc.regs.TransferMode := SYSTEM.VAL(INTEGER, txFlags)
  1520. END;
  1521. hc.regs.Command := SYSTEM.VAL(INTEGER, SYSTEM.VAL(SET, reg + LSH(cmd, Command_CommandIndexOffset)) + flags);
  1522. (* 7 *)
  1523. RETURN WaitForCompletion(hc, ~abort, status, result)
  1524. (* Steps 7, 8 and 9 of WaitForCompletion have to be done by caller *)
  1525. END StartCommand;
  1526. PROCEDURE ErrorRecovery (hc: HostController; VAR result: LONGINT; VAR status: SET): BOOLEAN;
  1527. BEGIN
  1528. (* 1 is done *)
  1529. status := hc.regs.InterruptStatus;
  1530. hc.regs.InterruptStatusEnable := {0 .. 14};
  1531. EXCL(hc.regs.InterruptStatusEnable, Interrupt_Normal_ErrorInterrupt);
  1532. EXCL(hc.regs.InterruptStatusEnable, Interrupt_Normal_ErrorInterrupt);
  1533. EXCL(hc.regs.InterruptStatusEnable, Interrupt_Normal_ErrorInterrupt);
  1534. (* 2 *)
  1535. IF (Interrupt_Error_CommandTimeout IN status) OR (Interrupt_Error_CommandCrc IN status) OR (Interrupt_Error_CommandEndBit IN status)
  1536. OR (Interrupt_Error_CommandIndex IN status) THEN
  1537. (* 3 & 4 *)
  1538. IF ~Reset(hc, TRUE, FALSE) THEN
  1539. result := ErrorUnrecoverable;
  1540. RETURN FALSE
  1541. END
  1542. END;
  1543. (* 5 *)
  1544. IF (Interrupt_Error_DataTimeout IN status) OR (Interrupt_Error_DataCrc IN status) OR (Interrupt_Error_DataEndBit IN status) THEN
  1545. (* 6 & 7 *)
  1546. IF ~Reset(hc, FALSE, TRUE) THEN
  1547. result := ErrorUnrecoverable;
  1548. RETURN FALSE
  1549. END
  1550. END;
  1551. (* 8 & 9 *)
  1552. hc.regs.InterruptStatus := status;
  1553. (* 10 & 11 *)
  1554. (*IF ~Command(hc, CMD_STOP_TRANSMISSION, 0, ResponseR1b, FALSE, TRUE, result) THEN
  1555. (* 12 *)
  1556. IF (Interrupt_Error_CommandTimeout IN status) OR (Interrupt_Error_CommandCrc IN status) OR (Interrupt_Error_CommandEndBit IN status)
  1557. OR (Interrupt_Error_CommandIndex IN status) THEN
  1558. TRACE('CMD12 CMD LINE ERROR');
  1559. result := ErrorUnrecoverable;
  1560. RETURN FALSE
  1561. END;
  1562. (* 13 *)
  1563. IF ~WaitForTransfer(hc, result) THEN
  1564. result := ErrorUnrecoverable;
  1565. RETURN FALSE
  1566. END;
  1567. TRACE(hc.regs.BufferData);
  1568. END;
  1569. (* 15 *)
  1570. IF hc.regs.PresentState * PresentState_DatLineSignalLevelMask # PresentState_DatLineSignalLevelMask THEN
  1571. TRACE('CMD12 DAT LINE ERROR');
  1572. result := ErrorUnrecoverable;
  1573. RETURN FALSE
  1574. END;*)
  1575. hc.regs.InterruptStatusEnable := {0 .. 31};
  1576. INCL(hc.regs.InterruptStatusEnable, Interrupt_Normal_ErrorInterrupt);
  1577. result := ErrorNone;
  1578. RETURN TRUE
  1579. END ErrorRecovery;
  1580. (** Wait for completion of an SD command [Simplified specs. 3.7.1.2 pp. 109-110 *)
  1581. PROCEDURE WaitForCompletion (hc: HostController; tryRecover: BOOLEAN; VAR status: SET; VAR result: LONGINT): BOOLEAN;
  1582. BEGIN
  1583. result := ErrorNone;
  1584. (* 1 *)
  1585. REPEAT
  1586. status := hc.regs.InterruptStatus;
  1587. UNTIL (Interrupt_Normal_CommandComplete IN status)
  1588. OR (Interrupt_Normal_ErrorInterrupt IN status);
  1589. IF Interrupt_Normal_ErrorInterrupt IN status THEN
  1590. IF ~tryRecover THEN
  1591. hc.regs.InterruptStatus := status;
  1592. result := ErrorUnrecoverable;
  1593. RETURN FALSE
  1594. END;
  1595. IF ~ErrorRecovery(hc, result, status) THEN RETURN FALSE END;
  1596. IF Interrupt_Error_CommandTimeout IN status THEN
  1597. IF TraceCmd THEN SdEnvironment.String("[SD] Timeout in command"); SdEnvironment.Ln END;
  1598. result := ErrorCmdTimeout;
  1599. RETURN FALSE
  1600. ELSIF Interrupt_Error_CommandCrc IN status THEN
  1601. result := ErrorCmdCrc;
  1602. RETURN FALSE
  1603. ELSE
  1604. result := ErrorCard;
  1605. RETURN FALSE
  1606. END
  1607. END;
  1608. (* 2 *)
  1609. IF TraceCmd THEN SdEnvironment.String("[SD] Command successful"); SdEnvironment.Ln END;
  1610. INCL(hc.regs.InterruptStatus, Interrupt_Normal_CommandComplete);
  1611. RETURN TRUE
  1612. END WaitForCompletion;
  1613. PROCEDURE WaitForTransfer (hc: HostController; VAR result: LONGINT): BOOLEAN;
  1614. VAR
  1615. status: SET;
  1616. BEGIN
  1617. (* 5 *)
  1618. REPEAT UNTIL (Interrupt_Normal_TransferComplete IN hc.regs.InterruptStatus) OR (Interrupt_Normal_ErrorInterrupt IN hc.regs.InterruptStatus);
  1619. IF Interrupt_Normal_ErrorInterrupt IN hc.regs.InterruptStatus THEN
  1620. IF ~ErrorRecovery(hc, result, status) THEN RETURN FALSE END;
  1621. result := ErrorCard;
  1622. RETURN FALSE
  1623. END;
  1624. (* 6 *)
  1625. INCL(hc.regs.InterruptStatus, Interrupt_Normal_TransferComplete)
  1626. END WaitForTransfer;
  1627. (** Fills a Csd record from the raw csd bytes *)
  1628. PROCEDURE GetCsd (CONST raw: ARRAY OF LONGINT; VAR csd: Csd);
  1629. VAR
  1630. sizeMult, val, version: LONGINT;
  1631. real: REAL;
  1632. BEGIN
  1633. version := ReadBitfield(raw, CardCsd_CsdStructureOfs, CardCsd_CsdStructureWidth) + 1;
  1634. IF version = 1 THEN
  1635. sizeMult := LSH(LONGINT(2), ReadBitfield(raw, CardCsd_CSizeMultOfs1, CardCsd_CSizeMultWidth1));
  1636. csd.capacity := sizeMult * (1 + ReadBitfield(raw, CardCsd_CSizeOfs1, CardCsd_CSizeWidth1)) * 512;
  1637. ELSE
  1638. csd.capacity := 1024 * (HUGEINT(ReadBitfield(raw, CardCsd_CSizeOfs2, CardCsd_CSizeWidth2)) + 1);
  1639. END;
  1640. csd.commandClasses := SYSTEM.VAL(SET, ReadBitfield(raw, CardCsd_CccOfs, CardCsd_CccWidth));
  1641. csd.nsac := ReadBitfield(raw, CardCsd_NsacOfs, CardCsd_NsacWidth) * 100;
  1642. val := ReadBitfield(raw, CardCsd_R2wFactorOfs, CardCsd_R2wFactorWidth);
  1643. IF val >= 6 THEN
  1644. csd.r2w := 0
  1645. ELSE
  1646. csd.r2w := LSH(LONGINT(1), val);
  1647. END;
  1648. val := ReadBitfield(raw, CardCsd_TranSpeedOfs, CardCsd_TranSpeedWidth);
  1649. CASE val DIV 8 OF
  1650. 1: csd.txSpeed := 10
  1651. |2: csd.txSpeed := 12
  1652. |3: csd.txSpeed := 13
  1653. |4: csd.txSpeed := 15
  1654. |5: csd.txSpeed := 20
  1655. |6: csd.txSpeed := 25
  1656. |7: csd.txSpeed := 30
  1657. |8: csd.txSpeed := 35
  1658. |9: csd.txSpeed := 40
  1659. |10: csd.txSpeed := 45
  1660. |11: csd.txSpeed := 50
  1661. |12: csd.txSpeed := 55
  1662. |13: csd.txSpeed := 60
  1663. |14: csd.txSpeed := 70
  1664. |15: csd.txSpeed := 80
  1665. ELSE
  1666. csd.txSpeed := 00
  1667. END;
  1668. csd.txSpeed := csd.txSpeed * 100;
  1669. CASE val MOD 8 OF
  1670. 0: csd.txSpeed := csd.txSpeed * 100
  1671. |1: csd.txSpeed := csd.txSpeed * 1000
  1672. |2: csd.txSpeed := csd.txSpeed * 10000
  1673. |3: csd.txSpeed := csd.txSpeed * 100000
  1674. END;
  1675. val := ReadBitfield(raw, CardCsd_TaacOfs, CardCsd_TaacWidth);
  1676. CASE val DIV 8 OF
  1677. 1: real := 1.0
  1678. |2: real := 1.2
  1679. |3: real := 1.3
  1680. |4: real := 1.5
  1681. |5: real := 2.0
  1682. |6: real := 2.5
  1683. |7: real := 3.0
  1684. |8: real := 3.5
  1685. |9: real := 4.0
  1686. |10: real := 4.5
  1687. |11: real := 5.0
  1688. |12: real := 5.5
  1689. |13: real := 6.0
  1690. |14: real := 7.0
  1691. |15: real := 8.0
  1692. ELSE
  1693. real := 0.0
  1694. END;
  1695. CASE val MOD 8 OF
  1696. 0: real := real * 1.0E-9
  1697. |1: real := real * 1.0E-8
  1698. |2: real := real * 1.0E-7
  1699. |3: real := real * 1.0E-6
  1700. |4: real := real * 1.0E-5
  1701. |5: real := real * 1.0E-4
  1702. |6: real := real * 1.0E-3
  1703. |7: real := real * 1.0E-2
  1704. END;
  1705. csd.taac := real
  1706. END GetCsd;
  1707. PROCEDURE GetScr (CONST raw: ARRAY OF CHAR; VAR scr: Scr);
  1708. TYPE
  1709. Array = ARRAY 8 OF CHAR;
  1710. VAR
  1711. bfield: ARRAY 2 OF LONGINT;
  1712. i: LONGINT;
  1713. BEGIN
  1714. FOR i := 0 TO 7 DO SYSTEM.VAL(Array, bfield)[7-i] := raw[i] END;
  1715. IF ReadBitfield(bfield, CardScr_StructureOfs, CardScr_StructureWidth) # 0 THEN RETURN END;
  1716. scr.version := ReadBitfield(bfield, CardScr_SdSpecVersionOfs, CardScr_SdSpecVersionWidth);
  1717. IF (scr.version = Version2) & (ReadBitfield(bfield, CardScr_SpecV3, 1) # 0) THEN
  1718. scr.version := Version3
  1719. END;
  1720. CASE ReadBitfield(bfield, CardScr_SecurityOfs, CardScr_SecurityWidth) OF
  1721. 0: scr.security := TypeNone
  1722. |2: scr.security := TypeSDSC
  1723. |3: scr.security := TypeSDHC
  1724. |4: scr.security := TypeSDXC
  1725. END;
  1726. scr.busWidth := SYSTEM.VAL(SET, ReadBitfield(bfield, CardScr_SdBusWidthsOfs, CardScr_SdBusWidthsWidth))
  1727. END GetScr;
  1728. PROCEDURE PrintCapabilities * (hc: HostController);
  1729. VAR
  1730. c0, c1: SET;
  1731. BEGIN
  1732. IF Trace THEN
  1733. c0 := hc.regs.Capabilities[0];
  1734. c1 := hc.regs.Capabilities[1];
  1735. SdEnvironment.String("[SD] "); SdEnvironment.String("Host Capabilities:"); SdEnvironment.Ln;
  1736. SdEnvironment.String("[SD] "); SdEnvironment.String(" Timeout Clock Frequency: ");
  1737. IF c0 * Capabilities_TimeoutClockFrequencyMask = {} THEN
  1738. SdEnvironment.String("Unknown")
  1739. ELSE
  1740. SdEnvironment.Int(SYSTEM.VAL(LONGINT, c0 * Capabilities_TimeoutClockFrequencyMask), 0);
  1741. IF Capabilities_TimeoutClockUnit IN c0 THEN
  1742. SdEnvironment.String(" MHz")
  1743. ELSE
  1744. SdEnvironment.String(" kHz")
  1745. END
  1746. END;
  1747. SdEnvironment.Ln;
  1748. SdEnvironment.String("[SD] "); SdEnvironment.String(" Base Clock Frequency: ");
  1749. IF c0 * Capabilities_BaseClockFreqSdMask = {} THEN
  1750. SdEnvironment.String("Unknown")
  1751. ELSE
  1752. SdEnvironment.Int(LSH(SYSTEM.VAL(LONGINT, c0 * Capabilities_BaseClockFreqSdMask), -Capabilities_BaseClockFreqSdOfs), 0)
  1753. END;
  1754. SdEnvironment.Ln;
  1755. SdEnvironment.String("[SD] "); SdEnvironment.String(" Max Block Length: ");
  1756. SdEnvironment.Int(512 * (1 + LSH(SYSTEM.VAL(LONGINT, c0 * Capabilities_MaxBlockLenMask), -Capabilities_MaxBlockLenOfs)), 0);
  1757. SdEnvironment.String(" B");
  1758. SdEnvironment.Ln;
  1759. SdEnvironment.String("[SD] "); SdEnvironment.String(" 8 Bit Support for Embedded Device: ");
  1760. SdEnvironment.Boolean(Capabilities_8BitEmbedded IN c0);
  1761. SdEnvironment.Ln;
  1762. SdEnvironment.String("[SD] "); SdEnvironment.String(" Support for ADMA2: ");
  1763. SdEnvironment.Boolean(Capabilities_ADMA2 IN c0);
  1764. SdEnvironment.Ln;
  1765. SdEnvironment.String("[SD] "); SdEnvironment.String(" Support for High Speed: ");
  1766. SdEnvironment.Boolean(Capabilities_HighSpeed IN c0);
  1767. SdEnvironment.Ln;
  1768. SdEnvironment.String("[SD] "); SdEnvironment.String(" Support for SDMA: ");
  1769. SdEnvironment.Boolean(Capabilities_SDMA IN c0);
  1770. SdEnvironment.Ln;
  1771. SdEnvironment.String("[SD] "); SdEnvironment.String(" Support for Suspend/Resume: ");
  1772. SdEnvironment.Boolean(Capabilities_SuspendResume IN c0);
  1773. SdEnvironment.Ln;
  1774. SdEnvironment.String("[SD] "); SdEnvironment.String(" Voltage Support for 3.3 V: ");
  1775. SdEnvironment.Boolean(Capabilities_Voltage33 IN c0);
  1776. SdEnvironment.Ln;
  1777. SdEnvironment.String("[SD] "); SdEnvironment.String(" Voltage Support for 3.0 V: ");
  1778. SdEnvironment.Boolean(Capabilities_Voltage30 IN c0);
  1779. SdEnvironment.Ln;
  1780. SdEnvironment.String("[SD] "); SdEnvironment.String(" Voltage Support for 1.8 V: ");
  1781. SdEnvironment.Boolean(Capabilities_Voltage18 IN c0);
  1782. SdEnvironment.Ln;
  1783. SdEnvironment.String("[SD] "); SdEnvironment.String(" Support for 64 Bit Bus: ");
  1784. SdEnvironment.Boolean(Capabilities_64BitBus IN c0);
  1785. SdEnvironment.Ln;
  1786. SdEnvironment.String("[SD] "); SdEnvironment.String(" Support for Asynchronous Interrupts: ");
  1787. SdEnvironment.Boolean(Capabilities_AsyncInterrupt IN c0);
  1788. SdEnvironment.Ln;
  1789. SdEnvironment.String("[SD] "); SdEnvironment.String(" Slot Type: ");
  1790. IF c0 * Capabilities_SlotTypeMask = Capabilities_SlotType_Removable THEN
  1791. SdEnvironment.String("Removable Card Slot")
  1792. ELSIF c0 * Capabilities_SlotTypeMask = Capabilities_SlotType_Embedded THEN
  1793. SdEnvironment.String("Embedded Slot for One Device")
  1794. ELSIF c0 * Capabilities_SlotTypeMask = Capabilities_SlotType_SharedBus THEN
  1795. SdEnvironment.String("Shared Bus Slot")
  1796. END;
  1797. SdEnvironment.Ln;
  1798. IF hc.version = 3 THEN
  1799. SdEnvironment.String("[SD] "); SdEnvironment.String(" Support for SDR50: ");
  1800. SdEnvironment.Boolean(Capabilities_SDR50 IN c1);
  1801. SdEnvironment.Ln;
  1802. SdEnvironment.String("[SD] "); SdEnvironment.String(" Support for SDR104: ");
  1803. SdEnvironment.Boolean(Capabilities_SDR104 IN c1);
  1804. SdEnvironment.Ln;
  1805. SdEnvironment.String("[SD] "); SdEnvironment.String(" Support for DDR50: ");
  1806. SdEnvironment.Boolean(Capabilities_DDR50 IN c1);
  1807. SdEnvironment.Ln;
  1808. SdEnvironment.String("[SD] "); SdEnvironment.String(" Support for Driver Type A: ");
  1809. SdEnvironment.Boolean(Capabilities_DriverTypeA IN c1);
  1810. SdEnvironment.Ln;
  1811. SdEnvironment.String("[SD] "); SdEnvironment.String(" Support for Driver Type C: ");
  1812. SdEnvironment.Boolean(Capabilities_DriverTypeC IN c1);
  1813. SdEnvironment.Ln;
  1814. SdEnvironment.String("[SD] "); SdEnvironment.String(" Support for Driver Type D: ");
  1815. SdEnvironment.Boolean(Capabilities_DriverTypeD IN c1);
  1816. SdEnvironment.Ln;
  1817. SdEnvironment.String("[SD] "); SdEnvironment.String(" Timer Count for Retuning: ");
  1818. IF c1 * Capabilities_TimerCountRetuningMask = Capabilities_TimerCountRetuningMask THEN
  1819. SdEnvironment.String("Unknown")
  1820. ELSIF c1 * Capabilities_TimerCountRetuningMask = {} THEN
  1821. SdEnvironment.String("Disabled")
  1822. ELSE
  1823. SdEnvironment.Int(LSH(LONGINT(1), LSH(SYSTEM.VAL(LONGINT, c1 * Capabilities_TimerCountRetuningMask), -Capabilities_TimerCountRetuningOfs)), 0);
  1824. SdEnvironment.String(" s")
  1825. END;
  1826. SdEnvironment.Ln;
  1827. SdEnvironment.String("[SD] "); SdEnvironment.String(" SDR50 Requires Retuning: ");
  1828. SdEnvironment.Boolean(Capabilities_TuningSDR50 IN c1);
  1829. SdEnvironment.Ln;
  1830. SdEnvironment.String("[SD] "); SdEnvironment.String(" Retuning Mode: ");
  1831. SdEnvironment.Int(LSH(SYSTEM.VAL(LONGINT, c1 * Capabilities_RetuningModesMask), -Capabilities_RetuningModesOfs), 0);
  1832. SdEnvironment.Ln;
  1833. SdEnvironment.String("[SD] "); SdEnvironment.String(" Clock Multiplier: ");
  1834. IF c1 * Capabilities_ClockMultiplierMask = {} THEN
  1835. SdEnvironment.String("Not Supported")
  1836. ELSE
  1837. SdEnvironment.Int(LSH(SYSTEM.VAL(LONGINT, c1 * Capabilities_ClockMultiplierMask), -Capabilities_ClockMultiplierOfs) + 1, 0)
  1838. END;
  1839. SdEnvironment.Ln
  1840. END
  1841. END
  1842. END PrintCapabilities;
  1843. PROCEDURE PrintCardStatus * (status: SET);
  1844. BEGIN
  1845. IF TRUE OR Trace THEN
  1846. SdEnvironment.String("[SD] Card Status:"); SdEnvironment.Ln;
  1847. SdEnvironment.String("[SD] AKE Error: "); SdEnvironment.Boolean(CardStatus_AkeSpecError IN status); SdEnvironment.Ln;
  1848. SdEnvironment.String("[SD] App Command: "); SdEnvironment.Boolean(CardStatus_AppCmd IN status); SdEnvironment.Ln;
  1849. SdEnvironment.String("[SD] Ready For Data: "); SdEnvironment.Boolean(CardStatus_ReadyForData IN status); SdEnvironment.Ln;
  1850. SdEnvironment.String("[SD] Card State: ");
  1851. CASE LSH(SYSTEM.VAL(LONGINT, status * CardStatus_CurrentStateMask), -CardStatus_CurrentStateOffset) OF
  1852. CardIdle: SdEnvironment.String("Idle")
  1853. |CardReady: SdEnvironment.String("Ready")
  1854. |CardIdentification: SdEnvironment.String("Identification")
  1855. |CardStandby: SdEnvironment.String("Standby")
  1856. |CardTransfer: SdEnvironment.String("Transfer")
  1857. |CardData: SdEnvironment.String("Sending Data")
  1858. |CardReceive: SdEnvironment.String("Receiving Data")
  1859. |CardProgram: SdEnvironment.String("Programming")
  1860. |CardDisabled: SdEnvironment.String("Disabled")
  1861. END;
  1862. SdEnvironment.Ln;
  1863. SdEnvironment.String("[SD] Erase Reset: "); SdEnvironment.Boolean(CardStatus_EraseReset IN status); SdEnvironment.Ln;
  1864. SdEnvironment.String("[SD] Internal ECC Enable: "); SdEnvironment.Boolean(CardStatus_CardEccDisable IN status); SdEnvironment.Ln;
  1865. SdEnvironment.String("[SD] Write_Protection Erase Skip: "); SdEnvironment.Boolean(CardStatus_WpEraseSkip IN status); SdEnvironment.Ln;
  1866. SdEnvironment.String("[SD] CSD Overwrite: "); SdEnvironment.Boolean(CardStatus_CsdOverwrite IN status); SdEnvironment.Ln;
  1867. SdEnvironment.String("[SD] Error: "); SdEnvironment.Boolean(CardStatus_Error IN status); SdEnvironment.Ln;
  1868. SdEnvironment.String("[SD] Card Controller Error: "); SdEnvironment.Boolean(CardStatus_CcError IN status); SdEnvironment.Ln;
  1869. SdEnvironment.String("[SD] Card ECC Failed: "); SdEnvironment.Boolean(CardStatus_CardEccFailed IN status); SdEnvironment.Ln;
  1870. SdEnvironment.String("[SD] Illegal Command: "); SdEnvironment.Boolean(CardStatus_IllegalCommand IN status); SdEnvironment.Ln;
  1871. SdEnvironment.String("[SD] Command CRC Error: "); SdEnvironment.Boolean(CardStatus_ComCrcError IN status); SdEnvironment.Ln;
  1872. SdEnvironment.String("[SD] Lock/Unlock Failed: "); SdEnvironment.Boolean(CardStatus_LockUnlockFailed IN status); SdEnvironment.Ln;
  1873. SdEnvironment.String("[SD] Card is Locked: "); SdEnvironment.Boolean(CardStatus_CardIsLocked IN status); SdEnvironment.Ln;
  1874. SdEnvironment.String("[SD] Write-Protection Violation: "); SdEnvironment.Boolean(CardStatus_WpViolation IN status); SdEnvironment.Ln;
  1875. SdEnvironment.String("[SD] Invalid Erase Parameters: "); SdEnvironment.Boolean(CardStatus_EraseParam IN status); SdEnvironment.Ln;
  1876. SdEnvironment.String("[SD] Erase Sequence Error: "); SdEnvironment.Boolean(CardStatus_EraseSeqError IN status); SdEnvironment.Ln;
  1877. SdEnvironment.String("[SD] Block Length Error: "); SdEnvironment.Boolean(CardStatus_BlockLenError IN status); SdEnvironment.Ln;
  1878. SdEnvironment.String("[SD] Address Error: "); SdEnvironment.Boolean(CardStatus_AddressError IN status); SdEnvironment.Ln;
  1879. SdEnvironment.String("[SD] Argument Out of Range: "); SdEnvironment.Boolean(CardStatus_OutOfRange IN status); SdEnvironment.Ln
  1880. END
  1881. END PrintCardStatus;
  1882. PROCEDURE PrintCardCsd * (CONST csd: ARRAY OF LONGINT);
  1883. VAR
  1884. cap: HUGEINT;
  1885. val, version, sizeMult: LONGINT;
  1886. BEGIN
  1887. IF Trace THEN
  1888. version := ReadBitfield(csd, CardCsd_CsdStructureOfs, CardCsd_CsdStructureWidth) + 1;
  1889. SdEnvironment.String("[SD] "); SdEnvironment.String("Card CSD:"); SdEnvironment.Ln;
  1890. SdEnvironment.String("[SD] "); SdEnvironment.String(" Version: "); SdEnvironment.Int(version, 0); SdEnvironment.Ln;
  1891. (* Common Fields *)
  1892. SdEnvironment.String("[SD] "); SdEnvironment.String(" File Format: ");
  1893. val := ReadBitfield(csd, CardCsd_FileFormatOfs, CardCsd_FileFormatWidth);
  1894. IF ReadBitfield(csd, CardCsd_FileFormatGrp, 1) = 1 THEN
  1895. SdEnvironment.String("Unknown Value (");
  1896. SdEnvironment.Int(val, 0);
  1897. SdEnvironment.String(")")
  1898. ELSIF val = 0 THEN
  1899. SdEnvironment.String("Hard-disk file system with partition table")
  1900. ELSIF val = 1 THEN
  1901. SdEnvironment.String("FAT")
  1902. ELSIF val = 2 THEN
  1903. SdEnvironment.String("Universal File Format")
  1904. ELSE
  1905. SdEnvironment.String("Other")
  1906. END;
  1907. SdEnvironment.Ln;
  1908. SdEnvironment.String("[SD] "); SdEnvironment.String(" Temporary Write Protection: "); SdEnvironment.Boolean(ReadBitfield(csd, CardCsd_TmpWriteProtect, 1) = 1); SdEnvironment.Ln;
  1909. SdEnvironment.String("[SD] "); SdEnvironment.String(" Permanent Write Protection: "); SdEnvironment.Boolean(ReadBitfield(csd, CardCsd_PermWriteProtect, 1) = 1); SdEnvironment.Ln;
  1910. SdEnvironment.String("[SD] "); SdEnvironment.String(" Copy: "); SdEnvironment.Boolean(ReadBitfield(csd, CardCsd_Copy, 1) = 1); SdEnvironment.Ln;
  1911. SdEnvironment.String("[SD] "); SdEnvironment.String(" Partial Block Write: "); SdEnvironment.Boolean(ReadBitfield(csd, CardCsd_WriteBlPartial, 1) = 1); SdEnvironment.Ln;
  1912. SdEnvironment.String("[SD] "); SdEnvironment.String(" Maximum Write Block Length: ");
  1913. val := ReadBitfield(csd, CardCsd_WriteBlLenOfs, CardCsd_WriteBlLenWidth);
  1914. IF (val <= 8) OR (val >= 12) THEN
  1915. SdEnvironment.String("Unknown Value (");
  1916. SdEnvironment.Int(val, 0);
  1917. SdEnvironment.String(")")
  1918. ELSE
  1919. SdEnvironment.Int(LSH(LONGINT(1), val), 0);
  1920. END;
  1921. SdEnvironment.Ln;
  1922. SdEnvironment.String("[SD] "); SdEnvironment.String(" Block Program Time / Block Read Time: ");
  1923. val := ReadBitfield(csd, CardCsd_R2wFactorOfs, CardCsd_R2wFactorWidth);
  1924. IF val >= 6 THEN
  1925. SdEnvironment.String("Unknown Value (");
  1926. SdEnvironment.Int(val, 0);
  1927. SdEnvironment.String(")")
  1928. ELSE
  1929. SdEnvironment.Int(LSH(LONGINT(1), val), 0);
  1930. END;
  1931. SdEnvironment.Ln;
  1932. SdEnvironment.String("[SD] "); SdEnvironment.String(" Group Write Protection: "); SdEnvironment.Boolean(ReadBitfield(csd, CardCsd_WpGrpEnable, 1) = 1); SdEnvironment.Ln;
  1933. SdEnvironment.String("[SD] "); SdEnvironment.String(" WpGrpSize: "); SdEnvironment.Int(ReadBitfield(csd, CardCsd_WpGrpSizeOfs, CardCsd_WpGrpSizeWidth) + 1, 0); SdEnvironment.String(" sectors"); SdEnvironment.Ln;
  1934. SdEnvironment.String("[SD] "); SdEnvironment.String(" Sector Size: "); SdEnvironment.Int(ReadBitfield(csd, CardCsd_SectorSizeOfs, CardCsd_SectorSizeWidth) + 1, 0); SdEnvironment.Ln;
  1935. SdEnvironment.String("[SD] "); SdEnvironment.String(" Erase Block Enable: "); SdEnvironment.Boolean(ReadBitfield(csd, CardCsd_EraseBlkEn, 1) = 1); SdEnvironment.Ln;
  1936. IF version = 1 THEN
  1937. sizeMult := LSH(LONGINT(2), ReadBitfield(csd, CardCsd_CSizeMultOfs1, CardCsd_CSizeMultWidth1));
  1938. cap := sizeMult * (1 + ReadBitfield(csd, CardCsd_CSizeOfs1, CardCsd_CSizeWidth1)) * 512;
  1939. ELSE
  1940. cap := 1024 * (HUGEINT(ReadBitfield(csd, CardCsd_CSizeOfs2, CardCsd_CSizeWidth2)) + 1);
  1941. END;
  1942. SdEnvironment.String("[SD] "); SdEnvironment.String(" Card Capacity: "); SdEnvironment.Int(cap, 0); SdEnvironment.String(" B"); SdEnvironment.Ln;
  1943. SdEnvironment.String("[SD] "); SdEnvironment.String(" DSR Implemented: "); SdEnvironment.Boolean(ReadBitfield(csd, CardCsd_DsrImp, 1) = 1); SdEnvironment.Ln;
  1944. SdEnvironment.String("[SD] "); SdEnvironment.String(" Misaligned Block Read: "); SdEnvironment.Boolean(ReadBitfield(csd, CardCsd_ReadBlkMisalign, 1) = 1); SdEnvironment.Ln;
  1945. SdEnvironment.String("[SD] "); SdEnvironment.String(" Misaligned Block Write: "); SdEnvironment.Boolean(ReadBitfield(csd, CardCsd_WriteBlkMisalign, 1) = 1); SdEnvironment.Ln;
  1946. SdEnvironment.String("[SD] "); SdEnvironment.String(" Partial Block Read: "); SdEnvironment.Boolean(ReadBitfield(csd, CardCsd_ReadBlPartial, 1) = 1); SdEnvironment.Ln;
  1947. (*ASSERT(ReadBitfield(csd, CardCsd_ReadBlPartial, 1) = 1);*)
  1948. SdEnvironment.String("[SD] "); SdEnvironment.String(" Maximal Block Read Length: ");
  1949. val := ReadBitfield(csd, CardCsd_ReadBlLenOfs, CardCsd_ReadBlLenWidth);
  1950. IF (val <= 8) OR (val >= 12) THEN
  1951. SdEnvironment.String("Unknown Value (");
  1952. SdEnvironment.Int(val, 0);
  1953. SdEnvironment.String(")")
  1954. ELSE
  1955. SdEnvironment.Int(LSH(LONGINT(1), val), 0); SdEnvironment.String(" B")
  1956. END;
  1957. SdEnvironment.Ln;
  1958. SdEnvironment.String("[SD] "); SdEnvironment.String(" Supported Command Classes: "); SdEnvironment.Set(SYSTEM.VAL(SET, ReadBitfield(csd, CardCsd_CccOfs, CardCsd_CccWidth))); SdEnvironment.Ln;
  1959. SdEnvironment.String("[SD] "); SdEnvironment.String(" Transfer Speed: ");
  1960. val := ReadBitfield(csd, CardCsd_TranSpeedOfs, CardCsd_TranSpeedWidth);
  1961. CASE val DIV 8 OF
  1962. 1: SdEnvironment.String("1.0")
  1963. |2: SdEnvironment.String("1.2")
  1964. |3: SdEnvironment.String("1.3")
  1965. |4: SdEnvironment.String("1.5")
  1966. |5: SdEnvironment.String("2.0")
  1967. |6: SdEnvironment.String("2.0")
  1968. |7: SdEnvironment.String("2.5")
  1969. |8: SdEnvironment.String("3.5")
  1970. |9: SdEnvironment.String("4.0")
  1971. |10: SdEnvironment.String("4.5")
  1972. |11: SdEnvironment.String("5.0")
  1973. |12: SdEnvironment.String("5.5")
  1974. |13: SdEnvironment.String("6.0")
  1975. |14: SdEnvironment.String("7.0")
  1976. |15: SdEnvironment.String("8.0")
  1977. ELSE
  1978. SdEnvironment.String("Unknown Value (");
  1979. SdEnvironment.Int(val, 0);
  1980. SdEnvironment.String(")")
  1981. END;
  1982. SdEnvironment.String(" * 1");
  1983. CASE val MOD 8 OF
  1984. 0: SdEnvironment.String("00 k")
  1985. |1: SdEnvironment.String(" M")
  1986. |2: SdEnvironment.String("0 M")
  1987. |3: SdEnvironment.String("00 M")
  1988. END;
  1989. SdEnvironment.String("Bit/s");
  1990. SdEnvironment.Ln;
  1991. SdEnvironment.String("[SD] "); SdEnvironment.String(" Clock-Dependent Access Time: "); SdEnvironment.Int(ReadBitfield(csd, CardCsd_NsacOfs, CardCsd_NsacWidth) * 100, 0); SdEnvironment.String("000 clock cycles"); SdEnvironment.Ln;
  1992. SdEnvironment.String("[SD] "); SdEnvironment.String(" Asynchronous Access Time: ");
  1993. val := ReadBitfield(csd, CardCsd_TaacOfs, CardCsd_TaacWidth);
  1994. CASE val DIV 8 OF
  1995. 1: SdEnvironment.String("1.0")
  1996. |2: SdEnvironment.String("1.2")
  1997. |3: SdEnvironment.String("1.3")
  1998. |4: SdEnvironment.String("1.5")
  1999. |5: SdEnvironment.String("2.0")
  2000. |6: SdEnvironment.String("2.5")
  2001. |7: SdEnvironment.String("3.0")
  2002. |8: SdEnvironment.String("3.5")
  2003. |9: SdEnvironment.String("4.0")
  2004. |10: SdEnvironment.String("4.5")
  2005. |11: SdEnvironment.String("5.0")
  2006. |12: SdEnvironment.String("5.5")
  2007. |13: SdEnvironment.String("6.0")
  2008. |14: SdEnvironment.String("7.0")
  2009. |15: SdEnvironment.String("8.0")
  2010. ELSE
  2011. SdEnvironment.String("Unknown Value (");
  2012. SdEnvironment.Int(val, 0);
  2013. SdEnvironment.String(")")
  2014. END;
  2015. SdEnvironment.String(" * 1");
  2016. CASE val MOD 8 OF
  2017. 0: SdEnvironment.String(" ns")
  2018. |1: SdEnvironment.String("0 ns")
  2019. |2: SdEnvironment.String("00 ns")
  2020. |3: SdEnvironment.String(" microsecond")
  2021. |4: SdEnvironment.String("0 microsecond")
  2022. |5: SdEnvironment.String("00 microsecond")
  2023. |6: SdEnvironment.String(" ms")
  2024. |7: SdEnvironment.String("0 ms")
  2025. END;
  2026. SdEnvironment.Ln;
  2027. END
  2028. END PrintCardCsd;
  2029. PROCEDURE ReadBitfield (CONST field: ARRAY OF LONGINT; ofs, width: LONGINT): LONGINT;
  2030. VAR
  2031. bits: ADDRESS;
  2032. BEGIN
  2033. ASSERT(ofs MOD 8 + width <= 32);
  2034. bits := SYSTEM.GET8(ADDRESSOF(field[0]) + ofs DIV 8);
  2035. IF ofs MOD 8 + width > 8 THEN
  2036. bits := bits + SYSTEM.GET8(ADDRESSOF(field[0]) + ofs DIV 8 + 1) * 100H
  2037. END;
  2038. IF ofs MOD 8 + width > 16 THEN
  2039. bits := bits + SYSTEM.GET8(ADDRESSOF(field[0]) + ofs DIV 8 + 2) * 10000H
  2040. END;
  2041. IF ofs MOD 8 + width > 24 THEN
  2042. bits := bits + SYSTEM.GET8(ADDRESSOF(field[0]) + ofs DIV 8 + 3) * 1000000H
  2043. END;
  2044. RETURN SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, LSH(bits, -(ofs MOD 8))) * {0 .. width - 1})
  2045. END ReadBitfield;
  2046. END Sd.