Skip to content

Commit aed7ad5

Browse files
committed
refactor panda to use source + header file structure
Split many previously header-implemented modules into conventional *.h declarations + *.c definitions (drivers, sys, stm32h7, boards, comms, libc/crc/provision, early init). Update MISRA/cppcheck invocation and suppressions to analyze multi-file builds across multiple translation units. Update tests/libpanda build/link inputs and test mutation targets to match the new file layout. Standardize include paths and create separate shared objects for can_common and can_comms in the test build. Closes #2171
1 parent 14b1906 commit aed7ad5

134 files changed

Lines changed: 7816 additions & 6970 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

SConscript

Lines changed: 153 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,109 @@ def to_c_uint32(x):
6161
return "{" + 'U,'.join(map(str, nums)) + "U}"
6262

6363

64-
def build_project(project_name, project, main, extra_flags):
64+
common_driver_sources = [
65+
"./board/stm32h7/interrupt_handlers.c",
66+
"./board/stm32h7/peripherals.c",
67+
"./board/stm32h7/clock.c",
68+
"./board/stm32h7/llfdcan.c",
69+
"./board/stm32h7/llusb.c",
70+
"./board/stm32h7/llspi.c",
71+
"./board/stm32h7/lluart.c",
72+
"./board/stm32h7/lladc.c",
73+
"./board/drivers/gpio.c",
74+
"./board/drivers/registers.c",
75+
"./board/drivers/interrupts.c",
76+
"./board/drivers/timers.c",
77+
"./board/drivers/pwm.c",
78+
"./board/drivers/led.c",
79+
"./board/drivers/can_common.c",
80+
"./board/drivers/fdcan.c",
81+
"./board/drivers/uart.c",
82+
"./board/drivers/spi.c",
83+
"./board/drivers/usb.c",
84+
"./board/can_comms.c",
85+
]
86+
87+
panda_extra_driver_sources = [
88+
"./board/stm32h7/board.c",
89+
"./board/stm32h7/llfan.c",
90+
"./board/stm32h7/lli2c.c",
91+
"./board/stm32h7/sound.c",
92+
"./board/boards/unused_funcs.c",
93+
"./board/boards/red.c",
94+
"./board/boards/tres.c",
95+
"./board/boards/cuatro.c",
96+
"./board/drivers/simple_watchdog.c",
97+
"./board/drivers/bootkick.c",
98+
"./board/drivers/clock_source.c",
99+
"./board/drivers/fan.c",
100+
"./board/drivers/harness.c",
101+
"./board/drivers/fake_siren.c",
102+
"./board/sys/power_saving.c",
103+
"./board/main_comms.c",
104+
]
105+
106+
jungle_extra_driver_sources = [
107+
"./board/jungle/stm32h7/board.c",
108+
"./board/jungle/boards/board_v2.c",
109+
"./board/jungle/main_comms.c",
110+
]
111+
112+
body_extra_driver_sources = [
113+
"./board/body/stm32h7/board.c",
114+
"./board/body/boards/board_body.c",
115+
"./board/body/motor_encoder.c",
116+
"./board/body/motor_control.c",
117+
"./board/body/can.c",
118+
"./board/body/main_comms.c",
119+
]
120+
121+
bootstub_common_driver_sources = [
122+
"./board/stm32h7/interrupt_handlers.c",
123+
"./board/stm32h7/peripherals.c",
124+
"./board/stm32h7/clock.c",
125+
"./board/stm32h7/llflash.c",
126+
"./board/stm32h7/llusb.c",
127+
"./board/stm32h7/llspi.c",
128+
"./board/stm32h7/lladc.c",
129+
"./board/drivers/gpio.c",
130+
"./board/drivers/registers.c",
131+
"./board/drivers/interrupts.c",
132+
"./board/drivers/timers.c",
133+
"./board/drivers/pwm.c",
134+
"./board/drivers/led.c",
135+
"./board/drivers/spi.c",
136+
"./board/drivers/usb.c",
137+
]
138+
139+
panda_extra_bootstub_driver_sources = [
140+
"./board/stm32h7/board.c",
141+
"./board/stm32h7/llfan.c",
142+
"./board/stm32h7/lli2c.c",
143+
"./board/stm32h7/sound.c",
144+
"./board/boards/unused_funcs.c",
145+
"./board/boards/red.c",
146+
"./board/boards/tres.c",
147+
"./board/boards/cuatro.c",
148+
"./board/drivers/harness.c",
149+
"./board/drivers/fan.c",
150+
"./board/drivers/fake_siren.c",
151+
"./board/drivers/clock_source.c",
152+
]
153+
154+
jungle_extra_bootstub_driver_sources = [
155+
"./board/jungle/stm32h7/board.c",
156+
"./board/jungle/boards/board_v2.c",
157+
]
158+
159+
body_extra_bootstub_driver_sources = [
160+
"./board/body/stm32h7/board.c",
161+
"./board/body/boards/board_body.c",
162+
"./board/body/motor_encoder.c",
163+
"./board/body/motor_control.c",
164+
]
165+
166+
def build_project(project_name, project, main, extra_flags, extra_driver_sources=None, extra_bootstub_driver_sources=None):
65167
project_dir = Dir(f'./board/obj/{project_name}/')
66168

67169
flags = project["FLAGS"] + extra_flags + common_flags + [
@@ -100,21 +202,58 @@ def build_project(project_name, project, main, extra_flags):
100202
)
101203

102204
startup = env.Object(project["STARTUP_FILE"])
205+
libc_obj = env.Object("./board/libc.c")
206+
crc_obj = env.Object("./board/crc.c")
207+
provision_obj = env.Object("./board/provision.c")
208+
critical_obj = env.Object("./board/sys/critical.c")
209+
faults_obj = env.Object("./board/sys/faults.c")
210+
main_globals_obj = env.Object("./board/main_globals.c")
211+
gitversion_obj = env.Object("./board/obj/gitversion.c")
212+
213+
drv_env = env.Clone()
214+
drv_env.Append(CFLAGS="-DDRIVER_BUILD")
215+
early_init_obj = drv_env.Object("./board/early_init.c")
103216

104217
# Build bootstub
105218
bs_env = env.Clone()
106219
bs_env.Append(CFLAGS="-DBOOTSTUB", ASFLAGS="-DBOOTSTUB", LINKFLAGS="-DBOOTSTUB")
220+
bs_env['OBJPREFIX'] = Dir(f'{project_dir}/bs_')
221+
bs_drv_env = bs_env.Clone()
222+
bs_drv_env.Append(CFLAGS="-DDRIVER_BUILD")
223+
bs_all_driver_sources = bootstub_common_driver_sources + (extra_bootstub_driver_sources or [])
224+
bs_driver_objs = [bs_drv_env.Object(src) for src in bs_all_driver_sources]
107225
bs_elf = bs_env.Program(f"{project_dir}/bootstub.elf", [
108226
startup,
109227
"./board/crypto/rsa.c",
110228
"./board/crypto/sha.c",
229+
libc_obj,
230+
crc_obj,
231+
provision_obj,
232+
critical_obj,
233+
faults_obj,
234+
gitversion_obj,
235+
bs_env.Object("./board/bootstub_globals.c"),
236+
bs_drv_env.Object("./board/early_init.c"),
237+
bs_drv_env.Object("./board/flasher.c"),
238+
] + bs_driver_objs + [
111239
"./board/bootstub.c",
112240
])
113241
bs_env.Objcopy(f"./board/obj/bootstub.{project_name}.bin", bs_elf)
114242

115243
# Build + sign main (aka app)
244+
driver_sources = common_driver_sources + (extra_driver_sources or [])
245+
driver_objs = [drv_env.Object(src) for src in driver_sources]
116246
main_elf = env.Program(f"{project_dir}/main.elf", [
117247
startup,
248+
libc_obj,
249+
crc_obj,
250+
provision_obj,
251+
critical_obj,
252+
faults_obj,
253+
main_globals_obj,
254+
gitversion_obj,
255+
early_init_obj,
256+
] + driver_objs + [
118257
main
119258
], LINKFLAGS=[f"-Wl,--section-start,.isr_vector={project['APP_START_ADDRESS']}"] + flags)
120259
main_bin = env.Objcopy(f"{project_dir}/main.bin", main_elf)
@@ -141,6 +280,10 @@ base_project_h7 = {
141280
with open("board/obj/gitversion.h", "w") as f:
142281
version = get_version(BUILDER, BUILD_TYPE)
143282
f.write(f'extern const uint8_t gitversion[{len(version)+1}];\n')
283+
284+
with open("board/obj/gitversion.c", "w") as f:
285+
version = get_version(BUILDER, BUILD_TYPE)
286+
f.write(f'#include <stdint.h>\n')
144287
f.write(f'const uint8_t gitversion[{len(version)+1}] = "{version}";\n')
145288

146289
with open("board/obj/version", "w") as f:
@@ -160,16 +303,22 @@ common_flags += [f"-DHEALTH_PACKET_VERSION=0x{hh:08X}U", f"-DCAN_PACKET_VERSION_
160303
f"-DJUNGLE_HEALTH_PACKET_VERSION=0x{jh:08X}U"]
161304

162305
# panda fw
163-
build_project("panda_h7", base_project_h7, "./board/main.c", [])
306+
build_project("panda_h7", base_project_h7, "./board/main.c", [],
307+
extra_driver_sources=panda_extra_driver_sources,
308+
extra_bootstub_driver_sources=panda_extra_bootstub_driver_sources)
164309

165310
# panda jungle fw
166311
flags = [
167312
"-DPANDA_JUNGLE",
168313
]
169-
build_project("panda_jungle_h7", base_project_h7, "./board/jungle/main.c", flags)
314+
build_project("panda_jungle_h7", base_project_h7, "./board/jungle/main.c", flags,
315+
extra_driver_sources=jungle_extra_driver_sources,
316+
extra_bootstub_driver_sources=jungle_extra_bootstub_driver_sources)
170317

171318
# body fw
172-
build_project("body_h7", base_project_h7, "./board/body/main.c", ["-DPANDA_BODY"])
319+
build_project("body_h7", base_project_h7, "./board/body/main.c", ["-DPANDA_BODY"],
320+
extra_driver_sources=body_extra_driver_sources,
321+
extra_bootstub_driver_sources=body_extra_bootstub_driver_sources)
173322

174323
# test files
175324
SConscript('tests/libpanda/SConscript')

board/boards/cuatro.c

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
#include "board/config.h"
2+
#include "board/boards/unused_funcs.h"
3+
#include "board/boards/tres.h"
4+
#include "board/boards/cuatro.h"
5+
#include "board/drivers/fake_siren.h"
6+
7+
// ////////////////////////// //
8+
// Cuatro (STM32H7) + Harness //
9+
// ////////////////////////// //
10+
11+
static void cuatro_enable_can_transceiver(uint8_t transceiver, bool enabled) {
12+
switch (transceiver) {
13+
case 1U:
14+
set_gpio_output(GPIOB, 7, !enabled);
15+
break;
16+
case 2U:
17+
set_gpio_output(GPIOB, 10, !enabled);
18+
break;
19+
case 3U:
20+
set_gpio_output(GPIOD, 8, !enabled);
21+
break;
22+
case 4U:
23+
set_gpio_output(GPIOB, 11, !enabled);
24+
break;
25+
default:
26+
break;
27+
}
28+
}
29+
30+
static uint32_t cuatro_read_voltage_mV(void) {
31+
return adc_get_mV(&(const adc_signal_t) ADC_CHANNEL_DEFAULT(ADC1, 8)) * 11U;
32+
}
33+
34+
static uint32_t cuatro_read_current_mA(void) {
35+
return adc_get_mV(&(const adc_signal_t) ADC_CHANNEL_DEFAULT(ADC1, 3)) * 2U;
36+
}
37+
38+
static void cuatro_set_fan_enabled(bool enabled) {
39+
set_gpio_output(GPIOD, 3, !enabled);
40+
}
41+
42+
static void cuatro_set_bootkick(BootState state) {
43+
set_gpio_output(GPIOA, 0, state != BOOT_BOOTKICK);
44+
// DC_IN rising edge wakes SOM from ship mode
45+
set_gpio_output(GPIOC, 11, state != BOOT_BOOTKICK);
46+
}
47+
48+
static void cuatro_set_amp_enabled(bool enabled) {
49+
set_gpio_output(GPIOB, 0, enabled);
50+
}
51+
52+
static void cuatro_init(void) {
53+
common_init_gpio();
54+
55+
// open drain
56+
set_gpio_output_type(GPIOD, 3, OUTPUT_TYPE_OPEN_DRAIN); // FAN_EN
57+
set_gpio_output_type(GPIOC, 11, OUTPUT_TYPE_OPEN_DRAIN); // DC_IN_EN_N
58+
59+
// Power readout
60+
set_gpio_mode(GPIOC, 5, MODE_ANALOG);
61+
set_gpio_mode(GPIOA, 6, MODE_ANALOG);
62+
63+
// CAN transceiver enables
64+
set_gpio_pullup(GPIOB, 7, PULL_NONE);
65+
set_gpio_mode(GPIOB, 7, MODE_OUTPUT);
66+
set_gpio_pullup(GPIOD, 8, PULL_NONE);
67+
set_gpio_mode(GPIOD, 8, MODE_OUTPUT);
68+
69+
// FDCAN3, different pins on this package than the rest of the reds
70+
set_gpio_pullup(GPIOD, 12, PULL_NONE);
71+
set_gpio_alternate(GPIOD, 12, GPIO_AF5_FDCAN3);
72+
set_gpio_pullup(GPIOD, 13, PULL_NONE);
73+
set_gpio_alternate(GPIOD, 13, GPIO_AF5_FDCAN3);
74+
75+
// C2: SOM GPIO used as input (fan control at boot)
76+
set_gpio_mode(GPIOC, 2, MODE_INPUT);
77+
set_gpio_pullup(GPIOC, 2, PULL_DOWN);
78+
79+
// SOM bootkick + reset lines
80+
cuatro_set_bootkick(BOOT_BOOTKICK);
81+
82+
// SOM debugging UART
83+
gpio_uart7_init();
84+
uart_init(&uart_ring_som_debug, 115200);
85+
86+
// fan setup
87+
set_gpio_alternate(GPIOC, 8, GPIO_AF2_TIM3);
88+
register_set_bits(&(GPIOC->OTYPER), GPIO_OTYPER_OT8); // open drain
89+
90+
// Clock source
91+
clock_source_init(true);
92+
93+
// Sound codec
94+
cuatro_set_amp_enabled(false);
95+
set_gpio_alternate(GPIOA, 2, GPIO_AF8_SAI4); // SAI4_SCK_B
96+
set_gpio_alternate(GPIOC, 0, GPIO_AF8_SAI4); // SAI4_FS_B
97+
set_gpio_alternate(GPIOD, 11, GPIO_AF10_SAI4); // SAI4_SD_A
98+
set_gpio_alternate(GPIOE, 3, GPIO_AF8_SAI4); // SAI4_SD_B
99+
set_gpio_alternate(GPIOE, 4, GPIO_AF3_DFSDM1); // DFSDM1_DATIN3
100+
set_gpio_alternate(GPIOE, 9, GPIO_AF3_DFSDM1); // DFSDM1_CKOUT
101+
set_gpio_alternate(GPIOE, 6, GPIO_AF10_SAI4); // SAI4_MCLK_B
102+
sound_init();
103+
}
104+
105+
static harness_configuration cuatro_harness_config = {
106+
.GPIO_SBU1 = GPIOC,
107+
.GPIO_SBU2 = GPIOA,
108+
.GPIO_relay_SBU1 = GPIOA,
109+
.GPIO_relay_SBU2 = GPIOA,
110+
.pin_SBU1 = 4,
111+
.pin_SBU2 = 1,
112+
.pin_relay_SBU1 = 9,
113+
.pin_relay_SBU2 = 3,
114+
.adc_signal_SBU1 = ADC_CHANNEL_DEFAULT(ADC1, 4),
115+
.adc_signal_SBU2 = ADC_CHANNEL_DEFAULT(ADC1, 17)
116+
};
117+
118+
board board_cuatro = {
119+
.harness_config = &cuatro_harness_config,
120+
.has_spi = true,
121+
.has_fan = true,
122+
.avdd_mV = 1800U,
123+
.fan_enable_cooldown_time = 3U,
124+
.init = cuatro_init,
125+
.init_bootloader = unused_init_bootloader,
126+
.enable_can_transceiver = cuatro_enable_can_transceiver,
127+
.led_GPIO = {GPIOC, GPIOC, GPIOC},
128+
.led_pin = {6, 7, 9},
129+
.led_pwm_channels = {1, 2, 4},
130+
.set_can_mode = tres_set_can_mode,
131+
.read_voltage_mV = cuatro_read_voltage_mV,
132+
.read_current_mA = cuatro_read_current_mA,
133+
.set_fan_enabled = cuatro_set_fan_enabled,
134+
.set_ir_power = unused_set_ir_power,
135+
.set_siren = fake_siren_set,
136+
.set_bootkick = cuatro_set_bootkick,
137+
.read_som_gpio = tres_read_som_gpio,
138+
.set_amp_enabled = cuatro_set_amp_enabled
139+
};

0 commit comments

Comments
 (0)