Skip to content
Open
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
2 changes: 1 addition & 1 deletion board/drivers/bootkick.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
bool bootkick_reset_triggered = false;

void bootkick_tick(bool ignition, bool recent_heartbeat) {
static uint16_t bootkick_last_serial_ptr = 0;
static uint32_t bootkick_last_serial_ptr = 0U;
static uint8_t waiting_to_boot_countdown = 0;
static uint8_t boot_reset_countdown = 0;
static uint8_t bootkick_harness_status_prev = HARNESS_STATUS_NC;
Expand Down
38 changes: 8 additions & 30 deletions board/drivers/can_common.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "can_common_declarations.h"
#include "ringbuffer.h"

uint32_t safety_tx_blocked = 0;
uint32_t safety_rx_invalid = 0;
Expand Down Expand Up @@ -43,38 +44,20 @@ can_ring *can_queues[CAN_QUEUES_ARRAY_SIZE] = {&can_tx1_q, &can_tx2_q, &can_tx3_

// ********************* interrupt safe queue *********************
bool can_pop(can_ring *q, CANPacket_t *elem) {
bool ret = 0;
bool ret;

ENTER_CRITICAL();
if (q->w_ptr != q->r_ptr) {
*elem = q->elems[q->r_ptr];
if ((q->r_ptr + 1U) == q->fifo_size) {
q->r_ptr = 0;
} else {
q->r_ptr += 1U;
}
ret = 1;
}
ret = ring_pop(&q->w_ptr, &q->r_ptr, q->fifo_size, (uint8_t *)q->elems, elem, sizeof(*elem));
EXIT_CRITICAL();

return ret;
}

bool can_push(can_ring *q, const CANPacket_t *elem) {
bool ret = false;
uint32_t next_w_ptr;
bool ret;

ENTER_CRITICAL();
if ((q->w_ptr + 1U) == q->fifo_size) {
next_w_ptr = 0;
} else {
next_w_ptr = q->w_ptr + 1U;
}
if (next_w_ptr != q->r_ptr) {
q->elems[q->w_ptr] = *elem;
q->w_ptr = next_w_ptr;
ret = true;
}
ret = ring_push(&q->w_ptr, &q->r_ptr, q->fifo_size, (uint8_t *)q->elems, elem, sizeof(*elem), false);
EXIT_CRITICAL();
if (!ret) {
#ifdef DEBUG
Expand All @@ -97,23 +80,18 @@ bool can_push(can_ring *q, const CANPacket_t *elem) {
}

uint32_t can_slots_empty(const can_ring *q) {
uint32_t ret = 0;
uint32_t ret;

ENTER_CRITICAL();
if (q->w_ptr >= q->r_ptr) {
ret = q->fifo_size - 1U - q->w_ptr + q->r_ptr;
} else {
ret = q->r_ptr - q->w_ptr - 1U;
}
ret = ring_slots_empty(&q->w_ptr, &q->r_ptr, q->fifo_size);
EXIT_CRITICAL();

return ret;
}

void can_clear(can_ring *q) {
ENTER_CRITICAL();
q->w_ptr = 0;
q->r_ptr = 0;
ring_clear(&q->w_ptr, &q->r_ptr);
EXIT_CRITICAL();
// handle TX buffer full with zero ECUs awake on the bus
refresh_can_tx_slots_available();
Expand Down
52 changes: 52 additions & 0 deletions board/drivers/ringbuffer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#pragma once

#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include <string.h>

static inline bool ring_push(volatile uint32_t *w_ptr, volatile uint32_t *r_ptr,
uint32_t fifo_size, uint8_t *elems,
const void *elem, size_t elem_size, bool overwrite) {
uint32_t next_w_ptr = (*w_ptr + 1U) % fifo_size;

if ((next_w_ptr == *r_ptr) && overwrite) {
*r_ptr = (*r_ptr + 1U) % fifo_size;
}

if (next_w_ptr != *r_ptr) {
(void)memcpy(&elems[*w_ptr * elem_size], elem, elem_size);
*w_ptr = next_w_ptr;
return true;
}

return false;
}

static inline bool ring_pop(volatile uint32_t *w_ptr, volatile uint32_t *r_ptr,
uint32_t fifo_size, uint8_t *elems,
void *elem, size_t elem_size) {
if (*w_ptr != *r_ptr) {
if (elem != NULL) {
(void)memcpy(elem, &elems[*r_ptr * elem_size], elem_size);
}
*r_ptr = (*r_ptr + 1U) % fifo_size;
return true;
}
return false;
}

static inline uint32_t ring_slots_empty(const volatile uint32_t *w_ptr, const volatile uint32_t *r_ptr,
uint32_t fifo_size) {
if (*w_ptr >= *r_ptr) {
return fifo_size - 1U - *w_ptr + *r_ptr;
} else {
return *r_ptr - *w_ptr - 1U;
}
}

static inline void ring_clear(volatile uint32_t *w_ptr, volatile uint32_t *r_ptr) {
*w_ptr = 0U;
*r_ptr = 0U;
}

48 changes: 14 additions & 34 deletions board/drivers/uart.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "uart_declarations.h"
#include "ringbuffer.h"

// ***************************** Definitions *****************************

Expand Down Expand Up @@ -46,65 +47,44 @@ uart_ring *get_ring_by_number(int a) {

// ************************* Low-level buffer functions *************************
bool get_char(uart_ring *q, char *elem) {
bool ret = false;
bool ret;

ENTER_CRITICAL();
if (q->w_ptr_rx != q->r_ptr_rx) {
if (elem != NULL) *elem = q->elems_rx[q->r_ptr_rx];
q->r_ptr_rx = (q->r_ptr_rx + 1U) % q->rx_fifo_size;
ret = true;
}
ret = ring_pop(&q->w_ptr_rx, &q->r_ptr_rx, q->rx_fifo_size, q->elems_rx, elem, sizeof(char));
EXIT_CRITICAL();

return ret;
}

bool injectc(uart_ring *q, char elem) {
int ret = false;
uint16_t next_w_ptr;
bool ret;

ENTER_CRITICAL();
next_w_ptr = (q->w_ptr_rx + 1U) % q->rx_fifo_size;

if ((next_w_ptr == q->r_ptr_rx) && q->overwrite) {
// overwrite mode: drop oldest byte
q->r_ptr_rx = (q->r_ptr_rx + 1U) % q->rx_fifo_size;
}

if (next_w_ptr != q->r_ptr_rx) {
q->elems_rx[q->w_ptr_rx] = elem;
q->w_ptr_rx = next_w_ptr;
ret = true;
}
ret = ring_push(&q->w_ptr_rx, &q->r_ptr_rx, q->rx_fifo_size, q->elems_rx, &elem, sizeof(char), q->overwrite);
EXIT_CRITICAL();

return ret;
}

bool put_char(uart_ring *q, char elem) {
bool ret = false;
uint16_t next_w_ptr;
bool ret;

ENTER_CRITICAL();
next_w_ptr = (q->w_ptr_tx + 1U) % q->tx_fifo_size;

if ((next_w_ptr == q->r_ptr_tx) && q->overwrite) {
// overwrite mode: drop oldest byte
q->r_ptr_tx = (q->r_ptr_tx + 1U) % q->tx_fifo_size;
}

if (next_w_ptr != q->r_ptr_tx) {
q->elems_tx[q->w_ptr_tx] = elem;
q->w_ptr_tx = next_w_ptr;
ret = true;
}
ret = ring_push(&q->w_ptr_tx, &q->r_ptr_tx, q->tx_fifo_size, q->elems_tx, &elem, sizeof(char), q->overwrite);
EXIT_CRITICAL();

uart_tx_ring(q);

return ret;
}

void clear_uart_buff(uart_ring *q) {
ENTER_CRITICAL();
ring_clear(&q->w_ptr_rx, &q->r_ptr_rx);
ring_clear(&q->w_ptr_tx, &q->r_ptr_tx);
EXIT_CRITICAL();
}

// ************************ High-level debug functions **********************
void putch(const char a) {
// misra-c2012-17.7: serial debug function, ok to ignore output
Expand Down
8 changes: 4 additions & 4 deletions board/drivers/uart_declarations.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
#define FIFO_SIZE_INT 0x400U

typedef struct uart_ring {
volatile uint16_t w_ptr_tx;
volatile uint16_t r_ptr_tx;
volatile uint32_t w_ptr_tx;
volatile uint32_t r_ptr_tx;
uint8_t *elems_tx;
uint32_t tx_fifo_size;
volatile uint16_t w_ptr_rx;
volatile uint16_t r_ptr_rx;
volatile uint32_t w_ptr_rx;
volatile uint32_t r_ptr_rx;
uint8_t *elems_rx;
uint32_t rx_fifo_size;
USART_TypeDef *uart;
Expand Down
29 changes: 9 additions & 20 deletions board/stm32h7/lluart.h
Original file line number Diff line number Diff line change
@@ -1,27 +1,14 @@
static void uart_rx_ring(uart_ring *q){
// Do not read out directly if DMA enabled
ENTER_CRITICAL();

// Read out RX buffer
uint8_t c = q->uart->RDR; // This read after reading SR clears a bunch of interrupts

uint16_t next_w_ptr = (q->w_ptr_rx + 1U) % q->rx_fifo_size;

if ((next_w_ptr == q->r_ptr_rx) && q->overwrite) {
// overwrite mode: drop oldest byte
q->r_ptr_rx = (q->r_ptr_rx + 1U) % q->rx_fifo_size;
}
ENTER_CRITICAL();
bool pushed = ring_push(&q->w_ptr_rx, &q->r_ptr_rx, q->rx_fifo_size, q->elems_rx, &c, sizeof(c), q->overwrite);
EXIT_CRITICAL();

// Do not overwrite buffer data
if (next_w_ptr != q->r_ptr_rx) {
q->elems_rx[q->w_ptr_rx] = c;
q->w_ptr_rx = next_w_ptr;
if (q->callback != NULL) {
q->callback(q);
}
if (pushed && (q->callback != NULL)) {
q->callback(q);
}

EXIT_CRITICAL();
}

void uart_tx_ring(uart_ring *q){
Expand All @@ -30,8 +17,10 @@ void uart_tx_ring(uart_ring *q){
if (q->w_ptr_tx != q->r_ptr_tx) {
// Only send if transmit register is empty (aka last byte has been sent)
if ((q->uart->ISR & USART_ISR_TXE_TXFNF) != 0U) {
q->uart->TDR = q->elems_tx[q->r_ptr_tx]; // This clears TXE
q->r_ptr_tx = (q->r_ptr_tx + 1U) % q->tx_fifo_size;
char c;
if (ring_pop(&q->w_ptr_tx, &q->r_ptr_tx, q->tx_fifo_size, q->elems_tx, &c, sizeof(c))) {
q->uart->TDR = (uint8_t)c; // This clears TXE
}
}

// Enable TXE interrupt if there is still data to be sent
Expand Down
Loading