diff --git a/board/drivers/gmlan_alt.h b/board/drivers/gmlan_alt.h index 45378747d..1c20e1ed7 100644 --- a/board/drivers/gmlan_alt.h +++ b/board/drivers/gmlan_alt.h @@ -121,23 +121,23 @@ int get_bit_message(char *out, CANPacket_t *to_bang) { return len; } -void TIM12_IRQ_Handler(void); +void GMLAN_BITBANG_IRQ_Handler(void); void setup_timer(void) { // register interrupt - REGISTER_INTERRUPT(TIM8_BRK_TIM12_IRQn, TIM12_IRQ_Handler, 40000U, FAULT_INTERRUPT_RATE_GMLAN) + REGISTER_INTERRUPT(GMLAN_BITBANG_TIMER_IRQ, GMLAN_BITBANG_IRQ_Handler, 40000U, FAULT_INTERRUPT_RATE_GMLAN) // setup - register_set(&(TIM12->PSC), (APB1_TIMER_FREQ-1U), 0xFFFFU); // Tick on 1 us - register_set(&(TIM12->CR1), TIM_CR1_CEN, 0x3FU); // Enable - register_set(&(TIM12->ARR), (30U-1U), 0xFFFFU); // 33.3 kbps + register_set(&(GMLAN_BITBANG_TIMER->PSC), (APB1_TIMER_FREQ-1U), 0xFFFFU); // Tick on 1 us + register_set(&(GMLAN_BITBANG_TIMER->CR1), TIM_CR1_CEN, 0x3FU); // Enable + register_set(&(GMLAN_BITBANG_TIMER->ARR), (30U-1U), 0xFFFFU); // 33.3 kbps // in case it's disabled - NVIC_EnableIRQ(TIM8_BRK_TIM12_IRQn); + NVIC_EnableIRQ(GMLAN_BITBANG_TIMER_IRQ); // run the interrupt - register_set(&(TIM12->DIER), TIM_DIER_UIE, 0x5F5FU); // Update interrupt - TIM12->SR = 0; + register_set(&(GMLAN_BITBANG_TIMER->DIER), TIM_DIER_UIE, 0x5F5FU); // Update interrupt + GMLAN_BITBANG_TIMER->SR = 0; } int gmlan_timeout_counter = GMLAN_TICKS_PER_TIMEOUT_TICKLE; //GMLAN transceiver times out every 17ms held high; tickle every 15ms @@ -191,9 +191,9 @@ int gmlan_fail_count = 0; #define REQUIRED_SILENT_TIME 10 #define MAX_FAIL_COUNT 10 -void TIM12_IRQ_Handler(void) { +void GMLAN_BITBANG_IRQ_Handler(void) { if (gmlan_alt_mode == BITBANG) { - if ((TIM12->SR & TIM_SR_UIF) && (gmlan_sendmax != -1)) { + if ((GMLAN_BITBANG_TIMER->SR & TIM_SR_UIF) && (gmlan_sendmax != -1)) { int read = get_gpio_input(GPIOB, 12); if (gmlan_silent_count < REQUIRED_SILENT_TIME) { if (read == 0) { @@ -235,13 +235,13 @@ void TIM12_IRQ_Handler(void) { if ((gmlan_sending == gmlan_sendmax) || (gmlan_fail_count == MAX_FAIL_COUNT)) { set_bitbanged_gmlan(1); // recessive set_gpio_mode(GPIOB, 13, MODE_INPUT); - register_clear_bits(&(TIM12->DIER), TIM_DIER_UIE); // No update interrupt - register_set(&(TIM12->CR1), 0U, 0x3FU); // Disable timer + register_clear_bits(&(GMLAN_BITBANG_TIMER->DIER), TIM_DIER_UIE); // No update interrupt + register_set(&(GMLAN_BITBANG_TIMER->CR1), 0U, 0x3FU); // Disable timer gmlan_sendmax = -1; // exit } } } else if (gmlan_alt_mode == GPIO_SWITCH) { - if ((TIM12->SR & TIM_SR_UIF) && (gmlan_switch_below_timeout != -1)) { + if ((GMLAN_BITBANG_TIMER->SR & TIM_SR_UIF) && (gmlan_switch_below_timeout != -1)) { if ((can_timeout_counter == 0) && gmlan_switch_timeout_enable) { //it has been more than 1 second since timeout was reset; disable timer and restore the GMLAN output set_gpio_output(GPIOB, 13, GMLAN_LOW); @@ -265,14 +265,13 @@ void TIM12_IRQ_Handler(void) { } else { // Invalid GMLAN mode. Do not put a print statement here, way too fast to keep up with } - TIM12->SR = 0; + GMLAN_BITBANG_TIMER->SR = 0; } bool bitbang_gmlan(CANPacket_t *to_bang) { gmlan_send_ok = true; gmlan_alt_mode = BITBANG; -#ifndef STM32H7 if (gmlan_sendmax == -1) { int len = get_bit_message(pkt_stuffed, to_bang); gmlan_fail_count = 0; @@ -286,8 +285,5 @@ bool bitbang_gmlan(CANPacket_t *to_bang) { // 33kbps setup_timer(); } -#else - UNUSED(to_bang); -#endif return gmlan_send_ok; } diff --git a/board/stm32fx/stm32fx_config.h b/board/stm32fx/stm32fx_config.h index b47011921..4d382e0e7 100644 --- a/board/stm32fx/stm32fx_config.h +++ b/board/stm32fx/stm32fx_config.h @@ -28,6 +28,9 @@ #define TICK_TIMER_IRQ TIM1_BRK_TIM9_IRQn #define TICK_TIMER TIM9 +#define GMLAN_BITBANG_TIMER_IRQ TIM8_BRK_TIM12_IRQn +#define GMLAN_BITBANG_TIMER TIM12 + #define MICROSECOND_TIMER TIM2 #define INTERRUPT_TIMER_IRQ TIM6_DAC_IRQn diff --git a/board/stm32h7/peripherals.h b/board/stm32h7/peripherals.h index b60f19016..db8c0221e 100644 --- a/board/stm32h7/peripherals.h +++ b/board/stm32h7/peripherals.h @@ -124,8 +124,8 @@ void peripherals_init(void) { RCC->APB1LENR |= RCC_APB1LENR_TIM3EN; // fan pwm RCC->APB1LENR |= RCC_APB1LENR_TIM6EN; // interrupt timer RCC->APB1LENR |= RCC_APB1LENR_TIM7EN; // DMA trigger timer - RCC->APB2ENR |= RCC_APB2ENR_TIM8EN; // tick timer - RCC->APB1LENR |= RCC_APB1LENR_TIM12EN; // slow loop + RCC->APB1LENR |= RCC_APB1LENR_TIM12EN; // tick timer + RCC->APB1LENR |= RCC_APB1LENR_TIM13EN; // gmlan bitbang timer #ifdef PANDA_JUNGLE RCC->AHB3ENR |= RCC_AHB3ENR_SDMMC1EN; // SDMMC diff --git a/board/stm32h7/stm32h7_config.h b/board/stm32h7/stm32h7_config.h index a7d54274b..880ee4559 100644 --- a/board/stm32h7/stm32h7_config.h +++ b/board/stm32h7/stm32h7_config.h @@ -36,6 +36,9 @@ separate IRQs for RX and TX. #define TICK_TIMER_IRQ TIM8_BRK_TIM12_IRQn #define TICK_TIMER TIM12 +#define GMLAN_BITBANG_TIMER_IRQ TIM8_UP_TIM13_IRQn +#define GMLAN_BITBANG_TIMER TIM13 + #define MICROSECOND_TIMER TIM2 #define INTERRUPT_TIMER_IRQ TIM6_DAC_IRQn diff --git a/tests/hitl/3_usb_to_can.py b/tests/hitl/3_usb_to_can.py index 9321eb4e8..401a81bfa 100644 --- a/tests/hitl/3_usb_to_can.py +++ b/tests/hitl/3_usb_to_can.py @@ -119,6 +119,14 @@ def test_gmlan_bad_toggle(p): assert comp_kbps_normal > (0.6 * SPEED_NORMAL) assert comp_kbps_normal < (1.0 * SPEED_NORMAL) +@pytest.mark.panda_expect_can_error +@pytest.mark.skip_panda_types(PandaGroup.GMLAN) +def test_gmlan_bitbang(p): + p.set_safety_mode(Panda.SAFETY_ALLOUTPUT) + for _ in range(10): + p.can_send(0x10, b"data", 3) + time.sleep(0.1) + assert p.health()['gmlan_send_errs'] == 0 # this will fail if you have hardware serial connected def test_serial_debug(p):