95 lines
2.7 KiB
C
95 lines
2.7 KiB
C
#include "usbh_core.h"
|
|
#include "bflb_mtimer.h"
|
|
#include "board.h"
|
|
|
|
#include "usbd_core.h"
|
|
#include "usbd_cdc.h"
|
|
|
|
extern void cdc_acm_init(void);
|
|
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 *);
|
|
|
|
char *prompt = "C:\\> ";
|
|
|
|
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t cmd_buffer[1024];
|
|
volatile bool display_prompt = false;
|
|
volatile uint32_t curr_char = 0;
|
|
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
|