This repository contains firmware for the STM32L476RG using STM32CubeIDE and STM32 HAL. It is organized around a cooperative scheduler, a DBC-driven CAN parameter database, and modular controller systems.
- Round-robin cooperative scheduler
- Runtime CAN DBC parsing / generated DBC text blob
- Named parameter database for signals
- CAN RX decode / TX encode
- PWM / GPIO / ADC platform helpers
- Example systems for testing hardware and CAN flows
- Centralized project configuration
Core/ CubeMX startup, HAL init, main.c
App/Inc/ Application headers
App/Src/ Application sources
App/systems/ Runtime controller systems
App/dbc/ DBC files and generated C blob
Platform/ Hardware helper drivers
Drivers/ STM32 HAL / CMSIS
Examples/ Example usage snippets
Use STM32CubeIDE.
- Import project.
- Select
Debugconfiguration. - Clean project.
- Build.
- Flash to target.
main()
├── HAL init
├── clock/peripheral init
├── register controllers
└── while(1)
RR_Scheduler_Tick()
Each registered controller runs repeatedly in sequence.
Initializes scheduler state.
Registers a controller callback.
Example:
RR_AddController(can_system_controller);
RR_AddController(test_pwm_system_controller);Runs all controllers once.
can_system.hcan_system.ccan_params.hcan_params.ccan_config.hcan_config.c
- DBC messages become named parameters.
- RX frames decode into parameters.
- TX frames are scheduled from parameter values.
- Hardware filters optionally restrict accepted IDs.
Schedules transmit for a message or signal.
Examples:
CanSystem_Send("POWER_PCB_R");
CanSystem_Send("SCIENCE_SERVO_PCB_R.heartbeat_success");Sends a raw standard-ID CAN data frame immediately without using the DBC or parameter database.
Accepted format:
XXX#
XXX#112233
7FF#0011223344556677
Rules:
XXXis a 1 to 3 digit hex standard ID (0x000..0x7FF)- payload is optional
- payload must contain an even number of hex digits
- maximum payload is 8 bytes (
16hex digits) - only standard 11-bit IDs are supported
Examples:
CanSystem_SendRaw("70#300000");
CanSystem_SendRaw("70#300040");
CanSystem_SendRaw("70#30FF7F");
CanSystem_SendRaw("123#1122334455667788");Sets parameter then schedules send.
Sets parameter then schedules send.
Sets parameter then schedules send.
Returns last RX tick for message/page.
Returns last TX tick for message/page.
Returns whether ID passes allowlist.
Update stored parameter values.
Read parameter values.
Read event flag.
Consumes/clears event.
Edit:
App/Inc/project_config.hApp/Src/can_config.c
Set:
#define PROJECT_CAN_USE_DEFAULT_RX_FILTER 1or 0 to accept all IDs.
Files:
pwm.hpwm.c
Initializes timer PWM output.
Writes pulse width.
Use STM32 HAL:
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, GPIO_PIN_SET);
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_5);Use HAL ADC APIs or project helper if included.
Owns CAN RX/TX processing.
Drives board LED from CAN parameter.
Sends heartbeat responses periodically.
Servo PWM / IO logic.
Reads:
SCIENCE_DC_MOTOR_PCB_C.dc_motor_velocity_target_0
Maps 0..32767 to PWM duty cycle.
In main.c uncomment desired controllers:
RR_AddController(can_system_controller);
RR_AddController(test_pwm_system_controller);Raw SocketCAN style examples:
70#300000 0%
70#300040 50%
70#30FF7F 100%
Primary config file:
App/Inc/project_config.h
Contains tunables such as:
- CAN capacities n- CAN IDs
- filter enable
- demo timing
- servo settings
- LED pin settings
- Build project.
- Flash board.
- Verify LED system.
- Verify CAN heartbeat.
- Verify PWM output.
- Verify actuator systems.
- If adding new messages, update DBC and regenerate blob.
- If using many CAN IDs, software fallback still validates IDs beyond hardware banks.
- Clean + rebuild after config changes.
- Below commands to pull main updates without losing your branch work
- git checkout your-branch
- git fetch origin
- git merge origin/main