Skip to content

Commit 421d043

Browse files
[SC64][FW][SW] Controller rewrite to remove task subsystem + minor bug fixes (#64)
This PR completely removes `task.c / task.h` from `sw/controller` STM32 code. Additionally, these changes were implemented: - Updated IPL3 - Added new diagnostic data (voltage and temperature) readout commands for USB and N64 - Fixed some issues with FlashRAM save type - Joybus timings were relaxed to accommodate communication with unsynchronized master controller (like _Datel Game Killer_, thanks @RWeick) - N64 embedded test program now waits for release of button press to proceed - Fixed issue where, in rare circumstances, I2C peripheral in STM32 would get locked-up on power-up - LED blinking behavior on SD card access was changed - LED blink duration on save writeback has been extended - Minor fixes through the entire of hardware abstraction layer for STM32 code - Primer now correctly detects issues with I2C bus during first time programming - `primer.py` script gives more meaningful error messages - Fixed bug where RTC time was always written on N64FlashcartMenu boot - sc64deployer now displays "Diagnostic data" instead of "MCU stack usage"
1 parent be37025 commit 421d043

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+1793
-1950
lines changed

build.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ build_cic () {
8383
build_fpga () {
8484
if [ "$BUILT_FPGA" = true ]; then return; fi
8585

86+
build_cic
87+
8688
pushd fw/project/lcmxo2 > /dev/null
8789
if [ "$FORCE_CLEAN" = true ]; then
8890
rm -rf ./impl1/

docker_build.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!/bin/bash
22

3-
BUILDER_IMAGE="ghcr.io/polprzewodnikowy/sc64env:v1.8"
3+
BUILDER_IMAGE="ghcr.io/polprzewodnikowy/sc64env:v1.9"
44

55
pushd $(dirname $0) > /dev/null
66

docs/02_n64_commands.md

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,28 @@
44

55
## N64 commands
66

7-
| id | name | arg0 | arg1 | rsp0 | rsp1 | description |
8-
| --- | --------------------- | -------------- | ------------ | ---------------- | -------------- | ---------------------------------------------------------- |
9-
| `v` | **IDENTIFIER_GET** | --- | --- | identifier | --- | Get flashcart identifier `SCv2` |
10-
| `V` | **VERSION_GET** | --- | --- | major/minor | revision | Get flashcart firmware version |
11-
| `c` | **CONFIG_GET** | config_id | --- | --- | current_value | Get config option |
12-
| `C` | **CONFIG_SET** | config_id | new_value | --- | previous_value | Set config option and get previous value |
13-
| `a` | **SETTING_GET** | setting_id | --- | --- | current_value | Get persistent setting option |
14-
| `A` | **SETTING_SET** | setting_id | new_value | --- | --- | Set persistent setting option |
15-
| `t` | **TIME_GET** | --- | --- | time_0 | time_1 | Get current RTC value |
16-
| `T` | **TIME_SET** | time_0 | time_1 | --- | --- | Set new RTC value |
17-
| `m` | **USB_READ** | pi_address | length | --- | --- | Receive data from USB to flashcart |
18-
| `M` | **USB_WRITE** | pi_address | length/type | --- | --- | Send data from from flashcart to USB |
19-
| `u` | **USB_READ_STATUS** | --- | --- | read_status/type | length | Get USB read status and type/length |
20-
| `U` | **USB_WRITE_STATUS** | --- | --- | write_status | --- | Get USB write status |
21-
| `i` | **SD_CARD_OP** | pi_address | operation | --- | return_data | Perform special operation on SD card |
22-
| `I` | **SD_SECTOR_SET** | sector | --- | --- | --- | Set starting sector for next SD card R/W operation |
23-
| `s` | **SD_READ** | pi_address | sector_count | --- | --- | Read sectors from SD card to flashcart |
24-
| `S` | **SD_WRITE** | pi_address | sector_count | --- | --- | Write sectors from flashcart to SD card |
25-
| `D` | **DISK_MAPPING_SET** | pi_address | table_size | --- | --- | Set 64DD disk mapping for SD mode |
26-
| `w` | **WRITEBACK_PENDING** | --- | --- | pending_status | --- | Get save writeback status (is write queued to the SD card) |
27-
| `W` | **WRITEBACK_SD_INFO** | pi_address | --- | --- | --- | Load writeback SD sector table and enable it |
28-
| `K` | **FLASH_PROGRAM** | pi_address | length | --- | --- | Program flash with bytes loaded into data buffer |
29-
| `p` | **FLASH_WAIT_BUSY** | wait | --- | erase_block_size | --- | Wait until flash ready / get block erase size |
30-
| `P` | **FLASH_ERASE_BLOCK** | pi_address | --- | --- | --- | Start flash block erase |
7+
| id | name | arg0 | arg1 | rsp0 | rsp1 | description |
8+
| --- | --------------------- | ------------- | ------------ | ---------------- | -------------- | ---------------------------------------------------------- |
9+
| `v` | **IDENTIFIER_GET** | --- | --- | identifier | --- | Get flashcart identifier `SCv2` |
10+
| `V` | **VERSION_GET** | --- | --- | major/minor | revision | Get flashcart firmware version |
11+
| `c` | **CONFIG_GET** | config_id | --- | --- | current_value | Get config option |
12+
| `C` | **CONFIG_SET** | config_id | new_value | --- | previous_value | Set config option and get previous value |
13+
| `a` | **SETTING_GET** | setting_id | --- | --- | current_value | Get persistent setting option |
14+
| `A` | **SETTING_SET** | setting_id | new_value | --- | --- | Set persistent setting option |
15+
| `t` | **TIME_GET** | --- | --- | time_0 | time_1 | Get current RTC value |
16+
| `T` | **TIME_SET** | time_0 | time_1 | --- | --- | Set new RTC value |
17+
| `m` | **USB_READ** | pi_address | length | --- | --- | Receive data from USB to flashcart |
18+
| `M` | **USB_WRITE** | pi_address | length/type | --- | --- | Send data from from flashcart to USB |
19+
| `u` | **USB_READ_STATUS** | --- | --- | read_status/type | length | Get USB read status and type/length |
20+
| `U` | **USB_WRITE_STATUS** | --- | --- | write_status | --- | Get USB write status |
21+
| `i` | **SD_CARD_OP** | pi_address | operation | --- | return_data | Perform special operation on SD card |
22+
| `I` | **SD_SECTOR_SET** | sector | --- | --- | --- | Set starting sector for next SD card R/W operation |
23+
| `s` | **SD_READ** | pi_address | sector_count | --- | --- | Read sectors from SD card to flashcart |
24+
| `S` | **SD_WRITE** | pi_address | sector_count | --- | --- | Write sectors from flashcart to SD card |
25+
| `D` | **DISK_MAPPING_SET** | pi_address | table_size | --- | --- | Set 64DD disk mapping for SD mode |
26+
| `w` | **WRITEBACK_PENDING** | --- | --- | pending_status | --- | Get save writeback status (is write queued to the SD card) |
27+
| `W` | **WRITEBACK_SD_INFO** | pi_address | --- | --- | --- | Load writeback SD sector table and enable it |
28+
| `K` | **FLASH_PROGRAM** | pi_address | length | --- | --- | Program flash with bytes loaded into data buffer |
29+
| `p` | **FLASH_WAIT_BUSY** | wait | --- | erase_block_size | --- | Wait until flash ready / get block erase size |
30+
| `P` | **FLASH_ERASE_BLOCK** | pi_address | --- | --- | --- | Start flash block erase |
31+
| `%` | **DIAGNOSTIC_GET** | diagnostic_id | --- | --- | value | Get diagnostic data |

docs/03_usb_interface.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ Available packet IDs are listed in the [asynchronous packets](#asynchronous-pack
170170
| `f` | **FIRMWARE_BACKUP** | address | --- | --- | status/length | Backup firmware to specified memory address |
171171
| `F` | **FIRMWARE_UPDATE** | address | length | --- | status | Update firmware from specified memory address |
172172
| `?` | **DEBUG_GET** | --- | --- | --- | debug_data | Get internal FPGA debug info |
173-
| `%` | **STACK_USAGE_GET** | --- | --- | --- | stack_usage | Get per task stack usage |
173+
| `%` | **DIAGNOSTIC_GET** | --- | --- | --- | diagnostic_data | Get diagnostic data |
174174

175175
---
176176

fw/rtl/mcu/mcu_top.sv

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -474,7 +474,7 @@ module mcu_top (
474474
18'd0,
475475
n64_scb.flashram_write_or_erase,
476476
n64_scb.flashram_sector_or_all,
477-
n64_scb.flashram_sector,
477+
n64_scb.flashram_page,
478478
n64_scb.flashram_pending,
479479
1'b0
480480
};

fw/rtl/n64/n64_flashram.sv

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ module n64_flashram (
88
);
99

1010
localparam [31:0] FLASH_TYPE_ID = 32'h1111_8001;
11-
localparam [31:0] FLASH_MODEL_ID = 32'h00C2_001D;
11+
localparam [31:0] FLASH_MODEL_ID = 32'h0032_00F1;
1212

1313
typedef enum bit [7:0] {
1414
CMD_STATUS_MODE = 8'hD2,
@@ -97,14 +97,14 @@ module n64_flashram (
9797
CMD_ERASE_SECTOR: begin
9898
state <= STATE_STATUS;
9999
erase_enabled <= 1'b1;
100-
n64_scb.flashram_sector <= reg_bus.wdata[9:0];
100+
n64_scb.flashram_page <= reg_bus.wdata[9:0];
101101
n64_scb.flashram_sector_or_all <= 1'b0;
102102
end
103103

104104
CMD_ERASE_CHIP: begin
105105
state <= STATE_STATUS;
106106
erase_enabled <= 1'b1;
107-
n64_scb.flashram_sector <= 10'd0;
107+
n64_scb.flashram_page <= 10'd0;
108108
n64_scb.flashram_sector_or_all <= 1'b1;
109109
end
110110

@@ -126,17 +126,17 @@ module n64_flashram (
126126
state <= STATE_STATUS;
127127
status[WRITE_BUSY] <= 1'b1;
128128
status[WRITE_DONE] <= 1'b0;
129-
n64_scb.flashram_sector <= reg_bus.wdata[9:0];
129+
n64_scb.flashram_page <= reg_bus.wdata[9:0];
130130
n64_scb.flashram_pending <= 1'b1;
131131
n64_scb.flashram_write_or_erase <= 1'b0;
132132
n64_scb.flashram_sector_or_all <= 1'b0;
133133
end
134134
endcase
135135
end
136136
end else begin
137-
if (reg_bus.address[1] && state != STATE_BUFFER) begin
138-
status[ERASE_BUSY] <= reg_bus.wdata[ERASE_BUSY];
139-
status[WRITE_BUSY] <= reg_bus.wdata[WRITE_BUSY];
137+
if (reg_bus.address[1] && state == STATE_STATUS) begin
138+
status[ERASE_DONE] <= 1'b0;
139+
status[WRITE_DONE] <= 1'b0;
140140
end
141141
end
142142
end

fw/rtl/n64/n64_scb.sv

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ interface n64_scb ();
2222

2323
logic flashram_pending;
2424
logic flashram_done;
25-
logic [9:0] flashram_sector;
25+
logic [9:0] flashram_page;
2626
logic flashram_sector_or_all;
2727
logic flashram_write_or_erase;
2828
logic flashram_read_mode;
@@ -84,7 +84,7 @@ interface n64_scb ();
8484

8585
input flashram_pending,
8686
output flashram_done,
87-
input flashram_sector,
87+
input flashram_page,
8888
input flashram_sector_or_all,
8989
input flashram_write_or_erase,
9090

@@ -143,7 +143,7 @@ interface n64_scb ();
143143
modport flashram (
144144
output flashram_pending,
145145
input flashram_done,
146-
output flashram_sector,
146+
output flashram_page,
147147
output flashram_sector_or_all,
148148
output flashram_write_or_erase,
149149

fw/rtl/n64/n64_si.sv

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ module n64_si (
5959
// Data falling/rising event generator
6060

6161
logic last_si_dq_in;
62+
logic si_dq_in_inhibit;
6263

6364
always_ff @(posedge clk) begin
6465
if (si_clk_rising_edge) begin
@@ -70,14 +71,14 @@ module n64_si (
7071
logic si_dq_rising_edge;
7172

7273
always_comb begin
73-
si_dq_falling_edge = si_clk_rising_edge && last_si_dq_in && !si_dq_in;
74-
si_dq_rising_edge = si_clk_rising_edge && !last_si_dq_in && si_dq_in;
74+
si_dq_falling_edge = si_clk_rising_edge && last_si_dq_in && !si_dq_in && !si_dq_in_inhibit;
75+
si_dq_rising_edge = si_clk_rising_edge && !last_si_dq_in && si_dq_in && !si_dq_in_inhibit;
7576
end
7677

7778

7879
// RX bit generator
7980

80-
logic [3:0] rx_sub_bit_counter;
81+
logic [4:0] rx_sub_bit_counter;
8182
logic rx_timeout;
8283
logic rx_bit_valid;
8384
logic rx_bit_data;
@@ -94,7 +95,7 @@ module n64_si (
9495
always_comb begin
9596
rx_timeout = si_clk_rising_edge && si_dq_in && (&rx_sub_bit_counter);
9697
rx_bit_valid = si_dq_rising_edge;
97-
rx_bit_data = (rx_sub_bit_counter >= 4'd3) ? 1'b0 : 1'b1;
98+
rx_bit_data = (rx_sub_bit_counter >= 5'd4) ? 1'b0 : 1'b1;
9899
end
99100

100101

@@ -124,7 +125,7 @@ module n64_si (
124125
logic rx_stop;
125126

126127
always_comb begin
127-
rx_stop = si_clk_rising_edge && si_dq_in && (rx_sub_bit_counter == 4'd7) && (rx_bit_counter == 3'd1);
128+
rx_stop = si_clk_rising_edge && si_dq_in && (rx_sub_bit_counter == 5'd15) && (rx_bit_counter == 3'd1);
128129
end
129130

130131

@@ -260,7 +261,8 @@ module n64_si (
260261
typedef enum bit [1:0] {
261262
TX_STATE_IDLE,
262263
TX_STATE_DATA,
263-
TX_STATE_STOP
264+
TX_STATE_STOP,
265+
TX_STATE_STOP_WAIT
264266
} e_tx_state;
265267

266268
e_tx_state tx_state;
@@ -278,12 +280,14 @@ module n64_si (
278280

279281
if (reset) begin
280282
tx_state <= TX_STATE_IDLE;
283+
si_dq_in_inhibit <= 1'b0;
281284
end else begin
282285
case (tx_state)
283286
TX_STATE_IDLE: begin
284287
if (tx_start) begin
285288
tx_byte_counter <= 4'd0;
286289
tx_state <= TX_STATE_DATA;
290+
si_dq_in_inhibit <= 1'b1;
287291
end
288292
end
289293

@@ -299,7 +303,14 @@ module n64_si (
299303
TX_STATE_STOP: begin
300304
tx_stop <= 1'b1;
301305
if (!tx_busy && tx_stop) begin
306+
tx_state <= TX_STATE_STOP_WAIT;
307+
end
308+
end
309+
310+
TX_STATE_STOP_WAIT: begin
311+
if (!tx_busy) begin
302312
tx_state <= TX_STATE_IDLE;
313+
si_dq_in_inhibit <= 1'b0;
303314
end
304315
end
305316
endcase
@@ -382,7 +393,7 @@ module n64_si (
382393
4'd1: {rtc_time_wp, rtc_backup_wp} <= rx_byte_data[1:0];
383394
4'd2: begin
384395
rtc_stopped <= rx_byte_data[2:1];
385-
if (rx_byte_data[2:1] == 2'b00) begin
396+
if ((|rtc_stopped) && (rx_byte_data[2:1] == 2'b00)) begin
386397
n64_scb.rtc_pending <= 1'b1;
387398
end
388399
end

sw/bootloader/src/font.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ const uint8_t font_data[96][FONT_CHAR_BYTES] = {
6868
{ 0x38, 0x30, 0x30, 0x30, 0x30, 0x30, 0x38, 0x00, },
6969
{ 0x00, 0x38, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, },
7070
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, },
71-
{ 0x00, 0x18, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, },
71+
{ 0x1C, 0x63, 0x63, 0x1C, 0x00, 0x00, 0x00, 0x00, },
7272
{ 0x00, 0x3C, 0x60, 0x7C, 0x66, 0x66, 0x7C, 0x00, },
7373
{ 0x06, 0x06, 0x3E, 0x66, 0x66, 0x66, 0x3E, 0x00, },
7474
{ 0x00, 0x3C, 0x66, 0x06, 0x06, 0x06, 0x7C, 0x00, },

sw/bootloader/src/sc64.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ typedef enum {
4848
CMD_ID_FLASH_PROGRAM = 'K',
4949
CMD_ID_FLASH_WAIT_BUSY = 'p',
5050
CMD_ID_FLASH_ERASE_BLOCK = 'P',
51+
CMD_ID_DIAGNOSTIC_GET = '%',
5152
} sc64_cmd_id_t;
5253

5354
typedef enum {
@@ -436,3 +437,14 @@ sc64_error_t sc64_flash_erase_block (void *address) {
436437
};
437438
return sc64_execute_cmd(&cmd);
438439
}
440+
441+
442+
sc64_error_t sc64_get_diagnostic (sc64_diagnostic_id_t id, uint32_t *value) {
443+
sc64_cmd_t cmd = {
444+
.id = CMD_ID_DIAGNOSTIC_GET,
445+
.arg = { id }
446+
};
447+
sc64_error_t error = sc64_execute_cmd(&cmd);
448+
*value = cmd.rsp[1];
449+
return error;
450+
}

0 commit comments

Comments
 (0)