Hi,
I am trying to setup a TWI interface between the nRF52 DK and the 16-bit ADC ADS1115 from TI. I am using the breakout board from Adafruit (https://www.adafruit.com/product/1085). Anyway, using the TWI scanner I can see the device and the correct address at 0x48. When trying to so a simple single ended reading I run into some trouble.
I get this error:
<error> app: ERROR 33282 [NRF_ERROR_DRV_TWI_ERR_DNACK] at /home/emil/nRF_SDK/SDK15/examples/Projects/nRF52832-Potentiometric-Board/main.c:185
Which is this line of code
err_code = nrf_drv_twi_tx(p_instance, i2cAddress, ®, sizeof(®), false); APP_ERROR_CHECK(err_code);
This is my current code:
void twi_init(void) {
ret_code_t err_code;
const nrf_drv_twi_config_t twi_ADS1115_config = {
.scl = 27,
.sda = 26,
.frequency = NRF_DRV_TWI_FREQ_100K,
.interrupt_priority = APP_IRQ_PRIORITY_HIGH,
.clear_bus_init = false};
GPIO_PIN_CNF_PULL_Disabled;
err_code = nrf_drv_twi_init(&m_twi, &twi_ADS1115_config, NULL, NULL);
APP_ERROR_CHECK(err_code);
nrf_drv_twi_enable(&m_twi);
}
static uint16_t readADC_SingleEnded(nrf_drv_twi_t const *const p_instance, uint8_t channel) {
if (channel > 3) {
return 0;
}
m_bitShift = 4;
m_gain = GAIN_FOUR;
//m_xfer_done = false;
// Start with the default values
uint16_t config = ADS1115_REG_CONFIG_CQUE_NONE | // Disable the comparator (default val)
ADS1115_REG_CONFIG_CLAT_NONLAT | // Non-latching (default val)
ADS1115_REG_CONFIG_CPOL_ACTVLOW | // Alert/Ready active low (default val)
ADS1115_REG_CONFIG_CMODE_TRAD | // Traditional comparator
ADS1115_REG_CONFIG_DR_1600SPS | // 1600 samples per second (default)
ADS1115_REG_CONFIG_MODE_SINGLE; // Single shot mode (default)
// Set PGA/Voltage gain
config |= m_gain;
// Set single-ended input channel to read from
switch (channel) {
case (0):
config |= ADS1115_REG_CONFIG_MUX_SINGLE_0;
break;
case (1):
config |= ADS1115_REG_CONFIG_MUX_SINGLE_1;
break;
case (2):
config |= ADS1115_REG_CONFIG_MUX_SINGLE_2;
break;
case (3):
config |= ADS1115_REG_CONFIG_MUX_SINGLE_3;
break;
}
// Set "start single-conversion" bit
config |= ADS1115_REG_CONFIG_OS_SINGLE;
// Write config register to the ADC
// Note: currently block until the write happens
writeRegister(p_instance, m_i2cAddress, ADS1115_REG_POINTER_CONFIG, config);
// Read the conversion results
// Shift 16-bit results right 4 bits for the ADS1115
uint16_t valInRegister = readRegister(p_instance, m_i2cAddress, ADS1115_REG_POINTER_CONVERT);
return valInRegister >> m_bitShift;
}
void writeRegister(nrf_drv_twi_t const *const p_instance, uint8_t i2cAddress, uint8_t reg, uint16_t value) {
uint8_t tx_data[3];
uint32_t err_code;
tx_data[0] = (uint8_t)reg;
tx_data[1] = (uint8_t)(value >> 8);
tx_data[2] = (uint8_t)(value & 0xFF);
err_code = nrf_drv_twi_tx(p_instance, i2cAddress, tx_data, sizeof(tx_data), false);
APP_ERROR_CHECK(err_code);
}
uint16_t readRegister(nrf_drv_twi_t const *const p_instance, uint8_t i2cAddress, uint8_t reg) {
uint32_t err_code;
// TBD: err_code (error handling) should be indentical to all other nordic modules
err_code = nrf_drv_twi_tx(p_instance, i2cAddress, ®, sizeof(®), false);
APP_ERROR_CHECK(err_code);
err_code = nrf_drv_twi_rx(p_instance, i2cAddress, m_sample, 2);
APP_ERROR_CHECK(err_code);
m_adcValue = (m_sample[0] << 8 | m_sample[1]);
return m_adcValue;
}
So it seems to work fine using the writeRegister function, but when doing the readRegister function after that I get the error. Could there be a problem using two TX commands after each other or is there something else obvious that I am missing?
Let me know if I should provide any more code. If needed, I can try to get a hold of an oscilloscope to try and probe something.
Best regards,
Emil