Skip to content

Commit

Permalink
Squashed 'panda/' changes from 0696730..ac1b64e
Browse files Browse the repository at this point in the history
ac1b64e Fix CAN Ignition for Black Panda and Uno (#526)
273e388 When initializing all the CAN busses, make sure the are also cleared (#527)
c2bea78 Fix python library on Windows (#523)
0a123b1 that too
ba6355d unused lines
c9102c0 Chrysler: use can packer in safety tests (#522)
9874e73 Abstract steering safety tests for Toyota and Chrysler (#520)
2299ecf Block 0xe5 (Honda Bosch) at the panda/uno. Only allow static values. (#515)
3517306 Subaru: fix steer torque scaling (#501)
0bc864b Make torque-based steering state global (#518)
d9355c4 Make cruise_engaged_prev a global + test case for it (#519)
2115376 Abstract sample speed test (#516)
11dc905 remove unused function
e5a586e Abstract gas interceptor tests (#517)
1dbed65 Safety Test Refactor: Honda (#495)
0632710 base class for different panda safety tests
bd98fe6 safety tests: use shorter function name
ba59ada No ESP in non-white (#514)
c333618 Fix the CAN init fix (#513)
884afa0 Safety Test Refactor: Chrysler and Volkswagen PQ (#508)
d77b72d Safety Test Refactor: Nissan (#510)
4c7755c Match Panda DFU entry fix in "make recover" process (#509)
0336f62 Pedal gas pressed safety limits (#507)
715b1a1 Hyundai-Kia-Genesis (HKG) (#503)
6f105e8 Safety Test Refactor: Subaru (#502)
57cc954 Safety Test Refactor: GM (#504)
dd01c3b Safety Test Refactor: Hyundai (#505)
592c2c8 add support to can_unique.py for Cabana CSV format. (#506)
ccf13b7 No more infinite while loops in CAN init (#499)
6c442b4 Safety Test Refactor: Volkswagen MQB (#493)
f07a6ee panda recover should go through bootstub first (#498)
8cc3a35 remove cadillac (#496)
62e4d3c Chrysler: fix missing button signal on TX (#490)
abce8f3 Safety Test Refactor: Toyota + support code (#491)
500370a Make sure relay faults make it to the health packet (#492)
bc90b60 toyota: use universal gas pressed bit (#488)
74d10cc Fixed possible race condition (#487)
a05361e cleanup safety_replay dockerfile (#486)
fe73dcc Openpilot-tools is deprecated (#484)
da8e00f1 TX message guaranteed delivery (#421)
d8f6184 Add ISO number for longitudinal limits flag comment
6a60b78 touch ups
2ce6536 comments on unsafe flags
d880134 remove from there as well
055ea07 remove that unsafe flag since it isn't implemented and it's unclear how to
4e98bbe Apply unsafe allow gas mode to all cars. (#480)
0c2c149 Fixing libusb busy error (#174)
753c42c Update Board Mac SDK Install script to work on clean mac (#146)
b9a9ea3 Unsafe gas disengage mods, fix test compile warning (#481)
08ef92d Safety model for Volkswagen PQ35/PQ46/NMS (#474)
51e0a55 Support code for unsafe mode unit tests (#478)
5325b62 current_safety_mode
7908b72 update updating unsafe mode
98503e8 disable stock honda AEB in unsafe mode (#477)
01b2ccb one more
9a30265 weak steering while not engaged
577f10b added options for unsafe mode
83cf7bf update comment
4556e74 enable unsafe mode, toggle for use by forks that so choose
de89fcd Nissan leaf (#473)

git-subtree-dir: panda
git-subtree-split: ac1b64e
  • Loading branch information
Vehicle Researcher committed May 8, 2020
1 parent a3690e4 commit 1568872
Show file tree
Hide file tree
Showing 48 changed files with 2,468 additions and 2,561 deletions.
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
- run:
name: Run safety test
command: |
docker run panda_safety /bin/bash -c "cd /panda/tests/safety; PYTHONPATH=/ ./test.sh"
docker run panda_safety /bin/bash -c "cd /openpilot/panda/tests/safety; PYTHONPATH=/openpilot ./test.sh"
misra-c2012:
machine:
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v1.7.3
v1.7.5
10 changes: 7 additions & 3 deletions board/boards/black.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,13 @@ void black_enable_can_transciever(uint8_t transciever, bool enabled) {
}

void black_enable_can_transcievers(bool enabled) {
uint8_t t1 = enabled ? 1U : 2U; // leave transciever 1 enabled to detect CAN ignition
for(uint8_t i=t1; i<=4U; i++) {
black_enable_can_transciever(i, enabled);
for(uint8_t i=1U; i<=4U; i++){
// Leave main CAN always on for CAN-based ignition detection
if((car_harness_status == HARNESS_STATUS_FLIPPED) ? (i == 3U) : (i == 1U)){
black_enable_can_transciever(i, true);
} else {
black_enable_can_transciever(i, enabled);
}
}
}

Expand Down
7 changes: 6 additions & 1 deletion board/boards/uno.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,12 @@ void uno_enable_can_transciever(uint8_t transciever, bool enabled) {

void uno_enable_can_transcievers(bool enabled) {
for(uint8_t i=1U; i<=4U; i++){
uno_enable_can_transciever(i, enabled);
// Leave main CAN always on for CAN-based ignition detection
if((car_harness_status == HARNESS_STATUS_FLIPPED) ? (i == 3U) : (i == 1U)){
uno_enable_can_transciever(i, true);
} else {
uno_enable_can_transciever(i, enabled);
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion board/build.mk
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ bin: obj/$(PROJ_NAME).bin

# this flashes everything
recover: obj/bootstub.$(PROJ_NAME).bin obj/$(PROJ_NAME).bin
-PYTHONPATH=../ python3 -c "from python import Panda; Panda().reset(enter_bootloader=True)"
-PYTHONPATH=../ python3 -c "from python import Panda; Panda().reset(enter_bootstub=True); Panda().reset(enter_bootloader=True)"
sleep 1.0
$(DFU_UTIL) -d 0483:df11 -a 0 -s 0x08004000 -D obj/$(PROJ_NAME).bin
$(DFU_UTIL) -d 0483:df11 -a 0 -s 0x08000000:leave -D obj/bootstub.$(PROJ_NAME).bin
Expand Down
67 changes: 46 additions & 21 deletions board/drivers/can.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@ extern uint32_t can_speed[4];

void can_set_forwarding(int from, int to);

void can_init(uint8_t can_number);
bool can_init(uint8_t can_number);
void can_init_all(void);
bool can_tx_check_min_slots_free(uint32_t min);
void can_send(CAN_FIFOMailBox_TypeDef *to_push, uint8_t bus_number, bool skip_tx_hook);
bool can_pop(can_ring *q, CAN_FIFOMailBox_TypeDef *elem);

Expand Down Expand Up @@ -107,6 +108,20 @@ bool can_push(can_ring *q, CAN_FIFOMailBox_TypeDef *elem) {
return ret;
}

uint32_t can_slots_empty(can_ring *q) {
uint32_t ret = 0;

ENTER_CRITICAL();
if (q->w_ptr >= q->r_ptr) {
ret = q->fifo_size - 1U - q->w_ptr + q->r_ptr;
} else {
ret = q->r_ptr - q->w_ptr - 1U;
}
EXIT_CRITICAL();

return ret;
}

void can_clear(can_ring *q) {
ENTER_CRITICAL();
q->w_ptr = 0;
Expand All @@ -133,27 +148,27 @@ uint32_t can_speed[] = {5000, 5000, 5000, 333};

#define CANIF_FROM_CAN_NUM(num) (cans[num])
#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"))
#define BUS_NUM_FROM_CAN_NUM(num) (bus_lookup[num])
#define CAN_NUM_FROM_BUS_NUM(num) (can_num_lookup[num])

void process_can(uint8_t can_number);

void can_set_speed(uint8_t can_number) {
bool can_set_speed(uint8_t can_number) {
bool ret = true;
CAN_TypeDef *CAN = CANIF_FROM_CAN_NUM(can_number);
uint8_t bus_number = BUS_NUM_FROM_CAN_NUM(can_number);

if (!llcan_set_speed(CAN, can_speed[bus_number], can_loopback, (unsigned int)(can_silent) & (1U << can_number))) {
puts("CAN init FAILED!!!!!\n");
puth(can_number); puts(" ");
puth(BUS_NUM_FROM_CAN_NUM(can_number)); puts("\n");
}
ret &= llcan_set_speed(CAN, can_speed[bus_number], can_loopback, (unsigned int)(can_silent) & (1U << can_number));
return ret;
}

void can_init_all(void) {
bool ret = true;
for (uint8_t i=0U; i < CAN_MAX; i++) {
can_init(i);
can_clear(can_queues[i]);
ret &= can_init(i);
}
UNUSED(ret);
}

void can_flip_buses(uint8_t bus1, uint8_t bus2){
Expand All @@ -179,7 +194,8 @@ void can_set_gmlan(uint8_t bus) {
bus_lookup[prev_bus] = prev_bus;
can_num_lookup[prev_bus] = prev_bus;
can_num_lookup[3] = -1;
can_init(prev_bus);
bool ret = can_init(prev_bus);
UNUSED(ret);
break;
default:
// GMLAN was not set on either BUS 1 or 2
Expand All @@ -198,7 +214,8 @@ void can_set_gmlan(uint8_t bus) {
bus_lookup[bus] = 3;
can_num_lookup[bus] = -1;
can_num_lookup[3] = bus;
can_init(bus);
bool ret = can_init(bus);
UNUSED(ret);
break;
case 0xFF: //-1 unsigned
break;
Expand Down Expand Up @@ -317,6 +334,10 @@ void process_can(uint8_t can_number) {
CAN->sTxMailBox[0].TDHR = to_send.RDHR;
CAN->sTxMailBox[0].TDTR = to_send.RDTR;
CAN->sTxMailBox[0].TIR = to_send.RIR;

if (can_tx_check_min_slots_free(MAX_CAN_MSGS_PER_BULK_TRANSFER)) {
usb_outep3_resume_if_paused();
}
}
}

Expand All @@ -342,11 +363,6 @@ void ignition_can_hook(CAN_FIFOMailBox_TypeDef *to_push) {
// GTW_status
ignition_can = (GET_BYTE(to_push, 0) & 0x1) != 0;
}
// Cadillac exception
if ((addr == 0x160) && (len == 5)) {
// this message isn't all zeros when ignition is on
ignition_can = GET_BYTES_04(to_push) != 0;
}
}
}

Expand Down Expand Up @@ -405,6 +421,14 @@ void CAN3_TX_IRQ_Handler(void) { process_can(2); }
void CAN3_RX0_IRQ_Handler(void) { can_rx(2); }
void CAN3_SCE_IRQ_Handler(void) { can_sce(CAN3); }

bool can_tx_check_min_slots_free(uint32_t min) {
return
(can_slots_empty(&can_tx1_q) >= min) &&
(can_slots_empty(&can_tx2_q) >= min) &&
(can_slots_empty(&can_tx3_q) >= min) &&
(can_slots_empty(&can_txgmlan_q) >= min);
}

void can_send(CAN_FIFOMailBox_TypeDef *to_push, uint8_t bus_number, bool skip_tx_hook) {
if (skip_tx_hook || safety_tx_hook(to_push) != 0) {
if (bus_number < BUS_MAX) {
Expand All @@ -425,7 +449,9 @@ void can_set_forwarding(int from, int to) {
can_forwarding[from] = to;
}

void can_init(uint8_t can_number) {
bool can_init(uint8_t can_number) {
bool ret = false;

REGISTER_INTERRUPT(CAN1_TX_IRQn, CAN1_TX_IRQ_Handler, CAN_INTERRUPT_RATE, FAULT_INTERRUPT_RATE_CAN_1)
REGISTER_INTERRUPT(CAN1_RX0_IRQn, CAN1_RX0_IRQ_Handler, CAN_INTERRUPT_RATE, FAULT_INTERRUPT_RATE_CAN_1)
REGISTER_INTERRUPT(CAN1_SCE_IRQn, CAN1_SCE_IRQ_Handler, CAN_INTERRUPT_RATE, FAULT_INTERRUPT_RATE_CAN_1)
Expand All @@ -438,12 +464,11 @@ void can_init(uint8_t can_number) {

if (can_number != 0xffU) {
CAN_TypeDef *CAN = CANIF_FROM_CAN_NUM(can_number);
can_set_speed(can_number);

llcan_init(CAN);

ret &= can_set_speed(can_number);
ret &= llcan_init(CAN);
// in case there are queued up messages
process_can(can_number);
}
return ret;
}

151 changes: 95 additions & 56 deletions board/drivers/llcan.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,82 +11,121 @@
#define GET_BUS(msg) (((msg)->RDTR >> 4) & 0xFF)
#define GET_LEN(msg) ((msg)->RDTR & 0xF)
#define GET_ADDR(msg) ((((msg)->RIR & 4) != 0) ? ((msg)->RIR >> 3) : ((msg)->RIR >> 21))
#define GET_BYTE(msg, b) (((int)(b) > 3) ? (((msg)->RDHR >> (8U * ((unsigned int)(b) % 4U))) & 0XFFU) : (((msg)->RDLR >> (8U * (unsigned int)(b))) & 0xFFU))
#define GET_BYTE(msg, b) (((int)(b) > 3) ? (((msg)->RDHR >> (8U * ((unsigned int)(b) % 4U))) & 0xFFU) : (((msg)->RDLR >> (8U * (unsigned int)(b))) & 0xFFU))
#define GET_BYTES_04(msg) ((msg)->RDLR)
#define GET_BYTES_48(msg) ((msg)->RDHR)

#define CAN_INIT_TIMEOUT_MS 500U
#define CAN_NAME_FROM_CANIF(CAN_DEV) (((CAN_DEV)==CAN1) ? "CAN1" : (((CAN_DEV) == CAN2) ? "CAN2" : "CAN3"))

void puts(const char *a);

bool llcan_set_speed(CAN_TypeDef *CAN_obj, uint32_t speed, bool loopback, bool silent) {
bool ret = true;

// initialization mode
register_set(&(CAN_obj->MCR), CAN_MCR_TTCM | CAN_MCR_INRQ, 0x180FFU);
while((CAN_obj->MSR & CAN_MSR_INAK) != CAN_MSR_INAK);

// set time quanta from defines
register_set(&(CAN_obj->BTR), ((CAN_BTR_TS1_0 * (CAN_SEQ1-1)) |
(CAN_BTR_TS2_0 * (CAN_SEQ2-1)) |
(can_speed_to_prescaler(speed) - 1U)), 0xC37F03FFU);

// silent loopback mode for debugging
if (loopback) {
register_set_bits(&(CAN_obj->BTR), CAN_BTR_SILM | CAN_BTR_LBKM);
}
if (silent) {
register_set_bits(&(CAN_obj->BTR), CAN_BTR_SILM);
uint32_t timeout_counter = 0U;
while((CAN_obj->MSR & CAN_MSR_INAK) != CAN_MSR_INAK){
// Delay for about 1ms
delay(10000);
timeout_counter++;

if(timeout_counter >= CAN_INIT_TIMEOUT_MS){
puts(CAN_NAME_FROM_CANIF(CAN_obj)); puts(" set_speed timed out (1)!\n");
ret = false;
break;
}
}

// reset
register_set(&(CAN_obj->MCR), CAN_MCR_TTCM | CAN_MCR_ABOM, 0x180FFU);

#define CAN_TIMEOUT 1000000
int tmp = 0;
bool ret = false;
while(((CAN_obj->MSR & CAN_MSR_INAK) == CAN_MSR_INAK) && (tmp < CAN_TIMEOUT)) tmp++;
if (tmp < CAN_TIMEOUT) {
ret = true;
if(ret){
// set time quanta from defines
register_set(&(CAN_obj->BTR), ((CAN_BTR_TS1_0 * (CAN_SEQ1-1)) |
(CAN_BTR_TS2_0 * (CAN_SEQ2-1)) |
(can_speed_to_prescaler(speed) - 1U)), 0xC37F03FFU);

// silent loopback mode for debugging
if (loopback) {
register_set_bits(&(CAN_obj->BTR), CAN_BTR_SILM | CAN_BTR_LBKM);
}
if (silent) {
register_set_bits(&(CAN_obj->BTR), CAN_BTR_SILM);
}

// reset
register_set(&(CAN_obj->MCR), CAN_MCR_TTCM | CAN_MCR_ABOM, 0x180FFU);

timeout_counter = 0U;
while(((CAN_obj->MSR & CAN_MSR_INAK) == CAN_MSR_INAK)) {
// Delay for about 1ms
delay(10000);
timeout_counter++;

if(timeout_counter >= CAN_INIT_TIMEOUT_MS){
puts(CAN_NAME_FROM_CANIF(CAN_obj)); puts(" set_speed timed out (2)!\n");
ret = false;
break;
}
}
}

return ret;
}

void llcan_init(CAN_TypeDef *CAN_obj) {
bool llcan_init(CAN_TypeDef *CAN_obj) {
bool ret = true;

// Enter init mode
register_set_bits(&(CAN_obj->FMR), CAN_FMR_FINIT);

// Wait for INAK bit to be set
while(((CAN_obj->MSR & CAN_MSR_INAK) == CAN_MSR_INAK)) {}

// no mask
// For some weird reason some of these registers do not want to set properly on CAN2 and CAN3. Probably something to do with the single/dual mode and their different filters.
CAN_obj->sFilterRegister[0].FR1 = 0U;
CAN_obj->sFilterRegister[0].FR2 = 0U;
CAN_obj->sFilterRegister[14].FR1 = 0U;
CAN_obj->sFilterRegister[14].FR2 = 0U;
CAN_obj->FA1R |= 1U | (1U << 14);

// Exit init mode, do not wait
register_clear_bits(&(CAN_obj->FMR), CAN_FMR_FINIT);

// enable certain CAN interrupts
register_set_bits(&(CAN_obj->IER), CAN_IER_TMEIE | CAN_IER_FMPIE0 | CAN_IER_WKUIE);

if (CAN_obj == CAN1) {
NVIC_EnableIRQ(CAN1_TX_IRQn);
NVIC_EnableIRQ(CAN1_RX0_IRQn);
NVIC_EnableIRQ(CAN1_SCE_IRQn);
} else if (CAN_obj == CAN2) {
NVIC_EnableIRQ(CAN2_TX_IRQn);
NVIC_EnableIRQ(CAN2_RX0_IRQn);
NVIC_EnableIRQ(CAN2_SCE_IRQn);
#ifdef CAN3
} else if (CAN_obj == CAN3) {
NVIC_EnableIRQ(CAN3_TX_IRQn);
NVIC_EnableIRQ(CAN3_RX0_IRQn);
NVIC_EnableIRQ(CAN3_SCE_IRQn);
#endif
} else {
puts("Invalid CAN: initialization failed\n");
uint32_t timeout_counter = 0U;
while(((CAN_obj->MSR & CAN_MSR_INAK) == CAN_MSR_INAK)) {
// Delay for about 1ms
delay(10000);
timeout_counter++;

if(timeout_counter >= CAN_INIT_TIMEOUT_MS){
puts(CAN_NAME_FROM_CANIF(CAN_obj)); puts(" initialization timed out!\n");
ret = false;
break;
}
}

if(ret){
// no mask
// For some weird reason some of these registers do not want to set properly on CAN2 and CAN3. Probably something to do with the single/dual mode and their different filters.
CAN_obj->sFilterRegister[0].FR1 = 0U;
CAN_obj->sFilterRegister[0].FR2 = 0U;
CAN_obj->sFilterRegister[14].FR1 = 0U;
CAN_obj->sFilterRegister[14].FR2 = 0U;
CAN_obj->FA1R |= 1U | (1U << 14);

// Exit init mode, do not wait
register_clear_bits(&(CAN_obj->FMR), CAN_FMR_FINIT);

// enable certain CAN interrupts
register_set_bits(&(CAN_obj->IER), CAN_IER_TMEIE | CAN_IER_FMPIE0 | CAN_IER_WKUIE);

if (CAN_obj == CAN1) {
NVIC_EnableIRQ(CAN1_TX_IRQn);
NVIC_EnableIRQ(CAN1_RX0_IRQn);
NVIC_EnableIRQ(CAN1_SCE_IRQn);
} else if (CAN_obj == CAN2) {
NVIC_EnableIRQ(CAN2_TX_IRQn);
NVIC_EnableIRQ(CAN2_RX0_IRQn);
NVIC_EnableIRQ(CAN2_SCE_IRQn);
#ifdef CAN3
} else if (CAN_obj == CAN3) {
NVIC_EnableIRQ(CAN3_TX_IRQn);
NVIC_EnableIRQ(CAN3_RX0_IRQn);
NVIC_EnableIRQ(CAN3_SCE_IRQn);
#endif
} else {
puts("Invalid CAN: initialization failed\n");
}
}
return ret;
}

void llcan_clear_send(CAN_TypeDef *CAN_obj) {
Expand Down
Loading

0 comments on commit 1568872

Please sign in to comment.