mirror of
https://github.com/openmv/openmv.git
synced 2025-11-04 14:49:50 +08:00
misc/usbdbg: Add CDC read/write callbacks.
These callbacks allow the debug code to read/write directly from the stack, if possible, to avoid the extra memcpy.
This commit is contained in:
parent
6b1308fcc5
commit
f306d07b03
@ -20,12 +20,13 @@
|
|||||||
#include "tusb.h"
|
#include "tusb.h"
|
||||||
#include "usbdbg.h"
|
#include "usbdbg.h"
|
||||||
#include "tinyusb_debug.h"
|
#include "tinyusb_debug.h"
|
||||||
|
#include "omv_common.h"
|
||||||
|
|
||||||
#define DEBUG_MAX_PACKET (OMV_TUSBDBG_PACKET)
|
#define DEBUG_BAUDRATE_SLOW (921600)
|
||||||
#define DEBUG_BAUDRATE_SLOW (921600)
|
#define DEBUG_BAUDRATE_FAST (12000000)
|
||||||
#define DEBUG_BAUDRATE_FAST (12000000)
|
#define DEBUG_EP_SIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
|
||||||
|
|
||||||
extern void __fatal_error();
|
void NORETURN __fatal_error(const char *msg);
|
||||||
|
|
||||||
typedef struct __attribute__((packed)) {
|
typedef struct __attribute__((packed)) {
|
||||||
uint8_t cmd;
|
uint8_t cmd;
|
||||||
@ -34,23 +35,23 @@ typedef struct __attribute__((packed)) {
|
|||||||
}
|
}
|
||||||
usbdbg_cmd_t;
|
usbdbg_cmd_t;
|
||||||
|
|
||||||
static uint8_t debug_ringbuf_array[OMV_TUSBDBG_BUFFER];
|
static uint8_t tx_array[OMV_TUSBDBG_BUFFER];
|
||||||
|
static ringbuf_t tx_ringbuf = { tx_array, sizeof(tx_array) };
|
||||||
static volatile bool tinyusb_debug_mode = false;
|
static volatile bool tinyusb_debug_mode = false;
|
||||||
ringbuf_t debug_ringbuf = { debug_ringbuf_array, sizeof(debug_ringbuf_array) };
|
|
||||||
|
|
||||||
uint32_t usb_cdc_buf_len() {
|
uint32_t usb_cdc_buf_len() {
|
||||||
return ringbuf_avail(&debug_ringbuf);
|
return ringbuf_avail(&tx_ringbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t usb_cdc_get_buf(uint8_t *buf, uint32_t len) {
|
uint32_t usb_cdc_get_buf(uint8_t *buf, uint32_t len) {
|
||||||
// Read all of the request bytes.
|
// Read all of the request bytes.
|
||||||
if (ringbuf_get_bytes(&debug_ringbuf, buf, len) == 0) {
|
if (ringbuf_get_bytes(&tx_ringbuf, buf, len) == 0) {
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
// Try to read as much data as possible.
|
// Try to read as much data as possible.
|
||||||
uint32_t bytes = 0;
|
uint32_t bytes = 0;
|
||||||
for (; bytes < len; bytes++) {
|
for (; bytes < len; bytes++) {
|
||||||
int c = ringbuf_get(&debug_ringbuf);
|
int c = ringbuf_get(&tx_ringbuf);
|
||||||
if (c == -1) {
|
if (c == -1) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -59,9 +60,13 @@ uint32_t usb_cdc_get_buf(uint8_t *buf, uint32_t len) {
|
|||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void usb_cdc_reset_buffers() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void tud_cdc_line_coding_cb(uint8_t itf, cdc_line_coding_t const *coding) {
|
void tud_cdc_line_coding_cb(uint8_t itf, cdc_line_coding_t const *coding) {
|
||||||
debug_ringbuf.iget = 0;
|
tx_ringbuf.iget = 0;
|
||||||
debug_ringbuf.iput = 0;
|
tx_ringbuf.iput = 0;
|
||||||
|
|
||||||
if (0) {
|
if (0) {
|
||||||
#if defined(MICROPY_BOARD_ENTER_BOOTLOADER)
|
#if defined(MICROPY_BOARD_ENTER_BOOTLOADER)
|
||||||
@ -112,9 +117,9 @@ mp_uint_t __wrap_mp_hal_stdout_tx_strn(const char *str, mp_uint_t len) {
|
|||||||
// rate and fast print rate. When this happens, reset the buffer and start
|
// rate and fast print rate. When this happens, reset the buffer and start
|
||||||
// over, if this string fits entirely in the buffer. This helps the ring buffer
|
// over, if this string fits entirely in the buffer. This helps the ring buffer
|
||||||
// self-recover from broken strings.
|
// self-recover from broken strings.
|
||||||
if (ringbuf_put(&debug_ringbuf, str[i]) == -1 && len <= debug_ringbuf.size) {
|
if (ringbuf_put(&tx_ringbuf, str[i]) == -1 && len <= tx_ringbuf.size) {
|
||||||
debug_ringbuf.iget = 0;
|
tx_ringbuf.iget = 0;
|
||||||
debug_ringbuf.iput = 0;
|
tx_ringbuf.iput = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NVIC_EnableIRQ(PendSV_IRQn);
|
NVIC_EnableIRQ(PendSV_IRQn);
|
||||||
@ -132,20 +137,16 @@ static void tinyusb_debug_task(void) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t dbg_buf[DEBUG_MAX_PACKET];
|
usbdbg_cmd_t cmd;
|
||||||
uint32_t count = tud_cdc_read(dbg_buf, 6);
|
tud_cdc_read(&cmd, sizeof(cmd));
|
||||||
|
|
||||||
if (count < 6 || dbg_buf[0] != 0x30) {
|
if (cmd.cmd != 0x30) {
|
||||||
// Maybe we should try to recover from this state
|
// TODO: Try to recover from this state but for now, call __fatal_error.
|
||||||
// but for now, call __fatal_error which doesn't
|
__fatal_error("Invalid USB CMD received.");
|
||||||
// return.
|
|
||||||
__fatal_error();
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
usbdbg_cmd_t *cmd = (usbdbg_cmd_t *) dbg_buf;
|
uint8_t request = cmd.request;
|
||||||
uint8_t request = cmd->request;
|
uint32_t xfer_length = cmd.xfer_length;
|
||||||
uint32_t xfer_length = cmd->xfer_length;
|
|
||||||
usbdbg_control(NULL, request, xfer_length);
|
usbdbg_control(NULL, request, xfer_length);
|
||||||
|
|
||||||
while (xfer_length) {
|
while (xfer_length) {
|
||||||
@ -155,19 +156,21 @@ static void tinyusb_debug_task(void) {
|
|||||||
}
|
}
|
||||||
if (request & 0x80) {
|
if (request & 0x80) {
|
||||||
// Device-to-host data phase
|
// Device-to-host data phase
|
||||||
int bytes = MIN(xfer_length, DEBUG_MAX_PACKET);
|
int size = OMV_MIN(xfer_length, tud_cdc_write_available());
|
||||||
if (bytes <= tud_cdc_write_available()) {
|
if (size) {
|
||||||
xfer_length -= bytes;
|
xfer_length -= size;
|
||||||
usbdbg_data_in(dbg_buf, bytes);
|
usbdbg_data_in(size, tud_cdc_write);
|
||||||
tud_cdc_write(dbg_buf, bytes);
|
}
|
||||||
|
if (size > 0 && size < DEBUG_EP_SIZE) {
|
||||||
|
tud_cdc_write_flush();
|
||||||
}
|
}
|
||||||
tud_cdc_write_flush();
|
|
||||||
} else {
|
} else {
|
||||||
// Host-to-device data phase
|
// Host-to-device data phase
|
||||||
int bytes = MIN(xfer_length, DEBUG_MAX_PACKET);
|
int size = OMV_MIN(xfer_length, tud_cdc_available());
|
||||||
uint32_t count = tud_cdc_read(dbg_buf, bytes);
|
if (size) {
|
||||||
xfer_length -= count;
|
xfer_length -= size;
|
||||||
usbdbg_data_out(dbg_buf, count);
|
usbdbg_data_out(size, tud_cdc_read);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -27,8 +27,8 @@
|
|||||||
#include "omv_boardconfig.h"
|
#include "omv_boardconfig.h"
|
||||||
#include "py_image.h"
|
#include "py_image.h"
|
||||||
|
|
||||||
static int xfer_bytes;
|
static int xfer_offs;
|
||||||
static int xfer_length;
|
static int xfer_size;
|
||||||
static enum usbdbg_cmd cmd;
|
static enum usbdbg_cmd cmd;
|
||||||
|
|
||||||
static volatile bool script_ready;
|
static volatile bool script_ready;
|
||||||
@ -36,13 +36,11 @@ static volatile bool script_running;
|
|||||||
static volatile bool irq_enabled;
|
static volatile bool irq_enabled;
|
||||||
static vstr_t script_buf;
|
static vstr_t script_buf;
|
||||||
|
|
||||||
// These functions must be implemented in MicroPython CDC driver.
|
// These functions must be implemented by the stack.
|
||||||
extern uint32_t usb_cdc_buf_len();
|
extern uint32_t usb_cdc_buf_len();
|
||||||
extern uint32_t usb_cdc_get_buf(uint8_t *buf, uint32_t len);
|
extern uint32_t usb_cdc_get_buf(uint8_t *buf, uint32_t len);
|
||||||
|
extern void usb_cdc_reset_buffers();
|
||||||
|
|
||||||
void __attribute__((weak)) usb_cdc_reset_buffers() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void usbdbg_init() {
|
void usbdbg_init() {
|
||||||
cmd = USBDBG_NONE;
|
cmd = USBDBG_NONE;
|
||||||
@ -100,47 +98,54 @@ bool usbdbg_get_irq_enabled() {
|
|||||||
return irq_enabled;
|
return irq_enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
void usbdbg_data_in(void *buffer, int length) {
|
void usbdbg_data_in(uint32_t size, usbdbg_write_callback_t write_callback) {
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case USBDBG_FW_VERSION: {
|
case USBDBG_FW_VERSION: {
|
||||||
uint32_t *ver_buf = buffer;
|
uint32_t buffer[3] = {
|
||||||
ver_buf[0] = FIRMWARE_VERSION_MAJOR;
|
FIRMWARE_VERSION_MAJOR,
|
||||||
ver_buf[1] = FIRMWARE_VERSION_MINOR;
|
FIRMWARE_VERSION_MINOR,
|
||||||
ver_buf[2] = FIRMWARE_VERSION_PATCH;
|
FIRMWARE_VERSION_PATCH,
|
||||||
|
};
|
||||||
cmd = USBDBG_NONE;
|
cmd = USBDBG_NONE;
|
||||||
|
write_callback(&buffer, sizeof(buffer));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case USBDBG_TX_BUF_LEN: {
|
case USBDBG_TX_BUF_LEN: {
|
||||||
uint32_t tx_buf_len = usb_cdc_buf_len();
|
uint32_t tx_buf_len = usb_cdc_buf_len();
|
||||||
memcpy(buffer, &tx_buf_len, sizeof(tx_buf_len));
|
|
||||||
cmd = USBDBG_NONE;
|
cmd = USBDBG_NONE;
|
||||||
|
write_callback(&tx_buf_len, sizeof(tx_buf_len));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case USBDBG_SENSOR_ID: {
|
case USBDBG_SENSOR_ID: {
|
||||||
int sensor_id = 0xFF;
|
uint32_t buffer = 0xFF;
|
||||||
#if MICROPY_PY_SENSOR
|
#if MICROPY_PY_SENSOR
|
||||||
if (sensor_is_detected() == true) {
|
if (sensor_is_detected() == true) {
|
||||||
sensor_id = sensor_get_id();
|
buffer = sensor_get_id();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
memcpy(buffer, &sensor_id, 4);
|
|
||||||
cmd = USBDBG_NONE;
|
cmd = USBDBG_NONE;
|
||||||
|
write_callback(&buffer, sizeof(buffer));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case USBDBG_TX_BUF: {
|
case USBDBG_TX_BUF: {
|
||||||
xfer_bytes += usb_cdc_get_buf(buffer, length);
|
uint8_t buffer[size];
|
||||||
if (xfer_bytes == xfer_length) {
|
size = usb_cdc_get_buf(buffer, size);
|
||||||
|
xfer_offs += size;
|
||||||
|
if (xfer_offs == xfer_size) {
|
||||||
cmd = USBDBG_NONE;
|
cmd = USBDBG_NONE;
|
||||||
}
|
}
|
||||||
|
if (size) {
|
||||||
|
write_callback(buffer, size);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case USBDBG_FRAME_SIZE:
|
case USBDBG_FRAME_SIZE: {
|
||||||
// Return 0 if FB is locked or not ready.
|
// Return 0 if FB is locked or not ready.
|
||||||
((uint32_t *) buffer)[0] = 0;
|
uint32_t buffer[3] = { 0 };
|
||||||
// Try to lock FB. If header size == 0 frame is not ready
|
// Try to lock FB. If header size == 0 frame is not ready
|
||||||
if (mutex_try_lock_alternate(&JPEG_FB()->lock, MUTEX_TID_IDE)) {
|
if (mutex_try_lock_alternate(&JPEG_FB()->lock, MUTEX_TID_IDE)) {
|
||||||
// If header size == 0 frame is not ready
|
// If header size == 0 frame is not ready
|
||||||
@ -149,19 +154,21 @@ void usbdbg_data_in(void *buffer, int length) {
|
|||||||
mutex_unlock(&JPEG_FB()->lock, MUTEX_TID_IDE);
|
mutex_unlock(&JPEG_FB()->lock, MUTEX_TID_IDE);
|
||||||
} else {
|
} else {
|
||||||
// Return header w, h and size/bpp
|
// Return header w, h and size/bpp
|
||||||
((uint32_t *) buffer)[0] = JPEG_FB()->w;
|
buffer[0] = JPEG_FB()->w;
|
||||||
((uint32_t *) buffer)[1] = JPEG_FB()->h;
|
buffer[1] = JPEG_FB()->h;
|
||||||
((uint32_t *) buffer)[2] = JPEG_FB()->size;
|
buffer[2] = JPEG_FB()->size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cmd = USBDBG_NONE;
|
cmd = USBDBG_NONE;
|
||||||
|
write_callback(&buffer, sizeof(buffer));
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case USBDBG_FRAME_DUMP:
|
case USBDBG_FRAME_DUMP:
|
||||||
if (xfer_bytes < xfer_length) {
|
if (xfer_offs < xfer_size) {
|
||||||
memcpy(buffer, JPEG_FB()->pixels + xfer_bytes, length);
|
write_callback(JPEG_FB()->pixels + xfer_offs, size);
|
||||||
xfer_bytes += length;
|
xfer_offs += size;
|
||||||
if (xfer_bytes == xfer_length) {
|
if (xfer_offs == xfer_size) {
|
||||||
cmd = USBDBG_NONE;
|
cmd = USBDBG_NONE;
|
||||||
JPEG_FB()->w = 0; JPEG_FB()->h = 0; JPEG_FB()->size = 0;
|
JPEG_FB()->w = 0; JPEG_FB()->h = 0; JPEG_FB()->size = 0;
|
||||||
mutex_unlock(&JPEG_FB()->lock, MUTEX_TID_IDE);
|
mutex_unlock(&JPEG_FB()->lock, MUTEX_TID_IDE);
|
||||||
@ -170,6 +177,7 @@ void usbdbg_data_in(void *buffer, int length) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case USBDBG_ARCH_STR: {
|
case USBDBG_ARCH_STR: {
|
||||||
|
uint8_t buffer[64];
|
||||||
unsigned int uid[3] = {
|
unsigned int uid[3] = {
|
||||||
#if (OMV_BOARD_UID_SIZE == 2)
|
#if (OMV_BOARD_UID_SIZE == 2)
|
||||||
0U,
|
0U,
|
||||||
@ -182,29 +190,29 @@ void usbdbg_data_in(void *buffer, int length) {
|
|||||||
snprintf((char *) buffer, 64, "%s [%s:%08X%08X%08X]",
|
snprintf((char *) buffer, 64, "%s [%s:%08X%08X%08X]",
|
||||||
OMV_BOARD_ARCH, OMV_BOARD_TYPE, uid[0], uid[1], uid[2]);
|
OMV_BOARD_ARCH, OMV_BOARD_TYPE, uid[0], uid[1], uid[2]);
|
||||||
cmd = USBDBG_NONE;
|
cmd = USBDBG_NONE;
|
||||||
|
write_callback(&buffer, sizeof(buffer));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case USBDBG_SCRIPT_RUNNING: {
|
case USBDBG_SCRIPT_RUNNING: {
|
||||||
uint32_t *buf = buffer;
|
|
||||||
buf[0] = (uint32_t) script_running;
|
|
||||||
cmd = USBDBG_NONE;
|
cmd = USBDBG_NONE;
|
||||||
|
uint32_t buffer = script_running;
|
||||||
|
write_callback(&buffer, sizeof(buffer));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case USBDBG_GET_STATE:
|
case USBDBG_GET_STATE: {
|
||||||
// Clear flags
|
uint32_t buffer[16] = { 0 };
|
||||||
((uint32_t *) buffer)[0] = 0;
|
|
||||||
|
|
||||||
// Set script running flag
|
// Set script running flag
|
||||||
if (script_running) {
|
if (script_running) {
|
||||||
((uint32_t *) buffer)[0] |= USBDBG_STATE_FLAGS_SCRIPT;
|
buffer[0] |= USBDBG_STATE_FLAGS_SCRIPT;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set text buf valid flag.
|
// Set text buf valid flag.
|
||||||
uint32_t tx_buf_len = usb_cdc_buf_len();
|
uint32_t tx_buf_len = usb_cdc_buf_len();
|
||||||
if (tx_buf_len) {
|
if (tx_buf_len) {
|
||||||
((uint32_t *) buffer)[0] |= USBDBG_STATE_FLAGS_TEXT;
|
buffer[0] |= USBDBG_STATE_FLAGS_TEXT;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to lock FB. If header size == 0 frame is not ready
|
// Try to lock FB. If header size == 0 frame is not ready
|
||||||
@ -214,13 +222,13 @@ void usbdbg_data_in(void *buffer, int length) {
|
|||||||
// unlock FB
|
// unlock FB
|
||||||
mutex_unlock(&JPEG_FB()->lock, MUTEX_TID_IDE);
|
mutex_unlock(&JPEG_FB()->lock, MUTEX_TID_IDE);
|
||||||
} else {
|
} else {
|
||||||
// Set frame width, height and size/bpp
|
|
||||||
((uint32_t *) buffer)[1] = JPEG_FB()->w;
|
|
||||||
((uint32_t *) buffer)[2] = JPEG_FB()->h;
|
|
||||||
((uint32_t *) buffer)[3] = JPEG_FB()->size;
|
|
||||||
|
|
||||||
// Set valid frame flag.
|
// Set valid frame flag.
|
||||||
((uint32_t *) buffer)[0] |= USBDBG_STATE_FLAGS_FRAME;
|
buffer[0] |= USBDBG_STATE_FLAGS_FRAME;
|
||||||
|
|
||||||
|
// Set frame width, height and size/bpp
|
||||||
|
buffer[1] = JPEG_FB()->w;
|
||||||
|
buffer[2] = JPEG_FB()->h;
|
||||||
|
buffer[3] = JPEG_FB()->size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -233,19 +241,20 @@ void usbdbg_data_in(void *buffer, int length) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cmd = USBDBG_NONE;
|
cmd = USBDBG_NONE;
|
||||||
|
write_callback(&buffer, sizeof(buffer));
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default: /* error */
|
default: /* error */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void usbdbg_data_out(void *buffer, int length) {
|
void usbdbg_data_out(uint32_t size, usbdbg_read_callback_t read_callback) {
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case USBDBG_FB_ENABLE: {
|
case USBDBG_FB_ENABLE: {
|
||||||
uint32_t enable = *((int32_t *) buffer);
|
read_callback(&(JPEG_FB()->enabled), 4);
|
||||||
JPEG_FB()->enabled = enable;
|
if (JPEG_FB()->enabled == 0) {
|
||||||
if (enable == 0) {
|
|
||||||
// When disabling framebuffer, the IDE might still be holding FB lock.
|
// When disabling framebuffer, the IDE might still be holding FB lock.
|
||||||
// If the IDE is not the current lock owner, this operation is ignored.
|
// If the IDE is not the current lock owner, this operation is ignored.
|
||||||
mutex_unlock(&JPEG_FB()->lock, MUTEX_TID_IDE);
|
mutex_unlock(&JPEG_FB()->lock, MUTEX_TID_IDE);
|
||||||
@ -256,16 +265,17 @@ void usbdbg_data_out(void *buffer, int length) {
|
|||||||
|
|
||||||
case USBDBG_SCRIPT_EXEC:
|
case USBDBG_SCRIPT_EXEC:
|
||||||
// check if GC is locked before allocating memory for vstr. If GC was locked
|
// check if GC is locked before allocating memory for vstr. If GC was locked
|
||||||
// at least once before the script is fully uploaded xfer_bytes will be less
|
// at least once before the script is fully uploaded xfer_offs will be less
|
||||||
// than the total length (xfer_length) and the script will Not be executed.
|
// than the total size (xfer_size) and the script will Not be executed.
|
||||||
if (!script_running) {
|
if (!script_running) {
|
||||||
nlr_buf_t nlr;
|
nlr_buf_t nlr;
|
||||||
if (!gc_is_locked() && nlr_push(&nlr) == 0) {
|
if (!gc_is_locked() && nlr_push(&nlr) == 0) {
|
||||||
vstr_add_strn(&script_buf, buffer, length);
|
char *buffer = vstr_add_len(&script_buf, size);
|
||||||
|
read_callback(buffer, size);
|
||||||
nlr_pop();
|
nlr_pop();
|
||||||
}
|
}
|
||||||
xfer_bytes += length;
|
xfer_offs += size;
|
||||||
if (xfer_bytes == xfer_length) {
|
if (xfer_offs == xfer_size) {
|
||||||
cmd = USBDBG_NONE;
|
cmd = USBDBG_NONE;
|
||||||
// Schedule the IDE exception to interrupt the VM.
|
// Schedule the IDE exception to interrupt the VM.
|
||||||
usbdbg_interrupt_vm(true);
|
usbdbg_interrupt_vm(true);
|
||||||
@ -278,17 +288,15 @@ void usbdbg_data_out(void *buffer, int length) {
|
|||||||
image_t image;
|
image_t image;
|
||||||
framebuffer_init_image(&image);
|
framebuffer_init_image(&image);
|
||||||
|
|
||||||
// null terminate the path
|
size = MIN(128, size);
|
||||||
length = (length == 64) ? 63:length;
|
char buffer[size];
|
||||||
((char *) buffer)[length] = 0;
|
read_callback(buffer, size);
|
||||||
|
buffer[size - 1] = 0;
|
||||||
|
|
||||||
rectangle_t *roi = (rectangle_t *) buffer;
|
rectangle_t *roi = (rectangle_t *) buffer;
|
||||||
char *path = (char *) buffer + sizeof(rectangle_t);
|
char *path = (char *) buffer + sizeof(rectangle_t);
|
||||||
|
|
||||||
imlib_save_image(&image, path, roi, 50);
|
imlib_save_image(&image, path, roi, 50);
|
||||||
|
|
||||||
// raise a flash IRQ to flush image
|
|
||||||
//NVIC->STIR = FLASH_IRQn;
|
|
||||||
#endif //IMLIB_ENABLE_IMAGE_FILE_IO
|
#endif //IMLIB_ENABLE_IMAGE_FILE_IO
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -299,9 +307,10 @@ void usbdbg_data_out(void *buffer, int length) {
|
|||||||
image_t image;
|
image_t image;
|
||||||
framebuffer_init_image(&image);
|
framebuffer_init_image(&image);
|
||||||
|
|
||||||
// null terminate the path
|
size = MIN(128, size);
|
||||||
length = (length == 64) ? 63:length;
|
char buffer[size];
|
||||||
((char *) buffer)[length] = 0;
|
read_callback(buffer, size);
|
||||||
|
buffer[size - 1] = 0;
|
||||||
|
|
||||||
rectangle_t *roi = (rectangle_t *) buffer;
|
rectangle_t *roi = (rectangle_t *) buffer;
|
||||||
char *path = (char *) buffer + sizeof(rectangle_t);
|
char *path = (char *) buffer + sizeof(rectangle_t);
|
||||||
@ -314,21 +323,24 @@ void usbdbg_data_out(void *buffer, int length) {
|
|||||||
|
|
||||||
case USBDBG_ATTR_WRITE: {
|
case USBDBG_ATTR_WRITE: {
|
||||||
#if MICROPY_PY_SENSOR
|
#if MICROPY_PY_SENSOR
|
||||||
/* write sensor attribute */
|
struct {
|
||||||
int32_t attr = *((int32_t *) buffer);
|
int32_t name;
|
||||||
int32_t val = *((int32_t *) buffer + 1);
|
int32_t value;
|
||||||
switch (attr) {
|
}
|
||||||
|
attr;
|
||||||
|
read_callback(&attr, sizeof(attr));
|
||||||
|
switch (attr.name) {
|
||||||
case ATTR_CONTRAST:
|
case ATTR_CONTRAST:
|
||||||
sensor_set_contrast(val);
|
sensor_set_contrast(attr.value);
|
||||||
break;
|
break;
|
||||||
case ATTR_BRIGHTNESS:
|
case ATTR_BRIGHTNESS:
|
||||||
sensor_set_brightness(val);
|
sensor_set_brightness(attr.value);
|
||||||
break;
|
break;
|
||||||
case ATTR_SATURATION:
|
case ATTR_SATURATION:
|
||||||
sensor_set_saturation(val);
|
sensor_set_saturation(attr.value);
|
||||||
break;
|
break;
|
||||||
case ATTR_GAINCEILING:
|
case ATTR_GAINCEILING:
|
||||||
sensor_set_gainceiling(val);
|
sensor_set_gainceiling(attr.value);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -340,61 +352,48 @@ void usbdbg_data_out(void *buffer, int length) {
|
|||||||
|
|
||||||
case USBDBG_SET_TIME: {
|
case USBDBG_SET_TIME: {
|
||||||
// TODO implement
|
// TODO implement
|
||||||
#if 0
|
uint8_t buffer[32];
|
||||||
uint32_t *timebuf = (uint32_t *) buffer;
|
read_callback(&buffer, sizeof(buffer));
|
||||||
timebuf[0]; // Year
|
|
||||||
timebuf[1]; // Month
|
|
||||||
timebuf[2]; // Day
|
|
||||||
timebuf[3]; // Day of the week
|
|
||||||
timebuf[4]; // Hour
|
|
||||||
timebuf[5]; // Minute
|
|
||||||
timebuf[6]; // Second
|
|
||||||
timebuf[7]; // Milliseconds
|
|
||||||
#endif
|
|
||||||
cmd = USBDBG_NONE;
|
cmd = USBDBG_NONE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case USBDBG_TX_INPUT: {
|
case USBDBG_TX_INPUT: {
|
||||||
// TODO implement
|
// TODO implement
|
||||||
#if 0
|
|
||||||
uint32_t key = *((uint32_t *) buffer);
|
|
||||||
#endif
|
|
||||||
cmd = USBDBG_NONE;
|
cmd = USBDBG_NONE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default: /* error */
|
default: /* error */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void usbdbg_control(void *buffer, uint8_t request, uint32_t length) {
|
void usbdbg_control(void *buffer, uint8_t request, uint32_t size) {
|
||||||
cmd = (enum usbdbg_cmd) request;
|
cmd = (enum usbdbg_cmd) request;
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case USBDBG_FW_VERSION:
|
case USBDBG_FW_VERSION:
|
||||||
xfer_bytes = 0;
|
xfer_offs = 0;
|
||||||
xfer_length = length;
|
xfer_size = size;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case USBDBG_FRAME_SIZE:
|
case USBDBG_FRAME_SIZE:
|
||||||
xfer_bytes = 0;
|
xfer_offs = 0;
|
||||||
xfer_length = length;
|
xfer_size = size;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case USBDBG_FRAME_DUMP:
|
case USBDBG_FRAME_DUMP:
|
||||||
xfer_bytes = 0;
|
xfer_offs = 0;
|
||||||
xfer_length = length;
|
xfer_size = size;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case USBDBG_ARCH_STR:
|
case USBDBG_ARCH_STR:
|
||||||
xfer_bytes = 0;
|
xfer_offs = 0;
|
||||||
xfer_length = length;
|
xfer_size = size;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case USBDBG_SCRIPT_EXEC:
|
case USBDBG_SCRIPT_EXEC:
|
||||||
xfer_bytes = 0;
|
xfer_offs = 0;
|
||||||
xfer_length = length;
|
xfer_size = size;
|
||||||
vstr_reset(&script_buf);
|
vstr_reset(&script_buf);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -415,20 +414,20 @@ void usbdbg_control(void *buffer, uint8_t request, uint32_t length) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case USBDBG_SCRIPT_RUNNING:
|
case USBDBG_SCRIPT_RUNNING:
|
||||||
xfer_bytes = 0;
|
xfer_offs = 0;
|
||||||
xfer_length = length;
|
xfer_size = size;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case USBDBG_TEMPLATE_SAVE:
|
case USBDBG_TEMPLATE_SAVE:
|
||||||
case USBDBG_DESCRIPTOR_SAVE:
|
case USBDBG_DESCRIPTOR_SAVE:
|
||||||
/* save template */
|
/* save template */
|
||||||
xfer_bytes = 0;
|
xfer_offs = 0;
|
||||||
xfer_length = length;
|
xfer_size = size;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case USBDBG_ATTR_WRITE:
|
case USBDBG_ATTR_WRITE:
|
||||||
xfer_bytes = 0;
|
xfer_offs = 0;
|
||||||
xfer_length = length;
|
xfer_size = size;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case USBDBG_SYS_RESET:
|
case USBDBG_SYS_RESET:
|
||||||
@ -449,35 +448,35 @@ void usbdbg_control(void *buffer, uint8_t request, uint32_t length) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case USBDBG_FB_ENABLE: {
|
case USBDBG_FB_ENABLE: {
|
||||||
xfer_bytes = 0;
|
xfer_offs = 0;
|
||||||
xfer_length = length;
|
xfer_size = size;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case USBDBG_TX_BUF:
|
case USBDBG_TX_BUF:
|
||||||
case USBDBG_TX_BUF_LEN:
|
case USBDBG_TX_BUF_LEN:
|
||||||
xfer_bytes = 0;
|
xfer_offs = 0;
|
||||||
xfer_length = length;
|
xfer_size = size;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case USBDBG_SENSOR_ID:
|
case USBDBG_SENSOR_ID:
|
||||||
xfer_bytes = 0;
|
xfer_offs = 0;
|
||||||
xfer_length = length;
|
xfer_size = size;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case USBDBG_SET_TIME:
|
case USBDBG_SET_TIME:
|
||||||
xfer_bytes = 0;
|
xfer_offs = 0;
|
||||||
xfer_length = length;
|
xfer_size = size;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case USBDBG_TX_INPUT:
|
case USBDBG_TX_INPUT:
|
||||||
xfer_bytes = 0;
|
xfer_offs = 0;
|
||||||
xfer_length = length;
|
xfer_size = size;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case USBDBG_GET_STATE:
|
case USBDBG_GET_STATE:
|
||||||
xfer_bytes = 0;
|
xfer_offs = 0;
|
||||||
xfer_length = length;
|
xfer_size = size;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: /* error */
|
default: /* error */
|
||||||
|
|||||||
@ -58,6 +58,9 @@ enum usbdbg_state_flags {
|
|||||||
USBDBG_STATE_FLAGS_FRAME = (1 << 2),
|
USBDBG_STATE_FLAGS_FRAME = (1 << 2),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef uint32_t (*usbdbg_read_callback_t) (void *buf, uint32_t len);
|
||||||
|
typedef uint32_t (*usbdbg_write_callback_t) (const void *buf, uint32_t len);
|
||||||
|
|
||||||
void usbdbg_init();
|
void usbdbg_init();
|
||||||
void usbdbg_wait_for_command(uint32_t timeout);
|
void usbdbg_wait_for_command(uint32_t timeout);
|
||||||
bool usbdbg_script_ready();
|
bool usbdbg_script_ready();
|
||||||
@ -66,8 +69,8 @@ bool usbdbg_is_busy();
|
|||||||
bool usbdbg_get_irq_enabled();
|
bool usbdbg_get_irq_enabled();
|
||||||
void usbdbg_set_irq_enabled(bool enabled);
|
void usbdbg_set_irq_enabled(bool enabled);
|
||||||
void usbdbg_set_script_running(bool running);
|
void usbdbg_set_script_running(bool running);
|
||||||
void usbdbg_data_in(void *buffer, int length);
|
void usbdbg_data_in(uint32_t size, usbdbg_write_callback_t write_callback);
|
||||||
void usbdbg_data_out(void *buffer, int length);
|
void usbdbg_data_out(uint32_t size, usbdbg_read_callback_t read_callback);
|
||||||
void usbdbg_control(void *buffer, uint8_t brequest, uint32_t wlength);
|
void usbdbg_control(void *buffer, uint8_t brequest, uint32_t wlength);
|
||||||
|
|
||||||
#endif /* __USBDBG_H__ */
|
#endif /* __USBDBG_H__ */
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user