From 08492f13d6a282a7f545845bada7bdfedf7a88a9 Mon Sep 17 00:00:00 2001 From: Harley Peterson Date: Wed, 10 Jun 2026 10:15:23 -0500 Subject: [PATCH] Autoformat code --- Mainboard/Firmware/mainboard/Core/Inc/adc.h | 1 - .../Firmware/mainboard/Core/Inc/drv_uart.h | 42 +- Mainboard/Firmware/mainboard/Core/Src/adc.c | 351 ++++----- .../Firmware/mainboard/Core/Src/drv_gpio.c | 8 +- .../Firmware/mainboard/Core/Src/drv_uart.c | 740 +++++++++--------- Mainboard/Firmware/mainboard/Core/Src/main.c | 46 +- 6 files changed, 588 insertions(+), 600 deletions(-) diff --git a/Mainboard/Firmware/mainboard/Core/Inc/adc.h b/Mainboard/Firmware/mainboard/Core/Inc/adc.h index c26e14b..7e64d26 100644 --- a/Mainboard/Firmware/mainboard/Core/Inc/adc.h +++ b/Mainboard/Firmware/mainboard/Core/Inc/adc.h @@ -5,5 +5,4 @@ void adc_init(void); - #endif // ADC_H diff --git a/Mainboard/Firmware/mainboard/Core/Inc/drv_uart.h b/Mainboard/Firmware/mainboard/Core/Inc/drv_uart.h index 358e0bd..e995c24 100644 --- a/Mainboard/Firmware/mainboard/Core/Inc/drv_uart.h +++ b/Mainboard/Firmware/mainboard/Core/Inc/drv_uart.h @@ -2,11 +2,11 @@ #define DRV_UART_H // BENCHMARK MODE FLAG for DMA -//#define BENCHMARK_MODE +// #define BENCHMARK_MODE #include "platform.h" -#include #include +#include void drv_uart_init(void); @@ -22,11 +22,7 @@ extern DMA_HandleTypeDef hdma_uart5_rx; extern DMA_HandleTypeDef hdma_uart6_rx; extern DMA_HandleTypeDef hdma_uart1_rx; -typedef enum { - STATE_IDLE, - STATE_GOT_HEADER, - STATE_GOT_MSB -} rx_state_t; +typedef enum { STATE_IDLE, STATE_GOT_HEADER, STATE_GOT_MSB } rx_state_t; typedef struct { rx_state_t state; @@ -57,31 +53,32 @@ void process_routing(void); /** * Thread-safe, non-blocking wrapper for process_routing(). - * Uses an atomic try-lock to prevent reentrancy without + * Uses an atomic try-lock to prevent reentrancy without * stalling the CPU or blinding interrupts for too long. */ -static inline void try_process_routing(void) { +static inline void try_process_routing(void) +{ // 1. Enter brief critical section (approx. 3 CPU cycles) __disable_irq(); - + // 2. Check if the lock is already claimed if (is_routing_active) { // Someone else is already routing. Safely abort. __enable_irq(); - return; + return; } - + // 3. Claim the lock is_routing_active = true; - + // 4. Exit critical section BEFORE the heavy lifting - __enable_irq(); + __enable_irq(); // 5. Perform the actual routing with interrupts perfectly active process_routing(); // 6. Release the lock when finished - // (This single write is inherently atomic on a 32-bit ARM core, + // (This single write is inherently atomic on a 32-bit ARM core, // so we don't need to disable interrupts just to clear it). is_routing_active = false; } @@ -90,24 +87,25 @@ static inline void try_process_routing(void) { * Attempt to instantly reset the routing state machine and flush buffers. * To be called ONLY from the very beginning of EXTI3_IRQHandler. */ -static inline void try_reset_routing_state(void) { - // Because we are inside an IRQ, we preempted main(). +static inline void try_reset_routing_state(void) +{ + // Because we are inside an IRQ, we preempted main(). // We do NOT need to disable interrupts here to check the flag safely. if (!is_routing_active) { - + // 1. Reset state machines to gracefully await the next packet tracker1.state = STATE_IDLE; tracker2.state = STATE_IDLE; - + // 2. Soft-flush the DMA buffers. - // We advance our read pointers to exactly where the DMA hardware + // We advance our read pointers to exactly where the DMA hardware // is currently writing. All old, unprocessed bytes are instantly discarded. #ifdef BENCHMARK_MODE tracker1.read_index = mock_dma_write_head; tracker2.read_index = mock_dma_write_head; #else - tracker1.read_index = (uint8_t)(AMDS_RX_BUF_SIZE - __HAL_DMA_GET_COUNTER(DAISY_RX1_UART.hdmarx)); - tracker2.read_index = (uint8_t)(AMDS_RX_BUF_SIZE - __HAL_DMA_GET_COUNTER(DAISY_RX2_UART.hdmarx)); + tracker1.read_index = (uint8_t) (AMDS_RX_BUF_SIZE - __HAL_DMA_GET_COUNTER(DAISY_RX1_UART.hdmarx)); + tracker2.read_index = (uint8_t) (AMDS_RX_BUF_SIZE - __HAL_DMA_GET_COUNTER(DAISY_RX2_UART.hdmarx)); #endif } } diff --git a/Mainboard/Firmware/mainboard/Core/Src/adc.c b/Mainboard/Firmware/mainboard/Core/Src/adc.c index 92abcd8..2dbb08a 100644 --- a/Mainboard/Firmware/mainboard/Core/Src/adc.c +++ b/Mainboard/Firmware/mainboard/Core/Src/adc.c @@ -1,6 +1,6 @@ #include "adc.h" -#include "drv_uart.h" #include "drv_spi.h" +#include "drv_uart.h" #include "platform.h" #include #include @@ -41,15 +41,14 @@ static void setup_pin_CONVST(void); #define ADC_BITS_TO_VOLTS(bits) (ADC_VOLTS_PER_BIT * (float) bits) - // Global bitmask: 1 = Active, 0 = Inactive. // For example: 0b00001111 (0x0F) means channels 1-4 are active, 5-8 are disabled. #if defined(TARGET_AMDS) - volatile uint8_t active_sensor_mask = 0xFF; +volatile uint8_t active_sensor_mask = 0xFF; #elif defined(TARGET_2S) - volatile uint8_t active_sensor_mask = 0x11; +volatile uint8_t active_sensor_mask = 0x11; #else - #error "Please define a target board (TARGET_AMDS or TARGET_2S)!" +#error "Please define a target board (TARGET_AMDS or TARGET_2S)!" #endif void adc_init(void) @@ -138,21 +137,21 @@ static void adc_sample_all_daughtercards(uint16_t *sample_data_out) void adc_sample_and_transmit_fast_path(uint16_t *sample_data_out) { - bool send_header = false; + bool send_header = false; // 1. Start all ADC conversions. SET_PIN_CONVST12_HIGH; SET_PIN_CONVST34_HIGH; SET_PIN_CONVST56_HIGH; SET_PIN_CONVST78_HIGH; - //Timing optimization: do work before the wait state below. + // Timing optimization: do work before the wait state below. uint32_t start_cycles = DWT->CYCCNT; // reset DMA routing state machine - try_reset_routing_state(); + try_reset_routing_state(); - // Calculate 1.3 microseconds in CPU cycles (integer math safe) - uint32_t wait_cycles = (SystemCoreClock / 1000000) * 13 / 10; + // Calculate 1.3 microseconds in CPU cycles (integer math safe) + uint32_t wait_cycles = (SystemCoreClock / 1000000) * 13 / 10; // Deterministic wait for exactly 1300ns using hardware cycles, not NOPs while ((DWT->CYCCNT - start_cycles) < wait_cycles) { @@ -167,45 +166,44 @@ void adc_sample_and_transmit_fast_path(uint16_t *sample_data_out) // Timing optimization: send our first header bytes here because code after this is waiting drv_uart_putc_fast(USART2, 0x90); - drv_uart_putc_fast(USART3, 0x90); + drv_uart_putc_fast(USART3, 0x90); - // 3. Wait and read first ADC data (Channels 0, 1, 2, 3) + // 3. Wait and read first ADC data (Channels 0, 1, 2, 3) drv_spi_finish_read_one_16bits(SPI1, &sample_data_out[3]); drv_spi_finish_read_one_16bits(SPI4, &sample_data_out[1]); drv_spi_finish_read_one_16bits(SPI5, &sample_data_out[0]); drv_spi_finish_read_one_16bits(SPI6, &sample_data_out[2]); - //Timing optimization: wait for only the last SPI that we started - drv_spi_wait_for_RX(SPI6); + // Timing optimization: wait for only the last SPI that we started + drv_spi_wait_for_RX(SPI6); - // Read second ADC data (Channels 4, 5, 6, 7) - drv_spi_get_DR(SPI1, &sample_data_out[7]); - drv_spi_get_DR(SPI4, &sample_data_out[5]); - drv_spi_get_DR(SPI5, &sample_data_out[4]); - drv_spi_get_DR(SPI6, &sample_data_out[6]); + // Read second ADC data (Channels 4, 5, 6, 7) + drv_spi_get_DR(SPI1, &sample_data_out[7]); + drv_spi_get_DR(SPI4, &sample_data_out[5]); + drv_spi_get_DR(SPI5, &sample_data_out[4]); + drv_spi_get_DR(SPI6, &sample_data_out[6]); for (uint32_t i = 0; i < 4; i++) { - //don't send first header because we sent it earlier (timing optimization) - if (send_header){ - drv_uart_putc_fast(USART2, 0x90 | i); - drv_uart_putc_fast(USART3, 0x90 | i); - } - else { - send_header = true; - } - - drv_uart_putc_fast(USART3, (uint8_t)(sample_data_out[i + 4] >> 8)); - drv_uart_putc_fast(USART2, (uint8_t)(sample_data_out[i] >> 8)); - - drv_uart_putc_fast(USART2, (uint8_t)sample_data_out[i]); - drv_uart_putc_fast(USART3, (uint8_t)sample_data_out[i + 4]); - } + // don't send first header because we sent it earlier (timing optimization) + if (send_header) { + drv_uart_putc_fast(USART2, 0x90 | i); + drv_uart_putc_fast(USART3, 0x90 | i); + } else { + send_header = true; + } + + drv_uart_putc_fast(USART3, (uint8_t) (sample_data_out[i + 4] >> 8)); + drv_uart_putc_fast(USART2, (uint8_t) (sample_data_out[i] >> 8)); + + drv_uart_putc_fast(USART2, (uint8_t) sample_data_out[i]); + drv_uart_putc_fast(USART3, (uint8_t) sample_data_out[i + 4]); + } // End conversion - SET_PIN_CONVST12_LOW; - SET_PIN_CONVST34_LOW; - SET_PIN_CONVST56_LOW; - SET_PIN_CONVST78_LOW; + SET_PIN_CONVST12_LOW; + SET_PIN_CONVST34_LOW; + SET_PIN_CONVST56_LOW; + SET_PIN_CONVST78_LOW; } // This ISR is triggered by the AMDC to sync the ADC @@ -213,28 +211,28 @@ void adc_sample_and_transmit_fast_path(uint16_t *sample_data_out) // this ISR, all the mainboard ADCs should be sampled. void EXTI3_IRQHandler(void) { - // alert daisy chained AMDSs to begin converting - GPIO_TOGGLE_PIN(GPIOD, GPIO_PIN_1); + // alert daisy chained AMDSs to begin converting + GPIO_TOGGLE_PIN(GPIOD, GPIO_PIN_1); #ifdef BENCHMARK_MODE // ========================================================================= // INJECT MOCK DMA DATA FOR BENCHMARKING // Simulates 8 packets (24 bytes) arriving instantly on the SYNC edge. // ========================================================================= - try_reset_routing_state(); + try_reset_routing_state(); uint8_t current_head = mock_dma_write_head; for (int i = 0; i < 24; i++) { - uint8_t idx = (uint8_t)(current_head + i); + uint8_t idx = (uint8_t) (current_head + i); if (i % 3 == 0) { - DAISY_RX1_Pool[idx] = 0x90; // Valid Header + DAISY_RX1_Pool[idx] = 0x90; // Valid Header DAISY_RX2_Pool[idx] = 0x90; } else { - DAISY_RX1_Pool[idx] = 0xAA; // Dummy Payload Data + DAISY_RX1_Pool[idx] = 0xAA; // Dummy Payload Data DAISY_RX2_Pool[idx] = 0xBB; } } // Instantly advance the mock hardware write head - mock_dma_write_head = (uint8_t)(current_head + 24); + mock_dma_write_head = (uint8_t) (current_head + 24); #endif uint16_t new_data[8] = { 0 }; @@ -250,9 +248,9 @@ void EXTI3_IRQHandler(void) // ========================================================================= else { #ifndef BENCHMARK_MODE - try_reset_routing_state(); + try_reset_routing_state(); #endif - adc_sample_all_daughtercards(new_data); + adc_sample_all_daughtercards(new_data); for (uint32_t i = 0; i < 4; i++) { uint8_t header = 0x90 | i; @@ -260,10 +258,10 @@ void EXTI3_IRQHandler(void) if ((active_sensor_mask & (1 << i)) && (active_sensor_mask & (1 << (i + 4)))) { drv_uart_putc_fast(USART2, header); drv_uart_putc_fast(USART3, header); - drv_uart_putc_fast(USART2, (uint8_t)(new_data[i] >> 8)); - drv_uart_putc_fast(USART3, (uint8_t)(new_data[i + 4] >> 8)); - drv_uart_putc_fast(USART2, (uint8_t)(new_data[i])); - drv_uart_putc_fast(USART3, (uint8_t)(new_data[i + 4])); + drv_uart_putc_fast(USART2, (uint8_t) (new_data[i] >> 8)); + drv_uart_putc_fast(USART3, (uint8_t) (new_data[i + 4] >> 8)); + drv_uart_putc_fast(USART2, (uint8_t) (new_data[i])); + drv_uart_putc_fast(USART3, (uint8_t) (new_data[i + 4])); } else { bool u3 = false; bool u2 = false; @@ -271,21 +269,23 @@ void EXTI3_IRQHandler(void) if (active_sensor_mask & (1 << i)) { drv_uart_putc_fast(USART2, header); u2 = true; - drv_uart_putc_fast(USART2, (uint8_t)(new_data[i] >> 8)); + drv_uart_putc_fast(USART2, (uint8_t) (new_data[i] >> 8)); } if (active_sensor_mask & (1 << (i + 4))) { drv_uart_putc_fast(USART3, header); u3 = true; - drv_uart_putc_fast(USART3, (uint8_t)(new_data[i + 4] >> 8)); + drv_uart_putc_fast(USART3, (uint8_t) (new_data[i + 4] >> 8)); } - if (u2) drv_uart_putc_fast(USART2, (uint8_t)(new_data[i] & 0xFF)); - if (u3) drv_uart_putc_fast(USART3, (uint8_t)(new_data[i + 4] & 0xFF)); + if (u2) + drv_uart_putc_fast(USART2, (uint8_t) (new_data[i] & 0xFF)); + if (u3) + drv_uart_putc_fast(USART3, (uint8_t) (new_data[i + 4] & 0xFF)); } } } // Handle any DMA data that has been received from daisy chain - try_process_routing(); + try_process_routing(); NVIC_ClearPendingIRQ(EXTI3_IRQn); __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_3); @@ -346,14 +346,14 @@ void adc_sample_and_transmit_1_5_fast_path(uint16_t *sample_data_out) // 1. Start all ADC conversions. SET_PIN_CONVST56_HIGH; - //Timing optimization: do work before the wait state below. + // Timing optimization: do work before the wait state below. uint32_t start_cycles = DWT->CYCCNT; // reset DMA routing state machine - try_reset_routing_state(); + try_reset_routing_state(); - // Calculate 1.3 microseconds in CPU cycles (integer math safe) - uint32_t wait_cycles = (SystemCoreClock / 1000000) * 13 / 10; + // Calculate 1.3 microseconds in CPU cycles (integer math safe) + uint32_t wait_cycles = (SystemCoreClock / 1000000) * 13 / 10; // Deterministic wait for exactly 1300ns using hardware cycles, not NOPs while ((DWT->CYCCNT - start_cycles) < wait_cycles) { @@ -363,118 +363,119 @@ void adc_sample_and_transmit_1_5_fast_path(uint16_t *sample_data_out) // 2. Start the SCLK drv_spi_start_read_two_16bits(SPI5); - // 3. Wait and read first ADC data (Channels 0, 1, 2, 3) + // 3. Wait and read first ADC data (Channels 0, 1, 2, 3) drv_spi_finish_read_one_16bits(SPI5, &sample_data_out[0]); - //Timing optimization: wait for only the last SPI that we started - drv_spi_wait_for_RX(SPI5); + // Timing optimization: wait for only the last SPI that we started + drv_spi_wait_for_RX(SPI5); - drv_uart_putc_fast(USART2, 0x90); - drv_uart_putc_fast(USART3, 0x90); + drv_uart_putc_fast(USART2, 0x90); + drv_uart_putc_fast(USART3, 0x90); - // Read second ADC data (Channels 4, 5, 6, 7) - drv_spi_get_DR(SPI5, &sample_data_out[4]); + // Read second ADC data (Channels 4, 5, 6, 7) + drv_spi_get_DR(SPI5, &sample_data_out[4]); - // don't send first header - drv_uart_putc_fast(USART2, (uint8_t)(sample_data_out[0] >> 8)); - drv_uart_putc_fast(USART3, (uint8_t)(sample_data_out[4] >> 8)); + // don't send first header + drv_uart_putc_fast(USART2, (uint8_t) (sample_data_out[0] >> 8)); + drv_uart_putc_fast(USART3, (uint8_t) (sample_data_out[4] >> 8)); - drv_uart_putc_fast(USART2, (uint8_t)sample_data_out[0]); - drv_uart_putc_fast(USART3, (uint8_t)sample_data_out[4]); + drv_uart_putc_fast(USART2, (uint8_t) sample_data_out[0]); + drv_uart_putc_fast(USART3, (uint8_t) sample_data_out[4]); // End conversion - SET_PIN_CONVST56_LOW; + SET_PIN_CONVST56_LOW; } // This ISR is for the FBC and is triggered by the // AMDC to sync the ADCconversions to the AMDC PWM // carrier waveform. In this ISR, on 2 ADCs should be sampled. -//void EXTI15_10_IRQHandler(void) +// void EXTI15_10_IRQHandler(void) void EXTI15_10_IRQHandler(void) { - // alert daisy chained AMDSs to begin converting - GPIO_TOGGLE_PIN(GPIOG, GPIO_PIN_14); + // alert daisy chained AMDSs to begin converting + GPIO_TOGGLE_PIN(GPIOG, GPIO_PIN_14); #ifdef BENCHMARK_MODE - // ========================================================================= - // INJECT MOCK DMA DATA FOR BENCHMARKING - // Simulates 8 packets (24 bytes) arriving instantly on the SYNC edge. - // ========================================================================= - try_reset_routing_state(); - uint8_t current_head = mock_dma_write_head; - for (int i = 0; i < 3; i++) { - uint8_t idx = (uint8_t)(current_head + i); - if (i == 0) { - DAISY_RX1_Pool[idx] = 0x90; // Valid Header - DAISY_RX2_Pool[idx] = 0x90; - } else if (i == 3) { - DAISY_RX1_Pool[idx] = 0x94; // Valid Header - DAISY_RX2_Pool[idx] = 0x94; - } else { - DAISY_RX1_Pool[idx] = 0xAA; // Dummy Payload Data - DAISY_RX2_Pool[idx] = 0xBB; - } - } - // Instantly advance the mock hardware write head - mock_dma_write_head = (uint8_t)(current_head + 3); + // ========================================================================= + // INJECT MOCK DMA DATA FOR BENCHMARKING + // Simulates 8 packets (24 bytes) arriving instantly on the SYNC edge. + // ========================================================================= + try_reset_routing_state(); + uint8_t current_head = mock_dma_write_head; + for (int i = 0; i < 3; i++) { + uint8_t idx = (uint8_t) (current_head + i); + if (i == 0) { + DAISY_RX1_Pool[idx] = 0x90; // Valid Header + DAISY_RX2_Pool[idx] = 0x90; + } else if (i == 3) { + DAISY_RX1_Pool[idx] = 0x94; // Valid Header + DAISY_RX2_Pool[idx] = 0x94; + } else { + DAISY_RX1_Pool[idx] = 0xAA; // Dummy Payload Data + DAISY_RX2_Pool[idx] = 0xBB; + } + } + // Instantly advance the mock hardware write head + mock_dma_write_head = (uint8_t) (current_head + 3); #endif - uint16_t new_data[8] = { 0 }; - - // ========================================================================= - // FAST PATH: Integrated Sampling and Transmission! - // ========================================================================= - if (active_sensor_mask == 0x11) { - adc_sample_and_transmit_1_5_fast_path(new_data); - } - // ========================================================================= - // SLOW PATH: Safe loop for Partial Masks - // ========================================================================= - else { + uint16_t new_data[8] = { 0 }; + + // ========================================================================= + // FAST PATH: Integrated Sampling and Transmission! + // ========================================================================= + if (active_sensor_mask == 0x11) { + adc_sample_and_transmit_1_5_fast_path(new_data); + } + // ========================================================================= + // SLOW PATH: Safe loop for Partial Masks + // ========================================================================= + else { #ifndef BENCHMARK_MODE - try_reset_routing_state(); + try_reset_routing_state(); #endif - adc_sample_1_5_daughtercards(new_data); - - bool u3 = false; - bool u2 = false; - uint8_t header = 0x90; - - if (active_sensor_mask & (1 << 0)) { - drv_uart_putc_fast(USART2, header); - u2 = true; - drv_uart_putc_fast(USART2, (uint8_t)(new_data[0] >> 8)); - } - if (active_sensor_mask & (1 << 4)) { - drv_uart_putc_fast(USART3, header); - u3 = true; - drv_uart_putc_fast(USART3, (uint8_t)(new_data[4] >> 8)); - } - if (u2) drv_uart_putc_fast(USART2, (uint8_t)(new_data[0])); - if (u3) drv_uart_putc_fast(USART3, (uint8_t)(new_data[4])); - } - - uint32_t start_cycles = DWT->CYCCNT; - - // Calculate 1 microseconds in CPU cycles (integer math safe) - uint32_t wait_cycles = (SystemCoreClock / 1000000); - - - while (!(USART2->ISR & UART_FLAG_TC) && !(USART3->ISR & UART_FLAG_TC) && ((DWT->CYCCNT - start_cycles) < wait_cycles)) { - - } - - //Handle any DMA data that has been received from daisy chain - try_process_routing(); // This try function is thread safe - - // Clear all pending IRQs for ADC conversions at the - // end of this ISR so that the system realigns the - // ADC conversions with the SYNC signal from the AMDC. - // - // For some reason, this only works if we call both of these: - NVIC_ClearPendingIRQ(EXTI15_10_IRQn); - __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_11); - NVIC_ClearPendingIRQ(EXTI15_10_IRQn); + adc_sample_1_5_daughtercards(new_data); + + bool u3 = false; + bool u2 = false; + uint8_t header = 0x90; + + if (active_sensor_mask & (1 << 0)) { + drv_uart_putc_fast(USART2, header); + u2 = true; + drv_uart_putc_fast(USART2, (uint8_t) (new_data[0] >> 8)); + } + if (active_sensor_mask & (1 << 4)) { + drv_uart_putc_fast(USART3, header); + u3 = true; + drv_uart_putc_fast(USART3, (uint8_t) (new_data[4] >> 8)); + } + if (u2) + drv_uart_putc_fast(USART2, (uint8_t) (new_data[0])); + if (u3) + drv_uart_putc_fast(USART3, (uint8_t) (new_data[4])); + } + + uint32_t start_cycles = DWT->CYCCNT; + + // Calculate 1 microseconds in CPU cycles (integer math safe) + uint32_t wait_cycles = (SystemCoreClock / 1000000); + + while (!(USART2->ISR & UART_FLAG_TC) && !(USART3->ISR & UART_FLAG_TC) + && ((DWT->CYCCNT - start_cycles) < wait_cycles)) { + } + + // Handle any DMA data that has been received from daisy chain + try_process_routing(); // This try function is thread safe + + // Clear all pending IRQs for ADC conversions at the + // end of this ISR so that the system realigns the + // ADC conversions with the SYNC signal from the AMDC. + // + // For some reason, this only works if we call both of these: + NVIC_ClearPendingIRQ(EXTI15_10_IRQn); + __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_11); + NVIC_ClearPendingIRQ(EXTI15_10_IRQn); } #else #error "Please define a target board (TARGET_AMDS or TARGET_2S)!" @@ -519,7 +520,7 @@ static void setup_pin_SYNC_ADC(void) #if defined(TARGET_AMDS) __HAL_RCC_GPIOA_CLK_ENABLE(); - __HAL_RCC_GPIOD_CLK_ENABLE(); + __HAL_RCC_GPIOD_CLK_ENABLE(); // Configure GPIO pin Output Level HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_RESET); @@ -534,38 +535,38 @@ static void setup_pin_SYNC_ADC(void) GPIO_InitStruct.Pin = GPIO_PIN_1; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; - HAL_GPIO_Init(GPIOD, &GPIO_InitStruct); + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + HAL_GPIO_Init(GPIOD, &GPIO_InitStruct); - // EXTI interrupt init - HAL_NVIC_SetPriority(EXTI3_IRQn, 10, 0); - HAL_NVIC_EnableIRQ(EXTI3_IRQn); + // EXTI interrupt init + HAL_NVIC_SetPriority(EXTI3_IRQn, 10, 0); + HAL_NVIC_EnableIRQ(EXTI3_IRQn); #elif defined(TARGET_2S) __HAL_RCC_GPIOB_CLK_ENABLE(); - __HAL_RCC_GPIOG_CLK_ENABLE(); + __HAL_RCC_GPIOG_CLK_ENABLE(); - // Configure GPIO pin Output Level - HAL_GPIO_WritePin(GPIOB, GPIO_PIN_11, GPIO_PIN_RESET); - HAL_GPIO_WritePin(GPIOG, GPIO_PIN_14, GPIO_PIN_SET); + // Configure GPIO pin Output Level + HAL_GPIO_WritePin(GPIOB, GPIO_PIN_11, GPIO_PIN_RESET); + HAL_GPIO_WritePin(GPIOG, GPIO_PIN_14, GPIO_PIN_SET); - // Configure GPIO pins - GPIO_InitStruct.Pin = GPIO_PIN_11; - GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; - HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + // Configure GPIO pins + GPIO_InitStruct.Pin = GPIO_PIN_11; + GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); - GPIO_InitStruct.Pin = GPIO_PIN_14; - GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; - HAL_GPIO_Init(GPIOG, &GPIO_InitStruct); + GPIO_InitStruct.Pin = GPIO_PIN_14; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + HAL_GPIO_Init(GPIOG, &GPIO_InitStruct); // EXTI interrupt init HAL_NVIC_SetPriority(EXTI15_10_IRQn, 10, 0); - HAL_NVIC_EnableIRQ(EXTI15_10_IRQn); + HAL_NVIC_EnableIRQ(EXTI15_10_IRQn); #else - #error "Please define a target board (TARGET_AMDS or TARGET_2S)!" +#error "Please define a target board (TARGET_AMDS or TARGET_2S)!" #endif } diff --git a/Mainboard/Firmware/mainboard/Core/Src/drv_gpio.c b/Mainboard/Firmware/mainboard/Core/Src/drv_gpio.c index 6e1ab95..d4a784e 100644 --- a/Mainboard/Firmware/mainboard/Core/Src/drv_gpio.c +++ b/Mainboard/Firmware/mainboard/Core/Src/drv_gpio.c @@ -34,8 +34,8 @@ static void MX_GPIO_Init(void) // Configure GPIO pin Output Level HAL_GPIO_WritePin(GPIOD, - GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 - | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7, + GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 + | GPIO_PIN_6 | GPIO_PIN_7, GPIO_PIN_RESET); // Configure GPIO pin Output Level @@ -80,8 +80,8 @@ static void MX_GPIO_Init(void) // Configure GPIO pins : PD8 PD9 PD10 PD11 // PD3 // PD4 PD5 PD6 PD7 - GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 - | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7; + GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 + | GPIO_PIN_6 | GPIO_PIN_7; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; diff --git a/Mainboard/Firmware/mainboard/Core/Src/drv_uart.c b/Mainboard/Firmware/mainboard/Core/Src/drv_uart.c index 2867915..8f8136b 100644 --- a/Mainboard/Firmware/mainboard/Core/Src/drv_uart.c +++ b/Mainboard/Firmware/mainboard/Core/Src/drv_uart.c @@ -29,65 +29,66 @@ uint8_t DAISY_RX2_Pool[AMDS_RX_BUF_SIZE]; volatile bool is_routing_active = false; #ifdef BENCHMARK_MODE - volatile uint8_t mock_dma_write_head = 0; - #define GET_W1() mock_dma_write_head - #define GET_W2() mock_dma_write_head +volatile uint8_t mock_dma_write_head = 0; +#define GET_W1() mock_dma_write_head +#define GET_W2() mock_dma_write_head #else - // NDTR counts down, so the write head is (SIZE - NDTR). - // Casting to uint8_t naturally handles the modulo wrap-around at 256. - // AMDS_RX_BUF_SIZE MUST BE 256 - #define GET_W1() (uint8_t)(AMDS_RX_BUF_SIZE - __HAL_DMA_GET_COUNTER(DAISY_RX1_UART.hdmarx)) - #define GET_W2() (uint8_t)(AMDS_RX_BUF_SIZE - __HAL_DMA_GET_COUNTER(DAISY_RX2_UART.hdmarx)) +// NDTR counts down, so the write head is (SIZE - NDTR). +// Casting to uint8_t naturally handles the modulo wrap-around at 256. +// AMDS_RX_BUF_SIZE MUST BE 256 +#define GET_W1() (uint8_t) (AMDS_RX_BUF_SIZE - __HAL_DMA_GET_COUNTER(DAISY_RX1_UART.hdmarx)) +#define GET_W2() (uint8_t) (AMDS_RX_BUF_SIZE - __HAL_DMA_GET_COUNTER(DAISY_RX2_UART.hdmarx)) #endif -bool drv_uart_has_dma_data(void) { - // Reading these 8-bit values is natively atomic, so it is safe to - // evaluate them even if an interrupt is modifying them in the background. - uint8_t w1 = GET_W1(); - uint8_t w2 = GET_W2(); +bool drv_uart_has_dma_data(void) +{ + // Reading these 8-bit values is natively atomic, so it is safe to + // evaluate them even if an interrupt is modifying them in the background. + uint8_t w1 = GET_W1(); + uint8_t w2 = GET_W2(); - return (tracker1.read_index != w1) || (tracker2.read_index != w2); + return (tracker1.read_index != w1) || (tracker2.read_index != w2); } -void process_routing(void) { +void process_routing(void) +{ // Load tracking state into local CPU registers - uint8_t r1 = tracker1.read_index; - uint8_t r2 = tracker2.read_index; - uint8_t s1 = tracker1.state; - uint8_t s2 = tracker2.state; + uint8_t r1 = tracker1.read_index; + uint8_t r2 = tracker2.read_index; + uint8_t s1 = tracker1.state; + uint8_t s2 = tracker2.state; - uint8_t w1 = GET_W1(); - uint8_t w2 = GET_W2(); + uint8_t w1 = GET_W1(); + uint8_t w2 = GET_W2(); // Process as long as either buffer has data - while ((r1 != w1) || (r2 != w2)) { + while ((r1 != w1) || (r2 != w2)) { // Calculate how many bytes are sitting unread in the DMA buffer - // Because everything is cast to uint8_t, this math safely handles + // Because everything is cast to uint8_t, this math safely handles // circular buffer wrap-around natively (e.g. w4=2, r4=254 -> avail=4) - uint8_t avail1 = (uint8_t)(w1 - r1); - uint8_t avail2 = (uint8_t)(w2 - r2); - + uint8_t avail1 = (uint8_t) (w1 - r1); + uint8_t avail2 = (uint8_t) (w2 - r2); - if (avail1 < 3 || avail2 < 3) { - // 1.3us timeout to let us receive enough data for dual-stream fast path - uint32_t start_cycles = DWT->CYCCNT; + if (avail1 < 3 || avail2 < 3) { + // 1.3us timeout to let us receive enough data for dual-stream fast path + uint32_t start_cycles = DWT->CYCCNT; - // Calculate 1.3 microseconds in CPU cycles (integer math safe) - uint32_t wait_cycles = (SystemCoreClock / 1000000) * 13 / 10; + // Calculate 1.3 microseconds in CPU cycles (integer math safe) + uint32_t wait_cycles = (SystemCoreClock / 1000000) * 13 / 10; - while ((avail1 >= 0 && avail1 <= 2) || (avail2 >= 0 && avail2 <= 2)) { - w1 = GET_W1(); - w2 = GET_W2(); + while ((avail1 >= 0 && avail1 <= 2) || (avail2 >= 0 && avail2 <= 2)) { + w1 = GET_W1(); + w2 = GET_W2(); - avail1 = (uint8_t)(w1 - r1); - avail2 = (uint8_t)(w2 - r2); + avail1 = (uint8_t) (w1 - r1); + avail2 = (uint8_t) (w2 - r2); - // Break if we reach the 2us timeout - if ((DWT->CYCCNT - start_cycles) > wait_cycles) { - break; - } - } - } + // Break if we reach the 2us timeout + if ((DWT->CYCCNT - start_cycles) > wait_cycles) { + break; + } + } + } // ===================================================================== // OPTIMIZATION 1: DUAL-STREAM FAST PATH (Perfect Interleaving) @@ -97,19 +98,19 @@ void process_routing(void) { while ((s1 == STATE_IDLE && avail1 >= 3) && (s2 == STATE_IDLE && avail2 >= 3)) { uint8_t h1 = DAISY_RX1_Pool[r1]; uint8_t h2 = DAISY_RX2_Pool[r2]; - + if (((h1 & 0xF0) == 0x90) && ((h2 & 0xF0) == 0x90)) { // Byte 1: Headers (Incremented) drv_uart_putc_fast(USART2, h1 + 4); drv_uart_putc_fast(USART3, h2 + 4); - + // Byte 2: MSB - drv_uart_putc_fast(USART3, DAISY_RX2_Pool[(uint8_t)(r2 + 1)]); - drv_uart_putc_fast(USART2, DAISY_RX1_Pool[(uint8_t)(r1 + 1)]); - + drv_uart_putc_fast(USART3, DAISY_RX2_Pool[(uint8_t) (r2 + 1)]); + drv_uart_putc_fast(USART2, DAISY_RX1_Pool[(uint8_t) (r1 + 1)]); + // Byte 3: LSB - drv_uart_putc_fast(USART2, DAISY_RX1_Pool[(uint8_t)(r1 + 2)]); - drv_uart_putc_fast(USART3, DAISY_RX2_Pool[(uint8_t)(r2 + 2)]); + drv_uart_putc_fast(USART2, DAISY_RX1_Pool[(uint8_t) (r1 + 2)]); + drv_uart_putc_fast(USART3, DAISY_RX2_Pool[(uint8_t) (r2 + 2)]); r1 += 3; r2 += 3; @@ -117,23 +118,23 @@ void process_routing(void) { avail2 -= 3; if (avail1 < 3 || avail2 < 3) { - uint32_t start_cycles = DWT->CYCCNT; + uint32_t start_cycles = DWT->CYCCNT; - // Calculate 3 microseconds in CPU cycles (integer math safe) - uint32_t wait_cycles = (SystemCoreClock / 1000000) * 3; + // Calculate 3 microseconds in CPU cycles (integer math safe) + uint32_t wait_cycles = (SystemCoreClock / 1000000) * 3; - while ((avail1 >= 0 && avail1 <= 2) || (avail2 >= 0 && avail2 <= 2)) { - w1 = GET_W1(); - w2 = GET_W2(); + while ((avail1 >= 0 && avail1 <= 2) || (avail2 >= 0 && avail2 <= 2)) { + w1 = GET_W1(); + w2 = GET_W2(); - avail1 = (uint8_t)(w1 - r1); - avail2 = (uint8_t)(w2 - r2); + avail1 = (uint8_t) (w1 - r1); + avail2 = (uint8_t) (w2 - r2); - // Break if we reach the 3us timeout - if ((DWT->CYCCNT - start_cycles) > wait_cycles) { - break; - } - } + // Break if we reach the 3us timeout + if ((DWT->CYCCNT - start_cycles) > wait_cycles) { + break; + } + } } } else { break; // Misaligned or corrupted header, break to let the slow-path handle it @@ -141,15 +142,15 @@ void process_routing(void) { } // ===================================================================== - // OPTIMIZATION 2: SINGLE-STREAM FAST PATHS + // OPTIMIZATION 2: SINGLE-STREAM FAST PATHS // ===================================================================== // If one UART receives data slightly faster than the other, process it. while (s1 == STATE_IDLE && avail1 >= 3) { uint8_t h1 = DAISY_RX1_Pool[r1]; if ((h1 & 0xF0) == 0x90) { drv_uart_putc_fast(USART2, h1 + 4); - drv_uart_putc_fast(USART2, DAISY_RX1_Pool[(uint8_t)(r1 + 1)]); - drv_uart_putc_fast(USART2, DAISY_RX1_Pool[(uint8_t)(r1 + 2)]); + drv_uart_putc_fast(USART2, DAISY_RX1_Pool[(uint8_t) (r1 + 1)]); + drv_uart_putc_fast(USART2, DAISY_RX1_Pool[(uint8_t) (r1 + 2)]); r1 += 3; avail1 -= 3; @@ -162,8 +163,8 @@ void process_routing(void) { uint8_t h2 = DAISY_RX2_Pool[r2]; if ((h2 & 0xF0) == 0x90) { drv_uart_putc_fast(USART3, h2 + 4); - drv_uart_putc_fast(USART3, DAISY_RX2_Pool[(uint8_t)(r2 + 1)]); - drv_uart_putc_fast(USART3, DAISY_RX2_Pool[(uint8_t)(r2 + 2)]); + drv_uart_putc_fast(USART3, DAISY_RX2_Pool[(uint8_t) (r2 + 1)]); + drv_uart_putc_fast(USART3, DAISY_RX2_Pool[(uint8_t) (r2 + 2)]); r2 += 3; avail2 -= 3; @@ -190,18 +191,18 @@ void process_routing(void) { } while (r2 != w2 && s2 != STATE_IDLE) { - uint8_t b2 = DAISY_RX2_Pool[r2++]; - if (s2 == STATE_GOT_HEADER) { - drv_uart_putc_fast(USART3, b2); - s2 = STATE_GOT_MSB; - } else { // STATE_GOT_MSB - drv_uart_putc_fast(USART3, b2); - s2 = STATE_IDLE; - } - } + uint8_t b2 = DAISY_RX2_Pool[r2++]; + if (s2 == STATE_GOT_HEADER) { + drv_uart_putc_fast(USART3, b2); + s2 = STATE_GOT_MSB; + } else { // STATE_GOT_MSB + drv_uart_putc_fast(USART3, b2); + s2 = STATE_IDLE; + } + } // Check if we caught up to our cached write pointers. - // If so, re-sample the DMA registers to see if new data arrived + // If so, re-sample the DMA registers to see if new data arrived // while we were actively processing the previous bytes. if ((r1 == w1) && (r2 == w2)) { w1 = GET_W1(); @@ -220,11 +221,8 @@ void process_routing(void) { void UART4_IRQHandler(void) { // Check for Parity, Overrun, Noise, or Frame errors - if (__HAL_UART_GET_FLAG(&DAISY_RX1_UART, UART_FLAG_PE) || - __HAL_UART_GET_FLAG(&DAISY_RX1_UART, UART_FLAG_ORE) || - __HAL_UART_GET_FLAG(&DAISY_RX1_UART, UART_FLAG_NE) || - __HAL_UART_GET_FLAG(&DAISY_RX1_UART, UART_FLAG_FE)) - { + if (__HAL_UART_GET_FLAG(&DAISY_RX1_UART, UART_FLAG_PE) || __HAL_UART_GET_FLAG(&DAISY_RX1_UART, UART_FLAG_ORE) + || __HAL_UART_GET_FLAG(&DAISY_RX1_UART, UART_FLAG_NE) || __HAL_UART_GET_FLAG(&DAISY_RX1_UART, UART_FLAG_FE)) { // 1. Clear the error flags (Added UART_CLEAR_PEF) __HAL_UART_CLEAR_IT(&DAISY_RX1_UART, UART_CLEAR_PEF | UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_FEF); @@ -246,22 +244,19 @@ void DMA1_Stream2_IRQHandler(void) void UART5_IRQHandler(void) { - // Check for Overrun, Noise, or Frame errors - if (__HAL_UART_GET_FLAG(&DAISY_RX2_UART, UART_FLAG_PE) || - __HAL_UART_GET_FLAG(&DAISY_RX2_UART, UART_FLAG_ORE) || - __HAL_UART_GET_FLAG(&DAISY_RX2_UART, UART_FLAG_NE) || - __HAL_UART_GET_FLAG(&DAISY_RX2_UART, UART_FLAG_FE)) - { - // 1. Clear the error flags - __HAL_UART_CLEAR_IT(&DAISY_RX2_UART, UART_CLEAR_PEF | UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_FEF); - - // 2. IMPORTANT: Re-enable DMA receiver request - // Sometimes HAL disables this bit (DMAR) on error. - SET_BIT(DAISY_RX2_UART.Instance->CR3, USART_CR3_DMAR); - - return; - } - HAL_UART_IRQHandler(&DAISY_RX2_UART); + // Check for Overrun, Noise, or Frame errors + if (__HAL_UART_GET_FLAG(&DAISY_RX2_UART, UART_FLAG_PE) || __HAL_UART_GET_FLAG(&DAISY_RX2_UART, UART_FLAG_ORE) + || __HAL_UART_GET_FLAG(&DAISY_RX2_UART, UART_FLAG_NE) || __HAL_UART_GET_FLAG(&DAISY_RX2_UART, UART_FLAG_FE)) { + // 1. Clear the error flags + __HAL_UART_CLEAR_IT(&DAISY_RX2_UART, UART_CLEAR_PEF | UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_FEF); + + // 2. IMPORTANT: Re-enable DMA receiver request + // Sometimes HAL disables this bit (DMAR) on error. + SET_BIT(DAISY_RX2_UART.Instance->CR3, USART_CR3_DMAR); + + return; + } + HAL_UART_IRQHandler(&DAISY_RX2_UART); } void DMA1_Stream0_IRQHandler(void) @@ -271,14 +266,11 @@ void DMA1_Stream0_IRQHandler(void) #elif defined(TARGET_2S) void USART6_IRQHandler(void) { - // Check for Parity, Overrun, Noise, or Frame errors - if (__HAL_UART_GET_FLAG(&DAISY_RX1_UART, UART_FLAG_PE) || - __HAL_UART_GET_FLAG(&DAISY_RX1_UART, UART_FLAG_ORE) || - __HAL_UART_GET_FLAG(&DAISY_RX1_UART, UART_FLAG_NE) || - __HAL_UART_GET_FLAG(&DAISY_RX1_UART, UART_FLAG_FE)) - { - - // 1. Clear the error flags + // Check for Parity, Overrun, Noise, or Frame errors + if (__HAL_UART_GET_FLAG(&DAISY_RX1_UART, UART_FLAG_PE) || __HAL_UART_GET_FLAG(&DAISY_RX1_UART, UART_FLAG_ORE) + || __HAL_UART_GET_FLAG(&DAISY_RX1_UART, UART_FLAG_NE) || __HAL_UART_GET_FLAG(&DAISY_RX1_UART, UART_FLAG_FE)) { + + // 1. Clear the error flags __HAL_UART_CLEAR_IT(&DAISY_RX1_UART, UART_CLEAR_PEF | UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_FEF); // 2. IMPORTANT: Re-enable DMA receiver request @@ -299,23 +291,20 @@ void DMA2_Stream2_IRQHandler(void) void USART1_IRQHandler(void) { - // Check for Overrun, Noise, or Frame errors - if (__HAL_UART_GET_FLAG(&DAISY_RX2_UART, UART_FLAG_PE) || - __HAL_UART_GET_FLAG(&DAISY_RX2_UART, UART_FLAG_ORE) || - __HAL_UART_GET_FLAG(&DAISY_RX2_UART, UART_FLAG_NE) || - __HAL_UART_GET_FLAG(&DAISY_RX2_UART, UART_FLAG_FE)) - { - - // 1. Clear the error flags - __HAL_UART_CLEAR_IT(&DAISY_RX2_UART, UART_CLEAR_PEF | UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_FEF); - - // 2. IMPORTANT: Re-enable DMA receiver request - // Sometimes HAL disables this bit (DMAR) on error. - SET_BIT(DAISY_RX2_UART.Instance->CR3, USART_CR3_DMAR); - - return; - } - HAL_UART_IRQHandler(&DAISY_RX2_UART); + // Check for Overrun, Noise, or Frame errors + if (__HAL_UART_GET_FLAG(&DAISY_RX2_UART, UART_FLAG_PE) || __HAL_UART_GET_FLAG(&DAISY_RX2_UART, UART_FLAG_ORE) + || __HAL_UART_GET_FLAG(&DAISY_RX2_UART, UART_FLAG_NE) || __HAL_UART_GET_FLAG(&DAISY_RX2_UART, UART_FLAG_FE)) { + + // 1. Clear the error flags + __HAL_UART_CLEAR_IT(&DAISY_RX2_UART, UART_CLEAR_PEF | UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_FEF); + + // 2. IMPORTANT: Re-enable DMA receiver request + // Sometimes HAL disables this bit (DMAR) on error. + SET_BIT(DAISY_RX2_UART.Instance->CR3, USART_CR3_DMAR); + + return; + } + HAL_UART_IRQHandler(&DAISY_RX2_UART); } void DMA2_Stream5_IRQHandler(void) @@ -323,14 +312,16 @@ void DMA2_Stream5_IRQHandler(void) HAL_DMA_IRQHandler(&hdma_uart1_rx); } #else - #error "Please define a target board (TARGET_AMDS or TARGET_2S)!" +#error "Please define a target board (TARGET_AMDS or TARGET_2S)!" #endif -void USART2_IRQHandler(void) { +void USART2_IRQHandler(void) +{ HAL_UART_IRQHandler(&huart2); } -void USART3_IRQHandler(void) { +void USART3_IRQHandler(void) +{ HAL_UART_IRQHandler(&huart3); } @@ -347,12 +338,12 @@ void drv_uart_init(void) __HAL_RCC_USART3_CONFIG(RCC_USART3CLKSOURCE_SYSCLK); #if defined(TARGET_AMDS) __HAL_RCC_UART4_CONFIG(RCC_UART4CLKSOURCE_SYSCLK); - __HAL_RCC_UART5_CONFIG(RCC_UART5CLKSOURCE_SYSCLK); + __HAL_RCC_UART5_CONFIG(RCC_UART5CLKSOURCE_SYSCLK); #elif defined(TARGET_2S) - __HAL_RCC_USART6_CONFIG(RCC_USART6CLKSOURCE_SYSCLK); - __HAL_RCC_USART1_CONFIG(RCC_USART1CLKSOURCE_SYSCLK); + __HAL_RCC_USART6_CONFIG(RCC_USART6CLKSOURCE_SYSCLK); + __HAL_RCC_USART1_CONFIG(RCC_USART1CLKSOURCE_SYSCLK); #else - #error "Please define a target board (TARGET_AMDS or TARGET_2S)!" +#error "Please define a target board (TARGET_AMDS or TARGET_2S)!" #endif MX_USART_UART_Init(&huart2, USART2); @@ -360,12 +351,12 @@ void drv_uart_init(void) #if defined(TARGET_AMDS) MX_USART_UART_Init(&DAISY_RX1_UART, UART4); - MX_USART_UART_Init(&DAISY_RX2_UART, UART5); + MX_USART_UART_Init(&DAISY_RX2_UART, UART5); #elif defined(TARGET_2S) MX_USART_UART_Init(&DAISY_RX1_UART, USART6); - MX_USART_UART_Init(&DAISY_RX2_UART, USART1); + MX_USART_UART_Init(&DAISY_RX2_UART, USART1); #else - #error "Please define a target board (TARGET_AMDS or TARGET_2S)!" +#error "Please define a target board (TARGET_AMDS or TARGET_2S)!" #endif } @@ -375,7 +366,7 @@ static void MX_USART_UART_Init(UART_HandleTypeDef *huart, USART_TypeDef *handle) // // Baud Rate: Each USART peripheral can be clocked from a variety of sources. // During uart_init() function, we set the clock tree mux such that all uart peripherals - // are now clocked by the system clock, which is configured to + // are now clocked by the system clock, which is configured to // 200 MHz via the PLL. // // If we configure our USART using oversampling of 8, we can get a baud @@ -393,11 +384,11 @@ static void MX_USART_UART_Init(UART_HandleTypeDef *huart, USART_TypeDef *handle) huart->Init.Parity = UART_PARITY_ODD; if (huart->Instance == UART4 || huart->Instance == USART6) { - huart->Init.Mode = UART_MODE_RX; + huart->Init.Mode = UART_MODE_RX; } else if (huart->Instance == UART5 || huart->Instance == USART1) { - huart->Init.Mode = UART_MODE_RX; + huart->Init.Mode = UART_MODE_RX; } else { - huart->Init.Mode = UART_MODE_TX; + huart->Init.Mode = UART_MODE_TX; } huart->Init.HwFlowCtl = UART_HWCONTROL_NONE; @@ -410,69 +401,68 @@ static void MX_USART_UART_Init(UART_HandleTypeDef *huart, USART_TypeDef *handle) } #if defined(TARGET_AMDS) - if (huart->Instance == UART4) { - NVIC_SetPriority(UART4_IRQn, 9); - HAL_NVIC_EnableIRQ(UART4_IRQn); + if (huart->Instance == UART4) { + NVIC_SetPriority(UART4_IRQn, 9); + HAL_NVIC_EnableIRQ(UART4_IRQn); - __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF); - __HAL_UART_FLUSH_DRREGISTER(huart); + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF); + __HAL_UART_FLUSH_DRREGISTER(huart); - if (HAL_UART_Receive_DMA(&DAISY_RX1_UART, DAISY_RX1_Pool, AMDS_RX_BUF_SIZE) != HAL_OK) { - PANIC; - } + if (HAL_UART_Receive_DMA(&DAISY_RX1_UART, DAISY_RX1_Pool, AMDS_RX_BUF_SIZE) != HAL_OK) { + PANIC; + } } - if (huart->Instance == UART5) { - NVIC_SetPriority(UART5_IRQn, 9); - HAL_NVIC_EnableIRQ(UART5_IRQn); + if (huart->Instance == UART5) { + NVIC_SetPriority(UART5_IRQn, 9); + HAL_NVIC_EnableIRQ(UART5_IRQn); - __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF); - __HAL_UART_FLUSH_DRREGISTER(huart); + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF); + __HAL_UART_FLUSH_DRREGISTER(huart); - if (HAL_UART_Receive_DMA(&DAISY_RX2_UART, DAISY_RX2_Pool, AMDS_RX_BUF_SIZE) != HAL_OK) { - PANIC; - } - } + if (HAL_UART_Receive_DMA(&DAISY_RX2_UART, DAISY_RX2_Pool, AMDS_RX_BUF_SIZE) != HAL_OK) { + PANIC; + } + } #elif defined(TARGET_2S) - if (huart->Instance == USART6) { - NVIC_SetPriority(USART6_IRQn, 9); - HAL_NVIC_EnableIRQ(USART6_IRQn); + if (huart->Instance == USART6) { + NVIC_SetPriority(USART6_IRQn, 9); + HAL_NVIC_EnableIRQ(USART6_IRQn); - __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF); - __HAL_UART_FLUSH_DRREGISTER(huart); + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF); + __HAL_UART_FLUSH_DRREGISTER(huart); - if (HAL_UART_Receive_DMA(&DAISY_RX1_UART, DAISY_RX1_Pool, AMDS_RX_BUF_SIZE) != HAL_OK) { - PANIC; - } + if (HAL_UART_Receive_DMA(&DAISY_RX1_UART, DAISY_RX1_Pool, AMDS_RX_BUF_SIZE) != HAL_OK) { + PANIC; + } } else if (huart->Instance == USART1) { - NVIC_SetPriority(USART1_IRQn, 9); - HAL_NVIC_EnableIRQ(USART1_IRQn); + NVIC_SetPriority(USART1_IRQn, 9); + HAL_NVIC_EnableIRQ(USART1_IRQn); - __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF); - __HAL_UART_FLUSH_DRREGISTER(huart); + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF); + __HAL_UART_FLUSH_DRREGISTER(huart); - if (HAL_UART_Receive_DMA(&DAISY_RX2_UART, DAISY_RX2_Pool, AMDS_RX_BUF_SIZE) != HAL_OK) { - PANIC; - } - } + if (HAL_UART_Receive_DMA(&DAISY_RX2_UART, DAISY_RX2_Pool, AMDS_RX_BUF_SIZE) != HAL_OK) { + PANIC; + } + } #else - #error "Please define a target board (TARGET_AMDS or TARGET_2S)!" +#error "Please define a target board (TARGET_AMDS or TARGET_2S)!" #endif - if (huart->Instance == USART2) { - NVIC_SetPriority(USART2_IRQn, 10); - HAL_NVIC_EnableIRQ(USART2_IRQn); + if (huart->Instance == USART2) { + NVIC_SetPriority(USART2_IRQn, 10); + HAL_NVIC_EnableIRQ(USART2_IRQn); - __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF); - __HAL_UART_FLUSH_DRREGISTER(huart); + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF); + __HAL_UART_FLUSH_DRREGISTER(huart); } else if (huart->Instance == USART3) { - NVIC_SetPriority(USART3_IRQn, 10); - HAL_NVIC_EnableIRQ(USART3_IRQn); + NVIC_SetPriority(USART3_IRQn, 10); + HAL_NVIC_EnableIRQ(USART3_IRQn); - __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF); - __HAL_UART_FLUSH_DRREGISTER(huart); - - } + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF); + __HAL_UART_FLUSH_DRREGISTER(huart); + } } void HAL_UART_MspInit(UART_HandleTypeDef *uartHandle) @@ -513,167 +503,167 @@ void HAL_UART_MspInit(UART_HandleTypeDef *uartHandle) } #if defined(TARGET_AMDS) else if (uartHandle->Instance == UART4) { - // USART3 clock enable - __HAL_RCC_UART4_CLK_ENABLE(); - __HAL_RCC_DMA1_CLK_ENABLE(); - - __HAL_RCC_GPIOD_CLK_ENABLE(); - // USART3 GPIO Configuration - // PD0 ------> UART4_RX - // PD1 ------> UART4_TX - GPIO_InitStruct.Pin = GPIO_PIN_0; - GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; - GPIO_InitStruct.Alternate = GPIO_AF8_UART4; - HAL_GPIO_Init(GPIOD, &GPIO_InitStruct); - - // DMA config - check your device's DMA request mapping table - // for the correct stream/channel for UART4_RX - hdma_uart4_rx.Instance = DMA1_Stream2; // verify in datasheet - hdma_uart4_rx.Init.Channel = DMA_CHANNEL_4; // HAL constant for your device - hdma_uart4_rx.Init.Direction = DMA_PERIPH_TO_MEMORY; - hdma_uart4_rx.Init.PeriphInc = DMA_PINC_DISABLE; // RDR address stays fixed - hdma_uart4_rx.Init.MemInc = DMA_MINC_ENABLE; // buffer pointer increments - hdma_uart4_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; - hdma_uart4_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; - hdma_uart4_rx.Init.Mode = DMA_CIRCULAR; // or DMA_CIRCULAR (see note below) - hdma_uart4_rx.Init.Priority = DMA_PRIORITY_HIGH; - hdma_uart4_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE; - - if (HAL_DMA_Init(&hdma_uart4_rx) != HAL_OK) { - PANIC; - } - - // This links the DMA handle to the UART handle - __HAL_LINKDMA(uartHandle, hdmarx, hdma_uart4_rx); - - // DMA stream IRQ - NVIC_SetPriority(DMA1_Stream2_IRQn, 6); // higher priority than UART - HAL_NVIC_EnableIRQ(DMA1_Stream2_IRQn); - } + // USART3 clock enable + __HAL_RCC_UART4_CLK_ENABLE(); + __HAL_RCC_DMA1_CLK_ENABLE(); + + __HAL_RCC_GPIOD_CLK_ENABLE(); + // USART3 GPIO Configuration + // PD0 ------> UART4_RX + // PD1 ------> UART4_TX + GPIO_InitStruct.Pin = GPIO_PIN_0; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF8_UART4; + HAL_GPIO_Init(GPIOD, &GPIO_InitStruct); + + // DMA config - check your device's DMA request mapping table + // for the correct stream/channel for UART4_RX + hdma_uart4_rx.Instance = DMA1_Stream2; // verify in datasheet + hdma_uart4_rx.Init.Channel = DMA_CHANNEL_4; // HAL constant for your device + hdma_uart4_rx.Init.Direction = DMA_PERIPH_TO_MEMORY; + hdma_uart4_rx.Init.PeriphInc = DMA_PINC_DISABLE; // RDR address stays fixed + hdma_uart4_rx.Init.MemInc = DMA_MINC_ENABLE; // buffer pointer increments + hdma_uart4_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; + hdma_uart4_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; + hdma_uart4_rx.Init.Mode = DMA_CIRCULAR; // or DMA_CIRCULAR (see note below) + hdma_uart4_rx.Init.Priority = DMA_PRIORITY_HIGH; + hdma_uart4_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE; + + if (HAL_DMA_Init(&hdma_uart4_rx) != HAL_OK) { + PANIC; + } + + // This links the DMA handle to the UART handle + __HAL_LINKDMA(uartHandle, hdmarx, hdma_uart4_rx); + + // DMA stream IRQ + NVIC_SetPriority(DMA1_Stream2_IRQn, 6); // higher priority than UART + HAL_NVIC_EnableIRQ(DMA1_Stream2_IRQn); + } else if (uartHandle->Instance == UART5) { - // USART3 clock enable - __HAL_RCC_UART5_CLK_ENABLE(); - __HAL_RCC_DMA1_CLK_ENABLE(); - - __HAL_RCC_GPIOD_CLK_ENABLE(); - // USART3 GPIO Configuration - // PD2 ------> UART5_RX - GPIO_InitStruct.Pin = GPIO_PIN_2; - GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; - GPIO_InitStruct.Alternate = GPIO_AF8_UART5; - HAL_GPIO_Init(GPIOD, &GPIO_InitStruct); - - // DMA config - check your device's DMA request mapping table - // for the correct stream/channel for UART5_RX - hdma_uart5_rx.Instance = DMA1_Stream0; // verify in datasheet - hdma_uart5_rx.Init.Channel = DMA_CHANNEL_4; // HAL constant for your device - hdma_uart5_rx.Init.Direction = DMA_PERIPH_TO_MEMORY; - hdma_uart5_rx.Init.PeriphInc = DMA_PINC_DISABLE; // RDR address stays fixed - hdma_uart5_rx.Init.MemInc = DMA_MINC_ENABLE; // buffer pointer increments - hdma_uart5_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; - hdma_uart5_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; - hdma_uart5_rx.Init.Mode = DMA_CIRCULAR; // or DMA_CIRCULAR (see note below) - hdma_uart5_rx.Init.Priority = DMA_PRIORITY_HIGH; - hdma_uart5_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE; - - if (HAL_DMA_Init(&hdma_uart5_rx) != HAL_OK) { - PANIC; - } - - // This links the DMA handle to the UART handle - __HAL_LINKDMA(uartHandle, hdmarx, hdma_uart5_rx); - - // DMA stream IRQ - NVIC_SetPriority(DMA1_Stream0_IRQn, 6); // higher priority than UART - HAL_NVIC_EnableIRQ(DMA1_Stream0_IRQn); - } + // USART3 clock enable + __HAL_RCC_UART5_CLK_ENABLE(); + __HAL_RCC_DMA1_CLK_ENABLE(); + + __HAL_RCC_GPIOD_CLK_ENABLE(); + // USART3 GPIO Configuration + // PD2 ------> UART5_RX + GPIO_InitStruct.Pin = GPIO_PIN_2; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF8_UART5; + HAL_GPIO_Init(GPIOD, &GPIO_InitStruct); + + // DMA config - check your device's DMA request mapping table + // for the correct stream/channel for UART5_RX + hdma_uart5_rx.Instance = DMA1_Stream0; // verify in datasheet + hdma_uart5_rx.Init.Channel = DMA_CHANNEL_4; // HAL constant for your device + hdma_uart5_rx.Init.Direction = DMA_PERIPH_TO_MEMORY; + hdma_uart5_rx.Init.PeriphInc = DMA_PINC_DISABLE; // RDR address stays fixed + hdma_uart5_rx.Init.MemInc = DMA_MINC_ENABLE; // buffer pointer increments + hdma_uart5_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; + hdma_uart5_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; + hdma_uart5_rx.Init.Mode = DMA_CIRCULAR; // or DMA_CIRCULAR (see note below) + hdma_uart5_rx.Init.Priority = DMA_PRIORITY_HIGH; + hdma_uart5_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE; + + if (HAL_DMA_Init(&hdma_uart5_rx) != HAL_OK) { + PANIC; + } + + // This links the DMA handle to the UART handle + __HAL_LINKDMA(uartHandle, hdmarx, hdma_uart5_rx); + + // DMA stream IRQ + NVIC_SetPriority(DMA1_Stream0_IRQn, 6); // higher priority than UART + HAL_NVIC_EnableIRQ(DMA1_Stream0_IRQn); + } #elif defined(TARGET_2S) else if (uartHandle->Instance == USART6) { - // USART6 clock enable - __HAL_RCC_USART6_CLK_ENABLE(); - __HAL_RCC_DMA2_CLK_ENABLE(); - - __HAL_RCC_GPIOG_CLK_ENABLE(); - // USART3 GPIO Configuration - // PG9 ------> UART4_RX - GPIO_InitStruct.Pin = GPIO_PIN_9; - GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; - GPIO_InitStruct.Alternate = GPIO_AF8_USART6; - HAL_GPIO_Init(GPIOG, &GPIO_InitStruct); - - // DMA config - check your device's DMA request mapping table - // for the correct stream/channel for USART6_RX pg 253 of reference manual - hdma_uart6_rx.Instance = DMA2_Stream2; // verify in reference manual - hdma_uart6_rx.Init.Channel = DMA_CHANNEL_5; // verify in reference manual - hdma_uart6_rx.Init.Direction = DMA_PERIPH_TO_MEMORY; - hdma_uart6_rx.Init.PeriphInc = DMA_PINC_DISABLE; // RDR address stays fixed - hdma_uart6_rx.Init.MemInc = DMA_MINC_ENABLE; // buffer pointer increments - hdma_uart6_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; - hdma_uart6_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; - hdma_uart6_rx.Init.Mode = DMA_CIRCULAR; // or DMA_CIRCULAR (see note below) - hdma_uart6_rx.Init.Priority = DMA_PRIORITY_HIGH; - hdma_uart6_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE; - - if (HAL_DMA_Init(&hdma_uart6_rx) != HAL_OK) { - PANIC; - } - - // This links the DMA handle to the UART handle - __HAL_LINKDMA(uartHandle, hdmarx, hdma_uart6_rx); - - // DMA stream IRQ - NVIC_SetPriority(DMA2_Stream2_IRQn, 6); // higher priority than UART - HAL_NVIC_EnableIRQ(DMA2_Stream2_IRQn); - } - - else if (uartHandle->Instance == USART1) { - // USART1 clock enable - __HAL_RCC_USART1_CLK_ENABLE(); - __HAL_RCC_DMA2_CLK_ENABLE(); - - __HAL_RCC_GPIOA_CLK_ENABLE(); - // USART1 GPIO Configuration - // PA10 ------> USART1_RX - GPIO_InitStruct.Pin = GPIO_PIN_10; - GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; - GPIO_InitStruct.Alternate = GPIO_AF7_USART1; - HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); - - // DMA config - check your device's DMA request mapping table - // for the correct stream/channel for USART1_RX pg 253 of reference manual - hdma_uart1_rx.Instance = DMA2_Stream5; // verify in reference manual - hdma_uart1_rx.Init.Channel = DMA_CHANNEL_4; // verify in reference manual - hdma_uart1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY; - hdma_uart1_rx.Init.PeriphInc = DMA_PINC_DISABLE; // RDR address stays fixed - hdma_uart1_rx.Init.MemInc = DMA_MINC_ENABLE; // buffer pointer increments - hdma_uart1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; - hdma_uart1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; - hdma_uart1_rx.Init.Mode = DMA_CIRCULAR; // or DMA_CIRCULAR (see note below) - hdma_uart1_rx.Init.Priority = DMA_PRIORITY_HIGH; - hdma_uart1_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE; - - if (HAL_DMA_Init(&hdma_uart1_rx) != HAL_OK) { - PANIC; - } - - // This links the DMA handle to the UART handle - __HAL_LINKDMA(uartHandle, hdmarx, hdma_uart1_rx); - - // DMA stream IRQ - NVIC_SetPriority(DMA2_Stream5_IRQn, 6); // higher priority than UART - HAL_NVIC_EnableIRQ(DMA2_Stream5_IRQn); - } + // USART6 clock enable + __HAL_RCC_USART6_CLK_ENABLE(); + __HAL_RCC_DMA2_CLK_ENABLE(); + + __HAL_RCC_GPIOG_CLK_ENABLE(); + // USART3 GPIO Configuration + // PG9 ------> UART4_RX + GPIO_InitStruct.Pin = GPIO_PIN_9; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF8_USART6; + HAL_GPIO_Init(GPIOG, &GPIO_InitStruct); + + // DMA config - check your device's DMA request mapping table + // for the correct stream/channel for USART6_RX pg 253 of reference manual + hdma_uart6_rx.Instance = DMA2_Stream2; // verify in reference manual + hdma_uart6_rx.Init.Channel = DMA_CHANNEL_5; // verify in reference manual + hdma_uart6_rx.Init.Direction = DMA_PERIPH_TO_MEMORY; + hdma_uart6_rx.Init.PeriphInc = DMA_PINC_DISABLE; // RDR address stays fixed + hdma_uart6_rx.Init.MemInc = DMA_MINC_ENABLE; // buffer pointer increments + hdma_uart6_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; + hdma_uart6_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; + hdma_uart6_rx.Init.Mode = DMA_CIRCULAR; // or DMA_CIRCULAR (see note below) + hdma_uart6_rx.Init.Priority = DMA_PRIORITY_HIGH; + hdma_uart6_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE; + + if (HAL_DMA_Init(&hdma_uart6_rx) != HAL_OK) { + PANIC; + } + + // This links the DMA handle to the UART handle + __HAL_LINKDMA(uartHandle, hdmarx, hdma_uart6_rx); + + // DMA stream IRQ + NVIC_SetPriority(DMA2_Stream2_IRQn, 6); // higher priority than UART + HAL_NVIC_EnableIRQ(DMA2_Stream2_IRQn); + } + + else if (uartHandle->Instance == USART1) { + // USART1 clock enable + __HAL_RCC_USART1_CLK_ENABLE(); + __HAL_RCC_DMA2_CLK_ENABLE(); + + __HAL_RCC_GPIOA_CLK_ENABLE(); + // USART1 GPIO Configuration + // PA10 ------> USART1_RX + GPIO_InitStruct.Pin = GPIO_PIN_10; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF7_USART1; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + // DMA config - check your device's DMA request mapping table + // for the correct stream/channel for USART1_RX pg 253 of reference manual + hdma_uart1_rx.Instance = DMA2_Stream5; // verify in reference manual + hdma_uart1_rx.Init.Channel = DMA_CHANNEL_4; // verify in reference manual + hdma_uart1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY; + hdma_uart1_rx.Init.PeriphInc = DMA_PINC_DISABLE; // RDR address stays fixed + hdma_uart1_rx.Init.MemInc = DMA_MINC_ENABLE; // buffer pointer increments + hdma_uart1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; + hdma_uart1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; + hdma_uart1_rx.Init.Mode = DMA_CIRCULAR; // or DMA_CIRCULAR (see note below) + hdma_uart1_rx.Init.Priority = DMA_PRIORITY_HIGH; + hdma_uart1_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE; + + if (HAL_DMA_Init(&hdma_uart1_rx) != HAL_OK) { + PANIC; + } + + // This links the DMA handle to the UART handle + __HAL_LINKDMA(uartHandle, hdmarx, hdma_uart1_rx); + + // DMA stream IRQ + NVIC_SetPriority(DMA2_Stream5_IRQn, 6); // higher priority than UART + HAL_NVIC_EnableIRQ(DMA2_Stream5_IRQn); + } #else - #error "Please define a target board (TARGET_AMDS or TARGET_2S)!" +#error "Please define a target board (TARGET_AMDS or TARGET_2S)!" #endif } @@ -703,48 +693,48 @@ void HAL_UART_MspDeInit(UART_HandleTypeDef *uartHandle) } #if defined(TARGET_AMDS) else if (uartHandle->Instance == UART4) { - /* Peripheral clock disable */ - __HAL_RCC_UART4_CLK_DISABLE(); + /* Peripheral clock disable */ + __HAL_RCC_UART4_CLK_DISABLE(); - /**USART3 GPIO Configuration - PD0 ------> UART4_RX - PD1 ------> UART4_TX - */ - HAL_GPIO_DeInit(GPIOD, GPIO_PIN_0); - } + /**USART3 GPIO Configuration + PD0 ------> UART4_RX + PD1 ------> UART4_TX + */ + HAL_GPIO_DeInit(GPIOD, GPIO_PIN_0); + } else if (uartHandle->Instance == UART5) { - /* Peripheral clock disable */ - __HAL_RCC_UART5_CLK_DISABLE(); - - /**USART3 GPIO Configuration - PD2 ------> UART5_RX - */ - HAL_GPIO_DeInit(GPIOD, GPIO_PIN_2); - } + /* Peripheral clock disable */ + __HAL_RCC_UART5_CLK_DISABLE(); + + /**USART3 GPIO Configuration + PD2 ------> UART5_RX + */ + HAL_GPIO_DeInit(GPIOD, GPIO_PIN_2); + } #elif defined(TARGET_2S) else if (uartHandle->Instance == USART6) { - /* Peripheral clock disable */ - __HAL_RCC_USART6_CLK_DISABLE(); - - /**USART3 GPIO Configuration - PG9 ------> USART6_RX - PG14 ------> USART6_TX - */ - HAL_GPIO_DeInit(GPIOG, GPIO_PIN_9 | GPIO_PIN_14); - } - - else if (uartHandle->Instance == USART1) { - /* Peripheral clock disable */ - __HAL_RCC_USART1_CLK_DISABLE(); - - /**USART3 GPIO Configuration - PA9 ------> UART5_TX - PA10 ------> UART5_RX - */ - HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9 | GPIO_PIN_10); - } + /* Peripheral clock disable */ + __HAL_RCC_USART6_CLK_DISABLE(); + + /**USART3 GPIO Configuration + PG9 ------> USART6_RX + PG14 ------> USART6_TX + */ + HAL_GPIO_DeInit(GPIOG, GPIO_PIN_9 | GPIO_PIN_14); + } + + else if (uartHandle->Instance == USART1) { + /* Peripheral clock disable */ + __HAL_RCC_USART1_CLK_DISABLE(); + + /**USART3 GPIO Configuration + PA9 ------> UART5_TX + PA10 ------> UART5_RX + */ + HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9 | GPIO_PIN_10); + } #else - #error "Please define a target board (TARGET_AMDS or TARGET_2S)!" +#error "Please define a target board (TARGET_AMDS or TARGET_2S)!" #endif } diff --git a/Mainboard/Firmware/mainboard/Core/Src/main.c b/Mainboard/Firmware/mainboard/Core/Src/main.c index bdf6ac4..eb7455c 100644 --- a/Mainboard/Firmware/mainboard/Core/Src/main.c +++ b/Mainboard/Firmware/mainboard/Core/Src/main.c @@ -29,10 +29,10 @@ int main(void) uint8_t led = 0; // Use DWT cycle counter instead of HAL_GetTick() - uint32_t ledDelta = DWT->CYCCNT; + uint32_t ledDelta = DWT->CYCCNT; - // Calculate how many CPU cycles are in 250ms. - uint32_t cyclesPer250ms = SystemCoreClock / 4; + // Calculate how many CPU cycles are in 250ms. + uint32_t cyclesPer250ms = SystemCoreClock / 4; // Disable the SysTick ISR // @@ -44,38 +44,38 @@ int main(void) SysTick->CTRL &= 0xFFFFFFFE; // Enable the Cortex-M7 DWT Cycle Counter for hardware delays - CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; - DWT->LAR = 0xC5ACCE55; - DWT->CYCCNT = 0; - DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; + CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; + DWT->LAR = 0xC5ACCE55; + DWT->CYCCNT = 0; + DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; - // Infinite loop (all real work is done in ISRs) + // Infinite loop (all real work is done in ISRs) while (1) { // Handle DMA data from UARTs and route to correct destination. // Only attempt to grab the lock and route data if there // is actually data waiting in the DMA buffers to help the // external IRQ retain higher priority access to process_routing - // IMPORTANT NOTE: the goal is to handle all data in the - // interrupts. This pathway to process_routing() is being provided - // as a fail safe. If it is regularly being used, consider this a - // warning sign of a broader system problem as it will cause slow - // link speeds. + // IMPORTANT NOTE: the goal is to handle all data in the + // interrupts. This pathway to process_routing() is being provided + // as a fail safe. If it is regularly being used, consider this a + // warning sign of a broader system problem as it will cause slow + // link speeds. if (drv_uart_has_dma_data()) - try_process_routing(); // This try function is thread safe + try_process_routing(); // This try function is thread safe // Handle LEDs using hardware cycle counts - if (DWT->CYCCNT - ledDelta >= cyclesPer250ms) { - ledDelta = DWT->CYCCNT; - drv_led_clear(); + if (DWT->CYCCNT - ledDelta >= cyclesPer250ms) { + ledDelta = DWT->CYCCNT; + drv_led_clear(); - drv_led_on(1 << led); - drv_led_display(); + drv_led_on(1 << led); + drv_led_display(); - if (++led >= DRV_LED_NUM_TOTAL) { - led = 0; - } - } + if (++led >= DRV_LED_NUM_TOTAL) { + led = 0; + } + } } }