I am using nrf51822, sdk version 11.0, sofdevice 130, i2c initialized in non-blocking mode. The read seems ok. The write is problematic for me.
I am using nrf51822, sdk version 11.0, sofdevice 130, i2c initialized in non-blocking mode. The read seems ok. The write is problematic for me.
Which I2C device are you trying to write to? You will have to look in the datasheet of the device you are interfacing to know how to perform a write operation.
Typically you put the register address and your data into a buffer and then transfers this to the device using a single nrf_drv_twi_tx() call. See for instance the function eeprom_write()
in TWIS Slave and TWI Master mode drivers Example in the SDK.
MPU56050. I try to write to register 0x1F value 0xFF.
I think Jorgen points to the best answer. For completeness below are some helper functions I have used to do write/read operations for the nrf twi interface.
//write byte to register
void write_byte(const nrf_drv_twi_t *twi_handle, uint8_t address, uint8_t sub_address, uint8_t *data, bool stop)
{
ret_code_t err_code;
uint8_t data_write[2];
data_write[0] = sub_address;
data_write[1] = *data;
err_code = nrf_drv_twi_tx(twi_handle, address, data_write, sizeof(data_write), stop);
APP_ERROR_CHECK(err_code);
}
//reading byte or bytes from register
void write_forread_byte(const nrf_drv_twi_t *twi_handle, uint8_t address, uint8_t sub_address)
{
ret_code_t err_code;
err_code = nrf_drv_twi_tx(twi_handle, address, &sub_address, sizeof(sub_address), true);
APP_ERROR_CHECK(err_code);
}
char read_byte(const nrf_drv_twi_t *twi_handle, uint8_t address, uint8_t sub_address)
{
ret_code_t err_code;
uint8_t data; // `data` will store the register data
write_forread_byte(twi_handle, address, sub_address);
err_code = nrf_drv_twi_rx(twi_handle, address, &data, sizeof(data));
APP_ERROR_CHECK(err_code);
return data;
}
void read_bytes(const nrf_drv_twi_t *twi_handle, uint8_t address, uint8_t sub_address, uint8_t * dest, uint8_t dest_count)
{
ret_code_t err_code;
write_forread_byte(twi_handle, address, sub_address);
err_code = nrf_drv_twi_rx(twi_handle, address, dest, dest_count);
APP_ERROR_CHECK(err_code);
}
I have done this:
uint8_t buffer[] = {0x1FU, 0xFFU};
nrf_drv_twi_tx(&twi_instance, slave_address, buffer, sizeof(buffer), false);
Hello Josh ! The read is ok, but the still doesn't work. Here is my complete code :
#include "app_util_platform.h" // APP_PRIORITY_HIGH
#include "i2c_interface.h"
#include "nrf_drv_twi.h"
#define SCL_PIN 8
#define SDA_PIN 10
static const nrf_drv_twi_t twi_instance = NRF_DRV_TWI_INSTANCE(0);
void init_i2c(){
nrf_drv_twi_config_t const config = {
.scl = SCL_PIN,
.sda = SDA_PIN,
.frequency = NRF_TWI_FREQ_100K,
.interrupt_priority = APP_IRQ_PRIORITY_HIGH
};
nrf_drv_twi_init(&twi_instance, &config, NULL, NULL);
nrf_drv_twi_enable(&twi_instance);
}
//write byte to register
void write_byte(const nrf_drv_twi_t *twi_handle, uint8_t address, uint8_t sub_address, uint8_t *data, bool stop){
ret_code_t err_code;
uint8_t data_write[2];
data_write[0] = sub_address;
data_write[1] = *data;
err_code = nrf_drv_twi_tx(twi_handle, address, data_write, sizeof(data_write), stop);
APP_ERROR_CHECK(err_code);
}
//reading byte or bytes from register
void write_forread_byte(const nrf_drv_twi_t *twi_handle, uint8_t address, uint8_t sub_address){
ret_code_t err_code;
err_code = nrf_drv_twi_tx(twi_handle, address, &sub_address, sizeof(sub_address), true);
APP_ERROR_CHECK(err_code);
}
char read_byte(const nrf_drv_twi_t *twi_handle, uint8_t address, uint8_t sub_address){
ret_code_t err_code;
uint8_t data; // `data` will store the register data
write_forread_byte(twi_handle, address, sub_address);
err_code = nrf_drv_twi_rx(twi_handle, address, &data, sizeof(data));
APP_ERROR_CHECK(err_code);
return data;
}
void read_bytes(const nrf_drv_twi_t *twi_handle, uint8_t address, uint8_t sub_address, uint8_t * dest, uint8_t dest_count){
ret_code_t err_code;
write_forread_byte(twi_handle, address, sub_address);
err_code = nrf_drv_twi_rx(twi_handle, address, dest, dest_count);
APP_ERROR_CHECK(err_code);
}
void i2c_write_byte(uint8_t address, uint8_t sub_address, uint8_t *data){
write_byte(&twi_instance, address, sub_address, data, false);
}
void i2c_read_byte(uint8_t address, uint8_t subaddress, uint8_t * data){
*data = read_byte(&twi_instance, address-1, subaddress);
}