[SC64][SW] Added USB debug feature (#8)

This commit is contained in:
Mateusz Faderewski 2021-10-23 21:55:52 +02:00 committed by GitHub
parent d1f5aac94f
commit c02494855e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 144 additions and 2 deletions

View File

@ -1,3 +1,3 @@
#!/bin/bash #!/bin/bash
docker run --mount type=bind,src="$(pwd)",target="/workdir" ghcr.io/polprzewodnikowy/sc64env:v1.0 /bin/bash -c "make clean all" docker run --mount type=bind,src="$(pwd)",target="/workdir" ghcr.io/polprzewodnikowy/sc64env:v1.0 /bin/bash -c "USER_FLAGS=\"-DDEBUG\" make clean all"

View File

@ -1,5 +1,6 @@
#include "cfg.h" #include "cfg.h"
#include "joybus.h" #include "joybus.h"
#include "usb.h"
#define SAVE_SIZE_EEPROM_4K (512) #define SAVE_SIZE_EEPROM_4K (512)
@ -199,6 +200,37 @@ void process_cfg (void) {
cfg_query(args); cfg_query(args);
break; break;
case 'S':
args[0] = usb_debug_tx_ready();
break;
case 'D':
if (!usb_debug_tx_data(args[0], (size_t) args[1])) {
change_scr_bits(CFG_SCR_CMD_ERROR, true);
}
break;
case 'A':
if (!usb_debug_rx_ready(&args[0], (size_t *) (&args[1]))) {
args[0] = 0;
args[1] = 0;
}
break;
case 'F':
args[0] = usb_debug_rx_busy();
break;
case 'E':
if (!usb_debug_rx_data(args[0], (size_t) args[1])) {
change_scr_bits(CFG_SCR_CMD_ERROR, true);
}
break;
case 'B':
usb_debug_reset();
break;
default: default:
change_scr_bits(CFG_SCR_CMD_ERROR, true); change_scr_bits(CFG_SCR_CMD_ERROR, true);
break; break;

View File

@ -67,6 +67,7 @@ enum state {
STATE_ARGS, STATE_ARGS,
STATE_DATA, STATE_DATA,
STATE_RESPONSE, STATE_RESPONSE,
STATE_DEBUG_TX,
}; };
struct process { struct process {
@ -76,22 +77,97 @@ struct process {
uint32_t args[2]; uint32_t args[2];
bool error; bool error;
bool dma_in_progress; bool dma_in_progress;
bool debug_rx_busy;
uint32_t debug_rx_address;
size_t debug_rx_length;
bool debug_tx_busy;
uint32_t debug_tx_address;
size_t debug_tx_length;
}; };
static struct process p; static struct process p;
bool usb_debug_rx_ready (uint32_t *type, size_t *length) {
if (p.state != STATE_DATA || p.cmd != 'D' || p.debug_rx_busy) {
return false;
}
*type = p.args[0];
*length = (size_t) p.args[1];
return true;
}
bool usb_debug_rx_busy (void) {
return p.debug_rx_busy;
}
bool usb_debug_rx_data (uint32_t address, size_t length) {
if (p.debug_rx_busy) {
return false;
}
p.debug_rx_busy = true;
p.debug_rx_address = address;
p.debug_rx_length = length;
return true;
}
bool usb_debug_tx_ready (void) {
return !p.debug_tx_busy;
}
bool usb_debug_tx_data (uint32_t address, size_t length) {
if (p.debug_tx_busy) {
return false;
}
p.debug_tx_busy = true;
p.debug_tx_address = address;
p.debug_tx_length = length;
return true;
}
void usb_debug_reset (void) {
uint8_t tmp;
if (p.state == STATE_DATA && p.cmd == 'D') {
for (size_t i = 0; i < p.args[1]; i++) {
rx_byte(&tmp);
}
p.args[1] = 0;
}
if (p.state == STATE_DEBUG_TX) {
p.state = STATE_IDLE;
}
p.debug_rx_busy = false;
p.debug_tx_busy = false;
USB->SCR = USB_SCR_FLUSH_TX | USB_SCR_FLUSH_RX;
}
void usb_init (void) { void usb_init (void) {
USB->SCR = USB_SCR_FLUSH_TX | USB_SCR_FLUSH_RX; USB->SCR = USB_SCR_FLUSH_TX | USB_SCR_FLUSH_RX;
p.state = STATE_IDLE; p.state = STATE_IDLE;
p.debug_rx_busy = false;
p.debug_tx_busy = false;
} }
void process_usb (void) { void process_usb (void) {
switch (p.state) { switch (p.state) {
case STATE_IDLE: case STATE_IDLE:
if (rx_word(&p.args[0])) { if (p.debug_tx_busy) {
p.state = STATE_DEBUG_TX;
p.dma_in_progress = false;
} else if (rx_word(&p.args[0])) {
if ((p.args[0] & 0xFFFFFF00) == USB_CMD_TOKEN) { if ((p.args[0] & 0xFFFFFF00) == USB_CMD_TOKEN) {
p.cmd = p.args[0] & 0xFF; p.cmd = p.args[0] & 0xFF;
p.counter = 0; p.counter = 0;
@ -142,6 +218,22 @@ void process_usb (void) {
} }
break; break;
case 'D':
if (!dma_busy() && p.debug_rx_busy && p.args[1] > 0) {
if (!p.dma_in_progress) {
dma_start(p.debug_rx_address, p.debug_rx_length, DMA_ID_USB, DMA_DIR_TO_SDRAM);
p.dma_in_progress = true;
} else {
p.args[1] -= p.debug_rx_length > p.args[1] ? p.args[1] : p.debug_rx_length;
p.dma_in_progress = false;
p.debug_rx_busy = false;
}
}
if (p.args[1] == 0) {
p.state = STATE_IDLE;
}
break;
default: default:
p.error = true; p.error = true;
p.state = STATE_RESPONSE; p.state = STATE_RESPONSE;
@ -154,5 +246,17 @@ void process_usb (void) {
p.state = STATE_IDLE; p.state = STATE_IDLE;
} }
break; break;
case STATE_DEBUG_TX:
if (!dma_busy()) {
if (!p.dma_in_progress) {
dma_start(p.debug_tx_address, p.debug_tx_length, DMA_ID_USB, DMA_DIR_FROM_SDRAM);
p.dma_in_progress = true;
} else {
p.debug_tx_busy = false;
p.state = STATE_IDLE;
}
}
break;
} }
} }

View File

@ -5,6 +5,12 @@
#include "sys.h" #include "sys.h"
bool usb_debug_rx_ready (uint32_t *type, size_t *length);
bool usb_debug_rx_busy (void);
bool usb_debug_rx_data (uint32_t address, size_t length);
bool usb_debug_tx_ready (void);
bool usb_debug_tx_data (uint32_t address, size_t length);
void usb_debug_reset (void);
void usb_init (void); void usb_init (void);
void process_usb (void); void process_usb (void);