Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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)) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps a less error-prone and more readable approach would be to use a struct with fields instead the array with magic indices.

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