From 1a3dfad34110158d08044bb4901e680480fe19f7 Mon Sep 17 00:00:00 2001 From: Rahix <rahix@rahix.de> Date: Thu, 26 Dec 2019 12:47:28 +0100 Subject: [PATCH] fix(bhi160): Fix interrupt behavior during initialization As discussed in issue card10/firmware#133, the BHI160 changes its interrupt behavior during initialization. In commit 2f56ff36403c ("fix(bhi160): Call bhy_mapping_matrix_set twice for the first time") a quick workaround for this issue was added. Replace this hack with a proper fix by reconfiguring the interrupt on the host side according to the specification. (Finally) fixes card10/firmware#133. Fixes: 2f56ff36403c ("fix(bhi160): Call bhy_mapping_matrix_set twice for the first time") Link: https://git.card10.badge.events.ccc.de/card10/firmware/issues/133#note_5894 Signed-off-by: Rahix <rahix@rahix.de> --- epicardium/modules/bhi.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/epicardium/modules/bhi.c b/epicardium/modules/bhi.c index 9891c0a4..3ef515b8 100644 --- a/epicardium/modules/bhi.c +++ b/epicardium/modules/bhi.c @@ -405,12 +405,20 @@ void vBhi160Task(void *pvParameters) memset(bhi160_streams, 0x00, sizeof(bhi160_streams)); - /* Install interrupt callback */ + /* + * The BHI160, coming out of power-on-reset will hold its interrupt line + * high until a firmware image is loaded. Once that firmware is loaded + * and running, the interrupt line is deasserted and from then on, + * interrupts are signaled using a rising edge. + * + * So, initially we need to configure the IRQ for a falling edge, load + * the firmware and then reconfigure for a rising edge. + */ GPIO_Config(&bhi160_interrupt_pin); GPIO_RegisterCallback( &bhi160_interrupt_pin, bhi160_interrupt_callback, NULL ); - GPIO_IntConfig(&bhi160_interrupt_pin, GPIO_INT_EDGE, GPIO_INT_RISING); + GPIO_IntConfig(&bhi160_interrupt_pin, GPIO_INT_EDGE, GPIO_INT_FALLING); GPIO_IntEnable(&bhi160_interrupt_pin); NVIC_SetPriority( (IRQn_Type)MXC_GPIO_GET_IRQ(bhi160_interrupt_pin.port), 2 @@ -424,17 +432,18 @@ void vBhi160Task(void *pvParameters) vTaskDelay(portMAX_DELAY); } - /* Wait for first interrupt */ + /* Wait for first interrupt, a falling edge */ hwlock_release(HWLOCK_I2C); ulTaskNotifyTake(pdTRUE, pdMS_TO_TICKS(100)); hwlock_acquire(HWLOCK_I2C); + /* + * The firmware is now loaded; as stated above, we now need to + * reconfigure the IRQ for a rising edge. + */ + GPIO_IntConfig(&bhi160_interrupt_pin, GPIO_INT_EDGE, GPIO_INT_RISING); + /* Remap axes to match card10 layout */ - /* Due to a known issue (#133) the first call to - * bhy_mapping_matrix_set might fail. */ - bhy_mapping_matrix_set( - PHYSICAL_SENSOR_INDEX_ACC, bhi160_mapping_matrix - ); bhy_mapping_matrix_set( PHYSICAL_SENSOR_INDEX_ACC, bhi160_mapping_matrix ); -- GitLab