mirror of https://github.com/commaai/panda.git
Bounty: panda high quality CAN autobaud (#96)
* CAN auto-baud * Disable autobaud when exiting silent mode
This commit is contained in:
parent
6557cd258a
commit
95919b932d
|
@ -86,6 +86,7 @@ int can_err_cnt = 0;
|
|||
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[] = {true, true, true, false};
|
||||
#define CAN_MAX 3
|
||||
#else
|
||||
CAN_TypeDef *cans[] = {CAN1, CAN2};
|
||||
|
@ -93,10 +94,21 @@ int can_err_cnt = 0;
|
|||
uint8_t can_num_lookup[] = {1,0};
|
||||
int8_t can_forwarding[] = {-1,-1};
|
||||
uint32_t can_speed[] = {5000, 5000};
|
||||
bool can_autobaud_enabled[] = {true, true};
|
||||
#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]))
|
||||
|
||||
#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])
|
||||
|
||||
|
@ -115,43 +127,78 @@ int can_err_cnt = 0;
|
|||
// 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) {
|
||||
CAN_TypeDef *CAN = CANIF_FROM_CAN_NUM(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) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void can_init(uint8_t can_number) {
|
||||
if (can_number == 0xff) return;
|
||||
|
||||
CAN_TypeDef *CAN = CANIF_FROM_CAN_NUM(can_number);
|
||||
set_can_enable(CAN, 1);
|
||||
|
||||
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_NUM_FROM_CAN_NUM(can_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) {
|
||||
puts("CAN init FAILED!!!!!\n");
|
||||
puth(can_number); puts(" ");
|
||||
puth(BUS_NUM_FROM_CAN_NUM(can_number)); puts("\n");
|
||||
}
|
||||
can_set_speed(can_number);
|
||||
|
||||
// accept all filter
|
||||
CAN->FMR |= CAN_FMR_FINIT;
|
||||
|
@ -166,7 +213,7 @@ void can_init(uint8_t can_number) {
|
|||
CAN->FMR &= ~(CAN_FMR_FINIT);
|
||||
|
||||
// enable certain CAN interrupts
|
||||
CAN->IER = CAN_IER_TMEIE | CAN_IER_FMPIE0;
|
||||
CAN->IER |= CAN_IER_TMEIE | CAN_IER_FMPIE0;
|
||||
|
||||
switch (can_number) {
|
||||
case 0:
|
||||
|
@ -244,6 +291,8 @@ void can_set_gmlan(int bus) {
|
|||
|
||||
// CAN error
|
||||
void can_sce(CAN_TypeDef *CAN) {
|
||||
enter_critical_section();
|
||||
|
||||
can_err_cnt += 1;
|
||||
#ifdef DEBUG
|
||||
if (CAN==CAN1) puts("CAN1: ");
|
||||
|
@ -264,9 +313,19 @@ 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_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;
|
||||
|
||||
exit_critical_section();
|
||||
}
|
||||
|
||||
// ***************************** CAN *****************************
|
||||
|
@ -334,6 +393,14 @@ 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) {
|
||||
if (can_autobaud_enabled[bus_number]) {
|
||||
can_autobaud_enabled[bus_number] = false;
|
||||
puts(CAN_NAME_FROM_CANIF(CAN));
|
||||
puts(" auto-baud ");
|
||||
putui(can_speed[bus_number]);
|
||||
puts(" cbps\n");
|
||||
}
|
||||
|
||||
can_rx_cnt += 1;
|
||||
|
||||
// can is live
|
||||
|
@ -392,7 +459,7 @@ void CAN3_SCE_IRQHandler() { can_sce(CAN3); }
|
|||
#endif
|
||||
|
||||
void can_send(CAN_FIFOMailBox_TypeDef *to_push, uint8_t bus_number) {
|
||||
if (safety_tx_hook(to_push)) {
|
||||
if (safety_tx_hook(to_push) && !can_autobaud_enabled[bus_number]) {
|
||||
if (bus_number < BUS_MAX) {
|
||||
// add CAN packet to send queue
|
||||
// bus number isn't passed through
|
||||
|
|
|
@ -266,6 +266,17 @@ int puts(const char *a) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
void putui(uint32_t i) {
|
||||
char str[11];
|
||||
uint8_t idx = 10;
|
||||
str[idx--] = '\0';
|
||||
do {
|
||||
str[idx--] = (i % 10) + 0x30;
|
||||
i /= 10;
|
||||
} while (i);
|
||||
puts(str + idx + 1);
|
||||
}
|
||||
|
||||
void puth(unsigned int i) {
|
||||
int pos;
|
||||
char c[] = "0123456789abcdef";
|
||||
|
|
12
board/main.c
12
board/main.c
|
@ -281,9 +281,15 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, int hardwired) {
|
|||
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;
|
||||
}
|
||||
can_init_all();
|
||||
|
@ -303,6 +309,7 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, int hardwired) {
|
|||
// **** 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));
|
||||
}
|
||||
|
@ -552,6 +559,11 @@ int main() {
|
|||
|
||||
__enable_irq();
|
||||
|
||||
// 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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue