Skip to content

Commit 2bf231f

Browse files
kuronekocarlescufi
authored andcommitted
adc: ads1x1x: improve behaviour during i2c errors
Fixes #61401 The ADS1x1x driver has a bad habit of assuming i2c operations will always suceed - this fixes the two worse cases in the code I could identify (there may yet be more). * During initial ADC setup, if either of the two I2C operations (read or write) fails, raise the error immediately to the caller rather than letting it fall through to the acquisition thread. This ensures that we only ever attempt to give a result that was definitely connected to our attempt to start the capture. * If the acquisition thread encounters an I2C error, raise the error but do not terminate the aquisition thread. This ensures the application can attempt to fix the condition that caused the I2C error and try again. Signed-off-by: Chris Collins <[email protected]>
1 parent 45701e6 commit 2bf231f

File tree

1 file changed

+18
-6
lines changed

1 file changed

+18
-6
lines changed

drivers/adc/adc_ads1x1x.c

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -185,12 +185,16 @@ static int ads1x1x_start_conversion(const struct device *dev)
185185
{
186186
/* send start sampling command */
187187
uint16_t config;
188+
int ret;
188189

189-
ads1x1x_read_reg(dev, ADS1X1X_REG_CONFIG, &config);
190+
ret = ads1x1x_read_reg(dev, ADS1X1X_REG_CONFIG, &config);
191+
if (ret != 0) {
192+
return ret;
193+
}
190194
config |= ADS1X1X_CONFIG_OS;
191-
ads1x1x_write_reg(dev, ADS1X1X_REG_CONFIG, config);
195+
ret = ads1x1x_write_reg(dev, ADS1X1X_REG_CONFIG, config);
192196

193-
return 0;
197+
return ret;
194198
}
195199

196200
static inline int ads1x1x_acq_time_to_dr(const struct device *dev, uint16_t acq_time)
@@ -458,11 +462,19 @@ static void adc_context_update_buffer_pointer(struct adc_context *ctx, bool repe
458462
static void adc_context_start_sampling(struct adc_context *ctx)
459463
{
460464
struct ads1x1x_data *data = CONTAINER_OF(ctx, struct ads1x1x_data, ctx);
465+
int ret;
461466

462467
data->repeat_buffer = data->buffer;
463468

464-
ads1x1x_start_conversion(data->dev);
465-
469+
ret = ads1x1x_start_conversion(data->dev);
470+
if (ret != 0) {
471+
/* if we fail to complete the I2C operations to start
472+
* sampling, return an immediate error (likely -EIO) rather
473+
* than handing it off to the acquisition thread.
474+
*/
475+
adc_context_complete(ctx, ret);
476+
return;
477+
}
466478
k_sem_give(&data->acq_sem);
467479
}
468480

@@ -537,7 +549,7 @@ static void ads1x1x_acquisition_thread(const struct device *dev)
537549
if (rc != 0) {
538550
LOG_ERR("failed to get ready status (err %d)", rc);
539551
adc_context_complete(&data->ctx, rc);
540-
break;
552+
continue;
541553
}
542554

543555
ads1x1x_adc_perform_read(dev);

0 commit comments

Comments
 (0)