Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proper ring buffer implementation, fixes #53 #58

Closed
wants to merge 7 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -22,6 +22,7 @@ target_sources(pico_ice_sdk INTERFACE
src/ice_led.c
src/ice_cram.c
src/ice_wishbone.c
src/rb.c
)
target_include_directories(pico_ice_sdk INTERFACE
include
@@ -46,6 +47,7 @@ add_library(pico_ice_usb INTERFACE)

target_sources(pico_ice_usb INTERFACE
src/ice_usb.c
src/ice_usb_uart.c
src/tinyuf2_main.c
src/tinyuf2_board.c
src/tinyuf2_include.c
2 changes: 1 addition & 1 deletion include/ice_usb.h
Original file line number Diff line number Diff line change
@@ -196,8 +196,8 @@ extern const tusb_desc_device_t tud_desc_device;
extern void (*tud_cdc_rx_cb_table[CFG_TUD_CDC])(uint8_t);

void ice_usb_init(void);
void ice_usb_sleep_ms(uint32_t ms);
void ice_usb_task();
// Task function should be called in main/rtos loop

#ifdef __cplusplus
}
144 changes: 24 additions & 120 deletions src/ice_usb.c
Original file line number Diff line number Diff line change
@@ -72,6 +72,9 @@
#define DFU_ALT_FLASH 0
#define DFU_ALT_CRAM 1

// uart functions
#include "ice_usb_uart.h"

// Provide a default config where some fields come be customized in <tusb_config.h>
const tusb_desc_device_t tud_desc_device = {
.bLength = sizeof(tusb_desc_device_t),
@@ -93,15 +96,6 @@ const tusb_desc_device_t tud_desc_device = {
// Also used in usb_descriptors.c.
char usb_serial_number[PICO_UNIQUE_BOARD_ID_SIZE_BYTES * 2 + 1];

// Sleeping without calling tud_task() hangs the USB stack in the meantime.
void ice_usb_sleep_ms(uint32_t ms)
{
while (ms-- > 0) {
ice_usb_task();
sleep_ms(1);
}
}

// Invoked when received GET DEVICE DESCRIPTOR
// Application return pointer to descriptor
uint8_t const *tud_descriptor_device_cb(void)
@@ -157,54 +151,21 @@ uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid)
return utf16;
}

#ifdef ICE_USB_UART0_CDC

static void ice_usb_cdc_to_uart0(uint8_t byte)
{
if (uart_is_writable(uart0)) {
uart_putc(uart0, byte);
}
}

static void ice_usb_uart0_to_cdc(void)
void tud_cdc_line_coding_cb(uint8_t itf, cdc_line_coding_t const *coding)
{
while (uart_is_readable(uart0)) {
uint8_t byte = uart_getc(uart0);
tud_cdc_n_write_char(ICE_USB_UART0_CDC, byte);
}
}

#endif

#ifdef ICE_USB_UART1_CDC
// printf("%s: coding=%p baud=%lu\n", __func__, coding, coding->bit_rate);

static void ice_usb_cdc_to_uart1(uint8_t byte)
{
if (uart_is_writable(uart1)) {
uart_putc(uart1, byte);
/* Mimick the Arduino reboot signal:
* https://arduino.github.io/arduino-cli/dev/platform-specification/#1200-bps-bootloader-reset */
if (coding->bit_rate == 1200) {
reset_usb_boot(0, 0);
assert(!"not reached");
}
}

char uart1_rx_buf[CFG_TUD_CDC_TX_BUFSIZE];
int uart1_rx_index_r;
long long uart1_rx_read_total;
int uart1_rx_index_w;
long long uart1_rx_written_total;

static void ice_usb_uart1_to_cdc(void)
{
while (uart_is_readable(uart1)) {
uint8_t byte = uart_getc(uart1);

uart1_rx_buf[uart1_rx_index_w++] = byte;
while (uart1_rx_index_w == CFG_TUD_CDC_TX_BUFSIZE)
uart1_rx_index_w -= CFG_TUD_CDC_TX_BUFSIZE;
uart1_rx_written_total++;
}
ice_usb_uart_cb_baud(itf, coding->bit_rate);
// ignore if handled or not
}

#endif

#ifdef ICE_USB_SPI_CDC

static void ice_usb_cdc_to_spi(uint8_t ch)
@@ -302,12 +263,6 @@ void ice_usb_cdc_to_fpga(uint8_t byte)
#endif

void (*tud_cdc_rx_cb_table[CFG_TUD_CDC])(uint8_t) = {
#ifdef ICE_USB_UART0_CDC
[ICE_USB_UART0_CDC] = &ice_usb_cdc_to_uart0,
#endif
#ifdef ICE_USB_UART1_CDC
[ICE_USB_UART1_CDC] = &ice_usb_cdc_to_uart1,
#endif
#ifdef ICE_USB_FPGA_CDC
[ICE_USB_FPGA_CDC] = &ice_usb_cdc_to_fpga,
#endif
@@ -316,43 +271,23 @@ void (*tud_cdc_rx_cb_table[CFG_TUD_CDC])(uint8_t) = {
#endif
};

void tud_cdc_line_coding_cb(uint8_t itf, cdc_line_coding_t const *coding)
{
printf("%s: coding=%p baud=%d\n", __func__, coding, coding->bit_rate);

/* Mimick the Arduino reboot signal:
* https://arduino.github.io/arduino-cli/dev/platform-specification/#1200-bps-bootloader-reset */
if (coding->bit_rate == 1200) {
reset_usb_boot(0, 0);
assert(!"not reached");
}

switch (itf) {
#ifdef ICE_USB_UART0_CDC
case ICE_USB_UART0_CDC:
uart_set_baudrate(uart0, coding->bit_rate);
break;
#endif
#ifdef ICE_USB_UART1_CDC
case ICE_USB_UART1_CDC:
uart_set_baudrate(uart1, coding->bit_rate);
break;
#endif
}
}

#if ICE_USB_UART0_CDC || ICE_USB_UART1_CDC || ICE_USB_FPGA_CDC || ICE_USB_SPI_CDC

void tud_cdc_rx_cb(uint8_t cdc_num)
void tud_cdc_rx_cb(uint8_t itf)
{
// special handling for uart
int handled = ice_usb_uart_cb_rx(itf);
if (handled)
return;

// existing callback for that CDC number, send it all available data
assert(cdc_num < sizeof(tud_cdc_rx_cb_table) / sizeof(*tud_cdc_rx_cb_table));
assert(itf < sizeof(tud_cdc_rx_cb_table) / sizeof(*tud_cdc_rx_cb_table));

if (tud_cdc_rx_cb_table[cdc_num] == NULL) {
if (tud_cdc_rx_cb_table[itf] == NULL) {
return;
}
for (int32_t ch; (ch = tud_cdc_n_read_char(cdc_num)) >= 0;) {
tud_cdc_rx_cb_table[cdc_num](ch);
for (int32_t ch; (ch = tud_cdc_n_read_char(itf)) >= 0;) {
tud_cdc_rx_cb_table[itf](ch);
}
}

@@ -473,17 +408,7 @@ void ice_usb_init(void)
tud_task();
}

#ifdef ICE_USB_UART0_CDC
irq_set_exclusive_handler(UART0_IRQ, ice_usb_uart0_to_cdc);
irq_set_enabled(UART0_IRQ, true);
uart_set_irq_enables(uart0, true, false);
#endif

#ifdef ICE_USB_UART1_CDC
irq_set_exclusive_handler(UART1_IRQ, ice_usb_uart1_to_cdc);
irq_set_enabled(UART1_IRQ, true);
uart_set_irq_enables(uart1, true, false);
#endif
ice_usb_uart_init();

#ifdef ICE_USB_SPI_CDC
ice_spi_init_cs_pin(ICE_SRAM_CS_PIN, true);
@@ -498,28 +423,7 @@ void ice_usb_init(void)
#endif
}

// Task function should be called in main/rtos loop
// this additionally flushes uart buffers
void ice_usb_task() {
tud_task();

#ifdef ICE_USB_UART0_CDC
tud_cdc_n_write_flush(ICE_USB_UART0_CDC);
#endif

#ifdef ICE_USB_UART1_CDC
uart1_rx_read_total = MAX(uart1_rx_read_total, uart1_rx_written_total - CFG_TUD_CDC_TX_BUFSIZE);

while (uart1_rx_read_total < uart1_rx_written_total) {
char byte = uart1_rx_buf[uart1_rx_index_r++];
while (uart1_rx_index_r == CFG_TUD_CDC_TX_BUFSIZE)
uart1_rx_index_r -= CFG_TUD_CDC_TX_BUFSIZE;
uart1_rx_read_total++;

if (tud_cdc_n_write_available(ICE_USB_UART1_CDC) > 0)
tud_cdc_n_write_char(ICE_USB_UART1_CDC, byte);
}

tud_cdc_n_write_flush(ICE_USB_UART1_CDC);
#endif
ice_usb_uart_task();
}
Loading