add a prompt and command processing stub
This commit is contained in:
		
							parent
							
								
									2f31d8f13c
								
							
						
					
					
						commit
						dd9bd91862
					
				
					 2 changed files with 95 additions and 24 deletions
				
			
		| 
						 | 
					@ -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_tx_busy_flag = false;
 | 
				
			||||||
volatile bool ep_dbg_tx_busy_flag = false;
 | 
					volatile bool ep_dbg_tx_busy_flag = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// TODO: Remove these. Debugging only
 | 
					void (*data_received_ptr)(uint32_t, uint8_t *) = NULL;
 | 
				
			||||||
volatile uint8_t debug_val_1 = 0;
 | 
					void (*dtr_changed_ptr)(bool);
 | 
				
			||||||
volatile uint8_t debug_val_2 = 0;
 | 
					 | 
				
			||||||
volatile uint32_t debug_val32_1 = 0;
 | 
					 | 
				
			||||||
volatile uint32_t debug_val32_2 = 0;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_USB_HS
 | 
					#ifdef CONFIG_USB_HS
 | 
				
			||||||
#define CDC_MAX_MPS 512
 | 
					#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)
 | 
					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);
 | 
					  USB_LOG_RAW("actual out len:%d\r\n", nbytes);
 | 
				
			||||||
  debuglog("Bytes received from host. 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 */
 | 
					  /* setup next out ep read transfer */
 | 
				
			||||||
  usbd_ep_start_read(ep, read_buffer, BUFFER_SIZE);
 | 
					  usbd_ep_start_read(ep, read_buffer, BUFFER_SIZE);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void usbd_cdc_acm_bulk_in(uint8_t ep, uint32_t nbytes)
 | 
					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);
 | 
					  USB_LOG_RAW("actual in len:%d\r\n", nbytes);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if ((nbytes % CDC_MAX_MPS) == 0 && 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 */
 | 
					  /* Based on above init, intf = 0 is normal, intf = 2 is debug */
 | 
				
			||||||
  if (dtr) {
 | 
					  if (dtr) {
 | 
				
			||||||
 | 
					    debuglog("Data terminal ready (DTR enabled) on intf: %d\r\n", intf);
 | 
				
			||||||
    if (intf == 0) {
 | 
					    if (intf == 0) {
 | 
				
			||||||
      dtr_enable = 1;
 | 
					      dtr_enable = 1;
 | 
				
			||||||
 | 
					      if (dtr_changed_ptr != NULL) { (*dtr_changed_ptr)(dtr); }
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      dtr_dbg_enable = 1;
 | 
					      dtr_dbg_enable = 1;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  } else {
 | 
					  } else {
 | 
				
			||||||
 | 
					    debuglog("DTR disabled on intf: %d\r\n", intf);
 | 
				
			||||||
    if (intf == 0) {
 | 
					    if (intf == 0) {
 | 
				
			||||||
 | 
					      if (dtr_changed_ptr != NULL) { (*dtr_changed_ptr)(dtr); }
 | 
				
			||||||
      dtr_enable = 0;
 | 
					      dtr_enable = 0;
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      dtr_dbg_enable = 0;
 | 
					      dtr_dbg_enable = 0;
 | 
				
			||||||
| 
						 | 
					@ -347,7 +348,6 @@ void nprintf(uint8_t lvl, const uint8_t ep,  const char *fmt, va_list ap) {
 | 
				
			||||||
  } else {
 | 
					  } else {
 | 
				
			||||||
    buffer = &debug_buffer[0];
 | 
					    buffer = &debug_buffer[0];
 | 
				
			||||||
    ep_dbg_tx_busy_flag = true;
 | 
					    ep_dbg_tx_busy_flag = true;
 | 
				
			||||||
    // TODO: Add debug prefix to buffer here...
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  int len = prefix(ep == CDC_IN_DBG_EP, lvl, buffer);
 | 
					  int len = prefix(ep == CDC_IN_DBG_EP, lvl, buffer);
 | 
				
			||||||
  len += vsnprintf(
 | 
					  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);
 | 
					  len = suffix(ep == CDC_IN_DBG_EP, lvl, buffer, len);
 | 
				
			||||||
  usbd_ep_start_write(ep, 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, ...) {
 | 
					void output(const char *fmt, ...) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										80
									
								
								main.c
									
										
									
									
									
								
							
							
						
						
									
										80
									
								
								main.c
									
										
									
									
									
								
							| 
						 | 
					@ -10,27 +10,85 @@ extern void output(const char *, ...);
 | 
				
			||||||
extern void debuglog(const char *, ...);
 | 
					extern void debuglog(const char *, ...);
 | 
				
			||||||
extern void debugwarn(const char *, ...);
 | 
					extern void debugwarn(const char *, ...);
 | 
				
			||||||
extern void debugerror(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 *);
 | 
					uint32_t buffer_init(char *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer_main[2048];
 | 
					char *prompt = "C:\\> ";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int main(void)
 | 
					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();
 | 
					  board_init();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  uint32_t inx = 0;
 | 
					 | 
				
			||||||
  cdc_acm_init();
 | 
					  cdc_acm_init();
 | 
				
			||||||
  debuglog("Initialized");
 | 
					  debuglog("Initialized");
 | 
				
			||||||
 | 
					  dtr_changed_ptr = &dtr_changed;
 | 
				
			||||||
 | 
					  data_received_ptr = &data_received;
 | 
				
			||||||
  while (1) {
 | 
					  while (1) {
 | 
				
			||||||
    if (inx++ >= 2000){
 | 
					    if (display_prompt) {
 | 
				
			||||||
      output("Hello world\r\n");
 | 
					      /* We can't display directly on the dtr_enabled interrupt, must be on the
 | 
				
			||||||
      debuglog("Hello to debuggers!\r\n");
 | 
					       * main loop. Without any delay, we will not see a prompt. But even 1ms
 | 
				
			||||||
      debugwarn("Warning to debuggers!\r\n");
 | 
					       * is enough
 | 
				
			||||||
      debugerror("Oh no - an error!\r\n");
 | 
					       */
 | 
				
			||||||
      inx = 0;
 | 
					      display_prompt = false;
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
      bflb_mtimer_delay_ms(1);
 | 
					      bflb_mtimer_delay_ms(1);
 | 
				
			||||||
 | 
					      output(prompt);
 | 
				
			||||||
 | 
					      debuglog("displayed prompt\r\n");
 | 
				
			||||||
 | 
					      curr_char = 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue