Merge branch 'spi_master' into 'master'

add spi controller and sd asm code.

See merge request bslathi19/super6502!17
This commit is contained in:
Byron Lathi
2023-07-29 22:32:21 +00:00
25 changed files with 1539 additions and 1643 deletions

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
.vscode

View File

@@ -1,5 +0,0 @@
{
"files.associations": {
"conio.h": "c"
}
}

View File

@@ -8,7 +8,7 @@ module addr_decode
output o_multiplier_cs, output o_multiplier_cs,
output o_divider_cs, output o_divider_cs,
output o_uart_cs, output o_uart_cs,
output o_sdcard_cs, output o_spi_cs,
output o_sdram_cs output o_sdram_cs
); );
@@ -17,7 +17,7 @@ assign o_timer_cs = i_addr >= 16'heff8 && i_addr <= 16'heffb;
assign o_multiplier_cs = i_addr >= 16'heff0 && i_addr <= 16'heff7; assign o_multiplier_cs = i_addr >= 16'heff0 && i_addr <= 16'heff7;
assign o_divider_cs = i_addr >= 16'hefe8 && i_addr <= 16'hefef; assign o_divider_cs = i_addr >= 16'hefe8 && i_addr <= 16'hefef;
assign o_uart_cs = i_addr >= 16'hefe6 && i_addr <= 16'hefe7; assign o_uart_cs = i_addr >= 16'hefe6 && i_addr <= 16'hefe7;
assign o_sdcard_cs = i_addr >= 16'hefd8 && i_addr <= 16'hefdf; assign o_spi_cs = i_addr >= 16'hefd8 && i_addr <= 16'hefdb;
assign o_leds_cs = i_addr == 16'hefff; assign o_leds_cs = i_addr == 16'hefff;
assign o_sdram_cs = i_addr < 16'h8000; assign o_sdram_cs = i_addr < 16'h8000;

File diff suppressed because it is too large Load Diff

View File

@@ -1,207 +1,147 @@
@00000000 @00000000
4C 00 00 8D 11 02 8E 12 02 8D 18 02 8E 19 02 88 8D 0E 02 8E 0F 02 8D 15 02 8E 16 02 88 B9 FF FF
B9 FF FF 8D 22 02 88 B9 FF FF 8D 21 02 8C 24 02 8D 1F 02 88 B9 FF FF 8D 1E 02 8C 21 02 20 FF FF
20 FF FF A0 FF D0 E8 60 00 00 02 FB 00 00 00 00 A0 FF D0 E8 60 A2 FF 9A D8 A9 F0 85 00 A9 7E 85
A2 FF 9A D8 A9 F0 85 00 A9 7E 85 01 20 7A FB 20 01 20 72 F8 20 F0 F6 20 45 F0 58 20 03 F1 6C FC
05 F8 20 50 F0 58 20 29 F1 6C FC FF 20 F9 F7 00 FF 20 E4 F6 00 A0 00 F0 07 A9 45 A2 F0 4C 00 02
A0 00 F0 07 A9 50 A2 F0 4C 03 02 60 AD FF EF A2 60 AD FF EF A2 00 60 8D FF EF 60 20 E9 F0 C9 0A
00 60 8D FF EF 60 20 0F F1 C9 0A D0 05 A9 0D 20 D0 05 A9 0D 20 E9 F0 60 DA 5A A8 B2 00 AA A9 1B
0F F1 60 DA 5A A8 B2 00 AA A9 1B 20 0F F1 A9 5B 20 E9 F0 A9 5B 20 E9 F0 98 20 E9 F0 A9 3B 20 E9
20 0F F1 98 20 0F F1 A9 3B 20 0F F1 8A 20 0F F1 F0 8A 20 E9 F0 A9 48 20 E9 F0 7A FA 60 DA A9 1B
A9 48 20 0F F1 7A FA 60 DA A9 1B 20 0F F1 A9 63 20 E9 F0 A9 63 20 E9 F0 68 60 40 DA BA 48 E8 E8
20 0F F1 68 60 40 DA BA 48 E8 E8 BD 00 01 29 10 BD 00 01 29 10 D0 06 68 FA 20 02 F1 40 4C AD F0
D0 06 68 FA 20 28 F1 40 4C B8 F0 48 20 6B F9 8D 48 A0 04 B1 00 09 40 20 D9 F0 88 B1 00 20 D9 F0
D8 EF 8E D9 EF A5 02 8D DA EF A5 03 8D DB EF 68 88 10 F8 68 09 01 20 D9 F0 20 AC F7 60 A9 01 8D
8D DC EF 60 5A 85 08 86 09 AD DC EF 29 01 F0 F9 DB EF 60 9C DB EF 60 A9 00 8D DA EF AD DB EF 30
AD D8 EF A0 00 91 08 AD D9 EF C8 91 08 AD DA EF FB AD D9 EF 60 8D E6 EF 60 48 8D E6 EF AD E7 EF
C8 91 08 AD DB EF C8 91 08 7A 60 AD DD EF A2 00 89 02 D0 F9 68 60 AD E6 EF A2 00 60 AD E7 EF A2
60 48 AD DC EF 29 02 F0 F9 68 60 8D E6 EF 60 48 00 60 60 20 70 F7 A2 00 86 02 86 03 A9 00 20 DD
8D E6 EF AD E7 EF 89 02 D0 F9 68 60 AD E6 EF A2 F7 20 49 F7 A9 B9 A2 F8 20 27 F7 20 45 F1 C9 00
00 60 AD E7 EF A2 00 60 60 20 9D F8 20 98 F0 A9 20 F5 F7 D0 03 4C 32 F1 A9 95 A2 F8 20 27 F7 4C
C4 A2 FB 20 66 F8 A9 9D A2 FB 20 79 FA A0 02 20 39 F1 A9 AA A2 F8 20 27 F7 4C 3C F1 4C 3C F1 A0
32 F8 20 AA F1 A9 D6 A2 FB 20 79 FA A0 02 20 32 0C 20 D7 F6 60 20 7D F7 A9 00 20 25 F8 20 B7 F2
F8 20 F7 F2 A0 00 20 A7 FA A9 E6 A2 FB 20 79 FA 4C 7C F1 A0 00 A2 00 18 A9 01 71 00 91 00 A0 00
A0 03 20 21 F9 20 79 FA A0 04 20 32 F8 A0 01 20 A2 00 B1 00 C9 FF 20 FB F7 D0 03 4C 7C F1 A9 DB
21 F9 20 36 F3 A9 EF A2 FB 20 79 FA A0 02 20 32 A2 F8 20 27 F7 A2 00 A9 01 4C B3 F2 20 69 F4 A0
F8 4C 87 F1 4C 81 F1 4C 84 F1 A9 B2 A2 FB 20 79 01 91 00 C9 01 20 F5 F7 D0 C9 A2 00 A9 00 A0 06
FA AD FC FF AE FD FF 20 79 FA A0 04 20 32 F8 A2 20 69 F8 A0 07 20 C1 F7 E0 03 D0 02 C9 E8 20 14
00 A9 00 4C A6 F1 20 CC F8 60 20 B7 F8 A9 1B A2 F8 F0 03 4C A9 F1 4C B5 F1 A0 06 A2 00 A9 01 20
FC 20 66 F8 A2 00 86 02 86 03 A9 00 20 89 F9 A2 C7 F6 4C 93 F1 A9 01 20 C8 F7 20 C3 F4 A0 01 A2
00 A9 00 20 BB F0 A9 0F A2 FC 20 79 FA A0 02 20 00 B1 00 C9 01 20 F5 F7 D0 03 4C DB F1 A9 D1 A2
32 F8 A2 01 A9 00 85 02 A9 00 85 03 A9 AA 20 89 F8 20 27 F7 A2 00 A9 01 4C B3 F2 A0 05 A2 00 B1
F9 A2 00 A9 08 20 BB F0 A9 02 20 3B F9 20 D4 F0 00 C9 AA 20 F5 F7 D0 03 4C F2 F1 A2 00 A9 01 4C
A9 32 A2 FC 20 79 FA A0 07 20 2A F9 20 89 F9 A0 B3 F2 A2 00 A9 00 A0 00 91 00 A0 00 A2 00 B1 00
06 20 32 F8 A2 00 A9 00 A0 01 91 00 A0 01 A2 00 C9 FF 20 FB F7 D0 03 4C 18 F2 A9 C1 A2 F8 20 27
B1 00 C9 65 A9 00 A2 00 2A D0 03 4C 2D F2 A9 F6 F7 A2 00 A9 01 4C B3 F2 20 E5 F5 A0 01 91 00 A0
A2 FB 20 79 FA A0 02 20 32 F8 4C F3 F2 A2 00 86 01 A2 00 B1 00 C9 02 20 14 F8 D0 03 4C 36 F2 20
02 86 03 A9 00 20 89 F9 A2 00 A9 37 20 BB F0 A9 3F F6 A0 01 91 00 A2 00 A9 00 A0 06 20 69 F8 A0
02 20 3B F9 20 D4 F0 A2 00 A9 18 85 02 A9 40 85 07 20 C1 F7 E0 03 D0 02 C9 E8 20 14 F8 F0 03 4C
03 A9 00 20 89 F9 A2 00 A9 29 20 BB F0 A9 02 20 55 F2 4C 61 F2 A0 06 A2 00 A9 01 20 C7 F6 4C 3F
3B F9 20 D4 F0 A9 03 A2 FC 20 79 FA A0 07 20 2A F2 A0 00 A2 00 18 A9 01 71 00 91 00 A0 01 A2 00
F9 20 89 F9 A0 06 20 32 F8 A2 00 A9 00 A0 00 91 B1 00 C9 00 20 F5 F7 D0 81 A2 00 A9 00 A0 06 20
00 A0 00 A2 00 B1 00 C9 FF 20 55 FA F0 03 4C 94 69 F8 A0 07 20 C1 F7 E0 03 D0 02 C9 E8 20 14 F8
F2 4C A2 F2 A0 00 A2 00 18 A9 01 71 00 91 00 4C F0 03 4C 98 F2 4C A4 F2 A0 06 A2 00 A9 01 20 C7
81 F2 A0 01 A2 00 18 A9 01 71 00 91 00 A0 05 20 F6 4C 82 F2 A9 01 20 C8 F7 20 6B F5 A2 00 A9 00
2A F9 20 89 F9 A2 00 86 02 86 03 A9 00 20 47 F9 4C B3 F2 20 B1 F7 60 20 56 F7 A2 00 A9 00 20 D3
F0 03 4C 0C F2 A2 00 86 02 86 03 A9 00 20 89 F9 F0 A2 00 A9 00 A0 01 20 69 F8 A0 02 20 C1 F7 E0
A2 00 A9 02 20 BB F0 A9 02 20 3B F9 20 D4 F0 A9 03 D0 02 C9 E8 20 14 F8 F0 03 4C E0 F2 4C EC F2
27 A2 FC 20 79 FA A0 07 20 2A F9 20 89 F9 A0 06 A0 01 A2 00 A9 01 20 C7 F6 4C CA F2 A2 00 A9 FF
20 32 F8 20 DF F8 60 20 AA F8 A2 00 86 02 86 03 20 D9 F0 A2 00 A9 00 20 D3 F0 A2 00 A9 00 A0 00
A9 00 20 89 F9 A2 00 A9 03 20 BB F0 A2 00 86 02 91 00 A0 00 A2 00 B1 00 C9 50 20 14 F8 F0 03 4C
86 03 A9 00 A0 00 20 B2 FA A5 00 A6 01 20 D4 F0 15 F3 4C 2A F3 A2 00 A9 FF 20 D9 F0 A0 00 A2 00
A0 03 20 2A F9 A0 00 A6 03 A5 02 84 03 84 02 4C 18 A9 01 71 00 91 00 4C 02 F3 20 A7 F7 60 A9 00
32 F3 20 DA F8 60 20 79 FA 20 AA F8 A0 05 20 21 20 25 F8 20 40 F7 4C 59 F3 A0 01 A2 00 18 A9 01
F9 20 F2 F7 86 03 85 02 A9 00 AA 20 89 F9 A2 00 71 00 91 00 A0 01 A2 00 B1 00 C9 09 A9 00 A2 00
A9 07 20 BB F0 A5 00 A6 01 20 D4 F0 A0 01 20 21 2A D0 03 4C 59 F3 4C 6B F3 A2 00 A9 FF 20 D9 F0
F9 4C 64 F3 20 DF F8 60 20 79 FA 20 AA F8 A0 05 A0 00 91 00 C9 FF 20 FB F7 D0 CE A0 00 A2 00 B1
20 21 F9 20 F2 F7 86 03 85 02 A9 00 AA 20 89 F9 00 4C 74 F3 20 99 F7 60 20 3B F8 A0 01 20 C1 F7
A2 00 A9 0D 20 BB F0 A5 00 A6 01 20 D4 F0 A0 01 20 3B F8 20 2E F3 A0 00 20 51 F8 A0 01 20 C1 F7
20 21 F9 4C 96 F3 20 DF F8 60 20 79 FA 20 B7 F8 1A D0 01 E8 20 3B F8 A2 00 A9 FF 20 D9 F0 A0 00
A0 0B 20 2A F9 20 89 F9 A2 00 A9 11 20 BB F0 A9 20 51 F8 20 99 F7 60 20 3B F8 A0 01 20 C1 F7 20
02 20 3B F9 20 D4 F0 20 01 F1 A2 00 A9 00 A0 00 3B F8 20 2E F3 A0 00 20 51 F8 A0 01 20 C1 F7 A0
20 A7 FA A0 01 20 21 F9 C9 00 8A E9 02 50 02 49 00 20 B6 F7 C9 02 A9 00 A2 00 2A D0 03 4C D3 F3
80 0A A9 00 A2 00 2A F0 03 4C DF F3 4C 06 F4 A0 4C E6 F3 A0 01 20 C1 F7 1A D0 01 E8 20 3B F8 A2
07 20 21 F9 20 79 FA A0 03 20 21 F9 20 B3 F7 20 00 A9 04 20 2D F4 20 99 F7 60 20 3B F8 A0 01 20
79 FA 20 FB F0 A0 00 20 8F FA A0 00 A2 00 A9 01 C1 F7 20 3B F8 20 2E F3 A0 00 20 51 F8 A0 01 20
20 CF F7 4C C3 F3 A0 0C 20 DF F7 60 A0 00 B1 16 C1 F7 A0 00 20 B6 F7 C9 02 A9 00 A2 00 2A D0 03
E6 16 D0 02 E6 17 60 AD 3B 04 8D 36 04 20 B8 F4 4C 16 F4 4C 29 F4 A0 01 20 C1 F7 1A D0 01 E8 20
A9 36 A2 04 20 79 FA 20 70 FA 4C 00 02 A5 14 38 3B F8 A2 00 A9 04 20 2D F4 20 99 F7 60 20 25 F8
E9 02 85 14 B0 02 C6 15 60 AD 40 04 D0 11 20 56 4C 52 F4 A0 02 20 C1 F7 20 3B F8 A2 00 A9 FF 48
F4 4C F2 F7 AD 40 04 D0 06 20 56 F4 4C EC F7 20 A0 03 A2 00 A9 01 20 C7 F6 68 20 D9 F0 A0 00 20
56 F4 85 02 86 03 20 2D F4 A0 01 B1 14 AA 88 B1 51 F8 A0 00 B1 00 08 A0 00 A2 00 B1 00 38 E9 01
14 60 A0 00 84 08 84 09 B1 16 38 E9 30 90 2C C9 91 00 28 D0 CE 20 A7 F7 60 20 40 F7 A2 00 A9 FF
0A B0 28 20 10 F4 48 A5 08 A6 09 06 08 26 09 06 20 D9 F0 A2 00 A9 00 20 CD F0 A2 00 A9 FF 20 D9
08 26 09 65 08 85 08 8A 65 09 85 09 06 08 26 09 F0 A2 00 A9 00 20 25 F8 A2 00 86 02 86 03 A9 00
68 65 08 85 08 90 D1 E6 09 B0 CD A5 08 A6 09 60 20 DD F7 A2 00 A9 94 20 B0 F0 20 2E F3 A0 00 91
AC 42 04 EE 42 04 99 43 04 60 A9 43 A2 04 18 6D 00 A2 00 A9 FF 20 D9 F0 A2 00 A9 00 20 D3 F0 A2
42 04 90 01 E8 4C 79 FA A5 18 A6 19 4C 79 FA 20 00 A9 FF 20 D9 F0 A0 00 A2 00 B1 00 4C BF F4 20
17 F4 EE 3C 04 D0 F8 EE 3D 04 D0 F3 60 20 B8 F4 8A F7 60 20 3B F8 A2 00 A9 FF 20 D9 F0 A2 00 A9
AD 57 04 AE 58 04 20 79 FA AD 59 04 AE 5A 04 20 00 20 CD F0 A2 00 A9 FF 20 D9 F0 A2 00 A9 08 20
79 FA 4C 00 02 84 08 20 89 F9 20 AA F4 A5 08 4C 25 F8 A2 01 A9 00 85 02 A9 00 85 03 A9 AA 20 DD
B9 F9 84 08 20 89 F9 20 AA F4 A5 08 4C FA F9 48 F7 A2 00 A9 86 20 B0 F0 A0 01 20 C1 F7 20 EA F3
A0 05 B9 14 00 99 30 04 88 10 F7 68 85 14 86 15 A2 00 A9 FF 20 D9 F0 A2 00 A9 00 20 D3 F0 A2 00
20 C4 F8 85 16 86 17 20 C4 F8 85 18 86 19 A9 00 A9 FF 20 D9 F0 20 99 F7 60 20 3B F8 A2 00 A9 FF
A8 91 18 C8 91 18 C8 B1 18 8D 01 02 C8 B1 18 8D 20 D9 F0 A2 00 A9 00 20 CD F0 A2 00 A9 FF 20 D9
02 02 A5 16 85 08 A5 17 85 09 A0 00 B1 16 F0 0B F0 A2 00 A9 0D 20 25 F8 A2 00 86 02 86 03 A9 00
C9 25 F0 07 C8 D0 F5 E6 17 D0 F1 98 18 65 16 85 20 DD F7 A2 00 A9 00 20 B0 F0 A0 01 20 C1 F7 20
16 90 02 E6 17 38 E5 08 85 0A A5 17 E5 09 85 0B 78 F3 A2 00 A9 FF 20 D9 F0 A2 00 A9 00 20 D3 F0
05 0A F0 25 20 B7 F8 A0 05 A5 19 91 00 88 A5 18 A2 00 A9 FF 20 D9 F0 20 99 F7 60 20 3B F8 20 40
91 00 88 A5 09 91 00 88 A5 08 91 00 88 A5 0B 91 F7 A2 00 A9 FF 20 D9 F0 A2 00 A9 00 20 CD F0 A2
00 88 A5 0A 91 00 20 00 02 20 0C F4 AA D0 0B A2 00 A9 FF 20 D9 F0 A0 00 91 00 A0 00 A2 00 B1 00
05 BD 30 04 95 14 CA 10 F8 60 C9 25 D0 09 B1 16 C9 FF 20 F5 F7 D0 03 4C AB F5 4C 9D F5 A2 00 A9
C9 25 D0 09 20 10 F4 20 1A F4 4C 32 F5 A9 00 A2 FF 20 D9 F0 C9 FF 20 F5 F7 D0 F2 A2 00 A9 3A 20
0B 9D 37 04 CA 10 FA B1 16 C9 2D D0 05 8E 37 04 25 F8 A2 00 86 02 86 03 A9 00 20 DD F7 A2 00 A9
F0 19 C9 2B D0 05 8E 38 04 F0 10 C9 20 D0 05 8E 00 20 B0 F0 A0 02 20 C1 F7 20 A7 F3 A2 00 A9 FF
39 04 F0 07 C9 23 D0 09 8E 3A 04 20 10 F4 4C B7 20 D9 F0 A2 00 A9 00 20 D3 F0 A2 00 A9 FF 20 D9
F5 A2 20 C9 30 D0 06 AA 20 10 F4 B1 16 8E 3B 04 F0 20 A7 F7 60 20 40 F7 A2 00 A9 FF 20 D9 F0 A2
C9 2A D0 09 20 10 F4 20 56 F4 4C 00 F6 20 62 F4 00 A9 00 20 CD F0 A2 00 A9 FF 20 D9 F0 A2 00 A9
8D 3C 04 8E 3D 04 8C 3E 04 8C 3F 04 B1 16 C9 2E 37 20 25 F8 A2 00 86 02 86 03 A9 00 20 DD F7 A2
D0 1B 20 10 F4 B1 16 C9 2A D0 09 20 10 F4 20 56 00 A9 00 20 B0 F0 20 2E F3 A0 00 91 00 A2 00 A9
F4 4C 27 F6 20 62 F4 8D 3E 04 8E 3F 04 B1 16 C9 FF 20 D9 F0 A2 00 A9 00 20 D3 F0 A2 00 A9 FF 20
7A F0 19 C9 68 F0 15 C9 74 F0 11 C9 6A F0 08 C9 D9 F0 A0 00 A2 00 B1 00 4C 3B F6 20 8A F7 60 20
4C F0 04 C9 6C D0 0B A9 FF 8D 40 04 20 10 F4 4C 40 F7 A2 00 A9 FF 20 D9 F0 A2 00 A9 00 20 CD F0
2D F6 8C 42 04 A2 43 8E 57 04 A2 04 8E 58 04 20 A2 00 A9 FF 20 D9 F0 A2 00 A9 29 20 25 F8 A2 00
10 F4 C9 63 D0 0E 20 56 F4 8D 43 04 A9 00 8D 44 86 02 A9 40 85 03 A9 00 20 DD F7 A2 00 A9 00 20
04 4C 51 F7 C9 64 F0 04 C9 69 D0 2D A2 00 AD 39 B0 F0 20 2E F3 A0 00 91 00 A2 00 A9 FF 20 D9 F0
04 F0 02 A2 20 AD 38 04 F0 02 A2 2B 8E 41 04 20 A2 00 A9 00 20 D3 F0 A2 00 A9 FF 20 D9 F0 A0 00
44 F4 A4 03 30 0B AC 41 04 F0 06 8C 43 04 EE 42 A2 00 B1 00 4C 97 F6 20 8A F7 60 20 3B F8 20 70
04 A0 0A 20 E5 F4 4C 51 F7 C9 6E D0 15 20 56 F4 F7 A0 05 A2 00 B1 00 4C AA F6 A0 0E 20 D7 F6 60
85 08 86 09 A0 00 B1 18 91 08 C8 B1 18 91 08 4C 20 3B F8 20 70 F7 A0 03 A2 00 B1 00 4C BF F6 A0
32 F5 C9 6F D0 27 20 44 F4 AC 3A 04 F0 17 48 86 0E 20 D7 F6 60 A0 00 18 71 00 91 00 48 C8 8A 71
10 05 10 05 02 05 03 0D 3E 04 0D 3F 04 F0 06 A9 00 91 00 AA 68 60 C8 48 18 98 65 00 85 00 90 02
30 20 A0 F4 68 A0 08 20 E5 F4 4C 51 F7 C9 70 D0 E6 01 68 60 A0 00 F0 07 A9 45 A2 F0 4C 00 02 60
0D A2 00 8E 40 04 E8 8E 3A 04 A9 78 D0 27 C9 73 A9 00 85 08 A9 F0 85 09 A9 00 85 0A A9 02 85 0B
D0 0C 20 56 F4 8D 57 04 8E 58 04 4C 51 F7 C9 75 A2 DA A9 FF 85 10 A0 00 E8 F0 0D B1 08 91 0A C8
D0 0B 20 39 F4 A0 0A 20 F2 F4 4C 51 F7 C9 78 F0 D0 F6 E6 09 E6 0B D0 F0 E6 10 D0 EF 60 85 08 86
04 C9 58 D0 29 48 AD 3A 04 F0 0A A9 30 20 A0 F4 09 20 68 F0 4C 2B F7 85 08 86 09 A0 00 B1 08 F0
A9 58 20 A0 F4 20 39 F4 A0 10 20 F2 F4 68 C9 78 0E C8 84 10 20 5B F0 A4 10 D0 F2 E6 09 D0 EE 60
D0 09 AD 57 04 AE 58 04 20 DB FA 4C 51 F7 4C 32 A4 00 D0 02 C6 01 C6 00 60 A5 00 38 E9 02 85 00
F5 AD 57 04 AE 58 04 20 C5 FA 8D 59 04 8E 5A 04 90 01 60 C6 01 60 A5 00 38 E9 03 85 00 90 01 60
AD 3E 04 0D 3F 04 F0 15 AE 3E 04 EC 59 04 AD 3F C6 01 60 A5 00 38 E9 04 85 00 90 01 60 C6 01 60
04 A8 ED 5A 04 B0 06 8E 59 04 8C 5A 04 38 AD 3C A5 00 38 E9 06 85 00 90 01 60 C6 01 60 A5 00 38
04 ED 59 04 AA AD 3D 04 ED 5A 04 B0 03 A9 00 AA E9 07 85 00 90 01 60 C6 01 60 E6 00 D0 02 E6 01
49 FF 8D 3D 04 8A 49 FF 8D 3C 04 AD 37 04 D0 03 60 A0 01 B1 00 AA 88 B1 00 E6 00 F0 05 E6 00 F0
20 C2 F4 20 CD F4 AD 37 04 F0 03 20 C2 F4 4C 32 03 60 E6 00 E6 01 60 A0 03 4C D7 F6 A0 05 4C D7
F5 A2 00 18 A0 00 71 00 C8 85 10 8A 71 00 AA 18 F6 A0 08 4C D7 F6 85 08 86 09 A2 00 B1 08 60 A0
A5 00 69 02 85 00 90 02 E6 01 A5 10 60 A0 00 18 01 B1 00 AA 88 B1 00 60 A2 00 18 65 00 48 8A 65
71 00 91 00 48 C8 8A 71 00 91 00 AA 68 60 C8 48 01 AA 68 60 A9 00 AA A0 00 84 02 84 03 48 20 63
18 98 65 00 85 00 90 02 E6 01 68 60 A0 FF E0 80 F7 A0 03 A5 03 91 00 88 A5 02 91 00 88 8A 91 00
B0 02 A0 00 84 02 84 03 60 A0 00 F0 07 A9 50 A2 68 88 91 00 60 D0 06 A2 00 8A 60 D0 FA A2 00 A9
F0 4C 03 02 60 A9 00 85 08 A9 F0 85 09 A9 00 85 01 60 F0 F9 30 F7 A2 00 8A 60 F0 02 10 EF A2 00
0A A9 02 85 0B A2 CF A9 FF 85 10 A0 00 E8 F0 0D 8A 60 F0 E9 90 E7 A2 00 8A 60 F0 DB A2 00 8A 2A
B1 08 91 0A C8 D0 F6 E6 09 E6 0B D0 F0 E6 10 D0 60 A0 00 B1 00 A4 00 F0 07 C6 00 A0 00 91 00 60
EF 60 8C 5B 04 88 88 98 18 65 00 85 08 A6 01 90 C6 01 C6 00 91 00 60 A9 00 A2 00 48 A5 00 38 E9
01 E8 86 09 A0 01 B1 08 AA 88 B1 08 20 79 FA A5 02 85 00 B0 02 C6 01 A0 01 8A 91 00 68 88 91 00
08 A6 09 20 4A FB AC 5B 04 4C DF F7 85 08 86 09 60 48 84 10 A0 01 B1 00 85 09 88 B1 00 85 08 A4
20 73 F0 4C 6A F8 85 08 86 09 A0 00 B1 08 F0 0E 10 68 91 08 4C 99 F7 A0 00 91 00 C8 48 8A 91 00
C8 84 10 20 66 F0 A4 10 D0 F2 E6 09 D0 EE 60 E0 68 60 A9 25 85 08 A9 02 85 09 A9 00 A8 A2 02 F0
00 D0 15 4A AA BD 64 FC 90 05 4A 4A 4A 4A 18 29 0A 91 08 C8 D0 FB E6 09 CA D0 F6 C0 00 F0 05 91
0F AA BD 59 FC A2 00 60 38 A9 00 AA 60 A5 00 38 08 C8 D0 F7 60 45 72 72 6F 72 20 69 6E 69 74 20
E9 02 85 00 90 01 60 C6 01 60 A5 00 38 E9 04 85 53 44 20 43 41 52 44 0D 0A 00 53 44 20 43 61 72
00 90 01 60 C6 01 60 A5 00 38 E9 06 85 00 90 01 64 20 69 6E 69 74 0D 0A 00 53 74 61 72 74 0D 0A
60 C6 01 60 A0 01 B1 00 AA 88 B1 00 E6 00 F0 05 00 6F 70 5F 63 6F 6E 64 20 65 72 72 6F 72 0D 0A
E6 00 F0 03 60 E6 00 E6 01 60 A0 04 4C DF F7 A0 00 49 46 20 43 6F 6E 64 0D 0A 00 47 6F 20 49 44
06 4C DF F7 85 08 86 09 A0 03 B1 00 38 E5 03 D0 4C 45 0D 0A 00 00 00 00 00 00 00 00 00 00 00 00
22 88 B1 00 C5 02 D0 0C 88 B1 00 C5 09 D0 05 88
B1 00 C5 08 08 20 DA F8 28 F0 04 B0 03 A9 FF 60
A9 01 60 50 04 49 FF 09 01 08 20 DA F8 28 60 A0
01 B1 00 AA 88 B1 00 60 A0 03 B1 00 85 03 88 B1
00 85 02 88 B1 00 AA 88 B1 00 60 A2 00 18 65 00
48 8A 65 01 AA 68 60 20 E4 F8 4C 36 FA 18 49 FF
69 01 48 8A 49 FF 69 00 AA A5 02 49 FF 69 00 85
02 A5 03 49 FF 69 00 85 03 68 60 A0 03 B1 00 85
03 88 B1 00 85 02 88 B1 00 AA 88 B1 00 4C DA F8
A9 00 AA A0 00 84 02 84 03 48 20 AA F8 A0 03 A5
03 91 00 88 A5 02 91 00 88 8A 91 00 68 88 91 00
60 85 10 20 C4 F8 85 0A 86 0B 85 0C 86 0D 20 62
FA 20 C4 F8 85 02 86 03 60 20 A1 F9 A6 03 A4 10
C0 0A D0 39 A5 02 05 09 05 08 D0 11 E0 80 D0 0D
A0 0B B9 4D FC 91 0A 88 10 F8 4C 31 FA 8A 10 1D
A9 2D A0 00 91 0A E6 0A D0 02 E6 0B A5 08 A6 09
20 4D F9 85 08 86 09 4C FD F9 20 A1 F9 A9 00 48
A0 20 A9 00 06 08 26 09 26 02 26 03 2A C5 10 90
04 E5 10 E6 08 88 D0 EC A8 B9 3D FC 48 A5 08 05
09 05 02 05 03 D0 D9 A0 00 68 91 0A F0 03 C8 D0
F8 A5 0C A6 0D 60 D0 06 A2 00 8A 60 D0 FA A2 00
A9 01 60 F0 F9 30 F7 A2 00 8A 60 F0 02 10 EF A2
00 8A 60 F0 E9 90 E7 A2 00 8A 60 F0 DB A2 00 8A
2A 60 A0 01 B1 00 85 09 88 B1 00 85 08 4C CC F8
A9 01 4C 77 FA A9 00 A2 00 48 A5 00 38 E9 02 85
00 B0 02 C6 01 A0 01 8A 91 00 68 88 91 00 60 48
84 10 A0 01 B1 00 85 09 88 B1 00 85 08 A4 10 68
91 08 4C CC F8 A0 00 91 00 C8 48 8A 91 00 68 60
A0 00 91 00 C8 48 8A 91 00 C8 A5 02 91 00 C8 A5
03 91 00 68 60 85 0A 86 0B A2 00 A0 00 B1 0A F0
08 C8 D0 F9 E6 0B E8 D0 F4 98 60 85 08 86 09 85
0A 86 0B A0 00 B1 08 F0 14 20 83 F8 29 02 F0 06
B1 08 69 20 91 08 C8 D0 EC E6 09 D0 E8 A5 0A A6
0B 60 20 C4 F8 85 0A 86 0B E8 8E 2F 02 AA E8 8E
2E 02 20 62 FA 20 C4 F8 85 0C 86 0D A0 00 84 10
B1 0C 18 65 0A 91 0C C8 B1 0C 65 0B 91 0C CE 2E
02 F0 11 A4 10 B1 08 C8 D0 02 E6 09 84 10 20 66
F0 4C 2E FB CE 2F 02 D0 EA 60 85 08 86 09 A9 00
8D 28 02 8D 29 02 A0 01 B1 00 AA 88 B1 00 20 79
FA A0 02 A9 28 91 00 C8 A9 02 91 00 A5 08 A6 09
20 FF F4 AD 28 02 AE 29 02 60 A9 30 85 08 A9 02
85 09 A9 00 A8 A2 02 F0 0A 91 08 C8 D0 FB E6 09
CA D0 F6 C0 2C F0 05 91 08 C8 D0 F7 60 41 6E 64
20 74 65 73 74 69 6E 67 20 63 70 72 69 6E 74 66
0A 00 52 65 73 65 74 20 76 65 63 74 6F 72 3A 20
25 78 0A 00 53 74 61 72 74 69 6E 67 20 73 64 5F
69 6E 69 74 0A 00 66 69 6E 69 73 68 20 73 64 5F
69 6E 69 74 0A 00 72 63 61 3A 20 25 78 0A 00 44
6F 6E 65 21 0A 00 53 44 20 54 69 6D 65 64 20 6F
75 74 00 43 4D 44 34 31 3A 20 25 6C 78 0A 00 53
65 6E 74 20 52 65 73 65 74 0A 00 49 6E 20 73 64
5F 69 6E 69 74 0A 00 43 4D 44 32 3A 20 25 6C 78
0A 00 43 4D 44 38 3A 20 25 6C 78 0A 00 30 31 32
33 34 35 36 37 38 39 41 42 43 44 45 46 2D 32 31
34 37 34 38 33 36 34 38 00 00 01 02 0C 09 0A 10
40 50 A0 D0 66 66 66 66 A6 88 88 66 66 66 66 66
66 66 66 66 09 00 00 00 00 00 00 00 33 33 33 33
33 00 00 00 50 55 55 25 22 22 22 22 22 22 22 22
22 02 00 00 40 44 44 14 11 11 11 11 11 11 11 11
11 01 00 70 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
@@ -254,4 +194,64 @@ CA D0 F6 C0 2C F0 05 91 08 C8 D0 F7 60 41 6E 64
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 A5 F0 30 F0 A6 F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 9A F0 25 F0 9B F0

View File

@@ -19,31 +19,16 @@
"ENABLE_PARITY": "1'b0", "ENABLE_PARITY": "1'b0",
"FIX_BAUDRATE": "1'b1", "FIX_BAUDRATE": "1'b1",
"PARITY_MODE": "1'b0", "PARITY_MODE": "1'b0",
"BOOTUP_CHECK": "1'b1" "BOOTUP_CHECK": "1'b0"
}, },
"output": { "output": {
"external_source_source": [ "external_source_source": [
"/home/byron/Projects/super6502/hw/efinix_fpga/ip/uart/uart_define.vh",
"/home/byron/Projects/super6502/hw/efinix_fpga/ip/uart/uart_tmpl.v", "/home/byron/Projects/super6502/hw/efinix_fpga/ip/uart/uart_tmpl.v",
"/home/byron/Projects/super6502/hw/efinix_fpga/ip/uart/uart.v", "/home/byron/Projects/super6502/hw/efinix_fpga/ip/uart/uart.v",
"/home/byron/Projects/super6502/hw/efinix_fpga/ip/uart/uart_tmpl.vhd" "/home/byron/Projects/super6502/hw/efinix_fpga/ip/uart/uart_tmpl.vhd",
], "/home/byron/Projects/super6502/hw/efinix_fpga/ip/uart/uart_define.vh"
"external_example_example": [
"/home/byron/Projects/super6502/hw/efinix_fpga/ip/uart/T20F256_devkit/command_state.v",
"/home/byron/Projects/super6502/hw/efinix_fpga/ip/uart/T20F256_devkit/decoder.v",
"/home/byron/Projects/super6502/hw/efinix_fpga/ip/uart/T20F256_devkit/encoder.v",
"/home/byron/Projects/super6502/hw/efinix_fpga/ip/uart/T20F256_devkit/led_ctl.v",
"/home/byron/Projects/super6502/hw/efinix_fpga/ip/uart/T20F256_devkit/resets.v",
"/home/byron/Projects/super6502/hw/efinix_fpga/ip/uart/T20F256_devkit/uart_defines.v",
"/home/byron/Projects/super6502/hw/efinix_fpga/ip/uart/T20F256_devkit/uart_demo_top.v",
"/home/byron/Projects/super6502/hw/efinix_fpga/ip/uart/T20F256_devkit/user_register.v",
"/home/byron/Projects/super6502/hw/efinix_fpga/ip/uart/T20F256_devkit/uart_demo.peri.xml",
"/home/byron/Projects/super6502/hw/efinix_fpga/ip/uart/T20F256_devkit/uart_demo.xml",
"/home/byron/Projects/super6502/hw/efinix_fpga/ip/uart/T20F256_devkit/uart_timing_T20.sdc",
"/home/byron/Projects/super6502/hw/efinix_fpga/ip/uart/T20F256_devkit/uart.v",
"/home/byron/Projects/super6502/hw/efinix_fpga/ip/uart/T20F256_devkit/uart_define.vh"
] ]
}, },
"sw_version": "2023.1.150", "sw_version": "2023.1.150",
"generated_date": "2023-07-16T20:20:12.259229" "generated_date": "2023-07-23T03:23:04.338270"
} }

View File

@@ -43,7 +43,7 @@
// //
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
`define IP_UUID _d1961caf8b8d4ca092806671a99095c2 `define IP_UUID _8d7ceb45e0e64e208e634a02f6a59365
`define IP_NAME_CONCAT(a,b) a``b `define IP_NAME_CONCAT(a,b) a``b
`define IP_MODULE_NAME(name) `IP_NAME_CONCAT(name,`IP_UUID) `define IP_MODULE_NAME(name) `IP_NAME_CONCAT(name,`IP_UUID)
module uart ( module uart (
@@ -69,7 +69,7 @@ input [7:0] tx_data
.ENABLE_PARITY (1'b0), .ENABLE_PARITY (1'b0),
.FIX_BAUDRATE (1'b1), .FIX_BAUDRATE (1'b1),
.PARITY_MODE (1'b0), .PARITY_MODE (1'b0),
.BOOTUP_CHECK (1'b1) .BOOTUP_CHECK (1'b0)
) u_top_uart( ) u_top_uart(
.tx_o ( tx_o ), .tx_o ( tx_o ),
.rx_i ( rx_i ), .rx_i ( rx_i ),

View File

@@ -49,4 +49,4 @@ localparam BAUD = 115200;
localparam ENABLE_PARITY = 1'b0; localparam ENABLE_PARITY = 1'b0;
localparam FIX_BAUDRATE = 1'b1; localparam FIX_BAUDRATE = 1'b1;
localparam PARITY_MODE = 1'b0; localparam PARITY_MODE = 1'b0;
localparam BOOTUP_CHECK = 1'b1; localparam BOOTUP_CHECK = 1'b0;

View File

@@ -1,4 +1,4 @@
TARGETS= timer interrupt_controller TARGETS= timer interrupt_controller spi_controller
TB=$(patsubst %, %_tb.sv, $(TARGETS)) TB=$(patsubst %, %_tb.sv, $(TARGETS))
all: $(TARGETS) all: $(TARGETS)
@@ -6,6 +6,9 @@ all: $(TARGETS)
timer: timer_tb.sv timer: timer_tb.sv
iverilog -g2005-sv -s sim -o $@ $@_tb.sv ../$@.sv iverilog -g2005-sv -s sim -o $@ $@_tb.sv ../$@.sv
spi_controller: spi_controller_tb.sv ../spi_controller.sv
iverilog -g2005-sv -s sim -o $@ $@_tb.sv ../$@.sv
interrupt_controller: interrupt_controller_tb.sv interrupt_controller: interrupt_controller_tb.sv
iverilog -g2005-sv -s sim -o $@ $@_tb.sv ../$@.sv iverilog -g2005-sv -s sim -o $@ $@_tb.sv ../$@.sv

View File

@@ -0,0 +1,102 @@
module sim();
timeunit 10ns;
timeprecision 1ns;
logic clk_50;
logic i_clk;
logic i_rst;
logic i_cs;
logic i_rwb;
logic [1:0] i_addr;
logic [7:0] i_data;
logic [7:0] o_data;
logic o_spi_cs;
logic o_spi_clk;
logic o_spi_mosi;
logic i_spi_miso;
spi_controller dut(.*);
always #1 clk_50 = clk_50 === 1'b0;
always #100 i_clk = i_clk === 1'b0;
task write_reg(input logic [2:0] _addr, input logic [7:0] _data);
@(negedge i_clk);
i_cs <= '1;
i_addr <= _addr;
i_rwb <= '0;
i_data <= '1;
@(posedge i_clk);
i_data <= _data;
@(negedge i_clk);
i_cs <= '0;
i_rwb <= '1;
endtask
task read_reg(input logic [2:0] _addr, output logic [7:0] _data);
@(negedge i_clk);
i_cs <= '1;
i_addr <= _addr;
i_rwb <= '1;
i_data <= '1;
@(posedge i_clk);
_data <= o_data;
@(negedge i_clk);
i_cs <= '0;
i_rwb <= '1;
endtask
initial
begin
$dumpfile("spi_controller.vcd");
$dumpvars(0,sim);
end
logic [7:0] data;
initial begin
i_rst <= '1;
repeat(5) @(posedge i_clk);
i_cs <= '0;
i_rwb <= '1;
i_addr <= '0;
i_rst <= '0;
repeat(5) @(posedge i_clk);
write_reg(3, 1);
write_reg(2, 8'hFF);
data = (1 << 7);
while(data & (1 << 7)) begin
read_reg(3, data);
end
write_reg(3, 0);
read_reg(1, data);
assert(data == 8'h55);
repeat(50) @(posedge i_clk);
$finish();
end
logic [7:0] _spi_device_data;
initial begin
_spi_device_data <= 8'h55;
end
always @(edge o_spi_clk) begin
if (o_spi_cs == '0) begin
if (o_spi_clk == '1)
i_spi_miso <= _spi_device_data[7];
if (o_spi_clk == '0)
_spi_device_data <= _spi_device_data << 1;
end
end
endmodule

View File

@@ -0,0 +1,97 @@
module spi_controller(
input i_clk,
input i_rst,
input i_cs,
input i_rwb,
input [1:0] i_addr,
input [7:0] i_data,
output logic [7:0] o_data,
output o_spi_cs,
output o_spi_clk,
output o_spi_mosi,
input i_spi_miso
);
// We need a speed register
// an input data register
// and an output data register
// and then a control register for cs
logic [7:0] r_baud_rate;
logic [7:0] r_input_data;
logic [7:0] r_output_data;
logic [7:0] r_control;
logic [8:0] r_clock_counter;
logic active;
logic [2:0] count;
logic spi_clk;
logic r_spi_mosi;
assign o_spi_cs = ~r_control[0];
assign o_spi_clk = spi_clk;
assign o_spi_mosi = r_spi_mosi;
always @(negedge i_clk) begin
if (i_rst) begin
r_baud_rate <= 8'h1;
r_input_data <= '0;
r_output_data <= '0;
r_control <= '0;
r_clock_counter <= '0;
count <= '0;
spi_clk <= '0;
active <= '0;
end else begin
if (~i_rwb & i_cs) begin
unique case (i_addr)
0: r_baud_rate <= i_data;
1:;
2: begin
r_output_data <= i_data;
active <= '1;
end
3: r_control <= i_data;
endcase
end
if (active) begin
r_spi_mosi <= r_output_data[7];
r_clock_counter <= r_clock_counter + 9'b1;
if (r_clock_counter >= r_baud_rate) begin
r_clock_counter <= '0;
spi_clk <= ~spi_clk;
// rising edge
if (spi_clk == '0) begin
r_output_data <= r_output_data << 1;
count <= count + 1;
end
// falling edge
if (spi_clk == '1) begin
r_input_data <= {r_input_data[6:0], i_spi_miso};
if (count == '0) begin
active <= '0;
end
end
end
end
end
end
always_comb begin
unique case (i_addr)
0: o_data = r_baud_rate;
1: o_data = r_input_data;
2:;
3: o_data = {active, r_control[6:0]};
endcase
end
endmodule

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<efxpt:design_db name="super6502" device_def="T20F256" location="/home/byron/Projects/super6502/hw/efinix_fpga" version="2023.1.150" db_version="20231999" last_change_date="Sun Jul 16 13:10:02 2023" xmlns:efxpt="http://www.efinixinc.com/peri_design_db" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.efinixinc.com/peri_design_db peri_design_db.xsd "> <efxpt:design_db name="super6502" device_def="T20F256" location="/home/byron/Projects/super6502/hw/efinix_fpga" version="2023.1.150" db_version="20231999" last_change_date="Sat Jul 22 17:30:06 2023" xmlns:efxpt="http://www.efinixinc.com/peri_design_db" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.efinixinc.com/peri_design_db peri_design_db.xsd ">
<efxpt:device_info> <efxpt:device_info>
<efxpt:iobank_info> <efxpt:iobank_info>
<efxpt:iobank name="1A" iostd="3.3 V LVTTL / LVCMOS"/> <efxpt:iobank name="1A" iostd="3.3 V LVTTL / LVCMOS"/>
@@ -306,21 +306,17 @@
<efxpt:gpio name="pll_in" gpio_def="GPIOR_157" mode="input" bus_name="" is_lvds_gpio="false" io_standard="3.3 V LVTTL / LVCMOS"> <efxpt:gpio name="pll_in" gpio_def="GPIOR_157" mode="input" bus_name="" is_lvds_gpio="false" io_standard="3.3 V LVTTL / LVCMOS">
<efxpt:input_config name="pll_in" name_ddio_lo="" conn_type="pll_clkin" is_register="false" clock_name="" is_clock_inverted="false" pull_option="none" is_schmitt_trigger="false" ddio_type="none"/> <efxpt:input_config name="pll_in" name_ddio_lo="" conn_type="pll_clkin" is_register="false" clock_name="" is_clock_inverted="false" pull_option="none" is_schmitt_trigger="false" ddio_type="none"/>
</efxpt:gpio> </efxpt:gpio>
<efxpt:gpio name="sd_clk" gpio_def="GPIOL_26" mode="output" bus_name="" is_lvds_gpio="false" io_standard="3.3 V LVTTL / LVCMOS">
<efxpt:output_config name="sd_clk" name_ddio_lo="" register_option="none" clock_name="" is_clock_inverted="false" is_slew_rate="false" tied_option="none" ddio_type="none" drive_strength="1"/>
</efxpt:gpio>
<efxpt:gpio name="sd_cmd" gpio_def="GPIOL_25" mode="inout" bus_name="" is_lvds_gpio="false" io_standard="3.3 V LVTTL / LVCMOS">
<efxpt:input_config name="sd_cmd_IN" name_ddio_lo="" conn_type="normal" is_register="false" clock_name="" is_clock_inverted="false" pull_option="weak pullup" is_schmitt_trigger="false" ddio_type="none"/>
<efxpt:output_config name="sd_cmd_OUT" name_ddio_lo="" register_option="none" clock_name="" is_clock_inverted="false" is_slew_rate="false" tied_option="none" ddio_type="none" drive_strength="3"/>
<efxpt:output_enable_config name="sd_cmd_OE" is_register="false" clock_name="" is_clock_inverted="false"/>
</efxpt:gpio>
<efxpt:gpio name="sd_cs" gpio_def="GPIOL_36" mode="output" bus_name="" is_lvds_gpio="false" io_standard="3.3 V LVTTL / LVCMOS"> <efxpt:gpio name="sd_cs" gpio_def="GPIOL_36" mode="output" bus_name="" is_lvds_gpio="false" io_standard="3.3 V LVTTL / LVCMOS">
<efxpt:output_config name="sd_cs" name_ddio_lo="" register_option="none" clock_name="" is_clock_inverted="false" is_slew_rate="false" tied_option="none" ddio_type="none" drive_strength="1"/> <efxpt:output_config name="sd_cs" name_ddio_lo="" register_option="none" clock_name="" is_clock_inverted="false" is_slew_rate="false" tied_option="none" ddio_type="none" drive_strength="1"/>
</efxpt:gpio> </efxpt:gpio>
<efxpt:gpio name="sd_data" gpio_def="GPIOL_29" mode="inout" bus_name="" is_lvds_gpio="false" io_standard="3.3 V LVTTL / LVCMOS"> <efxpt:gpio name="spi_clk" gpio_def="GPIOL_26" mode="output" bus_name="" is_lvds_gpio="false" io_standard="3.3 V LVTTL / LVCMOS">
<efxpt:input_config name="sd_data_IN" name_ddio_lo="" conn_type="normal" is_register="false" clock_name="" is_clock_inverted="false" pull_option="weak pullup" is_schmitt_trigger="false" ddio_type="none"/> <efxpt:output_config name="spi_clk" name_ddio_lo="" register_option="none" clock_name="" is_clock_inverted="false" is_slew_rate="false" tied_option="none" ddio_type="none" drive_strength="1"/>
<efxpt:output_config name="sd_data_OUT" name_ddio_lo="" register_option="none" clock_name="" is_clock_inverted="false" is_slew_rate="false" tied_option="none" ddio_type="none" drive_strength="3"/> </efxpt:gpio>
<efxpt:output_enable_config name="sd_data_OE" is_register="false" clock_name="" is_clock_inverted="false"/> <efxpt:gpio name="spi_miso" gpio_def="GPIOL_29" mode="input" bus_name="" is_lvds_gpio="false" io_standard="3.3 V LVTTL / LVCMOS">
<efxpt:input_config name="spi_miso" name_ddio_lo="" conn_type="normal" is_register="false" clock_name="" is_clock_inverted="false" pull_option="none" is_schmitt_trigger="false" ddio_type="none"/>
</efxpt:gpio>
<efxpt:gpio name="spi_mosi" gpio_def="GPIOL_25" mode="output" bus_name="" is_lvds_gpio="false" io_standard="3.3 V LVTTL / LVCMOS">
<efxpt:output_config name="spi_mosi" name_ddio_lo="" register_option="none" clock_name="" is_clock_inverted="false" is_slew_rate="false" tied_option="none" ddio_type="none" drive_strength="1"/>
</efxpt:gpio> </efxpt:gpio>
<efxpt:gpio name="uart_rx" gpio_def="GPIOL_11" mode="input" bus_name="" is_lvds_gpio="false" io_standard="3.3 V LVTTL / LVCMOS"> <efxpt:gpio name="uart_rx" gpio_def="GPIOL_11" mode="input" bus_name="" is_lvds_gpio="false" io_standard="3.3 V LVTTL / LVCMOS">
<efxpt:input_config name="uart_rx" name_ddio_lo="" conn_type="normal" is_register="false" clock_name="" is_clock_inverted="false" pull_option="none" is_schmitt_trigger="false" ddio_type="none"/> <efxpt:input_config name="uart_rx" name_ddio_lo="" conn_type="normal" is_register="false" clock_name="" is_clock_inverted="false" pull_option="none" is_schmitt_trigger="false" ddio_type="none"/>

View File

@@ -41,30 +41,12 @@ module super6502
output uart_tx, output uart_tx,
output sd_cs, output sd_cs,
output sd_clk, output spi_clk,
output spi_mosi,
input sd_cmd_IN,
output sd_cmd_OUT, input spi_miso
output sd_cmd_OE,
input sd_data_IN,
output sd_data_OUT,
output sd_data_OE
); );
assign sd_cs = '1;
logic o_sd_cmd, i_sd_cmd;
logic o_sd_data, i_sd_data;
assign i_sd_cmd = sd_cmd_IN;
assign sd_cmd_OUT = '0;
assign sd_cmd_OE = ~o_sd_cmd;
assign i_sd_data = sd_data_IN;
assign sd_data_OUT = '0;
assign sd_data_OE = ~o_sd_data;
assign pll_cpu_reset = '1; assign pll_cpu_reset = '1;
assign o_pll_reset = '1; assign o_pll_reset = '1;
@@ -97,7 +79,7 @@ logic w_timer_cs;
logic w_multiplier_cs; logic w_multiplier_cs;
logic w_divider_cs; logic w_divider_cs;
logic w_uart_cs; logic w_uart_cs;
logic w_sdcard_cs; logic w_spi_cs;
addr_decode u_addr_decode( addr_decode u_addr_decode(
.i_addr(cpu_addr), .i_addr(cpu_addr),
@@ -107,7 +89,7 @@ addr_decode u_addr_decode(
.o_multiplier_cs(w_multiplier_cs), .o_multiplier_cs(w_multiplier_cs),
.o_divider_cs(w_divider_cs), .o_divider_cs(w_divider_cs),
.o_uart_cs(w_uart_cs), .o_uart_cs(w_uart_cs),
.o_sdcard_cs(w_sdcard_cs), .o_spi_cs(w_spi_cs),
.o_sdram_cs(w_sdram_cs) .o_sdram_cs(w_sdram_cs)
); );
@@ -117,7 +99,7 @@ logic [7:0] w_timer_data_out;
logic [7:0] w_multiplier_data_out; logic [7:0] w_multiplier_data_out;
logic [7:0] w_divider_data_out; logic [7:0] w_divider_data_out;
logic [7:0] w_uart_data_out; logic [7:0] w_uart_data_out;
logic [7:0] w_sdcard_data_out; logic [7:0] w_spi_data_out;
logic [7:0] w_sdram_data_out; logic [7:0] w_sdram_data_out;
always_comb begin always_comb begin
@@ -133,8 +115,8 @@ always_comb begin
cpu_data_out = w_divider_data_out; cpu_data_out = w_divider_data_out;
else if (w_uart_cs) else if (w_uart_cs)
cpu_data_out = w_uart_data_out; cpu_data_out = w_uart_data_out;
else if (w_sdcard_cs) else if (w_spi_cs)
cpu_data_out = w_sdcard_data_out; cpu_data_out = w_spi_data_out;
else if (w_sdram_cs) else if (w_sdram_cs)
cpu_data_out = w_sdram_data_out; cpu_data_out = w_sdram_data_out;
else else
@@ -206,28 +188,19 @@ uart_wrapper u_uart(
.irqb(w_uart_irqb) .irqb(w_uart_irqb)
); );
logic sd_clk; spi_controller spi_controller(
always @(posedge clk_2) begin .i_clk(clk_2),
sd_clk <= ~sd_clk; .i_rst(~cpu_resb),
end .i_cs(w_spi_cs),
.i_rwb(cpu_rwb),
.i_addr(cpu_addr[1:0]),
.i_data(cpu_data_in),
.o_data(w_spi_data_out),
.o_spi_cs(sd_cs),
sd_controller sd_controller( .o_spi_clk(spi_clk),
.clk(clk_2), .o_spi_mosi(spi_mosi),
.sd_clk(sd_clk), .i_spi_miso(spi_miso)
.rst(rst),
.addr(cpu_addr[2:0]),
.data(cpu_data_in),
.cs(w_sdcard_cs),
.rw(cpu_rwb),
.i_sd_cmd(i_sd_cmd),
.o_sd_cmd(o_sd_cmd),
.i_sd_data(i_sd_data),
.o_sd_data(o_sd_data),
.data_out(w_sdcard_data_out)
); );

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<efx:project name="super6502" description="" last_change_date="Wed July 19 2023 21:04:26" location="/home/byron/Projects/super6502/hw/efinix_fpga" sw_version="2023.1.150" last_run_state="pass" last_run_tool="efx_pgm" last_run_flow="bitstream" config_result_in_sync="true" design_ood="sync" place_ood="sync" route_ood="sync" xmlns:efx="http://www.efinixinc.com/enf_proj" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.efinixinc.com/enf_proj enf_proj.xsd"> <efx:project name="super6502" description="" last_change_date="Sun July 23 2023 16:23:00" location="/home/byron/Projects/super6502/hw/efinix_fpga" sw_version="2023.1.150" last_run_state="pass" last_run_tool="efx_pgm" last_run_flow="bitstream" config_result_in_sync="true" design_ood="sync" place_ood="sync" route_ood="sync" xmlns:efx="http://www.efinixinc.com/enf_proj" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.efinixinc.com/enf_proj enf_proj.xsd">
<efx:device_info> <efx:device_info>
<efx:family name="Trion"/> <efx:family name="Trion"/>
<efx:device name="T20F256"/> <efx:device name="T20F256"/>
@@ -19,6 +19,7 @@
<efx:design_file name="sd_controller.sv" version="default" library="default"/> <efx:design_file name="sd_controller.sv" version="default" library="default"/>
<efx:design_file name="crc7.sv" version="default" library="default"/> <efx:design_file name="crc7.sv" version="default" library="default"/>
<efx:design_file name="rom.sv" version="default" library="default"/> <efx:design_file name="rom.sv" version="default" library="default"/>
<efx:design_file name="spi_controller.sv" version="default" library="default"/>
<efx:top_vhdl_arch name=""/> <efx:top_vhdl_arch name=""/>
</efx:design_info> </efx:design_info>
<efx:constraint_info> <efx:constraint_info>
@@ -62,11 +63,11 @@
<efx:param name="hdl-compile-unit" value="1" value_type="e_option"/> <efx:param name="hdl-compile-unit" value="1" value_type="e_option"/>
<efx:param name="create-onehot-fsms" value="0" value_type="e_option"/> <efx:param name="create-onehot-fsms" value="0" value_type="e_option"/>
<efx:param name="min-ce-fanout" value="0" value_type="e_integer"/> <efx:param name="min-ce-fanout" value="0" value_type="e_integer"/>
<efx:param name="mult-decomp-retime" value="0" value_type="e_option"/>
<efx:param name="optimize-zero-init-rom" value="1" value_type="e_option"/>
<efx:param name="include" value="ip/sdram_controller" value_type="e_string"/> <efx:param name="include" value="ip/sdram_controller" value_type="e_string"/>
<efx:param name="include" value="ip/divider" value_type="e_string"/> <efx:param name="include" value="ip/divider" value_type="e_string"/>
<efx:param name="include" value="ip/uart" value_type="e_string"/> <efx:param name="include" value="ip/uart" value_type="e_string"/>
<efx:param name="mult-decomp-retime" value="0" value_type="e_option"/>
<efx:param name="optimize-zero-init-rom" value="1" value_type="e_option"/>
</efx:synthesis> </efx:synthesis>
<efx:place_and_route tool_name="efx_pnr"> <efx:place_and_route tool_name="efx_pnr">
<efx:param name="work_dir" value="work_pnr" value_type="e_string"/> <efx:param name="work_dir" value="work_pnr" value_type="e_string"/>

View File

@@ -6,7 +6,8 @@ UART_STATUS = UART + 1
LED = $efff LED = $efff
SW = LED SW = LED
SD_ARG = $efd8 SPI_BAUD = $efd8
SD_CMD = $efdc SPI_INPUT = $efd9
SD_DATA = $efdd SPI_OUTPUT = $efda
SPI_CTRL = $efdb
SPI_STATUS = SPI_CTRL

View File

@@ -1,89 +1,437 @@
#include <stdint.h>
#include <conio.h> #include <conio.h>
#include "devices/sd_card.h" #include "sd_card.h"
#include "sd_print.h"
#include "spi.h"
void sd_init() { /*******************************************************************************
uint32_t resp; Initialize SD card
uint8_t attempts, i; *******************************************************************************/
uint8_t SD_init()
{
uint16_t i;
cputs("In sd_init\n"); uint8_t res[5], cmdAttempts = 0;
sd_card_command(0, 0); SD_powerUpSeq();
cprintf("Sent Reset\n"); while((res[0] = SD_goIdleState()) != SD_IN_IDLE_STATE)
{
cmdAttempts++;
if(cmdAttempts == CMD0_MAX_ATTEMPTS)
{
cputs("Go IDLE\r\n");
return SD_ERROR;
}
}
sd_card_command(0x000001aa, 8); for (i = 0; i < 1000; i++);
sd_card_resp(&resp);
cprintf("CMD8: %lx\n", resp);
attempts = 0; SD_sendIfCond(res);
do { if(res[0] != SD_IN_IDLE_STATE)
if (attempts > 100) { {
cprintf("SD Timed out"); cputs("IF Cond\r\n");
return; return SD_ERROR;
} }
sd_card_command(0, 55);
sd_card_resp(&resp);
sd_card_command(0x40180000, 41);
sd_card_resp(&resp);
cprintf("CMD41: %lx\n", resp);
//10ms loop? if(res[4] != 0xAA)
for (i = 0; i < 255; i++); {
return SD_ERROR;
}
attempts++; cmdAttempts = 0;
} while (resp != 0); do
{
if(cmdAttempts == CMD55_MAX_ATTEMPTS)
{
cputs("op_cond error\r\n");
return SD_ERROR;
}
sd_card_command(0, 2); res[0] = SD_sendApp();
sd_card_resp(&resp); if(SD_R1_NO_ERROR(res[0]))
cprintf("CMD2: %lx\n", resp); {
res[0] = SD_sendOpCond();
}
for (i = 0; i < 1000; i++);
cmdAttempts++;
}
while(res[0] != SD_READY);
for (i = 0; i < 1000; i++);
SD_readOCR(res);
return SD_SUCCESS;
} }
uint16_t sd_get_rca() { /*
uint32_t resp; // Send a command with starting end ending clock pulses
uint8_t res1_cmd(uint8_t cmd, uint32_t arg, uint8_t crc)
{
uint8_t res1;
// assert chip select
spi_exchange(0xFF);
spi_select(0);
spi_exchange(0xFF);
sd_card_command(0, 3); // send CMD0
resp = 0; SD_command(cmd, arg, crc);
sd_card_resp(&resp);
//cprintf("CMD3: %lx\n", resp); // read response
res1 = SD_readRes1();
return resp >> 16; // deassert chip select
spi_exchange(0xFF);
spi_deselect(0);
spi_exchange(0xFF);
return res1;
}
*/
/*******************************************************************************
Run power up sequence
*******************************************************************************/
/*
void SD_powerUpSeq()
{
uint16_t i;
uint8_t j;
// make sure card is deselected
spi_deselect(0);
// give SD card time to power up
for (i = 0; i < 1000; i++);
// select SD card
spi_exchange(0xFF);
spi_deselect(0);
// send 80 clock cycles to synchronize
for(j = 0; j < SD_INIT_CYCLES; j++)
spi_exchange(0xFF);
}
*/
/*******************************************************************************
Send command to SD card
*******************************************************************************/
/*
void SD_command(uint8_t cmd, uint32_t arg, uint8_t crc)
{
// transmit command to sd card
spi_exchange(cmd|0x40);
// transmit argument
spi_exchange((uint8_t)(arg >> 24));
spi_exchange((uint8_t)(arg >> 16));
spi_exchange((uint8_t)(arg >> 8));
spi_exchange((uint8_t)(arg));
// transmit crc
spi_exchange(crc|0x01);
}
*/
/*******************************************************************************
Read R1 from SD card
*******************************************************************************/
/*
uint8_t SD_readRes1()
{
uint8_t i = 0, res1;
// keep polling until actual data received
while((res1 = spi_exchange(0xFF)) == 0xFF)
{
i++;
// if no data received for 8 bytes, break
if(i > 8) break;
}
return res1;
}
*/
/*******************************************************************************
Read R2 from SD card
*******************************************************************************/
/*
void SD_readRes2(uint8_t *res)
{
// read response 1 in R2
res[0] = SD_readRes1();
// read final byte of response
res[1] = spi_exchange(0xFF);
}
*/
/*******************************************************************************
Read R3 from SD card
*******************************************************************************/
/*
void SD_readRes3(uint8_t *res)
{
// read response 1 in R3
res[0] = SD_readRes1();
// if error reading R1, return
if(res[0] > 1) return;
// read remaining bytes
SD_readBytes(res + 1, R3_BYTES);
}
*/
/*******************************************************************************
Read R7 from SD card
*******************************************************************************/
/*
void SD_readRes7(uint8_t *res)
{
// read response 1 in R7
res[0] = SD_readRes1();
// if error reading R1, return
if(res[0] > 1) return;
// read remaining bytes
SD_readBytes(res + 1, R7_BYTES);
}
*/
/*******************************************************************************
Read specified number of bytes from SD card
*******************************************************************************/
/*
void SD_readBytes(uint8_t *res, uint8_t n)
{
while(n--) *res++ = spi_exchange(0xFF);
}
*/
/*******************************************************************************
Command Idle State (CMD0)
*******************************************************************************/
uint8_t SD_goIdleState()
{
return res1_cmd(CMD0, CMD0_ARG, CMD0_CRC);
} }
uint16_t sd_select_card(uint16_t rca) { /*******************************************************************************
uint32_t resp; Send Interface Conditions (CMD8)
*******************************************************************************/
void SD_sendIfCond(uint8_t *res)
{
// assert chip select
spi_exchange(0xFF);
spi_select(0);
spi_exchange(0xFF);
sd_card_command((uint32_t)rca << 16, 7); // send CMD8
sd_card_resp(&resp); SD_command(CMD8, CMD8_ARG, CMD8_CRC);
return (uint16_t) resp; // read response
SD_readRes7(res);
//SD_readBytes(res + 1, R7_BYTES);
// deassert chip select
spi_exchange(0xFF);
spi_deselect(0);
spi_exchange(0xFF);
} }
uint16_t sd_get_status(uint16_t rca) { /*******************************************************************************
uint32_t resp; Read Status
*******************************************************************************/
void SD_sendStatus(uint8_t *res)
{
// assert chip select
spi_exchange(0xFF);
spi_select(0);
spi_exchange(0xFF);
sd_card_command((uint32_t)rca << 16, 13); // send CMD13
sd_card_resp(&resp); SD_command(CMD13, CMD13_ARG, CMD13_CRC);
return (uint16_t) resp; // read response
SD_readRes2(res);
// deassert chip select
spi_exchange(0xFF);
spi_deselect(0);
spi_exchange(0xFF);
} }
void sd_readblock(uint32_t addr, void* buf) { /*******************************************************************************
uint32_t resp; Read single 512 byte block
int i; token = 0xFE - Successful read
token = 0x0X - Data error
token = 0xFF - timeout
*******************************************************************************/
uint8_t SD_readSingleBlock(uint32_t addr, uint8_t *buf, uint8_t *token)
{
uint8_t res1, read;
uint16_t readAttempts;
uint16_t i;
sd_card_command(addr, 17); // set token to none
sd_card_resp(&resp); *token = 0xFF;
//cprintf("CMD17: %lx\n", resp);
sd_card_wait_for_data(); // assert chip select
spi_exchange(0xFF);
spi_select(0);
spi_exchange(0xFF);
//cprintf("Read data: \n"); // send CMD17
for (i = 0; i < 512; i++){ SD_command(CMD17, addr, CMD17_CRC);
((uint8_t*)buf)[i] = sd_card_read_byte();
}
//cprintf("\n"); // read R1
res1 = SD_readRes1();
// if response received from card
if(res1 != 0xFF)
{
// wait for a response token (timeout = 100ms)
readAttempts = 0;
while(++readAttempts != SD_MAX_READ_ATTEMPTS)
if((read = spi_exchange(0xFF)) != 0xFF) break;
// if response token is 0xFE
if(read == SD_START_TOKEN)
{
// read 512 byte block
for(i = 0; i < SD_BLOCK_LEN; i++) *buf++ = spi_exchange(0xFF);
// read 16-bit CRC
spi_exchange(0xFF);
spi_exchange(0xFF);
}
// set token to card response
*token = read;
}
// deassert chip select
spi_exchange(0xFF);
spi_deselect(0);
spi_exchange(0xFF);
return res1;
}
#define SD_MAX_WRITE_ATTEMPTS 3907
/*******************************************************************************
Write single 512 byte block
token = 0x00 - busy timeout
token = 0x05 - data accepted
token = 0xFF - response timeout
*******************************************************************************/
uint8_t SD_writeSingleBlock(uint32_t addr, uint8_t *buf, uint8_t *token)
{
uint16_t readAttempts;
uint8_t res1, read;
uint16_t i;
/*
// set token to none
*token = 0xFF;
// assert chip select
spi_exchange(0xFF);
spi_select(0);
spi_exchange(0xFF);
// send CMD24
SD_command(CMD24, addr, CMD24_CRC);
// read response
res1 = SD_readRes1();
// if no error
if(res1 == SD_READY)
{
// send start token
spi_exchange(SD_START_TOKEN);
// write buffer to card
for(i = 0; i < SD_BLOCK_LEN; i++) spi_exchange(buf[i]);
// wait for a response (timeout = 250ms)
readAttempts = 0;
while(++readAttempts != SD_MAX_WRITE_ATTEMPTS)
if((read = spi_exchange(0xFF)) != 0xFF) { *token = 0xFF; break; }
// if data accepted
if((read & 0x1F) == 0x05)
{
// set token to data accepted
*token = 0x05;
// wait for write to finish (timeout = 250ms)
readAttempts = 0;
while(spi_exchange(0xFF) == 0x00)
if(++readAttempts == SD_MAX_WRITE_ATTEMPTS) { *token = 0x00; break; }
}
}
// deassert chip select
spi_exchange(0xFF);
spi_deselect(0);
spi_exchange(0xFF);
*/
return res1;
}
/*******************************************************************************
Reads OCR from SD Card
*******************************************************************************/
void SD_readOCR(uint8_t *res)
{
uint8_t tmp;
// assert chip select
spi_exchange(0xFF);
spi_select(0);
tmp = spi_exchange(0xFF);
if(tmp != 0xFF) while(spi_exchange(0xFF) != 0xFF) ;
// send CMD58
SD_command(CMD58, CMD58_ARG, CMD58_CRC);
// read response
SD_readRes3(res);
// deassert chip select
spi_exchange(0xFF);
spi_deselect(0);
spi_exchange(0xFF);
}
/*******************************************************************************
Send application command (CMD55)
*******************************************************************************/
uint8_t SD_sendApp()
{
return res1_cmd(CMD55, CMD55_ARG, CMD55_CRC);;
}
/*******************************************************************************
Send operating condition (ACMD41)
*******************************************************************************/
uint8_t SD_sendOpCond()
{
return res1_cmd(ACMD41, ACMD41_ARG, ACMD41_CRC);
} }

View File

@@ -3,16 +3,78 @@
#include <stdint.h> #include <stdint.h>
void sd_init(); // command definitions
uint16_t sd_get_rca(); #define CMD0 0
uint16_t sd_select_card(uint16_t rca); #define CMD0_ARG 0x00000000
uint16_t sd_get_status(uint16_t rca); #define CMD0_CRC 0x94
void sd_readblock(uint32_t addr, void* buf); #define CMD8 8
#define CMD8_ARG 0x0000001AA
#define CMD8_CRC 0x86
#define CMD9 9
#define CMD9_ARG 0x00000000
#define CMD9_CRC 0x00
#define CMD10 9
#define CMD10_ARG 0x00000000
#define CMD10_CRC 0x00
#define CMD13 13
#define CMD13_ARG 0x00000000
#define CMD13_CRC 0x00
#define CMD17 17
#define CMD17_CRC 0x00
#define CMD24 24
#define CMD24_CRC 0x00
#define CMD55 55
#define CMD55_ARG 0x00000000
#define CMD55_CRC 0x00
#define CMD58 58
#define CMD58_ARG 0x00000000
#define CMD58_CRC 0x00
#define ACMD41 41
#define ACMD41_ARG 0x40000000
#define ACMD41_CRC 0x00
void sd_card_command(uint32_t arg, uint8_t cmd); #define SD_IN_IDLE_STATE 0x01
#define SD_READY 0x00
#define SD_R1_NO_ERROR(X) X < 0x02
void sd_card_resp(uint32_t* resp); #define R3_BYTES 4
uint8_t sd_card_read_byte(); #define R7_BYTES 4
void sd_card_wait_for_data();
#endif #define CMD0_MAX_ATTEMPTS 255
#define CMD55_MAX_ATTEMPTS 255
#define SD_ERROR 1
#define SD_SUCCESS 0
#define SD_MAX_READ_ATTEMPTS 1563
#define SD_READ_START_TOKEN 0xFE
#define SD_INIT_CYCLES 80
#define SD_START_TOKEN 0xFE
#define SD_ERROR_TOKEN 0x00
#define SD_DATA_ACCEPTED 0x05
#define SD_DATA_REJECTED_CRC 0x0B
#define SD_DATA_REJECTED_WRITE 0x0D
#define SD_BLOCK_LEN 512
// SD functions
uint8_t SD_init();
void SD_powerUpSeq();
void SD_command(uint8_t cmd, uint32_t arg, uint8_t crc);
uint8_t SD_readRes1();
void SD_readRes2(uint8_t *res);
void SD_readRes3(uint8_t *res);
void SD_readRes7(uint8_t *res);
void SD_readBytes(uint8_t *res, uint8_t n);
uint8_t SD_goIdleState();
void SD_sendIfCond(uint8_t *res);
void SD_sendStatus(uint8_t *res);
void SD_readOCR(uint8_t *res);
uint8_t SD_sendApp();
uint8_t SD_sendOpCond();
uint8_t SD_readSingleBlock(uint32_t addr, uint8_t *buf, uint8_t *error);
uint8_t SD_writeSingleBlock(uint32_t addr, uint8_t *buf, uint8_t *res);
uint8_t res1_cmd(uint8_t cmd, uint32_t arg, uint8_t crc);
#endif

View File

@@ -1,66 +1,190 @@
.include "io.inc65" .export _SD_command
.export _SD_readRes1
.export _SD_readRes2
.export _SD_readRes3
.export _SD_readRes7
.export _SD_readBytes
.export _SD_powerUpSeq
.export _res1_cmd
.importzp sp, sreg, ptr1 .importzp sp, ptr1
.export _sd_card_command
.export _sd_card_resp
.export _sd_card_read_byte
.export _sd_card_wait_for_data
.autoimport on .autoimport on
.code .MACPACK generic
; Send sd card command. ; void SD_command(uint8_t cmd, uint32_t arg, uint8_t crc)
; command is in A register, the args are on the stack
; I think the order is high byte first?
_sd_card_command:
pha
jsr popeax ; The plan: push crc to stack, load arg into tmp1 through 4
sta SD_ARG
stx SD_ARG+1
lda sreg
sta SD_ARG+2
lda sreg+1
sta SD_ARG+3
pla .proc _SD_command: near
sta SD_CMD
rts
; void sd_card_resp(uint32_t* resp); pha ; Push CRC to cpu stack
_sd_card_resp: ldy #$04
phy lda (sp),y ; Load CMD
sta ptr1 ; store pointer ora #$40 ; start bit
stx ptr1+1 jsr _spi_exchange
@1: lda SD_CMD ; wait for status flag
and #$01 dey
beq @1 arg_loop: ; send ARG
lda SD_ARG lda (sp),y
ldy #$0 jsr _spi_exchange
sta (ptr1),y dey
lda SD_ARG+1 bpl arg_loop
iny
sta (ptr1),y pla ; Pull CRC from stack
lda SD_ARG+2 ora #$01 ; stop bit
iny jsr _spi_exchange
sta (ptr1),y jsr incsp5 ; pop all off stack
lda SD_ARG+3
iny
sta (ptr1),y
ply
rts rts
_sd_card_read_byte: .endproc
lda SD_DATA
ldx #$00 ; uint8_t SD_readRes1 (void)
.proc _SD_readRes1: near
; Try to read/write up to 8 times, then return value
ldx #$08
tryread:
lda #$ff
jsr _spi_exchange
cmp #$ff
bne end
dex
bne tryread
end: ; x will be 0 here anyway
rts rts
_sd_card_wait_for_data: .endproc
pha
@1: lda SD_CMD ; wait for status flag ; void SD_readRes2(uint8_t *res)
and #$02
beq @1 .proc _SD_readRes2: near
sta ptr1 ; store res in ptr1
stx ptr1 + 1
jsr _SD_readRes1 ; get first response 1
sta (ptr1)
lda #$ff
jsr _spi_exchange ; get final byte of response
ldy #$01
sta (ptr1),y
jsr incsp2
rts
.endproc
; void SD_readBytes(uint8_t *res, uint8_t n)
.proc _SD_readBytes: near
tax
jsr popptr1 ; store res in ptr1
read:
lda #$ff ; read data first
jsr _spi_exchange
sta (ptr1)
inc ptr1 ; then increment res
bne @L1
inc ptr1 + 1
@L1: dex ; then decrement x
bne read ; and if x is zero we are done
rts
.endproc
; void SD_readRes7(uint8_t *res)
_SD_readRes7:
; void SD_readRes3(uint8_t *res)
.proc _SD_readRes3: near
sta ptr1 ; store res in ptr1
stx ptr1 + 1
jsr _SD_readRes1 ; read respopnse 1 in R3
cmp #$02 ; if error reading R1, return
bge @L1
inc ptr1 ; read remaining bytes
bne @L2
inc ptr1
@L2: lda ptr1 ; push low byte
ldx ptr1 + 1
jsr pushax
lda #$04 ; R3_BYTES
jsr _SD_readBytes
@L1: rts
.endproc
; uint8_t res1_cmd(uint8_t cmd, uint32_t arg, uint8_t crc)
.proc _res1_cmd: near
pha ; push crc to processor stack
lda #$ff
jsr _spi_exchange
lda #$00 ; this gets ignored anyway
jsr _spi_select
lda #$ff
jsr _spi_exchange
pla pla
rts jsr _SD_command ; rely on command to teardown stack
jsr _SD_readRes1
tay ; spi doesn't touch y
lda #$ff
jsr _spi_exchange
lda #$00 ; this gets ignored anyway
jsr _spi_deselect
lda #$ff
jsr _spi_exchange
tya
ldx #$00 ; Promote to integer
rts
.endproc
; void SD_powerUpSeq(void)
.proc _SD_powerUpSeq: near
lda #$00
jsr _spi_deselect
jsr _sd_delay
lda #$ff
jsr _spi_exchange
lda #$00
jsr _spi_deselect
ldx #$50 ; SD_INIT_CYCLES
@L1: lda #$ff
jsr _spi_exchange
dex
bne @L1
rts
.endproc
; 1ms delay approx. saves no registers
.proc _sd_delay: near
ldx #$01 ; delay loop: A*X*10 + 4
@L1: lda #$c8 ; 1ms at 2MHz
@L2: dec ; 2
bne @L2 ; 3
dex ; 2
bne @L1 ; 3
rts
.endproc

View File

@@ -0,0 +1,188 @@
#include <conio.h>
#include "sd_print.h"
#include "sd_card.h"
/*
void SD_printR1(uint8_t res)
{
if(res == 0xFF)
{ cputs("\tNo response\r\n"); return; }
if(res & 0x80)
{ cputs("\tError: MSB = 1\r\n"); return; }
if(res == 0)
{ cputs("\tCard Ready\r\n"); return; }
if(PARAM_ERROR(res))
cputs("\tParameter Error\r\n");
if(ADDR_ERROR(res))
cputs("\tAddress Error\r\n");
if(ERASE_SEQ_ERROR(res))
cputs("\tErase Sequence Error\r\n");
if(CRC_ERROR(res))
cputs("\tCRC Error\r\n");
if(ILLEGAL_CMD(res))
cputs("\tIllegal Command\r\n");
if(ERASE_RESET(res))
cputs("\tErase Reset Error\r\n");
if(IN_IDLE(res))
cputs("\tIn Idle State\r\n");
}
*/
/*
void SD_printR2(uint8_t *res)
{
SD_printR1(res[0]);
if(res[0] == 0xFF) return;
if(res[1] == 0x00)
cputs("\tNo R2 Error\r\n");
if(OUT_OF_RANGE(res[1]))
cputs("\tOut of Range\r\n");
if(ERASE_PARAM(res[1]))
cputs("\tErase Parameter\r\n");
if(WP_VIOLATION(res[1]))
cputs("\tWP Violation\r\n");
if(CARD_ECC_FAILED(res[1]))
cputs("\tECC Failed\r\n");
if(CC_ERROR(res[1]))
cputs("\tCC Error\r\n");
if(ERROR(res[1]))
cputs("\tError\r\n");
if(WP_ERASE_SKIP(res[1]))
cputs("\tWP Erase Skip\r\n");
if(CARD_LOCKED(res[1]))
cputs("\tCard Locked\r\n");
}
*/
/*
void SD_printR3(uint8_t *res)
{
SD_printR1(res[0]);
if(res[0] > 1) return;
cputs("\tCard Power Up Status: ");
if(POWER_UP_STATUS(res[1]))
{
cputs("READY\r\n");
cputs("\tCCS Status: ");
if(CCS_VAL(res[1])){ cputs("1\r\n"); }
else cputs("0\r\n");
}
else
{
cputs("BUSY\r\n");
}
cputs("\tVDD Window: ");
if(VDD_2728(res[3])) cputs("2.7-2.8, ");
if(VDD_2829(res[2])) cputs("2.8-2.9, ");
if(VDD_2930(res[2])) cputs("2.9-3.0, ");
if(VDD_3031(res[2])) cputs("3.0-3.1, ");
if(VDD_3132(res[2])) cputs("3.1-3.2, ");
if(VDD_3233(res[2])) cputs("3.2-3.3, ");
if(VDD_3334(res[2])) cputs("3.3-3.4, ");
if(VDD_3435(res[2])) cputs("3.4-3.5, ");
if(VDD_3536(res[2])) cputs("3.5-3.6");
cputs("\r\n");
}
*/
/*
void SD_printR7(uint8_t *res)
{
SD_printR1(res[0]);
if(res[0] > 1) return;
cputs("\tCommand Version: ");
cprintf("%x", CMD_VER(res[1]));
cputs("\r\n");
cputs("\tVoltage Accepted: ");
if(VOL_ACC(res[3]) == VOLTAGE_ACC_27_33) {
cputs("2.7-3.6V\r\n");
} else if(VOL_ACC(res[3]) == VOLTAGE_ACC_LOW) {
cputs("LOW VOLTAGE\r\n");
} else if(VOL_ACC(res[3]) == VOLTAGE_ACC_RES1) {
cputs("RESERVED\r\n");
} else if(VOL_ACC(res[3]) == VOLTAGE_ACC_RES2) {
cputs("RESERVED\r\n");
} else {
cputs("NOT DEFINED\r\n");
}
cputs("\tEcho: ");
cprintf("%x", res[4]);
cputs("\r\n");
}
*/
/*
void SD_printCSD(uint8_t *buf)
{
cputs("CSD:\r\n");
cputs("\tCSD Structure: ");
cprintf("%x", (buf[0] & 0b11000000) >> 6);
cputs("\r\n");
cputs("\tTAAC: ");
cprintf("%x", buf[1]);
cputs("\r\n");
cputs("\tNSAC: ");
cprintf("%x", buf[2]);
cputs("\r\n");
cputs("\tTRAN_SPEED: ");
cprintf("%x", buf[3]);
cputs("\r\n");
cputs("\tDevice Size: ");
cprintf("%x", buf[7] & 0b00111111);
cprintf("%x", buf[8]);
cprintf("%x", buf[9]);
cputs("\r\n");
}
*/
void SD_printBuf(uint8_t *buf)
{
uint8_t colCount = 0;
uint16_t i;
for(i = 0; i < SD_BLOCK_LEN; i++)
{
cprintf("%2x", *buf++);
if(colCount == 19)
{
cputs("\r\n");
colCount = 0;
}
else
{
cputc(' ');
colCount++;
}
}
cputs("\r\n");
}
/*
void SD_printDataErrToken(uint8_t token)
{
if(token & 0xF0)
cputs("\tNot Error token\r\n");
if(SD_TOKEN_OOR(token))
cputs("\tData out of range\r\n");
if(SD_TOKEN_CECC(token))
cputs("\tCard ECC failed\r\n");
if(SD_TOKEN_CC(token))
cputs("\tCC Error\r\n");
if(SD_TOKEN_ERROR(token))
cputs("\tError\r\n");
}
*/

View File

@@ -0,0 +1,61 @@
#ifndef SD_PRINT_H
#define SD_PRINT_H
#include <stdint.h>
/* R1 MACROS */
#define PARAM_ERROR(X) X & 0b01000000
#define ADDR_ERROR(X) X & 0b00100000
#define ERASE_SEQ_ERROR(X) X & 0b00010000
#define CRC_ERROR(X) X & 0b00001000
#define ILLEGAL_CMD(X) X & 0b00000100
#define ERASE_RESET(X) X & 0b00000010
#define IN_IDLE(X) X & 0b00000001
/* R2 MACROS */
#define OUT_OF_RANGE(X) X & 0b10000000
#define ERASE_PARAM(X) X & 0b01000000
#define WP_VIOLATION(X) X & 0b00100000
#define CARD_ECC_FAILED(X) X & 0b00010000
#define CC_ERROR(X) X & 0b00001000
#define ERROR(X) X & 0b00000100
#define WP_ERASE_SKIP(X) X & 0b00000010
#define CARD_LOCKED(X) X & 0b00000001
/* R3 MACROS */
#define POWER_UP_STATUS(X) X & 0x40
#define CCS_VAL(X) X & 0x40
#define VDD_2728(X) X & 0b10000000
#define VDD_2829(X) X & 0b00000001
#define VDD_2930(X) X & 0b00000010
#define VDD_3031(X) X & 0b00000100
#define VDD_3132(X) X & 0b00001000
#define VDD_3233(X) X & 0b00010000
#define VDD_3334(X) X & 0b00100000
#define VDD_3435(X) X & 0b01000000
#define VDD_3536(X) X & 0b10000000
/* R7 MACROS */
#define CMD_VER(X) ((X >> 4) & 0xF0)
#define VOL_ACC(X) (X & 0x1F)
#define VOLTAGE_ACC_27_33 0b00000001
#define VOLTAGE_ACC_LOW 0b00000010
#define VOLTAGE_ACC_RES1 0b00000100
#define VOLTAGE_ACC_RES2 0b00001000
/* DATA ERROR TOKEN */
#define SD_TOKEN_OOR(X) X & 0b00001000
#define SD_TOKEN_CECC(X) X & 0b00000100
#define SD_TOKEN_CC(X) X & 0b00000010
#define SD_TOKEN_ERROR(X) X & 0b00000001
void SD_printR1(uint8_t res);
void SD_printR2(uint8_t *res);
void SD_printR3(uint8_t *res);
void SD_printR7(uint8_t *res);
void SD_printBuf(uint8_t *buf);
void SD_printDataErrToken(uint8_t token);
#endif

View File

@@ -0,0 +1,12 @@
#ifndef _SPI_H
#define _SPI_H
#include <stdint.h>
void spi_select(uint8_t id);
void spi_deselect(uint8_t id);
uint8_t spi_read();
void spi_write(uint8_t data);
uint8_t spi_exchange(uint8_t data);
#endif

View File

@@ -0,0 +1,39 @@
.include "io.inc65"
.importzp zp, sreg
.export _spi_select, _spi_deselect
.export _spi_read, _spi_write, _spi_exchange
.autoimport on
.code
; void spi_select(uint8_t id)
; Select a (the) slave by pulling its CS line down
; TODO allow active high or active low CS
; TODO allow more than one slave
_spi_select:
lda #$1 ; Ignore whatever id is, 1 is the only option
sta SPI_CTRL
rts
; void spi_deslect(uint8_t id)
; Deslect a slave by pulling its CS line up
; TODO allow active high or active low CS
_spi_deselect:
stz SPI_CTRL
rts
; uint8_t spi_read()
_spi_read:
lda #$0
; void spi_write(uint8_t data)
_spi_write:
; uint8_t spi_exchange(uint8_t data)
_spi_exchange:
sta SPI_OUTPUT
@1: lda SPI_CTRL
bmi @1
lda SPI_INPUT
rts

View File

@@ -6,6 +6,7 @@
#include "devices/board_io.h" #include "devices/board_io.h"
#include "devices/uart.h" #include "devices/uart.h"
#include "devices/sd_card.h" #include "devices/sd_card.h"
#include "devices/sd_print.h"
#include "filesystem/fat.h" #include "filesystem/fat.h"
#define KERNEL_LOAD_ADDR 0xD000 #define KERNEL_LOAD_ADDR 0xD000
@@ -13,40 +14,68 @@
uint8_t buf[512]; uint8_t buf[512];
int main() { int main() {
uint16_t rca; // array to hold responses
clrscr(); uint8_t res[5], token;
cputs("Starting sd_init\n"); uint32_t addr = 0x00000000;
cprintf("And testing cprintf\n"); uint16_t i;
sd_init(); cputs("Start\r\n");
cprintf("finish sd_init\n"); // initialize sd card
if(SD_init() != SD_SUCCESS)
{
cputs("Error\r\n");
}
else
{
cputs("Success\r\n");
rca = sd_get_rca(); // read sector 0
cprintf("rca: %x\n", rca); cputs("\r\nReading sector: 0x");
// ((uint8_t)(addr >> 24));
// cprintf("%x", (uint8_t)(addr >> 16));
// cprintf("%x", (uint8_t)(addr >> 8));
// cprintf("%x", (uint8_t)addr);
res[0] = SD_readSingleBlock(addr, buf, &token);
cputs("\r\nResponse:\r\n");
//SD_printR1(res[0]);
sd_select_card(rca); // if no error, print buffer
if((res[0] == 0x00) && (token == SD_START_TOKEN))
SD_printBuf(buf);
//else if error token received, print
else if(!(token & 0xF0))
{
cputs("Error token:\r\n");
//SD_printDataErrToken(token);
}
/* // update address to 0x00000100
fat_init(); // addr = 0x00000100;
filename = (char*)malloc(FAT_MAX_FILE_NAME); // // fill buffer with 0x55
// for(i = 0; i < 512; i++) buf[i] = 0x55;
cluster = fat_parse_path_to_cluster("/kernel.bin"); // cputs("Writing 0x55 to sector: 0x");
for (kernel_load = (uint8_t*)KERNEL_LOAD_ADDR; cluster < FAT_CLUSTERMASK; kernel_load+=(8*512)) { // cprintf("%x", (uint8_t)(addr >> 24));
cprintf("cluster: %lx\n", cluster); // cprintf("%x", (uint8_t)(addr >> 16));
cprintf("Writing to %p\n", kernel_load); // cprintf("%x", (uint8_t)(addr >> 8));
fat_read_cluster(cluster, kernel_load); // cprintf("%x", (uint8_t)addr);
cluster = fat_get_chain_value(cluster);
}
*/ // // write data to sector
// res[0] = SD_writeSingleBlock(addr, buf, &token);
cprintf("Done!\n"); // cputs("\r\nResponse:\r\n");
// //SD_printR1(res[0]);
for(;;); // // if no errors writing
// if(res[0] == 0x00)
// {
// if(token == SD_DATA_ACCEPTED)
// cputs("Write successful\r\n");
// }
}
cprintf("Reset vector: %x\n", *((uint16_t*)0xfffc)); while(1) ;
return 0;
} }