Hi,
I' m trying to create a TMIM easydma sequence to same an ADC. The sequence involves a write, and timer delay and a read.
Given what I'm trying to achieve, I think I need to perform a write, without stopping the transaction.
I'm having problems getting the i2c write without stopping the transaction to work. My code is shown below:
void i2c_write(uint8_t addr, uint8_t data, bool noStop)
{
uint8_t tx_buf[2];
if (noStop == false)
NRF_TWIM0->SHORTS = TWIM_SHORTS_LASTTX_STOP_Msk;
tx_buf[0] = data;
NRF_TWIM0->TXD.MAXCNT = 1;
NRF_TWIM0->TXD.PTR = (uint32_t)&tx_buf[0];
NRF_TWIM0->EVENTS_STOPPED = 0;
NRF_TWIM0->TASKS_STARTTX = 1;
while (NRF_TWIM0->EVENTS_STOPPED == 0);
}
uint8_t i2c_read(uint8_t addr, uint8_t *data)
{
volatile uint8_t rx_buf[4];
NRF_TWIM0->SHORTS = TWIM_SHORTS_LASTTX_STARTRX_Msk | TWIM_SHORTS_LASTRX_STOP_Msk;
NRF_TWIM0->RXD.MAXCNT = 4;
NRF_TWIM0->RXD.PTR = (uint32_t)rx_buf;
NRF_TWIM0->EVENTS_STOPPED = 0;
NRF_TWIM0->TASKS_STARTRX = 1;
while (NRF_TWIM0->EVENTS_STOPPED == 0);
NRF_LOG_INFO("val: %X:%X:%X:%X\r\n", rx_buf[0], rx_buf[1], rx_buf[2], rx_buf[3]);
data[0] = rx_buf[0];
data[1] = rx_buf[1];
data[2] = rx_buf[2];
data[3] = rx_buf[3];
return 0;
}
void simple_test(void) {
volatile uint8_t data[4];
NRF_LOG_INFO("in simple_test\r\n");
NRF_LOG_FLUSH();
i2c_write(0x68, 0x88, true); //convert
nrf_delay_us(66667);
NRF_LOG_INFO("in simple_test: conv\r\n");
NRF_LOG_FLUSH();
i2c_read(0x68, data);
NRF_LOG_INFO("val: %X:%X:%X:%X\r\n", data[0], data[1], data[2], data[3]);
}
The code shown above hangs.
If I rmake the i2c_write stop, then the code no longer hangs, but does not perform the
write successfully, and the read just reads whatever is in the adc register.
If I change the highlighted write to use:
nrf_drv_twi_tx in the form of:
ret_code_t i2c_write_block(uint8_t i2cInstIdx, uint8_t address,uint8_t const *cmd, uint8_t cmd_length)
{
ret_code_t err_code;
switch (i2cInstIdx)
{
case I2C_INST_00:
err_code = nrf_drv_twi_tx(&twi_instance_00, address, cmd, cmd_length, false);
APP_ERROR_CHECK(err_code);
break;
case I2C_INST_01:
err_code = nrf_drv_twi_tx(&twi_instance_01, address, cmd, cmd_length, false);
APP_ERROR_CHECK(err_code);
break;
default:
NRF_LOG_WARNING("DRV:i2C: Bad inst idx : %d \r\n", i2cInstIdx);
break;
}
return err_code;
}
void simple_mixed_test(void) {
volatile uint8_t data[4];
ret_code_t err_code;
uint8_t instIdx = I2C_INST_00;
uint8_t init_cmd[2] = {0x0, 0x0};
uint8_t address = 0x68;
NRF_LOG_INFO("in simple_mixed_test\r\n");
NRF_LOG_FLUSH();
i2c_init_block(I2C_INST_00);
init_cmd[0] = 0x88;
err_code = i2c_write_block(instIdx, address, init_cmd, 1);
//i2c_write(0x68, 0x88, true); //convert
nrf_delay_us(66667);
i2c_read(0x68, data);
NRF_LOG_INFO("val: %X:%X:%X:%X\r\n", data[0], data[1], data[2], data[3]);
}
Then it all works fine.
Please can you advise!