Hello All,
I have been in the process of developing a product based on the nrf52810 microcontroller. So far I have created a custom board and BLE operational and advertising. The last thing I need to do is to establish a TWI connection with my accelerometer, which is the KXTJ3-1057 (https://www.digikey.ca/en/products/detail/kionix-inc/KXTJ3-1057/6573217). This has proved to be more difficult than I thought It would be. I have the nrfx drivers installed and referenced in the project, and have been having issue with those as well, however I now have a compiling project. Regardless, the nrf52810 does not send any signal though TWI, with the exception of what appears to be the start condition. I hooked up oscilloscope up to the sda and scl lines (mapped to pin 10 and 11) and observed that the voltage does in fact change once TWI init is called. The circut that connects the accelerometer sda and scl lines to pins 10 and 11 on the microcontroller consists of 2 5k pull up resitors connected to VDD, and then to the scl and sca lines. It appears as though it is starting to send the start condition, but does not send the slave address after in the nrf_drv_twi_tx() function. I do not have my oscilloscope on me at the moment, however I am happy to provide a recording of its observations soon if requested. I am relatively certain that I am following the correct start up procedure for the accelerometer as defined in the datasheet. In fact they have an arduino driver for the accelerometer so I pretty much just changed it over to work with the nrf drivers for TWI. I have also tried all possible combinations in the sdk_config file relating to which TWI driver is currently active, including nrfx_TWIM, TWI, and nrfx_TWI, as well as combination of the three. I don't really know where to go from here as I have been trying to debug this for about a week now. I will include my main code for attempting to connect the accelerometer. We are in a bit of a rush now to have this part of the project completed, so any help is greatly appreciated. I also ran the twi_scanner example and it only detects a device at 0x01, which doesn’t make a lot of sense.
Thank you!
M
#include <stdio.h>
#include "boards.h"
#include "app_util_platform.h"
#include "app_error.h"
#include "nrf_drv_twi.h"
#include "nrf_delay.h"
#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"
#define TWI_INSTANCE_ID 0
#define TWI_ADDRESSES 127
//---ACC Addresses---
#define KXTJ3_COMM_OK (0)
#define KXTJ3_COMM_ERROR (-1)
#define KXTJ3_WAI_ERROR (-2)
#define KXTJ3_PARAM_ERROR (-3)
#define KXTJ3_DEVICE_ADDRESS (0x0E)
#define KXTJ3_XOUT_L (0x06)
#define KXTJ3_WHO_AM_I (0x0F)
#define KXTJ3_CNTL1 (0x1B)
#define KXTJ3_DATA_CNTL (0x21)
#define KXTJ3_WAI_VAL (0x35)
#define KXTJ3_CNTL1_WUFE (1 << 1)
#define KXTJ3_CNTL1_TDTE (1 << 2)
#define KXTJ3_CNTL1_EN16GMASK (0x04)
#define KXTJ3_CNTL1_GSEL_16G (0x04)
#define KXTJ3_CNTL1_GSELMASK (0x18)
#define KXTJ3_CNTL1_GSEL_14BIT (0x18)
#define KXTJ3_CNTL1_GSEL_2G (0x00)
#define KXTJ3_CNTL1_GSEL_4G (0x08)
#define KXTJ3_CNTL1_GSEL_8G (0x10)
#define KXTJ3_CNTL1_DRDYE (1 << 5)
#define KXTJ3_CNTL1_RES (1 << 6)
#define KXTJ3_CNTL1_LOWPOWER (0x00)
#define KXTJ3_CNTL1_HIGHRESO (0x40)
#define KXTJ3_CNTL1_PC1 (1 << 7)
#define KXTJ3_DATA_CNTL_OSA_50HZ (2)
#define KXTJ3_CNTL1_VAL (KXTJ3_CNTL1_LOWPOWER | KXTJ3_CNTL1_GSEL_2G)
#define KXTJ3_DATA_CNTL_VAL (KXTJ3_DATA_CNTL_OSA_50HZ)
#define KXTJ3_DRIVER_VERSION ("1.0\n")
#define KXTJ3_GSENS_2G (2)
#define KXTJ3_GSENS_4G (4)
#define KXTJ3_GSENS_8G (8)
#define KXTJ3_GSENS_16G (16)
#define KXTJ3_GSENS_ERROR (0xFF)
#define KXTJ3_READ_DATA_SIZE (6)
#define KXTJ3_AXIS_SIZE (KXTJ3_READ_DATA_SIZE / 2)
#define KXTJ3_DIVIDE_SHIFT (15)
//-------------------
//---ACC Variables---
uint8_t Address;
uint8_t RegCtlVal;
int32_t GDivide;
//-------------------
static const nrf_drv_twi_t m_twi = NRF_DRV_TWI_INSTANCE(TWI_INSTANCE_ID);
static volatile bool m_xfer_done = false;
void twi_handler(nrf_drv_twi_evt_t const * p_event, void * p_context)
{
switch (p_event->type)
{
case NRF_DRV_TWI_EVT_DONE:
if (p_event->xfer_desc.type == NRF_DRV_TWI_XFER_RX)
{
}
m_xfer_done = true;
break;
case NRF_DRV_TWI_EVT_ADDRESS_NACK:
m_xfer_done = false;
NRF_LOG_INFO("NACK");
break;
default:
break;
}
}
//.scl = 11,
//.sda = 10,
void twi_init (void)
{
ret_code_t err_code;
const nrf_drv_twi_config_t twi_vnet_config = {
.scl = NRF_GPIO_PIN_MAP(0,14),
.sda = NRF_GPIO_PIN_MAP(0,12),
.frequency = NRF_DRV_TWI_FREQ_100K,
.interrupt_priority = APP_IRQ_PRIORITY_HIGH,
.clear_bus_init = true
};
err_code = nrf_drv_twi_init(&m_twi, &twi_vnet_config, twi_handler, NULL);
APP_ERROR_CHECK(err_code);
nrf_drv_twi_enable(&m_twi);
}
int32_t KXTJ3_init(void)
{
int32_t result;
int8_t control1 = 0;
result = KXTJ3_init_IC_set(&control1);
if (result = KXTJ3_COMM_OK){
result = init_setting_gval(control1);
}
return (result);
}
int32_t KXTJ3_start(void)
{
int32_t result;
uint8_t val;
val = RegCtlVal | KXTJ3_CNTL1_PC1;
result = nrf_drv_twi_tx(&m_twi, KXTJ3_CNTL1, &val, sizeof(val), true);
return (result);
}
int32_t KXTJ3_get_val(uint8_t *data)
{
int32_t result;
result = nrf_drv_twi_rx(&m_twi, KXTJ3_XOUT_L, data, KXTJ3_READ_DATA_SIZE);
if (result == NRF_SUCCESS){
result = KXTJ3_COMM_OK;
}
return (result);
}
int32_t KXTJ3_init_setting_gval(uint8_t control1)
{
int32_t result;
int32_t gsense;
uint8_t res, gsel, en16g;
RegCtlVal = control1;
res = control1 & KXTJ3_CNTL1_RES;
gsel = control1 & KXTJ3_CNTL1_GSELMASK;
en16g = control1 & KXTJ3_CNTL1_EN16GMASK;
if ((res == KXTJ3_CNTL1_LOWPOWER) && (gsel == KXTJ3_CNTL1_GSEL_14BIT)) {
result = KXTJ3_PARAM_ERROR;
} else {
if (en16g == KXTJ3_CNTL1_GSEL_16G) {
gsense = KXTJ3_GSENS_16G;
} else {
switch (gsel) {
case KXTJ3_CNTL1_GSEL_2G:
gsense = KXTJ3_GSENS_2G;
break;
case KXTJ3_CNTL1_GSEL_4G:
gsense = KXTJ3_GSENS_4G;
break;
default:
gsense = KXTJ3_GSENS_8G;
break;
}
}
GDivide = ((int32_t)1 << KXTJ3_DIVIDE_SHIFT) / gsense;
result = KXTJ3_COMM_OK;
}
return (result);
}
int32_t KXTJ3_init_IC_set(uint8_t *control1)
{
int32_t result;
uint8_t val;
result = nrf_drv_twi_rx(&m_twi, KXTJ3_WHO_AM_I, &val, sizeof(val));
nrf_delay_ms(100);
if (result == NRF_SUCCESS) {
if (val == KXTJ3_WAI_VAL) {
val = KXTJ3_CNTL1_VAL;
(void)nrf_drv_twi_tx(&m_twi, KXTJ3_CNTL1, &val, sizeof(val), true);
nrf_delay_ms(100);
val = KXTJ3_DATA_CNTL_VAL;
(void)nrf_drv_twi_tx(&m_twi, KXTJ3_DATA_CNTL, &val, sizeof(val), true);
nrf_delay_ms(100);
(void)nrf_drv_twi_rx(&m_twi, KXTJ3_CNTL1, &val, sizeof(val));
nrf_delay_ms(100);
*control1 = val;
NRF_LOG_INFO("Init Success");
}
else{
result = KXTJ3_WAI_ERROR;
NRF_LOG_INFO("Init Fail");
}
}
return (result);
}
//This function is me trying to test sending the slave address first
void KXTJ3_IC_set2(uint8_t *control1){
int32_t result;
int8_t val;
nrf_drv_twi_tx(&m_twi, KXTJ3_DEVICE_ADDRESS, 0, sizeof(KXTJ3_DEVICE_ADDRESS+1), true);
//while(m_xfer_done == false);
val = KXTJ3_CNTL1_VAL;
nrf_drv_twi_tx(&m_twi, KXTJ3_CNTL1, &val, sizeof(val), true);
//while(m_xfer_done == false);
//nrf_delay_ms(100);
val = KXTJ3_DATA_CNTL_VAL;
nrf_drv_twi_tx(&m_twi, KXTJ3_DATA_CNTL, &val, sizeof(val), true);
//while(m_xfer_done == false);
//nrf_delay_ms(100);
nrf_drv_twi_rx(&m_twi, KXTJ3_CNTL1, &val, sizeof(val));
//while(m_xfer_done == false);
//nrf_delay_ms(100);
return;
}
void KXTJ3_setup(void){
int32_t result;
result = KXTJ3_init();
if (result == KXTJ3_COMM_OK){
(void)KXTJ3_start();
}
else{
NRF_LOG_INFO("An Error has occured");
}
}
int main(void)
{
nrf_delay_ms(2000);
APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
NRF_LOG_DEFAULT_BACKENDS_INIT();
NRF_LOG_INFO("\r\nTWI sensor example started.");
NRF_LOG_FLUSH();
twi_init();
nrf_delay_ms(100);
KXTJ3_setup();
nrf_delay_ms(100);
while(true)
{
int32_t result;
float acc[KXTJ3_AXIS_SIZE];
//NRF_LOG_INFO(NRF_LOG_FLOAT_MARKER "\r\n", NRF_LOG_FLOAT(acc[2]));
result = KXTJ3_get_val(acc);
if (result == KXTJ3_COMM_OK){
NRF_LOG_INFO("---X---");
NRF_LOG_INFO(NRF_LOG_FLOAT_MARKER "\r\n", NRF_LOG_FLOAT(acc[0]));
NRF_LOG_INFO("---Y---");
NRF_LOG_INFO(NRF_LOG_FLOAT_MARKER "\r\n", NRF_LOG_FLOAT(acc[1]));
NRF_LOG_INFO("---Z---");
NRF_LOG_INFO(NRF_LOG_FLOAT_MARKER "\r\n", NRF_LOG_FLOAT(acc[2]));
NRF_LOG_INFO("-------");
}
else{
NRF_LOG_INFO("Comms Error");
}
NRF_LOG_FLUSH();
nrf_delay_ms(1000);
}
}