mirror of
https://github.com/Polprzewodnikowy/SummerCart64.git
synced 2024-11-21 21:49:15 +01:00
[SC64][SW] Added USB debug feature (#8)
This commit is contained in:
parent
d1f5aac94f
commit
c02494855e
@ -1,3 +1,3 @@
|
||||
#!/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"
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "cfg.h"
|
||||
#include "joybus.h"
|
||||
#include "usb.h"
|
||||
|
||||
|
||||
#define SAVE_SIZE_EEPROM_4K (512)
|
||||
@ -199,6 +200,37 @@ void process_cfg (void) {
|
||||
cfg_query(args);
|
||||
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:
|
||||
change_scr_bits(CFG_SCR_CMD_ERROR, true);
|
||||
break;
|
||||
|
@ -67,6 +67,7 @@ enum state {
|
||||
STATE_ARGS,
|
||||
STATE_DATA,
|
||||
STATE_RESPONSE,
|
||||
STATE_DEBUG_TX,
|
||||
};
|
||||
|
||||
struct process {
|
||||
@ -76,22 +77,97 @@ struct process {
|
||||
uint32_t args[2];
|
||||
bool error;
|
||||
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;
|
||||
|
||||
|
||||
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) {
|
||||
USB->SCR = USB_SCR_FLUSH_TX | USB_SCR_FLUSH_RX;
|
||||
|
||||
p.state = STATE_IDLE;
|
||||
p.debug_rx_busy = false;
|
||||
p.debug_tx_busy = false;
|
||||
}
|
||||
|
||||
|
||||
void process_usb (void) {
|
||||
switch (p.state) {
|
||||
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) {
|
||||
p.cmd = p.args[0] & 0xFF;
|
||||
p.counter = 0;
|
||||
@ -142,6 +218,22 @@ void process_usb (void) {
|
||||
}
|
||||
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:
|
||||
p.error = true;
|
||||
p.state = STATE_RESPONSE;
|
||||
@ -154,5 +246,17 @@ void process_usb (void) {
|
||||
p.state = STATE_IDLE;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,12 @@
|
||||
#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 process_usb (void);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user