mirror of
https://github.com/Polprzewodnikowy/SummerCart64.git
synced 2024-11-25 15:16:53 +01:00
[SC64][SW] Added USB debug feature (#8)
This commit is contained in:
parent
d1f5aac94f
commit
c02494855e
@ -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"
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user