diff --git a/board/board_declarations.h b/board/board_declarations.h index b6f7772..2b7ee87 100644 --- a/board/board_declarations.h +++ b/board/board_declarations.h @@ -13,6 +13,7 @@ typedef void (*board_set_ir_power)(uint8_t percentage); typedef void (*board_set_fan_power)(uint8_t percentage); typedef void (*board_set_phone_power)(bool enabled); typedef void (*board_set_clock_source_mode)(uint8_t mode); +typedef void (*board_set_siren)(bool enabled); struct board { const char *board_type; @@ -31,6 +32,7 @@ struct board { board_set_fan_power set_fan_power; board_set_phone_power set_phone_power; board_set_clock_source_mode set_clock_source_mode; + board_set_siren set_siren; }; // ******************* Definitions ******************** diff --git a/board/boards/black.h b/board/boards/black.h index 70248c7..b6ec2f9 100644 --- a/board/boards/black.h +++ b/board/boards/black.h @@ -158,6 +158,10 @@ void black_set_clock_source_mode(uint8_t mode){ UNUSED(mode); } +void black_set_siren(bool enabled){ + UNUSED(enabled); +} + void black_init(void) { common_init_gpio(); @@ -244,5 +248,6 @@ const board board_black = { .set_fan_power = black_set_fan_power, .set_ir_power = black_set_ir_power, .set_phone_power = black_set_phone_power, - .set_clock_source_mode = black_set_clock_source_mode + .set_clock_source_mode = black_set_clock_source_mode, + .set_siren = black_set_siren }; diff --git a/board/boards/dos.h b/board/boards/dos.h index 91bb313..64af855 100644 --- a/board/boards/dos.h +++ b/board/boards/dos.h @@ -136,6 +136,10 @@ void dos_set_clock_source_mode(uint8_t mode){ clock_source_init(mode); } +void dos_set_siren(bool enabled){ + set_gpio_output(GPIOC, 12, enabled); +} + void dos_init(void) { common_init_gpio(); @@ -228,5 +232,6 @@ const board board_dos = { .set_fan_power = dos_set_fan_power, .set_ir_power = dos_set_ir_power, .set_phone_power = dos_set_phone_power, - .set_clock_source_mode = dos_set_clock_source_mode + .set_clock_source_mode = dos_set_clock_source_mode, + .set_siren = dos_set_siren }; diff --git a/board/boards/grey.h b/board/boards/grey.h index 1a7668d..dad3295 100644 --- a/board/boards/grey.h +++ b/board/boards/grey.h @@ -49,5 +49,6 @@ const board board_grey = { .set_fan_power = white_set_fan_power, .set_ir_power = white_set_ir_power, .set_phone_power = white_set_phone_power, - .set_clock_source_mode = white_set_clock_source_mode -}; \ No newline at end of file + .set_clock_source_mode = white_set_clock_source_mode, + .set_siren = white_set_siren +}; diff --git a/board/boards/pedal.h b/board/boards/pedal.h index b3d00f5..4c9fdb1 100644 --- a/board/boards/pedal.h +++ b/board/boards/pedal.h @@ -81,6 +81,10 @@ void pedal_set_clock_source_mode(uint8_t mode){ UNUSED(mode); } +void pedal_set_siren(bool enabled){ + UNUSED(enabled); +} + void pedal_init(void) { common_init_gpio(); @@ -118,5 +122,6 @@ const board board_pedal = { .set_fan_power = pedal_set_fan_power, .set_ir_power = pedal_set_ir_power, .set_phone_power = pedal_set_phone_power, - .set_clock_source_mode = pedal_set_clock_source_mode -}; \ No newline at end of file + .set_clock_source_mode = pedal_set_clock_source_mode, + .set_siren = pedal_set_siren +}; diff --git a/board/boards/uno.h b/board/boards/uno.h index aa5b06f..0bd96b9 100644 --- a/board/boards/uno.h +++ b/board/boards/uno.h @@ -179,6 +179,10 @@ void uno_set_clock_source_mode(uint8_t mode){ UNUSED(mode); } +void uno_set_siren(bool enabled){ + UNUSED(enabled); +} + void uno_init(void) { common_init_gpio(); @@ -287,5 +291,6 @@ const board board_uno = { .set_fan_power = uno_set_fan_power, .set_ir_power = uno_set_ir_power, .set_phone_power = uno_set_phone_power, - .set_clock_source_mode = uno_set_clock_source_mode + .set_clock_source_mode = uno_set_clock_source_mode, + .set_siren = uno_set_siren }; diff --git a/board/boards/white.h b/board/boards/white.h index b6e639f..0141fe3 100644 --- a/board/boards/white.h +++ b/board/boards/white.h @@ -246,6 +246,10 @@ void white_set_clock_source_mode(uint8_t mode){ UNUSED(mode); } +void white_set_siren(bool enabled){ + UNUSED(enabled); +} + void white_grey_common_init(void) { common_init_gpio(); @@ -348,5 +352,6 @@ const board board_white = { .set_fan_power = white_set_fan_power, .set_ir_power = white_set_ir_power, .set_phone_power = white_set_phone_power, - .set_clock_source_mode = white_set_clock_source_mode + .set_clock_source_mode = white_set_clock_source_mode, + .set_siren = white_set_siren }; diff --git a/board/main.c b/board/main.c index 207e5dc..9548474 100644 --- a/board/main.c +++ b/board/main.c @@ -610,6 +610,10 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, bool hardwired) case 0xf5: current_board->set_clock_source_mode(setup->b.wValue.w); break; + // **** 0xf6: set siren enabled + case 0xf6: + siren_enabled = (setup->b.wValue.w != 0U); + break; default: puts("NO HANDLER "); puth(setup->b.bRequest); @@ -667,87 +671,97 @@ void __attribute__ ((noinline)) enable_fpu(void) { #define EON_HEARTBEAT_IGNITION_CNT_ON 5U #define EON_HEARTBEAT_IGNITION_CNT_OFF 2U -// called at 1Hz +// called at 8Hz +uint8_t loop_counter = 0U; void TIM1_BRK_TIM9_IRQ_Handler(void) { if (TIM9->SR != 0) { - can_live = pending_can_live; + // siren + current_board->set_siren((loop_counter & 1U) && siren_enabled); - current_board->usb_power_mode_tick(uptime_cnt); + // decimated to 1Hz + if(loop_counter == 0U){ + can_live = pending_can_live; - //puth(usart1_dma); puts(" "); puth(DMA2_Stream5->M0AR); puts(" "); puth(DMA2_Stream5->NDTR); puts("\n"); + current_board->usb_power_mode_tick(uptime_cnt); - // reset this every 16th pass - if ((uptime_cnt & 0xFU) == 0U) { - 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 + //puth(usart1_dma); puts(" "); puth(DMA2_Stream5->M0AR); puts(" "); puth(DMA2_Stream5->NDTR); puts("\n"); - // Tick drivers - fan_tick(); - - // set green LED to be controls allowed - current_board->set_led(LED_GREEN, controls_allowed); - - // turn off the blue LED, turned on by CAN - // unless we are in power saving mode - current_board->set_led(LED_BLUE, (uptime_cnt & 1U) && (power_save_status == POWER_SAVE_STATUS_ENABLED)); - - // increase heartbeat counter and cap it at the uint32 limit - if (heartbeat_counter < __UINT32_MAX__) { - heartbeat_counter += 1U; - } - - #ifdef EON - // check heartbeat counter if we are running EON code. - // if the heartbeat has been gone for a while, go to SILENT safety mode and enter power save - if (heartbeat_counter >= (check_started() ? EON_HEARTBEAT_IGNITION_CNT_ON : EON_HEARTBEAT_IGNITION_CNT_OFF)) { - puts("EON hasn't sent a heartbeat for 0x"); - puth(heartbeat_counter); - puts(" seconds. Safety is set to SILENT mode.\n"); - if (current_safety_mode != SAFETY_SILENT) { - set_safety_mode(SAFETY_SILENT, 0U); + // reset this every 16th pass + if ((uptime_cnt & 0xFU) == 0U) { + pending_can_live = 0; } - if (power_save_status != POWER_SAVE_STATUS_ENABLED) { - set_power_save_state(POWER_SAVE_STATUS_ENABLED); + #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 + + // Tick drivers + fan_tick(); + + // set green LED to be controls allowed + current_board->set_led(LED_GREEN, controls_allowed); + + // turn off the blue LED, turned on by CAN + // unless we are in power saving mode + current_board->set_led(LED_BLUE, (uptime_cnt & 1U) && (power_save_status == POWER_SAVE_STATUS_ENABLED)); + + // increase heartbeat counter and cap it at the uint32 limit + if (heartbeat_counter < __UINT32_MAX__) { + heartbeat_counter += 1U; } - // Also disable IR when the heartbeat goes missing - current_board->set_ir_power(0U); + #ifdef EON + // check heartbeat counter if we are running EON code. + // if the heartbeat has been gone for a while, go to SILENT safety mode and enter power save + if (heartbeat_counter >= (check_started() ? EON_HEARTBEAT_IGNITION_CNT_ON : EON_HEARTBEAT_IGNITION_CNT_OFF)) { + puts("EON hasn't sent a heartbeat for 0x"); + puth(heartbeat_counter); + puts(" seconds. Safety is set to SILENT mode.\n"); + if (current_safety_mode != SAFETY_SILENT) { + set_safety_mode(SAFETY_SILENT, 0U); + } + if (power_save_status != POWER_SAVE_STATUS_ENABLED) { + set_power_save_state(POWER_SAVE_STATUS_ENABLED); + } - // If enumerated but no heartbeat (phone up, boardd not running), turn the fan on to cool the device - if(usb_enumerated()){ - current_board->set_fan_power(50U); - } else { - current_board->set_fan_power(0U); + // Also disable IR when the heartbeat goes missing + current_board->set_ir_power(0U); + + // If enumerated but no heartbeat (phone up, boardd not running), turn the fan on to cool the device + if(usb_enumerated()){ + current_board->set_fan_power(50U); + } else { + current_board->set_fan_power(0U); + } } + + // enter CDP mode when car starts to ensure we are charging a turned off EON + if (check_started() && (usb_power_mode != USB_POWER_CDP)) { + current_board->set_usb_power_mode(USB_POWER_CDP); + } + #endif + + // check registers + check_registers(); + + // set ignition_can to false after 2s of no CAN seen + if (ignition_can_cnt > 2U) { + ignition_can = false; + }; + + // on to the next one + uptime_cnt += 1U; + safety_mode_cnt += 1U; + ignition_can_cnt += 1U; + + // synchronous safety check + safety_tick(current_hooks); } - // enter CDP mode when car starts to ensure we are charging a turned off EON - if (check_started() && (usb_power_mode != USB_POWER_CDP)) { - current_board->set_usb_power_mode(USB_POWER_CDP); - } - #endif - - // check registers - check_registers(); - - // set ignition_can to false after 2s of no CAN seen - if (ignition_can_cnt > 2U) { - ignition_can = false; - }; - - // on to the next one - uptime_cnt += 1U; - safety_mode_cnt += 1U; - ignition_can_cnt += 1U; - - // synchronous safety check - safety_tick(current_hooks); + loop_counter++; + loop_counter %= 8U; } TIM9->SR = 0; } @@ -757,8 +771,8 @@ int main(void) { // Init interrupt table init_interrupts(true); - // 1s timer - REGISTER_INTERRUPT(TIM1_BRK_TIM9_IRQn, TIM1_BRK_TIM9_IRQ_Handler, 2U, FAULT_INTERRUPT_RATE_TIM9) + // 8Hz timer + REGISTER_INTERRUPT(TIM1_BRK_TIM9_IRQn, TIM1_BRK_TIM9_IRQ_Handler, 10U, FAULT_INTERRUPT_RATE_TIM9) // shouldn't have interrupts here, but just in case disable_interrupts(); @@ -830,8 +844,8 @@ int main(void) { spi_init(); #endif - // 1hz - timer_init(TIM9, 1464); + // 8hz + timer_init(TIM9, 183); NVIC_EnableIRQ(TIM1_BRK_TIM9_IRQn); #ifdef DEBUG diff --git a/board/main_declarations.h b/board/main_declarations.h index 363a992..7fa2c4b 100644 --- a/board/main_declarations.h +++ b/board/main_declarations.h @@ -13,3 +13,4 @@ const board *current_board; bool is_enumerated = 0; uint32_t heartbeat_counter = 0; uint32_t uptime_cnt = 0; +bool siren_enabled = false; diff --git a/python/__init__.py b/python/__init__.py index c602305..21b2fd5 100644 --- a/python/__init__.py +++ b/python/__init__.py @@ -673,3 +673,7 @@ class Panda(object): # ************** Clock Source ************** def set_clock_source_mode(self, mode): self._handle.controlWrite(Panda.REQUEST_OUT, 0xf5, int(mode), 0, b'') + + # ****************** Siren ***************** + def set_siren(self, enabled): + self._handle.controlWrite(Panda.REQUEST_OUT, 0xf6, int(enabled), 0, b'')