void gdb_if_putchar(unsigned char c, int flush) { buffer_in[count_in++] = c; if(flush || (count_in == CDCACM_PACKET_SIZE)) { /* Refuse to send if USB isn't configured, and * don't bother if nobody's listening */ if((cdcacm_get_config() != 1) || !cdcacm_get_dtr()) { count_in = 0; return; } while(usbd_ep_write_packet(usbdev, CDCACM_GDB_ENDPOINT, buffer_in, count_in) <= 0); if (flush && (count_in == CDCACM_PACKET_SIZE)) { /* We need to send an empty packet for some hosts * to accept this as a complete transfer. */ /* libopencm3 needs a change for us to confirm when * that transfer is complete, so we just send a packet * containing a null byte for now. */ while (usbd_ep_write_packet(usbdev, CDCACM_GDB_ENDPOINT, "\0", 1) <= 0); } count_in = 0; } }
/* * Read a character from the UART RX and stuff it in a software FIFO. * Allowed to read from FIFO out pointer, but not write to it. * Allowed to write to FIFO in pointer. */ void USBUART_ISR(void) { int flush = uart_is_interrupt_source(USBUART, UART_INT_RT); while (!uart_is_rx_fifo_empty(USBUART)) { char c = uart_recv(USBUART); /* If the next increment of rx_in would put it at the same point * as rx_out, the FIFO is considered full. */ if (((buf_rx_in + 1) % FIFO_SIZE) != buf_rx_out) { /* insert into FIFO */ buf_rx[buf_rx_in++] = c; /* wrap out pointer */ if (buf_rx_in >= FIFO_SIZE) { buf_rx_in = 0; } } else { flush = 1; } } if (flush) { /* forcibly empty fifo if no USB endpoint */ if (cdcacm_get_config() != 1) { buf_rx_out = buf_rx_in; return; } uint8_t packet_buf[CDCACM_PACKET_SIZE]; uint8_t packet_size = 0; uint8_t buf_out = buf_rx_out; /* copy from uart FIFO into local usb packet buffer */ while (buf_rx_in != buf_out && packet_size < CDCACM_PACKET_SIZE) { packet_buf[packet_size++] = buf_rx[buf_out++]; /* wrap out pointer */ if (buf_out >= FIFO_SIZE) { buf_out = 0; } } /* advance fifo out pointer by amount written */ buf_rx_out += usbd_ep_write_packet(usbdev, CDCACM_UART_ENDPOINT, packet_buf, packet_size); buf_rx_out %= FIFO_SIZE; } }
unsigned char gdb_if_getchar(void) { while(tail_out == head_out) { /* Detach if port closed */ if(!cdcacm_get_dtr()) return 0x04; while(cdcacm_get_config() != 1); } return buffer_out[tail_out++ % sizeof(buffer_out)]; }
void cdcacm_init(void) { //system setup rcc_peripheral_enable_clock(&RCC_AHB1ENR, RCC_AHB1ENR_IOPAEN); rcc_peripheral_enable_clock(&RCC_AHB2ENR, RCC_AHB2ENR_OTGFSEN); gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO9 | GPIO11 | GPIO12); gpio_set_af(GPIOA, GPIO_AF10, GPIO9 | GPIO11 | GPIO12); cdcacm_usb_init(); nvic_set_priority(NVIC_OTG_FS_IRQ, IRQ_PRI_USB); nvic_enable_irq(NVIC_OTG_FS_IRQ); while (cdcacm_get_config() != 1) { wait(1); }; //wait until usb is configured }
void gdb_if_putchar(unsigned char c, int flush) { buffer_in[count_in++] = c; if(flush || (count_in == CDCACM_PACKET_SIZE)) { /* Refuse to send if USB isn't configured, and * don't bother if nobody's listening */ if((cdcacm_get_config() != 1) || !cdcacm_get_dtr()) { count_in = 0; return; } while(usbd_ep_write_packet(usbdev, CDCACM_GDB_ENDPOINT, buffer_in, count_in) <= 0); count_in = 0; } }
unsigned char gdb_if_getchar(void) { while(!(out_ptr < count_out)) { /* Detach if port closed */ if(!cdcacm_get_dtr()) return 0x04; while(cdcacm_get_config() != 1); count_out = usbd_ep_read_packet(usbdev, CDCACM_GDB_ENDPOINT, buffer_out, CDCACM_PACKET_SIZE); out_ptr = 0; } return buffer_out[out_ptr++]; }
unsigned char gdb_if_getchar_to(int timeout) { platform_timeout t; platform_timeout_set(&t, timeout); if(head_out == tail_out) do { /* Detach if port closed */ if(!cdcacm_get_dtr()) return 0x04; while(cdcacm_get_config() != 1); } while(!platform_timeout_is_expired(&t) && head_out == tail_out); if(head_out != tail_out) return gdb_if_getchar(); return -1; }
static void gdb_if_update_buf(void) { while (cdcacm_get_config() != 1); #ifdef STM32F4 asm volatile ("cpsid i; isb"); if (count_new) { memcpy(buffer_out, double_buffer_out, count_new); count_out = count_new; count_new = 0; out_ptr = 0; usbd_ep_nak_set(usbdev, CDCACM_GDB_ENDPOINT, 0); } asm volatile ("cpsie i; isb"); #else count_out = usbd_ep_read_packet(usbdev, CDCACM_GDB_ENDPOINT, buffer_out, CDCACM_PACKET_SIZE); out_ptr = 0; #endif }
unsigned char gdb_if_getchar(void) { while(!(out_ptr < count_out)) { /* Detach if port closed */ if(!cdcacm_get_dtr()) return 0x04; while(cdcacm_get_config() != 1); if (count_new) { memcpy(buffer_out, double_buffer_out,count_new); count_out = count_new; count_new = 0; out_ptr = 0; usbd_ep_nak_set(usbdev, CDCACM_GDB_ENDPOINT, 0); } } return buffer_out[out_ptr++]; }
/* * Runs deferred processing for usb uart rx, draining RX FIFO by sending * characters to host PC via CDCACM. Allowed to read from FIFO in pointer, * but not write to it. Allowed to write to FIFO out pointer. */ static void usbuart_run(void) { /* forcibly empty fifo if no USB endpoint */ if (cdcacm_get_config() != 1) { buf_rx_out = buf_rx_in; } /* if fifo empty, nothing further to do */ if (buf_rx_in == buf_rx_out) { /* turn off LED, disable IRQ */ timer_disable_irq(USBUSART_TIM, TIM_DIER_UIE); gpio_clear(LED_PORT_UART, LED_UART); } else { uint8_t packet_buf[CDCACM_PACKET_SIZE]; uint8_t packet_size = 0; uint8_t buf_out = buf_rx_out; /* copy from uart FIFO into local usb packet buffer */ while (buf_rx_in != buf_out && packet_size < CDCACM_PACKET_SIZE) { packet_buf[packet_size++] = buf_rx[buf_out++]; /* wrap out pointer */ if (buf_out >= FIFO_SIZE) { buf_out = 0; } } /* advance fifo out pointer by amount written */ buf_rx_out += usbd_ep_write_packet(usbdev, CDCACM_UART_ENDPOINT, packet_buf, packet_size); buf_rx_out %= FIFO_SIZE; } }
unsigned char gdb_if_getchar_to(int timeout) { timeout_counter = timeout/100; if(!(out_ptr < count_out)) do { /* Detach if port closed */ if(!cdcacm_get_dtr()) return 0x04; while(cdcacm_get_config() != 1); if (count_new) { memcpy(buffer_out, double_buffer_out,count_new); count_out = count_new; count_new = 0; out_ptr = 0; usbd_ep_nak_set(usbdev, CDCACM_GDB_ENDPOINT, 0); } } while(timeout_counter && !(out_ptr < count_out)); if(out_ptr < count_out) return gdb_if_getchar(); return -1; }