Add full automotive RTOS project
Add kernel (Cortex-M0/M3/M4, Tricore, S32K, RISC-V ports), drivers, middleware (CAN stack, diagnostics, safety), applications, board support, build/test tooling, and documentation.
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
/**
|
||||
* @file board.h
|
||||
* @brief Custom ECU board definitions
|
||||
*/
|
||||
|
||||
#ifndef BOARD_H
|
||||
#define BOARD_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/* ============================================================================
|
||||
* Board Identification
|
||||
* ============================================================================ */
|
||||
#define BOARD_NAME "CustomECU-v1.0"
|
||||
#define BOARD_MANUFACTURER "Automotive RTOS Team"
|
||||
#define BOARD_VERSION "1.0"
|
||||
#define BOARD_MCU "Custom"
|
||||
|
||||
/* ============================================================================
|
||||
* Clock Configuration
|
||||
* ============================================================================ */
|
||||
#define SYSTEM_CLOCK 100000000U /* 100 MHz */
|
||||
#define PERIPHERAL_CLOCK 50000000U /* 50 MHz */
|
||||
#define TIMER_CLOCK 10000000U /* 10 MHz */
|
||||
|
||||
/* ============================================================================
|
||||
* LED Definitions
|
||||
* ============================================================================ */
|
||||
#define LED_COUNT 4
|
||||
#define LED_STATUS 0
|
||||
#define LED_ERROR 1
|
||||
#define LED_CAN_TX 2
|
||||
#define LED_CAN_RX 3
|
||||
|
||||
/* ============================================================================
|
||||
* Communication Interfaces
|
||||
* ============================================================================ */
|
||||
#define CAN_INTERFACE_COUNT 2
|
||||
#define UART_INTERFACE_COUNT 2
|
||||
#define SPI_INTERFACE_COUNT 1
|
||||
#define I2C_INTERFACE_COUNT 1
|
||||
|
||||
/* ============================================================================
|
||||
* Board Functions
|
||||
* ============================================================================ */
|
||||
void board_init(void);
|
||||
void board_clock_init(void);
|
||||
void board_gpio_init(void);
|
||||
void board_uart_init(void);
|
||||
void board_can_init(void);
|
||||
void board_spi_init(void);
|
||||
void board_i2c_init(void);
|
||||
void board_adc_init(void);
|
||||
void board_pwm_init(void);
|
||||
void board_watchdog_init(void);
|
||||
void board_watchdog_service(void);
|
||||
void board_led_on(uint8_t led);
|
||||
void board_led_off(uint8_t led);
|
||||
void board_led_toggle(uint8_t led);
|
||||
bool board_button_read(uint8_t button);
|
||||
void board_delay_ms(uint32_t ms);
|
||||
void board_delay_us(uint32_t us);
|
||||
float board_get_temperature(void);
|
||||
float board_get_voltage(void);
|
||||
|
||||
#endif /* BOARD_H */
|
||||
@@ -0,0 +1,292 @@
|
||||
/**
|
||||
* @file board_init.c
|
||||
* @brief Custom ECU board initialization
|
||||
*/
|
||||
|
||||
#include "board.h"
|
||||
#include "kernel.h"
|
||||
#include "gpio_driver.h"
|
||||
#include "uart_driver.h"
|
||||
#include "can_driver.h"
|
||||
#include "spi_driver.h"
|
||||
#include "i2c_driver.h"
|
||||
#include "adc_driver.h"
|
||||
#include "pwm_driver.h"
|
||||
#include <string.h>
|
||||
|
||||
static bool board_initialized = false;
|
||||
|
||||
/* Board-specific configuration */
|
||||
typedef struct {
|
||||
uint32_t can_baudrate;
|
||||
uint32_t uart_baudrate;
|
||||
uint8_t node_id;
|
||||
bool can_fd_enabled;
|
||||
} BoardConfig_t;
|
||||
|
||||
static const BoardConfig_t board_config = {
|
||||
.can_baudrate = 500000,
|
||||
.uart_baudrate = 115200,
|
||||
.node_id = 0x01,
|
||||
.can_fd_enabled = true
|
||||
};
|
||||
|
||||
/* ============================================================================
|
||||
* Board Initialization
|
||||
* ============================================================================ */
|
||||
void board_init(void) {
|
||||
if (board_initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Initialize clock */
|
||||
board_clock_init();
|
||||
|
||||
/* Initialize GPIO */
|
||||
board_gpio_init();
|
||||
|
||||
/* Initialize UART */
|
||||
board_uart_init();
|
||||
|
||||
/* Initialize CAN */
|
||||
board_can_init();
|
||||
|
||||
/* Initialize SPI */
|
||||
board_spi_init();
|
||||
|
||||
/* Initialize I2C */
|
||||
board_i2c_init();
|
||||
|
||||
/* Initialize ADC */
|
||||
board_adc_init();
|
||||
|
||||
/* Initialize PWM */
|
||||
board_pwm_init();
|
||||
|
||||
/* Initialize watchdog */
|
||||
board_watchdog_init();
|
||||
|
||||
board_initialized = true;
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
* Clock Initialization
|
||||
* ============================================================================ */
|
||||
void board_clock_init(void) {
|
||||
/* Custom clock initialization */
|
||||
/* This would be implemented for specific hardware */
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
* GPIO Initialization
|
||||
* ============================================================================ */
|
||||
void board_gpio_init(void) {
|
||||
/* Configure status LEDs */
|
||||
GpioPinConfig_t led_config = {
|
||||
.mode = GPIO_MODE_OUTPUT,
|
||||
.output_type = GPIO_OUTPUT_PUSH_PULL,
|
||||
.pull = GPIO_PULL_NONE,
|
||||
.speed = GPIO_SPEED_HIGH
|
||||
};
|
||||
|
||||
/* Configure each LED */
|
||||
for (int i = 0; i < LED_COUNT; i++) {
|
||||
led_config.port = 0;
|
||||
led_config.pin = i;
|
||||
gpio_init(&led_config);
|
||||
}
|
||||
|
||||
/* Turn off all LEDs */
|
||||
for (int i = 0; i < LED_COUNT; i++) {
|
||||
board_led_off(i);
|
||||
}
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
* UART Initialization
|
||||
* ============================================================================ */
|
||||
void board_uart_init(void) {
|
||||
/* Configure debug UART */
|
||||
UartConfig_t uart_config = {
|
||||
.baudrate = board_config.uart_baudrate,
|
||||
.data_bits = UART_DATA_BITS_8,
|
||||
.stop_bits = UART_STOP_BITS_1,
|
||||
.parity = UART_PARITY_NONE,
|
||||
.flow_control = UART_FLOW_CONTROL_NONE,
|
||||
.enable_rx = true,
|
||||
.enable_tx = true,
|
||||
.use_dma = false
|
||||
};
|
||||
|
||||
uart_init(0, &uart_config);
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
* CAN Initialization
|
||||
* ============================================================================ */
|
||||
void board_can_init(void) {
|
||||
/* Configure main CAN interface */
|
||||
CanConfig_t can_config = {
|
||||
.nominal_baudrate = board_config.can_baudrate,
|
||||
.data_baudrate = board_config.can_baudrate,
|
||||
.frame_type = CAN_FRAME_CLASSIC,
|
||||
.enable_fd = board_config.can_fd_enabled,
|
||||
.enable_automatic_retransmission = true,
|
||||
.filter_count = 0
|
||||
};
|
||||
|
||||
can_init(0, &can_config);
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
* SPI Initialization
|
||||
* ============================================================================ */
|
||||
void board_spi_init(void) {
|
||||
/* Configure SPI for external devices */
|
||||
SpiConfig_t spi_config = {
|
||||
.mode = SPI_MODE_0,
|
||||
.clock_speed = SPI_CLOCK_8MHZ,
|
||||
.data_order = SPI_DATA_ORDER_MSB_FIRST,
|
||||
.data_size = 8,
|
||||
.use_dma = true,
|
||||
.enable_hardware_cs = false,
|
||||
.cs_polarity = SPI_CS_ACTIVE_LOW,
|
||||
.cs_port = 0,
|
||||
.cs_pin = 10
|
||||
};
|
||||
|
||||
spi_init(0, &spi_config);
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
* I2C Initialization
|
||||
* ============================================================================ */
|
||||
void board_i2c_init(void) {
|
||||
/* Configure I2C for sensors */
|
||||
I2cConfig_t i2c_config = {
|
||||
.speed = I2C_SPEED_FAST,
|
||||
.addressing_mode = I2C_ADDRESSING_7BIT,
|
||||
.own_address = 0x50,
|
||||
.enable_general_call = false,
|
||||
.enable_clock_stretching = true,
|
||||
.use_dma = false
|
||||
};
|
||||
|
||||
i2c_init(0, &i2c_config);
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
* ADC Initialization
|
||||
* ============================================================================ */
|
||||
void board_adc_init(void) {
|
||||
/* Configure ADC for analog inputs */
|
||||
AdcConfig_t adc_config = {
|
||||
.resolution = ADC_RESOLUTION_12BIT,
|
||||
.mode = ADC_MODE_SCAN,
|
||||
.trigger_source = ADC_TRIGGER_TIMER,
|
||||
.reference = ADC_REFERENCE_VDD,
|
||||
.enable_dma = true,
|
||||
.conversion_frequency = 1000,
|
||||
.channel_count = 8,
|
||||
.channels = {
|
||||
{.channel = 0, .sampling_time = ADC_SAMPLING_28_5_CYCLES},
|
||||
{.channel = 1, .sampling_time = ADC_SAMPLING_28_5_CYCLES},
|
||||
{.channel = 2, .sampling_time = ADC_SAMPLING_28_5_CYCLES},
|
||||
{.channel = 3, .sampling_time = ADC_SAMPLING_28_5_CYCLES},
|
||||
{.channel = 4, .sampling_time = ADC_SAMPLING_28_5_CYCLES},
|
||||
{.channel = 5, .sampling_time = ADC_SAMPLING_28_5_CYCLES},
|
||||
{.channel = 6, .sampling_time = ADC_SAMPLING_28_5_CYCLES},
|
||||
{.channel = 7, .sampling_time = ADC_SAMPLING_28_5_CYCLES}
|
||||
}
|
||||
};
|
||||
|
||||
adc_init(0, &adc_config);
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
* PWM Initialization
|
||||
* ============================================================================ */
|
||||
void board_pwm_init(void) {
|
||||
/* Configure PWM outputs */
|
||||
PwmConfig_t pwm_config = {
|
||||
.frequency_hz = 1000,
|
||||
.alignment = PWM_ALIGNMENT_EDGE,
|
||||
.period_ticks = 1000,
|
||||
.prescaler = 100,
|
||||
.channel_count = 4,
|
||||
.channels = {
|
||||
{.channel = 0, .duty_cycle = 0},
|
||||
{.channel = 1, .duty_cycle = 0},
|
||||
{.channel = 2, .duty_cycle = 0},
|
||||
{.channel = 3, .duty_cycle = 0}
|
||||
},
|
||||
.enable_fault_protection = true,
|
||||
.fault_action = PWM_FAULT_DISABLE
|
||||
};
|
||||
|
||||
pwm_init(0, &pwm_config);
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
* Watchdog Initialization
|
||||
* ============================================================================ */
|
||||
void board_watchdog_init(void) {
|
||||
/* Custom watchdog initialization */
|
||||
}
|
||||
|
||||
void board_watchdog_service(void) {
|
||||
/* Custom watchdog service */
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
* LED Functions
|
||||
* ============================================================================ */
|
||||
void board_led_on(uint8_t led) {
|
||||
if (led < LED_COUNT) {
|
||||
gpio_write(0, led, true);
|
||||
}
|
||||
}
|
||||
|
||||
void board_led_off(uint8_t led) {
|
||||
if (led < LED_COUNT) {
|
||||
gpio_write(0, led, false);
|
||||
}
|
||||
}
|
||||
|
||||
void board_led_toggle(uint8_t led) {
|
||||
if (led < LED_COUNT) {
|
||||
gpio_toggle(0, led);
|
||||
}
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
* Button Functions
|
||||
* ============================================================================ */
|
||||
bool board_button_read(uint8_t button) {
|
||||
/* Custom button implementation */
|
||||
return false;
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
* Delay Functions
|
||||
* ============================================================================ */
|
||||
void board_delay_ms(uint32_t ms) {
|
||||
kernel_delay(ms);
|
||||
}
|
||||
|
||||
void board_delay_us(uint32_t us) {
|
||||
/* Custom microsecond delay */
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
* Sensor Functions
|
||||
* ============================================================================ */
|
||||
float board_get_temperature(void) {
|
||||
/* Custom temperature sensor reading */
|
||||
return 25.0f;
|
||||
}
|
||||
|
||||
float board_get_voltage(void) {
|
||||
/* Custom voltage reading */
|
||||
return 3.3f;
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
/**
|
||||
* @file linker_script.ld
|
||||
* @brief Linker script for Custom ECU
|
||||
*/
|
||||
|
||||
ENTRY(Reset_Handler)
|
||||
|
||||
MEMORY
|
||||
{
|
||||
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 2048K
|
||||
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 512K
|
||||
EEPROM (rw) : ORIGIN = 0x08080000, LENGTH = 16K
|
||||
}
|
||||
|
||||
_estack = ORIGIN(RAM) + LENGTH(RAM);
|
||||
_min_stack_size = 0x800;
|
||||
_min_heap_size = 0x400;
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.isr_vector :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
KEEP(*(.isr_vector))
|
||||
. = ALIGN(4);
|
||||
} >FLASH
|
||||
|
||||
.text :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(.text)
|
||||
*(.text*)
|
||||
KEEP(*(.init))
|
||||
KEEP(*(.fini))
|
||||
. = ALIGN(4);
|
||||
_etext = .;
|
||||
} >FLASH
|
||||
|
||||
.rodata :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(.rodata)
|
||||
*(.rodata*)
|
||||
. = ALIGN(4);
|
||||
} >FLASH
|
||||
|
||||
.ARM.extab :
|
||||
{
|
||||
*(.ARM.extab* .gnu.linkonce.armextab.*)
|
||||
} >FLASH
|
||||
|
||||
.ARM :
|
||||
{
|
||||
__exidx_start = .;
|
||||
*(.ARM.exidx*)
|
||||
__exidx_end = .;
|
||||
} >FLASH
|
||||
|
||||
.preinit_array :
|
||||
{
|
||||
PROVIDE_HIDDEN(__preinit_array_start = .);
|
||||
KEEP(*(.preinit_array*))
|
||||
PROVIDE_HIDDEN(__preinit_array_end = .);
|
||||
} >FLASH
|
||||
|
||||
.init_array :
|
||||
{
|
||||
PROVIDE_HIDDEN(__init_array_start = .);
|
||||
KEEP(*(SORT(.init_array.*)))
|
||||
KEEP(*(.init_array*))
|
||||
PROVIDE_HIDDEN(__init_array_end = .);
|
||||
} >FLASH
|
||||
|
||||
.fini_array :
|
||||
{
|
||||
PROVIDE_HIDDEN(__fini_array_start = .);
|
||||
KEEP(*(SORT(.fini_array.*)))
|
||||
KEEP(*(.fini_array*))
|
||||
PROVIDE_HIDDEN(__fini_array_end = .);
|
||||
} >FLASH
|
||||
|
||||
_sidata = LOADADDR(.data);
|
||||
|
||||
.data :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_sdata = .;
|
||||
*(.data)
|
||||
*(.data*)
|
||||
. = ALIGN(4);
|
||||
_edata = .;
|
||||
} >RAM AT> FLASH
|
||||
|
||||
.bss :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_sbss = .;
|
||||
__bss_start__ = _sbss;
|
||||
*(.bss)
|
||||
*(.bss*)
|
||||
*(COMMON)
|
||||
. = ALIGN(4);
|
||||
_ebss = .;
|
||||
__bss_end__ = _ebss;
|
||||
} >RAM
|
||||
|
||||
.eeprom :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(.eeprom)
|
||||
*(.eeprom*)
|
||||
. = ALIGN(4);
|
||||
} >EEPROM
|
||||
|
||||
._user_heap_stack :
|
||||
{
|
||||
. = ALIGN(8);
|
||||
PROVIDE(end = .);
|
||||
PROVIDE(_end = .);
|
||||
. = . + _min_heap_size;
|
||||
. = . + _min_stack_size;
|
||||
. = ALIGN(8);
|
||||
} >RAM
|
||||
|
||||
/DISCARD/ :
|
||||
{
|
||||
libc.a(*)
|
||||
libm.a(*)
|
||||
libgcc.a(*)
|
||||
}
|
||||
|
||||
.ARM.attributes 0 : { *(.ARM.attributes) }
|
||||
}
|
||||
@@ -0,0 +1,203 @@
|
||||
/**
|
||||
* @file board.h
|
||||
* @brief NXP S32K144 EVB board definitions
|
||||
*/
|
||||
|
||||
#ifndef BOARD_H
|
||||
#define BOARD_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "S32K144.h"
|
||||
|
||||
/* ============================================================================
|
||||
* Board Identification
|
||||
* ============================================================================ */
|
||||
#define BOARD_NAME "S32K144EVB-Q100"
|
||||
#define BOARD_MANUFACTURER "NXP Semiconductors"
|
||||
#define BOARD_VERSION "1.0"
|
||||
#define BOARD_MCU "S32K144"
|
||||
|
||||
/* ============================================================================
|
||||
* Clock Configuration
|
||||
* ============================================================================ */
|
||||
#define SOSC_FREQUENCY 8000000U /* System oscillator */
|
||||
#define SPLL_FREQUENCY 160000000U /* System PLL */
|
||||
#define FIRC_FREQUENCY 48000000U /* Fast IRC */
|
||||
#define SIRC_FREQUENCY 8000000U /* Slow IRC */
|
||||
|
||||
#define SYSTEM_CLOCK 160000000U /* 160 MHz */
|
||||
#define BUS_CLOCK 40000000U /* 40 MHz */
|
||||
#define FLASH_CLOCK 20000000U /* 20 MHz */
|
||||
|
||||
/* PLL Configuration */
|
||||
#define PLL_MULT 20
|
||||
#define PLL_DIV 1
|
||||
|
||||
/* ============================================================================
|
||||
* LED Definitions
|
||||
* ============================================================================ */
|
||||
#define LED_COUNT 3
|
||||
|
||||
#define LED_RED_PORT PTC
|
||||
#define LED_RED_PIN 0
|
||||
#define LED_RED_INDEX 0
|
||||
|
||||
#define LED_GREEN_PORT PTC
|
||||
#define LED_GREEN_PIN 1
|
||||
#define LED_GREEN_INDEX 1
|
||||
|
||||
#define LED_BLUE_PORT PTC
|
||||
#define LED_BLUE_PIN 2
|
||||
#define LED_BLUE_INDEX 2
|
||||
|
||||
/* LED Active Level */
|
||||
#define LED_ACTIVE_LEVEL 0 /* Active low */
|
||||
|
||||
/* ============================================================================
|
||||
* Button Definitions
|
||||
* ============================================================================ */
|
||||
#define BUTTON_COUNT 2
|
||||
|
||||
#define BUTTON1_PORT PTC
|
||||
#define BUTTON1_PIN 3
|
||||
#define BUTTON1_INDEX 0
|
||||
|
||||
#define BUTTON2_PORT PTC
|
||||
#define BUTTON2_PIN 4
|
||||
#define BUTTON2_INDEX 1
|
||||
|
||||
/* Button Active Level */
|
||||
#define BUTTON_ACTIVE_LEVEL 0 /* Active low */
|
||||
|
||||
/* ============================================================================
|
||||
* UART Definitions
|
||||
* ============================================================================ */
|
||||
#define UART0_INSTANCE 0
|
||||
#define UART0_BAUDRATE 115200
|
||||
#define UART0_TX_PORT PTA
|
||||
#define UART0_TX_PIN 2
|
||||
#define UART0_TX_MUX 2
|
||||
#define UART0_RX_PORT PTA
|
||||
#define UART0_RX_PIN 3
|
||||
#define UART0_RX_MUX 2
|
||||
|
||||
#define UART1_INSTANCE 1
|
||||
#define UART1_BAUDRATE 115200
|
||||
#define UART1_TX_PORT PTC
|
||||
#define UART1_TX_PIN 7
|
||||
#define UART1_TX_MUX 2
|
||||
#define UART1_RX_PORT PTC
|
||||
#define UART1_RX_PIN 6
|
||||
#define UART1_RX_MUX 2
|
||||
|
||||
/* ============================================================================
|
||||
* CAN Definitions
|
||||
* ============================================================================ */
|
||||
#define CAN0_INSTANCE 0
|
||||
#define CAN0_BAUDRATE 500000
|
||||
#define CAN0_TX_PORT PTE
|
||||
#define CAN0_TX_PIN 5
|
||||
#define CAN0_TX_MUX 5
|
||||
#define CAN0_RX_PORT PTE
|
||||
#define CAN0_RX_PIN 4
|
||||
#define CAN0_RX_MUX 5
|
||||
|
||||
#define CAN1_INSTANCE 1
|
||||
#define CAN1_BAUDRATE 500000
|
||||
#define CAN1_TX_PORT PTC
|
||||
#define CAN1_TX_PIN 17
|
||||
#define CAN1_TX_MUX 2
|
||||
#define CAN1_RX_PORT PTC
|
||||
#define CAN1_RX_PIN 16
|
||||
#define CAN1_RX_MUX 2
|
||||
|
||||
/* ============================================================================
|
||||
* SPI Definitions
|
||||
* ============================================================================ */
|
||||
#define SPI0_INSTANCE 0
|
||||
#define SPI0_SCK_PORT PTA
|
||||
#define SPI0_SCK_PIN 6
|
||||
#define SPI0_SCK_MUX 2
|
||||
#define SPI0_MISO_PORT PTA
|
||||
#define SPI0_MISO_PIN 7
|
||||
#define SPI0_MISO_MUX 2
|
||||
#define SPI0_MOSI_PORT PTA
|
||||
#define SPI0_MOSI_PIN 8
|
||||
#define SPI0_MOSI_MUX 2
|
||||
|
||||
/* ============================================================================
|
||||
* I2C Definitions
|
||||
* ============================================================================ */
|
||||
#define I2C0_INSTANCE 0
|
||||
#define I2C0_SCL_PORT PTA
|
||||
#define I2C0_SCL_PIN 9
|
||||
#define I2C0_SCL_MUX 3
|
||||
#define I2C0_SDA_PORT PTA
|
||||
#define I2C0_SDA_PIN 10
|
||||
#define I2C0_SDA_MUX 3
|
||||
|
||||
/* ============================================================================
|
||||
* ADC Definitions
|
||||
* ============================================================================ */
|
||||
#define ADC0_INSTANCE 0
|
||||
#define ADC0_CHANNEL_COUNT 8
|
||||
#define ADC0_CH0_PORT PTA
|
||||
#define ADC0_CH0_PIN 0
|
||||
#define ADC0_CH0_MUX 0
|
||||
#define ADC0_CH1_PORT PTA
|
||||
#define ADC0_CH1_PIN 1
|
||||
#define ADC0_CH1_MUX 0
|
||||
|
||||
/* ============================================================================
|
||||
* PWM Definitions
|
||||
* ============================================================================ */
|
||||
#define PWM_INSTANCE 0
|
||||
#define PWM_TIMER FTM0
|
||||
#define PWM_TIMER_CHANNEL_COUNT 4
|
||||
#define PWM_TIMER_FREQUENCY 10000
|
||||
#define PWM_TIMER_PRESCALER 4
|
||||
|
||||
#define PWM_CH0_PORT PTC
|
||||
#define PWM_CH0_PIN 1
|
||||
#define PWM_CH0_MUX 4
|
||||
#define PWM_CH1_PORT PTC
|
||||
#define PWM_CH1_PIN 2
|
||||
#define PWM_CH1_MUX 4
|
||||
#define PWM_CH2_PORT PTC
|
||||
#define PWM_CH2_PIN 3
|
||||
#define PWM_CH2_MUX 4
|
||||
#define PWM_CH3_PORT PTC
|
||||
#define PWM_CH3_PIN 4
|
||||
#define PWM_CH3_MUX 4
|
||||
|
||||
/* ============================================================================
|
||||
* Watchdog Configuration
|
||||
* ============================================================================ */
|
||||
#define WATCHDOG_TIMEOUT_MS 100
|
||||
#define WATCHDOG_WINDOW_MS 50
|
||||
|
||||
/* ============================================================================
|
||||
* Board Functions
|
||||
* ============================================================================ */
|
||||
void board_init(void);
|
||||
void board_clock_init(void);
|
||||
void board_gpio_init(void);
|
||||
void board_uart_init(void);
|
||||
void board_can_init(void);
|
||||
void board_spi_init(void);
|
||||
void board_i2c_init(void);
|
||||
void board_adc_init(void);
|
||||
void board_pwm_init(void);
|
||||
void board_watchdog_init(void);
|
||||
void board_watchdog_service(void);
|
||||
void board_led_on(uint8_t led);
|
||||
void board_led_off(uint8_t led);
|
||||
void board_led_toggle(uint8_t led);
|
||||
bool board_button_read(uint8_t button);
|
||||
void board_delay_ms(uint32_t ms);
|
||||
void board_delay_us(uint32_t us);
|
||||
float board_get_temperature(void);
|
||||
float board_get_voltage(void);
|
||||
|
||||
#endif /* BOARD_H */
|
||||
@@ -0,0 +1,371 @@
|
||||
/**
|
||||
* @file board_init.c
|
||||
* @brief NXP S32K144 EVB board initialization
|
||||
*/
|
||||
|
||||
#include "board.h"
|
||||
#include "kernel.h"
|
||||
#include "gpio_driver.h"
|
||||
#include "uart_driver.h"
|
||||
#include "can_driver.h"
|
||||
#include "spi_driver.h"
|
||||
#include "i2c_driver.h"
|
||||
#include "adc_driver.h"
|
||||
#include "pwm_driver.h"
|
||||
#include <string.h>
|
||||
|
||||
static bool board_initialized = false;
|
||||
|
||||
/* ============================================================================
|
||||
* Board Initialization
|
||||
* ============================================================================ */
|
||||
void board_init(void) {
|
||||
if (board_initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Initialize clock */
|
||||
board_clock_init();
|
||||
|
||||
/* Initialize GPIO */
|
||||
board_gpio_init();
|
||||
|
||||
/* Initialize UART */
|
||||
board_uart_init();
|
||||
|
||||
/* Initialize CAN */
|
||||
board_can_init();
|
||||
|
||||
/* Initialize SPI */
|
||||
board_spi_init();
|
||||
|
||||
/* Initialize I2C */
|
||||
board_i2c_init();
|
||||
|
||||
/* Initialize ADC */
|
||||
board_adc_init();
|
||||
|
||||
/* Initialize PWM */
|
||||
board_pwm_init();
|
||||
|
||||
/* Initialize watchdog */
|
||||
board_watchdog_init();
|
||||
|
||||
board_initialized = true;
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
* Clock Initialization
|
||||
* ============================================================================ */
|
||||
void board_clock_init(void) {
|
||||
/* Configure system PLL */
|
||||
SCG->SPLLCSR = 0; /* Reset SPLL */
|
||||
SCG->SPLLDIV = SCG_SPLLDIV_SPLLDIV1(1) | SCG_SPLLDIV_SPLLDIV2(1);
|
||||
SCG->SPLLCFG = SCG_SPLLCFG_MULT(20); /* 8MHz * 20 = 160MHz */
|
||||
|
||||
/* Enable SPLL */
|
||||
SCG->SPLLCSR |= SCG_SPLLCSR_SPLLEN_MASK;
|
||||
|
||||
/* Wait for PLL lock */
|
||||
while (!(SCG->SPLLCSR & SCG_SPLLCSR_SPLLVLD_MASK));
|
||||
|
||||
/* Switch to SPLL */
|
||||
SCG->RCCR = SCG_RCCR_DIVCORE(1) |
|
||||
SCG_RCCR_DIVBUS(4) | /* 160/4 = 40MHz */
|
||||
SCG_RCCR_DIVSLOW(8) | /* 160/8 = 20MHz */
|
||||
SCG_RCCR_SCS(6); /* SPLL */
|
||||
|
||||
/* Wait for clock switch */
|
||||
while ((SCG->CSR & SCG_CSR_SCS_MASK) != SCG_CSR_SCS(6));
|
||||
|
||||
/* Update SystemCoreClock */
|
||||
SystemCoreClock = SYSTEM_CLOCK;
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
* GPIO Initialization
|
||||
* ============================================================================ */
|
||||
void board_gpio_init(void) {
|
||||
/* Enable GPIO clocks */
|
||||
PCC->PCCn[PCC_PORTA_INDEX] |= PCC_PCCn_CGC_MASK;
|
||||
PCC->PCCn[PCC_PORTB_INDEX] |= PCC_PCCn_CGC_MASK;
|
||||
PCC->PCCn[PCC_PORTC_INDEX] |= PCC_PCCn_CGC_MASK;
|
||||
PCC->PCCn[PCC_PORTD_INDEX] |= PCC_PCCn_CGC_MASK;
|
||||
PCC->PCCn[PCC_PORTE_INDEX] |= PCC_PCCn_CGC_MASK;
|
||||
|
||||
/* Configure LEDs */
|
||||
GpioPinConfig_t led_config = {
|
||||
.mode = GPIO_MODE_OUTPUT,
|
||||
.output_type = GPIO_OUTPUT_PUSH_PULL,
|
||||
.pull = GPIO_PULL_NONE,
|
||||
.speed = GPIO_SPEED_HIGH
|
||||
};
|
||||
|
||||
led_config.port = 2; /* PTC */
|
||||
led_config.pin = 0;
|
||||
gpio_init(&led_config);
|
||||
|
||||
led_config.pin = 1;
|
||||
gpio_init(&led_config);
|
||||
|
||||
led_config.pin = 2;
|
||||
gpio_init(&led_config);
|
||||
|
||||
/* Configure buttons */
|
||||
GpioPinConfig_t button_config = {
|
||||
.port = 2, /* PTC */
|
||||
.pin = 3,
|
||||
.mode = GPIO_MODE_INPUT,
|
||||
.pull = GPIO_PULL_UP
|
||||
};
|
||||
gpio_init(&button_config);
|
||||
|
||||
button_config.pin = 4;
|
||||
gpio_init(&button_config);
|
||||
|
||||
/* Turn off all LEDs */
|
||||
board_led_off(0);
|
||||
board_led_off(1);
|
||||
board_led_off(2);
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
* UART Initialization
|
||||
* ============================================================================ */
|
||||
void board_uart_init(void) {
|
||||
/* Configure UART0 */
|
||||
UartConfig_t uart_config = {
|
||||
.baudrate = UART0_BAUDRATE,
|
||||
.data_bits = UART_DATA_BITS_8,
|
||||
.stop_bits = UART_STOP_BITS_1,
|
||||
.parity = UART_PARITY_NONE,
|
||||
.flow_control = UART_FLOW_CONTROL_NONE,
|
||||
.enable_rx = true,
|
||||
.enable_tx = true,
|
||||
.use_dma = false
|
||||
};
|
||||
|
||||
uart_init(UART0_INSTANCE, &uart_config);
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
* CAN Initialization
|
||||
* ============================================================================ */
|
||||
void board_can_init(void) {
|
||||
/* Configure CAN0 */
|
||||
CanConfig_t can_config = {
|
||||
.nominal_baudrate = CAN0_BAUDRATE,
|
||||
.data_baudrate = CAN0_BAUDRATE,
|
||||
.frame_type = CAN_FRAME_CLASSIC,
|
||||
.enable_fd = true, /* S32K144 supports CAN FD */
|
||||
.enable_automatic_retransmission = true,
|
||||
.filter_count = 0
|
||||
};
|
||||
|
||||
can_init(CAN0_INSTANCE, &can_config);
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
* SPI Initialization
|
||||
* ============================================================================ */
|
||||
void board_spi_init(void) {
|
||||
/* Configure SPI0 */
|
||||
SpiConfig_t spi_config = {
|
||||
.mode = SPI_MODE_0,
|
||||
.clock_speed = SPI_CLOCK_8MHZ,
|
||||
.data_order = SPI_DATA_ORDER_MSB_FIRST,
|
||||
.data_size = 8,
|
||||
.use_dma = false,
|
||||
.enable_hardware_cs = false,
|
||||
.cs_polarity = SPI_CS_ACTIVE_LOW,
|
||||
.cs_port = 1,
|
||||
.cs_pin = 0
|
||||
};
|
||||
|
||||
spi_init(SPI0_INSTANCE, &spi_config);
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
* I2C Initialization
|
||||
* ============================================================================ */
|
||||
void board_i2c_init(void) {
|
||||
/* Configure I2C0 */
|
||||
I2cConfig_t i2c_config = {
|
||||
.speed = I2C_SPEED_FAST,
|
||||
.addressing_mode = I2C_ADDRESSING_7BIT,
|
||||
.own_address = 0x50,
|
||||
.enable_general_call = false,
|
||||
.enable_clock_stretching = true,
|
||||
.use_dma = false
|
||||
};
|
||||
|
||||
i2c_init(I2C0_INSTANCE, &i2c_config);
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
* ADC Initialization
|
||||
* ============================================================================ */
|
||||
void board_adc_init(void) {
|
||||
/* Configure ADC0 */
|
||||
AdcConfig_t adc_config = {
|
||||
.resolution = ADC_RESOLUTION_12BIT,
|
||||
.mode = ADC_MODE_SCAN,
|
||||
.trigger_source = ADC_TRIGGER_SOFTWARE,
|
||||
.reference = ADC_REFERENCE_VDD,
|
||||
.enable_dma = false,
|
||||
.conversion_frequency = 1000,
|
||||
.channel_count = 8,
|
||||
.channels = {
|
||||
{.channel = 0, .sampling_time = ADC_SAMPLING_13_5_CYCLES},
|
||||
{.channel = 1, .sampling_time = ADC_SAMPLING_13_5_CYCLES},
|
||||
{.channel = 2, .sampling_time = ADC_SAMPLING_13_5_CYCLES},
|
||||
{.channel = 3, .sampling_time = ADC_SAMPLING_13_5_CYCLES},
|
||||
{.channel = 4, .sampling_time = ADC_SAMPLING_13_5_CYCLES},
|
||||
{.channel = 5, .sampling_time = ADC_SAMPLING_13_5_CYCLES},
|
||||
{.channel = 6, .sampling_time = ADC_SAMPLING_13_5_CYCLES},
|
||||
{.channel = 7, .sampling_time = ADC_SAMPLING_13_5_CYCLES}
|
||||
}
|
||||
};
|
||||
|
||||
adc_init(ADC0_INSTANCE, &adc_config);
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
* PWM Initialization
|
||||
* ============================================================================ */
|
||||
void board_pwm_init(void) {
|
||||
/* Configure PWM */
|
||||
PwmConfig_t pwm_config = {
|
||||
.frequency_hz = PWM_TIMER_FREQUENCY,
|
||||
.alignment = PWM_ALIGNMENT_EDGE,
|
||||
.period_ticks = 10000,
|
||||
.prescaler = PWM_TIMER_PRESCALER,
|
||||
.channel_count = 4,
|
||||
.channels = {
|
||||
{.channel = 0, .duty_cycle = 0},
|
||||
{.channel = 1, .duty_cycle = 0},
|
||||
{.channel = 2, .duty_cycle = 0},
|
||||
{.channel = 3, .duty_cycle = 0}
|
||||
},
|
||||
.enable_fault_protection = true,
|
||||
.fault_action = PWM_FAULT_DISABLE
|
||||
};
|
||||
|
||||
pwm_init(PWM_INSTANCE, &pwm_config);
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
* Watchdog Initialization
|
||||
* ============================================================================ */
|
||||
void board_watchdog_init(void) {
|
||||
/* Configure WDOG */
|
||||
WDOG->CNT = 0x1000; /* Timeout value */
|
||||
WDOG->TOVAL = 0x1000;
|
||||
WDOG->CS = WDOG_CS_EN_MASK |
|
||||
WDOG_CS_CLK(1) |
|
||||
WDOG_CS_WIN_MASK |
|
||||
WDOG_CS_UPDATE_MASK;
|
||||
}
|
||||
|
||||
void board_watchdog_service(void) {
|
||||
/* Service WDOG */
|
||||
WDOG->CNT = 0xB480;
|
||||
WDOG->CNT = 0x4B80;
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
* LED Functions
|
||||
* ============================================================================ */
|
||||
void board_led_on(uint8_t led) {
|
||||
switch (led) {
|
||||
case 0:
|
||||
gpio_write(2, 0, false); /* Active low */
|
||||
break;
|
||||
case 1:
|
||||
gpio_write(2, 1, false);
|
||||
break;
|
||||
case 2:
|
||||
gpio_write(2, 2, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void board_led_off(uint8_t led) {
|
||||
switch (led) {
|
||||
case 0:
|
||||
gpio_write(2, 0, true);
|
||||
break;
|
||||
case 1:
|
||||
gpio_write(2, 1, true);
|
||||
break;
|
||||
case 2:
|
||||
gpio_write(2, 2, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void board_led_toggle(uint8_t led) {
|
||||
switch (led) {
|
||||
case 0:
|
||||
gpio_toggle(2, 0);
|
||||
break;
|
||||
case 1:
|
||||
gpio_toggle(2, 1);
|
||||
break;
|
||||
case 2:
|
||||
gpio_toggle(2, 2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
* Button Functions
|
||||
* ============================================================================ */
|
||||
bool board_button_read(uint8_t button) {
|
||||
switch (button) {
|
||||
case 0:
|
||||
return !gpio_read(2, 3); /* Active low */
|
||||
case 1:
|
||||
return !gpio_read(2, 4);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
* Delay Functions
|
||||
* ============================================================================ */
|
||||
void board_delay_ms(uint32_t ms) {
|
||||
kernel_delay(ms);
|
||||
}
|
||||
|
||||
void board_delay_us(uint32_t us) {
|
||||
uint32_t count = us * (SystemCoreClock / 1000000) / 5;
|
||||
while (count--) {
|
||||
__NOP();
|
||||
}
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
* Sensor Functions
|
||||
* ============================================================================ */
|
||||
float board_get_temperature(void) {
|
||||
/* Read internal temperature sensor */
|
||||
uint16_t adc_value = 0;
|
||||
adc_read_channel(ADC0_INSTANCE, 26, &adc_value, 10); /* Internal temp sensor */
|
||||
|
||||
/* Convert to temperature (S32K144 specific formula) */
|
||||
float voltage = adc_convert_to_voltage(adc_value, ADC_RESOLUTION_12BIT, 3.3f);
|
||||
float temperature = 25.0f - ((voltage - 0.716f) / 0.00162f);
|
||||
|
||||
return temperature;
|
||||
}
|
||||
|
||||
float board_get_voltage(void) {
|
||||
/* Read bandgap reference */
|
||||
uint16_t adc_value = 0;
|
||||
adc_read_channel(ADC0_INSTANCE, 27, &adc_value, 10); /* Bandgap */
|
||||
|
||||
float voltage = adc_convert_to_voltage(adc_value, ADC_RESOLUTION_12BIT, 3.3f);
|
||||
return voltage;
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
/**
|
||||
* @file linker_script.ld
|
||||
* @brief Linker script for NXP S32K144
|
||||
*/
|
||||
|
||||
ENTRY(Reset_Handler)
|
||||
|
||||
MEMORY
|
||||
{
|
||||
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 512K
|
||||
SRAM_L (rwx) : ORIGIN = 0x1FFF8000, LENGTH = 32K
|
||||
SRAM_U (rwx) : ORIGIN = 0x20000000, LENGTH = 28K
|
||||
}
|
||||
|
||||
_estack = ORIGIN(SRAM_U) + LENGTH(SRAM_U);
|
||||
_min_stack_size = 0x400;
|
||||
_min_heap_size = 0x200;
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
/* Interrupt Vector Table */
|
||||
.isr_vector :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
KEEP(*(.isr_vector))
|
||||
. = ALIGN(4);
|
||||
} >FLASH
|
||||
|
||||
/* Program Code */
|
||||
.text :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(.text)
|
||||
*(.text*)
|
||||
*(.glue_7)
|
||||
*(.glue_7t)
|
||||
*(.eh_frame)
|
||||
|
||||
KEEP(*(.init))
|
||||
KEEP(*(.fini))
|
||||
|
||||
. = ALIGN(4);
|
||||
_etext = .;
|
||||
} >FLASH
|
||||
|
||||
/* Constant Data */
|
||||
.rodata :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(.rodata)
|
||||
*(.rodata*)
|
||||
. = ALIGN(4);
|
||||
} >FLASH
|
||||
|
||||
/* ARM Extensions */
|
||||
.ARM.extab :
|
||||
{
|
||||
*(.ARM.extab* .gnu.linkonce.armextab.*)
|
||||
} >FLASH
|
||||
|
||||
.ARM :
|
||||
{
|
||||
__exidx_start = .;
|
||||
*(.ARM.exidx*)
|
||||
__exidx_end = .;
|
||||
} >FLASH
|
||||
|
||||
/* Initialization Arrays */
|
||||
.preinit_array :
|
||||
{
|
||||
PROVIDE_HIDDEN(__preinit_array_start = .);
|
||||
KEEP(*(.preinit_array*))
|
||||
PROVIDE_HIDDEN(__preinit_array_end = .);
|
||||
} >FLASH
|
||||
|
||||
.init_array :
|
||||
{
|
||||
PROVIDE_HIDDEN(__init_array_start = .);
|
||||
KEEP(*(SORT(.init_array.*)))
|
||||
KEEP(*(.init_array*))
|
||||
PROVIDE_HIDDEN(__init_array_end = .);
|
||||
} >FLASH
|
||||
|
||||
.fini_array :
|
||||
{
|
||||
PROVIDE_HIDDEN(__fini_array_start = .);
|
||||
KEEP(*(SORT(.fini_array.*)))
|
||||
KEEP(*(.fini_array*))
|
||||
PROVIDE_HIDDEN(__fini_array_end = .);
|
||||
} >FLASH
|
||||
|
||||
/* Data Sections */
|
||||
_sidata = LOADADDR(.data);
|
||||
|
||||
.data :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_sdata = .;
|
||||
*(.data)
|
||||
*(.data*)
|
||||
|
||||
. = ALIGN(4);
|
||||
_edata = .;
|
||||
} >SRAM_L AT> FLASH
|
||||
|
||||
/* BSS Section */
|
||||
.bss :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_sbss = .;
|
||||
__bss_start__ = _sbss;
|
||||
*(.bss)
|
||||
*(.bss*)
|
||||
*(COMMON)
|
||||
|
||||
. = ALIGN(4);
|
||||
_ebss = .;
|
||||
__bss_end__ = _ebss;
|
||||
} >SRAM_L
|
||||
|
||||
/* Heap and Stack */
|
||||
._user_heap_stack :
|
||||
{
|
||||
. = ALIGN(8);
|
||||
PROVIDE(end = .);
|
||||
PROVIDE(_end = .);
|
||||
. = . + _min_heap_size;
|
||||
. = . + _min_stack_size;
|
||||
. = ALIGN(8);
|
||||
} >SRAM_U
|
||||
|
||||
/* Discard */
|
||||
/DISCARD/ :
|
||||
{
|
||||
libc.a(*)
|
||||
libm.a(*)
|
||||
libgcc.a(*)
|
||||
}
|
||||
|
||||
.ARM.attributes 0 : { *(.ARM.attributes) }
|
||||
}
|
||||
@@ -0,0 +1,227 @@
|
||||
/**
|
||||
* @file board.h
|
||||
* @brief STM32F407 Discovery board definitions
|
||||
*/
|
||||
|
||||
#ifndef BOARD_H
|
||||
#define BOARD_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "stm32f4xx.h"
|
||||
|
||||
/* ============================================================================
|
||||
* Board Identification
|
||||
* ============================================================================ */
|
||||
#define BOARD_NAME "STM32F407G-DISC1"
|
||||
#define BOARD_MANUFACTURER "STMicroelectronics"
|
||||
#define BOARD_VERSION "1.0"
|
||||
#define BOARD_MCU "STM32F407VG"
|
||||
|
||||
/* ============================================================================
|
||||
* Clock Configuration
|
||||
* ============================================================================ */
|
||||
#define HSE_VALUE 8000000U /* External crystal */
|
||||
#define HSI_VALUE 16000000U /* Internal oscillator */
|
||||
#define LSE_VALUE 32768U /* Low speed external */
|
||||
#define LSI_VALUE 32000U /* Low speed internal */
|
||||
|
||||
#define SYSTEM_CLOCK 168000000U /* 168 MHz */
|
||||
#define AHB_CLOCK 168000000U
|
||||
#define APB1_CLOCK 42000000U
|
||||
#define APB2_CLOCK 84000000U
|
||||
#define USB_CLOCK 48000000U
|
||||
|
||||
/* PLL Configuration */
|
||||
#define PLL_M 8
|
||||
#define PLL_N 336
|
||||
#define PLL_P 2
|
||||
#define PLL_Q 7
|
||||
|
||||
/* ============================================================================
|
||||
* LED Definitions
|
||||
* ============================================================================ */
|
||||
#define LED_COUNT 4
|
||||
|
||||
#define LED1_PORT GPIOD
|
||||
#define LED1_PIN GPIO_PIN_12
|
||||
#define LED1_CLOCK __HAL_RCC_GPIOD_CLK_ENABLE()
|
||||
|
||||
#define LED2_PORT GPIOD
|
||||
#define LED2_PIN GPIO_PIN_13
|
||||
#define LED2_CLOCK __HAL_RCC_GPIOD_CLK_ENABLE()
|
||||
|
||||
#define LED3_PORT GPIOD
|
||||
#define LED3_PIN GPIO_PIN_14
|
||||
#define LED3_CLOCK __HAL_RCC_GPIOD_CLK_ENABLE()
|
||||
|
||||
#define LED4_PORT GPIOD
|
||||
#define LED4_PIN GPIO_PIN_15
|
||||
#define LED4_CLOCK __HAL_RCC_GPIOD_CLK_ENABLE()
|
||||
|
||||
/* LED Active Level */
|
||||
#define LED_ACTIVE_LEVEL GPIO_PIN_SET
|
||||
|
||||
/* ============================================================================
|
||||
* Button Definitions
|
||||
* ============================================================================ */
|
||||
#define BUTTON_COUNT 1
|
||||
|
||||
#define BUTTON1_PORT GPIOA
|
||||
#define BUTTON1_PIN GPIO_PIN_0
|
||||
#define BUTTON1_CLOCK __HAL_RCC_GPIOA_CLK_ENABLE()
|
||||
#define BUTTON1_EXTI_IRQ EXTI0_IRQn
|
||||
|
||||
/* Button Active Level */
|
||||
#define BUTTON_ACTIVE_LEVEL GPIO_PIN_SET
|
||||
|
||||
/* ============================================================================
|
||||
* UART Definitions
|
||||
* ============================================================================ */
|
||||
#define UART1_INSTANCE 0
|
||||
#define UART1_BAUDRATE 115200
|
||||
#define UART1_WORDLENGTH UART_WORDLENGTH_8B
|
||||
#define UART1_STOPBITS UART_STOPBITS_1
|
||||
#define UART1_PARITY UART_PARITY_NONE
|
||||
#define UART1_HWFLOWCTL UART_HWCONTROL_NONE
|
||||
|
||||
#define UART1_TX_PORT GPIOA
|
||||
#define UART1_TX_PIN GPIO_PIN_9
|
||||
#define UART1_TX_AF GPIO_AF7_USART1
|
||||
#define UART1_RX_PORT GPIOA
|
||||
#define UART1_RX_PIN GPIO_PIN_10
|
||||
#define UART1_RX_AF GPIO_AF7_USART1
|
||||
#define UART1_CLOCK_ENABLE() __HAL_RCC_USART1_CLK_ENABLE()
|
||||
#define UART1_GPIO_CLOCK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
|
||||
|
||||
#define UART2_INSTANCE 1
|
||||
#define UART2_BAUDRATE 115200
|
||||
#define UART2_TX_PORT GPIOA
|
||||
#define UART2_TX_PIN GPIO_PIN_2
|
||||
#define UART2_TX_AF GPIO_AF7_USART2
|
||||
#define UART2_RX_PORT GPIOA
|
||||
#define UART2_RX_PIN GPIO_PIN_3
|
||||
#define UART2_RX_AF GPIO_AF7_USART2
|
||||
#define UART2_CLOCK_ENABLE() __HAL_RCC_USART2_CLK_ENABLE()
|
||||
|
||||
/* ============================================================================
|
||||
* CAN Definitions
|
||||
* ============================================================================ */
|
||||
#define CAN1_INSTANCE 0
|
||||
#define CAN1_BAUDRATE 500000
|
||||
#define CAN1_TX_PORT GPIOB
|
||||
#define CAN1_TX_PIN GPIO_PIN_9
|
||||
#define CAN1_TX_AF GPIO_AF9_CAN1
|
||||
#define CAN1_RX_PORT GPIOB
|
||||
#define CAN1_RX_PIN GPIO_PIN_8
|
||||
#define CAN1_RX_AF GPIO_AF9_CAN1
|
||||
#define CAN1_CLOCK_ENABLE() __HAL_RCC_CAN1_CLK_ENABLE()
|
||||
#define CAN1_GPIO_CLOCK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
|
||||
|
||||
#define CAN2_INSTANCE 1
|
||||
#define CAN2_BAUDRATE 500000
|
||||
#define CAN2_TX_PORT GPIOB
|
||||
#define CAN2_TX_PIN GPIO_PIN_13
|
||||
#define CAN2_TX_AF GPIO_AF9_CAN2
|
||||
#define CAN2_RX_PORT GPIOB
|
||||
#define CAN2_RX_PIN GPIO_PIN_12
|
||||
#define CAN2_RX_AF GPIO_AF9_CAN2
|
||||
#define CAN2_CLOCK_ENABLE() __HAL_RCC_CAN2_CLK_ENABLE()
|
||||
|
||||
/* ============================================================================
|
||||
* SPI Definitions
|
||||
* ============================================================================ */
|
||||
#define SPI1_INSTANCE 0
|
||||
#define SPI1_SCK_PORT GPIOA
|
||||
#define SPI1_SCK_PIN GPIO_PIN_5
|
||||
#define SPI1_SCK_AF GPIO_AF5_SPI1
|
||||
#define SPI1_MISO_PORT GPIOA
|
||||
#define SPI1_MISO_PIN GPIO_PIN_6
|
||||
#define SPI1_MISO_AF GPIO_AF5_SPI1
|
||||
#define SPI1_MOSI_PORT GPIOA
|
||||
#define SPI1_MOSI_PIN GPIO_PIN_7
|
||||
#define SPI1_MOSI_AF GPIO_AF5_SPI1
|
||||
#define SPI1_CLOCK_ENABLE() __HAL_RCC_SPI1_CLK_ENABLE()
|
||||
|
||||
/* ============================================================================
|
||||
* I2C Definitions
|
||||
* ============================================================================ */
|
||||
#define I2C1_INSTANCE 0
|
||||
#define I2C1_SCL_PORT GPIOB
|
||||
#define I2C1_SCL_PIN GPIO_PIN_6
|
||||
#define I2C1_SCL_AF GPIO_AF4_I2C1
|
||||
#define I2C1_SDA_PORT GPIOB
|
||||
#define I2C1_SDA_PIN GPIO_PIN_7
|
||||
#define I2C1_SDA_AF GPIO_AF4_I2C1
|
||||
#define I2C1_CLOCK_ENABLE() __HAL_RCC_I2C1_CLK_ENABLE()
|
||||
|
||||
/* ============================================================================
|
||||
* ADC Definitions
|
||||
* ============================================================================ */
|
||||
#define ADC1_INSTANCE 0
|
||||
#define ADC1_CHANNEL_COUNT 6
|
||||
#define ADC1_CH0_PORT GPIOA
|
||||
#define ADC1_CH0_PIN GPIO_PIN_0
|
||||
#define ADC1_CH1_PORT GPIOA
|
||||
#define ADC1_CH1_PIN GPIO_PIN_1
|
||||
#define ADC1_CH2_PORT GPIOA
|
||||
#define ADC1_CH2_PIN GPIO_PIN_2
|
||||
#define ADC1_CH3_PORT GPIOA
|
||||
#define ADC1_CH3_PIN GPIO_PIN_3
|
||||
#define ADC1_CLOCK_ENABLE() __HAL_RCC_ADC1_CLK_ENABLE()
|
||||
|
||||
/* ============================================================================
|
||||
* PWM/Timer Definitions
|
||||
* ============================================================================ */
|
||||
#define PWM_TIMER_INSTANCE 0
|
||||
#define PWM_TIMER TIM1
|
||||
#define PWM_TIMER_CLOCK_ENABLE() __HAL_RCC_TIM1_CLK_ENABLE()
|
||||
#define PWM_TIMER_CHANNEL_COUNT 4
|
||||
#define PWM_TIMER_PRESCALER 168 /* 1 MHz */
|
||||
#define PWM_TIMER_PERIOD 1000 /* 1 kHz */
|
||||
#define PWM_TIMER_IRQ TIM1_UP_TIM10_IRQn
|
||||
|
||||
#define PWM_CH1_PORT GPIOA
|
||||
#define PWM_CH1_PIN GPIO_PIN_8
|
||||
#define PWM_CH1_AF GPIO_AF1_TIM1
|
||||
#define PWM_CH2_PORT GPIOA
|
||||
#define PWM_CH2_PIN GPIO_PIN_9
|
||||
#define PWM_CH2_AF GPIO_AF1_TIM1
|
||||
#define PWM_CH3_PORT GPIOA
|
||||
#define PWM_CH3_PIN GPIO_PIN_10
|
||||
#define PWM_CH3_AF GPIO_AF1_TIM1
|
||||
#define PWM_CH4_PORT GPIOA
|
||||
#define PWM_CH4_PIN GPIO_PIN_11
|
||||
#define PWM_CH4_AF GPIO_AF1_TIM1
|
||||
|
||||
/* ============================================================================
|
||||
* Watchdog Configuration
|
||||
* ============================================================================ */
|
||||
#define WATCHDOG_INSTANCE 0
|
||||
#define WATCHDOG_TIMEOUT_MS 100
|
||||
#define WATCHDOG_WINDOW_MS 50
|
||||
|
||||
/* ============================================================================
|
||||
* Board Functions
|
||||
* ============================================================================ */
|
||||
void board_init(void);
|
||||
void board_clock_init(void);
|
||||
void board_gpio_init(void);
|
||||
void board_uart_init(void);
|
||||
void board_can_init(void);
|
||||
void board_spi_init(void);
|
||||
void board_i2c_init(void);
|
||||
void board_adc_init(void);
|
||||
void board_pwm_init(void);
|
||||
void board_watchdog_init(void);
|
||||
void board_watchdog_service(void);
|
||||
void board_led_on(uint8_t led);
|
||||
void board_led_off(uint8_t led);
|
||||
void board_led_toggle(uint8_t led);
|
||||
bool board_button_read(uint8_t button);
|
||||
void board_delay_ms(uint32_t ms);
|
||||
void board_delay_us(uint32_t us);
|
||||
float board_get_temperature(void);
|
||||
float board_get_voltage(void);
|
||||
|
||||
#endif /* BOARD_H */
|
||||
@@ -0,0 +1,388 @@
|
||||
/**
|
||||
* @file board_init.c
|
||||
* @brief STM32F407 Discovery board initialization
|
||||
*/
|
||||
|
||||
#include "board.h"
|
||||
#include "kernel.h"
|
||||
#include "gpio_driver.h"
|
||||
#include "uart_driver.h"
|
||||
#include "can_driver.h"
|
||||
#include "spi_driver.h"
|
||||
#include "i2c_driver.h"
|
||||
#include "adc_driver.h"
|
||||
#include "pwm_driver.h"
|
||||
#include <string.h>
|
||||
|
||||
/* Board state */
|
||||
static bool board_initialized = false;
|
||||
|
||||
/* ============================================================================
|
||||
* Board Initialization
|
||||
* ============================================================================ */
|
||||
void board_init(void) {
|
||||
if (board_initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Initialize clock */
|
||||
board_clock_init();
|
||||
|
||||
/* Initialize GPIO */
|
||||
board_gpio_init();
|
||||
|
||||
/* Initialize UART */
|
||||
board_uart_init();
|
||||
|
||||
/* Initialize CAN */
|
||||
board_can_init();
|
||||
|
||||
/* Initialize SPI */
|
||||
board_spi_init();
|
||||
|
||||
/* Initialize I2C */
|
||||
board_i2c_init();
|
||||
|
||||
/* Initialize ADC */
|
||||
board_adc_init();
|
||||
|
||||
/* Initialize PWM */
|
||||
board_pwm_init();
|
||||
|
||||
/* Initialize watchdog */
|
||||
board_watchdog_init();
|
||||
|
||||
board_initialized = true;
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
* Clock Initialization
|
||||
* ============================================================================ */
|
||||
void board_clock_init(void) {
|
||||
/* Reset RCC */
|
||||
RCC->CR |= RCC_CR_HSION;
|
||||
while (!(RCC->CR & RCC_CR_HSIRDY));
|
||||
|
||||
/* Configure PLL */
|
||||
RCC->PLLCFGR = (PLL_M << RCC_PLLCFGR_PLLM_Pos) |
|
||||
(PLL_N << RCC_PLLCFGR_PLLN_Pos) |
|
||||
(((PLL_P >> 1) - 1) << RCC_PLLCFGR_PLLP_Pos) |
|
||||
(PLL_Q << RCC_PLLCFGR_PLLQ_Pos);
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CR |= RCC_CR_PLLON;
|
||||
while (!(RCC->CR & RCC_CR_PLLRDY));
|
||||
|
||||
/* Configure flash latency */
|
||||
FLASH->ACR = FLASH_ACR_LATENCY_5WS | FLASH_ACR_PRFTEN | FLASH_ACR_ICEN | FLASH_ACR_DCEN;
|
||||
|
||||
/* Configure AHB, APB1, APB2 prescalers */
|
||||
RCC->CFGR = RCC_CFGR_HPRE_DIV1 | RCC_CFGR_PPRE1_DIV4 | RCC_CFGR_PPRE2_DIV2;
|
||||
|
||||
/* Switch to PLL */
|
||||
RCC->CFGR |= RCC_CFGR_SW_PLL;
|
||||
while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL);
|
||||
|
||||
/* Update SystemCoreClock variable */
|
||||
SystemCoreClockUpdate();
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
* GPIO Initialization
|
||||
* ============================================================================ */
|
||||
void board_gpio_init(void) {
|
||||
/* Enable GPIO clocks */
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOB_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOC_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOD_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOE_CLK_ENABLE();
|
||||
|
||||
/* Configure LEDs */
|
||||
GpioPinConfig_t led_config = {
|
||||
.mode = GPIO_MODE_OUTPUT,
|
||||
.output_type = GPIO_OUTPUT_PUSH_PULL,
|
||||
.pull = GPIO_PULL_NONE,
|
||||
.speed = GPIO_SPEED_HIGH
|
||||
};
|
||||
|
||||
led_config.port = 3; /* GPIOD */
|
||||
led_config.pin = 12;
|
||||
gpio_init(&led_config);
|
||||
|
||||
led_config.pin = 13;
|
||||
gpio_init(&led_config);
|
||||
|
||||
led_config.pin = 14;
|
||||
gpio_init(&led_config);
|
||||
|
||||
led_config.pin = 15;
|
||||
gpio_init(&led_config);
|
||||
|
||||
/* Configure button */
|
||||
GpioPinConfig_t button_config = {
|
||||
.port = 0, /* GPIOA */
|
||||
.pin = 0,
|
||||
.mode = GPIO_MODE_INPUT,
|
||||
.pull = GPIO_PULL_DOWN
|
||||
};
|
||||
gpio_init(&button_config);
|
||||
|
||||
/* Turn off all LEDs */
|
||||
board_led_off(0);
|
||||
board_led_off(1);
|
||||
board_led_off(2);
|
||||
board_led_off(3);
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
* UART Initialization
|
||||
* ============================================================================ */
|
||||
void board_uart_init(void) {
|
||||
/* Configure UART1 */
|
||||
UartConfig_t uart1_config = {
|
||||
.baudrate = UART1_BAUDRATE,
|
||||
.data_bits = UART_DATA_BITS_8,
|
||||
.stop_bits = UART_STOP_BITS_1,
|
||||
.parity = UART_PARITY_NONE,
|
||||
.flow_control = UART_FLOW_CONTROL_NONE,
|
||||
.enable_rx = true,
|
||||
.enable_tx = true,
|
||||
.use_dma = false
|
||||
};
|
||||
|
||||
uart_init(UART1_INSTANCE, &uart1_config);
|
||||
|
||||
/* Configure UART2 */
|
||||
UartConfig_t uart2_config = uart1_config;
|
||||
uart_init(UART2_INSTANCE, &uart2_config);
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
* CAN Initialization
|
||||
* ============================================================================ */
|
||||
void board_can_init(void) {
|
||||
/* Configure CAN1 */
|
||||
CanConfig_t can1_config = {
|
||||
.nominal_baudrate = CAN1_BAUDRATE,
|
||||
.data_baudrate = CAN1_BAUDRATE,
|
||||
.frame_type = CAN_FRAME_CLASSIC,
|
||||
.enable_fd = false,
|
||||
.enable_automatic_retransmission = true,
|
||||
.filter_count = 0
|
||||
};
|
||||
|
||||
can_init(&can1_config);
|
||||
|
||||
/* Configure CAN2 */
|
||||
CanConfig_t can2_config = can1_config;
|
||||
can_init(&can2_config);
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
* SPI Initialization
|
||||
* ============================================================================ */
|
||||
void board_spi_init(void) {
|
||||
/* Configure SPI1 */
|
||||
SpiConfig_t spi1_config = {
|
||||
.mode = SPI_MODE_0,
|
||||
.clock_speed = SPI_CLOCK_8MHZ,
|
||||
.data_order = SPI_DATA_ORDER_MSB_FIRST,
|
||||
.data_size = 8,
|
||||
.use_dma = false,
|
||||
.enable_hardware_cs = false,
|
||||
.cs_polarity = SPI_CS_ACTIVE_LOW,
|
||||
.cs_port = 0,
|
||||
.cs_pin = 4
|
||||
};
|
||||
|
||||
spi_init(SPI1_INSTANCE, &spi1_config);
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
* I2C Initialization
|
||||
* ============================================================================ */
|
||||
void board_i2c_init(void) {
|
||||
/* Configure I2C1 */
|
||||
I2cConfig_t i2c1_config = {
|
||||
.speed = I2C_SPEED_FAST,
|
||||
.addressing_mode = I2C_ADDRESSING_7BIT,
|
||||
.own_address = 0x50,
|
||||
.enable_general_call = false,
|
||||
.enable_clock_stretching = true,
|
||||
.use_dma = false
|
||||
};
|
||||
|
||||
i2c_init(I2C1_INSTANCE, &i2c1_config);
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
* ADC Initialization
|
||||
* ============================================================================ */
|
||||
void board_adc_init(void) {
|
||||
/* Configure ADC1 */
|
||||
AdcConfig_t adc1_config = {
|
||||
.resolution = ADC_RESOLUTION_12BIT,
|
||||
.mode = ADC_MODE_SCAN,
|
||||
.trigger_source = ADC_TRIGGER_TIMER,
|
||||
.reference = ADC_REFERENCE_VDD,
|
||||
.enable_dma = false,
|
||||
.conversion_frequency = 1000,
|
||||
.channel_count = 6,
|
||||
.channels = {
|
||||
{.channel = 0, .sampling_time = ADC_SAMPLING_28_5_CYCLES},
|
||||
{.channel = 1, .sampling_time = ADC_SAMPLING_28_5_CYCLES},
|
||||
{.channel = 2, .sampling_time = ADC_SAMPLING_28_5_CYCLES},
|
||||
{.channel = 3, .sampling_time = ADC_SAMPLING_28_5_CYCLES},
|
||||
{.channel = 4, .sampling_time = ADC_SAMPLING_28_5_CYCLES},
|
||||
{.channel = 5, .sampling_time = ADC_SAMPLING_28_5_CYCLES}
|
||||
}
|
||||
};
|
||||
|
||||
adc_init(ADC1_INSTANCE, &adc1_config);
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
* PWM Initialization
|
||||
* ============================================================================ */
|
||||
void board_pwm_init(void) {
|
||||
/* Configure PWM timer */
|
||||
PwmConfig_t pwm_config = {
|
||||
.frequency_hz = 1000,
|
||||
.alignment = PWM_ALIGNMENT_EDGE,
|
||||
.period_ticks = 1000,
|
||||
.prescaler = 168,
|
||||
.channel_count = 4,
|
||||
.channels = {
|
||||
{.channel = 0, .duty_cycle = 0, .polarity = PWM_POLARITY_ACTIVE_HIGH},
|
||||
{.channel = 1, .duty_cycle = 0, .polarity = PWM_POLARITY_ACTIVE_HIGH},
|
||||
{.channel = 2, .duty_cycle = 0, .polarity = PWM_POLARITY_ACTIVE_HIGH},
|
||||
{.channel = 3, .duty_cycle = 0, .polarity = PWM_POLARITY_ACTIVE_HIGH}
|
||||
},
|
||||
.enable_fault_protection = true,
|
||||
.fault_action = PWM_FAULT_DISABLE
|
||||
};
|
||||
|
||||
pwm_init(PWM_TIMER_INSTANCE, &pwm_config);
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
* Watchdog Initialization
|
||||
* ============================================================================ */
|
||||
void board_watchdog_init(void) {
|
||||
/* Enable IWDG */
|
||||
IWDG->KR = 0x5555; /* Enable write access */
|
||||
IWDG->PR = 0x06; /* Prescaler: 256 */
|
||||
IWDG->RLR = 0x0FFF; /* Reload value */
|
||||
IWDG->KR = 0xCCCC; /* Start watchdog */
|
||||
}
|
||||
|
||||
void board_watchdog_service(void) {
|
||||
/* Service IWDG */
|
||||
IWDG->KR = 0xAAAA;
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
* LED Functions
|
||||
* ============================================================================ */
|
||||
void board_led_on(uint8_t led) {
|
||||
switch (led) {
|
||||
case 0:
|
||||
gpio_write(3, 12, true);
|
||||
break;
|
||||
case 1:
|
||||
gpio_write(3, 13, true);
|
||||
break;
|
||||
case 2:
|
||||
gpio_write(3, 14, true);
|
||||
break;
|
||||
case 3:
|
||||
gpio_write(3, 15, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void board_led_off(uint8_t led) {
|
||||
switch (led) {
|
||||
case 0:
|
||||
gpio_write(3, 12, false);
|
||||
break;
|
||||
case 1:
|
||||
gpio_write(3, 13, false);
|
||||
break;
|
||||
case 2:
|
||||
gpio_write(3, 14, false);
|
||||
break;
|
||||
case 3:
|
||||
gpio_write(3, 15, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void board_led_toggle(uint8_t led) {
|
||||
switch (led) {
|
||||
case 0:
|
||||
gpio_toggle(3, 12);
|
||||
break;
|
||||
case 1:
|
||||
gpio_toggle(3, 13);
|
||||
break;
|
||||
case 2:
|
||||
gpio_toggle(3, 14);
|
||||
break;
|
||||
case 3:
|
||||
gpio_toggle(3, 15);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
* Button Functions
|
||||
* ============================================================================ */
|
||||
bool board_button_read(uint8_t button) {
|
||||
if (button == 0) {
|
||||
return gpio_read(0, 0);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
* Delay Functions
|
||||
* ============================================================================ */
|
||||
void board_delay_ms(uint32_t ms) {
|
||||
kernel_delay(ms);
|
||||
}
|
||||
|
||||
void board_delay_us(uint32_t us) {
|
||||
/* Simple busy-wait delay */
|
||||
uint32_t count = us * (SystemCoreClock / 1000000) / 5;
|
||||
while (count--) {
|
||||
__NOP();
|
||||
}
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
* Sensor Functions
|
||||
* ============================================================================ */
|
||||
float board_get_temperature(void) {
|
||||
/* Read internal temperature sensor */
|
||||
uint16_t adc_value = 0;
|
||||
adc_read_channel(ADC1_INSTANCE, 16, &adc_value, 10);
|
||||
|
||||
/* Convert to temperature */
|
||||
float voltage = adc_convert_to_voltage(adc_value, ADC_RESOLUTION_12BIT, 3.3f);
|
||||
float temperature = ((voltage - 0.76f) / 0.0025f) + 25.0f;
|
||||
|
||||
return temperature;
|
||||
}
|
||||
|
||||
float board_get_voltage(void) {
|
||||
/* Read VREFINT */
|
||||
uint16_t adc_value = 0;
|
||||
adc_read_channel(ADC1_INSTANCE, 17, &adc_value, 10);
|
||||
|
||||
/* Convert to voltage */
|
||||
float voltage = adc_convert_to_voltage(adc_value, ADC_RESOLUTION_12BIT, 3.3f);
|
||||
|
||||
return voltage;
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
/**
|
||||
* @file linker_script.ld
|
||||
* @brief Linker script for STM32F407VG
|
||||
*/
|
||||
|
||||
/* Entry Point */
|
||||
ENTRY(Reset_Handler)
|
||||
|
||||
/* Memory Map */
|
||||
MEMORY
|
||||
{
|
||||
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K
|
||||
CCMRAM (rw) : ORIGIN = 0x10000000, LENGTH = 64K
|
||||
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
|
||||
}
|
||||
|
||||
/* Stack Configuration */
|
||||
_estack = ORIGIN(RAM) + LENGTH(RAM); /* End of RAM */
|
||||
_min_stack_size = 0x400; /* 1KB minimum stack */
|
||||
_min_heap_size = 0x200; /* 512B minimum heap */
|
||||
|
||||
/* Sections */
|
||||
SECTIONS
|
||||
{
|
||||
/* Interrupt Vector Table */
|
||||
.isr_vector :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
KEEP(*(.isr_vector))
|
||||
. = ALIGN(4);
|
||||
} >FLASH
|
||||
|
||||
/* Program Code */
|
||||
.text :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(.text)
|
||||
*(.text*)
|
||||
*(.glue_7)
|
||||
*(.glue_7t)
|
||||
*(.eh_frame)
|
||||
|
||||
KEEP(*(.init))
|
||||
KEEP(*(.fini))
|
||||
|
||||
. = ALIGN(4);
|
||||
_etext = .;
|
||||
} >FLASH
|
||||
|
||||
/* Constant Data */
|
||||
.rodata :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(.rodata)
|
||||
*(.rodata*)
|
||||
. = ALIGN(4);
|
||||
} >FLASH
|
||||
|
||||
/* ARM Extensions */
|
||||
.ARM.extab :
|
||||
{
|
||||
*(.ARM.extab* .gnu.linkonce.armextab.*)
|
||||
} >FLASH
|
||||
|
||||
.ARM :
|
||||
{
|
||||
__exidx_start = .;
|
||||
*(.ARM.exidx*)
|
||||
__exidx_end = .;
|
||||
} >FLASH
|
||||
|
||||
/* Pre-initialization Array */
|
||||
.preinit_array :
|
||||
{
|
||||
PROVIDE_HIDDEN(__preinit_array_start = .);
|
||||
KEEP(*(.preinit_array*))
|
||||
PROVIDE_HIDDEN(__preinit_array_end = .);
|
||||
} >FLASH
|
||||
|
||||
/* Initialization Array */
|
||||
.init_array :
|
||||
{
|
||||
PROVIDE_HIDDEN(__init_array_start = .);
|
||||
KEEP(*(SORT(.init_array.*)))
|
||||
KEEP(*(.init_array*))
|
||||
PROVIDE_HIDDEN(__init_array_end = .);
|
||||
} >FLASH
|
||||
|
||||
/* Finalization Array */
|
||||
.fini_array :
|
||||
{
|
||||
PROVIDE_HIDDEN(__fini_array_start = .);
|
||||
KEEP(*(SORT(.fini_array.*)))
|
||||
KEEP(*(.fini_array*))
|
||||
PROVIDE_HIDDEN(__fini_array_end = .);
|
||||
} >FLASH
|
||||
|
||||
/* Used by startup to initialize data */
|
||||
_sidata = LOADADDR(.data);
|
||||
|
||||
/* Initialized Data */
|
||||
.data :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_sdata = .;
|
||||
*(.data)
|
||||
*(.data*)
|
||||
|
||||
. = ALIGN(4);
|
||||
_edata = .;
|
||||
} >RAM AT> FLASH
|
||||
|
||||
/* Uninitialized Data */
|
||||
.bss :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_sbss = .;
|
||||
__bss_start__ = _sbss;
|
||||
*(.bss)
|
||||
*(.bss*)
|
||||
*(COMMON)
|
||||
|
||||
. = ALIGN(4);
|
||||
_ebss = .;
|
||||
__bss_end__ = _ebss;
|
||||
} >RAM
|
||||
|
||||
/* CCMRAM Section */
|
||||
.ccmram :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_sccmram = .;
|
||||
*(.ccmram)
|
||||
*(.ccmram*)
|
||||
|
||||
. = ALIGN(4);
|
||||
_eccmram = .;
|
||||
} >CCMRAM
|
||||
|
||||
/* Heap Section */
|
||||
._user_heap_stack :
|
||||
{
|
||||
. = ALIGN(8);
|
||||
PROVIDE(end = .);
|
||||
PROVIDE(_end = .);
|
||||
. = . + _min_heap_size;
|
||||
. = . + _min_stack_size;
|
||||
. = ALIGN(8);
|
||||
} >RAM
|
||||
|
||||
/* Remove information from standard libraries */
|
||||
/DISCARD/ :
|
||||
{
|
||||
libc.a(*)
|
||||
libm.a(*)
|
||||
libgcc.a(*)
|
||||
}
|
||||
|
||||
.ARM.attributes 0 : { *(.ARM.attributes) }
|
||||
}
|
||||
Reference in New Issue
Block a user