/** * tundra_uart.c * * Listen to Tundra TL448K6D-VR debug messages via its UART output * * Copyright (c) 2024 Bigscreen, Inc. */ #include #include #define TUNDRA_BUFFER_CAPACITY (256) #define TUNDRA_UART_HID_CAPACITY (62) uint8_t tundra_buffer[TUNDRA_BUFFER_CAPACITY]; circular_buffer_t* tbuf; uint8_t tundra_hid_buffer[TUNDRA_UART_HID_CAPACITY]; uint32_t hid_buf_pos = 0; TaskHandle_t xTundraUartTaskHandle = NULL; void tundra_uart_task(void* pvParameters); void tundra_uart_init(void); void start_tundra_uart_task() { if(xTaskCreate(tundra_uart_task, "Tundra Uart", TASK_REPORT_STACK_SIZE, NULL, TASK_REPORT_PRIORITY, &xTundraUartTaskHandle) != pdPASS) { printf("Failed to create Tundra UART task\r\n"); } } void send_code_to_tundra_uart_task(uint32_t code) { xTaskNotify(xTundraUartTaskHandle, code, eSetValueWithOverwrite); } void tundra_uart_init(void) { // enable pins in UART mode ioport_set_port_mode(PINS_USART2_PORT, PINS_USART2, PINS_USART2_FLAGS); ioport_disable_port(PINS_USART2_PORT, PINS_USART2); // startup the UART with 460.8 kBaud, 8N1 sam_usart_opt_t usart_settings; usart_settings.baudrate = (460800UL); usart_settings.char_length = US_MR_CHRL_8_BIT; usart_settings.parity_type = US_MR_PAR_NO; usart_settings.stop_bits= US_MR_NBSTOP_1_BIT; usart_settings.channel_mode= US_MR_CHMODE_NORMAL; flexcom_enable(TUNDRA_FLEXCOM); flexcom_set_opmode(TUNDRA_FLEXCOM, FLEXCOM_USART); usart_init_rs232(TUNDRA_UART, &usart_settings, sysclk_get_peripheral_hz()); NVIC_EnableIRQ(TUNDRA_UART_ID); NVIC_SetPriority(TUNDRA_UART_ID, USART_INTERRUPT_PRIO); // trigger whenever a byte is waiting in the receiver TUNDRA_UART->US_IER = US_IER_RXRDY; usart_enable_rx(TUNDRA_UART); } void tundra_uart_task(void* pvParameters) { UNUSED(pvParameters); // initialize circular buffer circular_buffer_t tundra_buf; tundra_buf.buffer = tundra_buffer; tundra_buf.capacity = TUNDRA_BUFFER_CAPACITY; tundra_buf.head = 0; tundra_buf.tail = 0; tundra_buf.flags = 0; tbuf = &tundra_buf; tundra_uart_init(); hid_buf_pos = 0; uint8_t temp; while(1) { vTaskDelay(1); temp = 0; while((!circular_buffer_is_empty(tbuf)) && (hid_buf_pos < TUNDRA_UART_HID_CAPACITY)) { if(circular_buffer_get(tbuf, &temp)) { tundra_hid_buffer[hid_buf_pos++] = temp; } } if((hid_buf_pos == TUNDRA_UART_HID_CAPACITY) || (temp == '\n')) { // send the buffer when it gets full or a newline appears send_code_to_hid_task(HID_REPORT_TASK_CODE_FOR_TUNDRA_UART); ulTaskNotifyTake(pdTRUE, portMAX_DELAY); hid_buf_pos = 0; } } } uint8_t* tundra_uart_get_hid_buffer() { return tundra_hid_buffer; } uint32_t tundra_uart_get_hid_buffer_length() { return hid_buf_pos; } // Tundra is on USART2 (PA5) void FLEXCOM2_Handler(void) { // Check for RXRDY interrupt if(((TUNDRA_UART->US_IMR) & (US_IMR_RXRDY)) != 0) { if(((TUNDRA_UART->US_CSR) & (US_CSR_RXRDY)) != 0) { // New character received, add it to the holding buffer uint32_t newdat = TUNDRA_UART->US_RHR; circular_buffer_put(tbuf, (uint8_t)newdat); } } }