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