single header for all drivers (#2335)

* drivers.h, claude's try

* include from root

* fix mac

* organize a lil more
This commit is contained in:
Adeeb Shihadeh
2026-02-15 16:33:58 -08:00
committed by GitHub
parent 46e02cc5b0
commit ad377ced81
30 changed files with 457 additions and 431 deletions

View File

@@ -6,7 +6,7 @@
#include "board/can.h"
#include "board/health.h"
#include "board/body/motor_control.h"
#include "board/drivers/can_common_declarations.h"
#include "board/drivers/drivers.h"
#include "opendbc/safety/declarations.h"
#define BODY_CAN_ADDR_MOTOR_SPEED 0x201U

View File

@@ -1,16 +1,15 @@
// ******************** Prototypes ********************
void print(const char *a){ UNUSED(a); }
void puth(uint8_t i){ UNUSED(i); }
void puth2(uint8_t i){ UNUSED(i); }
void puth4(uint8_t i){ UNUSED(i); }
void puth(unsigned int i){ UNUSED(i); }
void puth2(unsigned int i){ UNUSED(i); }
__attribute__((unused)) static void puth4(unsigned int i){ UNUSED(i); }
void hexdump(const void *a, int l){ UNUSED(a); UNUSED(l); }
typedef struct board board;
typedef struct harness_configuration harness_configuration;
void pwm_init(TIM_TypeDef *TIM, uint8_t channel);
void pwm_set(TIM_TypeDef *TIM, uint8_t channel, uint8_t percentage);
// No UART support in bootloader
typedef struct uart_ring {} uart_ring;
uart_ring uart_ring_som_debug;
typedef struct uart_ring uart_ring;
void uart_init(uart_ring *q, int baud) { UNUSED(q); UNUSED(baud); }
// ********************* Globals **********************

View File

@@ -1,4 +1,4 @@
#include "bootkick_declarations.h"
#include "board/drivers/drivers.h"
bool bootkick_reset_triggered = false;

View File

@@ -1,5 +0,0 @@
#pragma once
extern bool bootkick_reset_triggered;
void bootkick_tick(bool ignition, bool recent_heartbeat);

View File

@@ -1,4 +1,4 @@
#include "can_common_declarations.h"
#include "board/drivers/drivers.h"
uint32_t safety_tx_blocked = 0;
uint32_t safety_rx_invalid = 0;

View File

@@ -1,70 +0,0 @@
#pragma once
#include "board/can.h"
typedef struct {
volatile uint32_t w_ptr;
volatile uint32_t r_ptr;
uint32_t fifo_size;
CANPacket_t *elems;
} can_ring;
typedef struct {
uint8_t bus_lookup;
uint8_t can_num_lookup;
int8_t forwarding_bus;
uint32_t can_speed;
uint32_t can_data_speed;
bool canfd_auto;
bool canfd_enabled;
bool brs_enabled;
bool canfd_non_iso;
} bus_config_t;
extern uint32_t safety_tx_blocked;
extern uint32_t safety_rx_invalid;
extern uint32_t tx_buffer_overflow;
extern uint32_t rx_buffer_overflow;
extern can_health_t can_health[PANDA_CAN_CNT];
// Ignition detected from CAN meessages
extern bool ignition_can;
extern uint32_t ignition_can_cnt;
extern bool can_silent;
extern bool can_loopback;
// ******************* functions prototypes *********************
bool can_init(uint8_t can_number);
void process_can(uint8_t can_number);
// ********************* instantiate queues *********************
extern can_ring *can_queues[PANDA_CAN_CNT];
// helpers
#define WORD_TO_BYTE_ARRAY(dst8, src32) 0[dst8] = ((src32) & 0xFFU); 1[dst8] = (((src32) >> 8U) & 0xFFU); 2[dst8] = (((src32) >> 16U) & 0xFFU); 3[dst8] = (((src32) >> 24U) & 0xFFU)
#define BYTE_ARRAY_TO_WORD(dst32, src8) ((dst32) = 0[src8] | (1[src8] << 8U) | (2[src8] << 16U) | (3[src8] << 24U))
// ********************* interrupt safe queue *********************
bool can_pop(can_ring *q, CANPacket_t *elem);
bool can_push(can_ring *q, const CANPacket_t *elem);
uint32_t can_slots_empty(const can_ring *q);
extern bus_config_t bus_config[PANDA_CAN_CNT];
#define CANIF_FROM_CAN_NUM(num) (cans[num])
#define BUS_NUM_FROM_CAN_NUM(num) (bus_config[num].bus_lookup)
#define CAN_NUM_FROM_BUS_NUM(num) (bus_config[num].can_num_lookup)
void can_init_all(void);
void can_set_orientation(bool flipped);
#ifdef PANDA_JUNGLE
void can_set_forwarding(uint8_t from, uint8_t to);
#endif
void ignition_can_hook(CANPacket_t *to_push);
bool can_tx_check_min_slots_free(uint32_t min);
uint8_t calculate_checksum(const uint8_t *dat, uint32_t len);
void can_set_checksum(CANPacket_t *packet);
bool can_check_checksum(CANPacket_t *packet);
void can_send(CANPacket_t *to_push, uint8_t bus_number, bool skip_tx_hook);
bool is_speed_valid(uint32_t speed, const uint32_t *all_speeds, uint8_t len);

View File

@@ -1,4 +1,7 @@
#include "clock_source_declarations.h"
#include "board/drivers/drivers.h"
#define CLOCK_SOURCE_PERIOD_MS 50U
#define CLOCK_SOURCE_PULSE_LEN_MS 2U
void clock_source_set_timer_params(uint16_t param1, uint16_t param2) {
// Pulse length of each channel

View File

@@ -1,7 +0,0 @@
#pragma once
#define CLOCK_SOURCE_PERIOD_MS 50U
#define CLOCK_SOURCE_PULSE_LEN_MS 2U
void clock_source_set_timer_params(uint16_t param1, uint16_t param2);
void clock_source_init(bool enable_channel1);

287
board/drivers/drivers.h Normal file
View File

@@ -0,0 +1,287 @@
#pragma once
#include "board/can.h"
#include "board/health.h"
#include "board/crc.h"
#ifdef STM32H7
#include "board/stm32h7/lladc_declarations.h"
#endif
// ******************** bootkick ********************
extern bool bootkick_reset_triggered;
void bootkick_tick(bool ignition, bool recent_heartbeat);
// ******************** can_common ********************
typedef struct {
volatile uint32_t w_ptr;
volatile uint32_t r_ptr;
uint32_t fifo_size;
CANPacket_t *elems;
} can_ring;
typedef struct {
uint8_t bus_lookup;
uint8_t can_num_lookup;
int8_t forwarding_bus;
uint32_t can_speed;
uint32_t can_data_speed;
bool canfd_auto;
bool canfd_enabled;
bool brs_enabled;
bool canfd_non_iso;
} bus_config_t;
extern uint32_t safety_tx_blocked;
extern uint32_t safety_rx_invalid;
extern uint32_t tx_buffer_overflow;
extern uint32_t rx_buffer_overflow;
extern can_health_t can_health[PANDA_CAN_CNT];
// Ignition detected from CAN meessages
extern bool ignition_can;
extern uint32_t ignition_can_cnt;
extern bool can_silent;
extern bool can_loopback;
// ******************* functions prototypes *********************
bool can_init(uint8_t can_number);
void process_can(uint8_t can_number);
// ********************* instantiate queues *********************
extern can_ring *can_queues[PANDA_CAN_CNT];
// helpers
#define WORD_TO_BYTE_ARRAY(dst8, src32) 0[dst8] = ((src32) & 0xFFU); 1[dst8] = (((src32) >> 8U) & 0xFFU); 2[dst8] = (((src32) >> 16U) & 0xFFU); 3[dst8] = (((src32) >> 24U) & 0xFFU)
#define BYTE_ARRAY_TO_WORD(dst32, src8) ((dst32) = 0[src8] | (1[src8] << 8U) | (2[src8] << 16U) | (3[src8] << 24U))
// ********************* interrupt safe queue *********************
bool can_pop(can_ring *q, CANPacket_t *elem);
bool can_push(can_ring *q, const CANPacket_t *elem);
uint32_t can_slots_empty(const can_ring *q);
extern bus_config_t bus_config[PANDA_CAN_CNT];
#define CANIF_FROM_CAN_NUM(num) (cans[num])
#define BUS_NUM_FROM_CAN_NUM(num) (bus_config[num].bus_lookup)
#define CAN_NUM_FROM_BUS_NUM(num) (bus_config[num].can_num_lookup)
void can_init_all(void);
void can_set_orientation(bool flipped);
#ifdef PANDA_JUNGLE
void can_set_forwarding(uint8_t from, uint8_t to);
#endif
void ignition_can_hook(CANPacket_t *to_push);
bool can_tx_check_min_slots_free(uint32_t min);
uint8_t calculate_checksum(const uint8_t *dat, uint32_t len);
void can_set_checksum(CANPacket_t *packet);
bool can_check_checksum(CANPacket_t *packet);
void can_send(CANPacket_t *to_push, uint8_t bus_number, bool skip_tx_hook);
bool is_speed_valid(uint32_t speed, const uint32_t *all_speeds, uint8_t len);
// ******************** clock_source ********************
void clock_source_set_timer_params(uint16_t param1, uint16_t param2);
void clock_source_init(bool enable_channel1);
// ******************** fan ********************
struct fan_state_t {
uint16_t tach_counter;
uint16_t rpm;
uint8_t power;
float error_integral;
uint8_t cooldown_counter;
};
extern struct fan_state_t fan_state;
void fan_set_power(uint8_t percentage);
void llfan_init(void);
void fan_init(void);
// Call this at FAN_TICK_FREQ
void fan_tick(void);
// ******************** fdcan ********************
#ifdef STM32H7
typedef struct {
volatile uint32_t header[2];
volatile uint32_t data_word[CANPACKET_DATA_SIZE_MAX/4U];
} canfd_fifo;
extern FDCAN_GlobalTypeDef *cans[PANDA_CAN_CNT];
#define CAN_ACK_ERROR 3U
void can_clear_send(FDCAN_GlobalTypeDef *FDCANx, uint8_t can_number);
void update_can_health_pkt(uint8_t can_number, uint32_t ir_reg);
void process_can(uint8_t can_number);
void can_rx(uint8_t can_number);
bool can_init(uint8_t can_number);
// ******************** harness ********************
#define HARNESS_STATUS_NC 0U
#define HARNESS_STATUS_NORMAL 1U
#define HARNESS_STATUS_FLIPPED 2U
struct harness_t {
uint8_t status;
uint16_t sbu1_voltage_mV;
uint16_t sbu2_voltage_mV;
bool relay_driven;
bool sbu_adc_lock;
};
extern struct harness_t harness;
struct harness_configuration {
GPIO_TypeDef * const GPIO_SBU1;
GPIO_TypeDef * const GPIO_SBU2;
GPIO_TypeDef * const GPIO_relay_SBU1;
GPIO_TypeDef * const GPIO_relay_SBU2;
const uint8_t pin_SBU1;
const uint8_t pin_SBU2;
const uint8_t pin_relay_SBU1;
const uint8_t pin_relay_SBU2;
const adc_signal_t adc_signal_SBU1;
const adc_signal_t adc_signal_SBU2;
};
// The ignition relay is only used for testing purposes
void set_intercept_relay(bool intercept, bool ignition_relay);
bool harness_check_ignition(void);
void harness_tick(void);
void harness_init(void);
// ******************** interrupts ********************
typedef struct interrupt {
IRQn_Type irq_type;
void (*handler)(void);
uint32_t call_counter;
uint32_t call_rate;
uint32_t max_call_rate; // Call rate is defined as the amount of calls each second
uint32_t call_rate_fault;
} interrupt;
void interrupt_timer_init(void);
uint32_t microsecond_timer_get(void);
void unused_interrupt_handler(void);
extern interrupt interrupts[NUM_INTERRUPTS];
#define REGISTER_INTERRUPT(irq_num, func_ptr, call_rate_max, rate_fault) \
interrupts[irq_num].irq_type = (irq_num); \
interrupts[irq_num].handler = (func_ptr); \
interrupts[irq_num].call_counter = 0U; \
interrupts[irq_num].call_rate = 0U; \
interrupts[irq_num].max_call_rate = (call_rate_max); \
interrupts[irq_num].call_rate_fault = (rate_fault);
extern float interrupt_load;
void handle_interrupt(IRQn_Type irq_type);
// Every second
void interrupt_timer_handler(void);
void init_interrupts(bool check_rate_limit);
#endif // STM32H7
// ******************** registers ********************
// 10 bit hash with 23 as a prime
#define REGISTER_MAP_SIZE 0x3FFU
#define HASHING_PRIME 23U
// Do not put bits in the check mask that get changed by the hardware
void register_set(volatile uint32_t *addr, uint32_t val, uint32_t mask);
// Set individual bits. Also add them to the check_mask.
// Do not use this to change bits that get reset by the hardware
void register_set_bits(volatile uint32_t *addr, uint32_t val);
// Clear individual bits. Also add them to the check_mask.
// Do not use this to clear bits that get set by the hardware
void register_clear_bits(volatile uint32_t *addr, uint32_t val);
// To be called periodically
void check_registers(void);
void init_registers(void);
// ******************** simple_watchdog ********************
typedef struct simple_watchdog_state_t {
uint32_t fault;
uint32_t last_ts;
uint32_t threshold;
} simple_watchdog_state_t;
void simple_watchdog_kick(void);
void simple_watchdog_init(uint32_t fault, uint32_t threshold);
// ******************** spi ********************
// got max rate from hitting a non-existent endpoint
// in a tight loop, plus some buffer
#define SPI_IRQ_RATE 16000U
#define SPI_BUF_SIZE 4096U
extern uint8_t spi_buf_rx[SPI_BUF_SIZE];
extern uint8_t spi_buf_tx[SPI_BUF_SIZE];
extern uint16_t spi_error_count;
void can_tx_comms_resume_spi(void);
void spi_init(void);
void spi_rx_done(void);
void spi_tx_done(bool reset);
// ******************** uart ********************
#ifdef STM32H7
// ***************************** Definitions *****************************
#define FIFO_SIZE_INT 0x400U
typedef struct uart_ring {
volatile uint16_t w_ptr_tx;
volatile uint16_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;
uint8_t *elems_rx;
uint32_t rx_fifo_size;
USART_TypeDef *uart;
void (*callback)(struct uart_ring*);
bool overwrite;
} uart_ring;
// ***************************** Function prototypes *****************************
void debug_ring_callback(uart_ring *ring);
void uart_tx_ring(uart_ring *q);
uart_ring *get_ring_by_number(int a);
// ************************* Low-level buffer functions *************************
bool get_char(uart_ring *q, char *elem);
bool injectc(uart_ring *q, char elem);
bool put_char(uart_ring *q, char elem);
void clear_uart_buff(uart_ring *q);
// ************************ High-level debug functions **********************
void putch(const char a);
void print(const char *a);
void puthx(uint32_t i, uint8_t len);
void puth(unsigned int i);
#if defined(DEBUG_SPI) || defined(BOOTSTUB) || defined(DEBUG)
static void puth4(unsigned int i);
#endif
#if defined(DEBUG_SPI) || defined(DEBUG_USB) || defined(DEBUG_COMMS)
static void hexdump(const void *a, int l);
#endif
#endif // STM32H7
// ******************** usb ********************
void usb_init(void);
void refresh_can_tx_slots_available(void);
void can_tx_comms_resume_usb(void);

View File

@@ -1,4 +1,4 @@
#include "fan_declarations.h"
#include "board/drivers/drivers.h"
struct fan_state_t fan_state;

View File

@@ -1,16 +0,0 @@
#pragma once
struct fan_state_t {
uint16_t tach_counter;
uint16_t rpm;
uint8_t power;
float error_integral;
uint8_t cooldown_counter;
};
extern struct fan_state_t fan_state;
void fan_set_power(uint8_t percentage);
void llfan_init(void);
void fan_init(void);
// Call this at FAN_TICK_FREQ
void fan_tick(void);

View File

@@ -1,4 +1,4 @@
#include "fdcan_declarations.h"
#include "board/drivers/drivers.h"
FDCAN_GlobalTypeDef *cans[PANDA_CAN_CNT] = {FDCAN1, FDCAN2, FDCAN3};

View File

@@ -1,19 +0,0 @@
#pragma once
#include "board/can.h"
typedef struct {
volatile uint32_t header[2];
volatile uint32_t data_word[CANPACKET_DATA_SIZE_MAX/4U];
} canfd_fifo;
extern FDCAN_GlobalTypeDef *cans[PANDA_CAN_CNT];
#define CAN_ACK_ERROR 3U
void can_clear_send(FDCAN_GlobalTypeDef *FDCANx, uint8_t can_number);
void update_can_health_pkt(uint8_t can_number, uint32_t ir_reg);
void process_can(uint8_t can_number);
void can_rx(uint8_t can_number);
bool can_init(uint8_t can_number);

View File

@@ -1,4 +1,4 @@
#include "harness_declarations.h"
#include "board/drivers/drivers.h"
struct harness_t harness;

View File

@@ -1,33 +0,0 @@
#pragma once
#define HARNESS_STATUS_NC 0U
#define HARNESS_STATUS_NORMAL 1U
#define HARNESS_STATUS_FLIPPED 2U
struct harness_t {
uint8_t status;
uint16_t sbu1_voltage_mV;
uint16_t sbu2_voltage_mV;
bool relay_driven;
bool sbu_adc_lock;
};
extern struct harness_t harness;
struct harness_configuration {
GPIO_TypeDef * const GPIO_SBU1;
GPIO_TypeDef * const GPIO_SBU2;
GPIO_TypeDef * const GPIO_relay_SBU1;
GPIO_TypeDef * const GPIO_relay_SBU2;
const uint8_t pin_SBU1;
const uint8_t pin_SBU2;
const uint8_t pin_relay_SBU1;
const uint8_t pin_relay_SBU2;
const adc_signal_t adc_signal_SBU1;
const adc_signal_t adc_signal_SBU2;
};
// The ignition relay is only used for testing purposes
void set_intercept_relay(bool intercept, bool ignition_relay);
bool harness_check_ignition(void);
void harness_tick(void);
void harness_init(void);

View File

@@ -1,4 +1,4 @@
#include "interrupts_declarations.h"
#include "board/drivers/drivers.h"
void unused_interrupt_handler(void) {
// Something is wrong if this handler is called!

View File

@@ -1,31 +0,0 @@
#pragma once
typedef struct interrupt {
IRQn_Type irq_type;
void (*handler)(void);
uint32_t call_counter;
uint32_t call_rate;
uint32_t max_call_rate; // Call rate is defined as the amount of calls each second
uint32_t call_rate_fault;
} interrupt;
void interrupt_timer_init(void);
uint32_t microsecond_timer_get(void);
void unused_interrupt_handler(void);
extern interrupt interrupts[NUM_INTERRUPTS];
#define REGISTER_INTERRUPT(irq_num, func_ptr, call_rate_max, rate_fault) \
interrupts[irq_num].irq_type = (irq_num); \
interrupts[irq_num].handler = (func_ptr); \
interrupts[irq_num].call_counter = 0U; \
interrupts[irq_num].call_rate = 0U; \
interrupts[irq_num].max_call_rate = (call_rate_max); \
interrupts[irq_num].call_rate_fault = (rate_fault);
extern float interrupt_load;
void handle_interrupt(IRQn_Type irq_type);
// Every second
void interrupt_timer_handler(void);
void init_interrupts(bool check_rate_limit);

View File

@@ -1,4 +1,13 @@
#include "registers_declarations.h"
#include "board/drivers/drivers.h"
typedef struct reg {
volatile uint32_t *address;
uint32_t value;
uint32_t check_mask;
bool logged_fault;
} reg;
#define CHECK_COLLISION(hash, addr) (((uint32_t) register_map[hash].address != 0U) && (register_map[hash].address != (addr)))
static reg register_map[REGISTER_MAP_SIZE];

View File

@@ -1,25 +0,0 @@
#pragma once
typedef struct reg {
volatile uint32_t *address;
uint32_t value;
uint32_t check_mask;
bool logged_fault;
} reg;
// 10 bit hash with 23 as a prime
#define REGISTER_MAP_SIZE 0x3FFU
#define HASHING_PRIME 23U
#define CHECK_COLLISION(hash, addr) (((uint32_t) register_map[hash].address != 0U) && (register_map[hash].address != (addr)))
// Do not put bits in the check mask that get changed by the hardware
void register_set(volatile uint32_t *addr, uint32_t val, uint32_t mask);
// Set individual bits. Also add them to the check_mask.
// Do not use this to change bits that get reset by the hardware
void register_set_bits(volatile uint32_t *addr, uint32_t val);
// Clear individual bits. Also add them to the check_mask.
// Do not use this to clear bits that get set by the hardware
void register_clear_bits(volatile uint32_t *addr, uint32_t val);
// To be called periodically
void check_registers(void);
void init_registers(void);

View File

@@ -1,4 +1,4 @@
#include "simple_watchdog_declarations.h"
#include "board/drivers/drivers.h"
static simple_watchdog_state_t wd_state;

View File

@@ -1,10 +0,0 @@
#pragma once
typedef struct simple_watchdog_state_t {
uint32_t fault;
uint32_t last_ts;
uint32_t threshold;
} simple_watchdog_state_t;
void simple_watchdog_kick(void);
void simple_watchdog_init(uint32_t fault, uint32_t threshold);

View File

@@ -1,13 +1,43 @@
#pragma once
#include "board/drivers/spi_declarations.h"
#include "board/crc.h"
#include "board/drivers/drivers.h"
#define SPI_TIMEOUT_US 10000U
// H7 DMA2 located in D2 domain, so we need to use SRAM1/SRAM2
#ifdef STM32H7
__attribute__((section(".sram12"))) uint8_t spi_buf_rx[SPI_BUF_SIZE];
__attribute__((section(".sram12"))) uint8_t spi_buf_tx[SPI_BUF_SIZE];
#else
uint8_t spi_buf_rx[SPI_BUF_SIZE];
uint8_t spi_buf_tx[SPI_BUF_SIZE];
#endif
#define SPI_CHECKSUM_START 0xABU
#define SPI_SYNC_BYTE 0x5AU
#define SPI_HACK 0x79U
#define SPI_DACK 0x85U
#define SPI_NACK 0x1FU
// SPI states
enum {
SPI_STATE_HEADER,
SPI_STATE_HEADER_ACK,
SPI_STATE_HEADER_NACK,
SPI_STATE_DATA_RX,
SPI_STATE_DATA_RX_ACK,
SPI_STATE_DATA_TX
};
uint16_t spi_error_count = 0;
#define SPI_HEADER_SIZE 7U
// low level SPI prototypes
void llspi_init(void);
void llspi_mosi_dma(uint8_t *addr, int len);
void llspi_miso_dma(uint8_t *addr, int len);
static uint8_t spi_state = SPI_STATE_HEADER;
static uint16_t spi_data_len_mosi;
static bool spi_can_tx_ready = false;

View File

@@ -1,44 +0,0 @@
#pragma once
#include "board/crc.h"
#define SPI_TIMEOUT_US 10000U
// got max rate from hitting a non-existent endpoint
// in a tight loop, plus some buffer
#define SPI_IRQ_RATE 16000U
#define SPI_BUF_SIZE 4096U
// H7 DMA2 located in D2 domain, so we need to use SRAM1/SRAM2
__attribute__((section(".sram12"))) extern uint8_t spi_buf_rx[SPI_BUF_SIZE];
__attribute__((section(".sram12"))) extern uint8_t spi_buf_tx[SPI_BUF_SIZE];
#define SPI_CHECKSUM_START 0xABU
#define SPI_SYNC_BYTE 0x5AU
#define SPI_HACK 0x79U
#define SPI_DACK 0x85U
#define SPI_NACK 0x1FU
// SPI states
enum {
SPI_STATE_HEADER,
SPI_STATE_HEADER_ACK,
SPI_STATE_HEADER_NACK,
SPI_STATE_DATA_RX,
SPI_STATE_DATA_RX_ACK,
SPI_STATE_DATA_TX
};
extern uint16_t spi_error_count;
#define SPI_HEADER_SIZE 7U
// low level SPI prototypes
void llspi_init(void);
void llspi_mosi_dma(uint8_t *addr, int len);
void llspi_miso_dma(uint8_t *addr, int len);
void can_tx_comms_resume_spi(void);
void spi_init(void);
void spi_rx_done(void);
void spi_tx_done(bool reset);

View File

@@ -1,4 +1,4 @@
#include "uart_declarations.h"
#include "board/drivers/drivers.h"
// ***************************** Definitions *****************************

View File

@@ -1,39 +0,0 @@
#pragma once
// ***************************** Definitions *****************************
#define FIFO_SIZE_INT 0x400U
typedef struct uart_ring {
volatile uint16_t w_ptr_tx;
volatile uint16_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;
uint8_t *elems_rx;
uint32_t rx_fifo_size;
USART_TypeDef *uart;
void (*callback)(struct uart_ring*);
bool overwrite;
} uart_ring;
// ***************************** Function prototypes *****************************
void debug_ring_callback(uart_ring *ring);
void uart_tx_ring(uart_ring *q);
uart_ring *get_ring_by_number(int a);
// ************************* Low-level buffer functions *************************
bool get_char(uart_ring *q, char *elem);
bool injectc(uart_ring *q, char elem);
bool put_char(uart_ring *q, char elem);
void clear_uart_buff(uart_ring *q);
// ************************ High-level debug functions **********************
void putch(const char a);
void print(const char *a);
void puthx(uint32_t i, uint8_t len);
void puth(unsigned int i);
#if defined(DEBUG_SPI) || defined(BOOTSTUB) || defined(DEBUG)
static void puth4(unsigned int i);
#endif
#if defined(DEBUG_SPI) || defined(DEBUG_USB) || defined(DEBUG_COMMS)
static void hexdump(const void *a, int l);
#endif

View File

@@ -1,4 +1,108 @@
#include "usb_declarations.h"
#include "board/drivers/drivers.h"
// IRQs: OTG_FS
typedef union {
uint16_t w;
struct BW {
uint8_t msb;
uint8_t lsb;
}
bw;
} uint16_t_uint8_t;
typedef union _USB_Setup {
uint32_t d8[2];
struct _SetupPkt_Struc
{
uint8_t bmRequestType;
uint8_t bRequest;
uint16_t_uint8_t wValue;
uint16_t_uint8_t wIndex;
uint16_t_uint8_t wLength;
} b;
} USB_Setup_TypeDef;
// **** supporting defines ****
#define USB_REQ_GET_STATUS 0x00
#define USB_REQ_CLEAR_FEATURE 0x01
#define USB_REQ_SET_FEATURE 0x03
#define USB_REQ_SET_ADDRESS 0x05
#define USB_REQ_GET_DESCRIPTOR 0x06
#define USB_REQ_SET_DESCRIPTOR 0x07
#define USB_REQ_GET_CONFIGURATION 0x08
#define USB_REQ_SET_CONFIGURATION 0x09
#define USB_REQ_GET_INTERFACE 0x0A
#define USB_REQ_SET_INTERFACE 0x0B
#define USB_REQ_SYNCH_FRAME 0x0C
#define USB_DESC_TYPE_DEVICE 0x01
#define USB_DESC_TYPE_CONFIGURATION 0x02
#define USB_DESC_TYPE_STRING 0x03
#define USB_DESC_TYPE_INTERFACE 0x04
#define USB_DESC_TYPE_ENDPOINT 0x05
#define USB_DESC_TYPE_DEVICE_QUALIFIER 0x06
#define USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION 0x07
#define USB_DESC_TYPE_BINARY_OBJECT_STORE 0x0f
// offsets for configuration strings
#define STRING_OFFSET_LANGID 0x00
#define STRING_OFFSET_IMANUFACTURER 0x01
#define STRING_OFFSET_IPRODUCT 0x02
#define STRING_OFFSET_ISERIAL 0x03
#define STRING_OFFSET_ICONFIGURATION 0x04
#define STRING_OFFSET_IINTERFACE 0x05
// WebUSB requests
#define WEBUSB_REQ_GET_URL 0x02
// WebUSB types
#define WEBUSB_DESC_TYPE_URL 0x03
#define WEBUSB_URL_SCHEME_HTTPS 0x01
#define WEBUSB_URL_SCHEME_HTTP 0x00
// WinUSB requests
#define WINUSB_REQ_GET_COMPATID_DESCRIPTOR 0x04
#define WINUSB_REQ_GET_EXT_PROPS_OS 0x05
#define WINUSB_REQ_GET_DESCRIPTOR 0x07
#define STS_GOUT_NAK 1
#define STS_DATA_UPDT 2
#define STS_XFER_COMP 3
#define STS_SETUP_COMP 4
#define STS_SETUP_UPDT 6
// for the repeating interfaces
#define DSCR_INTERFACE_LEN 9
#define DSCR_ENDPOINT_LEN 7
#define DSCR_CONFIG_LEN 9
#define DSCR_DEVICE_LEN 18
// endpoint types
#define ENDPOINT_TYPE_CONTROL 0
#define ENDPOINT_TYPE_ISO 1
#define ENDPOINT_TYPE_BULK 2
#define ENDPOINT_TYPE_INT 3
// These are arbitrary values used in bRequest
#define MS_VENDOR_CODE 0x20
#define WEBUSB_VENDOR_CODE 0x30
// BOS constants
#define BINARY_OBJECT_STORE_DESCRIPTOR_LENGTH 0x05
#define BINARY_OBJECT_STORE_DESCRIPTOR 0x0F
#define WINUSB_PLATFORM_DESCRIPTOR_LENGTH 0x9E
// Convert machine byte order to USB byte order
#define TOUSBORDER(num)\
((num) & 0xFFU), (((uint16_t)(num) >> 8) & 0xFFU)
// take in string length and return the first 2 bytes of a string descriptor
#define STRING_DESCRIPTOR_HEADER(size)\
(((((size) * 2) + 2) & 0xFF) | 0x0300)
#define ENDPOINT_RCV 0x80
#define ENDPOINT_SND 0x00
static uint8_t response[USBPACKET_MAX_SIZE];

View File

@@ -1,111 +0,0 @@
#pragma once
// IRQs: OTG_FS
typedef union {
uint16_t w;
struct BW {
uint8_t msb;
uint8_t lsb;
}
bw;
} uint16_t_uint8_t;
typedef union _USB_Setup {
uint32_t d8[2];
struct _SetupPkt_Struc
{
uint8_t bmRequestType;
uint8_t bRequest;
uint16_t_uint8_t wValue;
uint16_t_uint8_t wIndex;
uint16_t_uint8_t wLength;
} b;
} USB_Setup_TypeDef;
void usb_init(void);
void refresh_can_tx_slots_available(void);
// **** supporting defines ****
#define USB_REQ_GET_STATUS 0x00
#define USB_REQ_CLEAR_FEATURE 0x01
#define USB_REQ_SET_FEATURE 0x03
#define USB_REQ_SET_ADDRESS 0x05
#define USB_REQ_GET_DESCRIPTOR 0x06
#define USB_REQ_SET_DESCRIPTOR 0x07
#define USB_REQ_GET_CONFIGURATION 0x08
#define USB_REQ_SET_CONFIGURATION 0x09
#define USB_REQ_GET_INTERFACE 0x0A
#define USB_REQ_SET_INTERFACE 0x0B
#define USB_REQ_SYNCH_FRAME 0x0C
#define USB_DESC_TYPE_DEVICE 0x01
#define USB_DESC_TYPE_CONFIGURATION 0x02
#define USB_DESC_TYPE_STRING 0x03
#define USB_DESC_TYPE_INTERFACE 0x04
#define USB_DESC_TYPE_ENDPOINT 0x05
#define USB_DESC_TYPE_DEVICE_QUALIFIER 0x06
#define USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION 0x07
#define USB_DESC_TYPE_BINARY_OBJECT_STORE 0x0f
// offsets for configuration strings
#define STRING_OFFSET_LANGID 0x00
#define STRING_OFFSET_IMANUFACTURER 0x01
#define STRING_OFFSET_IPRODUCT 0x02
#define STRING_OFFSET_ISERIAL 0x03
#define STRING_OFFSET_ICONFIGURATION 0x04
#define STRING_OFFSET_IINTERFACE 0x05
// WebUSB requests
#define WEBUSB_REQ_GET_URL 0x02
// WebUSB types
#define WEBUSB_DESC_TYPE_URL 0x03
#define WEBUSB_URL_SCHEME_HTTPS 0x01
#define WEBUSB_URL_SCHEME_HTTP 0x00
// WinUSB requests
#define WINUSB_REQ_GET_COMPATID_DESCRIPTOR 0x04
#define WINUSB_REQ_GET_EXT_PROPS_OS 0x05
#define WINUSB_REQ_GET_DESCRIPTOR 0x07
#define STS_GOUT_NAK 1
#define STS_DATA_UPDT 2
#define STS_XFER_COMP 3
#define STS_SETUP_COMP 4
#define STS_SETUP_UPDT 6
// for the repeating interfaces
#define DSCR_INTERFACE_LEN 9
#define DSCR_ENDPOINT_LEN 7
#define DSCR_CONFIG_LEN 9
#define DSCR_DEVICE_LEN 18
// endpoint types
#define ENDPOINT_TYPE_CONTROL 0
#define ENDPOINT_TYPE_ISO 1
#define ENDPOINT_TYPE_BULK 2
#define ENDPOINT_TYPE_INT 3
// These are arbitrary values used in bRequest
#define MS_VENDOR_CODE 0x20
#define WEBUSB_VENDOR_CODE 0x30
// BOS constants
#define BINARY_OBJECT_STORE_DESCRIPTOR_LENGTH 0x05
#define BINARY_OBJECT_STORE_DESCRIPTOR 0x0F
#define WINUSB_PLATFORM_DESCRIPTOR_LENGTH 0x9E
// Convert machine byte order to USB byte order
#define TOUSBORDER(num)\
((num) & 0xFFU), (((uint16_t)(num) >> 8) & 0xFFU)
// take in string length and return the first 2 bytes of a string descriptor
#define STRING_DESCRIPTOR_HEADER(size)\
(((((size) * 2) + 2) & 0xFF) | 0x0300)
#define ENDPOINT_RCV 0x80
#define ENDPOINT_SND 0x00
// ***************************** USB port *****************************
void can_tx_comms_resume_usb(void);

View File

@@ -5,8 +5,6 @@
uint32_t *prog_ptr = NULL;
bool unlocked = false;
void spi_init(void);
int comms_control_handler(ControlPacket_t *req, uint8_t *resp) {
int resp_len = 0;

View File

@@ -1,3 +1,5 @@
#pragma once
// When changing these structs, python/__init__.py needs to be kept up to date!
#define HEALTH_PACKET_VERSION 17

View File

@@ -59,6 +59,10 @@ separate IRQs for RX and TX.
#include "board/drivers/registers.h"
#include "board/drivers/interrupts.h"
#ifdef BOOTSTUB
uart_ring uart_ring_som_debug;
#endif
#include "board/drivers/gpio.h"
#include "board/stm32h7/peripherals.h"
#include "board/stm32h7/interrupt_handlers.h"