diff options
author | Alexis Hovorka <[email protected]> | 2022-12-07 15:01:08 -0700 |
---|---|---|
committer | Alexis Hovorka <[email protected]> | 2022-12-07 15:01:08 -0700 |
commit | ab37031b1198778b2f559306658cb338cca5e551 (patch) | |
tree | 6619507d399bec2790818afaf1b0d0098bbbf8f5 | |
parent | 110204d48f34aa8a034dd182aa62503ed2a93f30 (diff) |
[feat] Add basic MicroSD card driver
-rw-r--r-- | io.notes | 1 | ||||
-rw-r--r-- | src/microsd.f1 | 505 |
2 files changed, 506 insertions, 0 deletions
@@ -24,6 +24,7 @@ C SPI ctl - 4 inky cmd - 5 inky data - 6 adc + - 7 ext (e.g. secondary MicroSD) D SPI dat - also incorporate busy/wait signal from tft/inky E GPIO0 diff --git a/src/microsd.f1 b/src/microsd.f1 new file mode 100644 index 0000000..ea23bbf --- /dev/null +++ b/src/microsd.f1 @@ -0,0 +1,505 @@ +// microsd.f1 +// -------------------------------------------- +// +// MicroSD access test +// +// Static variables: +// 003F sdhc (bool) +// +// -------------------------------------------- + +:busywait +1107F // addi 1,0,-1 // Set up 2s timer +22005 // lui 2,0140 +1223F // addi 2,2,3F + +// Sleep for ~2s +1117F // addi 1,1,-1 +6517E // bnz 1,-2 +1227F // addi 2,2,-1 +6527C // bnz 2,-2 + +50700 // ret + +// -------------------------------------------- + +:putchar // (char n) +32079 // lw 2,0,@uart +6127E // blz 2,-2 +41079 // sw 1,0,@uart +50700 // ret + +// -------------------------------------------- + +:xchgspi // (byte tx) -> byte rx +4107D // sw 1,0,@spi_dat +3107D // lw 1,0,@spi_dat +6117E // blz 1,-2 +01100 // lsbl 1,1 +50700 // ret + +:dualspi // (word tx) -> word rx +47600 // | push 7 +1667F // +------- + +02100 // lsbl 2,1 +01103 // msbl 1,1 +@xchgspi +01122 // xor 1,1,2 +02122 // xor 2,1,2 +01122 // xor 1,1,2 +@xchgspi +02207 // swpb 2,2 +01121 // or 1,1,2 + +16601 // +------ +37600 // | pop 7 +50700 // ret + +// -------------------------------------------- + +:WaitSD // -> byte response +47600 // | push 7 +1667F // +------- + +22008 // lui 2,0200 +1107F // addi 1,0,-1 +01100 // lsbl 1,1 + +13100 // mv 3,1 +@xchgspi +1227F // addi 2,2,-1 +62202 // bz 2,@ret +03315 // sub 3,3,1 +62379 // bz 3,@loop + +16601 // +------ +37600 // | pop 7 +50700 // ret + +// -------------------------------------------- + +:SendAndCRC // (byte byte, byte crc) -> byte crc (R2) +47600 // | push 7 +1667F // +------- + +02212 // xor 2,2,1 +@xchgspi + +13008 // addi 3,0,08 +// { +02224 // add 2,2,2 + +21004 // lui 1,0100 // +01120 // and 1,1,2 // +62102 // bz 1,@endif // if (crc & 0x0100) +11012 // addi 1,0,12 // crc = crc ^ 0x12; +02212 // xor 2,2,1 // + +1337F // addi 3,3,-1 +65378 // bnz 3,@loop +// } + +02200 // lsbl 2,2 + +16601 // +------ +37600 // | pop 7 +50700 // ret + +// -------------------------------------------- + +:CmdSD // (byte cmd, word a, word b) -> byte response +47600 // | push 7 +4467F // | push 4 +4367E // | push 3 +4267D // | push 2 +1667C // +------- + +14100 // mv 4,1 +@WaitSD + +12000 // mv 2,0 // let crc = 0; +11400 // mv 1,4 +@SendAndCRC // Send command + +16601 // addi 6,6,01 +34600 // lw 4,6,00 // pop 4 +01403 // msbl 1,4 +@SendAndCRC // Send first args +01400 // lsbl 1,4 +@SendAndCRC + +16601 // addi 6,6,01 +34600 // lw 4,6,00 // pop 4 +01403 // msbl 1,4 +@SendAndCRC // Send second args +01400 // lsbl 1,4 +@SendAndCRC + +11001 // addi 1,0,01 +01121 // or 1,1,2 +@xchgspi // Send CRC | 0x01 + +@WaitSD + +16602 // +------ +3467F // | pop 4 +37600 // | pop 7 +50700 // ret + +// -------------------------------------------- + +:1CMD // (byte cmd, word a, word b) -> byte response +47600 // | push 7 +4467F // | push 4 +1667E // +------- + +14002 // addi 4,0,02 // Set CS = 2 +4407C // sw 4,0,@spi_ctl +@CmdSD +4007C // sw 0,0,@spi_ctl // Set CS = 0 + +16602 // +------ +3467F // | pop 4 +37600 // | pop 7 +50700 // ret + +// -------------------------------------------- + +:7CMD // (byte cmd, word a, word b) -> (byte resp, word a, word b) +47600 // | push 7 +4467F // | push 4 +1667E // +------- + +14002 // addi 4,0,02 // Set CS = 2 +4407C // sw 4,0,@spi_ctl + +@CmdSD +14100 // mv 4,1 + +1107F // addi 1,0,-1 +@dualspi +13100 // mv 3,1 +1107F // addi 1,0,-1 +@dualspi +12300 // mv 2,3 +13100 // mv 3,1 + +11400 // mv 1,4 + +4007C // sw 0,0,@spi_ctl // Set CS = 0 + +16602 // +------ +3467F // | pop 4 +37600 // | pop 7 +50700 // ret + +// -------------------------------------------- + +:BADJ // (uint block) -> (_, rA, rB) // Block addr adjustment +3203F // lw 2,0,@sdhc // +62203 // bz 2,@else // if (sdhc) { +12000 // mv 2,0 // let ra = 0; +13100 // mv 3,1 // let rb = block; +50700 // ret // +12079 // addi 2,0,-7 // } else { +02123 // shl 2,1,2 // let ra = block >> 7; +13009 // addi 3,0,09 // let rb = block << 9; +03133 // shl 3,1,3 // } +50700 // ret // + +// -------------------------------------------- + +:InitSD +47600 // | push 7 +4467F // | push 4 +1667E // +------- + +@busywait // Tune to 2ms (at least 1ms) + +14005 // addi 4,0,05 // Send 10 dummy cycles +// { +1107F // addi 1,0,-1 +@dualspi +1447F // addi 4,4,-1 +6547B // bnz 4,@loop +// } + +1400A // addi 4,0,0A +// { +21001 // lui 1,0040 // CMD0 Idle +12000 // mv 2,0 +13000 // mv 3,0 +@1CMD +1117F // addi 1,1,-1 // Expected response: 0x01 +62102 // bz 1,@next +1447F // addi 4,4,-1 +65477 // bnz 4,@loop +// } + + // bnz 1,@Error // TODO + +// --------------------- + +21001 // lui 1,0040 +11108 // addi 1,1,08 // CMD8 Check Voltage (Used to check SD Version >= 2) +12000 // mv 2,0 +23006 // lui 3,0180 // rB = 0x01AA +1332A // addi 3,3,2A +14300 // mv 4,3 +@7CMD + // sub 3,3,4 + // addi 1,1,-1 // Expected response: 0x01, 0x0000, 0x01AA + // and 1,1,2 + // and 1,1,3 + // bnz 1,@Error // TODO + +// --------------------- + +// { +21001 // lui 1,0040 +11137 // addi 1,1,37 // CMD55 (app cmd prefix) +12000 // mv 2,0 +13000 // mv 3,0 +@1CMD +1117F // addi 1,1,-1 // Expected response: 0x01 + // bnz 1,@Error // TODO +21001 // lui 1,0040 +11129 // addi 1,1,29 // ACMD41 Initialize +22200 // lui 2,4000 +13000 // mv 3,0 +@1CMD +1117F // addi 1,1,-1 // Expected response: 0x00 or 0x01 + // bgz 1,@Error // TODO +62171 // bz 1,@loop +// } // Out of idle mode, success! + +// --------------------- + +21001 // lui 1,0040 +1113A // addi 1,1,3A // CMD58 Read OCR +12000 // mv 2,0 +13000 // mv 3,0 +@7CMD +21200 // lui 1,4000 +01120 // and 1,1,2 +4103F // sw 1,0,@sdhc + +// --------------------- + +65106 // bnz 1,@endif +21001 // lui 1,0040 +11110 // addi 1,1,10 // CMD16 Set block size (512b) +12000 // mv 2,0 +23008 // lui 3,0200 +@1CMD + +16602 // +------ +3467F // | pop 4 +37600 // | pop 7 +50700 // ret + +// -------------------------------------------- + +:crc16 // (word input, _, word crc) -> (_, _, word crc) +47600 // | push 7 +4467F // | push 4 +1667E // +------- + +04100 // lsbl 4,1 +01142 // xor 1,1,4 + +03132 // xor 3,1,3 +12008 // addi 2,0,08 + +// { +66305 // bge 3,@else // if (crc < 0) { +03334 // add 3,3,3 // let crc = crc + crc; +21040 // lui 1,1000 // let crc = crc ^ 0x1021; +11121 // addi 1,1,21 // +03132 // xor 3,1,3 // +67001 // j @endif // } else { +03334 // add 3,3,3 // let crc = crc + crc; +1227F // addi 2,2,-1 // } +65277 // bnz 2,@loop +// } + +01407 // swpb 1,4 +03132 // xor 3,1,3 +12008 // addi 2,0,08 + +// { +66305 // bge 3,@else // if (crc < 0) { +03334 // add 3,3,3 // let crc = crc + crc; +21040 // lui 1,1000 // let crc = crc ^ 0x1021; +11121 // addi 1,1,21 // +03132 // xor 3,1,3 // +67001 // j @endif // } else { +03334 // add 3,3,3 // let crc = crc + crc; +1227F // addi 2,2,-1 // } +65277 // bnz 2,@loop +// } + +16602 // +------ +3467F // | pop 4 +37600 // | pop 7 +50700 // ret + +// -------------------------------------------- + +:readBlock // (uint block, word dest) +47600 // | push 7 +4567F // | push 5 +4467E // | push 4 +1667D // +------- + +14002 // addi 4,0,02 // Set CS = 2 +4407C // sw 4,0,@spi_ctl +14200 // mv 4,2 + +@BADJ +21001 // lui 1,0040 +11111 // addi 1,1,11 // CMD17 +@CmdSD + // bnz 1,@Error // TODO + +@WaitSD + +22003 // lui 2,00C0 +1223E // addi 2,2,3E +02215 // sub 2,2,1 + // bnz 1,@Error // TODO + +13000 // mv 3,0 // let crc1 = 0; +25004 // lui 5,0100 // while (i --> 256) { +1107F // addi 1,0,-1 +@dualspi +41400 // sw 1,4,00 +14401 // addi 4,4,01 +@crc16 // let crc1 = SD.crc16(crc1, dest[i]); +1557F // addi 5,5,-1 +65577 // bnz 5,@loop // } + +1107F // addi 1,0,-1 +@dualspi // let crc2 = (SPI.transfer(0xFF), SPI.transfer(0xFF)); +04130 // sub 4,1,3 + +@WaitSD +4007C // sw 0,0,@spi_ctl // Set CS = 0 + + // bnz 4,@Error // if (~(crc1 = crc2)) { do SD.err(); } // TODO + +16603 // +------ +3467E // | pop 4 +3567F // | pop 5 +37600 // | pop 7 +50700 // ret + +// -------------------------------------------- + +:writeBlock // (uint block, word src) +47600 // | push 7 +4567F // | push 5 +4467E // | push 4 +1667D // +------- + +14002 // addi 4,0,02 // Set CS = 2 +4407C // sw 4,0,@spi_ctl +14200 // mv 4,2 + +@BADJ +21001 // lui 1,0040 +11118 // addi 1,1,18 // CMD24 +@CmdSD + // bnz 1,@Error // TODO + +1107E // addi 1,0,-2 +@dualspi + +13000 // mv 3,0 // let crc = 0; +25004 // lui 5,0100 // while (i --> 256) { +31400 // lw 1,4,00 +@dualspi +31400 // lw 1,4,00 +@crc16 // let crc = SD.crc16(crc, dest[i]); +14401 // addi 4,4,01 +1557F // addi 5,5,-1 +65577 // bnz 5,@loop // } + +11300 // mv 1,3 +@dualspi + +@WaitSD +1201F // addi 2,0,1F +01120 // and 1,1,2 +1117B // addi 1,1,-5 + // bnz 1,@Error // TODO + +// { +1107F // addi 1,0,-1 +01100 // lsbl 1,1 +@xchgspi +11101 // addi 1,1,01 +01100 // lsbl 1,1 +65179 // bnz 1,@loop // Wait until ready +// } + +4007C // sw 0,0,@spi_ctl // Set CS = 0 + +16603 // +------ +3467E // | pop 4 +3567F // | pop 5 +37600 // | pop 7 +50700 // ret + +// -------------------------------------------- + +:start +2677F // lui 6,FFC0 // Set up stack pointer +@InitSD + + +//11000 // mv 1,0 // Block number +//22400 // lui 2,8000 // Destination +//@readBlock +// +// +//22400 // lui 2,8000 +//2167A // lui 1,DE80 +//1112D // addi 1,1,2D +//41200 // sw 1,2,00 +//2157B // lui 1,BEC0 +//1112F // addi 1,1,2F +//41201 // sw 1,2,01 +// +// +//11000 // mv 1,0 // Block number +//22400 // lui 2,8000 // Destination +//@writeBlock + + +//11000 // mv 1,0 +21020 // lui 1,0800 // Block number +22400 // lui 2,8000 // Destination +@readBlock + + +23400 // lui 3,8000 +24004 // lui 4,0100 + +35300 // lw 5,3,00 +01503 // msbl 1,5 +@putchar +01500 // lsbl 1,5 +@putchar + +13301 // addi 3,3,01 +1447F // addi 4,4,-1 +65476 // bnz 4,@loop + + +6707F // wfi + + +@start +6707D // j -3 |