diff --git a/board/boards/cuatro.h b/board/boards/cuatro.h index 00c2cf2285..545f87da8b 100644 --- a/board/boards/cuatro.h +++ b/board/boards/cuatro.h @@ -12,7 +12,7 @@ static void cuatro_set_led(uint8_t color, bool enabled) { set_gpio_output(GPIOD, 15, !enabled); break; case LED_GREEN: - set_gpio_output(GPIOD, 14, !enabled); + set_gpio_output(GPIOB, 2, !enabled); break; case LED_BLUE: set_gpio_output(GPIOE, 2, !enabled); @@ -71,12 +71,16 @@ static void cuatro_set_bootkick(BootState state) { //set_gpio_output(GPIOC, 12, state != BOOT_RESET); } +static void cuatro_set_siren(bool enabled){ + beeper_enable(enabled); +} + static void cuatro_init(void) { red_chiplet_init(); // init LEDs as open drain set_gpio_output_type(GPIOE, 2, OUTPUT_TYPE_OPEN_DRAIN); - set_gpio_output_type(GPIOD, 14, OUTPUT_TYPE_OPEN_DRAIN); + set_gpio_output_type(GPIOB, 2, OUTPUT_TYPE_OPEN_DRAIN); set_gpio_output_type(GPIOD, 15, OUTPUT_TYPE_OPEN_DRAIN); // Power readout @@ -120,6 +124,10 @@ static void cuatro_init(void) { // Clock source clock_source_init(); + + // Beeper + set_gpio_alternate(GPIOD, 14, GPIO_AF2_TIM4); + beeper_init(); } board board_cuatro = { @@ -143,7 +151,7 @@ board board_cuatro = { .read_current_mA = cuatro_read_current_mA, .set_fan_enabled = cuatro_set_fan_enabled, .set_ir_power = tres_set_ir_power, - .set_siren = unused_set_siren, + .set_siren = cuatro_set_siren, .set_bootkick = cuatro_set_bootkick, .read_som_gpio = tres_read_som_gpio }; diff --git a/board/drivers/beeper.h b/board/drivers/beeper.h new file mode 100644 index 0000000000..0ae02ff5e6 --- /dev/null +++ b/board/drivers/beeper.h @@ -0,0 +1,26 @@ + +#define BEEPER_COUNTER_OVERFLOW 25000U // 4kHz + +void beeper_enable(bool enabled) { + if (enabled) { + register_set_bits(&(TIM4->CCER), TIM_CCER_CC3E); + } else { + register_clear_bits(&(TIM4->CCER), TIM_CCER_CC3E); + } +} + +void beeper_init(void) { + // Enable timer and auto-reload + register_set(&(TIM4->CR1), TIM_CR1_CEN | TIM_CR1_ARPE, 0x3FU); + + // Set channel as PWM mode 1 and disable output + register_set_bits(&(TIM4->CCMR2), (TIM_CCMR2_OC3M_2 | TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3PE)); + beeper_enable(false); + + // Set max counter value and compare to get 50% duty + register_set(&(TIM4->CCR3), BEEPER_COUNTER_OVERFLOW / 2U, 0xFFFFU); + register_set(&(TIM4->ARR), BEEPER_COUNTER_OVERFLOW, 0xFFFFU); + + // Update registers and clear counter + TIM4->EGR |= TIM_EGR_UG; +} diff --git a/board/stm32h7/board.h b/board/stm32h7/board.h index e8ea23b252..6fbadcb633 100644 --- a/board/stm32h7/board.h +++ b/board/stm32h7/board.h @@ -10,6 +10,7 @@ #include "drivers/fan.h" #include "stm32h7/llfan.h" #include "stm32h7/lldac.h" +#include "drivers/beeper.h" #include "drivers/fake_siren.h" #include "drivers/clock_source.h" #include "boards/red.h" diff --git a/board/stm32h7/peripherals.h b/board/stm32h7/peripherals.h index b9a5861224..8b1cae2a68 100644 --- a/board/stm32h7/peripherals.h +++ b/board/stm32h7/peripherals.h @@ -126,6 +126,7 @@ void peripherals_init(void) { RCC->APB2ENR |= RCC_APB2ENR_TIM1EN; // clock source timer RCC->APB1LENR |= RCC_APB1LENR_TIM2EN; // main counter RCC->APB1LENR |= RCC_APB1LENR_TIM3EN; // fan pwm + RCC->APB1LENR |= RCC_APB1LENR_TIM4EN; // beeper source RCC->APB1LENR |= RCC_APB1LENR_TIM6EN; // interrupt timer RCC->APB1LENR |= RCC_APB1LENR_TIM7EN; // DMA trigger timer RCC->APB2ENR |= RCC_APB2ENR_TIM8EN; // tick timer