mirror of
https://github.com/dragonpilot/dragonpilot.git
synced 2026-06-23 06:52:07 +08:00
Merge panda subtree
This commit is contained in:
@@ -12,6 +12,37 @@ jobs:
|
||||
name: Run safety test
|
||||
command: |
|
||||
docker run panda_safety /bin/bash -c "cd /panda/tests/safety; ./test.sh"
|
||||
|
||||
misra-c2012:
|
||||
machine:
|
||||
docker_layer_caching: true
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: Build image
|
||||
command: "docker build -t panda_misra -f tests/misra/Dockerfile ."
|
||||
- run:
|
||||
name: Run Misra C 2012 test
|
||||
command: |
|
||||
mkdir /tmp/misra
|
||||
docker run -v /tmp/misra:/tmp/misra panda_misra /bin/bash -c "cd /panda/tests/misra; ./test_misra.sh"
|
||||
- store_artifacts:
|
||||
name: Store misra test output
|
||||
path: /tmp/misra/output.txt
|
||||
|
||||
strict-compiler:
|
||||
machine:
|
||||
docker_layer_caching: true
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: Build image
|
||||
command: "docker build -t panda_strict_compiler -f tests/build_strict/Dockerfile ."
|
||||
- run:
|
||||
name: Build Panda with strict compiler rules
|
||||
command: |
|
||||
docker run panda_strict_compiler /bin/bash -c "cd /panda/board; make -f Makefile.strict clean; make -f Makefile.strict bin"
|
||||
|
||||
build:
|
||||
machine:
|
||||
docker_layer_caching: true
|
||||
@@ -40,10 +71,6 @@ jobs:
|
||||
name: Build Pedal STM bootstub image
|
||||
command: |
|
||||
docker run panda_build /bin/bash -c "cd /panda/board/pedal; make obj/bootstub.bin"
|
||||
- run:
|
||||
name: Build NEO STM image
|
||||
command: |
|
||||
docker run panda_build /bin/bash -c "cd /panda/board; make clean; make -f Makefile.legacy obj/comma.bin"
|
||||
- run:
|
||||
name: Build ESP image
|
||||
command: |
|
||||
@@ -54,4 +81,6 @@ workflows:
|
||||
main:
|
||||
jobs:
|
||||
- safety
|
||||
- misra-c2012
|
||||
- strict-compiler
|
||||
- build
|
||||
|
||||
+3
-2
@@ -10,5 +10,6 @@ a.out
|
||||
dist/
|
||||
pandacan.egg-info/
|
||||
board/obj/
|
||||
examples/output.csv
|
||||
.DS_Store
|
||||
examples/output.csv
|
||||
.DS_Store
|
||||
nosetests.xml
|
||||
|
||||
@@ -59,6 +59,4 @@ USER pandauser
|
||||
RUN cd /tmp/panda/boardesp && ./get_sdk_ci.sh
|
||||
USER root
|
||||
|
||||
COPY ./xx/pandaextra /tmp/pandaextra
|
||||
|
||||
ADD ./panda.tar.gz /tmp/panda
|
||||
|
||||
Vendored
-2
@@ -14,8 +14,6 @@ pipeline {
|
||||
steps {
|
||||
timeout(time: 60, unit: 'MINUTES') {
|
||||
script {
|
||||
sh 'git clone --no-checkout --depth 1 git@github.com:commaai/xx.git || true'
|
||||
sh 'cd xx && git fetch origin && git checkout origin/master -- pandaextra && cd ..' // Needed for certs for panda flashing
|
||||
sh 'git archive -v -o panda.tar.gz --format=tar.gz HEAD'
|
||||
dockerImage = docker.build("${env.DOCKER_IMAGE_TAG}")
|
||||
}
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
v1.2.1
|
||||
v1.3.1
|
||||
@@ -1,9 +0,0 @@
|
||||
# :set noet
|
||||
PROJ_NAME = comma
|
||||
CFLAGS = -g -Wall
|
||||
|
||||
CFLAGS += -mlittle-endian -mthumb -mcpu=cortex-m3
|
||||
CFLAGS += -msoft-float -DSTM32F2 -DSTM32F205xx
|
||||
STARTUP_FILE = startup_stm32f205xx
|
||||
|
||||
include build.mk
|
||||
@@ -0,0 +1,8 @@
|
||||
PROJ_NAME = panda
|
||||
CFLAGS = -g -Wall -Wextra -pedantic -Wstrict-prototypes
|
||||
|
||||
CFLAGS += -mlittle-endian -mthumb -mcpu=cortex-m4
|
||||
CFLAGS += -mhard-float -DSTM32F4 -DSTM32F413xx -mfpu=fpv4-sp-d16 -fsingle-precision-constant
|
||||
STARTUP_FILE = startup_stm32f413xx
|
||||
|
||||
include build.mk
|
||||
@@ -23,12 +23,6 @@ Programming
|
||||
make
|
||||
```
|
||||
|
||||
**NEO**
|
||||
|
||||
```
|
||||
make -f Makefile.legacy
|
||||
```
|
||||
|
||||
Troubleshooting
|
||||
----
|
||||
|
||||
|
||||
+5
-11
@@ -12,11 +12,14 @@
|
||||
#include "stm32f2xx_hal_gpio_ex.h"
|
||||
#endif
|
||||
|
||||
// default since there's no serial
|
||||
int puts(const char *a) { return 0; }
|
||||
void puth(unsigned int i) {}
|
||||
|
||||
#include "libc.h"
|
||||
#include "provision.h"
|
||||
|
||||
#include "drivers/drivers.h"
|
||||
|
||||
#include "drivers/clock.h"
|
||||
#include "drivers/llgpio.h"
|
||||
#include "gpio.h"
|
||||
|
||||
@@ -24,15 +27,6 @@
|
||||
#include "drivers/usb.h"
|
||||
//#include "drivers/uart.h"
|
||||
|
||||
#ifdef PEDAL
|
||||
#define CUSTOM_CAN_INTERRUPTS
|
||||
#include "safety.h"
|
||||
#include "drivers/can.h"
|
||||
#endif
|
||||
|
||||
int puts(const char *a) { return 0; }
|
||||
void puth(unsigned int i) {}
|
||||
|
||||
#include "crypto/rsa.h"
|
||||
#include "crypto/sha.h"
|
||||
|
||||
|
||||
+61
-216
@@ -1,10 +1,38 @@
|
||||
// IRQs: CAN1_TX, CAN1_RX0, CAN1_SCE, CAN2_TX, CAN2_RX0, CAN2_SCE, CAN3_TX, CAN3_RX0, CAN3_SCE
|
||||
// IRQs: CAN1_TX, CAN1_RX0, CAN1_SCE
|
||||
// CAN2_TX, CAN2_RX0, CAN2_SCE
|
||||
// CAN3_TX, CAN3_RX0, CAN3_SCE
|
||||
|
||||
typedef struct {
|
||||
uint32_t w_ptr;
|
||||
uint32_t r_ptr;
|
||||
uint32_t fifo_size;
|
||||
CAN_FIFOMailBox_TypeDef *elems;
|
||||
} can_ring;
|
||||
|
||||
#define CAN_BUS_RET_FLAG 0x80
|
||||
#define CAN_BUS_NUM_MASK 0x7F
|
||||
|
||||
#define BUS_MAX 4
|
||||
|
||||
extern int can_live, pending_can_live;
|
||||
|
||||
// must reinit after changing these
|
||||
extern int can_loopback, can_silent;
|
||||
extern uint32_t can_speed[];
|
||||
|
||||
void can_set_forwarding(int from, int to);
|
||||
|
||||
void can_init(uint8_t can_number);
|
||||
void can_init_all();
|
||||
void can_send(CAN_FIFOMailBox_TypeDef *to_push, uint8_t bus_number);
|
||||
int can_pop(can_ring *q, CAN_FIFOMailBox_TypeDef *elem);
|
||||
|
||||
// end API
|
||||
|
||||
#define ALL_CAN_SILENT 0xFF
|
||||
#define ALL_CAN_BUT_MAIN_SILENT 0xFE
|
||||
#define ALL_CAN_LIVE 0
|
||||
|
||||
#include "lline_relay.h"
|
||||
|
||||
int can_live = 0, pending_can_live = 0, can_loopback = 0, can_silent = ALL_CAN_SILENT;
|
||||
|
||||
// ********************* instantiate queues *********************
|
||||
@@ -16,19 +44,9 @@ int can_live = 0, pending_can_live = 0, can_loopback = 0, can_silent = ALL_CAN_S
|
||||
can_buffer(rx_q, 0x1000)
|
||||
can_buffer(tx1_q, 0x100)
|
||||
can_buffer(tx2_q, 0x100)
|
||||
|
||||
#ifdef PANDA
|
||||
can_buffer(tx3_q, 0x100)
|
||||
can_buffer(txgmlan_q, 0x100)
|
||||
can_ring *can_queues[] = {&can_tx1_q, &can_tx2_q, &can_tx3_q, &can_txgmlan_q};
|
||||
#else
|
||||
can_ring *can_queues[] = {&can_tx1_q, &can_tx2_q};
|
||||
#endif
|
||||
|
||||
#ifdef PANDA
|
||||
// Forward declare
|
||||
void power_save_reset_timer();
|
||||
#endif
|
||||
can_buffer(tx3_q, 0x100)
|
||||
can_buffer(txgmlan_q, 0x100)
|
||||
can_ring *can_queues[] = {&can_tx1_q, &can_tx2_q, &can_tx3_q, &can_txgmlan_q};
|
||||
|
||||
// ********************* interrupt safe queue *********************
|
||||
|
||||
@@ -85,76 +103,20 @@ int can_tx_cnt = 0;
|
||||
int can_txd_cnt = 0;
|
||||
int can_err_cnt = 0;
|
||||
|
||||
// NEO: Bus 1=CAN1 Bus 2=CAN2
|
||||
// Panda: Bus 0=CAN1 Bus 1=CAN2 Bus 2=CAN3
|
||||
#ifdef PANDA
|
||||
CAN_TypeDef *cans[] = {CAN1, CAN2, CAN3};
|
||||
uint8_t bus_lookup[] = {0,1,2};
|
||||
uint8_t can_num_lookup[] = {0,1,2,-1};
|
||||
int8_t can_forwarding[] = {-1,-1,-1,-1};
|
||||
uint32_t can_speed[] = {5000, 5000, 5000, 333};
|
||||
bool can_autobaud_enabled[] = {false, false, false, false};
|
||||
#define CAN_MAX 3
|
||||
#else
|
||||
CAN_TypeDef *cans[] = {CAN1, CAN2};
|
||||
uint8_t bus_lookup[] = {1,0};
|
||||
uint8_t can_num_lookup[] = {1,0};
|
||||
int8_t can_forwarding[] = {-1,-1};
|
||||
uint32_t can_speed[] = {5000, 5000};
|
||||
bool can_autobaud_enabled[] = {false, false};
|
||||
#define CAN_MAX 2
|
||||
#endif
|
||||
|
||||
uint32_t can_autobaud_speeds[] = {5000, 2500, 1250, 1000, 10000};
|
||||
#define AUTOBAUD_SPEEDS_LEN (sizeof(can_autobaud_speeds) / sizeof(can_autobaud_speeds[0]))
|
||||
CAN_TypeDef *cans[] = {CAN1, CAN2, CAN3};
|
||||
uint8_t bus_lookup[] = {0,1,2};
|
||||
uint8_t can_num_lookup[] = {0,1,2,-1};
|
||||
int8_t can_forwarding[] = {-1,-1,-1,-1};
|
||||
uint32_t can_speed[] = {5000, 5000, 5000, 333};
|
||||
#define CAN_MAX 3
|
||||
|
||||
#define CANIF_FROM_CAN_NUM(num) (cans[num])
|
||||
#ifdef PANDA
|
||||
#define CAN_NUM_FROM_CANIF(CAN) (CAN==CAN1 ? 0 : (CAN==CAN2 ? 1 : 2))
|
||||
#define CAN_NAME_FROM_CANIF(CAN) (CAN==CAN1 ? "CAN1" : (CAN==CAN2 ? "CAN2" : "CAN3"))
|
||||
#else
|
||||
#define CAN_NUM_FROM_CANIF(CAN) (CAN==CAN1 ? 0 : 1)
|
||||
#define CAN_NAME_FROM_CANIF(CAN) (CAN==CAN1 ? "CAN1" : "CAN2")
|
||||
#endif
|
||||
#define BUS_NUM_FROM_CAN_NUM(num) (bus_lookup[num])
|
||||
#define CAN_NUM_FROM_BUS_NUM(num) (can_num_lookup[num])
|
||||
|
||||
// other option
|
||||
/*#define CAN_QUANTA 16
|
||||
#define CAN_SEQ1 13
|
||||
#define CAN_SEQ2 2*/
|
||||
|
||||
// this is needed for 1 mbps support
|
||||
#define CAN_QUANTA 8
|
||||
#define CAN_SEQ1 6 // roundf(quanta * 0.875f) - 1;
|
||||
#define CAN_SEQ2 1 // roundf(quanta * 0.125f);
|
||||
|
||||
#define CAN_PCLK 24000
|
||||
// 333 = 33.3 kbps
|
||||
// 5000 = 500 kbps
|
||||
#define can_speed_to_prescaler(x) (CAN_PCLK / CAN_QUANTA * 10 / (x))
|
||||
|
||||
void can_autobaud_speed_increment(uint8_t can_number) {
|
||||
uint32_t autobaud_speed = can_autobaud_speeds[0];
|
||||
uint8_t bus_number = BUS_NUM_FROM_CAN_NUM(can_number);
|
||||
for (int i = 0; i < AUTOBAUD_SPEEDS_LEN; i++) {
|
||||
if (can_speed[bus_number] == can_autobaud_speeds[i]) {
|
||||
if (i+1 < AUTOBAUD_SPEEDS_LEN) {
|
||||
autobaud_speed = can_autobaud_speeds[i+1];
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
can_speed[bus_number] = autobaud_speed;
|
||||
#ifdef DEBUG
|
||||
CAN_TypeDef* CAN = CANIF_FROM_CAN_NUM(can_number);
|
||||
puts(CAN_NAME_FROM_CANIF(CAN));
|
||||
puts(" auto-baud test ");
|
||||
putui(can_speed[bus_number]);
|
||||
puts(" cbps\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
void process_can(uint8_t can_number);
|
||||
|
||||
void can_set_speed(uint8_t can_number) {
|
||||
@@ -162,41 +124,14 @@ void can_set_speed(uint8_t can_number) {
|
||||
uint8_t bus_number = BUS_NUM_FROM_CAN_NUM(can_number);
|
||||
|
||||
while (true) {
|
||||
// initialization mode
|
||||
CAN->MCR = CAN_MCR_TTCM | CAN_MCR_INRQ;
|
||||
while((CAN->MSR & CAN_MSR_INAK) != CAN_MSR_INAK);
|
||||
|
||||
// set time quanta from defines
|
||||
CAN->BTR = (CAN_BTR_TS1_0 * (CAN_SEQ1-1)) |
|
||||
(CAN_BTR_TS2_0 * (CAN_SEQ2-1)) |
|
||||
(can_speed_to_prescaler(can_speed[bus_number]) - 1);
|
||||
|
||||
// silent loopback mode for debugging
|
||||
if (can_loopback) {
|
||||
CAN->BTR |= CAN_BTR_SILM | CAN_BTR_LBKM;
|
||||
}
|
||||
if (can_silent & (1 << can_number)) {
|
||||
CAN->BTR |= CAN_BTR_SILM;
|
||||
}
|
||||
|
||||
// reset
|
||||
CAN->MCR = CAN_MCR_TTCM | CAN_MCR_ABOM;
|
||||
|
||||
#define CAN_TIMEOUT 1000000
|
||||
int tmp = 0;
|
||||
while((CAN->MSR & CAN_MSR_INAK) == CAN_MSR_INAK && tmp < CAN_TIMEOUT) tmp++;
|
||||
if (tmp < CAN_TIMEOUT) {
|
||||
if (llcan_set_speed(CAN, can_speed[bus_number], can_loopback, can_silent & (1 << can_number))) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (can_autobaud_enabled[bus_number]) {
|
||||
can_autobaud_speed_increment(can_number);
|
||||
} else {
|
||||
puts("CAN init FAILED!!!!!\n");
|
||||
puth(can_number); puts(" ");
|
||||
puth(BUS_NUM_FROM_CAN_NUM(can_number)); puts("\n");
|
||||
return;
|
||||
}
|
||||
puts("CAN init FAILED!!!!!\n");
|
||||
puth(can_number); puts(" ");
|
||||
puth(BUS_NUM_FROM_CAN_NUM(can_number)); puts("\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -207,40 +142,7 @@ void can_init(uint8_t can_number) {
|
||||
set_can_enable(CAN, 1);
|
||||
can_set_speed(can_number);
|
||||
|
||||
// accept all filter
|
||||
CAN->FMR |= CAN_FMR_FINIT;
|
||||
|
||||
// no mask
|
||||
CAN->sFilterRegister[0].FR1 = 0;
|
||||
CAN->sFilterRegister[0].FR2 = 0;
|
||||
CAN->sFilterRegister[14].FR1 = 0;
|
||||
CAN->sFilterRegister[14].FR2 = 0;
|
||||
CAN->FA1R |= 1 | (1 << 14);
|
||||
|
||||
CAN->FMR &= ~(CAN_FMR_FINIT);
|
||||
|
||||
// enable certain CAN interrupts
|
||||
CAN->IER |= CAN_IER_TMEIE | CAN_IER_FMPIE0 | CAN_IER_WKUIE;
|
||||
|
||||
switch (can_number) {
|
||||
case 0:
|
||||
NVIC_EnableIRQ(CAN1_TX_IRQn);
|
||||
NVIC_EnableIRQ(CAN1_RX0_IRQn);
|
||||
NVIC_EnableIRQ(CAN1_SCE_IRQn);
|
||||
break;
|
||||
case 1:
|
||||
NVIC_EnableIRQ(CAN2_TX_IRQn);
|
||||
NVIC_EnableIRQ(CAN2_RX0_IRQn);
|
||||
NVIC_EnableIRQ(CAN2_SCE_IRQn);
|
||||
break;
|
||||
#ifdef CAN3
|
||||
case 2:
|
||||
NVIC_EnableIRQ(CAN3_TX_IRQn);
|
||||
NVIC_EnableIRQ(CAN3_RX0_IRQn);
|
||||
NVIC_EnableIRQ(CAN3_SCE_IRQn);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
llcan_init(CAN);
|
||||
|
||||
// in case there are queued up messages
|
||||
process_can(can_number);
|
||||
@@ -253,7 +155,6 @@ void can_init_all() {
|
||||
}
|
||||
|
||||
void can_set_gmlan(int bus) {
|
||||
#ifdef PANDA
|
||||
if (bus == -1 || bus != can_num_lookup[3]) {
|
||||
// GMLAN OFF
|
||||
switch (can_num_lookup[3]) {
|
||||
@@ -284,7 +185,7 @@ void can_set_gmlan(int bus) {
|
||||
can_num_lookup[1] = -1;
|
||||
can_num_lookup[3] = 1;
|
||||
can_init(1);
|
||||
} else if (bus == 2 && revision == PANDA_REV_C) {
|
||||
} else if (bus == 2) {
|
||||
puts("GMLAN on CAN3\n");
|
||||
// GMLAN on CAN3
|
||||
set_can_mode(2, 1);
|
||||
@@ -293,7 +194,6 @@ void can_set_gmlan(int bus) {
|
||||
can_num_lookup[3] = 2;
|
||||
can_init(2);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// CAN error
|
||||
@@ -319,34 +219,8 @@ void can_sce(CAN_TypeDef *CAN) {
|
||||
puts("\n");
|
||||
#endif
|
||||
|
||||
uint8_t can_number = CAN_NUM_FROM_CANIF(CAN);
|
||||
uint8_t bus_number = BUS_NUM_FROM_CAN_NUM(can_number);
|
||||
|
||||
if (CAN->MSR & CAN_MSR_WKUI) {
|
||||
//Waking from sleep
|
||||
#ifdef DEBUG
|
||||
puts("WAKE\n");
|
||||
#endif
|
||||
set_can_enable(CAN, 1);
|
||||
CAN->MSR &= ~(CAN_MSR_WKUI);
|
||||
CAN->MSR = CAN->MSR;
|
||||
#ifdef PANDA
|
||||
power_save_reset_timer();
|
||||
#endif
|
||||
} else {
|
||||
can_err_cnt += 1;
|
||||
|
||||
|
||||
if (can_autobaud_enabled[bus_number] && (CAN->ESR & CAN_ESR_LEC)) {
|
||||
can_autobaud_speed_increment(can_number);
|
||||
can_set_speed(can_number);
|
||||
}
|
||||
|
||||
// clear current send
|
||||
CAN->TSR |= CAN_TSR_ABRQ0;
|
||||
CAN->MSR &= ~(CAN_MSR_ERRI);
|
||||
CAN->MSR = CAN->MSR;
|
||||
}
|
||||
can_err_cnt += 1;
|
||||
llcan_clear_send(CAN);
|
||||
exit_critical_section();
|
||||
}
|
||||
|
||||
@@ -354,9 +228,6 @@ void can_sce(CAN_TypeDef *CAN) {
|
||||
|
||||
void process_can(uint8_t can_number) {
|
||||
if (can_number == 0xff) return;
|
||||
#ifdef PANDA
|
||||
power_save_reset_timer();
|
||||
#endif
|
||||
|
||||
enter_critical_section();
|
||||
|
||||
@@ -422,22 +293,9 @@ void process_can(uint8_t can_number) {
|
||||
// CAN receive handlers
|
||||
// blink blue when we are receiving CAN messages
|
||||
void can_rx(uint8_t can_number) {
|
||||
#ifdef PANDA
|
||||
power_save_reset_timer();
|
||||
#endif
|
||||
CAN_TypeDef *CAN = CANIF_FROM_CAN_NUM(can_number);
|
||||
uint8_t bus_number = BUS_NUM_FROM_CAN_NUM(can_number);
|
||||
while (CAN->RF0R & CAN_RF0R_FMP0) {
|
||||
if (can_autobaud_enabled[bus_number]) {
|
||||
can_autobaud_enabled[bus_number] = false;
|
||||
puts(CAN_NAME_FROM_CANIF(CAN));
|
||||
#ifdef DEBUG
|
||||
puts(" auto-baud ");
|
||||
putui(can_speed[bus_number]);
|
||||
puts(" cbps\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
can_rx_cnt += 1;
|
||||
|
||||
// can is live
|
||||
@@ -454,25 +312,19 @@ void can_rx(uint8_t can_number) {
|
||||
to_push.RDTR = (to_push.RDTR & 0xFFFF000F) | (bus_number << 4);
|
||||
|
||||
// forwarding (panda only)
|
||||
#ifdef PANDA
|
||||
if ((get_lline_status() != 0) || !relay_control) { //Relay engaged or relay isn't controlled, allow fwd
|
||||
int bus_fwd_num = can_forwarding[bus_number] != -1 ? can_forwarding[bus_number] : safety_fwd_hook(bus_number, &to_push);
|
||||
if (bus_fwd_num != -1) {
|
||||
CAN_FIFOMailBox_TypeDef to_send;
|
||||
to_send.RIR = to_push.RIR | 1; // TXRQ
|
||||
to_send.RDTR = to_push.RDTR;
|
||||
to_send.RDLR = to_push.RDLR;
|
||||
to_send.RDHR = to_push.RDHR;
|
||||
can_send(&to_send, bus_fwd_num);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
int bus_fwd_num = can_forwarding[bus_number] != -1 ? can_forwarding[bus_number] : safety_fwd_hook(bus_number, &to_push);
|
||||
if (bus_fwd_num != -1) {
|
||||
CAN_FIFOMailBox_TypeDef to_send;
|
||||
to_send.RIR = to_push.RIR | 1; // TXRQ
|
||||
to_send.RDTR = to_push.RDTR;
|
||||
to_send.RDLR = to_push.RDLR;
|
||||
to_send.RDHR = to_push.RDHR;
|
||||
can_send(&to_send, bus_fwd_num);
|
||||
}
|
||||
|
||||
safety_rx_hook(&to_push);
|
||||
|
||||
#ifdef PANDA
|
||||
set_led(LED_BLUE, 1);
|
||||
#endif
|
||||
set_led(LED_BLUE, 1);
|
||||
can_push(&can_rx_q, &to_push);
|
||||
|
||||
// next
|
||||
@@ -480,8 +332,6 @@ void can_rx(uint8_t can_number) {
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef CUSTOM_CAN_INTERRUPTS
|
||||
|
||||
void CAN1_TX_IRQHandler() { process_can(0); }
|
||||
void CAN1_RX0_IRQHandler() { can_rx(0); }
|
||||
void CAN1_SCE_IRQHandler() { can_sce(CAN1); }
|
||||
@@ -490,25 +340,19 @@ void CAN2_TX_IRQHandler() { process_can(1); }
|
||||
void CAN2_RX0_IRQHandler() { can_rx(1); }
|
||||
void CAN2_SCE_IRQHandler() { can_sce(CAN2); }
|
||||
|
||||
#ifdef CAN3
|
||||
void CAN3_TX_IRQHandler() { process_can(2); }
|
||||
void CAN3_RX0_IRQHandler() { can_rx(2); }
|
||||
void CAN3_SCE_IRQHandler() { can_sce(CAN3); }
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
void can_send(CAN_FIFOMailBox_TypeDef *to_push, uint8_t bus_number) {
|
||||
if (safety_tx_hook(to_push) && !can_autobaud_enabled[bus_number]) {
|
||||
if (safety_tx_hook(to_push)) {
|
||||
if (bus_number < BUS_MAX) {
|
||||
// add CAN packet to send queue
|
||||
// bus number isn't passed through
|
||||
to_push->RDTR &= 0xF;
|
||||
if (bus_number == 3 && can_num_lookup[3] == 0xFF) {
|
||||
#ifdef PANDA
|
||||
// TODO: why uint8 bro? only int8?
|
||||
bitbang_gmlan(to_push);
|
||||
#endif
|
||||
} else {
|
||||
can_push(can_queues[bus_number], to_push);
|
||||
process_can(CAN_NUM_FROM_BUS_NUM(bus_number));
|
||||
@@ -520,3 +364,4 @@ void can_send(CAN_FIFOMailBox_TypeDef *to_push, uint8_t bus_number) {
|
||||
void can_set_forwarding(int from, int to) {
|
||||
can_forwarding[from] = to;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
void clock_init() {
|
||||
// enable external oscillator
|
||||
RCC->CR |= RCC_CR_HSEON;
|
||||
while ((RCC->CR & RCC_CR_HSERDY) == 0);
|
||||
|
||||
// divide shit
|
||||
RCC->CFGR = RCC_CFGR_HPRE_DIV1 | RCC_CFGR_PPRE2_DIV2 | RCC_CFGR_PPRE1_DIV4;
|
||||
|
||||
// 16mhz crystal
|
||||
RCC->PLLCFGR = RCC_PLLCFGR_PLLQ_2 | RCC_PLLCFGR_PLLM_3 |
|
||||
RCC_PLLCFGR_PLLN_6 | RCC_PLLCFGR_PLLN_5 | RCC_PLLCFGR_PLLSRC_HSE;
|
||||
|
||||
// start PLL
|
||||
RCC->CR |= RCC_CR_PLLON;
|
||||
while ((RCC->CR & RCC_CR_PLLRDY) == 0);
|
||||
|
||||
// Configure Flash prefetch, Instruction cache, Data cache and wait state
|
||||
// *** without this, it breaks ***
|
||||
FLASH->ACR = FLASH_ACR_ICEN | FLASH_ACR_DCEN | FLASH_ACR_LATENCY_5WS;
|
||||
|
||||
// switch to PLL
|
||||
RCC->CFGR |= RCC_CFGR_SW_PLL;
|
||||
while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL);
|
||||
|
||||
// *** running on PLL ***
|
||||
}
|
||||
|
||||
void watchdog_init() {
|
||||
// setup watchdog
|
||||
IWDG->KR = 0x5555;
|
||||
IWDG->PR = 0; // divider /4
|
||||
// 0 = 0.125 ms, let's have a 50ms watchdog
|
||||
IWDG->RLR = 400 - 1;
|
||||
IWDG->KR = 0xCCCC;
|
||||
}
|
||||
|
||||
void watchdog_feed() {
|
||||
IWDG->KR = 0xAAAA;
|
||||
}
|
||||
|
||||
@@ -1,141 +0,0 @@
|
||||
#ifndef PANDA_DRIVERS_H
|
||||
#define PANDA_DRIVERS_H
|
||||
|
||||
// ********************* LLGPIO *********************
|
||||
|
||||
#define MODE_INPUT 0
|
||||
#define MODE_OUTPUT 1
|
||||
#define MODE_ALTERNATE 2
|
||||
#define MODE_ANALOG 3
|
||||
|
||||
#define PULL_NONE 0
|
||||
#define PULL_UP 1
|
||||
#define PULL_DOWN 2
|
||||
|
||||
void set_gpio_mode(GPIO_TypeDef *GPIO, int pin, int mode);
|
||||
void set_gpio_output(GPIO_TypeDef *GPIO, int pin, int val);
|
||||
void set_gpio_alternate(GPIO_TypeDef *GPIO, int pin, int mode);
|
||||
void set_gpio_pullup(GPIO_TypeDef *GPIO, int pin, int mode);
|
||||
|
||||
int get_gpio_input(GPIO_TypeDef *GPIO, int pin);
|
||||
|
||||
|
||||
// ********************* USB *********************
|
||||
// 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();
|
||||
int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, int hardwired);
|
||||
int usb_cb_ep1_in(uint8_t *usbdata, int len, int hardwired);
|
||||
void usb_cb_ep2_out(uint8_t *usbdata, int len, int hardwired);
|
||||
void usb_cb_ep3_out(uint8_t *usbdata, int len, int hardwired);
|
||||
void usb_cb_enumeration_complete();
|
||||
|
||||
|
||||
// ********************* UART *********************
|
||||
// IRQs: USART1, USART2, USART3, UART5
|
||||
|
||||
#define FIFO_SIZE 0x400
|
||||
typedef struct uart_ring {
|
||||
uint16_t w_ptr_tx;
|
||||
uint16_t r_ptr_tx;
|
||||
uint8_t elems_tx[FIFO_SIZE];
|
||||
uint16_t w_ptr_rx;
|
||||
uint16_t r_ptr_rx;
|
||||
uint8_t elems_rx[FIFO_SIZE];
|
||||
USART_TypeDef *uart;
|
||||
void (*callback)(struct uart_ring*);
|
||||
} uart_ring;
|
||||
|
||||
void uart_init(USART_TypeDef *u, int baud);
|
||||
|
||||
int getc(uart_ring *q, char *elem);
|
||||
int putc(uart_ring *q, char elem);
|
||||
|
||||
int puts(const char *a);
|
||||
void puth(unsigned int i);
|
||||
void hexdump(const void *a, int l);
|
||||
|
||||
|
||||
// ********************* ADC *********************
|
||||
|
||||
void adc_init();
|
||||
uint32_t adc_get(int channel);
|
||||
|
||||
|
||||
// ********************* DAC *********************
|
||||
|
||||
void dac_init();
|
||||
void dac_set(int channel, uint32_t value);
|
||||
|
||||
|
||||
// ********************* TIMER *********************
|
||||
|
||||
void timer_init(TIM_TypeDef *TIM, int psc);
|
||||
|
||||
|
||||
// ********************* SPI *********************
|
||||
// IRQs: DMA2_Stream2, DMA2_Stream3, EXTI4
|
||||
|
||||
void spi_init();
|
||||
int spi_cb_rx(uint8_t *data, int len, uint8_t *data_out);
|
||||
|
||||
|
||||
// ********************* CAN *********************
|
||||
// IRQs: CAN1_TX, CAN1_RX0, CAN1_SCE
|
||||
// CAN2_TX, CAN2_RX0, CAN2_SCE
|
||||
// CAN3_TX, CAN3_RX0, CAN3_SCE
|
||||
|
||||
typedef struct {
|
||||
uint32_t w_ptr;
|
||||
uint32_t r_ptr;
|
||||
uint32_t fifo_size;
|
||||
CAN_FIFOMailBox_TypeDef *elems;
|
||||
} can_ring;
|
||||
|
||||
#define CAN_BUS_RET_FLAG 0x80
|
||||
#define CAN_BUS_NUM_MASK 0x7F
|
||||
|
||||
#ifdef PANDA
|
||||
#define BUS_MAX 4
|
||||
#else
|
||||
#define BUS_MAX 2
|
||||
#endif
|
||||
|
||||
extern int can_live, pending_can_live;
|
||||
|
||||
// must reinit after changing these
|
||||
extern int can_loopback, can_silent;
|
||||
extern uint32_t can_speed[];
|
||||
|
||||
void can_set_forwarding(int from, int to);
|
||||
|
||||
void can_init(uint8_t can_number);
|
||||
void can_init_all();
|
||||
void can_send(CAN_FIFOMailBox_TypeDef *to_push, uint8_t bus_number);
|
||||
int can_pop(can_ring *q, CAN_FIFOMailBox_TypeDef *elem);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -114,8 +114,6 @@ int get_bit_message(char *out, CAN_FIFOMailBox_TypeDef *to_bang) {
|
||||
return len;
|
||||
}
|
||||
|
||||
#ifdef PANDA
|
||||
|
||||
void setup_timer4() {
|
||||
// setup
|
||||
TIM4->PSC = 48-1; // tick on 1 us
|
||||
@@ -273,4 +271,3 @@ void bitbang_gmlan(CAN_FIFOMailBox_TypeDef *to_bang) {
|
||||
setup_timer4();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
// this is needed for 1 mbps support
|
||||
#define CAN_QUANTA 8
|
||||
#define CAN_SEQ1 6 // roundf(quanta * 0.875f) - 1;
|
||||
#define CAN_SEQ2 1 // roundf(quanta * 0.125f);
|
||||
|
||||
#define CAN_PCLK 24000
|
||||
// 333 = 33.3 kbps
|
||||
// 5000 = 500 kbps
|
||||
#define can_speed_to_prescaler(x) (CAN_PCLK / CAN_QUANTA * 10 / (x))
|
||||
|
||||
bool llcan_set_speed(CAN_TypeDef *CAN, uint32_t speed, bool loopback, bool silent) {
|
||||
// initialization mode
|
||||
CAN->MCR = CAN_MCR_TTCM | CAN_MCR_INRQ;
|
||||
while((CAN->MSR & CAN_MSR_INAK) != CAN_MSR_INAK);
|
||||
|
||||
// set time quanta from defines
|
||||
CAN->BTR = (CAN_BTR_TS1_0 * (CAN_SEQ1-1)) |
|
||||
(CAN_BTR_TS2_0 * (CAN_SEQ2-1)) |
|
||||
(can_speed_to_prescaler(speed) - 1);
|
||||
|
||||
// silent loopback mode for debugging
|
||||
if (loopback) {
|
||||
CAN->BTR |= CAN_BTR_SILM | CAN_BTR_LBKM;
|
||||
}
|
||||
if (silent) {
|
||||
CAN->BTR |= CAN_BTR_SILM;
|
||||
}
|
||||
|
||||
// reset
|
||||
CAN->MCR = CAN_MCR_TTCM | CAN_MCR_ABOM;
|
||||
|
||||
#define CAN_TIMEOUT 1000000
|
||||
int tmp = 0;
|
||||
while((CAN->MSR & CAN_MSR_INAK) == CAN_MSR_INAK && tmp < CAN_TIMEOUT) tmp++;
|
||||
if (tmp < CAN_TIMEOUT) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void llcan_init(CAN_TypeDef *CAN) {
|
||||
// accept all filter
|
||||
CAN->FMR |= CAN_FMR_FINIT;
|
||||
|
||||
// no mask
|
||||
CAN->sFilterRegister[0].FR1 = 0;
|
||||
CAN->sFilterRegister[0].FR2 = 0;
|
||||
CAN->sFilterRegister[14].FR1 = 0;
|
||||
CAN->sFilterRegister[14].FR2 = 0;
|
||||
CAN->FA1R |= 1 | (1 << 14);
|
||||
|
||||
CAN->FMR &= ~(CAN_FMR_FINIT);
|
||||
|
||||
// enable certain CAN interrupts
|
||||
CAN->IER |= CAN_IER_TMEIE | CAN_IER_FMPIE0 | CAN_IER_WKUIE;
|
||||
|
||||
if (CAN == CAN1) {
|
||||
NVIC_EnableIRQ(CAN1_TX_IRQn);
|
||||
NVIC_EnableIRQ(CAN1_RX0_IRQn);
|
||||
NVIC_EnableIRQ(CAN1_SCE_IRQn);
|
||||
} else if (CAN == CAN2) {
|
||||
NVIC_EnableIRQ(CAN2_TX_IRQn);
|
||||
NVIC_EnableIRQ(CAN2_RX0_IRQn);
|
||||
NVIC_EnableIRQ(CAN2_SCE_IRQn);
|
||||
#ifdef CAN3
|
||||
} else if (CAN == CAN3) {
|
||||
NVIC_EnableIRQ(CAN3_TX_IRQn);
|
||||
NVIC_EnableIRQ(CAN3_RX0_IRQn);
|
||||
NVIC_EnableIRQ(CAN3_SCE_IRQn);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void llcan_clear_send(CAN_TypeDef *CAN) {
|
||||
CAN->TSR |= CAN_TSR_ABRQ0;
|
||||
CAN->MSR &= ~(CAN_MSR_ERRI);
|
||||
CAN->MSR = CAN->MSR;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,12 @@
|
||||
#define MODE_INPUT 0
|
||||
#define MODE_OUTPUT 1
|
||||
#define MODE_ALTERNATE 2
|
||||
#define MODE_ANALOG 3
|
||||
|
||||
#define PULL_NONE 0
|
||||
#define PULL_UP 1
|
||||
#define PULL_DOWN 2
|
||||
|
||||
void set_gpio_mode(GPIO_TypeDef *GPIO, int pin, int mode) {
|
||||
uint32_t tmp = GPIO->MODER;
|
||||
tmp &= ~(3 << (pin*2));
|
||||
|
||||
@@ -1,88 +0,0 @@
|
||||
#ifdef PANDA
|
||||
|
||||
int relay_control = 0; // True if relay is controlled through l-line
|
||||
|
||||
/* Conrol a relay connected to l-line pin */
|
||||
|
||||
// 160us cycles, 1 high, 25 low
|
||||
|
||||
volatile int turn_on_relay = 0;
|
||||
volatile int on_cycles = 25;
|
||||
|
||||
//5s timeout
|
||||
#define LLINE_TIMEOUT_CYCLES 31250
|
||||
volatile int timeout_cycles = LLINE_TIMEOUT_CYCLES;
|
||||
|
||||
void TIM5_IRQHandler(void) {
|
||||
if (TIM5->SR & TIM_SR_UIF) {
|
||||
on_cycles--;
|
||||
timeout_cycles--;
|
||||
if (timeout_cycles == 0) {
|
||||
turn_on_relay = 0;
|
||||
}
|
||||
if (on_cycles > 0) {
|
||||
if (turn_on_relay) {
|
||||
set_gpio_output(GPIOC, 10, 0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
set_gpio_output(GPIOC, 10, 1);
|
||||
on_cycles = 25;
|
||||
}
|
||||
}
|
||||
TIM5->ARR = 160-1;
|
||||
TIM5->SR = 0;
|
||||
}
|
||||
|
||||
void lline_relay_init (void) {
|
||||
set_lline_output(0);
|
||||
relay_control = 1;
|
||||
set_gpio_output(GPIOC, 10, 1);
|
||||
|
||||
// setup
|
||||
TIM5->PSC = 48-1; // tick on 1 us
|
||||
TIM5->CR1 = TIM_CR1_CEN; // enable
|
||||
TIM5->ARR = 50-1; // 50 us
|
||||
TIM5->DIER = TIM_DIER_UIE; // update interrupt
|
||||
TIM5->CNT = 0;
|
||||
|
||||
NVIC_EnableIRQ(TIM5_IRQn);
|
||||
|
||||
#ifdef DEBUG
|
||||
puts("INIT LLINE\n");
|
||||
puts(" SR ");
|
||||
putui(TIM5->SR);
|
||||
puts(" PSC ");
|
||||
putui(TIM5->PSC);
|
||||
puts(" CR1 ");
|
||||
putui(TIM5->CR1);
|
||||
puts(" ARR ");
|
||||
putui(TIM5->ARR);
|
||||
puts(" DIER ");
|
||||
putui(TIM5->DIER);
|
||||
puts(" SR ");
|
||||
putui(TIM5->SR);
|
||||
puts(" CNT ");
|
||||
putui(TIM5->CNT);
|
||||
puts("\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
void lline_relay_release (void) {
|
||||
set_lline_output(0);
|
||||
relay_control = 0;
|
||||
puts("RELEASE LLINE\n");
|
||||
set_gpio_alternate(GPIOC, 10, GPIO_AF7_USART3);
|
||||
NVIC_DisableIRQ(TIM5_IRQn);
|
||||
}
|
||||
|
||||
void set_lline_output(int to_set) {
|
||||
timeout_cycles = LLINE_TIMEOUT_CYCLES;
|
||||
turn_on_relay = to_set;
|
||||
}
|
||||
|
||||
int get_lline_status() {
|
||||
return turn_on_relay;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,5 +1,10 @@
|
||||
// IRQs: DMA2_Stream2, DMA2_Stream3, EXTI4
|
||||
|
||||
void spi_init();
|
||||
int spi_cb_rx(uint8_t *data, int len, uint8_t *data_out);
|
||||
|
||||
// end API
|
||||
|
||||
#define SPI_BUF_SIZE 256
|
||||
uint8_t spi_buf[SPI_BUF_SIZE];
|
||||
int spi_buf_count = 0;
|
||||
@@ -23,8 +28,8 @@ void spi_init() {
|
||||
|
||||
// setup interrupt on falling edge of SPI enable (on PA4)
|
||||
SYSCFG->EXTICR[2] = SYSCFG_EXTICR2_EXTI4_PA;
|
||||
EXTI->IMR = (1 << 4);
|
||||
EXTI->FTSR = (1 << 4);
|
||||
EXTI->IMR |= (1 << 4);
|
||||
EXTI->FTSR |= (1 << 4);
|
||||
NVIC_EnableIRQ(EXTI4_IRQn);
|
||||
}
|
||||
|
||||
@@ -108,7 +113,7 @@ void DMA2_Stream3_IRQHandler(void) {
|
||||
}
|
||||
|
||||
void EXTI4_IRQHandler(void) {
|
||||
volatile int pr = EXTI->PR;
|
||||
volatile int pr = EXTI->PR & (1 << 4);
|
||||
#ifdef DEBUG_SPI
|
||||
puts("exti4\n");
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,27 @@
|
||||
// IRQs: USART1, USART2, USART3, UART5
|
||||
|
||||
#define FIFO_SIZE 0x400
|
||||
typedef struct uart_ring {
|
||||
uint16_t w_ptr_tx;
|
||||
uint16_t r_ptr_tx;
|
||||
uint8_t elems_tx[FIFO_SIZE];
|
||||
uint16_t w_ptr_rx;
|
||||
uint16_t r_ptr_rx;
|
||||
uint8_t elems_rx[FIFO_SIZE];
|
||||
USART_TypeDef *uart;
|
||||
void (*callback)(struct uart_ring*);
|
||||
} uart_ring;
|
||||
|
||||
void uart_init(USART_TypeDef *u, int baud);
|
||||
|
||||
int getc(uart_ring *q, char *elem);
|
||||
int putc(uart_ring *q, char elem);
|
||||
|
||||
int puts(const char *a);
|
||||
void puth(unsigned int i);
|
||||
void hexdump(const void *a, int l);
|
||||
|
||||
|
||||
// ***************************** serial port queues *****************************
|
||||
|
||||
// esp = USART1
|
||||
|
||||
+31
-17
@@ -1,5 +1,35 @@
|
||||
// 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();
|
||||
int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, int hardwired);
|
||||
int usb_cb_ep1_in(uint8_t *usbdata, int len, int hardwired);
|
||||
void usb_cb_ep2_out(uint8_t *usbdata, int len, int hardwired);
|
||||
void usb_cb_ep3_out(uint8_t *usbdata, int len, int hardwired);
|
||||
void usb_cb_enumeration_complete();
|
||||
|
||||
// **** supporting defines ****
|
||||
|
||||
typedef struct
|
||||
@@ -186,17 +216,10 @@ uint16_t string_manufacturer_desc[] = {
|
||||
'c', 'o', 'm', 'm', 'a', '.', 'a', 'i'
|
||||
};
|
||||
|
||||
#ifdef PANDA
|
||||
uint16_t string_product_desc[] = {
|
||||
STRING_DESCRIPTOR_HEADER(5),
|
||||
'p', 'a', 'n', 'd', 'a'
|
||||
};
|
||||
#else
|
||||
uint16_t string_product_desc[] = {
|
||||
STRING_DESCRIPTOR_HEADER(5),
|
||||
'N', 'E', 'O', 'v', '1'
|
||||
};
|
||||
#endif
|
||||
|
||||
// default serial number when we're not a panda
|
||||
uint16_t string_serial_desc[] = {
|
||||
@@ -210,7 +233,6 @@ uint16_t string_configuration_desc[] = {
|
||||
'0', '1' // "01"
|
||||
};
|
||||
|
||||
#ifdef PANDA
|
||||
// WCID (auto install WinUSB driver)
|
||||
// https://github.com/pbatard/libwdi/wiki/WCID-Devices
|
||||
// https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/winusb-installation#automatic-installation-of--winusb-without-an-inf-file
|
||||
@@ -360,8 +382,6 @@ uint8_t winusb_20_desc[WINUSB_PLATFORM_DESCRIPTOR_LENGTH] = {
|
||||
'1', 0x00, 'a', 0x00, 'd', 0x00, 'e', 0x00, '9', 0x00, '}', 0x00, 0x00, 0x00 // 78 bytes
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
// current packet
|
||||
USB_Setup_TypeDef setup;
|
||||
uint8_t usbdata[0x100];
|
||||
@@ -550,7 +570,7 @@ void usb_setup() {
|
||||
USB_WritePacket((uint8_t*)string_product_desc, min(sizeof(string_product_desc), setup.b.wLength.w), 0);
|
||||
break;
|
||||
case STRING_OFFSET_ISERIAL:
|
||||
#ifdef PANDA
|
||||
#ifdef UID_BASE
|
||||
resp[0] = 0x02 + 12*4;
|
||||
resp[1] = 0x03;
|
||||
|
||||
@@ -568,14 +588,12 @@ void usb_setup() {
|
||||
USB_WritePacket((const uint8_t *)string_serial_desc, min(sizeof(string_serial_desc), setup.b.wLength.w), 0);
|
||||
#endif
|
||||
break;
|
||||
#ifdef PANDA
|
||||
case STRING_OFFSET_ICONFIGURATION:
|
||||
USB_WritePacket((uint8_t*)string_configuration_desc, min(sizeof(string_configuration_desc), setup.b.wLength.w), 0);
|
||||
break;
|
||||
case 238:
|
||||
USB_WritePacket((uint8_t*)string_238_desc, min(sizeof(string_238_desc), setup.b.wLength.w), 0);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
// nothing
|
||||
USB_WritePacket(0, 0, 0);
|
||||
@@ -583,12 +601,10 @@ void usb_setup() {
|
||||
}
|
||||
USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK;
|
||||
break;
|
||||
#ifdef PANDA
|
||||
case USB_DESC_TYPE_BINARY_OBJECT_STORE:
|
||||
USB_WritePacket(binary_object_store_desc, min(sizeof(binary_object_store_desc), setup.b.wLength.w), 0);
|
||||
USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
// nothing here?
|
||||
USB_WritePacket(0, 0, 0);
|
||||
@@ -609,7 +625,6 @@ void usb_setup() {
|
||||
USB_WritePacket(0, 0, 0);
|
||||
USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK;
|
||||
break;
|
||||
#ifdef PANDA
|
||||
case WEBUSB_VENDOR_CODE:
|
||||
switch (setup.b.wIndex.w) {
|
||||
case WEBUSB_REQ_GET_URL:
|
||||
@@ -641,7 +656,6 @@ void usb_setup() {
|
||||
USB_WritePacket_EP0(0, 0);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
resp_len = usb_cb_control_msg(&setup, resp, 1);
|
||||
USB_WritePacket(resp, min(resp_len, setup.b.wLength.w), 0);
|
||||
|
||||
+15
-62
@@ -1,3 +1,5 @@
|
||||
// this is last place with ifdef PANDA
|
||||
|
||||
#ifdef STM32F4
|
||||
#include "stm32f4xx_hal_gpio_ex.h"
|
||||
#else
|
||||
@@ -61,43 +63,6 @@ void detect() {
|
||||
|
||||
// ********************* bringup *********************
|
||||
|
||||
void clock_init() {
|
||||
// enable external oscillator
|
||||
RCC->CR |= RCC_CR_HSEON;
|
||||
while ((RCC->CR & RCC_CR_HSERDY) == 0);
|
||||
|
||||
// divide shit
|
||||
RCC->CFGR = RCC_CFGR_HPRE_DIV1 | RCC_CFGR_PPRE2_DIV2 | RCC_CFGR_PPRE1_DIV4;
|
||||
#ifdef PANDA
|
||||
RCC->PLLCFGR = RCC_PLLCFGR_PLLQ_2 | RCC_PLLCFGR_PLLM_3 |
|
||||
RCC_PLLCFGR_PLLN_6 | RCC_PLLCFGR_PLLN_5 | RCC_PLLCFGR_PLLSRC_HSE;
|
||||
#else
|
||||
#ifdef PEDAL
|
||||
// comma pedal has a 16mhz crystal
|
||||
RCC->PLLCFGR = RCC_PLLCFGR_PLLQ_2 | RCC_PLLCFGR_PLLM_3 |
|
||||
RCC_PLLCFGR_PLLN_6 | RCC_PLLCFGR_PLLN_5 | RCC_PLLCFGR_PLLSRC_HSE;
|
||||
#else
|
||||
// NEO board has a 8mhz crystal
|
||||
RCC->PLLCFGR = RCC_PLLCFGR_PLLQ_2 | RCC_PLLCFGR_PLLM_3 |
|
||||
RCC_PLLCFGR_PLLN_7 | RCC_PLLCFGR_PLLN_6 | RCC_PLLCFGR_PLLSRC_HSE;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// start PLL
|
||||
RCC->CR |= RCC_CR_PLLON;
|
||||
while ((RCC->CR & RCC_CR_PLLRDY) == 0);
|
||||
|
||||
// Configure Flash prefetch, Instruction cache, Data cache and wait state
|
||||
// *** without this, it breaks ***
|
||||
FLASH->ACR = FLASH_ACR_ICEN | FLASH_ACR_DCEN | FLASH_ACR_LATENCY_5WS;
|
||||
|
||||
// switch to PLL
|
||||
RCC->CFGR |= RCC_CFGR_SW_PLL;
|
||||
while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL);
|
||||
|
||||
// *** running on PLL ***
|
||||
}
|
||||
|
||||
void periph_init() {
|
||||
// enable GPIOB, UART2, CAN, USB clock
|
||||
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;
|
||||
@@ -117,18 +82,16 @@ void periph_init() {
|
||||
RCC->APB1ENR |= RCC_APB1ENR_CAN3EN;
|
||||
#endif
|
||||
RCC->APB1ENR |= RCC_APB1ENR_DACEN;
|
||||
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
|
||||
RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
|
||||
RCC->APB1ENR |= RCC_APB1ENR_TIM4EN;
|
||||
RCC->APB1ENR |= RCC_APB1ENR_TIM5EN;
|
||||
RCC->APB1ENR |= RCC_APB1ENR_TIM6EN;
|
||||
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; // main counter
|
||||
RCC->APB1ENR |= RCC_APB1ENR_TIM3EN; // slow loop and pedal
|
||||
RCC->APB1ENR |= RCC_APB1ENR_TIM4EN; // gmlan_alt
|
||||
//RCC->APB1ENR |= RCC_APB1ENR_TIM5EN;
|
||||
//RCC->APB1ENR |= RCC_APB1ENR_TIM6EN;
|
||||
RCC->APB2ENR |= RCC_APB2ENR_USART1EN;
|
||||
RCC->AHB2ENR |= RCC_AHB2ENR_OTGFSEN;
|
||||
RCC->APB2ENR |= RCC_APB2ENR_TIM1EN;
|
||||
//RCC->APB2ENR |= RCC_APB2ENR_TIM1EN;
|
||||
RCC->APB2ENR |= RCC_APB2ENR_ADC1EN;
|
||||
RCC->APB2ENR |= RCC_APB2ENR_SPI1EN;
|
||||
|
||||
// needed?
|
||||
RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN;
|
||||
}
|
||||
|
||||
@@ -197,7 +160,7 @@ void set_can_mode(int can, int use_gmlan) {
|
||||
set_gpio_alternate(GPIOB, 12, GPIO_AF9_CAN2);
|
||||
set_gpio_alternate(GPIOB, 13, GPIO_AF9_CAN2);
|
||||
#ifdef CAN3
|
||||
} else if (revision == PANDA_REV_C && can == 2) {
|
||||
} else if (can == 2) {
|
||||
// A8,A15: disable normal mode
|
||||
set_gpio_mode(GPIOA, 8, MODE_INPUT);
|
||||
set_gpio_mode(GPIOA, 15, MODE_INPUT);
|
||||
@@ -218,11 +181,9 @@ void set_can_mode(int can, int use_gmlan) {
|
||||
set_gpio_alternate(GPIOB, 6, GPIO_AF9_CAN2);
|
||||
#ifdef CAN3
|
||||
} else if (can == 2) {
|
||||
if(revision == PANDA_REV_C){
|
||||
// B3,B4: disable gmlan mode
|
||||
set_gpio_mode(GPIOB, 3, MODE_INPUT);
|
||||
set_gpio_mode(GPIOB, 4, MODE_INPUT);
|
||||
}
|
||||
// B3,B4: disable gmlan mode
|
||||
set_gpio_mode(GPIOB, 3, MODE_INPUT);
|
||||
set_gpio_mode(GPIOB, 4, MODE_INPUT);
|
||||
// A8,A15: normal mode
|
||||
set_gpio_alternate(GPIOA, 8, GPIO_AF11_CAN3);
|
||||
set_gpio_alternate(GPIOA, 15, GPIO_AF11_CAN3);
|
||||
@@ -377,11 +338,7 @@ void gpio_init() {
|
||||
|
||||
#ifdef PANDA
|
||||
// K-line enable moved from B4->B7 to make room for GMLAN on CAN3
|
||||
if (revision == PANDA_REV_C) {
|
||||
set_gpio_output(GPIOB, 7, 1); // REV C
|
||||
} else {
|
||||
set_gpio_output(GPIOB, 4, 1); // REV AB
|
||||
}
|
||||
set_gpio_output(GPIOB, 7, 1); // REV C
|
||||
|
||||
// C12,D2: K-Line setup on UART 5
|
||||
set_gpio_alternate(GPIOC, 12, GPIO_AF8_UART5);
|
||||
@@ -392,16 +349,12 @@ void gpio_init() {
|
||||
set_gpio_output(GPIOA, 14, 1);
|
||||
|
||||
// C10,C11: L-Line setup on USART 3
|
||||
// LLine now used for relay output
|
||||
set_gpio_output(GPIOC, 10, 1);
|
||||
//set_gpio_alternate(GPIOC, 10, GPIO_AF7_USART3);
|
||||
set_gpio_alternate(GPIOC, 10, GPIO_AF7_USART3);
|
||||
set_gpio_alternate(GPIOC, 11, GPIO_AF7_USART3);
|
||||
set_gpio_pullup(GPIOC, 11, PULL_UP);
|
||||
#endif
|
||||
|
||||
if (revision == PANDA_REV_C) {
|
||||
set_usb_power_mode(USB_POWER_CLIENT);
|
||||
}
|
||||
set_usb_power_mode(USB_POWER_CLIENT);
|
||||
}
|
||||
|
||||
// ********************* early bringup *********************
|
||||
|
||||
+238
-244
@@ -1,14 +1,15 @@
|
||||
//#define EON
|
||||
|
||||
#include "config.h"
|
||||
#include "obj/gitversion.h"
|
||||
|
||||
// ********************* includes *********************
|
||||
|
||||
|
||||
#include "libc.h"
|
||||
#include "safety.h"
|
||||
#include "provision.h"
|
||||
|
||||
#include "drivers/drivers.h"
|
||||
|
||||
#include "drivers/llcan.h"
|
||||
#include "drivers/llgpio.h"
|
||||
#include "gpio.h"
|
||||
|
||||
@@ -16,25 +17,13 @@
|
||||
#include "drivers/adc.h"
|
||||
#include "drivers/usb.h"
|
||||
#include "drivers/gmlan_alt.h"
|
||||
#include "drivers/can.h"
|
||||
#include "drivers/spi.h"
|
||||
#include "drivers/timer.h"
|
||||
#include "drivers/clock.h"
|
||||
|
||||
#include "power_saving.h"
|
||||
|
||||
|
||||
// ***************************** fan *****************************
|
||||
|
||||
void fan_init() {
|
||||
// timer for fan PWM
|
||||
TIM3->CCMR2 = TIM_CCMR2_OC3M_2 | TIM_CCMR2_OC3M_1;
|
||||
TIM3->CCER = TIM_CCER_CC3E;
|
||||
timer_init(TIM3, 10);
|
||||
}
|
||||
|
||||
void fan_set_speed(int fan_speed) {
|
||||
TIM3->CCR3 = fan_speed;
|
||||
}
|
||||
#include "safety.h"
|
||||
#include "drivers/can.h"
|
||||
|
||||
// ********************* serial debugging *********************
|
||||
|
||||
@@ -70,6 +59,41 @@ void debug_ring_callback(uart_ring *ring) {
|
||||
}
|
||||
}
|
||||
|
||||
// ***************************** started logic *****************************
|
||||
|
||||
int is_gpio_started() {
|
||||
// ignition is on PA1
|
||||
return (GPIOA->IDR & (1 << 1)) == 0;
|
||||
}
|
||||
|
||||
void EXTI1_IRQHandler() {
|
||||
volatile int pr = EXTI->PR & (1 << 1);
|
||||
if (pr & (1 << 1)) {
|
||||
#ifdef DEBUG
|
||||
puts("got started interrupt\n");
|
||||
#endif
|
||||
|
||||
// jenky debounce
|
||||
delay(100000);
|
||||
|
||||
// set power savings mode here
|
||||
if (is_gpio_started() == 1) {
|
||||
power_save_disable();
|
||||
} else {
|
||||
power_save_enable();
|
||||
}
|
||||
EXTI->PR = (1 << 1);
|
||||
}
|
||||
}
|
||||
|
||||
void started_interrupt_init() {
|
||||
SYSCFG->EXTICR[1] = SYSCFG_EXTICR1_EXTI1_PA;
|
||||
EXTI->IMR |= (1 << 1);
|
||||
EXTI->RTSR |= (1 << 1);
|
||||
EXTI->FTSR |= (1 << 1);
|
||||
NVIC_EnableIRQ(EXTI1_IRQn);
|
||||
}
|
||||
|
||||
// ***************************** USB port *****************************
|
||||
|
||||
int get_health_pkt(void *dat) {
|
||||
@@ -85,40 +109,25 @@ int get_health_pkt(void *dat) {
|
||||
|
||||
//Voltage will be measured in mv. 5000 = 5V
|
||||
uint32_t voltage = adc_get(ADCCHAN_VOLTAGE);
|
||||
if (revision == PANDA_REV_AB) {
|
||||
//REVB has a 100, 27 (27/127) voltage divider
|
||||
//Here is the calculation for the scale
|
||||
//ADCV = VIN_S * (27/127) * (4095/3.3)
|
||||
//RETVAL = ADCV * s = VIN_S*1000
|
||||
//s = 1000/((4095/3.3)*(27/127)) = 3.79053046
|
||||
|
||||
//Avoid needing floating point math
|
||||
health->voltage = (voltage * 3791) / 1000;
|
||||
} else {
|
||||
//REVC has a 10, 1 (1/11) voltage divider
|
||||
//Here is the calculation for the scale (s)
|
||||
//ADCV = VIN_S * (1/11) * (4095/3.3)
|
||||
//RETVAL = ADCV * s = VIN_S*1000
|
||||
//s = 1000/((4095/3.3)*(1/11)) = 8.8623046875
|
||||
// REVC has a 10, 1 (1/11) voltage divider
|
||||
// Here is the calculation for the scale (s)
|
||||
// ADCV = VIN_S * (1/11) * (4095/3.3)
|
||||
// RETVAL = ADCV * s = VIN_S*1000
|
||||
// s = 1000/((4095/3.3)*(1/11)) = 8.8623046875
|
||||
|
||||
//Avoid needing floating point math
|
||||
health->voltage = (voltage * 8862) / 1000;
|
||||
}
|
||||
// Avoid needing floating point math
|
||||
health->voltage = (voltage * 8862) / 1000;
|
||||
|
||||
#ifdef PANDA
|
||||
health->current = adc_get(ADCCHAN_CURRENT);
|
||||
int safety_ignition = safety_ignition_hook();
|
||||
if (safety_ignition < 0) {
|
||||
//Use the GPIO pin to determine ignition
|
||||
health->started = (GPIOA->IDR & (1 << 1)) == 0;
|
||||
health->started = is_gpio_started();
|
||||
} else {
|
||||
//Current safety hooks want to determine ignition (ex: GM)
|
||||
health->started = safety_ignition;
|
||||
}
|
||||
#else
|
||||
health->current = 0;
|
||||
health->started = (GPIOC->IDR & (1 << 13)) != 0;
|
||||
#endif
|
||||
|
||||
health->controls_allowed = controls_allowed;
|
||||
health->gas_interceptor_detected = gas_interceptor_detected;
|
||||
@@ -143,7 +152,6 @@ void usb_cb_ep2_out(uint8_t *usbdata, int len, int hardwired) {
|
||||
uart_ring *ur = get_ring_by_number(usbdata[0]);
|
||||
if (!ur) return;
|
||||
if ((usbdata[0] < 2) || safety_tx_lin_hook(usbdata[0]-2, usbdata+1, len-1)) {
|
||||
if (ur == &esp_ring) power_save_reset_timer();
|
||||
for (int i = 1; i < len; i++) while (!putc(ur, usbdata[i]));
|
||||
}
|
||||
}
|
||||
@@ -163,14 +171,6 @@ void usb_cb_ep3_out(uint8_t *usbdata, int len, int hardwired) {
|
||||
|
||||
uint8_t bus_number = (to_push.RDTR >> 4) & CAN_BUS_NUM_MASK;
|
||||
can_send(&to_push, bus_number);
|
||||
|
||||
#ifdef PANDA
|
||||
// Enable relay on can message if allowed.
|
||||
// Temporary until OP has support for relay
|
||||
if (safety_relay_hook()) {
|
||||
set_lline_output(1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -201,16 +201,14 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, int hardwired) {
|
||||
break;
|
||||
// **** 0xd0: fetch serial number
|
||||
case 0xd0:
|
||||
#ifdef PANDA
|
||||
// addresses are OTP
|
||||
if (setup->b.wValue.w == 1) {
|
||||
memcpy(resp, (void *)0x1fff79c0, 0x10);
|
||||
resp_len = 0x10;
|
||||
} else {
|
||||
get_provision_chunk(resp);
|
||||
resp_len = PROVISION_CHUNK_LEN;
|
||||
}
|
||||
#endif
|
||||
// addresses are OTP
|
||||
if (setup->b.wValue.w == 1) {
|
||||
memcpy(resp, (void *)0x1fff79c0, 0x10);
|
||||
resp_len = 0x10;
|
||||
} else {
|
||||
get_provision_chunk(resp);
|
||||
resp_len = PROVISION_CHUNK_LEN;
|
||||
}
|
||||
break;
|
||||
// **** 0xd1: enter bootloader mode
|
||||
case 0xd1:
|
||||
@@ -235,10 +233,6 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, int hardwired) {
|
||||
case 0xd2:
|
||||
resp_len = get_health_pkt(resp);
|
||||
break;
|
||||
// **** 0xd3: set fan speed
|
||||
case 0xd3:
|
||||
fan_set_speed(setup->b.wValue.w);
|
||||
break;
|
||||
// **** 0xd6: get version
|
||||
case 0xd6:
|
||||
COMPILE_TIME_ASSERT(sizeof(gitversion) <= MAX_RESP_LEN)
|
||||
@@ -273,44 +267,43 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, int hardwired) {
|
||||
break;
|
||||
// **** 0xdb: set GMLAN multiplexing mode
|
||||
case 0xdb:
|
||||
#ifdef PANDA
|
||||
if (setup->b.wValue.w == 1) {
|
||||
// GMLAN ON
|
||||
if (setup->b.wIndex.w == 1) {
|
||||
can_set_gmlan(1);
|
||||
} else if (setup->b.wIndex.w == 2) {
|
||||
// might be ignored on rev b panda
|
||||
can_set_gmlan(2);
|
||||
}
|
||||
} else {
|
||||
can_set_gmlan(-1);
|
||||
if (setup->b.wValue.w == 1) {
|
||||
// GMLAN ON
|
||||
if (setup->b.wIndex.w == 1) {
|
||||
can_set_gmlan(1);
|
||||
} else if (setup->b.wIndex.w == 2) {
|
||||
can_set_gmlan(2);
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
can_set_gmlan(-1);
|
||||
}
|
||||
break;
|
||||
// **** 0xdc: set safety mode
|
||||
case 0xdc:
|
||||
// this is the only way to leave silent mode
|
||||
// and it's blocked over WiFi
|
||||
// Allow ELM security mode to be set over wifi.
|
||||
if (hardwired || setup->b.wValue.w == SAFETY_NOOUTPUT || setup->b.wValue.w == SAFETY_ELM327) {
|
||||
if (hardwired || (setup->b.wValue.w == SAFETY_NOOUTPUT) || (setup->b.wValue.w == SAFETY_ELM327)) {
|
||||
safety_set_mode(setup->b.wValue.w, (int16_t)setup->b.wIndex.w);
|
||||
switch (setup->b.wValue.w) {
|
||||
case SAFETY_NOOUTPUT:
|
||||
can_silent = ALL_CAN_SILENT;
|
||||
break;
|
||||
case SAFETY_ELM327:
|
||||
can_silent = ALL_CAN_BUT_MAIN_SILENT;
|
||||
can_autobaud_enabled[0] = false;
|
||||
break;
|
||||
default:
|
||||
can_silent = ALL_CAN_LIVE;
|
||||
can_autobaud_enabled[0] = false;
|
||||
can_autobaud_enabled[1] = false;
|
||||
#ifdef PANDA
|
||||
can_autobaud_enabled[2] = false;
|
||||
#endif
|
||||
break;
|
||||
if (safety_ignition_hook() != -1) {
|
||||
// if the ignition hook depends on something other than the started GPIO
|
||||
// we have to disable power savings (fix for GM and Tesla)
|
||||
power_save_disable();
|
||||
}
|
||||
#ifndef EON
|
||||
// always LIVE on EON
|
||||
switch (setup->b.wValue.w) {
|
||||
case SAFETY_NOOUTPUT:
|
||||
can_silent = ALL_CAN_SILENT;
|
||||
break;
|
||||
case SAFETY_ELM327:
|
||||
can_silent = ALL_CAN_BUT_MAIN_SILENT;
|
||||
break;
|
||||
default:
|
||||
can_silent = ALL_CAN_LIVE;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
can_init_all();
|
||||
}
|
||||
break;
|
||||
@@ -318,21 +311,26 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, int hardwired) {
|
||||
case 0xdd:
|
||||
// wValue = Can Bus Num to forward from
|
||||
// wIndex = Can Bus Num to forward to
|
||||
if (setup->b.wValue.w < BUS_MAX && setup->b.wIndex.w < BUS_MAX &&
|
||||
setup->b.wValue.w != setup->b.wIndex.w) { // set forwarding
|
||||
if ((setup->b.wValue.w < BUS_MAX) && (setup->b.wIndex.w < BUS_MAX) &&
|
||||
(setup->b.wValue.w != setup->b.wIndex.w)) { // set forwarding
|
||||
can_set_forwarding(setup->b.wValue.w, setup->b.wIndex.w & CAN_BUS_NUM_MASK);
|
||||
} else if(setup->b.wValue.w < BUS_MAX && setup->b.wIndex.w == 0xFF){ //Clear Forwarding
|
||||
} else if((setup->b.wValue.w < BUS_MAX) && (setup->b.wIndex.w == 0xFF)){ //Clear Forwarding
|
||||
can_set_forwarding(setup->b.wValue.w, -1);
|
||||
}
|
||||
break;
|
||||
// **** 0xde: set can bitrate
|
||||
case 0xde:
|
||||
if (setup->b.wValue.w < BUS_MAX) {
|
||||
can_autobaud_enabled[setup->b.wValue.w] = false;
|
||||
can_speed[setup->b.wValue.w] = setup->b.wIndex.w;
|
||||
can_init(CAN_NUM_FROM_BUS_NUM(setup->b.wValue.w));
|
||||
}
|
||||
break;
|
||||
// **** 0xdf: set long controls allowed
|
||||
case 0xdf:
|
||||
if (hardwired) {
|
||||
long_controls_allowed = setup->b.wValue.w & 1;
|
||||
}
|
||||
break;
|
||||
// **** 0xe0: uart read
|
||||
case 0xe0:
|
||||
ur = get_ring_by_number(setup->b.wValue.w);
|
||||
@@ -386,17 +384,15 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, int hardwired) {
|
||||
break;
|
||||
// **** 0xe6: set USB power
|
||||
case 0xe6:
|
||||
if (revision == PANDA_REV_C) {
|
||||
if (setup->b.wValue.w == 1) {
|
||||
puts("user setting CDP mode\n");
|
||||
set_usb_power_mode(USB_POWER_CDP);
|
||||
} else if (setup->b.wValue.w == 2) {
|
||||
puts("user setting DCP mode\n");
|
||||
set_usb_power_mode(USB_POWER_DCP);
|
||||
} else {
|
||||
puts("user setting CLIENT mode\n");
|
||||
set_usb_power_mode(USB_POWER_CLIENT);
|
||||
}
|
||||
if (setup->b.wValue.w == 1) {
|
||||
puts("user setting CDP mode\n");
|
||||
set_usb_power_mode(USB_POWER_CDP);
|
||||
} else if (setup->b.wValue.w == 2) {
|
||||
puts("user setting DCP mode\n");
|
||||
set_usb_power_mode(USB_POWER_DCP);
|
||||
} else {
|
||||
puts("user setting CLIENT mode\n");
|
||||
set_usb_power_mode(USB_POWER_CLIENT);
|
||||
}
|
||||
break;
|
||||
// **** 0xf0: do k-line wValue pulse on uart2 for Acura
|
||||
@@ -452,16 +448,6 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, int hardwired) {
|
||||
}
|
||||
break;
|
||||
}
|
||||
// **** 0xf3: set l-line relay
|
||||
case 0xf3:
|
||||
{
|
||||
#ifdef PANDA
|
||||
if (safety_relay_hook()) {
|
||||
set_lline_output(setup->b.wValue.w == 1);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
default:
|
||||
puts("NO HANDLER ");
|
||||
puth(setup->b.bRequest);
|
||||
@@ -471,7 +457,6 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, int hardwired) {
|
||||
return resp_len;
|
||||
}
|
||||
|
||||
#ifdef PANDA
|
||||
int spi_cb_rx(uint8_t *data, int len, uint8_t *data_out) {
|
||||
// data[0] = endpoint
|
||||
// data[2] = length
|
||||
@@ -499,12 +484,6 @@ int spi_cb_rx(uint8_t *data, int len, uint8_t *data_out) {
|
||||
return resp_len;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
int spi_cb_rx(uint8_t *data, int len, uint8_t *data_out) { return 0; };
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
// ***************************** main code *****************************
|
||||
|
||||
@@ -514,7 +493,99 @@ void __initialize_hardware_early() {
|
||||
|
||||
void __attribute__ ((noinline)) enable_fpu() {
|
||||
// enable the FPU
|
||||
SCB->CPACR |= ((3UL << 10*2) | (3UL << 11*2));
|
||||
SCB->CPACR |= ((3UL << (10 * 2)) | (3UL << (11 * 2)));
|
||||
}
|
||||
|
||||
uint64_t tcnt = 0;
|
||||
uint64_t marker = 0;
|
||||
|
||||
// called once per second
|
||||
void TIM3_IRQHandler() {
|
||||
#define CURRENT_THRESHOLD 0xF00
|
||||
#define CLICKS 5 // 5 seconds to switch modes
|
||||
|
||||
if (TIM3->SR != 0) {
|
||||
can_live = pending_can_live;
|
||||
|
||||
//puth(usart1_dma); puts(" "); puth(DMA2_Stream5->M0AR); puts(" "); puth(DMA2_Stream5->NDTR); puts("\n");
|
||||
|
||||
uint32_t current = adc_get(ADCCHAN_CURRENT);
|
||||
|
||||
switch (usb_power_mode) {
|
||||
case USB_POWER_CLIENT:
|
||||
if ((tcnt-marker) >= CLICKS) {
|
||||
if (!is_enumerated) {
|
||||
puts("USBP: didn't enumerate, switching to CDP mode\n");
|
||||
// switch to CDP
|
||||
set_usb_power_mode(USB_POWER_CDP);
|
||||
marker = tcnt;
|
||||
}
|
||||
}
|
||||
// keep resetting the timer if it's enumerated
|
||||
if (is_enumerated) {
|
||||
marker = tcnt;
|
||||
}
|
||||
break;
|
||||
case USB_POWER_CDP:
|
||||
// On the EON, if we get into CDP mode we stay here. No need to go to DCP.
|
||||
#ifndef EON
|
||||
// been CLICKS clicks since we switched to CDP
|
||||
if ((tcnt-marker) >= CLICKS) {
|
||||
// measure current draw, if positive and no enumeration, switch to DCP
|
||||
if (!is_enumerated && (current < CURRENT_THRESHOLD)) {
|
||||
puts("USBP: no enumeration with current draw, switching to DCP mode\n");
|
||||
set_usb_power_mode(USB_POWER_DCP);
|
||||
marker = tcnt;
|
||||
}
|
||||
}
|
||||
// keep resetting the timer if there's no current draw in CDP
|
||||
if (current >= CURRENT_THRESHOLD) {
|
||||
marker = tcnt;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case USB_POWER_DCP:
|
||||
// been at least CLICKS clicks since we switched to DCP
|
||||
if ((tcnt-marker) >= CLICKS) {
|
||||
// if no current draw, switch back to CDP
|
||||
if (current >= CURRENT_THRESHOLD) {
|
||||
puts("USBP: no current draw, switching back to CDP mode\n");
|
||||
set_usb_power_mode(USB_POWER_CDP);
|
||||
marker = tcnt;
|
||||
}
|
||||
}
|
||||
// keep resetting the timer if there's current draw in DCP
|
||||
if (current < CURRENT_THRESHOLD) {
|
||||
marker = tcnt;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// ~0x9a = 500 ma
|
||||
/*puth(current);
|
||||
puts("\n");*/
|
||||
|
||||
// reset this every 16th pass
|
||||
if ((tcnt&0xF) == 0) pending_can_live = 0;
|
||||
|
||||
#ifdef DEBUG
|
||||
puts("** blink ");
|
||||
puth(can_rx_q.r_ptr); puts(" "); puth(can_rx_q.w_ptr); puts(" ");
|
||||
puth(can_tx1_q.r_ptr); puts(" "); puth(can_tx1_q.w_ptr); puts(" ");
|
||||
puth(can_tx2_q.r_ptr); puts(" "); puth(can_tx2_q.w_ptr); puts("\n");
|
||||
#endif
|
||||
|
||||
// set green LED to be controls allowed
|
||||
set_led(LED_GREEN, controls_allowed);
|
||||
|
||||
// turn off the blue LED, turned on by CAN
|
||||
// unless we are in power saving mode
|
||||
set_led(LED_BLUE, (tcnt&1) && power_save_status == POWER_SAVE_STATUS_ENABLED);
|
||||
|
||||
// on to the next one
|
||||
tcnt += 1;
|
||||
}
|
||||
TIM3->SR = 0;
|
||||
}
|
||||
|
||||
int main() {
|
||||
@@ -531,21 +602,19 @@ int main() {
|
||||
|
||||
// detect the revision and init the GPIOs
|
||||
puts("config:\n");
|
||||
#ifdef PANDA
|
||||
puts(revision == PANDA_REV_C ? " panda rev c\n" : " panda rev a or b\n");
|
||||
#else
|
||||
puts(" legacy\n");
|
||||
#endif
|
||||
puts((revision == PANDA_REV_C) ? " panda rev c\n" : " panda rev a or b\n");
|
||||
puts(has_external_debug_serial ? " real serial\n" : " USB serial\n");
|
||||
puts(is_giant_panda ? " GIANTpanda detected\n" : " not GIANTpanda\n");
|
||||
puts(is_grey_panda ? " gray panda detected!\n" : " white panda\n");
|
||||
puts(is_entering_bootmode ? " ESP wants bootmode\n" : " no bootmode\n");
|
||||
|
||||
// non rev c panda are no longer supported
|
||||
while (revision != PANDA_REV_C);
|
||||
|
||||
gpio_init();
|
||||
|
||||
#ifdef PANDA
|
||||
// panda has an FPU, let's use it!
|
||||
enable_fpu();
|
||||
#endif
|
||||
|
||||
// enable main uart if it's connected
|
||||
if (has_external_debug_serial) {
|
||||
@@ -554,22 +623,18 @@ int main() {
|
||||
uart_init(USART2, 115200);
|
||||
}
|
||||
|
||||
#ifdef PANDA
|
||||
if (is_grey_panda) {
|
||||
uart_init(USART1, 9600);
|
||||
} else {
|
||||
// enable ESP uart
|
||||
uart_init(USART1, 115200);
|
||||
#ifdef EON
|
||||
set_esp_mode(ESP_DISABLED);
|
||||
#endif
|
||||
}
|
||||
|
||||
// enable LIN
|
||||
uart_init(UART5, 10400);
|
||||
UART5->CR2 |= USART_CR2_LINEN;
|
||||
uart_init(USART3, 10400);
|
||||
USART3->CR2 |= USART_CR2_LINEN;
|
||||
#endif
|
||||
|
||||
// init microsecond system timer
|
||||
// increments 1000000 times per second
|
||||
@@ -585,136 +650,65 @@ int main() {
|
||||
// default to silent mode to prevent issues with Ford
|
||||
// hardcode a specific safety mode if you want to force the panda to be in a specific mode
|
||||
safety_set_mode(SAFETY_NOOUTPUT, 0);
|
||||
#ifdef EON
|
||||
// if we're on an EON, it's fine for CAN to be live for fingerprinting
|
||||
can_silent = ALL_CAN_LIVE;
|
||||
#else
|
||||
can_silent = ALL_CAN_SILENT;
|
||||
#endif
|
||||
can_init_all();
|
||||
|
||||
adc_init();
|
||||
|
||||
#ifdef PANDA
|
||||
spi_init();
|
||||
|
||||
#ifdef EON
|
||||
// have to save power
|
||||
if (!is_grey_panda) {
|
||||
set_esp_mode(ESP_DISABLED);
|
||||
}
|
||||
// only enter power save after the first cycle
|
||||
/*if (is_gpio_started() == 0) {
|
||||
power_save_enable();
|
||||
}*/
|
||||
// interrupt on started line
|
||||
started_interrupt_init();
|
||||
#endif
|
||||
|
||||
// 48mhz / 65536 ~= 732 / 732 = 1
|
||||
timer_init(TIM3, 732);
|
||||
NVIC_EnableIRQ(TIM3_IRQn);
|
||||
|
||||
#ifdef DEBUG
|
||||
puts("DEBUG ENABLED\n");
|
||||
#endif
|
||||
|
||||
// set PWM
|
||||
fan_init();
|
||||
fan_set_speed(0);
|
||||
|
||||
puts("**** INTERRUPTS ON ****\n");
|
||||
|
||||
__enable_irq();
|
||||
|
||||
power_save_init();
|
||||
|
||||
// if the error interrupt is enabled to quickly when the CAN bus is active
|
||||
// something bad happens and you can't connect to the device over USB
|
||||
delay(10000000);
|
||||
CAN1->IER |= CAN_IER_ERRIE | CAN_IER_LECIE;
|
||||
|
||||
// LED should keep on blinking all the time
|
||||
uint64_t cnt = 0;
|
||||
|
||||
#ifdef PANDA
|
||||
uint64_t marker = 0;
|
||||
#define CURRENT_THRESHOLD 0xF00
|
||||
#define CLICKS 8
|
||||
#endif
|
||||
|
||||
for (cnt=0;;cnt++) {
|
||||
can_live = pending_can_live;
|
||||
if (power_save_status == POWER_SAVE_STATUS_DISABLED) {
|
||||
int div_mode = ((usb_power_mode == USB_POWER_DCP) ? 4 : 1);
|
||||
|
||||
//puth(usart1_dma); puts(" "); puth(DMA2_Stream5->M0AR); puts(" "); puth(DMA2_Stream5->NDTR); puts("\n");
|
||||
|
||||
#ifdef PANDA
|
||||
uint32_t current = adc_get(ADCCHAN_CURRENT);
|
||||
|
||||
switch (usb_power_mode) {
|
||||
case USB_POWER_CLIENT:
|
||||
if ((cnt-marker) >= CLICKS) {
|
||||
if (!is_enumerated) {
|
||||
puts("USBP: didn't enumerate, switching to CDP mode\n");
|
||||
// switch to CDP
|
||||
set_usb_power_mode(USB_POWER_CDP);
|
||||
marker = cnt;
|
||||
}
|
||||
// useful for debugging, fade breaks = panda is overloaded
|
||||
for (int div_mode_loop = 0; div_mode_loop < div_mode; div_mode_loop++) {
|
||||
for (int fade = 0; fade < 1024; fade += 8) {
|
||||
for (int i = 0; i < (128/div_mode); i++) {
|
||||
set_led(LED_RED, 1);
|
||||
if (fade < 512) { delay(fade); } else { delay(1024-fade); }
|
||||
set_led(LED_RED, 0);
|
||||
if (fade < 512) { delay(512-fade); } else { delay(fade-512); }
|
||||
}
|
||||
// keep resetting the timer if it's enumerated
|
||||
if (is_enumerated) {
|
||||
marker = cnt;
|
||||
}
|
||||
break;
|
||||
case USB_POWER_CDP:
|
||||
#ifndef EON
|
||||
// been CLICKS clicks since we switched to CDP
|
||||
if ((cnt-marker) >= CLICKS) {
|
||||
// measure current draw, if positive and no enumeration, switch to DCP
|
||||
if (!is_enumerated && current < CURRENT_THRESHOLD) {
|
||||
puts("USBP: no enumeration with current draw, switching to DCP mode\n");
|
||||
set_usb_power_mode(USB_POWER_DCP);
|
||||
marker = cnt;
|
||||
}
|
||||
}
|
||||
// keep resetting the timer if there's no current draw in CDP
|
||||
if (current >= CURRENT_THRESHOLD) {
|
||||
marker = cnt;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case USB_POWER_DCP:
|
||||
// been at least CLICKS clicks since we switched to DCP
|
||||
if ((cnt-marker) >= CLICKS) {
|
||||
// if no current draw, switch back to CDP
|
||||
if (current >= CURRENT_THRESHOLD) {
|
||||
puts("USBP: no current draw, switching back to CDP mode\n");
|
||||
set_usb_power_mode(USB_POWER_CDP);
|
||||
marker = cnt;
|
||||
}
|
||||
}
|
||||
// keep resetting the timer if there's current draw in DCP
|
||||
if (current < CURRENT_THRESHOLD) {
|
||||
marker = cnt;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// ~0x9a = 500 ma
|
||||
/*puth(current);
|
||||
puts("\n");*/
|
||||
#endif
|
||||
|
||||
// reset this every 16th pass
|
||||
if ((cnt&0xF) == 0) pending_can_live = 0;
|
||||
|
||||
#ifdef DEBUG
|
||||
puts("** blink ");
|
||||
puth(can_rx_q.r_ptr); puts(" "); puth(can_rx_q.w_ptr); puts(" ");
|
||||
puth(can_tx1_q.r_ptr); puts(" "); puth(can_tx1_q.w_ptr); puts(" ");
|
||||
puth(can_tx2_q.r_ptr); puts(" "); puth(can_tx2_q.w_ptr); puts("\n");
|
||||
#endif
|
||||
|
||||
// set green LED to be controls allowed
|
||||
set_led(LED_GREEN, controls_allowed);
|
||||
|
||||
// blink the red LED
|
||||
int div_mode = ((usb_power_mode == USB_POWER_DCP) ? 4 : 1);
|
||||
|
||||
for (int div_mode_loop = 0; div_mode_loop < div_mode; div_mode_loop++) {
|
||||
for (int fade = 0; fade < 1024; fade += 8) {
|
||||
for (int i = 0; i < 128/div_mode; i++) {
|
||||
set_led(LED_RED, 0);
|
||||
if (fade < 512) { delay(512-fade); } else { delay(fade-512); }
|
||||
set_led(LED_RED, 1);
|
||||
if (fade < 512) { delay(fade); } else { delay(1024-fade); }
|
||||
}
|
||||
}
|
||||
} else {
|
||||
__WFI();
|
||||
}
|
||||
|
||||
// turn off the blue LED, turned on by CAN
|
||||
#ifdef PANDA
|
||||
set_led(LED_BLUE, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
+17
-27
@@ -1,29 +1,26 @@
|
||||
//#define DEBUG
|
||||
//#define CAN_LOOPBACK_MODE
|
||||
//#define USE_INTERNAL_OSC
|
||||
|
||||
#include "../config.h"
|
||||
|
||||
#include "drivers/drivers.h"
|
||||
#include "drivers/llcan.h"
|
||||
#include "drivers/llgpio.h"
|
||||
#include "gpio.h"
|
||||
|
||||
#define CUSTOM_CAN_INTERRUPTS
|
||||
|
||||
#include "libc.h"
|
||||
#include "safety.h"
|
||||
#include "drivers/clock.h"
|
||||
#include "drivers/adc.h"
|
||||
#include "drivers/uart.h"
|
||||
#include "drivers/dac.h"
|
||||
#include "drivers/can.h"
|
||||
#include "drivers/timer.h"
|
||||
|
||||
#include "gpio.h"
|
||||
#include "libc.h"
|
||||
|
||||
#define CAN CAN1
|
||||
|
||||
//#define PEDAL_USB
|
||||
|
||||
#ifdef PEDAL_USB
|
||||
#include "drivers/uart.h"
|
||||
#include "drivers/usb.h"
|
||||
#else
|
||||
// no serial either
|
||||
int puts(const char *a) { return 0; }
|
||||
void puth(unsigned int i) {}
|
||||
#endif
|
||||
|
||||
#define ENTER_BOOTLOADER_MAGIC 0xdeadbeef
|
||||
@@ -35,6 +32,8 @@ void __initialize_hardware_early() {
|
||||
|
||||
// ********************* serial debugging *********************
|
||||
|
||||
#ifdef PEDAL_USB
|
||||
|
||||
void debug_ring_callback(uart_ring *ring) {
|
||||
char rcv;
|
||||
while (getc(ring, &rcv)) {
|
||||
@@ -42,8 +41,6 @@ void debug_ring_callback(uart_ring *ring) {
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef PEDAL_USB
|
||||
|
||||
int usb_cb_ep1_in(uint8_t *usbdata, int len, int hardwired) { return 0; }
|
||||
void usb_cb_ep2_out(uint8_t *usbdata, int len, int hardwired) {}
|
||||
void usb_cb_ep3_out(uint8_t *usbdata, int len, int hardwired) {}
|
||||
@@ -185,7 +182,7 @@ void CAN1_RX0_IRQHandler() {
|
||||
|
||||
void CAN1_SCE_IRQHandler() {
|
||||
state = FAULT_SCE;
|
||||
can_sce(CAN);
|
||||
llcan_clear_send(CAN);
|
||||
}
|
||||
|
||||
int pdl0 = 0, pdl1 = 0;
|
||||
@@ -256,8 +253,7 @@ void pedal() {
|
||||
dac_set(1, pdl1);
|
||||
}
|
||||
|
||||
// feed the watchdog
|
||||
IWDG->KR = 0xAAAA;
|
||||
watchdog_feed();
|
||||
}
|
||||
|
||||
int main() {
|
||||
@@ -278,24 +274,18 @@ int main() {
|
||||
adc_init();
|
||||
|
||||
// init can
|
||||
can_silent = ALL_CAN_LIVE;
|
||||
can_init(0);
|
||||
llcan_set_speed(CAN1, 5000, false, false);
|
||||
llcan_init(CAN1);
|
||||
|
||||
// 48mhz / 65536 ~= 732
|
||||
timer_init(TIM3, 15);
|
||||
NVIC_EnableIRQ(TIM3_IRQn);
|
||||
|
||||
// setup watchdog
|
||||
IWDG->KR = 0x5555;
|
||||
IWDG->PR = 0; // divider /4
|
||||
// 0 = 0.125 ms, let's have a 50ms watchdog
|
||||
IWDG->RLR = 400 - 1;
|
||||
IWDG->KR = 0xCCCC;
|
||||
watchdog_init();
|
||||
|
||||
puts("**** INTERRUPTS ON ****\n");
|
||||
__enable_irq();
|
||||
|
||||
|
||||
// main pedal loop
|
||||
while (1) {
|
||||
pedal();
|
||||
|
||||
+20
-120
@@ -1,157 +1,57 @@
|
||||
#define POWER_SAVE_STATUS_DISABLED 0
|
||||
//Moving to enabled, but can wakeup not yet enabled
|
||||
#define POWER_SAVE_STATUS_SWITCHING 1
|
||||
#define POWER_SAVE_STATUS_ENABLED 2
|
||||
#define POWER_SAVE_STATUS_ENABLED 1
|
||||
|
||||
volatile int power_save_status = POWER_SAVE_STATUS_DISABLED;
|
||||
int power_save_status = POWER_SAVE_STATUS_DISABLED;
|
||||
|
||||
void power_save_enable(void) {
|
||||
power_save_status = POWER_SAVE_STATUS_SWITCHING;
|
||||
puts("Saving power\n");
|
||||
//Turn off can transciever
|
||||
if (power_save_status == POWER_SAVE_STATUS_ENABLED) return;
|
||||
puts("enable power savings\n");
|
||||
|
||||
// turn off can
|
||||
set_can_enable(CAN1, 0);
|
||||
set_can_enable(CAN2, 0);
|
||||
#ifdef PANDA
|
||||
set_can_enable(CAN3, 0);
|
||||
#endif
|
||||
|
||||
//Turn off GMLAN
|
||||
// turn off GMLAN
|
||||
set_gpio_output(GPIOB, 14, 0);
|
||||
set_gpio_output(GPIOB, 15, 0);
|
||||
|
||||
#ifdef PANDA
|
||||
//Turn off LIN K
|
||||
if (revision == PANDA_REV_C) {
|
||||
set_gpio_output(GPIOB, 7, 0); // REV C
|
||||
} else {
|
||||
set_gpio_output(GPIOB, 4, 0); // REV AB
|
||||
}
|
||||
// LIN L
|
||||
// turn off LIN
|
||||
set_gpio_output(GPIOB, 7, 0);
|
||||
set_gpio_output(GPIOA, 14, 0);
|
||||
#endif
|
||||
|
||||
if (is_grey_panda) {
|
||||
char* UBLOX_SLEEP_MSG = "\xb5\x62\x06\x04\x04\x00\x01\x00\x08\x00\x17\x78";
|
||||
int len = 12;
|
||||
char UBLOX_SLEEP_MSG[] = "\xb5\x62\x06\x04\x04\x00\x01\x00\x08\x00\x17\x78";
|
||||
uart_ring *ur = get_ring_by_number(1);
|
||||
for (int i = 0; i < len; i++) while (!putc(ur, UBLOX_SLEEP_MSG[i]));
|
||||
for (int i = 0; i < sizeof(UBLOX_SLEEP_MSG)-1; i++) while (!putc(ur, UBLOX_SLEEP_MSG[i]));
|
||||
}
|
||||
|
||||
//Setup timer for can enable
|
||||
TIM6->PSC = 48-1; // tick on 1 us
|
||||
|
||||
TIM6->ARR = 12; // 12us
|
||||
// Enable, One-Pulse Mode, Only overflow interrupt
|
||||
TIM6->CR1 = TIM_CR1_CEN | TIM_CR1_OPM | TIM_CR1_URS;
|
||||
TIM6->EGR = TIM_EGR_UG;
|
||||
TIM6->CR1 |= TIM_CR1_CEN;
|
||||
}
|
||||
|
||||
void power_save_enable_can_wake(void) {
|
||||
// CAN Automatic Wake must be done a little while after the sleep
|
||||
// On some cars turning off the can transciver can trigger the wakeup
|
||||
power_save_status = POWER_SAVE_STATUS_ENABLED;
|
||||
puts("Turning can off\n");
|
||||
CAN1->MCR |= CAN_MCR_SLEEP;
|
||||
CAN1->MCR |= CAN_MCR_AWUM;
|
||||
|
||||
CAN2->MCR |= CAN_MCR_SLEEP;
|
||||
CAN2->MCR |= CAN_MCR_AWUM;
|
||||
#ifdef PANDA
|
||||
CAN3->MCR |= CAN_MCR_SLEEP;
|
||||
CAN3->MCR |= CAN_MCR_AWUM;
|
||||
#endif
|
||||
|
||||
//set timer back
|
||||
TIM6->PSC = 48000-1; // tick on 1 ms
|
||||
TIM6->ARR = 10000; // 10s
|
||||
// Enable, One-Pulse Mode, Only overflow interrupt
|
||||
TIM6->CR1 = TIM_CR1_OPM | TIM_CR1_URS;
|
||||
TIM6->EGR = TIM_EGR_UG;
|
||||
}
|
||||
|
||||
void power_save_disable(void) {
|
||||
power_save_status = POWER_SAVE_STATUS_DISABLED;
|
||||
puts("not Saving power\n");
|
||||
TIM6->CR1 |= TIM_CR1_CEN; //Restart timer
|
||||
TIM6->CNT = 0;
|
||||
if (power_save_status == POWER_SAVE_STATUS_DISABLED) return;
|
||||
puts("disable power savings\n");
|
||||
|
||||
//Turn on can
|
||||
// turn on can
|
||||
set_can_enable(CAN1, 1);
|
||||
set_can_enable(CAN2, 1);
|
||||
|
||||
#ifdef PANDA
|
||||
set_can_enable(CAN3, 1);
|
||||
#endif
|
||||
|
||||
//Turn on GMLAN
|
||||
// turn on GMLAN
|
||||
set_gpio_output(GPIOB, 14, 1);
|
||||
set_gpio_output(GPIOB, 15, 1);
|
||||
|
||||
#ifdef PANDA
|
||||
//Turn on LIN K
|
||||
if (revision == PANDA_REV_C) {
|
||||
set_gpio_output(GPIOB, 7, 1); // REV C
|
||||
} else {
|
||||
set_gpio_output(GPIOB, 4, 1); // REV AB
|
||||
}
|
||||
// LIN L
|
||||
// turn on LIN
|
||||
set_gpio_output(GPIOB, 7, 1);
|
||||
set_gpio_output(GPIOA, 14, 1);
|
||||
#endif
|
||||
|
||||
if (is_grey_panda) {
|
||||
char* UBLOX_WAKE_MSG = "\xb5\x62\x06\x04\x04\x00\x01\x00\x09\x00\x18\x7a";
|
||||
int len = 12;
|
||||
char UBLOX_WAKE_MSG[] = "\xb5\x62\x06\x04\x04\x00\x01\x00\x09\x00\x18\x7a";
|
||||
uart_ring *ur = get_ring_by_number(1);
|
||||
for (int i = 0; i < len; i++) while (!putc(ur, UBLOX_WAKE_MSG[i]));
|
||||
for (int i = 0; i < sizeof(UBLOX_WAKE_MSG)-1; i++) while (!putc(ur, UBLOX_WAKE_MSG[i]));
|
||||
}
|
||||
|
||||
//set timer back
|
||||
TIM6->PSC = 48000-1; // tick on 1 ms
|
||||
TIM6->ARR = 10000; // 10s
|
||||
// Enable, One-Pulse Mode, Only overflow interrupt
|
||||
TIM6->CR1 = TIM_CR1_CEN | TIM_CR1_OPM | TIM_CR1_URS;
|
||||
TIM6->EGR = TIM_EGR_UG;
|
||||
TIM6->CR1 |= TIM_CR1_CEN;
|
||||
power_save_status = POWER_SAVE_STATUS_DISABLED;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Reset timer when activity
|
||||
void power_save_reset_timer() {
|
||||
TIM6->CNT = 0;
|
||||
if (power_save_status != POWER_SAVE_STATUS_DISABLED){
|
||||
power_save_disable();
|
||||
}
|
||||
}
|
||||
|
||||
void power_save_init(void) {
|
||||
puts("Saving power init\n");
|
||||
TIM6->PSC = 48000-1; // tick on 1 ms
|
||||
|
||||
|
||||
TIM6->ARR = 10000; // 10s
|
||||
// Enable, One-Pulse Mode, Only overflow interrupt
|
||||
TIM6->CR1 = TIM_CR1_CEN | TIM_CR1_OPM | TIM_CR1_URS;
|
||||
TIM6->EGR = TIM_EGR_UG;
|
||||
NVIC_EnableIRQ(TIM6_DAC_IRQn);
|
||||
puts("Saving power init done\n");
|
||||
TIM6->DIER = TIM_DIER_UIE;
|
||||
TIM6->CR1 |= TIM_CR1_CEN;
|
||||
}
|
||||
|
||||
void TIM6_DAC_IRQHandler(void) {
|
||||
//Timeout switch to power saving mode.
|
||||
if (TIM6->SR & TIM_SR_UIF) {
|
||||
TIM6->SR = 0;
|
||||
#ifdef EON
|
||||
if (power_save_status == POWER_SAVE_STATUS_DISABLED) {
|
||||
power_save_enable();
|
||||
} else if (power_save_status == POWER_SAVE_STATUS_SWITCHING) {
|
||||
power_save_enable_can_wake();
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
TIM6->CR1 |= TIM_CR1_CEN;
|
||||
}
|
||||
}
|
||||
|
||||
+6
-23
@@ -5,13 +5,11 @@ struct sample_t {
|
||||
int max;
|
||||
} sample_t_default = {{0}, 0, 0};
|
||||
|
||||
// no float support in STM32F2 micros (cortex-m3)
|
||||
#ifdef PANDA
|
||||
// safety code requires floats
|
||||
struct lookup_t {
|
||||
float x[3];
|
||||
float y[3];
|
||||
};
|
||||
#endif
|
||||
|
||||
void safety_rx_hook(CAN_FIFOMailBox_TypeDef *to_push);
|
||||
int safety_tx_hook(CAN_FIFOMailBox_TypeDef *to_send);
|
||||
@@ -27,21 +25,14 @@ int driver_limit_check(int val, int val_last, struct sample_t *val_driver,
|
||||
const int MAX, const int MAX_RATE_UP, const int MAX_RATE_DOWN,
|
||||
const int MAX_ALLOWANCE, const int DRIVER_FACTOR);
|
||||
int rt_rate_limit_check(int val, int val_last, const int MAX_RT_DELTA);
|
||||
#ifdef PANDA
|
||||
float interpolate(struct lookup_t xy, float x);
|
||||
|
||||
void lline_relay_init (void);
|
||||
void lline_relay_release (void);
|
||||
void set_lline_output(int to_set);
|
||||
#endif
|
||||
|
||||
typedef void (*safety_hook_init)(int16_t param);
|
||||
typedef void (*rx_hook)(CAN_FIFOMailBox_TypeDef *to_push);
|
||||
typedef int (*tx_hook)(CAN_FIFOMailBox_TypeDef *to_send);
|
||||
typedef int (*tx_lin_hook)(int lin_num, uint8_t *data, int len);
|
||||
typedef int (*ign_hook)();
|
||||
typedef int (*fwd_hook)(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd);
|
||||
typedef int (*relay_hook)();
|
||||
|
||||
typedef struct {
|
||||
safety_hook_init init;
|
||||
@@ -50,21 +41,23 @@ typedef struct {
|
||||
tx_hook tx;
|
||||
tx_lin_hook tx_lin;
|
||||
fwd_hook fwd;
|
||||
relay_hook relay;
|
||||
} safety_hooks;
|
||||
|
||||
// This can be set by the safety hooks.
|
||||
int controls_allowed = 0;
|
||||
int gas_interceptor_detected = 0;
|
||||
int gas_interceptor_prev = 0;
|
||||
|
||||
// This is set by USB command 0xdf
|
||||
int long_controls_allowed = 1;
|
||||
|
||||
// Include the actual safety policies.
|
||||
#include "safety/safety_defaults.h"
|
||||
#include "safety/safety_honda.h"
|
||||
#include "safety/safety_toyota.h"
|
||||
#ifdef PANDA
|
||||
#include "safety/safety_toyota_ipas.h"
|
||||
#include "safety/safety_tesla.h"
|
||||
#include "safety/safety_gm_ascm.h"
|
||||
#endif
|
||||
#include "safety/safety_gm.h"
|
||||
#include "safety/safety_ford.h"
|
||||
#include "safety/safety_cadillac.h"
|
||||
@@ -97,10 +90,6 @@ int safety_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) {
|
||||
return current_hooks->fwd(bus_num, to_fwd);
|
||||
}
|
||||
|
||||
int safety_relay_hook(void) {
|
||||
return current_hooks->relay();
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
uint16_t id;
|
||||
const safety_hooks *hooks;
|
||||
@@ -119,7 +108,6 @@ typedef struct {
|
||||
#define SAFETY_SUBARU 10
|
||||
#define SAFETY_GM_ASCM 0x1334
|
||||
#define SAFETY_TOYOTA_IPAS 0x1335
|
||||
#define SAFETY_TOYOTA_NOLIMITS 0x1336
|
||||
#define SAFETY_ALLOUTPUT 0x1337
|
||||
#define SAFETY_ELM327 0xE327
|
||||
|
||||
@@ -134,12 +122,9 @@ const safety_hook_config safety_hook_registry[] = {
|
||||
{SAFETY_HYUNDAI, &hyundai_hooks},
|
||||
{SAFETY_CHRYSLER, &chrysler_hooks},
|
||||
{SAFETY_SUBARU, &subaru_hooks},
|
||||
{SAFETY_TOYOTA_NOLIMITS, &toyota_nolimits_hooks},
|
||||
#ifdef PANDA
|
||||
{SAFETY_TOYOTA_IPAS, &toyota_ipas_hooks},
|
||||
{SAFETY_GM_ASCM, &gm_ascm_hooks},
|
||||
{SAFETY_TESLA, &tesla_hooks},
|
||||
#endif
|
||||
{SAFETY_ALLOUTPUT, &alloutput_hooks},
|
||||
{SAFETY_ELM327, &elm327_hooks},
|
||||
};
|
||||
@@ -239,7 +224,6 @@ int rt_rate_limit_check(int val, int val_last, const int MAX_RT_DELTA) {
|
||||
}
|
||||
|
||||
|
||||
#ifdef PANDA
|
||||
// interp function that holds extreme values
|
||||
float interpolate(struct lookup_t xy, float x) {
|
||||
int size = sizeof(xy.x) / sizeof(xy.x[0]);
|
||||
@@ -264,4 +248,3 @@ float interpolate(struct lookup_t xy, float x) {
|
||||
return xy.y[size - 1];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -115,9 +115,6 @@ static int cadillac_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {
|
||||
static void cadillac_init(int16_t param) {
|
||||
controls_allowed = 0;
|
||||
cadillac_ign = 0;
|
||||
#ifdef PANDA
|
||||
lline_relay_release();
|
||||
#endif
|
||||
}
|
||||
|
||||
static int cadillac_ign_hook() {
|
||||
@@ -131,5 +128,4 @@ const safety_hooks cadillac_hooks = {
|
||||
.tx_lin = nooutput_tx_lin_hook,
|
||||
.ignition = cadillac_ign_hook,
|
||||
.fwd = alloutput_fwd_hook,
|
||||
.relay = nooutput_relay_hook,
|
||||
};
|
||||
|
||||
@@ -127,9 +127,6 @@ static int chrysler_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {
|
||||
|
||||
static void chrysler_init(int16_t param) {
|
||||
chrysler_camera_detected = 0;
|
||||
#ifdef PANDA
|
||||
lline_relay_release();
|
||||
#endif
|
||||
}
|
||||
|
||||
static int chrysler_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) {
|
||||
@@ -153,5 +150,4 @@ const safety_hooks chrysler_hooks = {
|
||||
.tx_lin = nooutput_tx_lin_hook,
|
||||
.ignition = default_ign_hook,
|
||||
.fwd = chrysler_fwd_hook,
|
||||
.relay = nooutput_relay_hook,
|
||||
};
|
||||
|
||||
@@ -8,9 +8,6 @@ int default_ign_hook() {
|
||||
|
||||
static void nooutput_init(int16_t param) {
|
||||
controls_allowed = 0;
|
||||
#ifdef PANDA
|
||||
lline_relay_release();
|
||||
#endif
|
||||
}
|
||||
|
||||
static int nooutput_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {
|
||||
@@ -25,10 +22,6 @@ static int nooutput_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int nooutput_relay_hook(int to_set) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const safety_hooks nooutput_hooks = {
|
||||
.init = nooutput_init,
|
||||
.rx = default_rx_hook,
|
||||
@@ -36,16 +29,12 @@ const safety_hooks nooutput_hooks = {
|
||||
.tx_lin = nooutput_tx_lin_hook,
|
||||
.ignition = default_ign_hook,
|
||||
.fwd = nooutput_fwd_hook,
|
||||
.relay = nooutput_relay_hook,
|
||||
};
|
||||
|
||||
// *** all output safety mode ***
|
||||
|
||||
static void alloutput_init(int16_t param) {
|
||||
controls_allowed = 1;
|
||||
#ifdef PANDA
|
||||
lline_relay_release();
|
||||
#endif
|
||||
}
|
||||
|
||||
static int alloutput_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {
|
||||
@@ -60,10 +49,6 @@ static int alloutput_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int alloutput_relay_hook(int to_set) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const safety_hooks alloutput_hooks = {
|
||||
.init = alloutput_init,
|
||||
.rx = default_rx_hook,
|
||||
@@ -71,5 +56,4 @@ const safety_hooks alloutput_hooks = {
|
||||
.tx_lin = alloutput_tx_lin_hook,
|
||||
.ignition = default_ign_hook,
|
||||
.fwd = alloutput_fwd_hook,
|
||||
.relay = alloutput_relay_hook,
|
||||
};
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
static void elm327_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) {}
|
||||
|
||||
static int elm327_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {
|
||||
//All ELM traffic must appear on CAN0
|
||||
if(((to_send->RDTR >> 4) & 0xf) != 0) return 0;
|
||||
@@ -27,20 +25,11 @@ static int elm327_tx_lin_hook(int lin_num, uint8_t *data, int len) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static void elm327_init(int16_t param) {
|
||||
controls_allowed = 1;
|
||||
}
|
||||
|
||||
static int elm327_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
const safety_hooks elm327_hooks = {
|
||||
.init = elm327_init,
|
||||
.rx = elm327_rx_hook,
|
||||
.init = nooutput_init,
|
||||
.rx = default_rx_hook,
|
||||
.tx = elm327_tx_hook,
|
||||
.tx_lin = elm327_tx_lin_hook,
|
||||
.ignition = default_ign_hook,
|
||||
.fwd = elm327_fwd_hook,
|
||||
.relay = nooutput_relay_hook,
|
||||
.fwd = nooutput_fwd_hook,
|
||||
};
|
||||
|
||||
@@ -90,5 +90,4 @@ const safety_hooks ford_hooks = {
|
||||
.tx_lin = nooutput_tx_lin_hook,
|
||||
.ignition = default_ign_hook,
|
||||
.fwd = nooutput_fwd_hook,
|
||||
.relay = nooutput_relay_hook,
|
||||
};
|
||||
|
||||
@@ -101,7 +101,7 @@ static void gm_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) {
|
||||
// exit controls on rising edge of gas press
|
||||
if (addr == 417) {
|
||||
int gas = to_push->RDHR & 0xFF0000;
|
||||
if (gas && !gm_gas_prev) {
|
||||
if (gas && !gm_gas_prev && long_controls_allowed) {
|
||||
controls_allowed = 0;
|
||||
}
|
||||
gm_gas_prev = gas;
|
||||
@@ -148,7 +148,7 @@ static int gm_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {
|
||||
int rdlr = to_send->RDLR;
|
||||
int brake = ((rdlr & 0xF) << 8) + ((rdlr & 0xFF00) >> 8);
|
||||
brake = (0x1000 - brake) & 0xFFF;
|
||||
if (current_controls_allowed) {
|
||||
if (current_controls_allowed && long_controls_allowed) {
|
||||
if (brake > GM_MAX_BRAKE) return 0;
|
||||
} else {
|
||||
if (brake != 0) return 0;
|
||||
@@ -212,7 +212,7 @@ static int gm_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {
|
||||
int rdlr = to_send->RDLR;
|
||||
int gas_regen = ((rdlr & 0x7F0000) >> 11) + ((rdlr & 0xF8000000) >> 27);
|
||||
int apply = rdlr & 1;
|
||||
if (current_controls_allowed) {
|
||||
if (current_controls_allowed && long_controls_allowed) {
|
||||
if (gas_regen > GM_MAX_GAS) return 0;
|
||||
} else {
|
||||
// Disabled message is !engaed with gas
|
||||
@@ -228,9 +228,6 @@ static int gm_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {
|
||||
static void gm_init(int16_t param) {
|
||||
controls_allowed = 0;
|
||||
gm_ignition_started = 0;
|
||||
#ifdef PANDA
|
||||
lline_relay_release();
|
||||
#endif
|
||||
}
|
||||
|
||||
static int gm_ign_hook() {
|
||||
@@ -244,5 +241,4 @@ const safety_hooks gm_hooks = {
|
||||
.tx_lin = nooutput_tx_lin_hook,
|
||||
.ignition = gm_ign_hook,
|
||||
.fwd = nooutput_fwd_hook,
|
||||
.relay = nooutput_relay_hook,
|
||||
};
|
||||
|
||||
@@ -48,6 +48,5 @@ const safety_hooks gm_ascm_hooks = {
|
||||
.tx_lin = nooutput_tx_lin_hook,
|
||||
.ignition = default_ign_hook,
|
||||
.fwd = gm_ascm_fwd_hook,
|
||||
.relay = nooutput_relay_hook,
|
||||
};
|
||||
|
||||
|
||||
@@ -7,15 +7,11 @@
|
||||
// brake rising edge
|
||||
// brake > 0mph
|
||||
|
||||
// these are set in the Honda safety hooks...this is the wrong place
|
||||
const int gas_interceptor_threshold = 328;
|
||||
int gas_interceptor_detected = 0;
|
||||
int brake_prev = 0;
|
||||
int gas_prev = 0;
|
||||
int gas_interceptor_prev = 0;
|
||||
int ego_speed = 0;
|
||||
// TODO: auto-detect bosch hardware based on CAN messages?
|
||||
bool bosch_hardware = false;
|
||||
const int HONDA_GAS_INTERCEPTOR_THRESHOLD = 328; // ratio between offset and gain from dbc file
|
||||
int honda_brake_prev = 0;
|
||||
int honda_gas_prev = 0;
|
||||
int honda_ego_speed = 0;
|
||||
bool honda_bosch_hardware = false;
|
||||
bool honda_alt_brake_msg = false;
|
||||
|
||||
static void honda_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) {
|
||||
@@ -23,7 +19,7 @@ static void honda_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) {
|
||||
// sample speed
|
||||
if ((to_push->RIR>>21) == 0x158) {
|
||||
// first 2 bytes
|
||||
ego_speed = to_push->RDLR & 0xFFFF;
|
||||
honda_ego_speed = to_push->RDLR & 0xFFFF;
|
||||
}
|
||||
|
||||
// state machine to enter and exit controls
|
||||
@@ -49,10 +45,10 @@ static void honda_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) {
|
||||
// speed > 0
|
||||
if (IS_USER_BRAKE_MSG(to_push)) {
|
||||
int brake = USER_BRAKE_VALUE(to_push);
|
||||
if (brake && (!(brake_prev) || ego_speed)) {
|
||||
if (brake && (!(honda_brake_prev) || honda_ego_speed)) {
|
||||
controls_allowed = 0;
|
||||
}
|
||||
brake_prev = brake;
|
||||
honda_brake_prev = brake;
|
||||
}
|
||||
|
||||
// exit controls on rising edge of gas press if interceptor (0x201 w/ len = 6)
|
||||
@@ -60,8 +56,9 @@ static void honda_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) {
|
||||
if ((to_push->RIR>>21) == 0x201 && (to_push->RDTR & 0xf) == 6) {
|
||||
gas_interceptor_detected = 1;
|
||||
int gas_interceptor = ((to_push->RDLR & 0xFF) << 8) | ((to_push->RDLR & 0xFF00) >> 8);
|
||||
if ((gas_interceptor > gas_interceptor_threshold) &&
|
||||
(gas_interceptor_prev <= gas_interceptor_threshold)) {
|
||||
if ((gas_interceptor > HONDA_GAS_INTERCEPTOR_THRESHOLD) &&
|
||||
(gas_interceptor_prev <= HONDA_GAS_INTERCEPTOR_THRESHOLD) &&
|
||||
long_controls_allowed) {
|
||||
controls_allowed = 0;
|
||||
}
|
||||
gas_interceptor_prev = gas_interceptor;
|
||||
@@ -71,10 +68,10 @@ static void honda_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) {
|
||||
if (!gas_interceptor_detected) {
|
||||
if ((to_push->RIR>>21) == 0x17C) {
|
||||
int gas = to_push->RDLR & 0xFF;
|
||||
if (gas && !(gas_prev)) {
|
||||
if (gas && !(honda_gas_prev) && long_controls_allowed) {
|
||||
controls_allowed = 0;
|
||||
}
|
||||
gas_prev = gas;
|
||||
honda_gas_prev = gas;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -89,13 +86,13 @@ static int honda_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {
|
||||
|
||||
// disallow actuator commands if gas or brake (with vehicle moving) are pressed
|
||||
// and the the latching controls_allowed flag is True
|
||||
int pedal_pressed = gas_prev || (gas_interceptor_prev > gas_interceptor_threshold) ||
|
||||
(brake_prev && ego_speed);
|
||||
int pedal_pressed = honda_gas_prev || (gas_interceptor_prev > HONDA_GAS_INTERCEPTOR_THRESHOLD) ||
|
||||
(honda_brake_prev && honda_ego_speed);
|
||||
int current_controls_allowed = controls_allowed && !(pedal_pressed);
|
||||
|
||||
// BRAKE: safety check
|
||||
if ((to_send->RIR>>21) == 0x1FA) {
|
||||
if (current_controls_allowed) {
|
||||
if (current_controls_allowed && long_controls_allowed) {
|
||||
if ((to_send->RDLR & 0xFFFFFF3F) != to_send->RDLR) return 0;
|
||||
} else {
|
||||
if ((to_send->RDLR & 0xFFFF0000) != to_send->RDLR) return 0;
|
||||
@@ -113,7 +110,7 @@ static int honda_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {
|
||||
|
||||
// GAS: safety check
|
||||
if ((to_send->RIR>>21) == 0x200) {
|
||||
if (current_controls_allowed) {
|
||||
if (current_controls_allowed && long_controls_allowed) {
|
||||
// all messages are fine here
|
||||
} else {
|
||||
if ((to_send->RDLR & 0xFFFF0000) != to_send->RDLR) return 0;
|
||||
@@ -123,7 +120,7 @@ static int honda_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {
|
||||
// FORCE CANCEL: safety check only relevant when spamming the cancel button in Bosch HW
|
||||
// ensuring that only the cancel button press is sent (VAL 2) when controls are off.
|
||||
// This avoids unintended engagements while still allowing resume spam
|
||||
if (((to_send->RIR>>21) == 0x296) && bosch_hardware &&
|
||||
if (((to_send->RIR>>21) == 0x296) && honda_bosch_hardware &&
|
||||
!current_controls_allowed && ((to_send->RDTR >> 4) & 0xFF) == 0) {
|
||||
if (((to_send->RDLR >> 5) & 0x7) != 2) return 0;
|
||||
}
|
||||
@@ -134,21 +131,15 @@ static int honda_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {
|
||||
|
||||
static void honda_init(int16_t param) {
|
||||
controls_allowed = 0;
|
||||
bosch_hardware = false;
|
||||
honda_bosch_hardware = false;
|
||||
honda_alt_brake_msg = false;
|
||||
#ifdef PANDA
|
||||
lline_relay_release();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void honda_bosch_init(int16_t param) {
|
||||
controls_allowed = 0;
|
||||
bosch_hardware = true;
|
||||
honda_bosch_hardware = true;
|
||||
// Checking for alternate brake override from safety parameter
|
||||
honda_alt_brake_msg = param == 1 ? true : false;
|
||||
#ifdef PANDA
|
||||
lline_relay_release();
|
||||
#endif
|
||||
}
|
||||
|
||||
static int honda_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) {
|
||||
@@ -159,11 +150,15 @@ static int honda_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) {
|
||||
int addr = to_fwd->RIR>>21;
|
||||
if (bus_num == 0) {
|
||||
return 2;
|
||||
} else if (bus_num == 2 && addr != 0xE4 && addr != 0x194 && addr != 0x1FA &&
|
||||
addr != 0x30C && addr != 0x33D && addr != 0x39F) {
|
||||
} else if (bus_num == 2) {
|
||||
// block stock lkas messages and stock acc messages (if OP is doing ACC)
|
||||
int is_lkas_msg = (addr == 0xE4 || addr == 0x194 || addr == 0x33D);
|
||||
int is_acc_msg = (addr == 0x1FA || addr == 0x30C || addr == 0x39F);
|
||||
if (is_lkas_msg || (is_acc_msg && long_controls_allowed)) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -182,7 +177,6 @@ const safety_hooks honda_hooks = {
|
||||
.tx_lin = nooutput_tx_lin_hook,
|
||||
.ignition = default_ign_hook,
|
||||
.fwd = honda_fwd_hook,
|
||||
.relay = nooutput_relay_hook,
|
||||
};
|
||||
|
||||
const safety_hooks honda_bosch_hooks = {
|
||||
@@ -192,5 +186,4 @@ const safety_hooks honda_bosch_hooks = {
|
||||
.tx_lin = nooutput_tx_lin_hook,
|
||||
.ignition = default_ign_hook,
|
||||
.fwd = honda_bosch_fwd_hook,
|
||||
.relay = nooutput_relay_hook,
|
||||
};
|
||||
|
||||
@@ -152,9 +152,6 @@ static int hyundai_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) {
|
||||
static void hyundai_init(int16_t param) {
|
||||
controls_allowed = 0;
|
||||
hyundai_giraffe_switch_2 = 0;
|
||||
#ifdef PANDA
|
||||
lline_relay_release();
|
||||
#endif
|
||||
}
|
||||
|
||||
const safety_hooks hyundai_hooks = {
|
||||
@@ -164,5 +161,4 @@ const safety_hooks hyundai_hooks = {
|
||||
.tx_lin = nooutput_tx_lin_hook,
|
||||
.ignition = default_ign_hook,
|
||||
.fwd = hyundai_fwd_hook,
|
||||
.relay = nooutput_relay_hook,
|
||||
};
|
||||
|
||||
@@ -15,9 +15,6 @@ uint32_t subaru_ts_last = 0;
|
||||
struct sample_t subaru_torque_driver; // last few driver torques measured
|
||||
|
||||
static void subaru_init(int16_t param) {
|
||||
#ifdef PANDA
|
||||
lline_relay_init();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void subaru_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) {
|
||||
@@ -142,5 +139,4 @@ const safety_hooks subaru_hooks = {
|
||||
.tx_lin = nooutput_tx_lin_hook,
|
||||
.ignition = default_ign_hook,
|
||||
.fwd = subaru_fwd_hook,
|
||||
.relay = alloutput_relay_hook,
|
||||
};
|
||||
|
||||
@@ -219,20 +219,11 @@ static int tesla_tx_hook(CAN_FIFOMailBox_TypeDef *to_send)
|
||||
return true;
|
||||
}
|
||||
|
||||
static int tesla_tx_lin_hook(int lin_num, uint8_t *data, int len)
|
||||
{
|
||||
// LIN is not used on the Tesla
|
||||
return false;
|
||||
}
|
||||
|
||||
static void tesla_init(int16_t param)
|
||||
{
|
||||
controls_allowed = 0;
|
||||
tesla_ignition_started = 0;
|
||||
gmlan_switch_init(1); //init the gmlan switch with 1s timeout enabled
|
||||
#ifdef PANDA
|
||||
lline_relay_release();
|
||||
#endif
|
||||
}
|
||||
|
||||
static int tesla_ign_hook()
|
||||
@@ -281,11 +272,10 @@ static int tesla_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd)
|
||||
}
|
||||
|
||||
const safety_hooks tesla_hooks = {
|
||||
.init = tesla_init,
|
||||
.rx = tesla_rx_hook,
|
||||
.tx = tesla_tx_hook,
|
||||
.tx_lin = tesla_tx_lin_hook,
|
||||
.ignition = tesla_ign_hook,
|
||||
.fwd = tesla_fwd_hook,
|
||||
.relay = nooutput_relay_hook,
|
||||
.init = tesla_init,
|
||||
.rx = tesla_rx_hook,
|
||||
.tx = tesla_tx_hook,
|
||||
.tx_lin = nooutput_tx_lin_hook,
|
||||
.ignition = tesla_ign_hook,
|
||||
.fwd = tesla_fwd_hook,
|
||||
};
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
int toyota_giraffe_switch_1 = 0; // is giraffe switch 1 high?
|
||||
int toyota_camera_forwarded = 0; // should we forward the camera bus?
|
||||
|
||||
// global torque limit
|
||||
const int TOYOTA_MAX_TORQUE = 1500; // max torque cmd allowed ever
|
||||
|
||||
@@ -19,15 +16,19 @@ const int TOYOTA_RT_INTERVAL = 250000; // 250ms between real time checks
|
||||
const int TOYOTA_MAX_ACCEL = 1500; // 1.5 m/s2
|
||||
const int TOYOTA_MIN_ACCEL = -3000; // 3.0 m/s2
|
||||
|
||||
// global actuation limit state
|
||||
int toyota_actuation_limits = 1; // by default steer limits are imposed
|
||||
const int TOYOTA_GAS_INTERCEPTOR_THRESHOLD = 475; // ratio between offset and gain from dbc file
|
||||
|
||||
// global actuation limit states
|
||||
int toyota_dbc_eps_torque_factor = 100; // conversion factor for STEER_TORQUE_EPS in %: see dbc file
|
||||
|
||||
// state of torque limits
|
||||
// states
|
||||
int toyota_giraffe_switch_1 = 0; // is giraffe switch 1 high?
|
||||
int toyota_camera_forwarded = 0; // should we forward the camera bus?
|
||||
int toyota_desired_torque_last = 0; // last desired steer torque
|
||||
int toyota_rt_torque_last = 0; // last desired torque for real time check
|
||||
uint32_t toyota_ts_last = 0;
|
||||
int toyota_cruise_engaged_last = 0; // cruise state
|
||||
int toyota_gas_prev = 0;
|
||||
struct sample_t toyota_torque_meas; // last 3 motor torques produced by the eps
|
||||
|
||||
|
||||
@@ -40,23 +41,40 @@ static void toyota_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) {
|
||||
// scale by dbc_factor
|
||||
torque_meas_new = (torque_meas_new * toyota_dbc_eps_torque_factor) / 100;
|
||||
|
||||
// increase torque_meas by 1 to be conservative on rounding
|
||||
torque_meas_new += (torque_meas_new > 0 ? 1 : -1);
|
||||
|
||||
// update array of sample
|
||||
update_sample(&toyota_torque_meas, torque_meas_new);
|
||||
|
||||
// increase torque_meas by 1 to be conservative on rounding
|
||||
toyota_torque_meas.min--;
|
||||
toyota_torque_meas.max++;
|
||||
}
|
||||
|
||||
// enter controls on rising edge of ACC, exit controls on ACC off
|
||||
if ((to_push->RIR>>21) == 0x1D2) {
|
||||
// 5th bit is CRUISE_ACTIVE
|
||||
int cruise_engaged = to_push->RDLR & 0x20;
|
||||
if (cruise_engaged && !toyota_cruise_engaged_last) {
|
||||
controls_allowed = 1;
|
||||
} else if (!cruise_engaged) {
|
||||
// 4th bit is GAS_RELEASED
|
||||
int gas = !(to_push->RDLR & 0x10);
|
||||
if (!cruise_engaged ||
|
||||
(gas && !toyota_gas_prev && !gas_interceptor_detected && long_controls_allowed)) {
|
||||
controls_allowed = 0;
|
||||
} else if (cruise_engaged && !toyota_cruise_engaged_last) {
|
||||
controls_allowed = 1;
|
||||
}
|
||||
toyota_cruise_engaged_last = cruise_engaged;
|
||||
toyota_gas_prev = gas;
|
||||
}
|
||||
|
||||
// exit controls on rising edge of gas press if interceptor (0x201)
|
||||
if ((to_push->RIR>>21) == 0x201) {
|
||||
gas_interceptor_detected = 1;
|
||||
int gas_interceptor = ((to_push->RDLR & 0xFF) << 8) | ((to_push->RDLR & 0xFF00) >> 8);
|
||||
if ((gas_interceptor > TOYOTA_GAS_INTERCEPTOR_THRESHOLD) &&
|
||||
(gas_interceptor_prev <= TOYOTA_GAS_INTERCEPTOR_THRESHOLD) &&
|
||||
long_controls_allowed) {
|
||||
controls_allowed = 0;
|
||||
}
|
||||
gas_interceptor_prev = gas_interceptor;
|
||||
}
|
||||
|
||||
int bus = (to_push->RDTR >> 4) & 0xF;
|
||||
@@ -81,7 +99,7 @@ static int toyota_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {
|
||||
|
||||
// GAS PEDAL: safety check
|
||||
if ((to_send->RIR>>21) == 0x200) {
|
||||
if (controls_allowed && toyota_actuation_limits) {
|
||||
if (controls_allowed && long_controls_allowed) {
|
||||
// all messages are fine here
|
||||
} else {
|
||||
if ((to_send->RDLR & 0xFFFF0000) != to_send->RDLR) return 0;
|
||||
@@ -92,10 +110,10 @@ static int toyota_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {
|
||||
if ((to_send->RIR>>21) == 0x343) {
|
||||
int desired_accel = ((to_send->RDLR & 0xFF) << 8) | ((to_send->RDLR >> 8) & 0xFF);
|
||||
desired_accel = to_signed(desired_accel, 16);
|
||||
if (controls_allowed && toyota_actuation_limits) {
|
||||
if (controls_allowed && long_controls_allowed) {
|
||||
int violation = max_limit_check(desired_accel, TOYOTA_MAX_ACCEL, TOYOTA_MIN_ACCEL);
|
||||
if (violation) return 0;
|
||||
} else if (!controls_allowed && (desired_accel != 0)) {
|
||||
} else if (desired_accel != 0) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -108,8 +126,7 @@ static int toyota_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {
|
||||
|
||||
uint32_t ts = TIM2->CNT;
|
||||
|
||||
// only check if controls are allowed and actuation_limits are imposed
|
||||
if (controls_allowed && toyota_actuation_limits) {
|
||||
if (controls_allowed) {
|
||||
|
||||
// *** global torque limit check ***
|
||||
violation |= max_limit_check(desired_torque, TOYOTA_MAX_TORQUE, -TOYOTA_MAX_TORQUE);
|
||||
@@ -156,25 +173,27 @@ static int toyota_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {
|
||||
|
||||
static void toyota_init(int16_t param) {
|
||||
controls_allowed = 0;
|
||||
toyota_actuation_limits = 1;
|
||||
toyota_giraffe_switch_1 = 0;
|
||||
toyota_camera_forwarded = 0;
|
||||
toyota_dbc_eps_torque_factor = param;
|
||||
#ifdef PANDA
|
||||
lline_relay_release();
|
||||
#endif
|
||||
}
|
||||
|
||||
static int toyota_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) {
|
||||
|
||||
// forward cam to radar and viceversa if car, except lkas cmd and hud
|
||||
// don't forward when switch 1 is high
|
||||
if ((bus_num == 0 || bus_num == 2) && toyota_camera_forwarded && !toyota_giraffe_switch_1) {
|
||||
if (toyota_camera_forwarded && !toyota_giraffe_switch_1) {
|
||||
int addr = to_fwd->RIR>>21;
|
||||
bool is_lkas_msg = (addr == 0x2E4 || addr == 0x412) && bus_num == 2;
|
||||
// in TSSP 2.0 the camera does ACC as well, so filter 0x343
|
||||
bool is_acc_msg = (addr == 0x343 && bus_num == 2);
|
||||
return (is_lkas_msg || is_acc_msg)? -1 : (uint8_t)(~bus_num & 0x2);
|
||||
if (bus_num == 0) {
|
||||
return 2;
|
||||
} else if (bus_num == 2) {
|
||||
// block stock lkas messages and stock acc messages (if OP is doing ACC)
|
||||
int is_lkas_msg = (addr == 0x2E4 || addr == 0x412);
|
||||
// in TSSP 2.0 the camera does ACC as well, so filter 0x343
|
||||
int is_acc_msg = (addr == 0x343);
|
||||
if (is_lkas_msg || (is_acc_msg && long_controls_allowed)) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
@@ -186,26 +205,4 @@ const safety_hooks toyota_hooks = {
|
||||
.tx_lin = nooutput_tx_lin_hook,
|
||||
.ignition = default_ign_hook,
|
||||
.fwd = toyota_fwd_hook,
|
||||
.relay = nooutput_relay_hook,
|
||||
};
|
||||
|
||||
static void toyota_nolimits_init(int16_t param) {
|
||||
controls_allowed = 0;
|
||||
toyota_actuation_limits = 0;
|
||||
toyota_giraffe_switch_1 = 0;
|
||||
toyota_camera_forwarded = 0;
|
||||
toyota_dbc_eps_torque_factor = param;
|
||||
#ifdef PANDA
|
||||
lline_relay_release();
|
||||
#endif
|
||||
}
|
||||
|
||||
const safety_hooks toyota_nolimits_hooks = {
|
||||
.init = toyota_nolimits_init,
|
||||
.rx = toyota_rx_hook,
|
||||
.tx = toyota_tx_hook,
|
||||
.tx_lin = nooutput_tx_lin_hook,
|
||||
.ignition = default_ign_hook,
|
||||
.fwd = toyota_fwd_hook,
|
||||
.relay = nooutput_relay_hook,
|
||||
};
|
||||
|
||||
@@ -152,5 +152,4 @@ const safety_hooks toyota_ipas_hooks = {
|
||||
.tx_lin = nooutput_tx_lin_hook,
|
||||
.ignition = default_ign_hook,
|
||||
.fwd = toyota_fwd_hook,
|
||||
.relay = nooutput_relay_hook,
|
||||
};
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
uint32_t *prog_ptr = NULL;
|
||||
int unlocked = 0;
|
||||
|
||||
#ifdef uart_ring
|
||||
void debug_ring_callback(uart_ring *ring) {}
|
||||
#endif
|
||||
|
||||
int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, int hardwired) {
|
||||
int resp_len = 0;
|
||||
@@ -46,7 +48,7 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, int hardwired) {
|
||||
break;
|
||||
// **** 0xd0: fetch serial number
|
||||
case 0xd0:
|
||||
#ifdef PANDA
|
||||
#ifdef STM32F4
|
||||
// addresses are OTP
|
||||
if (setup->b.wValue.w == 1) {
|
||||
memcpy(resp, (void *)0x1fff79c0, 0x10);
|
||||
@@ -132,6 +134,7 @@ int spi_cb_rx(uint8_t *data, int len, uint8_t *data_out) {
|
||||
|
||||
#ifdef PEDAL
|
||||
|
||||
#include "drivers/llcan.h"
|
||||
#define CAN CAN1
|
||||
|
||||
#define CAN_BL_INPUT 0x1
|
||||
@@ -239,7 +242,7 @@ void CAN1_RX0_IRQHandler() {
|
||||
}
|
||||
|
||||
void CAN1_SCE_IRQHandler() {
|
||||
can_sce(CAN);
|
||||
llcan_clear_send(CAN);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -264,8 +267,8 @@ void soft_flasher_start() {
|
||||
set_can_enable(CAN1, 1);
|
||||
|
||||
// init can
|
||||
can_silent = ALL_CAN_LIVE;
|
||||
can_init(0);
|
||||
llcan_set_speed(CAN1, 5000, false, false);
|
||||
llcan_init(CAN1);
|
||||
#endif
|
||||
|
||||
// A4,A5,A6,A7: setup SPI
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 12 KiB |
@@ -3,7 +3,7 @@ import time
|
||||
import struct
|
||||
from panda import Panda
|
||||
from hexdump import hexdump
|
||||
from panda.isotp import isotp_send, isotp_recv
|
||||
from panda.python.isotp import isotp_send, isotp_recv
|
||||
|
||||
# 0x7e0 = Toyota
|
||||
# 0x18DB33F1 for Honda?
|
||||
@@ -33,7 +33,7 @@ if __name__ == "__main__":
|
||||
panda.can_clear(0)
|
||||
|
||||
# 09 02 = Get VIN
|
||||
isotp_send(panda, "\x09\x02", 0x7e0)
|
||||
isotp_send(panda, "\x09\x02", 0x7df)
|
||||
ret = isotp_recv(panda, 0x7e8)
|
||||
hexdump(ret)
|
||||
print "VIN: %s" % ret[2:]
|
||||
|
||||
@@ -392,9 +392,6 @@ class Panda(object):
|
||||
elif bus in [Panda.GMLAN_CAN2, Panda.GMLAN_CAN3]:
|
||||
self._handle.controlWrite(Panda.REQUEST_OUT, 0xdb, 1, bus, b'')
|
||||
|
||||
def set_lline_relay(self, enable):
|
||||
self._handle.controlWrite(Panda.REQUEST_OUT, 0xf3, int(enable), 0, b'')
|
||||
|
||||
def set_can_loopback(self, enable):
|
||||
# set can loopback mode for all buses
|
||||
self._handle.controlWrite(Panda.REQUEST_OUT, 0xe5, int(enable), 0, b'')
|
||||
|
||||
@@ -6,4 +6,9 @@ else
|
||||
TESTSUITE_NAME="Panda_Test-DEV"
|
||||
fi
|
||||
|
||||
PYTHONPATH="." nosetests -v --with-xunit --xunit-file=./$TEST_FILENAME --xunit-testsuite-name=$TESTSUITE_NAME -s tests/automated/$1*.py
|
||||
cd boardesp
|
||||
make flashall
|
||||
cd ..
|
||||
|
||||
|
||||
PYTHONPATH="." python $(which nosetests) -v --with-xunit --xunit-file=./$TEST_FILENAME --xunit-testsuite-name=$TESTSUITE_NAME -s tests/automated/$1*.py
|
||||
|
||||
@@ -1,12 +1,6 @@
|
||||
import os
|
||||
from panda import build_st
|
||||
|
||||
def test_build_legacy():
|
||||
build_st("obj/comma.bin", "Makefile.legacy")
|
||||
|
||||
def test_build_bootstub_legacy():
|
||||
build_st("obj/bootstub.comma.bin", "Makefile.legacy")
|
||||
|
||||
def test_build_panda():
|
||||
build_st("obj/panda.bin")
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ def test_connect_wifi(serial=None):
|
||||
@panda_color_to_serial
|
||||
def test_flash_wifi(serial=None):
|
||||
connect_wifi(serial)
|
||||
assert Panda.flash_ota_wifi(release=True), "OTA Wifi Flash Failed"
|
||||
assert Panda.flash_ota_wifi(release=False), "OTA Wifi Flash Failed"
|
||||
connect_wifi(serial)
|
||||
|
||||
@test_white
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
FROM ubuntu:16.04
|
||||
|
||||
RUN apt-get update && apt-get install -y gcc-arm-none-eabi libnewlib-arm-none-eabi python python-pip gcc g++
|
||||
|
||||
RUN pip install pycrypto==2.6.1
|
||||
|
||||
COPY . /panda
|
||||
|
||||
WORKDIR /panda
|
||||
@@ -0,0 +1,6 @@
|
||||
FROM ubuntu:16.04
|
||||
|
||||
RUN apt-get update && apt-get install -y make python python-pip git
|
||||
COPY tests/safety/requirements.txt /panda/tests/safety/requirements.txt
|
||||
RUN pip install -r /panda/tests/safety/requirements.txt
|
||||
COPY . /panda
|
||||
Executable
+8
@@ -0,0 +1,8 @@
|
||||
#!/bin/bash -e
|
||||
git clone https://github.com/danmar/cppcheck.git || true
|
||||
cd cppcheck
|
||||
git checkout 29e5992e51ecf1ddba469c73a0eed0b28b131de5
|
||||
make -j4
|
||||
cd ../../../
|
||||
tests/misra/cppcheck/cppcheck --dump board/main.c
|
||||
python tests/misra/cppcheck/addons/misra.py board/main.c.dump 2>/tmp/misra/output.txt || true
|
||||
@@ -32,6 +32,11 @@ typedef struct
|
||||
|
||||
void set_controls_allowed(int c);
|
||||
int get_controls_allowed(void);
|
||||
void set_long_controls_allowed(int c);
|
||||
int get_long_controls_allowed(void);
|
||||
void set_gas_interceptor_detected(int c);
|
||||
int get_gas_interceptor_detetcted(void);
|
||||
int get_gas_interceptor_prev(void);
|
||||
void set_timer(int t);
|
||||
void reset_angle_control(void);
|
||||
|
||||
@@ -41,19 +46,20 @@ int toyota_tx_hook(CAN_FIFOMailBox_TypeDef *to_send);
|
||||
void toyota_init(int16_t param);
|
||||
int get_toyota_torque_meas_min(void);
|
||||
int get_toyota_torque_meas_max(void);
|
||||
int get_toyota_gas_prev(void);
|
||||
void set_toyota_torque_meas(int min, int max);
|
||||
void set_toyota_desired_torque_last(int t);
|
||||
void set_toyota_rt_torque_last(int t);
|
||||
|
||||
void init_tests_honda(void);
|
||||
int get_ego_speed(void);
|
||||
int get_honda_ego_speed(void);
|
||||
void honda_init(int16_t param);
|
||||
void honda_rx_hook(CAN_FIFOMailBox_TypeDef *to_push);
|
||||
int honda_tx_hook(CAN_FIFOMailBox_TypeDef *to_send);
|
||||
int get_brake_prev(void);
|
||||
int get_gas_prev(void);
|
||||
int get_honda_brake_prev(void);
|
||||
int get_honda_gas_prev(void);
|
||||
void set_honda_alt_brake_msg(bool);
|
||||
void set_bosch_hardware(bool);
|
||||
void set_honda_bosch_hardware(bool);
|
||||
|
||||
void init_tests_cadillac(void);
|
||||
void cadillac_init(int16_t param);
|
||||
|
||||
+35
-20
@@ -51,6 +51,14 @@ void set_controls_allowed(int c){
|
||||
controls_allowed = c;
|
||||
}
|
||||
|
||||
void set_long_controls_allowed(int c){
|
||||
long_controls_allowed = c;
|
||||
}
|
||||
|
||||
void set_gas_interceptor_detected(int c){
|
||||
gas_interceptor_detected = c;
|
||||
}
|
||||
|
||||
void reset_angle_control(void){
|
||||
angle_control = 0;
|
||||
}
|
||||
@@ -59,6 +67,18 @@ int get_controls_allowed(void){
|
||||
return controls_allowed;
|
||||
}
|
||||
|
||||
int get_long_controls_allowed(void){
|
||||
return long_controls_allowed;
|
||||
}
|
||||
|
||||
int get_gas_interceptor_detected(void){
|
||||
return gas_interceptor_detected;
|
||||
}
|
||||
|
||||
int get_gas_interceptor_prev(void){
|
||||
return gas_interceptor_prev;
|
||||
}
|
||||
|
||||
void set_timer(int t){
|
||||
timer.CNT = t;
|
||||
}
|
||||
@@ -101,6 +121,10 @@ int get_chrysler_torque_meas_max(void){
|
||||
return chrysler_torque_meas.max;
|
||||
}
|
||||
|
||||
int get_toyota_gas_prev(void){
|
||||
return toyota_gas_prev;
|
||||
}
|
||||
|
||||
int get_toyota_torque_meas_min(void){
|
||||
return toyota_torque_meas.min;
|
||||
}
|
||||
@@ -157,24 +181,24 @@ void set_subaru_desired_torque_last(int t){
|
||||
subaru_desired_torque_last = t;
|
||||
}
|
||||
|
||||
int get_ego_speed(void){
|
||||
return ego_speed;
|
||||
int get_honda_ego_speed(void){
|
||||
return honda_ego_speed;
|
||||
}
|
||||
|
||||
int get_brake_prev(void){
|
||||
return brake_prev;
|
||||
int get_honda_brake_prev(void){
|
||||
return honda_brake_prev;
|
||||
}
|
||||
|
||||
int get_gas_prev(void){
|
||||
return gas_prev;
|
||||
int get_honda_gas_prev(void){
|
||||
return honda_gas_prev;
|
||||
}
|
||||
|
||||
void set_honda_alt_brake_msg(bool c){
|
||||
honda_alt_brake_msg = c;
|
||||
}
|
||||
|
||||
void set_bosch_hardware(bool c){
|
||||
bosch_hardware = c;
|
||||
void set_honda_bosch_hardware(bool c){
|
||||
honda_bosch_hardware = c;
|
||||
}
|
||||
|
||||
void init_tests_toyota(void){
|
||||
@@ -232,10 +256,9 @@ void init_tests_subaru(void){
|
||||
}
|
||||
|
||||
void init_tests_honda(void){
|
||||
ego_speed = 0;
|
||||
gas_interceptor_detected = 0;
|
||||
brake_prev = 0;
|
||||
gas_prev = 0;
|
||||
honda_ego_speed = 0;
|
||||
honda_brake_prev = 0;
|
||||
honda_gas_prev = 0;
|
||||
}
|
||||
|
||||
void set_gmlan_digital_output(int to_set){
|
||||
@@ -247,11 +270,3 @@ void reset_gmlan_switch_timeout(void){
|
||||
void gmlan_switch_init(int timeout_enable){
|
||||
}
|
||||
|
||||
void lline_relay_init (void) {
|
||||
}
|
||||
|
||||
void lline_relay_release (void) {
|
||||
}
|
||||
|
||||
void set_lline_output(int to_set) {
|
||||
}
|
||||
|
||||
@@ -138,10 +138,15 @@ class TestGmSafety(unittest.TestCase):
|
||||
self.safety.gm_rx_hook(self._brake_msg(False))
|
||||
|
||||
def test_disengage_on_gas(self):
|
||||
self.safety.set_controls_allowed(1)
|
||||
self.safety.gm_rx_hook(self._gas_msg(True))
|
||||
self.assertFalse(self.safety.get_controls_allowed())
|
||||
self.safety.gm_rx_hook(self._gas_msg(False))
|
||||
for long_controls_allowed in [0, 1]:
|
||||
self.safety.set_long_controls_allowed(long_controls_allowed)
|
||||
self.safety.set_controls_allowed(1)
|
||||
self.safety.gm_rx_hook(self._gas_msg(True))
|
||||
if long_controls_allowed:
|
||||
self.assertFalse(self.safety.get_controls_allowed())
|
||||
else:
|
||||
self.assertTrue(self.safety.get_controls_allowed())
|
||||
self.safety.gm_rx_hook(self._gas_msg(False))
|
||||
|
||||
def test_allow_engage_with_gas_pressed(self):
|
||||
self.safety.gm_rx_hook(self._gas_msg(True))
|
||||
@@ -151,22 +156,28 @@ class TestGmSafety(unittest.TestCase):
|
||||
self.safety.gm_rx_hook(self._gas_msg(False))
|
||||
|
||||
def test_brake_safety_check(self):
|
||||
for enabled in [0, 1]:
|
||||
for b in range(0, 500):
|
||||
self.safety.set_controls_allowed(enabled)
|
||||
if abs(b) > MAX_BRAKE or (not enabled and b != 0):
|
||||
self.assertFalse(self.safety.gm_tx_hook(self._send_brake_msg(b)))
|
||||
else:
|
||||
self.assertTrue(self.safety.gm_tx_hook(self._send_brake_msg(b)))
|
||||
for long_controls_allowed in [0, 1]:
|
||||
self.safety.set_long_controls_allowed(long_controls_allowed)
|
||||
for enabled in [0, 1]:
|
||||
for b in range(0, 500):
|
||||
self.safety.set_controls_allowed(enabled)
|
||||
if abs(b) > MAX_BRAKE or ((not enabled or not long_controls_allowed) and b != 0):
|
||||
self.assertFalse(self.safety.gm_tx_hook(self._send_brake_msg(b)))
|
||||
else:
|
||||
self.assertTrue(self.safety.gm_tx_hook(self._send_brake_msg(b)))
|
||||
self.safety.set_long_controls_allowed(True)
|
||||
|
||||
def test_gas_safety_check(self):
|
||||
for enabled in [0, 1]:
|
||||
for g in range(0, 2**12-1):
|
||||
self.safety.set_controls_allowed(enabled)
|
||||
if abs(g) > MAX_GAS or (not enabled and g != MAX_REGEN):
|
||||
self.assertFalse(self.safety.gm_tx_hook(self._send_gas_msg(g)))
|
||||
else:
|
||||
self.assertTrue(self.safety.gm_tx_hook(self._send_gas_msg(g)))
|
||||
for long_controls_allowed in [0, 1]:
|
||||
self.safety.set_long_controls_allowed(long_controls_allowed)
|
||||
for enabled in [0, 1]:
|
||||
for g in range(0, 2**12-1):
|
||||
self.safety.set_controls_allowed(enabled)
|
||||
if abs(g) > MAX_GAS or ((not enabled or not long_controls_allowed) and g != MAX_REGEN):
|
||||
self.assertFalse(self.safety.gm_tx_hook(self._send_gas_msg(g)))
|
||||
else:
|
||||
self.assertTrue(self.safety.gm_tx_hook(self._send_gas_msg(g)))
|
||||
self.safety.set_long_controls_allowed(True)
|
||||
|
||||
def test_steer_safety_check(self):
|
||||
for enabled in [0, 1]:
|
||||
|
||||
@@ -3,6 +3,7 @@ import unittest
|
||||
import numpy as np
|
||||
import libpandasafety_py
|
||||
|
||||
MAX_BRAKE = 255
|
||||
|
||||
class TestHondaSafety(unittest.TestCase):
|
||||
@classmethod
|
||||
@@ -49,14 +50,15 @@ class TestHondaSafety(unittest.TestCase):
|
||||
def _send_brake_msg(self, brake):
|
||||
to_send = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *')
|
||||
to_send[0].RIR = 0x1FA << 21
|
||||
to_send[0].RDLR = brake
|
||||
to_send[0].RDLR = ((brake & 0x3) << 8) | ((brake & 0x3FF) >> 2)
|
||||
|
||||
return to_send
|
||||
|
||||
def _send_gas_msg(self, gas):
|
||||
def _send_interceptor_msg(self, gas, addr):
|
||||
to_send = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *')
|
||||
to_send[0].RIR = 0x200 << 21
|
||||
to_send[0].RDLR = gas
|
||||
to_send[0].RIR = addr << 21
|
||||
to_send[0].RDTR = 6
|
||||
to_send[0].RDLR = ((gas & 0xff) << 8) | ((gas & 0xff00) >> 8)
|
||||
|
||||
return to_send
|
||||
|
||||
@@ -89,14 +91,14 @@ class TestHondaSafety(unittest.TestCase):
|
||||
self.assertFalse(self.safety.get_controls_allowed())
|
||||
|
||||
def test_sample_speed(self):
|
||||
self.assertEqual(0, self.safety.get_ego_speed())
|
||||
self.assertEqual(0, self.safety.get_honda_ego_speed())
|
||||
self.safety.honda_rx_hook(self._speed_msg(100))
|
||||
self.assertEqual(100, self.safety.get_ego_speed())
|
||||
self.assertEqual(100, self.safety.get_honda_ego_speed())
|
||||
|
||||
def test_prev_brake(self):
|
||||
self.assertFalse(self.safety.get_brake_prev())
|
||||
self.assertFalse(self.safety.get_honda_brake_prev())
|
||||
self.safety.honda_rx_hook(self._brake_msg(True))
|
||||
self.assertTrue(self.safety.get_brake_prev())
|
||||
self.assertTrue(self.safety.get_honda_brake_prev())
|
||||
|
||||
def test_disengage_on_brake(self):
|
||||
self.safety.set_controls_allowed(1)
|
||||
@@ -133,14 +135,30 @@ class TestHondaSafety(unittest.TestCase):
|
||||
self.assertFalse(self.safety.get_controls_allowed())
|
||||
|
||||
def test_prev_gas(self):
|
||||
self.assertFalse(self.safety.get_gas_prev())
|
||||
self.safety.honda_rx_hook(self._gas_msg(False))
|
||||
self.assertFalse(self.safety.get_honda_gas_prev())
|
||||
self.safety.honda_rx_hook(self._gas_msg(True))
|
||||
self.assertTrue(self.safety.get_gas_prev())
|
||||
self.assertTrue(self.safety.get_honda_gas_prev())
|
||||
|
||||
def test_prev_gas_interceptor(self):
|
||||
self.safety.honda_rx_hook(self._send_interceptor_msg(0x0, 0x201))
|
||||
self.assertFalse(self.safety.get_gas_interceptor_prev())
|
||||
self.safety.honda_rx_hook(self._send_interceptor_msg(0x1000, 0x201))
|
||||
self.assertTrue(self.safety.get_gas_interceptor_prev())
|
||||
self.safety.honda_rx_hook(self._send_interceptor_msg(0x0, 0x201))
|
||||
self.safety.set_gas_interceptor_detected(False)
|
||||
|
||||
def test_disengage_on_gas(self):
|
||||
self.safety.set_controls_allowed(1)
|
||||
self.safety.honda_rx_hook(self._gas_msg(1))
|
||||
self.assertFalse(self.safety.get_controls_allowed())
|
||||
for long_controls_allowed in [0, 1]:
|
||||
self.safety.set_long_controls_allowed(long_controls_allowed)
|
||||
self.safety.honda_rx_hook(self._gas_msg(0))
|
||||
self.safety.set_controls_allowed(1)
|
||||
self.safety.honda_rx_hook(self._gas_msg(1))
|
||||
if long_controls_allowed:
|
||||
self.assertFalse(self.safety.get_controls_allowed())
|
||||
else:
|
||||
self.assertTrue(self.safety.get_controls_allowed())
|
||||
self.safety.set_long_controls_allowed(True)
|
||||
|
||||
def test_allow_engage_with_gas_pressed(self):
|
||||
self.safety.honda_rx_hook(self._gas_msg(1))
|
||||
@@ -148,18 +166,53 @@ class TestHondaSafety(unittest.TestCase):
|
||||
self.safety.honda_rx_hook(self._gas_msg(1))
|
||||
self.assertTrue(self.safety.get_controls_allowed())
|
||||
|
||||
def test_brake_safety_check(self):
|
||||
self.assertTrue(self.safety.honda_tx_hook(self._send_brake_msg(0x0000)))
|
||||
self.assertFalse(self.safety.honda_tx_hook(self._send_brake_msg(0x1000)))
|
||||
def test_disengage_on_gas_interceptor(self):
|
||||
for long_controls_allowed in [0, 1]:
|
||||
self.safety.set_long_controls_allowed(long_controls_allowed)
|
||||
self.safety.honda_rx_hook(self._send_interceptor_msg(0, 0x201))
|
||||
self.safety.set_controls_allowed(1)
|
||||
self.safety.honda_rx_hook(self._send_interceptor_msg(0x1000, 0x201))
|
||||
if long_controls_allowed:
|
||||
self.assertFalse(self.safety.get_controls_allowed())
|
||||
else:
|
||||
self.assertTrue(self.safety.get_controls_allowed())
|
||||
self.safety.honda_rx_hook(self._send_interceptor_msg(0, 0x201))
|
||||
self.safety.set_gas_interceptor_detected(False)
|
||||
self.safety.set_long_controls_allowed(True)
|
||||
|
||||
def test_allow_engage_with_gas_interceptor_pressed(self):
|
||||
self.safety.honda_rx_hook(self._send_interceptor_msg(0x1000, 0x201))
|
||||
self.safety.set_controls_allowed(1)
|
||||
self.assertTrue(self.safety.honda_tx_hook(self._send_brake_msg(0x1000)))
|
||||
self.assertFalse(self.safety.honda_tx_hook(self._send_brake_msg(0x00F0)))
|
||||
self.safety.honda_rx_hook(self._send_interceptor_msg(0x1000, 0x201))
|
||||
self.assertTrue(self.safety.get_controls_allowed())
|
||||
self.safety.honda_rx_hook(self._send_interceptor_msg(0, 0x201))
|
||||
self.safety.set_gas_interceptor_detected(False)
|
||||
|
||||
def test_gas_safety_check(self):
|
||||
self.safety.set_controls_allowed(0)
|
||||
self.assertTrue(self.safety.honda_tx_hook(self._send_gas_msg(0x0000)))
|
||||
self.assertFalse(self.safety.honda_tx_hook(self._send_gas_msg(0x1000)))
|
||||
def test_brake_safety_check(self):
|
||||
for long_controls_allowed in [0, 1]:
|
||||
self.safety.set_long_controls_allowed(long_controls_allowed)
|
||||
for brake in np.arange(0, MAX_BRAKE + 10, 1):
|
||||
for controls_allowed in [True, False]:
|
||||
self.safety.set_controls_allowed(controls_allowed)
|
||||
if controls_allowed and long_controls_allowed:
|
||||
send = MAX_BRAKE >= brake >= 0
|
||||
else:
|
||||
send = brake == 0
|
||||
self.assertEqual(send, self.safety.honda_tx_hook(self._send_brake_msg(brake)))
|
||||
self.safety.set_long_controls_allowed(True)
|
||||
|
||||
def test_gas_interceptor_safety_check(self):
|
||||
for long_controls_allowed in [0, 1]:
|
||||
self.safety.set_long_controls_allowed(long_controls_allowed)
|
||||
for gas in np.arange(0, 4000, 100):
|
||||
for controls_allowed in [True, False]:
|
||||
self.safety.set_controls_allowed(controls_allowed)
|
||||
if controls_allowed and long_controls_allowed:
|
||||
send = True
|
||||
else:
|
||||
send = gas == 0
|
||||
self.assertEqual(send, self.safety.honda_tx_hook(self._send_interceptor_msg(gas, 0x200)))
|
||||
self.safety.set_long_controls_allowed(True)
|
||||
|
||||
def test_steer_safety_check(self):
|
||||
self.safety.set_controls_allowed(0)
|
||||
@@ -171,7 +224,7 @@ class TestHondaSafety(unittest.TestCase):
|
||||
SET_BTN = 3
|
||||
CANCEL_BTN = 2
|
||||
BUTTON_MSG = 0x296
|
||||
self.safety.set_bosch_hardware(1)
|
||||
self.safety.set_honda_bosch_hardware(1)
|
||||
self.safety.set_controls_allowed(0)
|
||||
self.assertTrue(self.safety.honda_tx_hook(self._button_msg(CANCEL_BTN, BUTTON_MSG)))
|
||||
self.assertFalse(self.safety.honda_tx_hook(self._button_msg(RESUME_BTN, BUTTON_MSG)))
|
||||
|
||||
@@ -119,13 +119,28 @@ class TestToyotaSafety(unittest.TestCase):
|
||||
to_send[0].RDLR = (a & 0xFF) << 8 | (a >> 8)
|
||||
return to_send
|
||||
|
||||
def _gas_msg(self, gas):
|
||||
def _send_gas_msg(self, gas):
|
||||
to_send = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *')
|
||||
to_send[0].RIR = 0x200 << 21
|
||||
to_send[0].RDLR = gas
|
||||
|
||||
return to_send
|
||||
|
||||
def _send_interceptor_msg(self, gas, addr):
|
||||
to_send = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *')
|
||||
to_send[0].RIR = addr << 21
|
||||
to_send[0].RDTR = 6
|
||||
to_send[0].RDLR = ((gas & 0xff) << 8) | ((gas & 0xff00) >> 8)
|
||||
|
||||
return to_send
|
||||
|
||||
def _pcm_cruise_msg(self, cruise_on, gas_pressed):
|
||||
to_send = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *')
|
||||
to_send[0].RIR = 0x1D2 << 21
|
||||
to_send[0].RDLR = (cruise_on << 5) | ((not gas_pressed) << 4 )
|
||||
|
||||
return to_send
|
||||
|
||||
def test_default_controls_not_allowed(self):
|
||||
self.assertFalse(self.safety.get_controls_allowed())
|
||||
|
||||
@@ -134,32 +149,84 @@ class TestToyotaSafety(unittest.TestCase):
|
||||
self.assertTrue(self.safety.get_controls_allowed())
|
||||
|
||||
def test_enable_control_allowed_from_cruise(self):
|
||||
to_push = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *')
|
||||
to_push[0].RIR = 0x1D2 << 21
|
||||
to_push[0].RDLR = 0x20
|
||||
|
||||
self.safety.toyota_rx_hook(to_push)
|
||||
self.safety.toyota_rx_hook(self._pcm_cruise_msg(False, False))
|
||||
self.assertFalse(self.safety.get_controls_allowed())
|
||||
self.safety.toyota_rx_hook(self._pcm_cruise_msg(True, False))
|
||||
self.assertTrue(self.safety.get_controls_allowed())
|
||||
|
||||
def test_disable_control_allowed_from_cruise(self):
|
||||
to_push = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *')
|
||||
to_push[0].RIR = 0x1D2 << 21
|
||||
to_push[0].RDLR = 0
|
||||
|
||||
self.safety.set_controls_allowed(1)
|
||||
self.safety.toyota_rx_hook(to_push)
|
||||
self.safety.toyota_rx_hook(self._pcm_cruise_msg(False, False))
|
||||
self.assertFalse(self.safety.get_controls_allowed())
|
||||
|
||||
def test_accel_actuation_limits(self):
|
||||
for accel in np.arange(MIN_ACCEL - 1000, MAX_ACCEL + 1000, 100):
|
||||
for controls_allowed in [True, False]:
|
||||
self.safety.set_controls_allowed(controls_allowed)
|
||||
def test_prev_gas(self):
|
||||
self.safety.toyota_rx_hook(self._pcm_cruise_msg(False, False))
|
||||
self.assertFalse(self.safety.get_toyota_gas_prev())
|
||||
self.safety.toyota_rx_hook(self._pcm_cruise_msg(False, True))
|
||||
self.assertTrue(self.safety.get_toyota_gas_prev())
|
||||
|
||||
if controls_allowed:
|
||||
send = MIN_ACCEL <= accel <= MAX_ACCEL
|
||||
else:
|
||||
send = accel == 0
|
||||
self.assertEqual(send, self.safety.toyota_tx_hook(self._accel_msg(accel)))
|
||||
def test_prev_gas_interceptor(self):
|
||||
self.safety.toyota_rx_hook(self._send_interceptor_msg(0x0, 0x201))
|
||||
self.assertFalse(self.safety.get_gas_interceptor_prev())
|
||||
self.safety.toyota_rx_hook(self._send_interceptor_msg(0x1000, 0x201))
|
||||
self.assertTrue(self.safety.get_gas_interceptor_prev())
|
||||
self.safety.toyota_rx_hook(self._send_interceptor_msg(0x0, 0x201))
|
||||
self.safety.set_gas_interceptor_detected(False)
|
||||
|
||||
def test_disengage_on_gas(self):
|
||||
for long_controls_allowed in [0, 1]:
|
||||
self.safety.set_long_controls_allowed(long_controls_allowed)
|
||||
self.safety.toyota_rx_hook(self._pcm_cruise_msg(False, False))
|
||||
self.safety.toyota_rx_hook(self._pcm_cruise_msg(True, False))
|
||||
self.assertTrue(self.safety.get_controls_allowed())
|
||||
self.safety.toyota_rx_hook(self._pcm_cruise_msg(True, True))
|
||||
if long_controls_allowed:
|
||||
self.assertFalse(self.safety.get_controls_allowed())
|
||||
else:
|
||||
self.assertTrue(self.safety.get_controls_allowed())
|
||||
self.safety.set_long_controls_allowed(True)
|
||||
|
||||
def test_allow_engage_with_gas_pressed(self):
|
||||
self.safety.toyota_rx_hook(self._pcm_cruise_msg(False, True))
|
||||
self.safety.toyota_rx_hook(self._pcm_cruise_msg(True, True))
|
||||
self.assertTrue(self.safety.get_controls_allowed())
|
||||
self.safety.toyota_rx_hook(self._pcm_cruise_msg(True, True))
|
||||
self.assertTrue(self.safety.get_controls_allowed())
|
||||
|
||||
def test_disengage_on_gas_interceptor(self):
|
||||
for long_controls_allowed in [0, 1]:
|
||||
self.safety.set_long_controls_allowed(long_controls_allowed)
|
||||
self.safety.toyota_rx_hook(self._send_interceptor_msg(0, 0x201))
|
||||
self.safety.set_controls_allowed(1)
|
||||
self.safety.toyota_rx_hook(self._send_interceptor_msg(0x1000, 0x201))
|
||||
if long_controls_allowed:
|
||||
self.assertFalse(self.safety.get_controls_allowed())
|
||||
else:
|
||||
self.assertTrue(self.safety.get_controls_allowed())
|
||||
self.safety.toyota_rx_hook(self._send_interceptor_msg(0, 0x201))
|
||||
self.safety.set_gas_interceptor_detected(False)
|
||||
self.safety.set_long_controls_allowed(True)
|
||||
|
||||
def test_allow_engage_with_gas_interceptor_pressed(self):
|
||||
self.safety.toyota_rx_hook(self._send_interceptor_msg(0x1000, 0x201))
|
||||
self.safety.set_controls_allowed(1)
|
||||
self.safety.toyota_rx_hook(self._send_interceptor_msg(0x1000, 0x201))
|
||||
self.assertTrue(self.safety.get_controls_allowed())
|
||||
self.safety.toyota_rx_hook(self._send_interceptor_msg(0, 0x201))
|
||||
self.safety.set_gas_interceptor_detected(False)
|
||||
|
||||
def test_accel_actuation_limits(self):
|
||||
for long_controls_allowed in [0, 1]:
|
||||
self.safety.set_long_controls_allowed(long_controls_allowed)
|
||||
for accel in np.arange(MIN_ACCEL - 1000, MAX_ACCEL + 1000, 100):
|
||||
for controls_allowed in [True, False]:
|
||||
self.safety.set_controls_allowed(controls_allowed)
|
||||
if controls_allowed and long_controls_allowed:
|
||||
send = MIN_ACCEL <= accel <= MAX_ACCEL
|
||||
else:
|
||||
send = accel == 0
|
||||
self.assertEqual(send, self.safety.toyota_tx_hook(self._accel_msg(accel)))
|
||||
self.safety.set_long_controls_allowed(True)
|
||||
|
||||
def test_torque_absolute_limits(self):
|
||||
for controls_allowed in [True, False]:
|
||||
@@ -244,11 +311,11 @@ class TestToyotaSafety(unittest.TestCase):
|
||||
self.assertEqual(51, self.safety.get_toyota_torque_meas_max())
|
||||
|
||||
self.safety.toyota_rx_hook(self._torque_meas_msg(0))
|
||||
self.assertEqual(-1, self.safety.get_toyota_torque_meas_max())
|
||||
self.assertEqual(1, self.safety.get_toyota_torque_meas_max())
|
||||
self.assertEqual(-51, self.safety.get_toyota_torque_meas_min())
|
||||
|
||||
self.safety.toyota_rx_hook(self._torque_meas_msg(0))
|
||||
self.assertEqual(-1, self.safety.get_toyota_torque_meas_max())
|
||||
self.assertEqual(1, self.safety.get_toyota_torque_meas_max())
|
||||
self.assertEqual(-1, self.safety.get_toyota_torque_meas_min())
|
||||
|
||||
def test_ipas_override(self):
|
||||
@@ -416,12 +483,13 @@ class TestToyotaSafety(unittest.TestCase):
|
||||
# reset no angle control at the end of the test
|
||||
self.safety.reset_angle_control()
|
||||
|
||||
def test_gas_safety_check(self):
|
||||
def test_gas_interceptor_safety_check(self):
|
||||
|
||||
self.safety.set_controls_allowed(0)
|
||||
self.assertTrue(self.safety.honda_tx_hook(self._gas_msg(0x0000)))
|
||||
self.assertFalse(self.safety.honda_tx_hook(self._gas_msg(0x1000)))
|
||||
self.assertTrue(self.safety.toyota_tx_hook(self._send_interceptor_msg(0, 0x200)))
|
||||
self.assertFalse(self.safety.toyota_tx_hook(self._send_interceptor_msg(0x1000, 0x200)))
|
||||
self.safety.set_controls_allowed(1)
|
||||
self.assertTrue(self.safety.honda_tx_hook(self._gas_msg(0x1000)))
|
||||
self.assertTrue(self.safety.toyota_tx_hook(self._send_interceptor_msg(0x1000, 0x200)))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
Reference in New Issue
Block a user