Skip to content

Commit

Permalink
ad7779: apply a sync pulse after configuration
Browse files Browse the repository at this point in the history
JIRA: DTR-342
  • Loading branch information
Jakub Sarzyński committed Oct 6, 2022
1 parent c346606 commit 86ea16a
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 16 deletions.
15 changes: 15 additions & 0 deletions adc/ad7779/ad7779-driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,12 @@ static int dev_ctl(msg_t *msg)
res = ad7779_set_enabled_channels(dev_ctl.config.enabled_ch);
if (res == AD7779_ARG_ERROR)
return -EINVAL;
if (res != AD7779_OK)
return -EIO;
/* NOTE: Here SYNC_IN is not required by the docs, but sometimes after
* turning on/off channels we encounter unexpected ADC hang-ups (SPI
* works but we don't get DRDY). Applying SYNC solves the issue. */
res = ad7779_pulse_sync();
if (res != AD7779_OK)
return -EIO;
return EOK;
Expand Down Expand Up @@ -175,6 +181,9 @@ static int dev_ctl(msg_t *msg)
res = ad7779_set_channel_mode(dev_ctl.ch_config.channel, mode);
if (res == AD7779_ARG_ERROR)
return -EINVAL;
if (res != AD7779_OK)
return -EIO;
res = ad7779_pulse_sync();
if (res != AD7779_OK)
return -EIO;
return EOK;
Expand Down Expand Up @@ -213,6 +222,9 @@ static int dev_ctl(msg_t *msg)
res = ad7779_set_channel_gain(dev_ctl.gain.channel, dev_ctl.gain.val);
if (res == AD7779_ARG_ERROR)
return -EINVAL;
if (res != AD7779_OK)
return -EIO;
res = ad7779_pulse_sync();
if (res != AD7779_OK)
return -EIO;
return EOK;
Expand All @@ -235,6 +247,9 @@ static int dev_ctl(msg_t *msg)
res = ad7779_set_channel_gain_correction(dev_ctl.calib.channel, dev_ctl.calib.gain);
if (res == AD7779_ARG_ERROR)
return -EINVAL;
if (res != AD7779_OK)
return -EIO;
res = ad7779_pulse_sync();
if (res != AD7779_OK)
return -EIO;
return EOK;
Expand Down
66 changes: 50 additions & 16 deletions adc/ad7779/ad7779.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,13 @@

#define AD7779_READ_BIT (0x80)

/* AD7779_STATUS_REG_3 */
#define INIT_COMPLETE_BIT (1 << 4)

/* AD7779_GEN_ERR_REG_2 */
#define RESET_DETECTED_BIT (1 << 5)


static int ad7779_read(uint8_t addr, uint8_t *data, uint8_t len)
{
uint8_t buff[len + 1];
Expand Down Expand Up @@ -181,6 +188,27 @@ int ad7779_get_mode(ad7779_mode_t *mode)
return AD7779_OK;
}

int ad7779_pulse_sync(void)
{
int res;

log_debug("resetting internal logic");
res = ad7779_gpio(start, 0);
if (res != 0) {
log_error("failed to set start GPIO to 0");
return AD7779_GPIO_IO_ERROR;
}

usleep(2);
res = ad7779_gpio(start, 1);
if (res != 0) {
log_error("failed to set start GPIO to 1");
return AD7779_GPIO_IO_ERROR;
}

return AD7779_OK;
}

int ad7779_set_mode(ad7779_mode_t mode)
{
if (mode == ad7779_mode__high_resolution)
Expand Down Expand Up @@ -267,13 +295,6 @@ int ad7779_set_sampling_rate(uint32_t fs)
if ((res = ad7779_set_clear_bits(AD7779_SRC_UPDATE, SRC_LOAD_UPDATE_BIT, 0)) < 0)
return res;

/* Reset internal logic */
log_debug("reseting internal logic");
if ((res = ad7779_set_clear_bits(AD7779_GENERAL_USER_CONFIG_2, 0, SPI_SYNC)) < 0)
return res;
if ((res = ad7779_set_clear_bits(AD7779_GENERAL_USER_CONFIG_2, SPI_SYNC, 0)) < 0)
return res;

return AD7779_OK;
}

Expand Down Expand Up @@ -543,25 +564,34 @@ static int ad7779_reset(int hard)
}

/* Software reset */
ad7779_gpio(start, 0);
usleep(10000);
ad7779_gpio(reset, 0);
usleep(200000);
ad7779_gpio(start, 1);
usleep(100000);
usleep(2);
ad7779_gpio(reset, 1);
usleep(300);

memset(status, 0, sizeof(status));

for (i = 0; i < 4; ++i) {
if (!ad7779_get_status(status)) {
if (status[16] & 0x10)
return AD7779_OK;
if (ad7779_get_status(status) != AD7779_OK) {
usleep(100 * 1000);
continue;
}

usleep(100000);
if ((status[16] & INIT_COMPLETE_BIT) && (status[13] & RESET_DETECTED_BIT)) {
return AD7779_OK;
}
else {
if (!(status[16] & INIT_COMPLETE_BIT)) {
log_error("init bit not detected");
}
if (!(status[13] & RESET_DETECTED_BIT)) {
log_error("reset bit not detected");
}
break;
}
}

log_error("failed to read status after the device restart");
return AD7779_CTRL_IO_ERROR;
}

Expand Down Expand Up @@ -598,6 +628,10 @@ int ad7779_init(int hard)
if ((res = ad7779_set_mode(ad7779_mode__high_resolution)) < 0)
return res;

/* Toggle START (to generate SYNC_IN) after mode change */
if ((res = ad7779_pulse_sync()) < 0)
return res;

/* Use one DOUTx line; DCLK_CLK_DIV = 1 */
log_debug("setting DOUT_FORMAT");
if ((res = ad7779_write_reg(AD7779_DOUT_FORMAT, 0xe0)) < 0)
Expand Down
2 changes: 2 additions & 0 deletions adc/ad7779/ad7779.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ int ad7779_set_channel_gain_correction(uint8_t channel, uint32_t gain);

int ad7779_get_status(uint8_t *status_buf);

int ad7779_pulse_sync(void);

/* For debugging purposes */
int ad7779_print_status(void);

Expand Down

0 comments on commit 86ea16a

Please sign in to comment.