From dd9bd918628b40b090eaa3396053e4726a6d3116 Mon Sep 17 00:00:00 2001 From: Emil Lerch Date: Wed, 3 May 2023 11:27:32 -0700 Subject: [PATCH] add a prompt and command processing stub --- cdc_acm_usb_interface.c | 29 +++++++++---- main.c | 90 +++++++++++++++++++++++++++++++++-------- 2 files changed, 95 insertions(+), 24 deletions(-) diff --git a/cdc_acm_usb_interface.c b/cdc_acm_usb_interface.c index 233d15a..b775351 100644 --- a/cdc_acm_usb_interface.c +++ b/cdc_acm_usb_interface.c @@ -180,11 +180,8 @@ USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t debug_buffer[BUFFER_SIZE]; volatile bool ep_tx_busy_flag = false; volatile bool ep_dbg_tx_busy_flag = false; -// TODO: Remove these. Debugging only -volatile uint8_t debug_val_1 = 0; -volatile uint8_t debug_val_2 = 0; -volatile uint32_t debug_val32_1 = 0; -volatile uint32_t debug_val32_2 = 0; +void (*data_received_ptr)(uint32_t, uint8_t *) = NULL; +void (*dtr_changed_ptr)(bool); #ifdef CONFIG_USB_HS #define CDC_MAX_MPS 512 @@ -203,17 +200,17 @@ void usbd_configure_done_callback(void) void usbd_cdc_acm_bulk_out(uint8_t ep, uint32_t nbytes) { - debug_val_1 = ep; debug_val32_1 = nbytes; USB_LOG_RAW("actual out len:%d\r\n", nbytes); debuglog("Bytes received from host. actual out len:%d\r\n", nbytes); + if (data_received_ptr != NULL) (*data_received_ptr)(nbytes, read_buffer); + /* setup next out ep read transfer */ usbd_ep_start_read(ep, read_buffer, BUFFER_SIZE); } void usbd_cdc_acm_bulk_in(uint8_t ep, uint32_t nbytes) { - debug_val_2 = ep; debug_val32_2 = nbytes; USB_LOG_RAW("actual in len:%d\r\n", nbytes); if ((nbytes % CDC_MAX_MPS) == 0 && nbytes) { @@ -287,13 +284,17 @@ void usbd_cdc_acm_set_dtr(uint8_t intf, bool dtr) { /* Based on above init, intf = 0 is normal, intf = 2 is debug */ if (dtr) { + debuglog("Data terminal ready (DTR enabled) on intf: %d\r\n", intf); if (intf == 0) { dtr_enable = 1; + if (dtr_changed_ptr != NULL) { (*dtr_changed_ptr)(dtr); } } else { dtr_dbg_enable = 1; } } else { + debuglog("DTR disabled on intf: %d\r\n", intf); if (intf == 0) { + if (dtr_changed_ptr != NULL) { (*dtr_changed_ptr)(dtr); } dtr_enable = 0; } else { dtr_dbg_enable = 0; @@ -347,7 +348,6 @@ void nprintf(uint8_t lvl, const uint8_t ep, const char *fmt, va_list ap) { } else { buffer = &debug_buffer[0]; ep_dbg_tx_busy_flag = true; - // TODO: Add debug prefix to buffer here... } int len = prefix(ep == CDC_IN_DBG_EP, lvl, buffer); len += vsnprintf( @@ -358,6 +358,19 @@ void nprintf(uint8_t lvl, const uint8_t ep, const char *fmt, va_list ap) { ); len = suffix(ep == CDC_IN_DBG_EP, lvl, buffer, len); usbd_ep_start_write(ep, buffer, len); + if (ep == CDC_IN_EP) { + //while (ep_tx_busy_flag) {} + }else { + //while (ep_dbg_tx_busy_flag) {} + } +} + +void raw_output(size_t len, uint8_t *data) { + if (!dtr_enable) return; + + ep_tx_busy_flag = true; + usbd_ep_start_write(CDC_IN_EP, data, len); + //while (ep_dbg_tx_busy_flag) {} } void output(const char *fmt, ...) { diff --git a/main.c b/main.c index 3fd24d6..b6b50e5 100644 --- a/main.c +++ b/main.c @@ -10,27 +10,85 @@ extern void output(const char *, ...); extern void debuglog(const char *, ...); extern void debugwarn(const char *, ...); extern void debugerror(const char *, ...); +extern void (*dtr_changed_ptr)(bool); +extern void (*data_received_ptr)(uint32_t, uint8_t *); +extern void raw_output(size_t, uint8_t *); uint32_t buffer_init(char *); -USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer_main[2048]; +char *prompt = "C:\\> "; -int main(void) -{ - board_init(); +USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t cmd_buffer[1024]; +volatile bool display_prompt = false; +volatile uint32_t curr_char = 0; - uint32_t inx = 0; - cdc_acm_init(); - debuglog("Initialized"); - while (1) { - if (inx++ >= 2000){ - output("Hello world\r\n"); - debuglog("Hello to debuggers!\r\n"); - debugwarn("Warning to debuggers!\r\n"); - debugerror("Oh no - an error!\r\n"); - inx = 0; - } - bflb_mtimer_delay_ms(1); +void process_cmd(uint8_t *cmd, uint32_t cmd_len){ + int prefix_len = strlen("echo "); + if (strncmp((char *)cmd, "echo ", prefix_len) == 0){ + raw_output(cmd_len - prefix_len + 1, cmd + prefix_len); + bflb_mtimer_delay_ms(1); /* There is a microsecond delay as well */ + output("\r\n"); + return; + } +} + +void data_received(uint32_t nbytes, uint8_t *bytes) { + /* I think we're getting an SOH after our output, but not sure why exactly */ + /* This if statement is a bit fragile (e.g. it doesn't cover SOH + data) */ + /* so we may need some further processing */ + if (curr_char == 0 && nbytes == 1 && *bytes == 0x01) return; + /* if (nbytes == 1) */ + /* debuglog("Received the letter '%c'. curr_char %d\r\n", *bytes, curr_char); */ + if (curr_char + nbytes >= 1024) { + /* We will overflow - bail */ + debugerror("command too long"); + output("\r\nCOMMAND TOO LONG\r\n%s", prompt); + curr_char = 0; + return; + } + /* Process new data */ + memcpy(&cmd_buffer[curr_char], bytes, nbytes); + raw_output(nbytes, &cmd_buffer[curr_char]); /* Echo data back to console */ + if (nbytes == 1 && cmd_buffer[curr_char] == '\r') { + /* User hit enter, process command */ + output("\r\n"); + bflb_mtimer_delay_ms(1); /* There is a microsecond delay as well */ + cmd_buffer[curr_char] = '\0'; + debuglog("Processing command '%s'\r\n", &cmd_buffer[0]); + process_cmd(&cmd_buffer[0], curr_char - 1); + output("%s", prompt); + curr_char = 0; + return; + } + curr_char += nbytes; +} + +void dtr_changed(bool dtr) { + if (dtr) { + debuglog("DTR enabled: requesting prompt\r\n"); + display_prompt = true; + } +} + +int main(void) { + board_init(); + + cdc_acm_init(); + debuglog("Initialized"); + dtr_changed_ptr = &dtr_changed; + data_received_ptr = &data_received; + while (1) { + if (display_prompt) { + /* We can't display directly on the dtr_enabled interrupt, must be on the + * main loop. Without any delay, we will not see a prompt. But even 1ms + * is enough + */ + display_prompt = false; + bflb_mtimer_delay_ms(1); + output(prompt); + debuglog("displayed prompt\r\n"); + curr_char = 0; + } } }