Skip to content
Draft
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
45 changes: 18 additions & 27 deletions Mainboard/Firmware/motherboard_v1/Core/Inc/drv_uart.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,19 @@ void drv_uart_init(void);
extern UART_HandleTypeDef huart2;
extern UART_HandleTypeDef huart3;

// 16-byte accumulator
// Layout: [UART4 pkt0-3 | UART5 pkt0-3][UART4 pkt4-7 | UART5 pkt4-7]
extern volatile uint16_t latest_valid_amds_samples[2][8];
extern volatile bool amds_samples_ready[2];
extern volatile uint8_t uart4_amds_sample_count;
extern volatile uint8_t uart5_amds_sample_count;
extern UART_HandleTypeDef huart4;
extern UART_HandleTypeDef huart5;

extern DMA_HandleTypeDef hdma_usart2_tx;
extern DMA_HandleTypeDef hdma_usart3_tx;

extern DMA_HandleTypeDef hdma_uart4_rx;
extern DMA_HandleTypeDef hdma_uart5_rx;

typedef enum {
STATE_IDLE,
STATE_GOT_HEADER,
STATE_GOT_BYTE1
STATE_GOT_MSB
} rx_state_t;

typedef struct {
Expand All @@ -38,18 +39,19 @@ extern uart_rx_tracker_t tracker5;
extern uint8_t UART4_DMA_Pool[AMDS_RX_BUF_SIZE];
extern uint8_t UART5_DMA_Pool[AMDS_RX_BUF_SIZE];

// Define large buffers for outgoing data
#define TX_BUF_SIZE 512
extern uint8_t usart2_tx_ring[TX_BUF_SIZE];
extern uint8_t usart3_tx_ring[TX_BUF_SIZE];

extern uint32_t usart2_tx_write_idx;
extern uint32_t usart3_tx_write_idx;
extern volatile uint8_t uart2_dma_queue[AMDS_RX_BUF_SIZE];
extern volatile uint8_t uart3_dma_queue[AMDS_RX_BUF_SIZE];
extern volatile uint8_t uart2_dma_buffer[AMDS_RX_BUF_SIZE];
extern volatile uint8_t uart3_dma_buffer[AMDS_RX_BUF_SIZE];

// Queue tracking indices
extern volatile uint16_t u2_q_head;
extern volatile uint16_t u2_q_tail;
extern volatile uint16_t u3_q_head;
extern volatile uint16_t u3_q_tail;

void process_uart_fifo(uint8_t *pool, uart_rx_tracker_t *track, uint8_t uart_id);

void dma_send(uint8_t uart_id, uint8_t *data, uint8_t len);
void dma_queue(uint8_t uart_id, uint8_t *data, uint8_t len);

static inline void drv_uart_putc_fast(USART_TypeDef *uart, uint8_t data)
{
Expand All @@ -62,17 +64,6 @@ static inline void drv_uart_putc_fast(USART_TypeDef *uart, uint8_t data)
uart->TDR = data;
}

static inline void drv_uart_putc_dma(USART_TypeDef *uart, uint8_t data)
{
if (uart == USART2) {
usart2_tx_ring[usart2_tx_write_idx] = data;
usart2_tx_write_idx = (usart2_tx_write_idx + 1) % TX_BUF_SIZE;
} else if (uart == USART3) {
usart3_tx_ring[usart3_tx_write_idx] = data;
usart3_tx_write_idx = (usart3_tx_write_idx + 1) % TX_BUF_SIZE;
}
}

static inline void drv_uart_wait_TC(USART_TypeDef *uart)
{
// After done sending characters, must wait for TC flag!!
Expand Down
26 changes: 26 additions & 0 deletions Mainboard/Firmware/motherboard_v1/Core/Inc/tx.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,32 @@
#ifndef TX_H
#define TX_H

#include "adc.h"
#include "drv_uart.h"

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

#define NUM_SETS 3 // 0 = local data, 1 = AMDS 1, 2 = AMDS 2
#define PACKETS_PER_SET 8

typedef struct {
uint8_t header;
uint8_t msb;
uint8_t lsb;
} packet_t;

// Global state arrays
extern volatile packet_t tx_packets[NUM_SETS * PACKETS_PER_SET];
extern volatile bool packet_ready[NUM_SETS * PACKETS_PER_SET];
extern bool packet_sent[NUM_SETS * PACKETS_PER_SET];

// Flag set by EXTI Sync Interrupt
extern volatile bool sync_event_flag;

void process_transmissions(void);

void transmit_samples(void);

#endif // TX_H
55 changes: 38 additions & 17 deletions Mainboard/Firmware/motherboard_v1/Core/Src/adc.c
Original file line number Diff line number Diff line change
Expand Up @@ -179,26 +179,47 @@ static void adc_sample_all_daughtercards(uint16_t *sample_data_out)
// this ISR, all the motherboard ADCs should be sampled.
void EXTI3_IRQHandler(void)
{
// Perform the actual SPI transactions
// alert daisy chained AMDSs to begin converting
GPIO_TOGGLE_PIN(GPIOD, GPIO_PIN_1);
uint16_t new_data[8] = { 0 };
static uint8_t local_tx2[12] = {0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB};
static uint8_t local_tx3[12] = {0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB};
// Perform the actual SPI transactions
/*uint16_t new_data[8] = { 0 };
adc_sample_all_daughtercards(new_data);

// Copy data into write buffer destination
volatile uint16_t *dest = latest_valid_adc_data;

// Unrolled loop for speed
dest[0] = new_data[0];
dest[1] = new_data[1];
dest[2] = new_data[2];
dest[3] = new_data[3];
dest[4] = new_data[4];
dest[5] = new_data[5];
dest[6] = new_data[6];
dest[7] = new_data[7];

// Call the function in tx.c to transmit the sampled data back to the AMDC
transmit_samples();
// 3. Bypass the circular queue and write straight to local linear buffers
// We use static buffers so they persist in memory while the DMA sends them in the background
static uint8_t local_tx2[12];
static uint8_t local_tx3[12];
uint8_t idx = 0;

for (int i = 0; i < 4; i++) {
// Ultra-fast header generation (0x90, 0x91, 0x92, 0x93)
uint8_t header = 0x90 | i;

// Pack UART2 data (Channels 0-3)
local_tx2[idx] = header;
local_tx2[idx+1] = (uint8_t)(new_data[i] >> 8);
local_tx2[idx+2] = (uint8_t)(new_data[i] & 0xFF);

// Pack UART3 data (Channels 4-7)
local_tx3[idx] = header;
local_tx3[idx+1] = (uint8_t)(new_data[i + 4] >> 8);
local_tx3[idx+2] = (uint8_t)(new_data[i + 4] & 0xFF);

idx += 3;
}*/

// 4. Fire the DMA immediately, back-to-back!
// No waiting for the main loop. As soon as the CPU hits these lines, the bits hit the wire.
if (huart2.gState == HAL_UART_STATE_READY) {
HAL_UART_Transmit_DMA(&huart2, local_tx2, 12);
}
if (huart3.gState == HAL_UART_STATE_READY) {
HAL_UART_Transmit_DMA(&huart3, local_tx3, 12);
}

// sync_event_flag = true;

// Clear all pending IRQs for ADC conversions at the
// end of this ISR so that the system realigns the
Expand Down
177 changes: 60 additions & 117 deletions Mainboard/Firmware/motherboard_v1/Core/Src/drv_uart.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "drv_uart.h"
#include "tx.h"
#include "defines.h"
#include "drv_clock.h"
#include "platform.h"
Expand All @@ -9,38 +10,31 @@ static void MX_USART_UART_Init(UART_HandleTypeDef *huart, USART_TypeDef *handle)
UART_HandleTypeDef huart2;
UART_HandleTypeDef huart3;

static DMA_HandleTypeDef hdma_usart2_tx;
static DMA_HandleTypeDef hdma_usart3_tx;
DMA_HandleTypeDef hdma_usart2_tx;
DMA_HandleTypeDef hdma_usart3_tx;

static UART_HandleTypeDef huart4;
static UART_HandleTypeDef huart5;

static DMA_HandleTypeDef hdma_uart4_rx;
static DMA_HandleTypeDef hdma_uart5_rx;

uint8_t usart2_tx_ring[TX_BUF_SIZE];
uint8_t usart3_tx_ring[TX_BUF_SIZE];

uint32_t usart2_tx_write_idx = 0;
uint32_t usart3_tx_write_idx = 0;

// 3-byte packet buffers for each UART
#define PACKET_SIZE 3
#define PACKETS_PER_UART 4
#define TOTAL_PACKETS (PACKETS_PER_UART * 2) // 8 packets, 24 bytes total

//static uint8_t uart4_packet_count = 0;
//static uint8_t uart5_packet_count = 0;
volatile uint8_t uart4_amds_sample_count = 0;
volatile uint8_t uart5_amds_sample_count = 0;
UART_HandleTypeDef huart4;
UART_HandleTypeDef huart5;

DMA_HandleTypeDef hdma_uart4_rx;
DMA_HandleTypeDef hdma_uart5_rx;

uart_rx_tracker_t tracker4 = {0};
uart_rx_tracker_t tracker5 = {0};

uint8_t UART4_DMA_Pool[AMDS_RX_BUF_SIZE];
uint8_t UART5_DMA_Pool[AMDS_RX_BUF_SIZE];

volatile uint8_t uart2_dma_queue[AMDS_RX_BUF_SIZE];
volatile uint8_t uart3_dma_queue[AMDS_RX_BUF_SIZE];
volatile uint8_t uart2_dma_buffer[AMDS_RX_BUF_SIZE];
volatile uint8_t uart3_dma_buffer[AMDS_RX_BUF_SIZE];

volatile uint16_t u2_q_head = 0;
volatile uint16_t u2_q_tail = 0;
volatile uint16_t u3_q_head = 0;
volatile uint16_t u3_q_tail = 0;

void process_uart_fifo(uint8_t *pool, uart_rx_tracker_t *track, uint8_t uart_id) {
// Calculate current DMA write position (NDTR counts down)
UART_HandleTypeDef *huart;
Expand All @@ -52,105 +46,54 @@ void process_uart_fifo(uint8_t *pool, uart_rx_tracker_t *track, uint8_t uart_id)

uint32_t dma_write_ptr = AMDS_RX_BUF_SIZE - __HAL_DMA_GET_COUNTER(huart->hdmarx);

while (track->read_index != dma_write_ptr) {
uint8_t byte = pool[track->read_index];
track->read_index = (track->read_index + 1) % AMDS_RX_BUF_SIZE;

switch (track->state) {
case STATE_IDLE:
// Look for any valid header (0x90, 0x94, 0x98 ranges)
if ((byte & 0xF0) == 0x90) {
track->header = byte;
track->state = STATE_GOT_HEADER;
}
break;

case STATE_GOT_HEADER:
track->data[0] = byte;
track->state = STATE_GOT_BYTE1;
break;

case STATE_GOT_BYTE1:
track->data[1] = byte;

// Packet Complete: Reconstruct 16-bit value
uint16_t value = ((uint16_t)track->data[0] << 8) | track->data[1];

// 1. Calculate the absolute global channel index (e.g., 0 to 23)
uint8_t base_index = track->header & 0x03;
uint8_t sample_set = (track->header & 0x0C) >> 2;

// This gives a flat number from 0 up to 23 regardless of which UART it came from
uint8_t global_index = base_index + (uart_id == 5 ? 4 : 0) + (sample_set * 8);

// 2. Map the global index to your desired 2D array structure
// Assuming you want exactly 12 packets per bank (0-11 in bank 0, 12-23 in bank 1)
uint8_t bank = (global_index < 12) ? 0 : 1;
uint8_t local_index = (global_index < 12) ? global_index : (global_index - 12);

// 3. Store the value logically rather than physically
latest_valid_amds_samples[bank][local_index] = value;

// 4. Update the ready flag for the specific bank
amds_samples_ready[bank] = true;
while (track->read_index != dma_write_ptr) {
uint8_t byte = pool[track->read_index];
track->read_index = (track->read_index + 1) % AMDS_RX_BUF_SIZE;

switch (track->state) {
case STATE_IDLE:
// Look for any valid header (0x90, 0x94, 0x98 ranges)
if ((byte & 0xF0) == 0x90) {
track->header = byte;
track->state = STATE_GOT_HEADER;
}
break;

case STATE_GOT_HEADER:
track->data[0] = byte;
track->state = STATE_GOT_MSB; // Wait for the next loop iteration to get LSB!
break;

case STATE_GOT_MSB:
track->data[1] = byte;

uint8_t packet_to_send[3] = {track->header + 4, track->data[0], track->data[1]};
if (uart_id == 4) {
dma_queue(2, packet_to_send, 3);
} else {
dma_queue(3, packet_to_send, 3);
}

track->state = STATE_IDLE;
break;
}
}
}

track->state = STATE_IDLE;
break;
void dma_queue(uint8_t uart_id, uint8_t *data, uint8_t len) {
if (uart_id == 2) {
for (int i = 0; i < len; i++) {
uart2_dma_queue[u2_q_head] = data[i];
u2_q_head = (u2_q_head + 1) % AMDS_RX_BUF_SIZE;
}
} else if (uart_id == 3) {
for (int i = 0; i < len; i++) {
uart3_dma_queue[u3_q_head] = data[i];
u3_q_head = (u3_q_head + 1) % AMDS_RX_BUF_SIZE;
}
}
}

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
// if (huart->Instance == UART4) {
// if (uart4_packet_count < PACKETS_PER_UART) {
//
// uint8_t offset = uart4_packet_count;
//
// uint16_t value = ((uint16_t)UART4_RxBuf[1] << 8) | (uint16_t)UART4_RxBuf[2];
//
// latest_valid_amds_samples[uart4_amds_sample_count][offset] = value;
//
// uart4_packet_count++;
// }
//
// if (uart4_packet_count == PACKETS_PER_UART) {
// amds_samples_ready[uart4_amds_sample_count] = true;
// uart4_amds_sample_count++;
// uart4_packet_count = 0;
// }
//
// if (uart4_amds_sample_count == 2) {
// amds_samples_ready[uart4_amds_sample_count + 1] = true;
// uart4_amds_sample_count = 0;
// }
//// HAL_UART_Receive_DMA(huart, UART4_RxBuf, PACKET_SIZE);
// } else if (huart->Instance == UART5) {
// if (uart5_packet_count < PACKETS_PER_UART) {
//
// uint8_t offset = uart5_packet_count + 4;
//
// uint16_t value = ((uint16_t)UART5_RxBuf[1] << 8) | (uint16_t)UART5_RxBuf[2];
//
// latest_valid_amds_samples[uart5_amds_sample_count][offset] = value;
//
// uart5_packet_count++;
// }
//
// if (uart5_packet_count == PACKETS_PER_UART) {
// amds_samples_ready[uart5_amds_sample_count] = true;
// uart5_amds_sample_count++;
// uart5_packet_count = 0;
// }
//
// if (uart5_amds_sample_count == 2) {
// amds_samples_ready[uart5_amds_sample_count + 2] = true;
// uart5_amds_sample_count = 0;
// }
//// HAL_UART_Receive_DMA(huart, UART5_RxBuf, PACKET_SIZE);
// }
}

void UART4_IRQHandler(void)
{
// Check for Overrun, Noise, or Frame errors
Expand Down
Loading