Sd.Mod 110 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067
  1. MODULE Sd;
  2. (**
  3. AUTHOR Timothée Martiel, 2015
  4. PURPOSE SD Card Host Controller Driver
  5. *)
  6. IMPORT
  7. SYSTEM, SdEnvironment, Log := SdEnvironment;
  8. CONST
  9. BlockSize * = 512;
  10. InitialClockFrequency * = 400000; (* Hz *)
  11. (* Commands *) (*! Do not change values *)
  12. CMD_GO_IDLE_STATE * = 0; (** CMD0 bc [31:0] stuff bits - *)
  13. CMD_ALL_SEND_CID * = 2; (** CMD2 bcr [31:0] stuff bits R2 *)
  14. CMD_SEND_RELATIVE_ADDR * = 3; (** CMD3 bcr [31:0] stuff bits R6 *)
  15. CMD_SET_DSR * = 4; (** CMD4 bc [31:16] DSR [15:0] stuff bits - *)
  16. CMD_IO_SEND_OP_COND * = 5; (** CMD5 ?? [31:25] stuff bits [24] switch 1.8V request [23:0] I/O OCR R4 *)
  17. 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 *)
  18. CMD_SELECT_DESELECT_CARD * = 7; (** CMD7 ac [31:16] RCA [15:0] stuff bits R1b (only from the selected card) *)
  19. CMD_SEND_IF_COND * = 8; (** CMD8 bcr [31:12] reserved bits [11:8] supply voltage(VHS) [7:0]check pattern R7 *)
  20. CMD_SEND_CSD * = 9; (** CMD9 ac [31:16] RCA [15:0] stuff bits R2 *)
  21. CMD_SEND_CID * = 10; (** CMD10 ac [31:16] RCA [15:0] stuff bits R2 *)
  22. CMD_VOLTAGE_SWITCH * = 11; (** CMD11 ac [31:0] reserved bits (all 0) R1 *)
  23. CMD_STOP_TRANSMISSION * = 12; (** CMD12 ac [31:0] stuff bits R1b *)
  24. CMD_SEND_STATUS * = 13; (** CMD13 ac [31:16] RCA [15:0] stuff bits R1 *)
  25. CMD_GO_INACTIVE_STATE * = 15; (** CMD15 ac [31:16] RCA [15:0] reserved bits - *)
  26. CMD_SET_BLOCKLEN * = 16; (** CMD16 ac [31:0] block length R1 *)
  27. CMD_READ_SINGLE_BLOCK * = 17; (** CMD17 adtc [31:0] data address2 R1 *)
  28. CMD_READ_MULTIPLE_BLOCK * = 18; (** CMD18 adtc [31:0] data address2 R1 *)
  29. CMD_SEND_TUNING_BLOCK * = 19; (** CMD19 adtc [31:0] reserved bits (all 0) R1 *)
  30. CMD_SPEED_CLASS_CONTROL * = 20; (** CMD20 ac [31:28]Speed Class Control [27:0] Reserved (all-0) R1b *)
  31. CMD_SET_BLOCK_COUNT * = 23; (** CMD23 ac [31:0] Block Count R1 *)
  32. CMD_WRITE_BLOCK * = 24; (** CMD24 adtc [31:0] data address2 R1 *)
  33. CMD_WRITE_MULTIPLE_BLOCK * = 25; (** CMD25 adtc [31:0] data address2 R1 *)
  34. CMD_PROGRAM_CSD * = 27; (** CMD27 adtc [31:0] stuff bits R1 *)
  35. CMD_SET_WRITE_PROT * = 28; (** CMD28 ac [31:0] data address2 R1b *)
  36. CMD_CLR_WRITE_PROT * = 29; (** CMD29 ac [31:0] data address2 R1b *)
  37. CMD_SEND_WRITE_PROT * = 30; (** CMD30 adtc [31:0] write protect data address2 R1 *)
  38. CMD_ERASE_WR_BLK_START * = 32; (** CMD32 ac [31:0] data address1 R1 *)
  39. CMD_ERASE_WR_BLK_END * = 33; (** CMD33 ac [31:0] data address1 R1 *)
  40. CMD_ERASE * = 38; (** CMD38 ac [31:0] stuff bits R1b *)
  41. CMD_LOCK_UNLOCK * = 42; (** CMD42 adtc [31:0] Reserved bits (Set all 0) R1 *)
  42. CMD_APP_CMD * = 55; (** CMD55 ac [31:16] RCA [15:0] stuff bits R1 *)
  43. CMD_GEN_CMD * = 56; (** CMD56 adtc [31:1] stuff bits. [0] RD/WR R1 *)
  44. (** Application Commands *) (*! Do Not Change Values *)
  45. ACMD_SET_BUS_WIDTH * = 6; (** ACMD6 ac [31:2] stuff bits [1:0] bus width R1 *)
  46. ACMD_SD_STATUS * = 13; (** ACMD13 adtc [31:0] stuff bits R1 *)
  47. ACMD_SEND_NUM_WR_BLOCKS * = 22; (** ACMD22 adtc [31:0] stuff bits R1 *)
  48. ACMD_SET_WR_BLK_ERASE_COUNT * = 23; (** ACMD23 ac [31:23] stuff bits [22:0] Number of blocks R1 *)
  49. 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 *)
  50. ACMD_SET_CLR_CARD_DETECT * = 42; (** ACMD42 ac [31:1] stuff bits [0] set_cd R1 *)
  51. ACMD_SEND_SCR * = 51; (** ACMD51 adtc [31:0] stuff bits R1 *)
  52. (** Errors *)
  53. ErrorNone * = 0; (** No error *)
  54. ErrorCmdTimeout * = 1; (** Timeout on command line *)
  55. ErrorCmdCrc * = 2; (** CRC error on command line *)
  56. ErrorDatTimeout * = 3; (** Timeout on data line *)
  57. ErrorDatCrc * = 4; (** CRC error on data line *)
  58. ErrorNoCard * = 5; (** No card present *)
  59. ErrorCard * = 6; (** Card failed to perform operation *)
  60. ErrorUnrecoverable * = 7; (** Host controller in an unrecoverable state *)
  61. ErrorInvalidParameters * = 8; (** Invalid parameters *)
  62. (** Card Versions: maximal SD physical layer specifications version supported by the card *)
  63. Version1 * = 0; (** v1.00 or v1.01 *)
  64. Version1p1 * = 1; (** v1.10 *)
  65. Version2 * = 2; (** v2.00 *)
  66. Version3 * = 3; (** v3.01 *)
  67. Version4 * = 4; (** v4.10 *)
  68. Version5 * = 5; (** v5.10 *)
  69. Version6 * =6; (** v6.0 *)
  70. (** Card Type *)
  71. TypeNone * = 0; (** Unknow *)
  72. TypeSDSC * = 1; (** SD standard capacity - physical specs v1.0 or v1.1, limited to 2 GB *)
  73. TypeSDHC * = 2; (** SD High Capacity - 2 GB to 32 GB *)
  74. TypeSDXC * = 3; (** SD Extended Capacity - 32 GB to 2 TB *)
  75. (** Card Events *)
  76. OnInitialization * = 0;
  77. OnRemoval * = 1;
  78. OnReadComplete * = 2;
  79. OnWriteComplete * = 3;
  80. (** Command Record Flags *)
  81. FlagData * = 0;
  82. FlagRead * = 1;
  83. FlagAutoCmd12 * = 2;
  84. FlagAutoCmd23 * = 3;
  85. FlagMultipleBlockTx * = 4;
  86. FlagCountBlocks * = 5;
  87. FlagAbort * = 7;
  88. FlagApplicationCmd * = 8;
  89. FlagIgnoreIllegalCmd * = 9;
  90. (** Response Types *) (*! Do not change values *)
  91. ResponseNone * = -1;
  92. ResponseR1 * = 0;
  93. ResponseR1b * = 1;
  94. ResponseR2 * = 2;
  95. ResponseR3 * = 3;
  96. ResponseR4 * = 4;
  97. ResponseR5 * = 5;
  98. ResponseR5b * = 6;
  99. ResponseR6 * = 7;
  100. ResponseR7 * = 8;
  101. (** Host Controller States *)
  102. HcOperational * = 0; (** Host controller is operational *)
  103. HcConfiguring * = 1; (** Host controller is waiting for configuration input *)
  104. HcError * = 2; (** Error occurred *)
  105. (** Card States *)
  106. CardIdle = 0;
  107. CardReady = 1;
  108. CardIdentification = 2;
  109. CardStandby = 3;
  110. CardTransfer = 4;
  111. CardData = 5;
  112. CardReceive = 6;
  113. CardProgram = 7;
  114. CardDisabled = 8;
  115. (** Operation modes *)
  116. OpCpu = 0;
  117. OpSdma = 1;
  118. OpAdma = 2;
  119. (* Present State bits *)
  120. PresentState_CommandInhibitCmd = 0;
  121. PresentState_CommandInhibitDat = 1;
  122. PresentState_DatLineActive = 2;
  123. PresentState_RetuningRequest = 3;
  124. PresentState_WriteTransferActive = 8;
  125. PresentState_ReadTransferActive = 9;
  126. PresentState_BufferWriteEnable = 10;
  127. PresentState_BufferReadEnable = 11;
  128. PresentState_CardInserted = 16;
  129. PresentState_CardStateStable = 17;
  130. PresentState_CardDetectPinLevel = 18;
  131. PresentState_WriteProtectSwitchPinLevel = 19;
  132. PresentState_CmdLineSignalLevel = 24;
  133. PresentState_DatLineSignalLevelOfs = 20;
  134. PresentState_DatLineSignalLevelMask = {20 .. 23};
  135. (* Interrupt Status, Status Enable, Signal Enable bits *)
  136. Interrupt_Normal_CommandComplete = 0;
  137. Interrupt_Normal_TransferComplete = 1;
  138. Interrupt_Normal_BlockGapEvent = 2;
  139. Interrupt_Normal_DmaInterrupt = 3;
  140. Interrupt_Normal_BufferWriteReady = 4;
  141. Interrupt_Normal_BufferReadReady = 5;
  142. Interrupt_Normal_CardInsertion = 6;
  143. Interrupt_Normal_CardRemoval = 7;
  144. Interrupt_Normal_CardInterrupt = 8;
  145. Interrupt_Normal_IntA = 9;
  146. Interrupt_Normal_IntB = 10;
  147. Interrupt_Normal_IntC = 11;
  148. Interrupt_Normal_RetuningEvent = 12;
  149. Interrupt_Normal_ErrorInterrupt = 15;
  150. Interrupt_Error_CommandTimeout = 16;
  151. Interrupt_Error_CommandCrc = 17;
  152. Interrupt_Error_CommandEndBit = 18;
  153. Interrupt_Error_CommandIndex = 19;
  154. Interrupt_Error_DataTimeout = 20;
  155. Interrupt_Error_DataCrc = 21;
  156. Interrupt_Error_DataEndBit = 22;
  157. Interrupt_Error_CurrentLimit = 23;
  158. Interrupt_Error_AutoCmd12 = 24;
  159. Interrupt_Error_Adma = 25;
  160. Interrupt_Error_Tuning = 26;
  161. Interrupt_Normal_All = {Interrupt_Normal_CommandComplete, Interrupt_Normal_TransferComplete, Interrupt_Normal_BlockGapEvent, Interrupt_Normal_DmaInterrupt,
  162. Interrupt_Normal_BufferWriteReady, Interrupt_Normal_BufferReadReady, Interrupt_Normal_CardInsertion, Interrupt_Normal_CardRemoval,
  163. Interrupt_Normal_CardInterrupt, Interrupt_Normal_IntA, Interrupt_Normal_IntB, Interrupt_Normal_IntC, Interrupt_Normal_RetuningEvent,
  164. Interrupt_Normal_ErrorInterrupt};
  165. Interrupt_Error_All = {Interrupt_Error_CommandTimeout, Interrupt_Error_CommandCrc, Interrupt_Error_CommandEndBit,
  166. Interrupt_Error_CommandIndex, Interrupt_Error_DataTimeout, Interrupt_Error_DataCrc, Interrupt_Error_DataEndBit, Interrupt_Error_CurrentLimit,
  167. Interrupt_Error_AutoCmd12, Interrupt_Error_Adma, Interrupt_Error_Tuning};
  168. Interrupt_All = Interrupt_Normal_All + Interrupt_Error_All;
  169. (* Transfer Mode Register bits *)
  170. TransferMode_DmaEnable = 0;
  171. TransferMode_BlockCountEnable = 1;
  172. TransferMode_AutoCmdOfs = 2;
  173. TransferMode_AutoCmdMask = {2 .. 3};
  174. TransferMode_DataTxDirection = 4;
  175. TransferMode_MultipleBlocks = 5;
  176. TransferMode_AutoCmd_None = {};
  177. TransferMode_AutoCmd_Cmd12 = {2};
  178. TransferMode_AutoCmd_Cmd23 = {3};
  179. (* Command Register bits *)
  180. Command_ResponseTypeOffset = 0;
  181. Command_CrcCheckEnable = 3;
  182. Command_IndexCheckEnable = 4;
  183. Command_DataPresent = 5;
  184. Command_CommandTypeOffset = 6;
  185. Command_CommandTypeMask = {6 .. 7};
  186. Command_CommandIndexOffset = 8;
  187. Command_CommandIndexMask = {8 .. 13};
  188. Command_ResponseType_None = 0;
  189. Command_ResponseType_136b = 1;
  190. Command_ResponseType_48b = 2;
  191. Command_ResponseType_48bBusy = 3;
  192. (* Capabilities Register *)
  193. (* Low Word *)
  194. Capabilities_TimeoutClockFrequencyOfs = 0;
  195. Capabilities_TimeoutClockFrequencyMask = {0 .. 5};
  196. Capabilities_TimeoutClockUnit = 7;
  197. Capabilities_BaseClockFreqSdOfs = 8;
  198. Capabilities_BaseClockFreqSdMask = {8 .. 15};
  199. Capabilities_MaxBlockLenOfs = 16;
  200. Capabilities_MaxBlockLenMask = {16 .. 17};
  201. Capabilities_8BitEmbedded = 18;
  202. Capabilities_ADMA2 = 19;
  203. Capabilities_HighSpeed = 21;
  204. Capabilities_SDMA = 22;
  205. Capabilities_SuspendResume = 23;
  206. Capabilities_Voltage33 = 24;
  207. Capabilities_Voltage30 = 25;
  208. Capabilities_Voltage18 = 26;
  209. Capabilities_64BitBus = 28;
  210. Capabilities_AsyncInterrupt = 29;
  211. Capabilities_SlotTypeOfs = 30;
  212. Capabilities_SlotTypeMask = {30 .. 31};
  213. (* High Word *)
  214. Capabilities_SDR50 = 0;
  215. Capabilities_SDR104 = 1;
  216. Capabilities_DDR50 = 2;
  217. Capabilities_DriverTypeA = 4;
  218. Capabilities_DriverTypeC = 5;
  219. Capabilities_DriverTypeD = 6;
  220. Capabilities_TimerCountRetuningOfs = 8;
  221. Capabilities_TimerCountRetuningMask = {8 .. 11};
  222. Capabilities_TuningSDR50 = 13;
  223. Capabilities_RetuningModesOfs = 14;
  224. Capabilities_RetuningModesMask = {14 .. 15};
  225. Capabilities_ClockMultiplierOfs = 16;
  226. Capabilities_ClockMultiplierMask = {16 .. 23};
  227. (* Patterns *)
  228. Capabilities_SlotType_Removable = {};
  229. Capabilities_SlotType_Embedded = {30};
  230. Capabilities_SlotType_SharedBus = {31};
  231. (* Host Control 1 register values *)
  232. HostControl1_LedControl = 0;
  233. HostControl1_DataTransferWidth = 1;
  234. HostControl1_HighSpeedEnable = 2;
  235. HostControl1_DmaSelectOfs = 3;
  236. HostControl1_DmaSelectMask = {3 .. 4};
  237. HostControl1_ExtendedDataTxWidth = 5;
  238. HostControl1_CardDetectTestLevel = 6;
  239. HostControl1_CardDetectSignalSelection = 7;
  240. HostControl1_DmaSelect_Sdma = {};
  241. HostControl1_DmaSelect_32Adma = {4};
  242. (* SoftwareReset register values *)
  243. SoftwareResetAll = 1;
  244. SoftwareResetCmd = 2;
  245. SoftwareResetDat = 4;
  246. (* Clock Control register values *)
  247. ClockControl_InternalClockEnable = 0;
  248. ClockControl_InternalClockState = 1;
  249. ClockControl_SdClockEnable = 2;
  250. ClockControl_ClockGeneratorSelect = 5;
  251. ClockControl_SdClockFreqUpperOfs = 6;
  252. ClockControl_SdClockFreqUpperMask = {6, 7};
  253. ClockControl_SdClockFreqOfs = 8;
  254. ClockControl_SdClockFreqMask = {8 .. 15};
  255. (* Power Control register values *)
  256. PowerControl_SDBusPower* = 0;
  257. PowerControl_SDBusVoltageOfs = 1;
  258. PowerControl_SDBusVoltageMask = {1 .. 3};
  259. PowerControl_SDBusVoltage_18 = {1, 3};
  260. PowerControl_SDBusVoltage_30 = {2, 3};
  261. PowerControl_SDBusVoltage_33 = {1, 2, 3};
  262. (* Host Controller Version *)
  263. HostControllerVersion_SpecificationMask = {0 .. 7};
  264. HostControllerVersion_VendorOfs = 8;
  265. HostControllerVersion_VendorMask = {8 .. 15};
  266. (* SD Status fields *)
  267. SdStatus_FuleSupport = 312;
  268. SdStatus_DiscardSupport = 313;
  269. SdStatus_PerformanceEnhanceOfs = 335;
  270. SdStatus_PerformanceEnhanceWidth = 8;
  271. SdStatus_AppPerfClassOfs = 336;
  272. SdStatus_AppPerfClassWidth = 4;
  273. SdStatus_SusAddrOfs = 346;
  274. SdStatus_SusAddrWidth = 22;
  275. SdStatus_VscAuSizeOfs = 368;
  276. SdStatus_VscAuSizeWidth = 10;
  277. SdStatus_VideoSpeedClassOfs = 384;
  278. SdStatus_VideoSpeedClassWidth = 8;
  279. SdStatus_UhsAuSizeOfs = 392;
  280. SdStatus_UhsAuSizeWidth = 4;
  281. SdStatus_UhsSpeedGradeOfs = 396;
  282. SdStatus_UhsSpeedGradeWidth = 4;
  283. SdStatus_EraseOffsetOfs = 400;
  284. SdStatus_EraseOffsetWidth = 2;
  285. SdStatus_EraseTimeoutOfs = 402;
  286. SdStatus_EraseTimeoutWidth = 6;
  287. SdStatus_EraseSizeOfs = 408;
  288. SdStatus_EraseSizeWidth = 16;
  289. SdStatus_AuSizeOfs = 428;
  290. SdStatus_AuSizeWidth = 4;
  291. SdStatus_PerformanceMoveOfs = 432;
  292. SdStatus_PerformanceMoveWidth = 8;
  293. SdStatus_SpeedClassOfs = 440;
  294. SdStatus_SpeedClassWidth = 8;
  295. SdStatus_SizeOfProtectedAreaOfs = 448;
  296. SdStatus_SizeOfProtectedAreaWidth = 32;
  297. SdStatus_SdCardTypeOfs = 480;
  298. SdStatus_SdCardTypeWidth = 16;
  299. SdStatus_SecuredMode = 509;
  300. SdStatus_DatBusWidthOfs = 510;
  301. SdStatus_DatBusWidthWidth = 2;
  302. (* Card Status register -- R1 *)
  303. CardStatus_AkeSpecError = 3;
  304. CardStatus_AppCmd = 5;
  305. CardStatus_ReadyForData = 8;
  306. CardStatus_CurrentStateOffset = 9;
  307. CardStatus_CurrentStateMask = {9 .. 12};
  308. CardStatus_EraseReset = 13;
  309. CardStatus_CardEccDisable = 14;
  310. CardStatus_WpEraseSkip = 15;
  311. CardStatus_CsdOverwrite = 16;
  312. CardStatus_Error = 19;
  313. CardStatus_CcError = 20;
  314. CardStatus_CardEccFailed = 21;
  315. CardStatus_IllegalCommand = 22;
  316. CardStatus_ComCrcError = 23;
  317. CardStatus_LockUnlockFailed = 24;
  318. CardStatus_CardIsLocked = 25;
  319. CardStatus_WpViolation = 26;
  320. CardStatus_EraseParam = 27;
  321. CardStatus_EraseSeqError = 28;
  322. CardStatus_BlockLenError = 29;
  323. CardStatus_AddressError = 30;
  324. CardStatus_OutOfRange = 31;
  325. (* OCR Registers *)
  326. CardOcr_Vdd27_28 = 15;
  327. CardOcr_Vdd28_29 = 16;
  328. CardOcr_Vdd29_30 = 17;
  329. CardOcr_Vdd30_31 = 18;
  330. CardOcr_Vdd31_32 = 19;
  331. CardOcr_Vdd32_33 = 20;
  332. CardOcr_Vdd33_34 = 21;
  333. CardOcr_Vdd34_35 = 22;
  334. CardOcr_Vdd35_36 = 23;
  335. CardOcr_S18A = 24;
  336. CardOcr_UHS2CardStatus = 29;
  337. CardOcr_CardCapacityStatus = 30;
  338. CardOcr_PowerUpStatus = 31;
  339. (* CID Register *)
  340. CardCid_ManufacturerIdOfs = 112;
  341. CardCid_ManufacturerIdWidth = 8;
  342. CardCid_OEM_ApplicationIdOfs = 96;
  343. CardCid_OEM_ApplicationIdWidth = 16;
  344. CardCid_ProductNameOfs = 56;
  345. CardCid_ProductNameWidth = 40;
  346. CardCid_ProductRevisionOfs = 48;
  347. CardCid_ProductRevisionWidth = 8;
  348. CardCid_ProductSerialNbOfs = 16;
  349. CardCid_ProductSerialNbWidth = 32;
  350. CardCid_ProductManufacturingDateOfs = 0;
  351. CardCid_ProductManufacturingDateWidth = 12;
  352. (* CSD Register. This excludes the CRC7 of the specifications. *)
  353. CardCsd_FileFormatOfs = 2;
  354. CardCsd_FileFormatWidth = 2;
  355. CardCsd_TmpWriteProtect = 4;
  356. CardCsd_PermWriteProtect = 5;
  357. CardCsd_Copy = 6;
  358. CardCsd_FileFormatGrp = 7;
  359. CardCsd_WriteBlPartial = 13;
  360. CardCsd_WriteBlLenOfs = 14;
  361. CardCsd_WriteBlLenWidth = 4;
  362. CardCsd_R2wFactorOfs = 18;
  363. CardCsd_R2wFactorWidth = 3;
  364. CardCsd_WpGrpEnable = 23;
  365. CardCsd_WpGrpSizeOfs = 24;
  366. CardCsd_WpGrpSizeWidth = 7;
  367. CardCsd_SectorSizeOfs = 31;
  368. CardCsd_SectorSizeWidth = 7;
  369. CardCsd_EraseBlkEn = 38;
  370. CardCsd_CSizeMultOfs1 = 39; (** V1 *)
  371. CardCsd_CSizeMultWidth1 = 3; (** V1 *)
  372. CardCsd_VddWCurrMaxOfs1 = 42; (** V1 *)
  373. CardCsd_VddWCurrMaxWidth1 = 3; (** V1 *)
  374. CardCsd_VddWCurrMinOfs1 = 45; (** V1 *)
  375. CardCsd_VddWCurrMinWidth1 = 3; (** V1 *)
  376. CardCsd_VddRCurrMaxOfs1 = 48; (** V1 *)
  377. CardCsd_VddRCurrMaxWidth1 = 3; (** V1 *)
  378. CardCsd_VddRCurrMinOfs1 = 51; (** V1 *)
  379. CardCsd_VdddRCurrMaxWidth1 = 3; (** V1 *)
  380. CardCsd_CSizeOfs1 = 54; (** V1 *)
  381. CardCsd_CSizeWidth1 = 12; (** V1 *)
  382. CardCsd_CSizeOfs2 = 40; (** V2 *)
  383. CardCsd_CSizeWidth2 = 22; (** V2 *)
  384. CardCsd_DsrImp = 68;
  385. CardCsd_ReadBlkMisalign = 69;
  386. CardCsd_WriteBlkMisalign = 70;
  387. CardCsd_ReadBlPartial = 71;
  388. CardCsd_ReadBlLenOfs = 72;
  389. CardCsd_ReadBlLenWidth = 4;
  390. CardCsd_CccOfs = 76;
  391. CardCsd_CccWidth = 12;
  392. CardCsd_TranSpeedOfs = 88;
  393. CardCsd_TranSpeedWidth = 8;
  394. CardCsd_NsacOfs = 96;
  395. CardCsd_NsacWidth = 8;
  396. CardCsd_TaacOfs = 104;
  397. CardCsd_TaacWidth = 8;
  398. CardCsd_CsdStructureOfs = 118;
  399. CardCsd_CsdStructureWidth = 2;
  400. (* SCR Register *)
  401. CardScr_CommandSupportOfs = 32;
  402. CardScr_CommandSupportWidth = 4;
  403. CardScr_SpecVXOfs = 38;
  404. CardScr_SpecVXWidth = 4;
  405. CardScr_SpecV4 = 42;
  406. CardScr_ExtendedSecurityOfs = 43;
  407. CardScr_ExtendedSecurityWidth = 4;
  408. CardScr_SpecV3 = 47;
  409. CardScr_BusWidthsOfs = 48;
  410. CardScr_BusWidthsWidth = 4;
  411. CardScr_SecurityOfs = 52;
  412. CardScr_SecurityWidth = 3;
  413. CardScr_DataStateAfterErase = 55;
  414. CardScr_SpecVersionOfs = 56;
  415. CardScr_SpecVersionWidth = 4;
  416. CardScr_StructureOfs = 60;
  417. CardScr_StructureWidth = 4;
  418. (* SCR register fields values *)
  419. CardScr_SpecVX_v5 = 1;
  420. CardScr_SpecVX_v6 = 2;
  421. (* Card categories, used in SD status card type *)
  422. CategoryRW * = 0;
  423. CategoryRO * = 1;
  424. CategoryOTP * = 2;
  425. (* Performance enhancing features, used in perfEnhance in SD status *)
  426. PerformanceCardMaintenance * = 0; (** Card supports card-initiated maintenance *)
  427. PerformanceHostMaintenance * = 1; (** Card supports host-initiated maintenance *)
  428. PerformanceCache * = 2; (** Card supports internal caching *)
  429. PerformanceQueue * =3; (** Card supports command queue *)
  430. (* Transfer options *)
  431. TxDma = TRUE; (** Use DMA for transfers on all hosts that support it *)
  432. TxBufferSize = 4096; (** Buffer size used for DMA transfers *)
  433. TxBufferAlign = 32; (** Alignment requirement on DMA buffer: here cache line size of ARM *)
  434. (* ADMA2 flags *) (*! Do not change values *)
  435. Adma2Valid = 0; (** Valid entry *)
  436. Adma2End = 1; (** Last entry *)
  437. Adma2Int = 2; (** Entry generates interrupt on completion *)
  438. Adma2Nop = {}; (** No-operation, just continue to next *)
  439. Adma2Trans = {5}; (** Transfer descriptor *)
  440. Adma2Link = {4, 5}; (** Link descriptor *)
  441. Adma2ActMask = {4, 5}; (** Mask for Nop, Trans and Link *)
  442. (* Timeout values *)
  443. TimeoutCardInit = 100; (** Timeout used in card initialization, ms *)
  444. TimeoutReadFactor = 100; (** Timeout factor on typical read time (according to CSD) *)
  445. TimeoutReadFix = 100; (** Maximal read timeout in ms. To be used unconditionally with SDHC *)
  446. TimeoutWriteFactor = 100; (** Timeout factor on typical write time (according to CSD) *)
  447. TimeoutWriteFix = 250; (** Maximal write timeout in ms. To be used unconditionally with SDHC *)
  448. TimeoutErase = 250; (** Typical timeout per erased block, ms *)
  449. DefaultTimeout = 1000; (* Default timeout for blocking, in ms *)
  450. (* Multi-threading *)
  451. Synchronize * = FALSE (*TRUE*); (** Do we need to take care of concurrency? *)
  452. (* Tracing options for debugging *)
  453. EnableTraceCmd* = FALSE;
  454. EnableTrace* = FALSE;
  455. TYPE
  456. (** Command execution procedure *)
  457. CommandProcedure * = PROCEDURE (VAR command: Command; VAR result: LONGINT): BOOLEAN;
  458. (** Data command execution procedure *)
  459. TransferProcedure * = PROCEDURE (VAR command: Command; VAR data: ARRAY OF SYSTEM.BYTE; ofs, len: LONGINT; VAR result: LONGINT): BOOLEAN;
  460. (** Procedure called to wait for interrupt. mask specifies which interrupts are expected, timeout is in ms. Returns FALSE if timeout occurred *)
  461. Blocker * = PROCEDURE {DELEGATE} (hc: HostController; mask: SET; timeout: LONGINT): BOOLEAN;
  462. (**
  463. SD Host controller descriptor.
  464. *)
  465. HostController * = POINTER TO HostControllerDesc;
  466. HostControllerDesc * = RECORD
  467. state -, (** HC state *)
  468. version -: LONGINT; (** Specifications version *)
  469. execute -: CommandProcedure; (** Method to execute commands *)
  470. transfer -: TransferProcedure; (** Method to execute data commands *)
  471. acquire *, release *: PROCEDURE {DELEGATE}; (** Procedures used for locking *)
  472. baseFrequency, (** Base hc clock frequency *)
  473. frequency, (** Bus frequency *)
  474. timeoutFrequency: HUGEINT; (** Timeout clock frequency *)
  475. lastRca: LONGINT; (** Last RCA selected by the controller. *)
  476. handle: EventHandler; (** Card event handler *)
  477. handlerParam: ANY; (** Parameter of the eventHandler *)
  478. block: Blocker; (** Procedure called to wait for interrupts *)
  479. regs-: HcRegisters; (** Memory-mapped I/O registers *)
  480. cards: Card; (** List of cards on this HC *)
  481. next: HostController; (** Linked list of controllers for interrupt handling *)
  482. desc{ALIGNED(32)}: ARRAY 32 OF HUGEINT; (** DMA descriptor *)
  483. END;
  484. (**
  485. Command record.
  486. This record type is used to describe a command and its result.
  487. To execute a command, fill in the fields 'hc', 'command', 'argument', 'responseType'.
  488. If the command uses the DAT line or is an application command, setup then necessary flags.
  489. If the command is an application command, you also need to specify the RCA for CMD55.
  490. After command execution, you can read the command response in the 'response' field. Use the
  491. 'GetR*' procedures to extract all information from this field in a convenient way.
  492. *)
  493. Command * = RECORD
  494. hc *: HostController; (** Host controller on which the command is executed *)
  495. rca *, (** Optional RCA parameter. Required only for ACMDs *)
  496. command *, (** Command number *)
  497. argument *, (** Command argument *)
  498. responseType *, (** Response type *)
  499. blockSize *, (** Block size for read, write or erase *)
  500. dataTimeout *: LONGINT; (** Timeout value used for data line *)
  501. flags *: SET; (** Command flags *)
  502. response *: ARRAY 4 OF LONGINT; (** Response *)
  503. END;
  504. (** SWITCH_FUNC returned status *)
  505. SwitchFuncStatus * = RECORD
  506. current -: LONGINT; (** Current for specified config *)
  507. functionGroups -: ARRAY 6 OF SET; (** Supported function in each group *)
  508. functionStatus -: ARRAY 6 OF LONGINT; (** Function status *)
  509. END;
  510. (** 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 *)
  511. EventHandler * = PROCEDURE {DELEGATE} (card: Card; event: LONGINT; param: ANY);
  512. (** Host controller registers *)
  513. HcRegisters * = POINTER {UNSAFE,UNTRACED} TO RECORD
  514. SDMASystemAddress * {ALIGNED(1)}: LONGINT; (** offset = 0H *)
  515. BlockSize * {ALIGNED(1)}, (** offset = 4H *)
  516. BlockCount * {ALIGNED(1)}: INTEGER; (** offset = 6H *)
  517. Argument1 * {ALIGNED(1)}: LONGINT; (** offset = 8H *)
  518. TransferMode * {ALIGNED(1)}, (** offset = 0CH *)
  519. Command * {ALIGNED(1)}: INTEGER; (** offset = 0EH *)
  520. Response * {ALIGNED(1)}: ARRAY 4 OF LONGINT; (** offset = 10H *)
  521. BufferData * {ALIGNED(1)}: LONGINT;
  522. PresentState * {ALIGNED(1)}: SET;
  523. HostControl1 * {ALIGNED(1)},
  524. PowerControl * {ALIGNED(1)},
  525. BlockGapControl * {ALIGNED(1)},
  526. WakeupControl * {ALIGNED(1)}: SHORTINT;
  527. ClockControl * {ALIGNED(1)}: INTEGER;
  528. TimeoutControl * {ALIGNED(1)},
  529. SoftwareReset * {ALIGNED(1)}: SHORTINT;
  530. InterruptStatus * {ALIGNED(1)},
  531. InterruptStatusEnable * {ALIGNED(1)},
  532. InterruptSignalEnable * {ALIGNED(1)}: SET;
  533. AutoCmdErrorStatus * {ALIGNED(1)},
  534. HostControl2 * {ALIGNED(1)}: INTEGER;
  535. Capabilities * {ALIGNED(1)}: ARRAY 2 OF SET;
  536. MaximumCurrentCapabilities * {ALIGNED(1)}: HUGEINT;
  537. ForceEventAutoCmdErrorStatus * {ALIGNED(1)},
  538. ForceEventErrorInterruptStatus * {ALIGNED(1)}: INTEGER;
  539. AdmaErrorStatus * {ALIGNED(1)}: SHORTINT;
  540. padding0 * {ALIGNED(1)}: ARRAY 3 OF SHORTINT;
  541. AdmaSystemAddress * {ALIGNED(1)}: HUGEINT;
  542. PresetValues * {ALIGNED(1)}: ARRAY 8 OF INTEGER;
  543. padding1 * {ALIGNED(1)}: ARRAY 28 OF LONGINT;
  544. SharedBusControl * {ALIGNED(1)}: LONGINT;
  545. padding2 * {ALIGNED(1)}: ARRAY 6 OF LONGINT;
  546. SlotInterruptStatus * {ALIGNED(1)},
  547. HostControllerVersion * {ALIGNED(1)}: INTEGER;
  548. END;
  549. VAR
  550. (** List of all host controllers *)
  551. hcs: HostController;
  552. (** Statistics *)
  553. NbyteRead -,
  554. NbyteWritten -,
  555. Nread -,
  556. Nwrite -: HUGEINT;
  557. Tread -,
  558. Twrite -: HUGEINT;
  559. start, stop: HUGEINT;
  560. (* ==================== Host Controller (Low-Level) Interface ==================== *)
  561. (**
  562. Create an host controller descriptor and initializes it with the given info.
  563. 'baseAddress' is the base address of the IO registers.
  564. 'extClockFreq' is an optional external clock frequency. It is used iff the host controller has no information about its clock frequency.
  565. 'handler' is the event handler and 'param' is user parameter.
  566. *)
  567. PROCEDURE InitHostController * (hc: HostController; baseAddress: ADDRESS)(*: HostController*);
  568. VAR
  569. val: LONGINT;
  570. BEGIN
  571. hc.regs := baseAddress;
  572. IF ~Reset(hc, TRUE, TRUE) THEN (*RETURN NIL*) END;
  573. hc.baseFrequency := LSH(SYSTEM.VAL(LONGINT, hc.regs.Capabilities[0] * Capabilities_BaseClockFreqSdMask), -Capabilities_BaseClockFreqSdOfs);
  574. hc.timeoutFrequency := LSH(SYSTEM.VAL(LONGINT, hc.regs.Capabilities[0] * Capabilities_TimeoutClockFrequencyMask), -Capabilities_TimeoutClockFrequencyOfs) * 1000;
  575. IF Capabilities_TimeoutClockUnit IN hc.regs.Capabilities[0] THEN hc.timeoutFrequency := hc.timeoutFrequency * 1000 END;
  576. (*SetBusClock(hc, InitialClockFrequency);
  577. SetTimeout(hc, 100);*)
  578. (* Power select 3.3V bus voltage *)
  579. hc.regs.PowerControl := SYSTEM.VAL(SHORTINT, PowerControl_SDBusVoltage_33 + {PowerControl_SDBusPower});
  580. (* Enable All Interrupts *)
  581. hc.regs.InterruptStatusEnable := Interrupt_All;
  582. hc.regs.InterruptSignalEnable := {Interrupt_Normal_CardInsertion, Interrupt_Normal_CardRemoval};
  583. hc.regs.BlockGapControl := 0;
  584. val := LONGINT(hc.regs.HostControllerVersion);
  585. hc.version := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, val) * HostControllerVersion_SpecificationMask) + 1;
  586. IF EnableTrace THEN
  587. Log.String("[SD] New Host Controller v");
  588. Log.Int(hc.version, 0);
  589. Log.String(" at ");
  590. Log.Address(baseAddress);
  591. Log.Ln;
  592. PrintCapabilities(hc);
  593. END;
  594. IF Synchronize THEN SdEnvironment.GetLock(hc.acquire, hc.release) END;
  595. (* Select method according to DMA support *)
  596. IF TxDma THEN
  597. IF (Capabilities_ADMA2 IN hc.regs.Capabilities[0]) THEN
  598. hc.transfer := ExecuteAdmaCommand;
  599. hc.regs.HostControl1 := SYSTEM.VAL(SHORTINT, SYSTEM.VAL(SET, LONGINT(hc.regs.HostControl1)) + HostControl1_DmaSelect_32Adma);
  600. ELSE
  601. (*! ADMA1 and SDMA are not implemented yet *)
  602. hc.transfer := ExecuteDataCommand
  603. END
  604. ELSE
  605. hc.transfer := ExecuteDataCommand
  606. END;
  607. hc.execute := ExecuteCommand;
  608. hc.block := SpinBlock; (* Use spin block by default *)
  609. IF (hc.baseFrequency = 0) OR (hc.timeoutFrequency = 0) THEN
  610. hc.state := HcConfiguring
  611. ELSE
  612. hc.state := HcOperational
  613. END;
  614. (* If there is a card already, initialize it *)
  615. (*IF (PresentState_CardInserted IN hc.regs.PresentState) & (PresentState_CardStateStable IN hc.regs.PresentState) THEN
  616. NEW(hc.cards);
  617. IF InitCard(hc, hc.cards, result) & (hc.handle # NIL) THEN
  618. hc.handle(hc.cards, OnInitialization, hc.handlerParam)
  619. ELSIF hc.handle # NIL THEN
  620. Log.String("[SD] Could not initialize inserted card: error ");
  621. Log.Int(result, 0);
  622. Log.Ln;
  623. END
  624. END;*)
  625. hc.next := hcs;
  626. hcs := hc;
  627. END InitHostController;
  628. (** Set external clock for a host controller. Host state must be HcConfiguring. bus is the SD bus clock frequency, timeout is the timeout clock frequency. *)
  629. PROCEDURE SetExternalClock * (hc: HostController; bus, timeout: HUGEINT; VAR result: LONGINT): BOOLEAN;
  630. BEGIN
  631. IF hc.state # HcConfiguring THEN
  632. result := ErrorInvalidParameters;
  633. RETURN FALSE
  634. END;
  635. hc.baseFrequency := bus;
  636. hc.timeoutFrequency := timeout;
  637. hc.state := HcOperational;
  638. RETURN TRUE
  639. END SetExternalClock;
  640. (** Set an event handler for a host controller *)
  641. PROCEDURE SetEventHandler * (hc: HostController; handler: EventHandler; param: ANY);
  642. VAR
  643. result: LONGINT;
  644. BEGIN
  645. hc.handle := handler;
  646. hc.handlerParam := param;
  647. (* Handle events if necessary *)
  648. IF (PresentState_CardInserted IN hc.regs.PresentState) & (PresentState_CardStateStable IN hc.regs.PresentState) THEN
  649. NEW(hc.cards);
  650. IF InitCard(hc, hc.cards, result) & (hc.handle # NIL) THEN
  651. hc.handle(hc.cards, OnInitialization, hc.handlerParam)
  652. ELSIF hc.handle # NIL THEN
  653. Log.String("[SD] Could not initialize inserted card: error ");
  654. Log.Int(result, 0);
  655. Log.Ln;
  656. END
  657. END;
  658. END SetEventHandler;
  659. (** Change the wait for interrupt method *)
  660. PROCEDURE SetBlocker * (hc: HostController; blocker: Blocker);
  661. BEGIN
  662. hc.block := blocker
  663. END SetBlocker;
  664. (** Turns the busy LED on or off *)
  665. PROCEDURE SetLedState * (hc: HostController; on: BOOLEAN);
  666. VAR
  667. reg: SET;
  668. BEGIN
  669. reg := SYSTEM.VAL(SET, hc.regs.HostControl1);
  670. IF on THEN
  671. INCL(reg, HostControl1_LedControl)
  672. ELSE
  673. EXCL(reg, HostControl1_LedControl)
  674. END;
  675. hc.regs.HostControl1 := SYSTEM.VAL(SHORTINT, reg)
  676. END SetLedState;
  677. (** Get the state of the busy LED *)
  678. PROCEDURE GetLedState * (hc: HostController): BOOLEAN;
  679. BEGIN
  680. RETURN HostControl1_LedControl IN SYSTEM.VAL(SET, hc.regs.HostControl1)
  681. END GetLedState;
  682. (**
  683. Execute the command 'command', without data transfer. If you need data transfer, use 'ExecuteDataCommand'.
  684. Performs all necessary steps for executing a command:
  685. o Runs CMD55 if command is an application command
  686. o Execute the command
  687. o Wait for response
  688. *)
  689. PROCEDURE ExecuteCommand (VAR command: Command; VAR result: LONGINT): BOOLEAN;
  690. VAR
  691. status, r1: SET;
  692. BEGIN
  693. IF Synchronize THEN command.hc.acquire END;
  694. result := ErrorNone;
  695. (* Check Parameters *)
  696. IF {FlagData, FlagRead, FlagAutoCmd12, FlagAutoCmd23, FlagMultipleBlockTx, FlagCountBlocks} * command.flags # {} THEN
  697. result := ErrorInvalidParameters;
  698. IF Synchronize THEN command.hc.release END;
  699. RETURN FALSE
  700. END;
  701. IF (FlagApplicationCmd IN command.flags) THEN
  702. IF ~StartCommand(command.hc, CMD_APP_CMD, LSH(command.rca, 16), ResponseR1, FlagRead IN command.flags, FALSE, FALSE, FALSE, status, result) THEN
  703. IF Synchronize THEN command.hc.release END;
  704. RETURN FALSE
  705. END;
  706. r1 := GetR1(command);
  707. IF EnableTrace THEN PrintCardStatus(r1) END;
  708. IF ~(FlagIgnoreIllegalCmd IN command.flags) & (CardStatus_Error IN r1) THEN
  709. result := ErrorCard;
  710. IF Synchronize THEN command.hc.release END;
  711. RETURN FALSE
  712. END
  713. END;
  714. IF ~StartCommand(
  715. command.hc, command.command, command.argument, command.responseType, FlagRead IN command.flags, FALSE,
  716. FALSE (*command.responseType = ResponseR1b*), FlagAbort IN command.flags, status, result) THEN
  717. IF Synchronize THEN command.hc.release END;
  718. RETURN FALSE
  719. END;
  720. GetResponse(command.hc, command.responseType, command.response);
  721. IF command.command = CMD_SELECT_DESELECT_CARD THEN
  722. command.hc.lastRca := LSH(command.argument, -16)
  723. ELSIF command.command = CMD_GO_IDLE_STATE THEN
  724. command.hc.lastRca := 0
  725. END;
  726. IF Synchronize THEN command.hc.release END;
  727. RETURN TRUE
  728. END ExecuteCommand;
  729. (**
  730. Execute command with data transfer using CPU.
  731. Data is read from/written to [data[ofs], data[ofs + len]).
  732. *)
  733. PROCEDURE ExecuteDataCommand (VAR command: Command; VAR data: ARRAY OF SYSTEM.BYTE; ofs, len: LONGINT; VAR result: LONGINT): BOOLEAN;
  734. TYPE
  735. DataBytes = ARRAY 4 OF CHAR;
  736. VAR
  737. tmp: DataBytes;
  738. i, stepLen: LONGINT;
  739. hc: HostController;
  740. r1, status, mask: SET;
  741. BEGIN
  742. ASSERT(ofs + len <= LEN(data), 7);
  743. result := ErrorNone;
  744. IF ~(FlagData IN command.flags) THEN
  745. result := ErrorInvalidParameters;
  746. RETURN FALSE
  747. END;
  748. hc := command.hc;
  749. IF Synchronize THEN hc.acquire END;
  750. (* Set timeout *)
  751. SetTimeout(hc, command.dataTimeout);
  752. (*IF (*~Reset(hc, TRUE, FALSE) OR*) ~Reset(hc, FALSE, TRUE) THEN
  753. result := ErrorCard;
  754. IF Synchronize THEN hc.release END;
  755. RETURN FALSE
  756. END;*)
  757. IF (FlagApplicationCmd IN command.flags) THEN
  758. IF ~StartCommand(hc, CMD_APP_CMD, LSH(command.rca, 16), ResponseR1, FlagRead IN command.flags, FALSE, FALSE, FALSE, status, result) THEN
  759. IF Synchronize THEN hc.release END;
  760. RETURN FALSE
  761. END;
  762. r1 := SYSTEM.VAL(SET, command.response[0]);
  763. IF CardStatus_Error IN r1 THEN
  764. IF Synchronize THEN hc.release END;
  765. RETURN FALSE
  766. END;
  767. IF EnableTrace THEN
  768. Log.String("[SD] CMD55 Status:");
  769. Log.Ln;
  770. PrintCardStatus(r1)
  771. END
  772. END;
  773. (* 1 *)
  774. IF ~(FlagApplicationCmd IN command.flags) &
  775. ((command.command = CMD_READ_SINGLE_BLOCK) OR (command.command = CMD_READ_MULTIPLE_BLOCK) OR
  776. (command.command = CMD_WRITE_BLOCK) OR (command.command = CMD_WRITE_MULTIPLE_BLOCK) OR
  777. (command.command = 53)(* SDIO Command *)) THEN
  778. IF len <= BlockSize THEN
  779. hc.regs.BlockSize := INTEGER(len);
  780. hc.regs.BlockCount := 1
  781. ELSE
  782. hc.regs.BlockSize := BlockSize;
  783. hc.regs.BlockCount := INTEGER(len DIV BlockSize)
  784. END;
  785. IF EnableTrace THEN
  786. Log.String("[SD] ");
  787. IF FlagRead IN command.flags THEN Log.String("Read")
  788. ELSE Log.String("Write") END;
  789. Log.String(" parameters:"); Log.Ln;
  790. Log.String("[SD] Block Size = "); Log.Int(hc.regs.BlockSize, 0); Log.Ln;
  791. Log.String("[SD] Block Count = "); Log.Int(hc.regs.BlockCount, 0); Log.Ln;
  792. Log.String("[SD] CMD"); Log.Int(command.command, 0); Log.Ln;
  793. Log.String("[SD] Argument = "); Log.Address(command.argument); Log.Ln
  794. END
  795. END;
  796. (* 3 - 8 *)
  797. IF FlagRead IN command.flags THEN
  798. (*REPEAT UNTIL (Interrupt_Normal_BufferReadReady IN hc.regs.InterruptStatus) OR (Interrupt_Normal_ErrorInterrupt IN hc.regs.InterruptStatus)*)
  799. mask := {Interrupt_Normal_BufferReadReady, Interrupt_Normal_ErrorInterrupt}
  800. ELSE
  801. (*REPEAT UNTIL (Interrupt_Normal_BufferWriteReady IN hc.regs.InterruptStatus) OR (Interrupt_Normal_ErrorInterrupt IN hc.regs.InterruptStatus)*)
  802. mask := {Interrupt_Normal_BufferWriteReady, Interrupt_Normal_ErrorInterrupt}
  803. END;
  804. IF ~StartCommand(hc, command.command, command.argument, ResponseR1, FlagRead IN command.flags, FALSE, TRUE, FALSE, status, result) THEN RETURN FALSE END;
  805. r1 := SYSTEM.VAL(SET, command.response[0]);
  806. IF CardStatus_Error IN r1 THEN
  807. IF Synchronize THEN hc.release END;
  808. RETURN FALSE
  809. END;
  810. IF EnableTrace THEN PrintCardStatus(r1) END;
  811. WHILE len > 0 DO
  812. (* 14 *)
  813. IF ~hc.block(hc, mask, command.dataTimeout * 1000) THEN
  814. Log.String("[SD] Error: interrupt timeout");
  815. Log.Ln;
  816. RETURN FALSE
  817. END;
  818. status := hc.regs.InterruptStatus;
  819. IF Interrupt_Normal_ErrorInterrupt IN hc.regs.InterruptStatus THEN
  820. IF ErrorRecovery(hc, result, status) THEN END;
  821. IF Interrupt_Error_DataTimeout IN status THEN
  822. result := ErrorDatTimeout
  823. ELSIF Interrupt_Error_DataCrc IN status THEN
  824. result := ErrorDatCrc
  825. ELSIF Interrupt_Error_DataEndBit IN status THEN
  826. result := ErrorCard
  827. END;
  828. IF Synchronize THEN hc.release END;
  829. RETURN FALSE
  830. END;
  831. (* 15 *)
  832. (*INCL(hc.regs.InterruptStatus, Interrupt_Normal_BufferReadReady);*)
  833. hc.regs.InterruptStatus := {Interrupt_Normal_BufferReadReady};
  834. (* 16 *)
  835. stepLen := MIN(BlockSize, len);
  836. IF FlagRead IN command.flags THEN
  837. FOR i := 0 TO stepLen - 1 BY 4 DO
  838. SYSTEM.PUT32(ADDRESSOF(data[ofs + i]), hc.regs.BufferData);
  839. (*SYSTEM.VAL(LONGINT, tmp) := hc.regs.BufferData;
  840. SYSTEM.VAL(DataBytes, data[ofs + i]) := tmp*)
  841. END
  842. ELSE
  843. FOR i := 0 TO stepLen - 1 BY 4 DO
  844. tmp := SYSTEM.VAL(DataBytes, data[ofs + i]);
  845. hc.regs.BufferData := SYSTEM.VAL(LONGINT, tmp);
  846. END
  847. END;
  848. (* 17 *)
  849. INC(ofs, stepLen);
  850. DEC(len, stepLen)
  851. END;
  852. (* 18 -> Not infinite block *)
  853. (*REPEAT UNTIL Interrupt_Normal_TransferComplete IN hc.regs.InterruptStatus;*)
  854. IF ~hc.block(hc, {Interrupt_Normal_TransferComplete}, command.dataTimeout * 1000) THEN
  855. Log.String("[SD] Error: timeout interrupt");
  856. Log.Ln;
  857. RETURN FALSE
  858. END;
  859. (* 19 *)
  860. (*INCL(hc.regs.InterruptStatus, Interrupt_Normal_TransferComplete);*)
  861. hc.regs.InterruptStatus := {Interrupt_Normal_TransferComplete};
  862. (*DEC(hc.regs.ClockControl, LSH(1, ClockControl_SdClockEnable));
  863. hc.regs.SoftwareReset := SYSTEM.VAL(SHORTINT, {SoftwareResetCmd, SoftwareResetDat});
  864. REPEAT UNTIL hc.regs.SoftwareReset = 0;
  865. INC(hc.regs.ClockControl, LSH(1, ClockControl_SdClockEnable));*)
  866. IF Synchronize THEN hc.release END;
  867. RETURN TRUE (*Reset(hc, TRUE, FALSE) & Reset(hc, FALSE, TRUE)*)
  868. END ExecuteDataCommand;
  869. (**
  870. Execute Command with data transfers using ADMA.
  871. command: ADMA command
  872. data, ofs, len: Buffer
  873. result: error code
  874. *)
  875. PROCEDURE ExecuteAdmaCommand (VAR command: Command; VAR data: ARRAY OF SYSTEM.BYTE; ofs, len: LONGINT; VAR result: LONGINT): BOOLEAN;
  876. VAR
  877. tt: SdEnvironment.Time;
  878. hc: HostController;
  879. r1, status, flags: SET;
  880. address, a: ADDRESS;
  881. blocks, blockSize, desc, txlen, l, tx: LONGINT;
  882. padd: BOOLEAN; (* Padd transfer to next block length? *)
  883. PROCEDURE WriteAdma2Desc (address: ADDRESS; len: LONGINT; flags: SET): HUGEINT;
  884. BEGIN
  885. IF EnableTrace THEN
  886. Log.String("[SD] ADMA2 Entry; address = "); Log.Hex(address, -8); Log.String(", size = "); Log.Int(len, 0);
  887. Log.String(", flags = ");
  888. IF flags * Adma2ActMask = Adma2Nop THEN Log.String("NOP ")
  889. ELSIF flags * Adma2ActMask = Adma2Trans THEN Log.String("TRANS ")
  890. ELSIF flags * Adma2ActMask = Adma2Link THEN Log.String("LINK ")
  891. END;
  892. IF Adma2Valid IN flags THEN Log.String("VALID ") END;
  893. IF Adma2End IN flags THEN Log.String("END ") END;
  894. IF Adma2Int IN flags THEN Log.String("INT ") END;
  895. Log.Ln
  896. END;
  897. ASSERT(address MOD 4 = 0);
  898. ASSERT((len > 0) OR (flags * Adma2ActMask # Adma2Trans));
  899. RETURN LSH(HUGEINT(address), 32) + LSH(len MOD 65536, 16) + SYSTEM.VAL(LONGINT, flags)
  900. END WriteAdma2Desc;
  901. BEGIN
  902. result := ErrorNone;
  903. hc := command.hc;
  904. IF Synchronize THEN hc.acquire END;
  905. (* Setup descriptors *)
  906. address := ADDRESSOF(data[ofs]);
  907. (*IF ~(FlagRead IN command.flags) THEN*) SdEnvironment.FlushDCacheRange(address, len); (*END;*)
  908. txlen := len;
  909. flags := Adma2Trans + {Adma2Valid};
  910. padd := FALSE; (*(len > BlockSize) & (len MOD BlockSize # 0);*)
  911. l := len;
  912. a := address;
  913. WHILE l > 0 DO
  914. IF ~padd & (l <= 65536) THEN flags := flags + {Adma2End, Adma2Int} END;
  915. tx := MIN(l, 65536);
  916. hc.desc[desc] := WriteAdma2Desc(a, tx, flags);
  917. DEC(l, tx);
  918. INC(a, tx);
  919. INC(desc);
  920. END;
  921. (*hc.desc[desc] := WriteAdma2Desc(0, 0, {Adma2Valid, Adma2End, Adma2Int} + Adma2Nop); INC(desc);*)
  922. SdEnvironment.FlushDCacheRange(ADDRESSOF(hc.desc[0]), (desc + 1) * 8);
  923. (* Reset command and data lines *)
  924. IF (*~Reset(hc, TRUE, FALSE) OR*) ~Reset(hc, FALSE, TRUE) THEN
  925. result := ErrorCard;
  926. IF Synchronize THEN hc.release END;
  927. RETURN FALSE
  928. END;
  929. (* 1 *)
  930. hc.regs.AdmaSystemAddress := ADDRESSOF(hc.desc[0]);
  931. IF (FlagApplicationCmd IN command.flags) THEN
  932. IF ~StartCommand(command.hc, CMD_APP_CMD, LSH(command.rca, 16), ResponseR1, FlagRead IN command.flags, FALSE, FALSE, FALSE, status, result) THEN
  933. IF Synchronize THEN hc.release END;
  934. RETURN FALSE
  935. END;
  936. r1 := SYSTEM.VAL(SET, command.response[0]);
  937. IF EnableTrace THEN
  938. Log.String("[SD] CMD55 Status:");
  939. Log.Ln;
  940. PrintCardStatus(r1)
  941. END;
  942. IF CardStatus_Error IN r1 THEN
  943. result := ErrorCard;
  944. IF Synchronize THEN hc.release END;
  945. RETURN FALSE
  946. END
  947. END;
  948. (* 2-3 *)
  949. IF command.blockSize = 0 THEN
  950. blockSize := BlockSize
  951. ELSE
  952. blockSize := command.blockSize
  953. END;
  954. IF FlagData IN command.flags THEN
  955. IF txlen <= blockSize THEN
  956. hc.regs.BlockSize := INTEGER(txlen);
  957. hc.regs.BlockCount := 1;
  958. blocks := 1
  959. ELSE
  960. hc.regs.BlockSize := INTEGER(blockSize);
  961. blocks := txlen DIV blockSize;
  962. hc.regs.BlockCount := INTEGER(blocks)
  963. END;
  964. (* Set data timeout *)
  965. ASSERT(command.dataTimeout > 0);
  966. SetTimeout(hc, command.dataTimeout);
  967. IF EnableTrace THEN
  968. Log.String("[SD] ");
  969. IF FlagRead IN command.flags THEN Log.String("Read")
  970. ELSE Log.String("Write") END;
  971. Log.String(" parameters:"); Log.Ln;
  972. Log.String("[SD] Block Size = "); Log.Int(hc.regs.BlockSize, 0); Log.Ln;
  973. Log.String("[SD] Block Count = "); Log.Int(hc.regs.BlockCount, 0); Log.Ln;
  974. Log.String("[SD] CMD"); Log.Int(command.command, 0); Log.Ln;
  975. Log.String("[SD] Argument = "); Log.Address(command.argument); Log.Ln
  976. END
  977. END;
  978. status := hc.regs.InterruptStatus;
  979. ASSERT({Interrupt_Normal_TransferComplete, Interrupt_Normal_ErrorInterrupt} * status = {});
  980. (*!start := SdEnvironment.GetTimeCounter();*)
  981. IF ~StartCommand(command.hc, command.command, command.argument, command.responseType, FlagRead IN command.flags, TRUE, TRUE, FALSE, status, result) THEN
  982. IF Synchronize THEN hc.release END;
  983. RETURN FALSE
  984. END;
  985. r1 := SYSTEM.VAL(SET, command.response[0]);
  986. IF CardStatus_Error IN r1 THEN
  987. result := ErrorCard;
  988. IF Synchronize THEN hc.release END;
  989. RETURN FALSE
  990. END;
  991. IF EnableTrace THEN PrintCardStatus(r1) END;
  992. (*t := SdEnvironment.GetTimeCounter();
  993. tt := t + SdEnvironment.FromMilli(1000);*)
  994. (*WHILE ({Interrupt_Normal_TransferComplete, Interrupt_Normal_ErrorInterrupt, Interrupt_Error_Adma} * status = {}) (*& (SdEnvironment.GetTimeCounter() <= tt)*) DO
  995. status := hc.regs.InterruptStatus
  996. END;*)
  997. (*IF SdEnvironment.GetTimeCounter() > tt(*{Interrupt_Normal_TransferComplete, Interrupt_Normal_ErrorInterrupt} * status = {}*) THEN*)
  998. IF ~hc.block(hc, {Interrupt_Normal_TransferComplete, Interrupt_Normal_ErrorInterrupt}, command.dataTimeout * 1000) THEN
  999. Log.String("[SD] Error: timeout has expired!"); Log.Ln;
  1000. PrintHcRegisters(hc.regs);
  1001. IF Synchronize THEN hc.release END;
  1002. HALT(512);
  1003. RETURN FALSE;
  1004. END;
  1005. (*!stop := SdEnvironment.GetTimeCounter();*)
  1006. status := hc.regs.InterruptStatus;
  1007. IF Interrupt_Normal_ErrorInterrupt IN status THEN
  1008. IF ErrorRecovery(hc, result, status) THEN END;
  1009. IF Interrupt_Error_DataTimeout IN status THEN
  1010. result := ErrorDatTimeout;
  1011. IF ~Reset(hc, FALSE, TRUE) THEN END
  1012. ELSIF Interrupt_Error_DataCrc IN status THEN
  1013. result := ErrorDatCrc
  1014. ELSIF Interrupt_Error_DataEndBit IN status THEN
  1015. result := ErrorCard
  1016. ELSIF Interrupt_Error_Adma IN status THEN
  1017. HALT(182)
  1018. END;
  1019. IF Synchronize THEN hc.release END;
  1020. RETURN FALSE
  1021. END;
  1022. hc.regs.InterruptStatus := status;
  1023. IF FlagRead IN command.flags THEN
  1024. SdEnvironment.InvalidateDCacheRange(address, len)
  1025. END;
  1026. (*!IF FlagRead IN command.flags THEN
  1027. INC(Tread, stop - start);
  1028. ELSE
  1029. INC(Twrite, stop - start);
  1030. END;*)
  1031. IF Synchronize THEN hc.release END;
  1032. RETURN TRUE
  1033. END ExecuteAdmaCommand;
  1034. (** Get the response registers in 'response' *)
  1035. PROCEDURE GetResponse (hc: HostController; responseType: LONGINT; VAR response: ARRAY 4 OF LONGINT);
  1036. BEGIN
  1037. response := hc.regs.Response
  1038. END GetResponse;
  1039. (** Issue an SD Card Transaction. [Simplified specs. 3.7.1.1 pp. 106-108] *)
  1040. PROCEDURE StartCommand (hc: HostController; cmd, argument, responseType: LONGINT; read, dma, busy, abort: BOOLEAN; VAR status: SET; VAR result: LONGINT): BOOLEAN;
  1041. VAR
  1042. t: HUGEINT;
  1043. reg: LONGINT;
  1044. flags, txFlags: SET;
  1045. BEGIN
  1046. IF EnableTraceCmd THEN
  1047. Log.String("[SD] Sending Command CMD"); Log.Int(cmd, 0); Log.Ln;
  1048. Log.String("[SD] Argument: "); Log.Hex(argument, -8); Log.Ln
  1049. END;
  1050. (* 1 *)
  1051. t := SdEnvironment.GetTimeCounter() + SdEnvironment.FromMilli(1000);
  1052. WHILE (PresentState_CommandInhibitCmd IN hc.regs.PresentState) & (t > SdEnvironment.GetTimeCounter()) DO END;
  1053. IF t < SdEnvironment.GetTimeCounter() THEN
  1054. Log.String("[SD] Timeout error in StartCommand (1)");
  1055. Log.Ln;
  1056. PrintHcRegisters(hc);
  1057. RETURN FALSE
  1058. END;
  1059. (* 2 *)
  1060. IF busy THEN
  1061. (* 3 *)
  1062. IF ~abort THEN
  1063. (* 4 *)
  1064. t := SdEnvironment.GetTimeCounter() + SdEnvironment.FromMilli(1000);
  1065. WHILE (PresentState_CommandInhibitDat IN hc.regs.PresentState) & (t > SdEnvironment.GetTimeCounter()) DO END;
  1066. IF t < SdEnvironment.GetTimeCounter() THEN
  1067. Log.String("[SD] Timeout error in StartCommand (2)");
  1068. Log.Ln;
  1069. PrintHcRegisters(hc);
  1070. RETURN FALSE
  1071. END;
  1072. END
  1073. END;
  1074. (* 5 *)
  1075. hc.regs.Argument1 := argument;
  1076. (* 6 *)
  1077. (* The response type determines the response-type and CRC/Index checks enabling *)
  1078. CASE responseType OF
  1079. ResponseNone:
  1080. reg := Command_ResponseType_None;
  1081. IF EnableTraceCmd THEN
  1082. Log.String("[SD] No Response Expected");
  1083. Log.Ln
  1084. END
  1085. |ResponseR1, ResponseR5, ResponseR6, ResponseR7:
  1086. reg := Command_ResponseType_48b;
  1087. flags := {Command_CrcCheckEnable, Command_IndexCheckEnable};
  1088. IF EnableTraceCmd THEN
  1089. Log.String("[SD] 48 Bit Response"); Log.Ln;
  1090. Log.String("[SD] Enabling CRC Check and Index Check"); Log.Ln
  1091. END
  1092. |ResponseR3, ResponseR4:
  1093. reg := Command_ResponseType_48b;
  1094. IF EnableTraceCmd THEN Log.String("[SD] 48 Bit Response"); Log.Ln END
  1095. |ResponseR1b, ResponseR5b:
  1096. reg := Command_ResponseType_48bBusy;
  1097. flags := {Command_CrcCheckEnable, Command_IndexCheckEnable};
  1098. IF EnableTraceCmd THEN
  1099. Log.String("[SD] 48 Bit Response"); Log.Ln;
  1100. Log.String("[SD] Enabling Index Check"); Log.Ln
  1101. END
  1102. |ResponseR2:
  1103. reg := Command_ResponseType_136b;
  1104. flags := {Command_CrcCheckEnable};
  1105. IF EnableTraceCmd THEN
  1106. Log.String("[SD] 136 Bit Response"); Log.Ln;
  1107. Log.String("[SD] Enabling Command CRC Check"); Log.Ln
  1108. END
  1109. END;
  1110. (* Command determines data-enable *)
  1111. IF busy THEN
  1112. INCL(flags, Command_DataPresent);
  1113. IF EnableTraceCmd THEN Log.String("[SD] Using DAT Line"); Log.Ln END;
  1114. txFlags := {};
  1115. IF (*(cmd = CMD_READ_SINGLE_BLOCK) OR (cmd = CMD_READ_MULTIPLE_BLOCK) OR (cmd = ACMD_SEND_SCR)*) read THEN
  1116. IF EnableTraceCmd THEN Log.String("[SD] Data Read"); Log.Ln END;
  1117. INCL(txFlags, TransferMode_DataTxDirection)
  1118. ELSIF EnableTraceCmd THEN
  1119. Log.String("[SD] Data Write");
  1120. Log.Ln
  1121. END;
  1122. IF (cmd = CMD_READ_MULTIPLE_BLOCK) OR (cmd = CMD_WRITE_MULTIPLE_BLOCK) THEN
  1123. IF EnableTraceCmd THEN Log.String("[SD] Multiple blocks: using Auto CMD12 & activating block count"); Log.Ln END;
  1124. txFlags := txFlags + TransferMode_AutoCmd_Cmd12 + {TransferMode_MultipleBlocks, TransferMode_BlockCountEnable}
  1125. ELSIF EnableTraceCmd THEN
  1126. Log.String("[SD] Single Block");
  1127. Log.Ln
  1128. END;
  1129. IF dma THEN INCL(txFlags, TransferMode_DmaEnable) END;
  1130. hc.regs.TransferMode := SYSTEM.VAL(INTEGER, txFlags)
  1131. END;
  1132. hc.regs.Command := SYSTEM.VAL(INTEGER, SYSTEM.VAL(SET, reg + LSH(cmd, Command_CommandIndexOffset)) + flags);
  1133. (* 7 *)
  1134. RETURN WaitForCompletion(hc, ~abort, status, result)
  1135. (* Steps 7, 8 and 9 of WaitForCompletion have to be done by caller *)
  1136. END StartCommand;
  1137. (**
  1138. Perform error recovery as specified by the triggered error interrupts.
  1139. Returns an error code (result) and the interrupt status register before recovery (status)
  1140. *)
  1141. PROCEDURE ErrorRecovery (hc: HostController; VAR result: LONGINT; VAR status: SET): BOOLEAN;
  1142. BEGIN
  1143. (* 1 is done *)
  1144. status := hc.regs.InterruptStatus;
  1145. hc.regs.InterruptStatusEnable := {0 .. 14};
  1146. EXCL(hc.regs.InterruptStatusEnable, Interrupt_Normal_ErrorInterrupt);
  1147. EXCL(hc.regs.InterruptStatusEnable, Interrupt_Normal_ErrorInterrupt);
  1148. EXCL(hc.regs.InterruptStatusEnable, Interrupt_Normal_ErrorInterrupt);
  1149. (* 2 *)
  1150. IF (Interrupt_Error_CommandTimeout IN status) OR (Interrupt_Error_CommandCrc IN status) OR (Interrupt_Error_CommandEndBit IN status)
  1151. OR (Interrupt_Error_CommandIndex IN status) THEN
  1152. (* 3 & 4 *)
  1153. IF ~Reset(hc, TRUE, FALSE) THEN
  1154. result := ErrorUnrecoverable;
  1155. RETURN FALSE
  1156. END
  1157. END;
  1158. (* 5 *)
  1159. IF Interrupt_Error_DataTimeout IN status THEN
  1160. Log.String("[SD] Got data timeout error"); Log.Ln
  1161. END;
  1162. IF (Interrupt_Error_DataTimeout IN status) OR (Interrupt_Error_DataCrc IN status) OR (Interrupt_Error_DataEndBit IN status) THEN
  1163. (* 6 & 7 *)
  1164. IF ~Reset(hc, FALSE, TRUE) THEN
  1165. result := ErrorUnrecoverable;
  1166. RETURN FALSE
  1167. END
  1168. END;
  1169. (* 8 & 9 *)
  1170. hc.regs.InterruptStatus := status;
  1171. (* 10 & 11 *)
  1172. (*IF ~Command(hc, CMD_STOP_TRANSMISSION, 0, ResponseR1b, FALSE, TRUE, result) THEN
  1173. (* 12 *)
  1174. IF (Interrupt_Error_CommandTimeout IN status) OR (Interrupt_Error_CommandCrc IN status) OR (Interrupt_Error_CommandEndBit IN status)
  1175. OR (Interrupt_Error_CommandIndex IN status) THEN
  1176. TRACE('CMD12 CMD LINE ERROR');
  1177. result := ErrorUnrecoverable;
  1178. RETURN FALSE
  1179. END;
  1180. (* 13 *)
  1181. IF ~WaitForTransfer(hc, result) THEN
  1182. result := ErrorUnrecoverable;
  1183. RETURN FALSE
  1184. END;
  1185. TRACE(hc.regs.BufferData);
  1186. END;
  1187. (* 15 *)
  1188. IF hc.regs.PresentState * PresentState_DatLineSignalLevelMask # PresentState_DatLineSignalLevelMask THEN
  1189. TRACE('CMD12 DAT LINE ERROR');
  1190. result := ErrorUnrecoverable;
  1191. RETURN FALSE
  1192. END;*)
  1193. hc.regs.InterruptStatusEnable := {0 .. 31};
  1194. INCL(hc.regs.InterruptStatusEnable, Interrupt_Normal_ErrorInterrupt);
  1195. result := ErrorNone;
  1196. RETURN TRUE
  1197. END ErrorRecovery;
  1198. (** Wait for completion of an SD command [Simplified specs. 3.7.1.2 pp. 109-110 *)
  1199. PROCEDURE WaitForCompletion (hc: HostController; tryRecover: BOOLEAN; VAR status: SET; VAR result: LONGINT): BOOLEAN;
  1200. BEGIN
  1201. result := ErrorNone;
  1202. (* 1 *)
  1203. IF ~hc.block(hc, {Interrupt_Normal_CommandComplete, Interrupt_Normal_ErrorInterrupt}, DefaultTimeout) THEN
  1204. Log.String("[SD] Timeout while waiting for completion");
  1205. Log.Ln;
  1206. PrintHcRegisters(hc);
  1207. RETURN FALSE
  1208. END;
  1209. status := hc.regs.InterruptStatus;
  1210. IF Interrupt_Normal_ErrorInterrupt IN status THEN
  1211. IF ~tryRecover THEN
  1212. hc.regs.InterruptStatus := status;
  1213. result := ErrorUnrecoverable;
  1214. RETURN Reset(hc, TRUE, FALSE) & Reset(hc, FALSE, TRUE)
  1215. END;
  1216. IF ~ErrorRecovery(hc, result, status) THEN RETURN FALSE END;
  1217. IF Interrupt_Error_CommandTimeout IN status THEN
  1218. IF EnableTraceCmd THEN Log.String("[SD] Timeout in command"); Log.Ln END;
  1219. result := ErrorCmdTimeout;
  1220. IF ~Reset(hc, TRUE, FALSE) THEN END;
  1221. ELSIF Interrupt_Error_CommandCrc IN status THEN
  1222. result := ErrorCmdCrc;
  1223. ELSE
  1224. result := ErrorCard;
  1225. END;
  1226. RETURN FALSE
  1227. END;
  1228. (* 2 *)
  1229. hc.regs.InterruptStatus := {Interrupt_Normal_CommandComplete};
  1230. IF EnableTraceCmd THEN Log.String("[SD] Command successful"); Log.Ln END;
  1231. RETURN TRUE
  1232. END WaitForCompletion;
  1233. (** Wait for transfer complete interrupt *)
  1234. PROCEDURE WaitForTransfer (hc: HostController; VAR result: LONGINT): BOOLEAN;
  1235. VAR
  1236. status: SET;
  1237. BEGIN
  1238. (* 5 *)
  1239. IF ~hc.block(hc, {Interrupt_Normal_TransferComplete, Interrupt_Normal_ErrorInterrupt}, DefaultTimeout) THEN
  1240. Log.String("[SD] Timeout failed in WaitForTransfer");
  1241. RETURN FALSE;
  1242. END;
  1243. (*REPEAT UNTIL (Interrupt_Normal_TransferComplete IN hc.regs.InterruptStatus) OR (Interrupt_Normal_ErrorInterrupt IN hc.regs.InterruptStatus);*)
  1244. status := hc.regs.InterruptStatus;
  1245. IF Interrupt_Normal_ErrorInterrupt IN hc.regs.InterruptStatus THEN
  1246. IF ~ErrorRecovery(hc, result, status) THEN RETURN FALSE END;
  1247. result := ErrorCard;
  1248. RETURN FALSE
  1249. END;
  1250. (* 6 *)
  1251. (*INCL(hc.regs.InterruptStatus, Interrupt_Normal_TransferComplete)*)
  1252. hc.regs.InterruptStatus := {Interrupt_Normal_TransferComplete}
  1253. END WaitForTransfer;
  1254. PROCEDURE SpinBlock (hc: HostController; mask: SET; timeout: LONGINT): BOOLEAN;
  1255. VAR
  1256. deadline: SdEnvironment.Time;
  1257. BEGIN
  1258. deadline := SdEnvironment.GetTimeCounter() + SdEnvironment.FromMilli(timeout);
  1259. REPEAT UNTIL (mask * hc.regs.InterruptStatus # {}) OR (SdEnvironment.GetTimeCounter() > deadline);
  1260. RETURN mask * hc.regs.InterruptStatus # {}
  1261. END SpinBlock;
  1262. (** Sends CMD7 if necessary to select the given card *)
  1263. PROCEDURE SelectCard * (hc: HostController; card: LONGINT; VAR result: LONGINT): BOOLEAN;
  1264. VAR
  1265. command: Command;
  1266. status: SET;
  1267. BEGIN
  1268. result := ErrorNone;
  1269. IF hc.lastRca = card THEN
  1270. IF EnableTrace THEN
  1271. Log.String("[SD] Card Already Selected");
  1272. Log.Ln
  1273. END;
  1274. RETURN TRUE
  1275. END;
  1276. IF EnableTrace THEN Log.String("[SD] Selecting Card "); Log.Int(card, 0); Log.Ln END;
  1277. command.hc := hc;
  1278. command.command := CMD_SELECT_DESELECT_CARD;
  1279. command.argument := LSH(card, 16);
  1280. command.responseType := ResponseR1b;
  1281. IF ~hc.execute(command, result) THEN RETURN FALSE END;
  1282. status := GetR1(command);
  1283. IF CardStatus_Error IN status THEN result := ErrorCard; RETURN FALSE END;
  1284. RETURN TRUE
  1285. END SelectCard;
  1286. (** Deselects all cards *)
  1287. PROCEDURE DeselectCards * (hc: HostController; VAR result: LONGINT): BOOLEAN;
  1288. VAR
  1289. command: Command;
  1290. ignoreRes: LONGINT;
  1291. ignoreBool: BOOLEAN;
  1292. BEGIN
  1293. result := ErrorNone;
  1294. IF hc.lastRca = 0 THEN
  1295. IF EnableTrace THEN Log.String("[SD] No card selected"); Log.Ln END;
  1296. RETURN TRUE
  1297. END;
  1298. IF EnableTrace THEN Log.String("[SD] Deselecting cards"); Log.Ln END;
  1299. command.hc := hc;
  1300. command.command := CMD_SELECT_DESELECT_CARD;
  1301. command.responseType := ResponseR1b;
  1302. ignoreBool := hc.execute(command, ignoreRes);
  1303. hc.lastRca := 0;
  1304. RETURN TRUE
  1305. END DeselectCards;
  1306. (** Read response R1 or R1b from command record *)
  1307. PROCEDURE GetR1 * (CONST command: Command): SET;
  1308. VAR
  1309. idx: LONGINT;
  1310. BEGIN
  1311. idx := 0;
  1312. (*IF (FlagAutoCmd12 IN command.flags) OR (FlagAutoCmd23 IN command.flags) THEN
  1313. idx := 3
  1314. END;*)
  1315. RETURN SYSTEM.VAL(SET, command.response[idx])
  1316. END GetR1;
  1317. (** Read response R2 from command record *)
  1318. PROCEDURE GetR2 * (CONST command: Command; VAR response: ARRAY OF LONGINT);
  1319. VAR
  1320. i: LONGINT;
  1321. BEGIN
  1322. FOR i := 0 TO 3 DO
  1323. response[i] := command.response[i]
  1324. END
  1325. END GetR2;
  1326. (** Read response R3 from command record *)
  1327. PROCEDURE GetR3 * (CONST command: Command): LONGINT;
  1328. BEGIN
  1329. RETURN command.response[0]
  1330. END GetR3;
  1331. (** Read response R4 from command record *)
  1332. PROCEDURE GetR4 * (CONST command: Command): LONGINT;
  1333. BEGIN
  1334. RETURN command.response[0]
  1335. END GetR4;
  1336. (** Read response R5 from command record *)
  1337. PROCEDURE GetR5 * (CONST command: Command): LONGINT;
  1338. BEGIN
  1339. RETURN command.response[0]
  1340. END GetR5;
  1341. (** Read response R6 from command record *)
  1342. PROCEDURE GetR6 * (CONST command: Command): LONGINT;
  1343. BEGIN
  1344. RETURN command.response[0]
  1345. END GetR6;
  1346. (** Read response R7 from command record *)
  1347. PROCEDURE GetR7 * (CONST command: Command): LONGINT;
  1348. BEGIN
  1349. RETURN command.response[0]
  1350. END GetR7;
  1351. (** Reset command and/or data lines of a host controller *)
  1352. PROCEDURE Reset (hc: HostController; cmd, dat: BOOLEAN): BOOLEAN;
  1353. VAR
  1354. val: SHORTINT;
  1355. BEGIN
  1356. IF cmd & dat THEN
  1357. val := SoftwareResetAll
  1358. ELSIF cmd THEN
  1359. val := SoftwareResetCmd
  1360. ELSIF dat THEN
  1361. val := SoftwareResetDat
  1362. ELSE
  1363. RETURN FALSE
  1364. END;
  1365. hc.regs.SoftwareReset := val;
  1366. REPEAT
  1367. UNTIL hc.regs.SoftwareReset # val;
  1368. RETURN TRUE
  1369. END Reset;
  1370. (** Set host controller bust clock *)
  1371. PROCEDURE SetBusClock (hc: HostController; freq: LONGINT);
  1372. VAR
  1373. val: LONGINT;
  1374. BEGIN
  1375. hc.regs.ClockControl := 0;
  1376. IF freq < hc.baseFrequency THEN
  1377. val := 1;
  1378. WHILE (val < 8) & (LSH(hc.baseFrequency,-val) > freq) DO
  1379. INC(val);
  1380. END;
  1381. IF EnableTrace THEN
  1382. Log.String(" [SD] baseFreq=");
  1383. Log.Int(hc.baseFrequency, 0);
  1384. Log.String(", val=");
  1385. Log.Int(val, 0);
  1386. Log.Ln
  1387. END;
  1388. hc.regs.ClockControl := INTEGER(LSH(LSH(LONGINT(1), val-1), 8) + SYSTEM.VAL(INTEGER, {ClockControl_InternalClockEnable}));
  1389. hc.frequency := LSH(hc.baseFrequency, -val);
  1390. ELSE
  1391. hc.regs.ClockControl := SYSTEM.VAL(INTEGER, {ClockControl_InternalClockEnable});
  1392. hc.frequency := hc.baseFrequency;
  1393. END;
  1394. REPEAT val := hc.regs.ClockControl UNTIL ClockControl_InternalClockState IN SYSTEM.VAL(SET, val);
  1395. val := hc.regs.ClockControl;
  1396. hc.regs.ClockControl := SYSTEM.VAL(INTEGER, SYSTEM.VAL(SET, val) + {ClockControl_SdClockEnable});
  1397. IF EnableTrace THEN
  1398. Log.String("[SD] Selecting Bus Clock Frequency: ");
  1399. Log.Int(hc.frequency, 0); Log.String(" Hz");
  1400. Log.Ln
  1401. END;
  1402. END SetBusClock;
  1403. (** Set host controller data timeout, in ms *)
  1404. PROCEDURE SetTimeout (hc: HostController; timeout: LONGINT);
  1405. VAR
  1406. ratio, val: LONGINT;
  1407. BEGIN
  1408. EXCL(hc.regs.InterruptStatusEnable, Interrupt_Error_DataTimeout);
  1409. ratio := LSH(LONGINT(hc.timeoutFrequency * timeout DIV 1000), -13);
  1410. val := 0;
  1411. WHILE (val < 15) & (LSH(LONGINT(1), val) < ratio) DO INC(val) END;
  1412. ASSERT(LSH(LONGINT(1), val) >= ratio);
  1413. hc.regs.TimeoutControl := SYSTEM.VAL(SHORTINT, val);
  1414. INCL(hc.regs.InterruptStatusEnable, Interrupt_Error_DataTimeout)
  1415. END SetTimeout;
  1416. (** Set the data bus width for a given RCA. *)
  1417. PROCEDURE SetBusWidth (hc: HostController; card: Card; width: LONGINT; VAR result: LONGINT): BOOLEAN;
  1418. VAR
  1419. command: Command;
  1420. val: LONGINT;
  1421. BEGIN
  1422. IF ~SelectCard(card.hc, card.rca, result) THEN RETURN FALSE END;
  1423. (*command.hc := card.hc;
  1424. command.command := ACMD_SET_CLR_CARD_DETECT;
  1425. command.argument := 0;
  1426. command.responseType := ResponseR1;
  1427. command.flags := {FlagApplicationCmd};
  1428. command.rca := card.rca;
  1429. IF ~ExecuteCommand(command, result) THEN RETURN FALSE END;*)
  1430. (* 1 *)
  1431. EXCL(hc.regs.InterruptStatusEnable, Interrupt_Normal_CardInterrupt);
  1432. (* 2: driver supports SD cards only *)
  1433. (* 3: not implemented *)
  1434. (* 4 *)
  1435. command.command := ACMD_SET_BUS_WIDTH;
  1436. CASE width OF
  1437. 1: command.argument := 0
  1438. |4: command.argument := 2
  1439. END;
  1440. command.hc := hc;
  1441. command.rca := card.rca;
  1442. command.flags := {FlagApplicationCmd};
  1443. command.responseType := ResponseR1;
  1444. IF ~ExecuteCommand(command, result) THEN RETURN FALSE END;
  1445. (* 5 *)
  1446. val := hc.regs.HostControl1;
  1447. CASE width OF
  1448. 1: EXCL(SYSTEM.VAL(SET, val), HostControl1_DataTransferWidth)
  1449. |4: INCL(SYSTEM.VAL(SET, val), HostControl1_DataTransferWidth)
  1450. END;
  1451. hc.regs.HostControl1 := SHORTINT(val);
  1452. (* 6: SD card only *)
  1453. (* 8 *)
  1454. INCL(hc.regs.InterruptStatusEnable, Interrupt_Normal_CardInterrupt);
  1455. RETURN TRUE
  1456. END SetBusWidth;
  1457. (** Executes a switch function command *)
  1458. PROCEDURE SwitchFunc (card: Card; switch: BOOLEAN; funcs: ARRAY 6 OF LONGINT; VAR sts: SwitchFuncStatus; VAR res: LONGINT): BOOLEAN;
  1459. VAR
  1460. status: ARRAY 64 OF CHAR;
  1461. command: Command;
  1462. PROCEDURE GetStatus (CONST status: ARRAY OF CHAR; VAR sts: SwitchFuncStatus);
  1463. VAR
  1464. i: LONGINT;
  1465. BEGIN
  1466. sts.current := LONGINT(ORD(status[0])) * 100H + LONGINT(ORD(status[1]));
  1467. FOR i := 0 TO 5 DO
  1468. sts.functionGroups[i] := SYSTEM.VAL(SET, LONGINT(ORD(status[2 + 2 * (5 - i)])) * 100H + LONGINT(ORD(status[1 + 2 + 2 * (5 - i)])))
  1469. END;
  1470. FOR i := 0 TO 5 BY 2 DO
  1471. sts.functionStatus[i] := ORD(status[14 + 2 - i DIV 2]) MOD 10H;
  1472. sts.functionStatus[i + 1] := ORD(status[14 + 2 - i DIV 2]) DIV 10H
  1473. END;
  1474. END GetStatus;
  1475. BEGIN
  1476. IF ~SelectCard(card.hc, card.rca, res) THEN RETURN FALSE END;
  1477. command.hc := card.hc;
  1478. command.command := CMD_SWITCH_FUNC;
  1479. command.responseType := ResponseR1;
  1480. 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);
  1481. IF switch THEN INCL(SYSTEM.VAL(SET, command.argument), 31) END;
  1482. command.flags := {FlagRead, FlagData};
  1483. command.dataTimeout := card.readTimeout;
  1484. IF ~card.hc.transfer(command, status, 0, 64, res) THEN RETURN FALSE END;
  1485. GetStatus(status, sts);
  1486. RETURN TRUE
  1487. END SwitchFunc;
  1488. (** Outputs the switch function status on the log *)
  1489. PROCEDURE PrintSwitchFuncStatus(CONST status: SwitchFuncStatus);
  1490. VAR
  1491. i: LONGINT;
  1492. BEGIN
  1493. Log.String("Switch Func Status");
  1494. Log.Ln;
  1495. Log.String("Current = ");
  1496. IF status.current = 0 THEN
  1497. Log.String("ERROR")
  1498. ELSE
  1499. Log.Int(status.current, 0);
  1500. Log.String(" mA");
  1501. Log.Ln
  1502. END;
  1503. FOR i := 0 TO 5 DO
  1504. Log.String("Function Group #");
  1505. Log.Int(i, 0);
  1506. Log.String(": functions = ");
  1507. Log.Set(status.functionGroups[i]);
  1508. Log.String(", status = ");
  1509. CASE status.functionStatus[i] OF
  1510. 0: Log.String("switchable")
  1511. |1: Log.String("switched")
  1512. |0FH: Log.String("ERROR")
  1513. END;
  1514. Log.Ln
  1515. END
  1516. END PrintSwitchFuncStatus;
  1517. (** Interrupt handler *)
  1518. PROCEDURE HandleInterrupt * (hc: HostController);
  1519. VAR
  1520. card: Card;
  1521. result: LONGINT;
  1522. interruptStatus: SET;
  1523. BEGIN
  1524. interruptStatus := hc.regs.InterruptStatus;
  1525. (*IF {Interrupt_Normal_TransferComplete, Interrupt_Normal_ErrorInterrupt} * interruptStatus # {} THEN
  1526. BEGIN {EXCLUSIVE} continue := TRUE END;
  1527. RETURN
  1528. END;*)
  1529. (*!TODO: make interrupt handling as quick as possible - handle all events in SdControllers asynchronously! *)
  1530. IF Interrupt_Normal_CardInsertion IN interruptStatus THEN
  1531. hc.regs.InterruptStatus := {Interrupt_Normal_CardInsertion};
  1532. IF EnableTrace THEN Log.String("[SD] Card Insertion"); Log.Ln END;
  1533. NEW(card);
  1534. IF InitCard(hc, card, result) & (hc.handle # NIL) THEN
  1535. hc.handle(card, OnInitialization, hc.handlerParam)
  1536. ELSIF EnableTrace THEN
  1537. Log.String("[SD] Could not initialize card"); Log.Ln
  1538. END
  1539. ELSIF Interrupt_Normal_CardRemoval IN interruptStatus THEN
  1540. hc.regs.InterruptStatus := {Interrupt_Normal_CardRemoval};
  1541. IF EnableTrace THEN Log.String("[SD] Card Removal"); Log.Ln END;
  1542. card := hc.cards;
  1543. IF hc.handle # NIL THEN hc.handle(card, OnRemoval, hc.handlerParam) END;
  1544. hc.cards := hc.cards.next
  1545. END;
  1546. END HandleInterrupt;
  1547. (* ==================== Card (High-Level) Interface ==================== *)
  1548. TYPE
  1549. (** Card descriptor *)
  1550. Card * = POINTER TO CardDesc;
  1551. CardDesc * = RECORD
  1552. state -, (** Card state. Currently not used *)
  1553. rca -: LONGINT; (** Card RCA *)
  1554. cid -: Cid; (** CID *)
  1555. csd -: Csd; (** CSD *)
  1556. scr -: Scr; (** SCR *)
  1557. sdStatus -: SdStatus; (** Current SD status for this card *)
  1558. hc -: HostController; (** Host controller on which the card is attached *)
  1559. acquire *, release *: PROCEDURE {DELEGATE}; (** Used for synchronization *)
  1560. readTimeout, (** Read timeout computed for this card, in ms *)
  1561. writeTimeout, (** Write timeout computed for this card, in ms *)
  1562. eraseTimeout: LONGINT; (** Erase timeout computed for this card, in ms *)
  1563. next: Card; (** Internal linked list of cards attached to the same HC *)
  1564. END;
  1565. (** SD Status *)
  1566. SdStatus * = RECORD
  1567. dataBusWidth -: LONGINT; (** Number of DAT bus lines currently used by card *)
  1568. securedMode -: BOOLEAN; (** Is card in secured mode? *)
  1569. cardType -: LONGINT; (** Card type, one of Category* *)
  1570. sizeProtArea -: HUGEINT; (** Size of the protected area, in bytes *)
  1571. perfMove -: LONGINT; (** Performance of move, in MB/s. 0 means 'sequential write', 255 means 'infinity' *)
  1572. eraseSize -: LONGINT; (** Numbers of AUs erased at a time. 0 means not supported *)
  1573. eraseTimeout -: LONGINT; (** Erase timeout value in second, per erase unit. 0 means not supported *)
  1574. eraseOffset -: LONGINT; (** Fixed timeout for erase timeout, in second *)
  1575. speedClass -: LONGINT; (** 3.x V speed class: 0 is 'unknown', 2, 4, 6 or 10 *)
  1576. auSize -: LONGINT; (** AU size for 3.x V *)
  1577. uhsSpeedGrade -: LONGINT; (** UHS speed grade: 0 is 'not supported', 1 or 3 *)
  1578. uhsAuSize -: LONGINT; (** AU size in UHS mode *)
  1579. vscSpeedClass -: LONGINT; (** Video mode speed class: 0 is 'not supported', 6, 10, 30, 60 or 90 *)
  1580. vscAuSize -: LONGINT; (** AU size in video mode *)
  1581. suspensionAdr -: LONGINT; (** Current suspension address, in blocks. See CMD20 *)
  1582. appPerfClass -: LONGINT; (** Application performance class: 0 is 'not supported', 1 or 2 *)
  1583. perfEnhance -: SET; (** Performance enhancing features of the card. Contains Performance* *)
  1584. commandQueueDepth -: LONGINT; (** Command queue depth. Valid only if PerformanceCommandQueue IN perfEnhance *)
  1585. discardSupport -: BOOLEAN; (** Card supports discard? *)
  1586. fuleSupport -: BOOLEAN; (** card supports FULE? *)
  1587. END;
  1588. (** Card Identification register *)
  1589. Cid * = RECORD
  1590. manufacturingDate -: RECORD (** Manufacturing date, with year and month *)
  1591. year -,
  1592. month -: LONGINT
  1593. END;
  1594. productSerialNumber -: ADDRESS; (** Serial number *)
  1595. productRevision -: RECORD (** Revision n.m *)
  1596. n-, m-: LONGINT
  1597. END;
  1598. productName -: ARRAY 6 OF CHAR; (** Product name *)
  1599. oemId -: ARRAY 3 OF CHAR; (** OEM/Application ID *)
  1600. manufacturerId -: LONGINT; (** Manufacturer identifier *)
  1601. END;
  1602. (* Card Registers *)
  1603. Csd * = RECORD
  1604. (* Card properties *)
  1605. capacity -: HUGEINT; (** Card capacity in bytes *)
  1606. commandClasses -: SET; (** Command classes supported by the card *)
  1607. (* Timing info *)
  1608. r2w -: LONGINT; (** Read to write time factor = read time / write time *)
  1609. taac -: REAL; (** Asynchronous access time, in s *)
  1610. nsac -: LONGINT; (** Worst-case clock dependent access time, in clock cycles *)
  1611. txSpeed -: LONGINT; (** Max transfer speed in bit/s *)
  1612. (* Block read properties *)
  1613. partialRead -,
  1614. misalignedRead -: BOOLEAN;
  1615. readBlockSize -: LONGINT;
  1616. (* Block write properties *)
  1617. partialWrite -,
  1618. misalignedWrite -: BOOLEAN;
  1619. writeBlockSize -: LONGINT;
  1620. END;
  1621. (** SCR register *)
  1622. Scr * = RECORD
  1623. version -, (** Card physical spec. version: one of Version* *)
  1624. security -: LONGINT; (** Card security type: one of Type* *)
  1625. busWidth -: SET; (** Bus widths supported by the card *)
  1626. commandSupport -: SET; (** Supported commands *)
  1627. END;
  1628. (**
  1629. Initializes a new card on the host controller.
  1630. Executes all commands until either an error occurs or the card is ready for data transfers.
  1631. *)
  1632. PROCEDURE InitCard * (hc: HostController; card: Card; VAR result: LONGINT): BOOLEAN;
  1633. VAR
  1634. response: LONGINT;
  1635. status: SET;
  1636. f8, sdio: BOOLEAN;
  1637. command: Command;
  1638. BEGIN
  1639. SetBusClock(hc, InitialClockFrequency);
  1640. FOR response := 0 TO 10000000 DO END;
  1641. command.hc := hc;
  1642. (* 1 *)
  1643. command.command := CMD_GO_IDLE_STATE;
  1644. command.argument := 0;
  1645. command.responseType := ResponseNone;
  1646. command.flags := {};
  1647. IF ~ExecuteCommand(command, result) THEN RETURN FALSE END;
  1648. (* 2 *)
  1649. command.command := CMD_SEND_IF_COND;
  1650. command.argument := 1AAH;
  1651. command.responseType := ResponseR7;
  1652. command.flags := {};
  1653. IF ~ExecuteCommand(command, result) THEN RETURN FALSE END;
  1654. (* 3 *)
  1655. response := GetR7(command);
  1656. IF response # 1AAH THEN
  1657. result := ErrorCard;
  1658. RETURN FALSE
  1659. END;
  1660. f8 := TRUE;
  1661. (* 5 *)
  1662. command.command := CMD_IO_SEND_OP_COND;
  1663. command.argument := 0;
  1664. command.responseType := ResponseR4;
  1665. command.flags := {};
  1666. IF ~ExecuteCommand(command, result) & (result = ErrorCmdTimeout) THEN
  1667. sdio := FALSE;
  1668. result := ErrorNone;
  1669. IF ~Reset(hc ,TRUE, FALSE) THEN RETURN FALSE END;
  1670. ELSIF result # ErrorNone THEN
  1671. RETURN FALSE
  1672. ELSE
  1673. sdio := TRUE;
  1674. END;
  1675. IF EnableTrace THEN Log.String("[SD] Card is SDIO: "); Log.Boolean(sdio); Log.Ln END;
  1676. (* 6 *)
  1677. IF sdio THEN
  1678. (*! NOT IMPLEMENTED YET *)
  1679. HALT(100);
  1680. (* 7 *)
  1681. (*IF ~StartCommand(hc, CMD_IO_SEND_OP_COND, 800H, ResponseR4, FALSE, FALSE, res) THEN
  1682. RETURN FALSE
  1683. END;
  1684. RETURN TRUE*)
  1685. END;
  1686. (* A *)
  1687. (* 12 & 19 *)
  1688. command.command := ACMD_SD_SEND_OP_COND;
  1689. command.argument := 0;
  1690. command.responseType := ResponseR3;
  1691. command.flags := {FlagApplicationCmd, FlagIgnoreIllegalCmd};
  1692. IF ~ExecuteCommand(command, result) THEN RETURN FALSE END;
  1693. response := GetR3(command);
  1694. IF EnableTrace THEN
  1695. Log.String("[SD] VDD: Ranges Supported by Card:"); Log.Ln;
  1696. IF CardOcr_Vdd27_28 IN SYSTEM.VAL(SET, response) THEN Log.String("[SD] 2.7 - 2.8 V"); Log.Ln END;
  1697. IF CardOcr_Vdd28_29 IN SYSTEM.VAL(SET, response) THEN Log.String("[SD] 2.8 - 2.9 V"); Log.Ln END;
  1698. IF CardOcr_Vdd29_30 IN SYSTEM.VAL(SET, response) THEN Log.String("[SD] 2.9 - 3.0 V"); Log.Ln END;
  1699. IF CardOcr_Vdd30_31 IN SYSTEM.VAL(SET, response) THEN Log.String("[SD] 3.0 - 3.1 V"); Log.Ln END;
  1700. IF CardOcr_Vdd31_32 IN SYSTEM.VAL(SET, response) THEN Log.String("[SD] 3.1 - 3.2 V"); Log.Ln END;
  1701. IF CardOcr_Vdd32_33 IN SYSTEM.VAL(SET, response) THEN Log.String("[SD] 3.2 - 3.3 V"); Log.Ln END;
  1702. IF CardOcr_Vdd33_34 IN SYSTEM.VAL(SET, response) THEN Log.String("[SD] 3.3 - 3.4 V"); Log.Ln END;
  1703. IF CardOcr_Vdd34_35 IN SYSTEM.VAL(SET, response) THEN Log.String("[SD] 3.4 - 3.5 V"); Log.Ln END;
  1704. IF CardOcr_Vdd35_36 IN SYSTEM.VAL(SET, response) THEN Log.String("[SD] 3.5 - 3.6 V"); Log.Ln END
  1705. END;
  1706. status := {30};
  1707. IF Capabilities_Voltage30 IN hc.regs.Capabilities[0] THEN
  1708. IF EnableTrace THEN Log.String("[SD] Selecting 3.0 V"); Log.Ln END;
  1709. INCL(status, CardOcr_Vdd30_31)
  1710. ELSIF Capabilities_Voltage33 IN hc.regs.Capabilities[0] THEN
  1711. IF EnableTrace THEN Log.String("[SD] Selecting 3.3 V"); Log.Ln END;
  1712. INCL(status, CardOcr_Vdd32_33)
  1713. END;
  1714. command.command := ACMD_SD_SEND_OP_COND;
  1715. command.argument := SYSTEM.VAL(LONGINT, status);
  1716. command.responseType := ResponseR3;
  1717. command.flags := {FlagApplicationCmd, FlagIgnoreIllegalCmd};
  1718. REPEAT
  1719. IF ~ExecuteCommand(command, result) THEN RETURN FALSE END;
  1720. status := SYSTEM.VAL(SET, GetR3(command));
  1721. UNTIL (CardOcr_PowerUpStatus IN status);
  1722. IF EnableTrace & (CardOcr_S18A IN status) THEN
  1723. Log.String("[SD] Card supports 1.8V");
  1724. Log.Ln
  1725. END;
  1726. IF f8 & (CardOcr_CardCapacityStatus IN status) THEN
  1727. IF EnableTrace THEN Log.String("[SD] Card: SDHC or SDXC") END;
  1728. card.scr.security := TypeSDHC
  1729. ELSIF f8 THEN
  1730. IF EnableTrace THEN Log.String("[SD] Card: SDSC v2 or v3") END;
  1731. card.scr.security := TypeSDSC
  1732. ELSE
  1733. IF EnableTrace THEN Log.String("[SD] Card: SDSC v1.0 or v1.1") END;
  1734. card.scr.security := TypeSDSC
  1735. END;
  1736. IF EnableTrace THEN Log.Ln END;
  1737. (* 32 *)
  1738. command.command := CMD_ALL_SEND_CID;
  1739. command.argument := 0;
  1740. command.responseType := ResponseR2;
  1741. command.flags := {};
  1742. IF ~ExecuteCommand(command, result) THEN RETURN FALSE END;
  1743. DecodeCid(command.response, card.cid);
  1744. PrintCardCid(card.cid);
  1745. (* 33 *)
  1746. command.command := CMD_SEND_RELATIVE_ADDR;
  1747. command.argument := 0;
  1748. command.responseType := ResponseR6;
  1749. command.flags := {};
  1750. REPEAT
  1751. IF ~ExecuteCommand(command, result) THEN RETURN FALSE END;
  1752. card.rca := LSH(GetR6(command), -16)
  1753. UNTIL card.rca # 0;
  1754. IF EnableTrace THEN Log.String("[SD] New Card with RCA: "); Log.Hex(card.rca, -4); Log.Ln END;
  1755. status := SYSTEM.VAL(SET, GetR6(command));
  1756. status := status * {0 .. 15};
  1757. (* status is a modified CardStatus: reform corresponding card status *)
  1758. IF 15 IN status THEN EXCL(status, 15); INCL(status, 23) END;
  1759. IF 14 IN status THEN EXCL(status, 14); INCL(status, 22) END;
  1760. IF 13 IN status THEN EXCL(status, 13); INCL(status, 19) END;
  1761. IF EnableTrace THEN PrintCardStatus(status) END;
  1762. card.hc := hc;
  1763. card.next := hc.cards;
  1764. hc.cards := card;
  1765. IF Synchronize THEN SdEnvironment.GetLock(card.acquire, card.release) END;
  1766. (* Get Additional card registers: CSD *)
  1767. IF ~ReadCsd(card, result) THEN RETURN FALSE END;
  1768. SetBusClock(hc, card.csd.txSpeed);
  1769. (* Reasonable default timeout values, later rewritten with the ones given by the card *)
  1770. card.readTimeout := 100;
  1771. card.writeTimeout := 250;
  1772. card.eraseTimeout := 250;
  1773. (*IF ~Reset(hc, TRUE, FALSE) OR ~Reset(hc, FALSE, TRUE) THEN RETURN FALSE END;*)
  1774. IF ~ReadScr(card, result) THEN RETURN FALSE END;
  1775. ComputeTimeouts(card);
  1776. IF (card.scr.version >= Version1p1) THEN
  1777. IF EnableTrace THEN
  1778. Log.String("[SD] Enabling high-speed mode");
  1779. Log.Ln
  1780. END;
  1781. IF ~SelectSpeedMode(card, TRUE, result) THEN RETURN FALSE END;
  1782. IF EnableTrace THEN
  1783. Log.String("[SD] High-speed mode enabled");
  1784. Log.Ln
  1785. END;
  1786. (* Get CSD again: transfer speed might have changed *)
  1787. IF ~ReadCsd(card, result) THEN RETURN FALSE END;
  1788. ComputeTimeouts(card);
  1789. SetBusClock(hc, card.csd.txSpeed)
  1790. END;
  1791. IF 4 IN card.scr.busWidth THEN
  1792. IF EnableTrace THEN
  1793. Log.String("[SD] Changing bus width to 4 bits");
  1794. Log.Ln
  1795. END;
  1796. IF ~SetBusWidth(card.hc, card, 4, result) THEN RETURN FALSE END;
  1797. IF EnableTrace THEN
  1798. Log.String("[SD] Bus width changed");
  1799. Log.Ln
  1800. END
  1801. END;
  1802. IF ~Reset(hc, TRUE, FALSE) OR ~Reset(hc, FALSE, TRUE) THEN RETURN FALSE END;
  1803. GetSdStatus(card);
  1804. (*ResetStatistics; NEW(testbuf);
  1805. FOR response := 1 TO 100 DO
  1806. IF ~Read(card, 33554432, LEN(testbuf), testbuf^, 0, result) THEN RETURN FALSE END;
  1807. IF ~Write(card, 33554432, LEN(testbuf), testbuf^, 0, result) THEN RETURN FALSE END;
  1808. END;
  1809. Statistics(Commands.GetContext());
  1810. HALT(512);*)
  1811. RETURN TRUE
  1812. END InitCard;
  1813. (** Write 'data[ofs, ofs + len)' to 'card', starting at block 'firstBlock'. *)
  1814. PROCEDURE Write * (card: Card; firstBlock, len: LONGINT; VAR data: ARRAY OF SYSTEM.BYTE; ofs: LONGINT; VAR result: LONGINT): BOOLEAN;
  1815. VAR
  1816. command: Command;
  1817. start, stop: HUGEINT;
  1818. ret: BOOLEAN;
  1819. BEGIN
  1820. result := ErrorNone;
  1821. IF Synchronize THEN card.acquire END;
  1822. start := SdEnvironment.GetTimeCounter();
  1823. IF ~SelectCard(card.hc, card.rca, result) THEN
  1824. IF Synchronize THEN card.release END;
  1825. RETURN FALSE
  1826. END;
  1827. command.hc := card.hc;
  1828. command.rca := card.rca;
  1829. (* Pre-erase blocks *)
  1830. command.command := ACMD_SET_WR_BLK_ERASE_COUNT;
  1831. command.flags := {FlagApplicationCmd};
  1832. command.responseType := ResponseR1;
  1833. command.argument := (len + BlockSize - 1) DIV BlockSize;
  1834. IF ~ExecuteCommand(command, result) THEN
  1835. IF Synchronize THEN card.release END;
  1836. RETURN FALSE
  1837. END;
  1838. command.argument := firstBlock;
  1839. command.responseType := ResponseR1;
  1840. command.flags := {FlagData};
  1841. command.dataTimeout := card.writeTimeout;
  1842. command.blockSize := card.csd.writeBlockSize;
  1843. IF len > card.csd.writeBlockSize THEN
  1844. INCL(command.flags, FlagMultipleBlockTx);
  1845. INCL(command.flags, FlagCountBlocks);
  1846. INCL(command.flags, FlagAutoCmd12);
  1847. command.command := CMD_WRITE_MULTIPLE_BLOCK;
  1848. ELSE
  1849. command.command := CMD_WRITE_BLOCK
  1850. END;
  1851. ret := command.hc.transfer(command, data, ofs, len, result);
  1852. stop := SdEnvironment.GetTimeCounter();
  1853. IF Synchronize THEN card.release END;
  1854. IF ret THEN
  1855. INC(Nwrite);
  1856. INC(NbyteWritten, len);
  1857. INC(Twrite, stop - start)
  1858. END;
  1859. RETURN ret
  1860. END Write;
  1861. (** Read 'len' bytes starting from 'firstBlock' of 'card' to 'data[ofs, ofs + len)' *)
  1862. PROCEDURE Read * (card: Card; firstBlock, len: LONGINT; VAR data: ARRAY OF SYSTEM.BYTE; ofs: LONGINT; VAR result: LONGINT): BOOLEAN;
  1863. VAR
  1864. command: Command;
  1865. start, stop: HUGEINT;
  1866. ret: BOOLEAN;
  1867. BEGIN
  1868. IF Synchronize THEN card.acquire END;
  1869. start := SdEnvironment.GetTimeCounter();
  1870. IF ~SelectCard(card.hc, card.rca, result) THEN
  1871. IF Synchronize THEN card.release END;
  1872. RETURN FALSE
  1873. END;
  1874. command.hc := card.hc;
  1875. command.argument := firstBlock;
  1876. command.responseType := ResponseR1;
  1877. (*command.flags := {FlagData, FlagRead};*)
  1878. command.rca := card.rca;
  1879. command.dataTimeout := card.readTimeout;
  1880. command.blockSize := card.csd.readBlockSize;
  1881. IF len > card.csd.readBlockSize THEN
  1882. command.flags := {FlagData, FlagRead, FlagMultipleBlockTx, FlagCountBlocks, FlagAutoCmd12};
  1883. (*INCL(command.flags, FlagMultipleBlockTx);
  1884. INCL(command.flags, FlagCountBlocks);
  1885. INCL(command.flags, FlagAutoCmd12);*)
  1886. command.command := CMD_READ_MULTIPLE_BLOCK
  1887. ELSE
  1888. command.flags := {FlagData, FlagRead};
  1889. command.command := CMD_READ_SINGLE_BLOCK
  1890. END;
  1891. ret := command.hc.transfer(command, data, ofs, len, result) & ~(CardStatus_Error IN GetR1(command));
  1892. stop := SdEnvironment.GetTimeCounter();
  1893. IF Synchronize THEN card.release END;
  1894. IF ret THEN
  1895. INC(Nread);
  1896. INC(NbyteRead, len);
  1897. INC(Tread, stop - start)
  1898. END;
  1899. RETURN ret
  1900. END Read;
  1901. (** Erase blocks [block, block + num) on specified card. *)
  1902. PROCEDURE Erase * (card: Card; block, num: LONGINT; VAR result: LONGINT): BOOLEAN;
  1903. VAR
  1904. command: Command;
  1905. r1: SET;
  1906. BEGIN
  1907. command.hc := card.hc;
  1908. command.flags := {};
  1909. command.rca := card.rca;
  1910. command.dataTimeout := card.eraseTimeout;
  1911. command.responseType := ResponseR1;
  1912. command.argument := block;
  1913. command.command := CMD_ERASE_WR_BLK_START;
  1914. IF ~ExecuteCommand(command, result) & (CardStatus_Error IN GetR1(command)) THEN RETURN FALSE END;
  1915. command.argument := block + num - 1;
  1916. command.command := CMD_ERASE_WR_BLK_END;
  1917. IF ~ExecuteCommand(command, result) & (CardStatus_Error IN GetR1(command)) THEN RETURN FALSE END;
  1918. command.argument := 0;
  1919. command.command := CMD_ERASE;
  1920. command.responseType := ResponseR1b;
  1921. IF ~ExecuteCommand(command, result) & (CardStatus_Error IN GetR1(command)) THEN RETURN FALSE END;
  1922. (*WHILE 20 IN card.hc.regs.PresentState DO END;*)
  1923. command.command := CMD_SEND_STATUS;
  1924. command.responseType := ResponseR1;
  1925. REPEAT
  1926. IF ~ExecuteCommand(command, result) THEN RETURN FALSE END;
  1927. r1 := GetR1(command);
  1928. IF CardStatus_Error IN r1 THEN RETURN FALSE END
  1929. UNTIL CardStatus_ReadyForData IN r1;
  1930. RETURN TRUE
  1931. END Erase;
  1932. PROCEDURE ReadCsd (card: Card; VAR result: LONGINT): BOOLEAN;
  1933. VAR
  1934. command: Command;
  1935. csd: ARRAY 4 OF LONGINT;
  1936. BEGIN
  1937. result := ErrorNone;
  1938. IF ~DeselectCards(card.hc, result) THEN RETURN FALSE END;
  1939. command.hc := card.hc;
  1940. command.command := CMD_SEND_CSD;
  1941. command.argument := LSH(card.rca, 16);
  1942. command.responseType := ResponseR2;
  1943. command.flags := {};
  1944. IF ~ExecuteCommand(command, result) THEN RETURN FALSE END;
  1945. GetR2(command, csd);
  1946. DecodeCsd(csd, card.csd);
  1947. IF EnableTrace THEN
  1948. PrintCardCsd(csd);
  1949. Log.String("[SD] Card Capacity: ");
  1950. PrintSize(card.csd.capacity);
  1951. Log.Ln;
  1952. Log.String("[SD] Bus frequency: "); Log.Int(card.csd.txSpeed, 0); Log.String(" Hz"); Log.Ln
  1953. END;
  1954. RETURN TRUE
  1955. END ReadCsd;
  1956. (** Read the SD card Configuration Register of a card *)
  1957. PROCEDURE ReadScr (card: Card; VAR result: LONGINT): BOOLEAN;
  1958. VAR
  1959. command: Command;
  1960. ofs: LONGINT;
  1961. scr: ARRAY 8 OF CHAR;
  1962. BEGIN
  1963. IF ~SelectCard(card.hc, card.rca, result) THEN RETURN FALSE END;
  1964. (*
  1965. disconnect the pull-up resistor on D3 line (important for high-speed mode with 4 lines)
  1966. *)
  1967. (*command.hc := card.hc;
  1968. command.command := ACMD_SET_CLR_CARD_DETECT;
  1969. command.argument := 0;
  1970. command.responseType := ResponseR1;
  1971. command.flags := {FlagApplicationCmd};
  1972. command.rca := card.rca;
  1973. IF ~ExecuteCommand(command, result) THEN RETURN FALSE END;*)
  1974. (* Get Card Register: SCR *)
  1975. command.hc := card.hc;
  1976. command.command := ACMD_SEND_SCR;
  1977. command.argument := 0;
  1978. command.responseType := ResponseR1;
  1979. command.flags := {FlagApplicationCmd, FlagData, FlagRead};
  1980. command.rca := card.rca;
  1981. command.dataTimeout := card.readTimeout;
  1982. (*ofs := 32 - ADDRESSOF(scr[0]) MOD 32;*)
  1983. IF ~card.hc.transfer(command, scr, ofs, 8, result) THEN RETURN FALSE END;
  1984. IF CardStatus_Error IN GetR1(command) THEN result := ErrorCard; RETURN FALSE END;
  1985. DecodeScr(scr, ofs, card.scr);
  1986. IF EnableTrace THEN PrintCardScr(card.scr) END;
  1987. RETURN TRUE
  1988. END ReadScr;
  1989. PROCEDURE GetSdStatus (card: Card);
  1990. TYPE Bitfield = ARRAY 16 OF LONGINT;
  1991. VAR
  1992. status: ARRAY 64 OF CHAR;
  1993. command: Command;
  1994. ignore: LONGINT;
  1995. bitfield: POINTER {UNSAFE,UNTRACED} TO Bitfield;
  1996. c: CHAR;
  1997. i: LONGINT;
  1998. BEGIN
  1999. ASSERT(SelectCard(card.hc, card.rca, ignore));
  2000. command.hc := card.hc;
  2001. command.rca := card.rca;
  2002. command.command := ACMD_SD_STATUS;
  2003. command.flags := {FlagApplicationCmd, FlagData, FlagRead};
  2004. command.responseType := ResponseR1;
  2005. command.dataTimeout := card.readTimeout;
  2006. IF ~card.hc.transfer(command, status, 0, LEN(status), ignore) THEN RETURN END;
  2007. FOR i := 0 TO LEN(status) DIV 2 DO
  2008. c := status[i];
  2009. status[i] := status[LEN(status) - 1 - i];
  2010. status[LEN(status) - 1 - i] := c
  2011. END;
  2012. bitfield := ADDRESSOF(status[0]);
  2013. DecodeSdStatus(bitfield^, card.sdStatus);
  2014. PrintSdStatus(card.sdStatus);
  2015. END GetSdStatus;
  2016. PROCEDURE GetCid (card: Card);
  2017. VAR
  2018. cid: Cid;
  2019. command: Command;
  2020. res: LONGINT;
  2021. BEGIN
  2022. IF ~DeselectCards(card.hc, res) THEN HALT(512) END;
  2023. command.hc := card.hc;
  2024. command.command := CMD_SEND_CID;
  2025. command.argument := LSH(card.rca, 16);
  2026. command.flags := {};
  2027. command.responseType := ResponseR2;
  2028. IF ~ExecuteCommand(command, res) THEN HALT(512) END;
  2029. DecodeCid(command.response, cid);
  2030. PrintCardCid(cid)
  2031. END GetCid;
  2032. (**
  2033. Computes data timeouts for read, write and erase operations according to SD specifications.
  2034. Stores them in card.readTimeout, writeTimeout, eraseTimeout.
  2035. *)
  2036. PROCEDURE ComputeTimeouts (card: Card);
  2037. VAR
  2038. readTime: LONGINT;
  2039. BEGIN
  2040. (*
  2041. Read timeout is the lower of:
  2042. o (CSD.TAAC + CSD.NSAC / busfreq * 100) * TimeoutReadFactor
  2043. o TimeoutReadFix
  2044. for a normal SD card and
  2045. TimeoutReadFix
  2046. for a SDHC card.
  2047. Write timeout is very similar to read timeout, except that (CSD.TAAC + CSD.NSAC) * CSD.R2W is used.
  2048. *)
  2049. IF card.scr.version >= TypeSDHC THEN
  2050. card.readTimeout := TimeoutReadFix;
  2051. card.writeTimeout := TimeoutWriteFix
  2052. ELSE
  2053. readTime := 100 * LONGINT((card.csd.taac + REAL(card.csd.nsac * 100) / REAL(card.hc.frequency)) * 1000.0);
  2054. card.readTimeout := MIN(readTime, TimeoutReadFix);
  2055. card.writeTimeout := MIN(readTime * card.csd.r2w, TimeoutWriteFix);
  2056. END;
  2057. card.eraseTimeout := TimeoutErase;
  2058. IF EnableTrace THEN
  2059. Log.String("[SD] Read timeout = "); Log.Int(card.readTimeout, 0); Log.String(" ms"); Log.Ln;
  2060. Log.String("[SD] Write timeout = "); Log.Int(card.writeTimeout, 0); Log.String(" ms"); Log.Ln;
  2061. Log.String("[SD] Erase timeout = "); Log.Int(card.eraseTimeout, 0); Log.String(" ms"); Log.Ln
  2062. END
  2063. END ComputeTimeouts;
  2064. (** Select card speed mode. It is necessary to set it to high in order to use higher bus clock frequencies. *)
  2065. PROCEDURE SelectSpeedMode(card: Card; high: BOOLEAN; VAR res: LONGINT): BOOLEAN;
  2066. VAR
  2067. funcs: ARRAY 6 OF LONGINT;
  2068. status: SwitchFuncStatus;
  2069. val: SET;
  2070. BEGIN
  2071. funcs[0] := 1;
  2072. IF ~SwitchFunc(card, FALSE, funcs, status, res) THEN RETURN FALSE END;
  2073. IF EnableTrace THEN
  2074. Log.String("[SD] Select speed, before:");
  2075. Log.Ln;
  2076. PrintSwitchFuncStatus(status)
  2077. END;
  2078. IF ~(1 IN status.functionGroups[0]) THEN
  2079. Log.String("[SD] HIGH-SPEED MODE NOT SUPPORTED");
  2080. Log.Ln;
  2081. RETURN TRUE
  2082. END;
  2083. IF ~SwitchFunc(card, TRUE, funcs, status, res) THEN RETURN FALSE END;
  2084. IF EnableTrace THEN
  2085. Log.String("[SD] Select speed, after:");
  2086. Log.Ln;
  2087. PrintSwitchFuncStatus(status)
  2088. END;
  2089. val := SYSTEM.VAL(SET, LONGINT(card.hc.regs.HostControl1));
  2090. IF high THEN
  2091. INCL(val, HostControl1_HighSpeedEnable)
  2092. ELSE
  2093. EXCL(val, HostControl1_HighSpeedEnable)
  2094. END;
  2095. card.hc.regs.HostControl1 := SYSTEM.VAL(SHORTINT, val);
  2096. RETURN TRUE
  2097. END SelectSpeedMode;
  2098. PROCEDURE DecodeSdStatus (CONST raw: ARRAY OF LONGINT; VAR status: SdStatus);
  2099. VAR
  2100. val: LONGINT;
  2101. BEGIN
  2102. val := ReadBitfield(raw, SdStatus_DatBusWidthOfs, SdStatus_DatBusWidthWidth);
  2103. CASE val OF
  2104. 0: status.dataBusWidth := 1
  2105. |2: status.dataBusWidth := 4
  2106. ELSE
  2107. status.dataBusWidth := 0
  2108. END;
  2109. status.securedMode := ReadBit(raw, SdStatus_SecuredMode);
  2110. val := ReadBitfield(raw, SdStatus_SdCardTypeOfs, SdStatus_SdCardTypeWidth);
  2111. CASE val OF
  2112. 0: status.cardType := CategoryRW
  2113. |1: status.cardType := CategoryRO
  2114. |2: status.cardType := CategoryOTP
  2115. END;
  2116. status.sizeProtArea := ReadBitfield(raw, SdStatus_SizeOfProtectedAreaOfs, SdStatus_SizeOfProtectedAreaWidth);
  2117. (*! TODO: multiply sizeProtArea by MULT * BLOCK_LEN if SDSC *)
  2118. val := ReadBitfield(raw, SdStatus_SpeedClassOfs, SdStatus_SpeedClassWidth);
  2119. CASE val OF
  2120. 0 .. 3: status.speedClass := 2 * val
  2121. |4: status.speedClass := 10
  2122. END;
  2123. status.perfMove := ReadBitfield(raw, SdStatus_PerformanceMoveOfs, SdStatus_PerformanceMoveWidth);
  2124. status.auSize := ReadBitfield(raw, SdStatus_AuSizeOfs, SdStatus_AuSizeWidth) * 16 * 1024;
  2125. status.eraseSize := ReadBitfield(raw, SdStatus_EraseSizeOfs, SdStatus_EraseSizeWidth);
  2126. status.eraseTimeout := ReadBitfield(raw, SdStatus_EraseTimeoutOfs, SdStatus_EraseTimeoutWidth);
  2127. status.eraseOffset := ReadBitfield(raw, SdStatus_EraseOffsetOfs, SdStatus_EraseOffsetWidth);
  2128. val := ReadBitfield(raw, SdStatus_UhsSpeedGradeOfs, SdStatus_UhsSpeedGradeWidth);
  2129. CASE val OF
  2130. 0, 1, 3: status.uhsSpeedGrade := val
  2131. END;
  2132. status.uhsAuSize := ReadBitfield(raw, SdStatus_UhsAuSizeOfs, SdStatus_UhsAuSizeWidth) * 1024 * 1024;
  2133. status.vscSpeedClass := ReadBitfield(raw, SdStatus_VideoSpeedClassOfs, SdStatus_VideoSpeedClassWidth);
  2134. status.vscAuSize := ReadBitfield(raw, SdStatus_VscAuSizeOfs, SdStatus_VscAuSizeWidth) * 1024 * 1024;
  2135. status.suspensionAdr := ReadBitfield(raw, SdStatus_SusAddrOfs, SdStatus_SusAddrWidth);
  2136. status.appPerfClass := ReadBitfield(raw, SdStatus_AppPerfClassOfs, SdStatus_AppPerfClassWidth);
  2137. val := ReadBitfield(raw, SdStatus_PerformanceEnhanceOfs, SdStatus_PerformanceEnhanceWidth);
  2138. status.perfEnhance := SYSTEM.VAL(SET, val) * {PerformanceCardMaintenance .. PerformanceCache};
  2139. IF SYSTEM.VAL(SET, val) * {3 .. MAX(SET)} # {} THEN
  2140. INCL(status.perfEnhance, PerformanceQueue);
  2141. status.commandQueueDepth := LSH(val, -3) + 1
  2142. END;
  2143. status.discardSupport := ReadBit(raw, SdStatus_DiscardSupport);
  2144. status.fuleSupport := ReadBit(raw, SdStatus_FuleSupport)
  2145. END DecodeSdStatus;
  2146. PROCEDURE DecodeCid (CONST raw: ARRAY OF LONGINT; VAR cid: Cid);
  2147. VAR
  2148. val: LONGINT;
  2149. BEGIN
  2150. val := ReadBitfield(raw, CardCid_ProductManufacturingDateOfs, CardCid_ProductManufacturingDateWidth);
  2151. cid.manufacturingDate.year := val DIV 10H + 2000;
  2152. cid.manufacturingDate.month := val MOD 10H;
  2153. cid.productSerialNumber := SYSTEM.VAL(ADDRESS, ReadBitfield(raw, CardCid_ProductSerialNbOfs, CardCid_ProductSerialNbWidth));
  2154. val := ReadBitfield(raw, CardCid_ProductRevisionOfs, CardCid_ProductRevisionWidth);
  2155. cid.productRevision.n := val DIV 10H;
  2156. cid.productRevision.m := val MOD 10H;
  2157. SYSTEM.MOVE(ADDRESSOF(raw[0]) + CardCid_ProductNameOfs DIV 8, ADDRESSOF(cid.productName), CardCid_ProductNameWidth DIV 8);
  2158. SYSTEM.MOVE(ADDRESSOF(raw[0]) + CardCid_OEM_ApplicationIdOfs DIV 8, ADDRESSOF(cid.oemId), CardCid_OEM_ApplicationIdWidth DIV 8);
  2159. cid.manufacturerId := ReadBitfield(raw, CardCid_ManufacturerIdOfs, CardCid_ManufacturerIdWidth)
  2160. END DecodeCid;
  2161. (** Fills a Csd record from the raw csd bytes *)
  2162. PROCEDURE DecodeCsd (CONST raw: ARRAY OF LONGINT; VAR csd: Csd);
  2163. VAR
  2164. sizeMult, val, version: LONGINT;
  2165. real: REAL;
  2166. BEGIN
  2167. version := ReadBitfield(raw, CardCsd_CsdStructureOfs, CardCsd_CsdStructureWidth) + 1;
  2168. IF version = 1 THEN
  2169. sizeMult := LSH(LONGINT(2), ReadBitfield(raw, CardCsd_CSizeMultOfs1, CardCsd_CSizeMultWidth1));
  2170. csd.capacity := sizeMult * (1 + ReadBitfield(raw, CardCsd_CSizeOfs1, CardCsd_CSizeWidth1)) * 512;
  2171. ELSE
  2172. csd.capacity := 512 * 1024 * (HUGEINT(ReadBitfield(raw, CardCsd_CSizeOfs2, CardCsd_CSizeWidth2)) + 1);
  2173. END;
  2174. csd.commandClasses := SYSTEM.VAL(SET, ReadBitfield(raw, CardCsd_CccOfs, CardCsd_CccWidth));
  2175. csd.nsac := ReadBitfield(raw, CardCsd_NsacOfs, CardCsd_NsacWidth) * 100;
  2176. val := ReadBitfield(raw, CardCsd_R2wFactorOfs, CardCsd_R2wFactorWidth);
  2177. IF val >= 6 THEN
  2178. csd.r2w := 0
  2179. ELSE
  2180. csd.r2w := LSH(LONGINT(1), val);
  2181. END;
  2182. val := ReadBitfield(raw, CardCsd_TranSpeedOfs, CardCsd_TranSpeedWidth);
  2183. CASE val DIV 8 OF
  2184. 1: csd.txSpeed := 10
  2185. |2: csd.txSpeed := 12
  2186. |3: csd.txSpeed := 13
  2187. |4: csd.txSpeed := 15
  2188. |5: csd.txSpeed := 20
  2189. |6: csd.txSpeed := 25
  2190. |7: csd.txSpeed := 30
  2191. |8: csd.txSpeed := 35
  2192. |9: csd.txSpeed := 40
  2193. |10: csd.txSpeed := 45
  2194. |11: csd.txSpeed := 50
  2195. |12: csd.txSpeed := 55
  2196. |13: csd.txSpeed := 60
  2197. |14: csd.txSpeed := 70
  2198. |15: csd.txSpeed := 80
  2199. ELSE
  2200. csd.txSpeed := 00
  2201. END;
  2202. csd.txSpeed := csd.txSpeed * 100;
  2203. CASE val MOD 8 OF
  2204. 0: csd.txSpeed := csd.txSpeed * 100
  2205. |1: csd.txSpeed := csd.txSpeed * 1000
  2206. |2: csd.txSpeed := csd.txSpeed * 10000
  2207. |3: csd.txSpeed := csd.txSpeed * 100000
  2208. END;
  2209. val := ReadBitfield(raw, CardCsd_TaacOfs, CardCsd_TaacWidth);
  2210. CASE val DIV 8 OF
  2211. 1: real := 1.0
  2212. |2: real := 1.2
  2213. |3: real := 1.3
  2214. |4: real := 1.5
  2215. |5: real := 2.0
  2216. |6: real := 2.5
  2217. |7: real := 3.0
  2218. |8: real := 3.5
  2219. |9: real := 4.0
  2220. |10: real := 4.5
  2221. |11: real := 5.0
  2222. |12: real := 5.5
  2223. |13: real := 6.0
  2224. |14: real := 7.0
  2225. |15: real := 8.0
  2226. ELSE
  2227. real := 0.0
  2228. END;
  2229. CASE val MOD 8 OF
  2230. 0: real := real * 1.0E-9
  2231. |1: real := real * 1.0E-8
  2232. |2: real := real * 1.0E-7
  2233. |3: real := real * 1.0E-6
  2234. |4: real := real * 1.0E-5
  2235. |5: real := real * 1.0E-4
  2236. |6: real := real * 1.0E-3
  2237. |7: real := real * 1.0E-2
  2238. END;
  2239. csd.taac := real;
  2240. csd.partialRead := ReadBitfield(raw, CardCsd_ReadBlPartial, 1) = 1;
  2241. csd.misalignedRead := ReadBitfield(raw, CardCsd_ReadBlkMisalign, 1) = 1;
  2242. val := ReadBitfield(raw, CardCsd_ReadBlLenOfs, CardCsd_ReadBlLenWidth);
  2243. IF (val <= 8) OR (val >= 12) THEN
  2244. csd.readBlockSize := BlockSize
  2245. ELSE
  2246. csd.readBlockSize := LSH(LONGINT(1), val)
  2247. END;
  2248. csd.partialWrite := ReadBitfield(raw, CardCsd_WriteBlPartial, 1) = 1;
  2249. csd.misalignedWrite := ReadBitfield(raw, CardCsd_WriteBlkMisalign, 1) = 1;
  2250. val := ReadBitfield(raw, CardCsd_WriteBlLenOfs, CardCsd_WriteBlLenWidth);
  2251. IF (val <= 8) OR (val >= 12) THEN
  2252. csd.writeBlockSize := BlockSize
  2253. ELSE
  2254. csd.writeBlockSize := LSH(LONGINT(1), val)
  2255. END
  2256. END DecodeCsd;
  2257. (** Fills a SCR record from raw data bytes *)
  2258. PROCEDURE DecodeScr (CONST raw: ARRAY OF CHAR; ofs: LONGINT; VAR scr: Scr);
  2259. TYPE
  2260. Array = ARRAY 8 OF CHAR;
  2261. VAR
  2262. bfield: ARRAY 2 OF LONGINT;
  2263. i: LONGINT;
  2264. val: SET;
  2265. BEGIN
  2266. FOR i := 0 TO 7 DO SYSTEM.VAL(Array, bfield)[7-i] := raw[ofs + i] END;
  2267. IF ReadBitfield(bfield, CardScr_StructureOfs, CardScr_StructureWidth) # 0 THEN RETURN END;
  2268. scr.version := ReadBitfield(bfield, CardScr_SpecVersionOfs, CardScr_SpecVersionWidth);
  2269. IF ReadBitfield(bfield, CardScr_SpecV3, 1) # 0 THEN scr.version := Version3 END;
  2270. IF ReadBitfield(bfield, CardScr_SpecV4, 1) # 0 THEN scr.version := Version4 END;
  2271. i := ReadBitfield(bfield, CardScr_SpecVXOfs, CardScr_SpecVXWidth);
  2272. IF i = CardScr_SpecVX_v5 THEN scr.version := Version5
  2273. ELSIF i = CardScr_SpecVX_v6 THEN scr.version := Version6
  2274. END;
  2275. CASE ReadBitfield(bfield, CardScr_SecurityOfs, CardScr_SecurityWidth) OF
  2276. 0: scr.security := TypeNone
  2277. |2: scr.security := TypeSDSC
  2278. |3: scr.security := TypeSDHC
  2279. |4: scr.security := TypeSDXC
  2280. END;
  2281. val := SYSTEM.VAL(SET, ReadBitfield(bfield, CardScr_BusWidthsOfs, CardScr_BusWidthsWidth));
  2282. FOR i := 0 TO MAX(SET) - 1 DO
  2283. IF i IN val THEN
  2284. INCL(scr.busWidth, LSH(LONGINT(1), i))
  2285. END
  2286. END
  2287. END DecodeScr;
  2288. (**
  2289. Print the state of all Host Controller registers
  2290. *)
  2291. PROCEDURE PrintHcRegisters * (regs: HcRegisters);
  2292. BEGIN
  2293. IF EnableTrace THEN
  2294. Log.String("[SD] HC registers status:"); Log.Ln;
  2295. Log.String("[SD] SDMASystemAddress: 0x"); Log.Hex(regs.SDMASystemAddress,-SIZEOF(LONGINT)*2); Log.Ln;
  2296. Log.String("[SD] BlockSize: 0x"); Log.Hex(regs.BlockSize,-SIZEOF(INTEGER)*2); Log.Ln;
  2297. Log.String("[SD] BlockCount: 0x"); Log.Hex(regs.BlockCount,-SIZEOF(INTEGER)*2); Log.Ln;
  2298. Log.String("[SD] Argument1: 0x"); Log.Hex(regs.Argument1,-SIZEOF(LONGINT)*2); Log.Ln;
  2299. Log.String("[SD] TransferMode: 0x"); Log.Hex(regs.TransferMode,-SIZEOF(INTEGER)*2); Log.Ln;
  2300. Log.String("[SD] Command: 0x"); Log.Hex(regs.Command,-SIZEOF(INTEGER)*2); Log.Ln;
  2301. Log.String("[SD] Response: 0x");
  2302. Log.Hex(regs.Response[0],-SIZEOF(LONGINT)*2); Log.String(" 0x");
  2303. Log.Hex(regs.Response[1],-SIZEOF(LONGINT)*2); Log.String(" 0x");
  2304. Log.Hex(regs.Response[2],-SIZEOF(LONGINT)*2); Log.String(" 0x");
  2305. Log.Hex(regs.Response[3],-SIZEOF(LONGINT)*2); Log.Ln;
  2306. Log.String("[SD] BufferData: 0x"); Log.Hex(regs.BufferData,-SIZEOF(LONGINT)*2); Log.Ln;
  2307. Log.String("[SD] PresentState: "); Log.Set(regs.PresentState); Log.Ln;
  2308. Log.String("[SD] HostControl1: 0x"); Log.Hex(regs.HostControl1,-SIZEOF(SHORTINT)*2); Log.Ln;
  2309. Log.String("[SD] PowerControl: 0x"); Log.Hex(regs.PowerControl,-SIZEOF(SHORTINT)*2); Log.Ln;
  2310. Log.String("[SD] BlockGapControl: 0x"); Log.Hex(regs.BlockGapControl,-SIZEOF(SHORTINT)*2); Log.Ln;
  2311. Log.String("[SD] WakeupControl: 0x"); Log.Hex(regs.WakeupControl,-SIZEOF(SHORTINT)*2); Log.Ln;
  2312. Log.String("[SD] ClockControl: 0x"); Log.Hex(regs.ClockControl,-SIZEOF(INTEGER)*2); Log.Ln;
  2313. Log.String("[SD] TimeoutControl: 0x"); Log.Hex(regs.TimeoutControl,-SIZEOF(SHORTINT)*2); Log.Ln;
  2314. Log.String("[SD] SoftwareReset: 0x"); Log.Hex(regs.SoftwareReset,-SIZEOF(SHORTINT)*2); Log.Ln;
  2315. Log.String("[SD] InterruptStatus: "); Log.Set(regs.InterruptStatus); Log.Ln;
  2316. Log.String("[SD] InterruptStatusEnable: "); Log.Set(regs.InterruptStatusEnable); Log.Ln;
  2317. Log.String("[SD] InterruptSignalEnable: "); Log.Set(regs.InterruptSignalEnable); Log.Ln;
  2318. Log.String("[SD] AutoCmdErrorStatus: 0x"); Log.Hex(regs.AutoCmdErrorStatus,-SIZEOF(INTEGER)*2); Log.Ln;
  2319. Log.String("[SD] HostControl2: 0x"); Log.Hex(regs.HostControl2,-SIZEOF(INTEGER)*2); Log.Ln;
  2320. Log.String("[SD] Capabilities: ");
  2321. Log.Set(regs.Capabilities[0]); Log.String(" ");
  2322. Log.Set(regs.Capabilities[1]); Log.Ln;
  2323. (*Log.String("[SD] MaximumCurrentCapabilities: 0x"); Log.Hex(regs.MaximumCurrentCapabilities,-SIZEOF(HUGEINT)*2); Log.Ln;
  2324. Log.String("[SD] ForceEventAutoCmdErrorStatus: 0x"); Log.Hex(regs.ForceEventAutoCmdErrorStatus,-SIZEOF(INTEGER)*2); Log.Ln;
  2325. Log.String("[SD] ForceEventErrorInterruptStatus: 0x"); Log.Hex(regs.ForceEventErrorInterruptStatus,-SIZEOF(INTEGER)*2); Log.Ln;
  2326. Log.String("[SD] AdmaErrorStatus: 0x"); Log.Hex(regs.AdmaErrorStatus,-SIZEOF(SHORTINT)*2); Log.Ln;
  2327. Log.String("[SD] AdmaSystemAddress: 0x"); Log.Hex(regs.AdmaSystemAddress,-SIZEOF(HUGEINT)*2); Log.Ln;*)
  2328. Log.String("[SD] PresetValues: 0x");
  2329. Log.Hex(regs.PresetValues[0],-SIZEOF(INTEGER)*2); Log.String(" 0x");
  2330. Log.Hex(regs.PresetValues[1],-SIZEOF(INTEGER)*2); Log.String(" 0x");
  2331. Log.Hex(regs.PresetValues[2],-SIZEOF(INTEGER)*2); Log.String(" 0x");
  2332. Log.Hex(regs.PresetValues[3],-SIZEOF(INTEGER)*2); Log.String(" 0x");
  2333. Log.Hex(regs.PresetValues[4],-SIZEOF(INTEGER)*2); Log.String(" 0x");
  2334. Log.Hex(regs.PresetValues[5],-SIZEOF(INTEGER)*2); Log.String(" 0x");
  2335. Log.Hex(regs.PresetValues[6],-SIZEOF(INTEGER)*2); Log.String(" 0x");
  2336. Log.Hex(regs.PresetValues[7],-SIZEOF(INTEGER)*2); Log.Ln;
  2337. Log.String("[SD] SharedBusControl: 0x"); Log.Hex(regs.SharedBusControl,-SIZEOF(LONGINT)*2); Log.Ln;
  2338. Log.String("[SD] SlotInterruptStatus: 0x"); Log.Hex(regs.SlotInterruptStatus,-SIZEOF(INTEGER)*2); Log.Ln;
  2339. Log.String("[SD] HostControllerVersion: 0x"); Log.Hex(regs.HostControllerVersion,-SIZEOF(INTEGER)*2); Log.Ln
  2340. END
  2341. END PrintHcRegisters;
  2342. (** Outputs the capabilities of a host controller on the log. *)
  2343. PROCEDURE PrintCapabilities * (hc: HostController);
  2344. VAR
  2345. c0, c1: SET;
  2346. BEGIN
  2347. IF EnableTrace THEN
  2348. c0 := hc.regs.Capabilities[0];
  2349. c1 := hc.regs.Capabilities[1];
  2350. Log.String("[SD] "); Log.String("Host Capabilities:"); Log.Ln;
  2351. Log.String("[SD] "); Log.String(" Timeout Clock Frequency: ");
  2352. IF c0 * Capabilities_TimeoutClockFrequencyMask = {} THEN
  2353. Log.String("Unknown")
  2354. ELSE
  2355. Log.Int(SYSTEM.VAL(LONGINT, c0 * Capabilities_TimeoutClockFrequencyMask), 0);
  2356. IF Capabilities_TimeoutClockUnit IN c0 THEN
  2357. Log.String(" MHz")
  2358. ELSE
  2359. Log.String(" kHz")
  2360. END
  2361. END;
  2362. Log.Ln;
  2363. Log.String("[SD] "); Log.String(" Base Clock Frequency: ");
  2364. IF c0 * Capabilities_BaseClockFreqSdMask = {} THEN
  2365. Log.String("Unknown")
  2366. ELSE
  2367. Log.Int(LSH(SYSTEM.VAL(LONGINT, c0 * Capabilities_BaseClockFreqSdMask), -Capabilities_BaseClockFreqSdOfs), 0)
  2368. END;
  2369. Log.Ln;
  2370. Log.String("[SD] "); Log.String(" Max Block Length: ");
  2371. Log.Int(512 * (1 + LSH(SYSTEM.VAL(LONGINT, c0 * Capabilities_MaxBlockLenMask), -Capabilities_MaxBlockLenOfs)), 0);
  2372. Log.String(" B");
  2373. Log.Ln;
  2374. Log.String("[SD] "); Log.String(" 8 Bit Support for Embedded Device: ");
  2375. Log.Boolean(Capabilities_8BitEmbedded IN c0);
  2376. Log.Ln;
  2377. Log.String("[SD] "); Log.String(" Support for ADMA2: ");
  2378. Log.Boolean(Capabilities_ADMA2 IN c0);
  2379. Log.Ln;
  2380. Log.String("[SD] "); Log.String(" Support for High Speed: ");
  2381. Log.Boolean(Capabilities_HighSpeed IN c0);
  2382. Log.Ln;
  2383. Log.String("[SD] "); Log.String(" Support for SDMA: ");
  2384. Log.Boolean(Capabilities_SDMA IN c0);
  2385. Log.Ln;
  2386. Log.String("[SD] "); Log.String(" Support for Suspend/Resume: ");
  2387. Log.Boolean(Capabilities_SuspendResume IN c0);
  2388. Log.Ln;
  2389. Log.String("[SD] "); Log.String(" Voltage Support for 3.3 V: ");
  2390. Log.Boolean(Capabilities_Voltage33 IN c0);
  2391. Log.Ln;
  2392. Log.String("[SD] "); Log.String(" Voltage Support for 3.0 V: ");
  2393. Log.Boolean(Capabilities_Voltage30 IN c0);
  2394. Log.Ln;
  2395. Log.String("[SD] "); Log.String(" Voltage Support for 1.8 V: ");
  2396. Log.Boolean(Capabilities_Voltage18 IN c0);
  2397. Log.Ln;
  2398. Log.String("[SD] "); Log.String(" Support for 64 Bit Bus: ");
  2399. Log.Boolean(Capabilities_64BitBus IN c0);
  2400. Log.Ln;
  2401. Log.String("[SD] "); Log.String(" Support for Asynchronous Interrupts: ");
  2402. Log.Boolean(Capabilities_AsyncInterrupt IN c0);
  2403. Log.Ln;
  2404. Log.String("[SD] "); Log.String(" Slot Type: ");
  2405. IF c0 * Capabilities_SlotTypeMask = Capabilities_SlotType_Removable THEN
  2406. Log.String("Removable Card Slot")
  2407. ELSIF c0 * Capabilities_SlotTypeMask = Capabilities_SlotType_Embedded THEN
  2408. Log.String("Embedded Slot for One Device")
  2409. ELSIF c0 * Capabilities_SlotTypeMask = Capabilities_SlotType_SharedBus THEN
  2410. Log.String("Shared Bus Slot")
  2411. END;
  2412. Log.Ln;
  2413. IF hc.version = 3 THEN
  2414. Log.String("[SD] "); Log.String(" Support for SDR50: ");
  2415. Log.Boolean(Capabilities_SDR50 IN c1);
  2416. Log.Ln;
  2417. Log.String("[SD] "); Log.String(" Support for SDR104: ");
  2418. Log.Boolean(Capabilities_SDR104 IN c1);
  2419. Log.Ln;
  2420. Log.String("[SD] "); Log.String(" Support for DDR50: ");
  2421. Log.Boolean(Capabilities_DDR50 IN c1);
  2422. Log.Ln;
  2423. Log.String("[SD] "); Log.String(" Support for Driver Type A: ");
  2424. Log.Boolean(Capabilities_DriverTypeA IN c1);
  2425. Log.Ln;
  2426. Log.String("[SD] "); Log.String(" Support for Driver Type C: ");
  2427. Log.Boolean(Capabilities_DriverTypeC IN c1);
  2428. Log.Ln;
  2429. Log.String("[SD] "); Log.String(" Support for Driver Type D: ");
  2430. Log.Boolean(Capabilities_DriverTypeD IN c1);
  2431. Log.Ln;
  2432. Log.String("[SD] "); Log.String(" Timer Count for Retuning: ");
  2433. IF c1 * Capabilities_TimerCountRetuningMask = Capabilities_TimerCountRetuningMask THEN
  2434. Log.String("Unknown")
  2435. ELSIF c1 * Capabilities_TimerCountRetuningMask = {} THEN
  2436. Log.String("Disabled")
  2437. ELSE
  2438. Log.Int(LSH(LONGINT(1), LSH(SYSTEM.VAL(LONGINT, c1 * Capabilities_TimerCountRetuningMask), -Capabilities_TimerCountRetuningOfs)), 0);
  2439. Log.String(" s")
  2440. END;
  2441. Log.Ln;
  2442. Log.String("[SD] "); Log.String(" SDR50 Requires Retuning: ");
  2443. Log.Boolean(Capabilities_TuningSDR50 IN c1);
  2444. Log.Ln;
  2445. Log.String("[SD] "); Log.String(" Retuning Mode: ");
  2446. Log.Int(LSH(SYSTEM.VAL(LONGINT, c1 * Capabilities_RetuningModesMask), -Capabilities_RetuningModesOfs), 0);
  2447. Log.Ln;
  2448. Log.String("[SD] "); Log.String(" Clock Multiplier: ");
  2449. IF c1 * Capabilities_ClockMultiplierMask = {} THEN
  2450. Log.String("Not Supported")
  2451. ELSE
  2452. Log.Int(LSH(SYSTEM.VAL(LONGINT, c1 * Capabilities_ClockMultiplierMask), -Capabilities_ClockMultiplierOfs) + 1, 0)
  2453. END;
  2454. Log.Ln
  2455. END
  2456. END
  2457. END PrintCapabilities;
  2458. (** Print a card status response on the log. *)
  2459. PROCEDURE PrintCardStatus * (status: SET);
  2460. BEGIN
  2461. IF EnableTrace THEN
  2462. Log.String("[SD] Card Status:"); Log.Ln;
  2463. Log.String("[SD] AKE Error: "); Log.Boolean(CardStatus_AkeSpecError IN status); Log.Ln;
  2464. Log.String("[SD] App Command: "); Log.Boolean(CardStatus_AppCmd IN status); Log.Ln;
  2465. Log.String("[SD] Ready For Data: "); Log.Boolean(CardStatus_ReadyForData IN status); Log.Ln;
  2466. Log.String("[SD] Card State: ");
  2467. CASE LSH(SYSTEM.VAL(LONGINT, status * CardStatus_CurrentStateMask), -CardStatus_CurrentStateOffset) OF
  2468. CardIdle: Log.String("Idle")
  2469. |CardReady: Log.String("Ready")
  2470. |CardIdentification: Log.String("Identification")
  2471. |CardStandby: Log.String("Standby")
  2472. |CardTransfer: Log.String("Transfer")
  2473. |CardData: Log.String("Sending Data")
  2474. |CardReceive: Log.String("Receiving Data")
  2475. |CardProgram: Log.String("Programming")
  2476. |CardDisabled: Log.String("Disabled")
  2477. END;
  2478. Log.Ln;
  2479. Log.String("[SD] Erase Reset: "); Log.Boolean(CardStatus_EraseReset IN status); Log.Ln;
  2480. Log.String("[SD] Internal ECC Enable: "); Log.Boolean(CardStatus_CardEccDisable IN status); Log.Ln;
  2481. Log.String("[SD] Write_Protection Erase Skip: "); Log.Boolean(CardStatus_WpEraseSkip IN status); Log.Ln;
  2482. Log.String("[SD] CSD Overwrite: "); Log.Boolean(CardStatus_CsdOverwrite IN status); Log.Ln;
  2483. Log.String("[SD] Error: "); Log.Boolean(CardStatus_Error IN status); Log.Ln;
  2484. Log.String("[SD] Card Controller Error: "); Log.Boolean(CardStatus_CcError IN status); Log.Ln;
  2485. Log.String("[SD] Card ECC Failed: "); Log.Boolean(CardStatus_CardEccFailed IN status); Log.Ln;
  2486. Log.String("[SD] Illegal Command: "); Log.Boolean(CardStatus_IllegalCommand IN status); Log.Ln;
  2487. Log.String("[SD] Command CRC Error: "); Log.Boolean(CardStatus_ComCrcError IN status); Log.Ln;
  2488. Log.String("[SD] Lock/Unlock Failed: "); Log.Boolean(CardStatus_LockUnlockFailed IN status); Log.Ln;
  2489. Log.String("[SD] Card is Locked: "); Log.Boolean(CardStatus_CardIsLocked IN status); Log.Ln;
  2490. Log.String("[SD] Write-Protection Violation: "); Log.Boolean(CardStatus_WpViolation IN status); Log.Ln;
  2491. Log.String("[SD] Invalid Erase Parameters: "); Log.Boolean(CardStatus_EraseParam IN status); Log.Ln;
  2492. Log.String("[SD] Erase Sequence Error: "); Log.Boolean(CardStatus_EraseSeqError IN status); Log.Ln;
  2493. Log.String("[SD] Block Length Error: "); Log.Boolean(CardStatus_BlockLenError IN status); Log.Ln;
  2494. Log.String("[SD] Address Error: "); Log.Boolean(CardStatus_AddressError IN status); Log.Ln;
  2495. Log.String("[SD] Argument Out of Range: "); Log.Boolean(CardStatus_OutOfRange IN status); Log.Ln
  2496. END
  2497. END PrintCardStatus;
  2498. (** Print SD Status record *)
  2499. PROCEDURE PrintSdStatus * (status: SdStatus);
  2500. BEGIN
  2501. IF EnableTrace THEN
  2502. Log.String("[SD] SD Status"); Log.Ln;
  2503. Log.String("[SD] data bus width: "); Log.Int(status.dataBusWidth, 0); Log.Ln;
  2504. Log.String("[SD] secured mode enabled: "); Log.Boolean(status.securedMode); Log.Ln;
  2505. Log.String("[SD] cardType: ");
  2506. CASE status.cardType OF
  2507. CategoryRW: Log.String("normal RW card")
  2508. |CategoryRO: Log.String("read-only card")
  2509. |CategoryOTP: Log.String("one-time programmable card")
  2510. END; Log.Ln;
  2511. Log.String("[SD] size of protected area: "); PrintSize(status.sizeProtArea); Log.Ln;
  2512. Log.String("[SD] move performance: ");
  2513. CASE status.perfMove OF
  2514. 0: Log.String("sequential write")
  2515. |255: Log.String("infinite")
  2516. ELSE
  2517. Log.Int(status.perfMove, 0);
  2518. Log.String(" MB/s")
  2519. END; Log.Ln;
  2520. Log.String("[SD] erase size: "); Log.Int(status.eraseSize, 0); Log.String(" AUs"); Log.Ln;
  2521. Log.String("[SD] erase timeout: ");
  2522. IF status.eraseTimeout = 0 THEN
  2523. Log.String("not supported")
  2524. ELSE
  2525. Log.Int(status.eraseTimeout, 0); Log.String(" s")
  2526. END; Log.Ln;
  2527. Log.String("[SD] erase timeout offset: "); Log.Int(status.eraseOffset, 0); Log.String(" s"); Log.Ln;
  2528. Log.String("[SD] speed class: "); Log.Int(status.speedClass, 0); Log.Ln;
  2529. Log.String("[SD] AU size: "); PrintSize(status.auSize); Log.Ln;
  2530. Log.String("[SD] UHS speed grade: "); Log.Int(status.uhsSpeedGrade, 0); Log.Ln;
  2531. Log.String("[SD] UHS AU size: "); PrintSize(status.uhsAuSize); Log.Ln;
  2532. Log.String("[SD] video speed class: "); Log.Int(status.vscSpeedClass, 0); Log.Ln;
  2533. Log.String("[SD] VSC AU size: "); PrintSize(status.vscAuSize); Log.Ln;
  2534. Log.String("[SD] suspension address: "); Log.Int(status.suspensionAdr, 0); Log.Ln;
  2535. Log.String("[SD] application performance class: ");
  2536. IF status.appPerfClass = 0 THEN
  2537. Log.String("not supported")
  2538. ELSE
  2539. Log.String("A");
  2540. Log.Int(status.appPerfClass, 0)
  2541. END; Log.Ln;
  2542. Log.String("[SD] performance enhance: ");
  2543. IF status.perfEnhance = {} THEN Log.String("none") END;
  2544. IF PerformanceCardMaintenance IN status.perfEnhance THEN Log.String("card-initiated maintenance; ") END;
  2545. IF PerformanceHostMaintenance IN status.perfEnhance THEN Log.String("host-initiated maintenance; ") END;
  2546. IF PerformanceCache IN status.perfEnhance THEN Log.String("cache; ") END;
  2547. IF PerformanceQueue IN status.perfEnhance THEN
  2548. Log.String("command queue;"); Log.Ln;
  2549. Log.String("[SD] command queue depth: ");
  2550. Log.Int(status.commandQueueDepth, 0)
  2551. END; Log.Ln;
  2552. Log.String("[SD] discard supported: "); Log.Boolean(status.discardSupport); Log.Ln;
  2553. Log.String("[SD] FULE supported: "); Log.Boolean(status.fuleSupport); Log.Ln
  2554. END
  2555. END PrintSdStatus;
  2556. (** Print the CID of a card to the log. *)
  2557. PROCEDURE PrintCardCid * (cid: Cid);
  2558. BEGIN
  2559. IF EnableTrace THEN
  2560. Log.String("[SD] CID"); Log.Ln;
  2561. Log.String("[SD] manufacturing date: "); Log.Int(cid.manufacturingDate.month, 0); Log.String("/"); Log.Int(cid.manufacturingDate.year, 0); Log.Ln;
  2562. Log.String("[SD] product serial number: "); Log.Int(cid.productSerialNumber, 0); Log.Ln;
  2563. Log.String("[SD] product revision: "); Log.Int(cid.productRevision.n, 0); Log.String("."); Log.Int(cid.productRevision.m, 0); Log.Ln;
  2564. Log.String("[SD] product name: "); Log.String(cid.productName); Log.Ln;
  2565. Log.String("[SD] OEM/application id: "); Log.String(cid.oemId); Log.Ln;
  2566. Log.String("[SD] manufacturer id: "); Log.Int(cid.manufacturerId, 0); Log.Ln
  2567. END
  2568. END PrintCardCid;
  2569. (** Print the CSD of a card to the log. *)
  2570. PROCEDURE PrintCardCsd * (CONST csd: ARRAY OF LONGINT);
  2571. VAR
  2572. cap: HUGEINT;
  2573. val, version, sizeMult: LONGINT;
  2574. BEGIN
  2575. IF EnableTrace THEN
  2576. version := ReadBitfield(csd, CardCsd_CsdStructureOfs, CardCsd_CsdStructureWidth) + 1;
  2577. Log.String("[SD] "); Log.String("Card CSD:"); Log.Ln;
  2578. Log.String("[SD] "); Log.String(" Version: "); Log.Int(version, 0); Log.Ln;
  2579. (* Common Fields *)
  2580. Log.String("[SD] "); Log.String(" File Format: ");
  2581. val := ReadBitfield(csd, CardCsd_FileFormatOfs, CardCsd_FileFormatWidth);
  2582. IF ReadBitfield(csd, CardCsd_FileFormatGrp, 1) = 1 THEN
  2583. Log.String("Unknown Value (");
  2584. Log.Int(val, 0);
  2585. Log.String(")")
  2586. ELSIF val = 0 THEN
  2587. Log.String("Hard-disk file system with partition table")
  2588. ELSIF val = 1 THEN
  2589. Log.String("FAT")
  2590. ELSIF val = 2 THEN
  2591. Log.String("Universal File Format")
  2592. ELSE
  2593. Log.String("Other")
  2594. END;
  2595. Log.Ln;
  2596. Log.String("[SD] "); Log.String(" Temporary Write Protection: "); Log.Boolean(ReadBitfield(csd, CardCsd_TmpWriteProtect, 1) = 1); Log.Ln;
  2597. Log.String("[SD] "); Log.String(" Permanent Write Protection: "); Log.Boolean(ReadBitfield(csd, CardCsd_PermWriteProtect, 1) = 1); Log.Ln;
  2598. Log.String("[SD] "); Log.String(" Copy: "); Log.Boolean(ReadBitfield(csd, CardCsd_Copy, 1) = 1); Log.Ln;
  2599. Log.String("[SD] "); Log.String(" Partial Block Write: "); Log.Boolean(ReadBitfield(csd, CardCsd_WriteBlPartial, 1) = 1); Log.Ln;
  2600. Log.String("[SD] "); Log.String(" Maximum Write Block Length: ");
  2601. val := ReadBitfield(csd, CardCsd_WriteBlLenOfs, CardCsd_WriteBlLenWidth);
  2602. IF (val <= 8) OR (val >= 12) THEN
  2603. Log.String("Unknown Value (");
  2604. Log.Int(val, 0);
  2605. Log.String(")")
  2606. ELSE
  2607. Log.Int(LSH(LONGINT(1), val), 0);
  2608. END;
  2609. Log.Ln;
  2610. Log.String("[SD] "); Log.String(" Block Program Time / Block Read Time: ");
  2611. val := ReadBitfield(csd, CardCsd_R2wFactorOfs, CardCsd_R2wFactorWidth);
  2612. IF val >= 6 THEN
  2613. Log.String("Unknown Value (");
  2614. Log.Int(val, 0);
  2615. Log.String(")")
  2616. ELSE
  2617. Log.Int(LSH(LONGINT(1), val), 0);
  2618. END;
  2619. Log.Ln;
  2620. Log.String("[SD] "); Log.String(" Group Write Protection: "); Log.Boolean(ReadBitfield(csd, CardCsd_WpGrpEnable, 1) = 1); Log.Ln;
  2621. Log.String("[SD] "); Log.String(" WpGrpSize: "); Log.Int(ReadBitfield(csd, CardCsd_WpGrpSizeOfs, CardCsd_WpGrpSizeWidth) + 1, 0); Log.String(" sectors"); Log.Ln;
  2622. Log.String("[SD] "); Log.String(" Sector Size: "); Log.Int(ReadBitfield(csd, CardCsd_SectorSizeOfs, CardCsd_SectorSizeWidth) + 1, 0); Log.Ln;
  2623. Log.String("[SD] "); Log.String(" Erase Block Enable: "); Log.Boolean(ReadBitfield(csd, CardCsd_EraseBlkEn, 1) = 1); Log.Ln;
  2624. IF version = 1 THEN
  2625. sizeMult := LSH(LONGINT(2), ReadBitfield(csd, CardCsd_CSizeMultOfs1, CardCsd_CSizeMultWidth1));
  2626. cap := sizeMult * (1 + ReadBitfield(csd, CardCsd_CSizeOfs1, CardCsd_CSizeWidth1)) * 512;
  2627. ELSE
  2628. cap := 512 * 1024 * (HUGEINT(ReadBitfield(csd, CardCsd_CSizeOfs2, CardCsd_CSizeWidth2)) + 1);
  2629. END;
  2630. Log.String("[SD] "); Log.String(" Card Capacity: "); Log.Int(cap, 0); Log.String(" B"); Log.Ln;
  2631. Log.String("[SD] "); Log.String(" DSR Implemented: "); Log.Boolean(ReadBitfield(csd, CardCsd_DsrImp, 1) = 1); Log.Ln;
  2632. Log.String("[SD] "); Log.String(" Misaligned Block Read: "); Log.Boolean(ReadBitfield(csd, CardCsd_ReadBlkMisalign, 1) = 1); Log.Ln;
  2633. Log.String("[SD] "); Log.String(" Misaligned Block Write: "); Log.Boolean(ReadBitfield(csd, CardCsd_WriteBlkMisalign, 1) = 1); Log.Ln;
  2634. Log.String("[SD] "); Log.String(" Partial Block Read: "); Log.Boolean(ReadBitfield(csd, CardCsd_ReadBlPartial, 1) = 1); Log.Ln;
  2635. (*ASSERT(ReadBitfield(csd, CardCsd_ReadBlPartial, 1) = 1);*)
  2636. Log.String("[SD] "); Log.String(" Maximal Block Read Length: ");
  2637. val := ReadBitfield(csd, CardCsd_ReadBlLenOfs, CardCsd_ReadBlLenWidth);
  2638. IF (val <= 8) OR (val >= 12) THEN
  2639. Log.String("Unknown Value (");
  2640. Log.Int(val, 0);
  2641. Log.String(")")
  2642. ELSE
  2643. Log.Int(LSH(LONGINT(1), val), 0); Log.String(" B")
  2644. END;
  2645. Log.Ln;
  2646. Log.String("[SD] "); Log.String(" Supported Command Classes: "); Log.Set(SYSTEM.VAL(SET, ReadBitfield(csd, CardCsd_CccOfs, CardCsd_CccWidth))); Log.Ln;
  2647. Log.String("[SD] "); Log.String(" Transfer Speed: ");
  2648. val := ReadBitfield(csd, CardCsd_TranSpeedOfs, CardCsd_TranSpeedWidth);
  2649. CASE val DIV 8 OF
  2650. 1: Log.String("1.0")
  2651. |2: Log.String("1.2")
  2652. |3: Log.String("1.3")
  2653. |4: Log.String("1.5")
  2654. |5: Log.String("2.0")
  2655. |6: Log.String("2.0")
  2656. |7: Log.String("2.5")
  2657. |8: Log.String("3.5")
  2658. |9: Log.String("4.0")
  2659. |10: Log.String("4.5")
  2660. |11: Log.String("5.0")
  2661. |12: Log.String("5.5")
  2662. |13: Log.String("6.0")
  2663. |14: Log.String("7.0")
  2664. |15: Log.String("8.0")
  2665. ELSE
  2666. Log.String("Unknown Value (");
  2667. Log.Int(val, 0);
  2668. Log.String(")")
  2669. END;
  2670. Log.String(" * 1");
  2671. CASE val MOD 8 OF
  2672. 0: Log.String("00 k")
  2673. |1: Log.String(" M")
  2674. |2: Log.String("0 M")
  2675. |3: Log.String("00 M")
  2676. END;
  2677. Log.String("Bit/s");
  2678. Log.Ln;
  2679. Log.String("[SD] "); Log.String(" Clock-Dependent Access Time: "); Log.Int(ReadBitfield(csd, CardCsd_NsacOfs, CardCsd_NsacWidth) * 100, 0); Log.String("000 clock cycles"); Log.Ln;
  2680. Log.String("[SD] "); Log.String(" Asynchronous Access Time: ");
  2681. val := ReadBitfield(csd, CardCsd_TaacOfs, CardCsd_TaacWidth);
  2682. CASE val DIV 8 OF
  2683. 1: Log.String("1.0")
  2684. |2: Log.String("1.2")
  2685. |3: Log.String("1.3")
  2686. |4: Log.String("1.5")
  2687. |5: Log.String("2.0")
  2688. |6: Log.String("2.5")
  2689. |7: Log.String("3.0")
  2690. |8: Log.String("3.5")
  2691. |9: Log.String("4.0")
  2692. |10: Log.String("4.5")
  2693. |11: Log.String("5.0")
  2694. |12: Log.String("5.5")
  2695. |13: Log.String("6.0")
  2696. |14: Log.String("7.0")
  2697. |15: Log.String("8.0")
  2698. ELSE
  2699. Log.String("Unknown Value (");
  2700. Log.Int(val, 0);
  2701. Log.String(")")
  2702. END;
  2703. Log.String(" * 1");
  2704. CASE val MOD 8 OF
  2705. 0: Log.String(" ns")
  2706. |1: Log.String("0 ns")
  2707. |2: Log.String("00 ns")
  2708. |3: Log.String(" microsecond")
  2709. |4: Log.String("0 microsecond")
  2710. |5: Log.String("00 microsecond")
  2711. |6: Log.String(" ms")
  2712. |7: Log.String("0 ms")
  2713. END;
  2714. Log.Ln
  2715. END
  2716. END PrintCardCsd;
  2717. PROCEDURE PrintCardScr * (CONST scr: Scr);
  2718. VAR i: LONGINT;
  2719. BEGIN
  2720. IF EnableTrace THEN
  2721. Log.String("[SD] Card SCR"); Log.Ln;
  2722. Log.String("[SD] physical layer version: ");
  2723. CASE scr.version OF
  2724. Version1: Log.String("1")
  2725. |Version1p1: Log.String("1.1")
  2726. |Version2: Log.String("2")
  2727. |Version3: Log.String("3")
  2728. |Version4: Log.String("4")
  2729. |Version5: Log.String("5")
  2730. |Version6: Log.String("6")
  2731. ELSE
  2732. Log.String("unknown")
  2733. END;
  2734. Log.Ln;
  2735. Log.String("[SD] security support: ");
  2736. CASE scr.security OF
  2737. TypeNone: Log.String("none")
  2738. |TypeSDSC: Log.String("SDSC")
  2739. |TypeSDHC: Log.String("SDHC")
  2740. |TypeSDXC: Log.String("SDXC")
  2741. END;
  2742. Log.Ln;
  2743. Log.String("[SD] supported bus widths: "); Log.Set(scr.busWidth); Log.Ln
  2744. END
  2745. END PrintCardScr;
  2746. (** Helper to write a size in a human-readable format *)
  2747. PROCEDURE PrintSize (size: HUGEINT);
  2748. VAR
  2749. prefix: ARRAY 8 OF CHAR;
  2750. i: LONGINT;
  2751. BEGIN
  2752. IF size < 1024 THEN
  2753. Log.Int(size, 0);
  2754. Log.String(" ")
  2755. ELSE
  2756. prefix := 'kMGT';
  2757. i := 0;
  2758. size := size DIV 1024;
  2759. WHILE size > 1024 DO
  2760. size := size DIV 1024;
  2761. INC(i)
  2762. END;
  2763. Log.Int(size, 0);
  2764. Log.String(" ");
  2765. Log.Char(prefix[i])
  2766. END;
  2767. Log.String("B")
  2768. END PrintSize;
  2769. (**
  2770. Helper procedure to read bit fields in a wide register.
  2771. field: large bitfield
  2772. ofs: offset of first bit to extract
  2773. width: number of bits to extract
  2774. Returns the bits as a LONGINT.
  2775. *)
  2776. PROCEDURE ReadBitfield (CONST field: ARRAY OF LONGINT; ofs, width: LONGINT): LONGINT;
  2777. VAR
  2778. adr, bits: ADDRESS;
  2779. BEGIN
  2780. ASSERT(ofs MOD 8 + width <= 32);
  2781. adr := ADDRESSOF(field[0]) + ofs DIV 8;
  2782. bits := SYSTEM.GET8(adr) MOD 100H;
  2783. IF ofs MOD 8 + width > 8 THEN
  2784. bits := bits + LSH(ADDRESS(SYSTEM.GET8(adr + 1)) MOD 100H, 8);
  2785. END;
  2786. IF ofs MOD 8 + width > 16 THEN
  2787. bits := bits + LSH(ADDRESS(SYSTEM.GET8(adr + 2)) MOD 100H, 16);
  2788. END;
  2789. IF ofs MOD 8 + width > 24 THEN
  2790. bits := bits + LSH(ADDRESS(SYSTEM.GET8(adr + 3)) MOD 100H, 24)
  2791. END;
  2792. RETURN SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, LSH(bits, -(ofs MOD 8))) * {0 .. width - 1})
  2793. END ReadBitfield;
  2794. PROCEDURE ReadBit (CONST field: ARRAY OF LONGINT; bit: LONGINT): BOOLEAN;
  2795. BEGIN
  2796. RETURN SYSTEM.VAL(BOOLEAN, LSH(SYSTEM.GET8(ADDRESSOF(field[0])) + bit DIV 8, -(bit MOD 8)))
  2797. END ReadBit;
  2798. PROCEDURE ResetStatistics *;
  2799. BEGIN
  2800. NbyteRead := 0;
  2801. Nread := 0;
  2802. Tread := 0;
  2803. NbyteWritten := 0;
  2804. Nwrite := 0;
  2805. Twrite := 0
  2806. END ResetStatistics;
  2807. END Sd.