aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexis Hovorka <[email protected]>2022-12-07 15:01:08 -0700
committerAlexis Hovorka <[email protected]>2022-12-07 15:01:08 -0700
commitab37031b1198778b2f559306658cb338cca5e551 (patch)
tree6619507d399bec2790818afaf1b0d0098bbbf8f5
parent110204d48f34aa8a034dd182aa62503ed2a93f30 (diff)
[feat] Add basic MicroSD card driver
-rw-r--r--io.notes1
-rw-r--r--src/microsd.f1505
2 files changed, 506 insertions, 0 deletions
diff --git a/io.notes b/io.notes
index 1887bf5..167028f 100644
--- a/io.notes
+++ b/io.notes
@@ -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