Skip to content

Commit

Permalink
tres: fix I2C hang on fake siren init (commaai#2069)
Browse files Browse the repository at this point in the history
* fix i2c hang

* misra fix

---------

Co-authored-by: Comma Device <[email protected]>
  • Loading branch information
adeebshihadeh and Comma Device authored Oct 30, 2024
1 parent 352e7ff commit 0b364ec
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 13 deletions.
1 change: 0 additions & 1 deletion board/boards/tres.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@ static void tres_init(void) {
set_gpio_alternate(GPIOC, 10, GPIO_AF4_I2C5);
set_gpio_alternate(GPIOC, 11, GPIO_AF4_I2C5);
register_set_bits(&(GPIOC->OTYPER), GPIO_OTYPER_OT10 | GPIO_OTYPER_OT11); // open drain
fake_siren_init();

// Clock source
clock_source_init();
Expand Down
8 changes: 8 additions & 0 deletions board/drivers/fake_siren.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

#define CODEC_I2C_ADDR 0x10

void fake_siren_init(void);

void fake_siren_codec_enable(bool enabled) {
if (enabled) {
bool success = true;
Expand All @@ -28,8 +30,14 @@ void fake_siren_codec_enable(bool enabled) {


void fake_siren_set(bool enabled) {
static bool initialized = false;
static bool fake_siren_enabled = false;

if (!initialized) {
fake_siren_init();
initialized = true;
}

if (enabled != fake_siren_enabled) {
fake_siren_codec_enable(enabled);
}
Expand Down
5 changes: 3 additions & 2 deletions board/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -325,12 +325,13 @@ int main(void) {
// panda has an FPU, let's use it!
enable_fpu();

microsecond_timer_init();

current_board->set_siren(false);
if (current_board->fan_max_rpm > 0U) {
fan_init();
}

microsecond_timer_init();

// init to SILENT and can silent
set_safety_mode(SAFETY_SILENT, 0U);

Expand Down
32 changes: 23 additions & 9 deletions board/stm32h7/lli2c.h
Original file line number Diff line number Diff line change
@@ -1,20 +1,27 @@

// TODO: this driver relies heavily on polling,
// if we want it to be more async, we should use interrupts

#define I2C_RETRY_COUNT 10U
#define I2C_TIMEOUT_US 100000U

// cppcheck-suppress misra-c2012-2.7; not sure why it triggers here?
bool i2c_status_wait(const volatile uint32_t *reg, uint32_t mask, uint32_t val) {
uint32_t start_time = microsecond_timer_get();
while(((*reg & mask) != val) && (get_ts_elapsed(microsecond_timer_get(), start_time) < I2C_TIMEOUT_US));
return ((*reg & mask) == val);
}

void i2c_reset(I2C_TypeDef *I2C) {
// peripheral reset
register_clear_bits(&I2C->CR1, I2C_CR1_PE);
while ((I2C->CR1 & I2C_CR1_PE) != 0U);
register_set_bits(&I2C->CR1, I2C_CR1_PE);
}

bool i2c_write_reg(I2C_TypeDef *I2C, uint8_t addr, uint8_t reg, uint8_t value) {
// Setup transfer and send START + addr
bool ret = false;
for(uint32_t i=0U; i<10U; i++) {

// Setup transfer and send START + addr
for (uint32_t i = 0U; i < I2C_RETRY_COUNT; i++) {
register_clear_bits(&I2C->CR2, I2C_CR2_ADD10);
I2C->CR2 = ((uint32_t)addr << 1U) & I2C_CR2_SADD_Msk;
register_clear_bits(&I2C->CR2, I2C_CR2_RD_WRN);
Expand Down Expand Up @@ -57,9 +64,10 @@ bool i2c_write_reg(I2C_TypeDef *I2C, uint8_t addr, uint8_t reg, uint8_t value) {
}

bool i2c_read_reg(I2C_TypeDef *I2C, uint8_t addr, uint8_t reg, uint8_t *value) {
// Setup transfer and send START + addr
bool ret = false;
for(uint32_t i=0U; i<10U; i++) {

// Setup transfer and send START + addr
for (uint32_t i = 0U; i < I2C_RETRY_COUNT; i++) {
register_clear_bits(&I2C->CR2, I2C_CR2_ADD10);
I2C->CR2 = ((uint32_t)addr << 1U) & I2C_CR2_SADD_Msk;
register_clear_bits(&I2C->CR2, I2C_CR2_RD_WRN);
Expand Down Expand Up @@ -116,6 +124,11 @@ bool i2c_read_reg(I2C_TypeDef *I2C, uint8_t addr, uint8_t reg, uint8_t *value) {
I2C->CR2 |= I2C_CR2_STOP;

end:

if (!ret) {
i2c_reset(I2C);
}

return ret;
}

Expand All @@ -131,7 +144,7 @@ bool i2c_set_reg_bits(I2C_TypeDef *I2C, uint8_t address, uint8_t regis, uint8_t
bool i2c_clear_reg_bits(I2C_TypeDef *I2C, uint8_t address, uint8_t regis, uint8_t bits) {
uint8_t value;
bool ret = i2c_read_reg(I2C, address, regis, &value);
if(ret) {
if (ret) {
ret = i2c_write_reg(I2C, address, regis, value & (uint8_t) (~bits));
}
return ret;
Expand All @@ -149,5 +162,6 @@ bool i2c_set_reg_mask(I2C_TypeDef *I2C, uint8_t address, uint8_t regis, uint8_t
void i2c_init(I2C_TypeDef *I2C) {
// 100kHz clock speed
I2C->TIMINGR = 0x107075B0;
I2C->CR1 = I2C_CR1_PE;
}

i2c_reset(I2C);
}
1 change: 0 additions & 1 deletion python/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,6 @@ def _cli_select_panda(self):
return None
if len(pandas) == 1:
print(f"INFO: connecting to panda {pandas[0]}")
time.sleep(1)
return pandas[0]
while True:
print("Multiple pandas available:")
Expand Down

0 comments on commit 0b364ec

Please sign in to comment.