mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-11-12 07:23:45 +08:00
22a8575199
Keep official openpilot ancestry and dependency licenses. Store resources directly in Git, remove LFS setup requirements, and leave the downloadable big model outside the source tree.
118 lines
5.7 KiB
C
118 lines
5.7 KiB
C
#pragma once
|
|
|
|
#include "board/stm32h7/lli2c.h"
|
|
|
|
#define CODEC_I2C_ADDR 0x10
|
|
|
|
void siren_tim7_init(void) {
|
|
// Init trigger timer (around 2.5kHz)
|
|
register_set(&TIM7->PSC, 0U, 0xFFFFU);
|
|
register_set(&TIM7->ARR, 133U, 0xFFFFU);
|
|
register_set(&TIM7->CR2, (0b10U << TIM_CR2_MMS_Pos), TIM_CR2_MMS_Msk);
|
|
register_set(&TIM7->CR1, TIM_CR1_ARPE | TIM_CR1_URS, 0x088EU);
|
|
TIM7->SR = 0U;
|
|
TIM7->CR1 |= TIM_CR1_CEN;
|
|
}
|
|
|
|
void siren_dac_init(void) {
|
|
DAC1->DHR8R1 = (1U << 7);
|
|
DAC1->DHR8R2 = (1U << 7);
|
|
register_set(&DAC1->MCR, 0U, 0xFFFFFFFFU);
|
|
register_set(&DAC1->CR, DAC_CR_TEN1 | (6U << DAC_CR_TSEL1_Pos) | DAC_CR_DMAEN1, 0xFFFFFFFFU);
|
|
register_set_bits(&DAC1->CR, DAC_CR_EN1 | DAC_CR_EN2);
|
|
}
|
|
|
|
void siren_dma_init(void) {
|
|
// 1Vpp sine wave with 1V offset
|
|
static const uint8_t fake_siren_lut[360] = { 134U, 135U, 137U, 138U, 139U, 140U, 141U, 143U, 144U, 145U, 146U, 148U, 149U, 150U, 151U, 152U, 154U, 155U, 156U, 157U, 158U, 159U, 160U, 162U, 163U, 164U, 165U, 166U, 167U, 168U, 169U, 170U, 171U, 172U, 174U, 175U, 176U, 177U, 177U, 178U, 179U, 180U, 181U, 182U, 183U, 184U, 185U, 186U, 186U, 187U, 188U, 189U, 190U, 190U, 191U, 192U, 193U, 193U, 194U, 195U, 195U, 196U, 196U, 197U, 197U, 198U, 199U, 199U, 199U, 200U, 200U, 201U, 201U, 202U, 202U, 202U, 203U, 203U, 203U, 203U, 204U, 204U, 204U, 204U, 204U, 204U, 204U, 205U, 205U, 205U, 205U, 205U, 205U, 205U, 204U, 204U, 204U, 204U, 204U, 204U, 204U, 203U, 203U, 203U, 203U, 202U, 202U, 202U, 201U, 201U, 200U, 200U, 199U, 199U, 199U, 198U, 197U, 197U, 196U, 196U, 195U, 195U, 194U, 193U, 193U, 192U, 191U, 190U, 190U, 189U, 188U, 187U, 186U, 186U, 185U, 184U, 183U, 182U, 181U, 180U, 179U, 178U, 177U, 177U, 176U, 175U, 174U, 172U, 171U, 170U, 169U, 168U, 167U, 166U, 165U, 164U, 163U, 162U, 160U, 159U, 158U, 157U, 156U, 155U, 154U, 152U, 151U, 150U, 149U, 148U, 146U, 145U, 144U, 143U, 141U, 140U, 139U, 138U, 137U, 135U, 134U, 133U, 132U, 130U, 129U, 128U, 127U, 125U, 124U, 123U, 122U, 121U, 119U, 118U, 117U, 116U, 115U, 113U, 112U, 111U, 110U, 109U, 108U, 106U, 105U, 104U, 103U, 102U, 101U, 100U, 99U, 98U, 97U, 96U, 95U, 94U, 93U, 92U, 91U, 90U, 89U, 88U, 87U, 86U, 85U, 84U, 83U, 82U, 82U, 81U, 80U, 79U, 78U, 78U, 77U, 76U, 76U, 75U, 74U, 74U, 73U, 72U, 72U, 71U, 71U, 70U, 70U, 69U, 69U, 68U, 68U, 67U, 67U, 67U, 66U, 66U, 66U, 65U, 65U, 65U, 65U, 64U, 64U, 64U, 64U, 64U, 64U, 64U, 64U, 64U, 63U, 64U, 64U, 64U, 64U, 64U, 64U, 64U, 64U, 64U, 65U, 65U, 65U, 65U, 66U, 66U, 66U, 67U, 67U, 67U, 68U, 68U, 69U, 69U, 70U, 70U, 71U, 71U, 72U, 72U, 73U, 74U, 74U, 75U, 76U, 76U, 77U, 78U, 78U, 79U, 80U, 81U, 82U, 82U, 83U, 84U, 85U, 86U, 87U, 88U, 89U, 90U, 91U, 92U, 93U, 94U, 95U, 96U, 97U, 98U, 99U, 100U, 101U, 102U, 103U, 104U, 105U, 106U, 108U, 109U, 110U, 111U, 112U, 113U, 115U, 116U, 117U, 118U, 119U, 121U, 122U, 123U, 124U, 125U, 127U, 128U, 129U, 130U, 132U, 133U };
|
|
// Setup DMAMUX (DAC_CH1_DMA as input)
|
|
register_set(&DMAMUX1_Channel1->CCR, 67U, DMAMUX_CxCR_DMAREQ_ID_Msk);
|
|
register_set(&DMA1_Stream1->PAR, (uint32_t)&(DAC1->DHR8R1), 0xFFFFFFFFU);
|
|
// Setup DMA
|
|
register_set(&DMA1_Stream1->M0AR, (uint32_t)fake_siren_lut, 0xFFFFFFFFU);
|
|
register_set(&DMA1_Stream1->FCR, 0U, 0x00000083U);
|
|
DMA1_Stream1->NDTR = sizeof(fake_siren_lut);
|
|
DMA1_Stream1->CR = (0b11UL << DMA_SxCR_PL_Pos) | DMA_SxCR_MINC | DMA_SxCR_CIRC | (1U << DMA_SxCR_DIR_Pos);
|
|
}
|
|
|
|
void fake_siren_codec_enable(bool enabled) {
|
|
if (enabled) {
|
|
bool success = true;
|
|
success &= i2c_set_reg_bits(I2C5, CODEC_I2C_ADDR, 0x2B, (1U << 1)); // Left speaker mix from INA1
|
|
success &= i2c_set_reg_bits(I2C5, CODEC_I2C_ADDR, 0x2C, (1U << 1)); // Right speaker mix from INA1
|
|
success &= i2c_set_reg_mask(I2C5, CODEC_I2C_ADDR, 0x3D, 0x17, 0b11111); // Left speaker volume
|
|
success &= i2c_set_reg_mask(I2C5, CODEC_I2C_ADDR, 0x3E, 0x17, 0b11111); // Right speaker volume
|
|
success &= i2c_set_reg_mask(I2C5, CODEC_I2C_ADDR, 0x37, 0b101, 0b111); // INA gain
|
|
success &= i2c_set_reg_bits(I2C5, CODEC_I2C_ADDR, 0x4C, (1U << 7)); // Enable INA
|
|
success &= i2c_set_reg_bits(I2C5, CODEC_I2C_ADDR, 0x51, (1U << 7)); // Disable global shutdown
|
|
if (!success) {
|
|
print("Siren codec enable failed\n");
|
|
fault_occurred(FAULT_SIREN_MALFUNCTION);
|
|
}
|
|
} else {
|
|
// Disable INA input. Make sure to retry a few times if the I2C bus is busy.
|
|
for (uint8_t i=0U; i<10U; i++) {
|
|
if (i2c_clear_reg_bits(I2C5, CODEC_I2C_ADDR, 0x4C, (1U << 7))) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void fake_i2c_siren_init(void) {
|
|
siren_dac_init();
|
|
siren_dma_init();
|
|
siren_tim7_init();
|
|
// Enable the I2C to the codec
|
|
i2c_init(I2C5);
|
|
fake_siren_codec_enable(false);
|
|
}
|
|
|
|
void fake_i2c_siren_set(bool enabled) {
|
|
static bool initialized = false;
|
|
static bool fake_siren_enabled = false;
|
|
|
|
if (!initialized) {
|
|
fake_i2c_siren_init();
|
|
initialized = true;
|
|
}
|
|
|
|
if (enabled != fake_siren_enabled) {
|
|
fake_siren_codec_enable(enabled);
|
|
}
|
|
|
|
if (enabled) {
|
|
register_set_bits(&DMA1_Stream1->CR, DMA_SxCR_EN);
|
|
} else {
|
|
register_clear_bits(&DMA1_Stream1->CR, DMA_SxCR_EN);
|
|
}
|
|
fake_siren_enabled = enabled;
|
|
}
|
|
|
|
void fake_siren_set(bool enabled) {
|
|
static bool initialized = false;
|
|
static bool fake_siren_enabled = false;
|
|
|
|
if (!initialized) {
|
|
siren_tim7_init();
|
|
initialized = true;
|
|
}
|
|
|
|
if (enabled != fake_siren_enabled) {
|
|
if (enabled) {
|
|
sound_stop_dac();
|
|
siren_dac_init();
|
|
siren_dma_init();
|
|
current_board->set_amp_enabled(true);
|
|
register_set_bits(&DMA1_Stream1->CR, DMA_SxCR_EN);
|
|
} else {
|
|
current_board->set_amp_enabled(false);
|
|
// Stop modified 8-bit DAC and start normal 12-bit DAC
|
|
sound_stop_dac();
|
|
sound_init_dac();
|
|
register_set_bits(&BDMA_Channel0->CCR, BDMA_CCR_EN);
|
|
}
|
|
fake_siren_enabled = enabled;
|
|
}
|
|
}
|