mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-07-02 20:12:07 +08:00
38faf7f8a4
30c7ca8a5 bump version to 1.5.3 9403dbebe Need to fix wifi test before re-enabling. 0812362b5 GPS UART fix until boardd is refactored (#294) ffbdb87a8 python2 -> 3 fixes to pedal flasher (#292) 78b75ef59 Added build type to release version strings 736c2cbf7 Fixed sending of bytes over PandaSerial 0894b28f1 Fixed USB power mode on black (#291) 4b3358c92 patch to be able to switch from EON to PC with a Panda that has EON b… (#290) a95c44a71 Made setting of NOOUTPUT on no heartbeat more efficient (#287) 948683688 UART instability fix with high interrupt load (#283) 9a9e9d47b Fix usb_power_mode missing initialization (#289) af0960ad3 DFU fix (#288) 70219d7bb match safety enum in cereal (#285) a338d3932 Fix build for jenkins test 78ef4a6eb Stop charge (#284) 5266a4028 Fix typo (#286) f4787ec5a Revert "turn on CDP when ignition switches on (#281)" d37daee97 Revert "NONE and CLIENT should be the same thing in white/grey pandas" e97b283e7 NONE and CLIENT should be the same thing in white/grey pandas 8c1df559f turn on CDP when ignition switches on (#281) 847a35d42 Fix bullet points fac027716 Misra update (#280) 5a04df6b1 Added description of regression tests to README c4aabae59 Fixed some python3 bugs in the test scripts and PandaSerial 9af0cb353 Bump version c4ac3d63b Disable GPS load switching on black pandas 078ee588c This is the correct table, actually 578b95ee3 Misra table of coverage added d383a2625 bump panda b98ca010d fix sdk build in python3 env (#279) 63d3dc7d3 Set python3 env before runnign get_sdk, so we know if it fails e951d79c0 legacy code we don't control can remain python2 11b715118 Merge pull request #276 from commaai/python3 9893a842a Merge pull request #277 from zorrobyte/patch-1 d3268690c Revert "revert back esptool to python2 and force to build esptools with python2" 875e76012 revert back esptool to python2 and force to build esptools with python2 9c40e6240 needed to install python3 ed2ac87cf Also moved safety tests to python3 6842b2d2c move esptool sdk installation before python3 env is set. Kind of a cheat b5a2cabcd this hopefully fixes build test 628050955 Fixes safety replay 2c220b623 this fixes language regr test fdbe789b8 use python 3 in Docker container ee1ae4f86 Better hash print 0de9ef73c Revert "Final 2to3 on the whole repo" c92fd3bc9 Final 2to3 on the whole repo 5f2bc4460 better b2a30fdbd make works! b74005d10 fix sign.py fe727706b read file as byte and no tab before sleep 32a344ef6 Update README.md 2dc34096a 2to3 applied ffa68ef71 undo unnecessary brackets for print dbc248027 Fix all the prints with 2to3, some need to be undo 5a7aeba0f xrange is gone 982c4c928 one more python3 env 1e2412a29 env python -> env python3 git-subtree-dir: panda git-subtree-split: 30c7ca8a53a3adb05d23d7cfe64fb716a656ef1a
409 lines
11 KiB
C
409 lines
11 KiB
C
// IRQs: CAN1_TX, CAN1_RX0, CAN1_SCE
|
|
// CAN2_TX, CAN2_RX0, CAN2_SCE
|
|
// CAN3_TX, CAN3_RX0, CAN3_SCE
|
|
|
|
typedef struct {
|
|
volatile uint32_t w_ptr;
|
|
volatile uint32_t r_ptr;
|
|
uint32_t fifo_size;
|
|
CAN_FIFOMailBox_TypeDef *elems;
|
|
} can_ring;
|
|
|
|
#define CAN_BUS_RET_FLAG 0x80U
|
|
#define CAN_BUS_NUM_MASK 0x7FU
|
|
|
|
#define BUS_MAX 4U
|
|
|
|
uint32_t can_send_errs = 0;
|
|
uint32_t can_fwd_errs = 0;
|
|
uint32_t gmlan_send_errs = 0;
|
|
extern int can_live, pending_can_live;
|
|
|
|
// must reinit after changing these
|
|
extern int can_loopback, can_silent;
|
|
extern uint32_t can_speed[4];
|
|
|
|
void can_set_forwarding(int from, int to);
|
|
|
|
void can_init(uint8_t can_number);
|
|
void can_init_all(void);
|
|
void can_send(CAN_FIFOMailBox_TypeDef *to_push, uint8_t bus_number);
|
|
bool can_pop(can_ring *q, CAN_FIFOMailBox_TypeDef *elem);
|
|
|
|
// end API
|
|
|
|
#define ALL_CAN_SILENT 0xFF
|
|
#define ALL_CAN_LIVE 0
|
|
|
|
int can_live = 0, pending_can_live = 0, can_loopback = 0, can_silent = ALL_CAN_SILENT;
|
|
|
|
// ********************* instantiate queues *********************
|
|
|
|
#define can_buffer(x, size) \
|
|
CAN_FIFOMailBox_TypeDef elems_##x[size]; \
|
|
can_ring can_##x = { .w_ptr = 0, .r_ptr = 0, .fifo_size = size, .elems = (CAN_FIFOMailBox_TypeDef *)&elems_##x };
|
|
|
|
can_buffer(rx_q, 0x1000)
|
|
can_buffer(tx1_q, 0x100)
|
|
can_buffer(tx2_q, 0x100)
|
|
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};
|
|
|
|
// global CAN stats
|
|
int can_rx_cnt = 0;
|
|
int can_tx_cnt = 0;
|
|
int can_txd_cnt = 0;
|
|
int can_err_cnt = 0;
|
|
int can_overflow_cnt = 0;
|
|
|
|
// ********************* interrupt safe queue *********************
|
|
|
|
bool can_pop(can_ring *q, CAN_FIFOMailBox_TypeDef *elem) {
|
|
bool ret = 0;
|
|
|
|
ENTER_CRITICAL();
|
|
if (q->w_ptr != q->r_ptr) {
|
|
*elem = q->elems[q->r_ptr];
|
|
if ((q->r_ptr + 1U) == q->fifo_size) {
|
|
q->r_ptr = 0;
|
|
} else {
|
|
q->r_ptr += 1U;
|
|
}
|
|
ret = 1;
|
|
}
|
|
EXIT_CRITICAL();
|
|
|
|
return ret;
|
|
}
|
|
|
|
bool can_push(can_ring *q, CAN_FIFOMailBox_TypeDef *elem) {
|
|
bool ret = false;
|
|
uint32_t next_w_ptr;
|
|
|
|
ENTER_CRITICAL();
|
|
if ((q->w_ptr + 1U) == q->fifo_size) {
|
|
next_w_ptr = 0;
|
|
} else {
|
|
next_w_ptr = q->w_ptr + 1U;
|
|
}
|
|
if (next_w_ptr != q->r_ptr) {
|
|
q->elems[q->w_ptr] = *elem;
|
|
q->w_ptr = next_w_ptr;
|
|
ret = true;
|
|
}
|
|
EXIT_CRITICAL();
|
|
if (!ret) {
|
|
can_overflow_cnt++;
|
|
#ifdef DEBUG
|
|
puts("can_push failed!\n");
|
|
#endif
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
void can_clear(can_ring *q) {
|
|
ENTER_CRITICAL();
|
|
q->w_ptr = 0;
|
|
q->r_ptr = 0;
|
|
EXIT_CRITICAL();
|
|
}
|
|
|
|
// assign CAN numbering
|
|
// bus num: Can bus number on ODB connector. Sent to/from USB
|
|
// Min: 0; Max: 127; Bit 7 marks message as receipt (bus 129 is receipt for but 1)
|
|
// cans: Look up MCU can interface from bus number
|
|
// can number: numeric lookup for MCU CAN interfaces (0 = CAN1, 1 = CAN2, etc);
|
|
// bus_lookup: Translates from 'can number' to 'bus number'.
|
|
// can_num_lookup: Translates from 'bus number' to 'can number'.
|
|
// can_forwarding: Given a bus num, lookup bus num to forward to. -1 means no forward.
|
|
|
|
// Panda: Bus 0=CAN1 Bus 1=CAN2 Bus 2=CAN3
|
|
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 3U
|
|
|
|
#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) {
|
|
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");
|
|
}
|
|
}
|
|
|
|
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);
|
|
|
|
// in case there are queued up messages
|
|
process_can(can_number);
|
|
}
|
|
}
|
|
|
|
void can_init_all(void) {
|
|
for (uint8_t i=0U; i < CAN_MAX; i++) {
|
|
can_init(i);
|
|
}
|
|
current_board->enable_can_transcievers(true);
|
|
}
|
|
|
|
void can_flip_buses(uint8_t bus1, uint8_t bus2){
|
|
bus_lookup[bus1] = bus2;
|
|
bus_lookup[bus2] = bus1;
|
|
can_num_lookup[bus1] = bus2;
|
|
can_num_lookup[bus2] = bus1;
|
|
}
|
|
|
|
// TODO: Cleanup with new abstraction
|
|
void can_set_gmlan(uint8_t bus) {
|
|
if(hw_type != HW_TYPE_BLACK_PANDA){
|
|
// first, disable GMLAN on prev bus
|
|
uint8_t prev_bus = can_num_lookup[3];
|
|
if (bus != prev_bus) {
|
|
switch (prev_bus) {
|
|
case 1:
|
|
case 2:
|
|
puts("Disable GMLAN on CAN");
|
|
puth(prev_bus + 1U);
|
|
puts("\n");
|
|
current_board->set_can_mode(CAN_MODE_NORMAL);
|
|
bus_lookup[prev_bus] = prev_bus;
|
|
can_num_lookup[prev_bus] = prev_bus;
|
|
can_num_lookup[3] = -1;
|
|
can_init(prev_bus);
|
|
break;
|
|
default:
|
|
// GMLAN was not set on either BUS 1 or 2
|
|
break;
|
|
}
|
|
}
|
|
|
|
// now enable GMLAN on the new bus
|
|
switch (bus) {
|
|
case 1:
|
|
case 2:
|
|
puts("Enable GMLAN on CAN");
|
|
puth(bus + 1U);
|
|
puts("\n");
|
|
current_board->set_can_mode((bus == 1U) ? CAN_MODE_GMLAN_CAN2 : CAN_MODE_GMLAN_CAN3);
|
|
bus_lookup[bus] = 3;
|
|
can_num_lookup[bus] = -1;
|
|
can_num_lookup[3] = bus;
|
|
can_init(bus);
|
|
break;
|
|
case 0xFF: //-1 unsigned
|
|
break;
|
|
default:
|
|
puts("GMLAN can only be set on CAN2 or CAN3\n");
|
|
break;
|
|
}
|
|
} else {
|
|
puts("GMLAN not available on black panda\n");
|
|
}
|
|
}
|
|
|
|
// TODO: remove
|
|
void can_set_obd(uint8_t harness_orientation, bool obd){
|
|
if(obd){
|
|
puts("setting CAN2 to be OBD\n");
|
|
} else {
|
|
puts("setting CAN2 to be normal\n");
|
|
}
|
|
if(hw_type == HW_TYPE_BLACK_PANDA){
|
|
if(obd != (bool)(harness_orientation == HARNESS_STATUS_NORMAL)){
|
|
// B5,B6: disable normal mode
|
|
set_gpio_mode(GPIOB, 5, MODE_INPUT);
|
|
set_gpio_mode(GPIOB, 6, MODE_INPUT);
|
|
// B12,B13: CAN2 mode
|
|
set_gpio_alternate(GPIOB, 12, GPIO_AF9_CAN2);
|
|
set_gpio_alternate(GPIOB, 13, GPIO_AF9_CAN2);
|
|
} else {
|
|
// B5,B6: CAN2 mode
|
|
set_gpio_alternate(GPIOB, 5, GPIO_AF9_CAN2);
|
|
set_gpio_alternate(GPIOB, 6, GPIO_AF9_CAN2);
|
|
// B12,B13: disable normal mode
|
|
set_gpio_mode(GPIOB, 12, MODE_INPUT);
|
|
set_gpio_mode(GPIOB, 13, MODE_INPUT);
|
|
}
|
|
} else {
|
|
puts("OBD CAN not available on non-black panda\n");
|
|
}
|
|
}
|
|
|
|
// CAN error
|
|
void can_sce(CAN_TypeDef *CAN) {
|
|
ENTER_CRITICAL();
|
|
|
|
#ifdef DEBUG
|
|
if (CAN==CAN1) puts("CAN1: ");
|
|
if (CAN==CAN2) puts("CAN2: ");
|
|
#ifdef CAN3
|
|
if (CAN==CAN3) puts("CAN3: ");
|
|
#endif
|
|
puts("MSR:");
|
|
puth(CAN->MSR);
|
|
puts(" TSR:");
|
|
puth(CAN->TSR);
|
|
puts(" RF0R:");
|
|
puth(CAN->RF0R);
|
|
puts(" RF1R:");
|
|
puth(CAN->RF1R);
|
|
puts(" ESR:");
|
|
puth(CAN->ESR);
|
|
puts("\n");
|
|
#endif
|
|
|
|
can_err_cnt += 1;
|
|
llcan_clear_send(CAN);
|
|
EXIT_CRITICAL();
|
|
}
|
|
|
|
// ***************************** CAN *****************************
|
|
|
|
void process_can(uint8_t can_number) {
|
|
if (can_number != 0xffU) {
|
|
|
|
ENTER_CRITICAL();
|
|
|
|
CAN_TypeDef *CAN = CANIF_FROM_CAN_NUM(can_number);
|
|
uint8_t bus_number = BUS_NUM_FROM_CAN_NUM(can_number);
|
|
|
|
// check for empty mailbox
|
|
CAN_FIFOMailBox_TypeDef to_send;
|
|
if ((CAN->TSR & CAN_TSR_TME0) == CAN_TSR_TME0) {
|
|
// add successfully transmitted message to my fifo
|
|
if ((CAN->TSR & CAN_TSR_RQCP0) == CAN_TSR_RQCP0) {
|
|
can_txd_cnt += 1;
|
|
|
|
if ((CAN->TSR & CAN_TSR_TXOK0) == CAN_TSR_TXOK0) {
|
|
CAN_FIFOMailBox_TypeDef to_push;
|
|
to_push.RIR = CAN->sTxMailBox[0].TIR;
|
|
to_push.RDTR = (CAN->sTxMailBox[0].TDTR & 0xFFFF000FU) | ((CAN_BUS_RET_FLAG | bus_number) << 4);
|
|
to_push.RDLR = CAN->sTxMailBox[0].TDLR;
|
|
to_push.RDHR = CAN->sTxMailBox[0].TDHR;
|
|
can_send_errs += can_push(&can_rx_q, &to_push) ? 0U : 1U;
|
|
}
|
|
|
|
if ((CAN->TSR & CAN_TSR_TERR0) == CAN_TSR_TERR0) {
|
|
#ifdef DEBUG
|
|
puts("CAN TX ERROR!\n");
|
|
#endif
|
|
}
|
|
|
|
if ((CAN->TSR & CAN_TSR_ALST0) == CAN_TSR_ALST0) {
|
|
#ifdef DEBUG
|
|
puts("CAN TX ARBITRATION LOST!\n");
|
|
#endif
|
|
}
|
|
|
|
// clear interrupt
|
|
// careful, this can also be cleared by requesting a transmission
|
|
CAN->TSR |= CAN_TSR_RQCP0;
|
|
}
|
|
|
|
if (can_pop(can_queues[bus_number], &to_send)) {
|
|
can_tx_cnt += 1;
|
|
// only send if we have received a packet
|
|
CAN->sTxMailBox[0].TDLR = to_send.RDLR;
|
|
CAN->sTxMailBox[0].TDHR = to_send.RDHR;
|
|
CAN->sTxMailBox[0].TDTR = to_send.RDTR;
|
|
CAN->sTxMailBox[0].TIR = to_send.RIR;
|
|
}
|
|
}
|
|
|
|
EXIT_CRITICAL();
|
|
}
|
|
}
|
|
|
|
// CAN receive handlers
|
|
// blink blue when we are receiving CAN messages
|
|
void can_rx(uint8_t can_number) {
|
|
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) != 0) {
|
|
can_rx_cnt += 1;
|
|
|
|
// can is live
|
|
pending_can_live = 1;
|
|
|
|
// add to my fifo
|
|
CAN_FIFOMailBox_TypeDef to_push;
|
|
to_push.RIR = CAN->sFIFOMailBox[0].RIR;
|
|
to_push.RDTR = CAN->sFIFOMailBox[0].RDTR;
|
|
to_push.RDLR = CAN->sFIFOMailBox[0].RDLR;
|
|
to_push.RDHR = CAN->sFIFOMailBox[0].RDHR;
|
|
|
|
// modify RDTR for our API
|
|
to_push.RDTR = (to_push.RDTR & 0xFFFF000F) | (bus_number << 4);
|
|
|
|
// forwarding (panda only)
|
|
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);
|
|
|
|
current_board->set_led(LED_BLUE, true);
|
|
can_send_errs += can_push(&can_rx_q, &to_push) ? 0U : 1U;
|
|
|
|
// next
|
|
CAN->RF0R |= CAN_RF0R_RFOM0;
|
|
}
|
|
}
|
|
|
|
void CAN1_TX_IRQHandler(void) { process_can(0); }
|
|
void CAN1_RX0_IRQHandler(void) { can_rx(0); }
|
|
void CAN1_SCE_IRQHandler(void) { can_sce(CAN1); }
|
|
|
|
void CAN2_TX_IRQHandler(void) { process_can(1); }
|
|
void CAN2_RX0_IRQHandler(void) { can_rx(1); }
|
|
void CAN2_SCE_IRQHandler(void) { can_sce(CAN2); }
|
|
|
|
void CAN3_TX_IRQHandler(void) { process_can(2); }
|
|
void CAN3_RX0_IRQHandler(void) { can_rx(2); }
|
|
void CAN3_SCE_IRQHandler(void) { can_sce(CAN3); }
|
|
|
|
void can_send(CAN_FIFOMailBox_TypeDef *to_push, uint8_t bus_number) {
|
|
if (safety_tx_hook(to_push) != 0) {
|
|
if (bus_number < BUS_MAX) {
|
|
// add CAN packet to send queue
|
|
// bus number isn't passed through
|
|
to_push->RDTR &= 0xF;
|
|
if ((bus_number == 3U) && (can_num_lookup[3] == 0xFFU)) {
|
|
gmlan_send_errs += bitbang_gmlan(to_push) ? 0U : 1U;
|
|
} else {
|
|
can_fwd_errs += can_push(can_queues[bus_number], to_push) ? 0U : 1U;
|
|
process_can(CAN_NUM_FROM_BUS_NUM(bus_number));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void can_set_forwarding(int from, int to) {
|
|
can_forwarding[from] = to;
|
|
}
|
|
|