Hi,
I am using an nrf52840 on a custom board with the 6.0 softdevice and 15.0 sdk. The I2C bus is running at 400khz.
I am reading 4 bytes on the i2c bus. The initial write to pass the register address takes about 90us for the bus to not be busy. The read takes about 6ms the first time and then subsequent times the time slowly grows to around 12plus milliseconds. I assume that I have stuffed up something in preparing the read.
Timing was done by toggling a GPIO pin high (GPIO_debug_on(true)) and low (GPIO_debug_on(false)) and then measuring the time with an CRO.
The I2C initilialisation:
void twim_init(void) {
static bool started = false;
if (!started) {
ret_code_t err_code;
nrfx_twim_config_t twi_config = NRFX_TWIM_DEFAULT_CONFIG;
twi_config.scl = TWI_SCL;
twi_config.sda = TWI_SDA;
err_code = nrfx_twim_init(&m_twim, &twi_config, twi_handler, NULL);
APP_ERROR_CHECK(err_code);
nrfx_twim_enable(&m_twim);
started = true;
}
}
The read code:
/** @brief low level read byte from a register
*** @param[in] chip_addr is the i2c accress of the chip
*** @param[in] reg is the register address
*** @param[out] data is a pointer to a buffer for the results
*** @param[in] count is size of buffer
*** @returns error code of the api read calls
*/
ret_code_t byte_read_multi_twi( uint8_t chip_addr, uint8_t reg, uint8_t *data, uint8_t count) {
ret_code_t err_code;
static rtc_mgt_t mgt;
startTimeout(&mgt, I2C_TIMEOUT);
// handle time out and busy
// prepare and write our reg on the bus that the chip will return the value in reg
err_code = wait_for_busy(&mgt);
if (err_code != NRF_SUCCESS) return err_code;
// write the reg we want to read to the wire and the contents will come back
err_code = nrfx_twim_tx(
&m_twim,
chip_addr,
®,
1,
false);
if (err_code != NRF_SUCCESS) {
// APP_ERROR_CHECK(err_code);
}
// prepare and read the data coming back. note that the state is changed in the handler on a successful write to idle
err_code = wait_for_busy(&mgt);
if (err_code != NRF_SUCCESS) {
// APP_ERROR_CHECK(err_code);
}
err_code = nrfx_twim_rx(
&m_twim,
chip_addr,
data,
count);
if (err_code != NRF_SUCCESS)
APP_ERROR_CHECK(err_code);
}
// wait for the stuff to come back
err_code = wait_for_busy(&mgt);
return err_code;
}
the wait for busy code that has the nrfx_twim_is_busy call
/** @brief waits for the i2c channel to be free while monitoring timeout
*** @param[in] mgt is the real time clock management structure for this timer
*** @returns bad transfer, timeout or success
*/
ret_code_t wait_for_busy(rtc_mgt_t *mgt) {
// while (nrfx_twim_is_busy(&m_twim) || !checkTimeoutExpired(mgt)) {
while (1) {
GPIO_debug_on(true);
if (!nrfx_twim_is_busy(&m_twim))
break;
GPIO_debug_on(false);
/*
if (checkTimeoutExpired(mgt))
break;*/
// yield();
}
Any help would be gratefully received
Cheers Paul