openpilot v0.9.6 release
date: 2024-01-12T10:13:37 master commit: ba792d576a49a0899b88a753fa1c52956bedf9e6
This commit is contained in:
1
panda/board/pedal/.gitignore
vendored
Normal file
1
panda/board/pedal/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
obj/*
|
||||
28
panda/board/pedal/README.md
Normal file
28
panda/board/pedal/README.md
Normal file
@@ -0,0 +1,28 @@
|
||||
# pedal
|
||||
|
||||
This is the firmware for the comma pedal.
|
||||
|
||||
The comma pedal is a gas pedal interceptor for Honda/Acura and Toyota/Lexus. It allows you to "virtually" press the pedal and borrows a lot from panda.
|
||||
|
||||
== Test Plan ==
|
||||
|
||||
* Startup
|
||||
** Confirm STATE_FAULT_STARTUP
|
||||
* Timeout
|
||||
** Send value
|
||||
** Confirm value is output
|
||||
** Stop sending messages
|
||||
** Confirm value is passthru after 100ms
|
||||
** Confirm STATE_FAULT_TIMEOUT
|
||||
* Random values
|
||||
** Send random 6 byte messages
|
||||
** Confirm random values cause passthru
|
||||
** Confirm STATE_FAULT_BAD_CHECKSUM
|
||||
* Same message lockout
|
||||
** Send same message repeated
|
||||
** Confirm timeout behavior
|
||||
* Don't set enable
|
||||
** Confirm no output
|
||||
* Set enable and values
|
||||
** Confirm output
|
||||
|
||||
28
panda/board/pedal/SConscript
Normal file
28
panda/board/pedal/SConscript
Normal file
@@ -0,0 +1,28 @@
|
||||
import copy
|
||||
|
||||
Import('build_project')
|
||||
|
||||
build_projects = {}
|
||||
|
||||
build_projects["pedal"] = {
|
||||
"MAIN": "main.c",
|
||||
"BOOTSTUB": "../bootstub.c",
|
||||
"STARTUP_FILE": "../stm32fx/startup_stm32f205xx.s",
|
||||
"LINKER_SCRIPT": "../stm32fx/stm32f2_flash.ld",
|
||||
"APP_START_ADDRESS": "0x8004000",
|
||||
"PROJECT_FLAGS": [
|
||||
"-mcpu=cortex-m3",
|
||||
"-msoft-float",
|
||||
"-DSTM32F2",
|
||||
"-DSTM32F205xx",
|
||||
"-O2",
|
||||
"-DPEDAL",
|
||||
],
|
||||
}
|
||||
|
||||
# build with the USB driver enabled
|
||||
build_projects["pedal_usb"] = copy.deepcopy(build_projects["pedal"])
|
||||
build_projects["pedal_usb"]["PROJECT_FLAGS"].append("-DPEDAL_USB")
|
||||
|
||||
for project_name, project in build_projects.items():
|
||||
build_project(project_name, project, [])
|
||||
8
panda/board/pedal/flash_can.sh
Executable file
8
panda/board/pedal/flash_can.sh
Executable file
@@ -0,0 +1,8 @@
|
||||
#!/usr/bin/env sh
|
||||
set -e
|
||||
|
||||
cd ..
|
||||
scons -u -j$(nproc)
|
||||
cd pedal
|
||||
|
||||
../../tests/pedal/enter_canloader.py obj/pedal.bin.signed
|
||||
316
panda/board/pedal/main.c
Normal file
316
panda/board/pedal/main.c
Normal file
@@ -0,0 +1,316 @@
|
||||
// ********************* Includes *********************
|
||||
//#define PEDAL_USB
|
||||
#include "../config.h"
|
||||
|
||||
#include "early_init.h"
|
||||
#include "crc.h"
|
||||
|
||||
#define CAN CAN1
|
||||
|
||||
#ifdef PEDAL_USB
|
||||
#include "drivers/usb.h"
|
||||
#else
|
||||
// no serial either
|
||||
void print(const char *a) {
|
||||
UNUSED(a);
|
||||
}
|
||||
void puth(unsigned int i) {
|
||||
UNUSED(i);
|
||||
}
|
||||
void puth2(unsigned int i) {
|
||||
UNUSED(i);
|
||||
}
|
||||
#endif
|
||||
|
||||
#define ENTER_BOOTLOADER_MAGIC 0xdeadbeefU
|
||||
uint32_t enter_bootloader_mode;
|
||||
|
||||
// cppcheck-suppress unusedFunction ; used in headers not included in cppcheck
|
||||
void __initialize_hardware_early(void) {
|
||||
early_initialization();
|
||||
}
|
||||
|
||||
// ********************* serial debugging *********************
|
||||
|
||||
#ifdef PEDAL_USB
|
||||
|
||||
void debug_ring_callback(uart_ring *ring) {
|
||||
char rcv;
|
||||
while (getc(ring, &rcv) != 0) {
|
||||
(void)putc(ring, rcv);
|
||||
}
|
||||
}
|
||||
|
||||
int comms_can_read(uint8_t *data, uint32_t max_len) {
|
||||
UNUSED(data);
|
||||
UNUSED(max_len);
|
||||
return 0;
|
||||
}
|
||||
void comms_can_write(uint8_t *data, uint32_t len) {
|
||||
UNUSED(data);
|
||||
UNUSED(len);
|
||||
}
|
||||
void comms_endpoint2_write(uint8_t *data, uint32_t len) {
|
||||
UNUSED(data);
|
||||
UNUSED(len);
|
||||
}
|
||||
void refresh_can_tx_slots_available(void) {}
|
||||
|
||||
int comms_control_handler(ControlPacket_t *req, uint8_t *resp) {
|
||||
unsigned int resp_len = 0;
|
||||
uart_ring *ur = NULL;
|
||||
switch (req->request) {
|
||||
// **** 0xc1: get hardware type
|
||||
case 0xc1:
|
||||
resp[0] = hw_type;
|
||||
resp_len = 1;
|
||||
break;
|
||||
// **** 0xe0: uart read
|
||||
case 0xe0:
|
||||
ur = get_ring_by_number(req->param1);
|
||||
if (!ur) {
|
||||
break;
|
||||
}
|
||||
// read
|
||||
while ((resp_len < MIN(req->length, USBPACKET_MAX_SIZE)) &&
|
||||
getc(ur, (char*)&resp[resp_len])) {
|
||||
++resp_len;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
print("NO HANDLER ");
|
||||
puth(req->request);
|
||||
print("\n");
|
||||
break;
|
||||
}
|
||||
return resp_len;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// ***************************** can port *****************************
|
||||
|
||||
// addresses to be used on CAN
|
||||
#define CAN_GAS_INPUT 0x200
|
||||
#define CAN_GAS_OUTPUT 0x201U
|
||||
#define CAN_GAS_SIZE 6
|
||||
#define COUNTER_CYCLE 0xFU
|
||||
|
||||
void CAN1_TX_IRQ_Handler(void) {
|
||||
// clear interrupt
|
||||
CAN->TSR |= CAN_TSR_RQCP0;
|
||||
}
|
||||
|
||||
// two independent values
|
||||
uint16_t gas_set_0 = 0;
|
||||
uint16_t gas_set_1 = 0;
|
||||
|
||||
#define MAX_TIMEOUT 10U
|
||||
uint32_t timeout = 0;
|
||||
uint32_t current_index = 0;
|
||||
|
||||
#define NO_FAULT 0U
|
||||
#define FAULT_BAD_CHECKSUM 1U
|
||||
#define FAULT_SEND 2U
|
||||
#define FAULT_SCE 3U
|
||||
#define FAULT_STARTUP 4U
|
||||
#define FAULT_TIMEOUT 5U
|
||||
#define FAULT_INVALID 6U
|
||||
uint8_t state = FAULT_STARTUP;
|
||||
const uint8_t crc_poly = 0xD5U; // standard crc8
|
||||
|
||||
void CAN1_RX0_IRQ_Handler(void) {
|
||||
while ((CAN->RF0R & CAN_RF0R_FMP0) != 0) {
|
||||
#ifdef DEBUG
|
||||
print("CAN RX\n");
|
||||
#endif
|
||||
int address = CAN->sFIFOMailBox[0].RIR >> 21;
|
||||
if (address == CAN_GAS_INPUT) {
|
||||
// softloader entry
|
||||
if (GET_MAILBOX_BYTES_04(&CAN->sFIFOMailBox[0]) == 0xdeadface) {
|
||||
if (GET_MAILBOX_BYTES_48(&CAN->sFIFOMailBox[0]) == 0x0ab00b1e) {
|
||||
enter_bootloader_mode = ENTER_SOFTLOADER_MAGIC;
|
||||
NVIC_SystemReset();
|
||||
} else if (GET_MAILBOX_BYTES_48(&CAN->sFIFOMailBox[0]) == 0x02b00b1e) {
|
||||
enter_bootloader_mode = ENTER_BOOTLOADER_MAGIC;
|
||||
NVIC_SystemReset();
|
||||
} else {
|
||||
print("Failed entering Softloader or Bootloader\n");
|
||||
}
|
||||
}
|
||||
|
||||
// normal packet
|
||||
uint8_t dat[8];
|
||||
for (int i=0; i<8; i++) {
|
||||
dat[i] = GET_MAILBOX_BYTE(&CAN->sFIFOMailBox[0], i);
|
||||
}
|
||||
uint16_t value_0 = (dat[0] << 8) | dat[1];
|
||||
uint16_t value_1 = (dat[2] << 8) | dat[3];
|
||||
bool enable = ((dat[4] >> 7) & 1U) != 0U;
|
||||
uint8_t index = dat[4] & COUNTER_CYCLE;
|
||||
if (crc_checksum(dat, CAN_GAS_SIZE - 1, crc_poly) == dat[5]) {
|
||||
if (((current_index + 1U) & COUNTER_CYCLE) == index) {
|
||||
#ifdef DEBUG
|
||||
print("setting gas ");
|
||||
puth(value_0);
|
||||
print("\n");
|
||||
#endif
|
||||
if (enable) {
|
||||
gas_set_0 = value_0;
|
||||
gas_set_1 = value_1;
|
||||
} else {
|
||||
// clear the fault state if values are 0
|
||||
if ((value_0 == 0U) && (value_1 == 0U)) {
|
||||
state = NO_FAULT;
|
||||
} else {
|
||||
state = FAULT_INVALID;
|
||||
}
|
||||
gas_set_0 = 0;
|
||||
gas_set_1 = 0;
|
||||
}
|
||||
// clear the timeout
|
||||
timeout = 0;
|
||||
}
|
||||
current_index = index;
|
||||
} else {
|
||||
// wrong checksum = fault
|
||||
state = FAULT_BAD_CHECKSUM;
|
||||
}
|
||||
}
|
||||
// next
|
||||
CAN->RF0R |= CAN_RF0R_RFOM0;
|
||||
}
|
||||
}
|
||||
|
||||
void CAN1_SCE_IRQ_Handler(void) {
|
||||
state = FAULT_SCE;
|
||||
llcan_clear_send(CAN);
|
||||
}
|
||||
|
||||
uint32_t pdl0 = 0;
|
||||
uint32_t pdl1 = 0;
|
||||
unsigned int pkt_idx = 0;
|
||||
|
||||
int led_value = 0;
|
||||
|
||||
void TIM3_IRQ_Handler(void) {
|
||||
#ifdef DEBUG
|
||||
puth(TIM3->CNT);
|
||||
print(" ");
|
||||
puth(pdl0);
|
||||
print(" ");
|
||||
puth(pdl1);
|
||||
print("\n");
|
||||
#endif
|
||||
|
||||
// check timer for sending the user pedal and clearing the CAN
|
||||
if ((CAN->TSR & CAN_TSR_TME0) == CAN_TSR_TME0) {
|
||||
uint8_t dat[8];
|
||||
dat[0] = (pdl0 >> 8) & 0xFFU;
|
||||
dat[1] = (pdl0 >> 0) & 0xFFU;
|
||||
dat[2] = (pdl1 >> 8) & 0xFFU;
|
||||
dat[3] = (pdl1 >> 0) & 0xFFU;
|
||||
dat[4] = ((state & 0xFU) << 4) | pkt_idx;
|
||||
dat[5] = crc_checksum(dat, CAN_GAS_SIZE - 1, crc_poly);
|
||||
CAN->sTxMailBox[0].TDLR = dat[0] | (dat[1] << 8) | (dat[2] << 16) | (dat[3] << 24);
|
||||
CAN->sTxMailBox[0].TDHR = dat[4] | (dat[5] << 8);
|
||||
CAN->sTxMailBox[0].TDTR = 6; // len of packet is 5
|
||||
CAN->sTxMailBox[0].TIR = (CAN_GAS_OUTPUT << 21) | 1U;
|
||||
++pkt_idx;
|
||||
pkt_idx &= COUNTER_CYCLE;
|
||||
} else {
|
||||
// old can packet hasn't sent!
|
||||
state = FAULT_SEND;
|
||||
#ifdef DEBUG
|
||||
print("CAN MISS\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
// blink the LED
|
||||
current_board->set_led(LED_GREEN, led_value);
|
||||
led_value = !led_value;
|
||||
|
||||
TIM3->SR = 0;
|
||||
|
||||
// up timeout for gas set
|
||||
if (timeout == MAX_TIMEOUT) {
|
||||
state = FAULT_TIMEOUT;
|
||||
} else {
|
||||
timeout += 1U;
|
||||
}
|
||||
}
|
||||
|
||||
// ***************************** main code *****************************
|
||||
|
||||
void pedal(void) {
|
||||
// read/write
|
||||
pdl0 = adc_get_raw(ADCCHAN_ACCEL0);
|
||||
pdl1 = adc_get_raw(ADCCHAN_ACCEL1);
|
||||
|
||||
// write the pedal to the DAC
|
||||
if (state == NO_FAULT) {
|
||||
dac_set(0, MAX(gas_set_0, pdl0));
|
||||
dac_set(1, MAX(gas_set_1, pdl1));
|
||||
} else {
|
||||
dac_set(0, pdl0);
|
||||
dac_set(1, pdl1);
|
||||
}
|
||||
|
||||
watchdog_feed();
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
// Init interrupt table
|
||||
init_interrupts(true);
|
||||
|
||||
REGISTER_INTERRUPT(CAN1_TX_IRQn, CAN1_TX_IRQ_Handler, CAN_INTERRUPT_RATE, FAULT_INTERRUPT_RATE_CAN_1)
|
||||
REGISTER_INTERRUPT(CAN1_RX0_IRQn, CAN1_RX0_IRQ_Handler, CAN_INTERRUPT_RATE, FAULT_INTERRUPT_RATE_CAN_1)
|
||||
REGISTER_INTERRUPT(CAN1_SCE_IRQn, CAN1_SCE_IRQ_Handler, CAN_INTERRUPT_RATE, FAULT_INTERRUPT_RATE_CAN_1)
|
||||
|
||||
// Should run at around 732Hz (see init below)
|
||||
REGISTER_INTERRUPT(TIM3_IRQn, TIM3_IRQ_Handler, 1000U, FAULT_INTERRUPT_RATE_TIM3)
|
||||
|
||||
disable_interrupts();
|
||||
|
||||
// init devices
|
||||
clock_init();
|
||||
peripherals_init();
|
||||
detect_board_type();
|
||||
|
||||
// init board
|
||||
current_board->init();
|
||||
|
||||
#ifdef PEDAL_USB
|
||||
// enable USB
|
||||
usb_init();
|
||||
#endif
|
||||
|
||||
// pedal stuff
|
||||
dac_init();
|
||||
adc_init();
|
||||
|
||||
// init can
|
||||
bool llcan_speed_set = llcan_set_speed(CAN, 5000, false, false);
|
||||
if (!llcan_speed_set) {
|
||||
print("Failed to set llcan speed");
|
||||
}
|
||||
|
||||
bool ret = llcan_init(CAN);
|
||||
UNUSED(ret);
|
||||
|
||||
// 48mhz / 65536 ~= 732
|
||||
timer_init(TIM3, 15);
|
||||
NVIC_EnableIRQ(TIM3_IRQn);
|
||||
|
||||
watchdog_init(WATCHDOG_50_MS);
|
||||
|
||||
print("**** INTERRUPTS ON ****\n");
|
||||
enable_interrupts();
|
||||
|
||||
// main pedal loop
|
||||
while (1) {
|
||||
pedal();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
11
panda/board/pedal/main_declarations.h
Normal file
11
panda/board/pedal/main_declarations.h
Normal file
@@ -0,0 +1,11 @@
|
||||
// ******************** Prototypes ********************
|
||||
void print(const char *a);
|
||||
void puth(unsigned int i);
|
||||
void puth2(unsigned int i);
|
||||
void puth4(unsigned int i);
|
||||
typedef struct board board;
|
||||
typedef struct harness_configuration harness_configuration;
|
||||
|
||||
// ********************* Globals **********************
|
||||
uint8_t hw_type = 0;
|
||||
const board *current_board;
|
||||
11
panda/board/pedal/recover.sh
Executable file
11
panda/board/pedal/recover.sh
Executable file
@@ -0,0 +1,11 @@
|
||||
#!/usr/bin/env sh
|
||||
set -e
|
||||
|
||||
DFU_UTIL="dfu-util"
|
||||
|
||||
cd ..
|
||||
scons -u -j$(nproc)
|
||||
cd pedal
|
||||
|
||||
$DFU_UTIL -d 0483:df11 -a 0 -s 0x08004000 -D obj/pedal.bin.signed
|
||||
$DFU_UTIL -d 0483:df11 -a 0 -s 0x08000000:leave -D obj/bootstub.pedal.bin
|
||||
Reference in New Issue
Block a user