being quite new both to ChibiOS and STM32 (but with several years of experience on MSP430), I am extremely reluctant to call the effect I am seeing here a bug, but it is hugely annoying. Maybe someone can point me in the right direction?
Setup: ChibiOS 19.1.3, ARM GCC 9.2.1 (from ARM site), STM32L152 Nucleo Board with Si7021 attached.
I am cyclically (every 5s) reading the latest data from the sensor via I2C, which is basically working all fine. The relevant parts of the code look like this:
Global variable declaration:
Code: Select all
#define WASIZE_HUM 128
#define AVERAGING_SAMPLES 20
/* Array of last read values, used for averaging. Contains raw data */
volatile struct {
uint16_t index;
uint16_t samples_to_init; /* counts down to zero until buffer is full */
uint16_t hum_values[AVERAGING_SAMPLES];
uint16_t hum_temp_values[AVERAGING_SAMPLES];
} hum_data;
volatile uint8_t i2c_data[3];
const uint8_t SI7020_MEASURE_HUM_HOLD = 0xE5;
I2CDriver *hum_i2c_driver;
uint8_t hum_i2c_address;
Thread function:
Code: Select all
static THD_WORKING_AREA(wa_thread_hum, WASIZE_HUM);
static THD_FUNCTION(thread_hum, arg) {
(void)arg;
...
while(true) {
i2cAcquireBus(hum_i2c_driver);
/* Measure humidity */
i2c_result = i2cMasterTransmitTimeout(hum_i2c_driver, hum_i2c_address, &SI7020_MEASURE_HUM_HOLD, 1, i2c_data, 3, TIME_MS2I(I2C_MAXTIME));
...
i2cReleaseBus(hum_i2c_driver);
...
}
}
After [font=Courier New]i2cMasterTransmitTimeout()[/font], i2c_data contains plausible data which matches what I see on the logic analyzer. So far, so good.
BUT: I see more or less random changes in [font=Courier New]hum_temp_values[/font]. See attached screenshots. Strangely enough, the affected memory is quite a bit away: [font=Courier New]i2c_data[/font] is at [font=Courier New]0x20000aec[/font], while the affected memory is at [font=Courier New]0x20000b48[/font] (or in the vicinity, the pattern is not always the same).
With the debugger, I have tracked down the effect to this piece of code in [font=Courier New]hal_i2c_lld.c[/font]:
Code: Select all
dp->CR2 |= I2C_CR2_ITEVTEN;
dp->CR1 |= I2C_CR1_START;
/* Waits for the operation completion or a timeout.*/
return osalThreadSuspendTimeoutS(&i2cp->thread, timeout);
Not being too familiar with STM32 (which is one of the reasons I chose ChibiOS), I assume that [font=Courier New]dp->CR1 |= I2C_CR1_START;[/font] starts the I2C/DMA transaction. When I step over the [font=Courier New]return()[/font], the effect is visible.
Any help is appreciated. Thank you!