Skip to content
Merged
Show file tree
Hide file tree
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
1 change: 0 additions & 1 deletion Mainboard/Firmware/mainboard/Core/Inc/adc.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,4 @@

void adc_init(void);


#endif // ADC_H
42 changes: 20 additions & 22 deletions Mainboard/Firmware/mainboard/Core/Inc/drv_uart.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
#define DRV_UART_H

// BENCHMARK MODE FLAG for DMA
//#define BENCHMARK_MODE
// #define BENCHMARK_MODE

#include "platform.h"
#include <stdint.h>
#include <stdbool.h>
#include <stdint.h>

void drv_uart_init(void);

Expand All @@ -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;
Expand Down Expand Up @@ -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;
}
Expand All @@ -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
}
}
Expand Down
Loading
Loading