This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

NACK from i2c slave

Hello Everyone,

          I am Using Nrf51822 module and s130_nrf51_2.0.1_softdevice . my actual function nrf51822 twi interface with stc3115 Gas gauge IC .read the battery voltage .i upload the twi_scanner . 

my output is TWI device detected at address 0x70  and then i read stc3115 id (address = 0x18 ) . i received err_code = 0x8021(Nack).

please help to correct my error

This is my code:

#include <stdio.h>
#include "boards.h"
#include "app_util_platform.h"
#include "app_error.h"
#include "nrf_drv_twi.h"
#include "stc3115_Driver.h"
#define NRF_LOG_MODULE_NAME "APP"
#include "nrf_delay.h"
#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_internal.h"
#include "SEGGER_RTT.h"
//#include "nrf_drv_timer.h"

/* TWI instance ID. */
#define TWI_INSTANCE_ID 0
#define DEBUG
/* Number of possible TWI addresses. */
#define TWI_ADDRESSES 127

/* TWI instance. */
static const nrf_drv_twi_t m_twi = NRF_DRV_TWI_INSTANCE(TWI_INSTANCE_ID);

static int GasGaugeTimerFinished(void);
static void Delay_ms(unsigned int value);
//void ChangeLowPowerMode(void);

#define TIMER_LIMIT 0x5000

/**
* @brief TWI initialization.
*/
void twi_init (void)
{
ret_code_t err_code;

const nrf_drv_twi_config_t twi_config = {
.scl = ARDUINO_SCL_PIN,   // pin 9
.sda = ARDUINO_SDA_PIN, // pin 8
.frequency = NRF_TWI_FREQ_100K,
.interrupt_priority = APP_IRQ_PRIORITY_HIGH,
.clear_bus_init = false
};

err_code = nrf_drv_twi_init(&m_twi, &twi_config,NULL, NULL);
APP_ERROR_CHECK(err_code);

nrf_drv_twi_enable(&m_twi);
}


/**
* @brief Function for main application entry.
*/
int main(void)
{
int res;
ret_code_t err_code;
uint8_t address;
uint8_t sample_data;
bool detected_device = false;
STC3115_ConfigData_TypeDef STC3115_ConfigData;
STC3115_BatteryData_TypeDef STC3115_BatteryData;
APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
// SEGGER_RTT_WriteString(0,"TWI scanner.\r\n");
nrf_drv_twi_uninit(&m_twi);
NRF_LOG_FLUSH();
twi_init();
int status;
volatile char GasGauge_HardwareShutDown = 0; //Optional: set to 1 when the user power down the hardware, and no need to monitor the battery
volatile char GasGauge_UnknowError = 0; //Optional: set to 1 by the application when unknow gas gauge error occurs
//volatile char GasGauge_ChangeLowPowerMode = 0; //Optional: set to 1 by the application when need to decrease the gas gauge power consumption (ie. switch to voltage mode only monitoring)
int CounterValue;
int i;
// nrf_drv_twi_uninit(&m_twi);

/* for (address = 1; address <= TWI_ADDRESSES; address++)
{
err_code = nrf_drv_twi_rx(&m_twi,address, &sample_data, sizeof(sample_data));

if (err_code == NRF_SUCCESS)
{
detected_device = true;
SEGGER_RTT_printf(0,"TWI device detected at address 0x%x.\r\n", address);
}
// NRF_LOG_FLUSH();
}*/

GasGauge_Restart:
SEGGER_RTT_WriteString(0,"STC3115 fuel gauge driver init ...\n");

//----------------------------------------------------------------------
//Check I2C is working and Fuel gauge device connected

status = STC3115_CheckI2cDeviceId();

SEGGER_RTT_printf(0, "status1:0x%x\n", status);

if (status != 0) //error
{
if(status == -1)
{
SEGGER_RTT_WriteString(0,"STC3115: I2C error\n");
#ifdef DEBUG
//wait to simulate the whole application restart
// while( GasGaugeTimerFinished() != 1);
nrf_delay_ms(1000);
goto GasGauge_Restart;
#endif
}
else if(status == -2)
SEGGER_RTT_WriteString(0,"STC3115: Wrong device detected\n");
else
SEGGER_RTT_WriteString(0,"STC3115: Unknown Hardware error\n");

return -1; //return on error
}


//----------------------------------------------------------------------
//Check Gasgauge is powered up & ready, and first measurement (V, I) is done (i.e. wait CounterValue is 3 or more)

for(i=0; i<20; i++) //check for 20*100ms = 2s
{
CounterValue = STC3115_GetRunningCounter();
if(CounterValue >= 3) //ok, device ready
{
break; //exit loop
}
else if(CounterValue < 0) //communication Error
{
SEGGER_RTT_WriteString(0,"STC3115: Error power up.\n");
goto GasGauge_Restart;
}
else
{
//wait
Delay_ms(100);
}
}

if(CounterValue < 3) //timeout, the devise has not started
{
SEGGER_RTT_WriteString(0,"STC3115: Error power up.\n");
//goto GasGauge_Restart;
}

//----------------------------------------------------------------------
//Call STC3115 driver init&start function
status = GasGauge_Initialization(&STC3115_ConfigData, &STC3115_BatteryData);
if(status!=0 && status!=-2)
{
SEGGER_RTT_WriteString(0,"STC3115: Error in GasGauge_Initialization\n");
return -1; //return on error
}


#ifdef DEBUG
//----------------------------------------------------------------------
//Check Gasgauge is running (also checked in GasGauge_Task)

for(i=0; i<20; i++)
{
CounterValue = STC3115_GetRunningCounter();

if(CounterValue > 3) //Gas gauge COUNTER stays at value '3' after power up or Soft Reset, if not running
{
break; //exit loop
}
else
{
//wait
Delay_ms(100);
}
}

if(CounterValue <= 3)
{
printf("STC3115: Error, GasGauge not running. Check your hardware.\n");
goto GasGauge_Restart;
}
#endif

//----------------------------------------------------------------------
while(1) //main infinite loop
{
if(GasGauge_HardwareShutDown == 1) //Completely shutdown the platform and the Gas gauge. (not recommended, it is better to let the Gas Gauge running connected to battery)
{
GasGauge_HardwareShutDown = 0;
status = GasGauge_Stop(); //stop the Gas gauge but keep its RAM content
if(status != 0)SEGGER_RTT_WriteString(0,"STC3115: Error in GasGauge_Stop\n");

#ifdef DEBUG
//wait to simulate the application is powered off for a couple of time
while( GasGaugeTimerFinished() != 1);
goto GasGauge_Restart;
#endif
return 0;
}
else if(GasGauge_UnknowError == 1)
{
GasGauge_UnknowError = 0;
status = GasGauge_Reset(); //Reset the Gasgauge without disconnecting the battery
if(status != 0) SEGGER_RTT_WriteString(0,"STC3115: Error in GasGauge_Reset\n");

goto GasGauge_Restart;
}
else //normal case
{
if(GasGaugeTimerFinished() == 1) //every 5s
{
/* if(GasGauge_ChangeLowPowerMode == 1) //switch between Voltage mode and Mixed mode
{
ChangeLowPowerMode();
GasGauge_ChangeLowPowerMode = 0;
}*/

//Call task function
status = GasGauge_Task(&STC3115_ConfigData, &STC3115_BatteryData); /* process gas gauge algorithm, returns results */

if (status > 0) //OK, new data available
{
/* printf("Battery: SoC=%i %%, Vbat=%i mV, I=%i mA, Cap=%i mAh, T=%i °C, Pres=%i ALM=%i , CCounter=%d, Time=%d s \r\n",
STC3115_BatteryData.SOC * 0.1,
STC3115_BatteryData.Voltage,
STC3115_BatteryData.Current,
STC3115_BatteryData.ChargeValue,
STC3115_BatteryData.Temperature,
STC3115_BatteryData.Presence,
STC3115_BatteryData.StatusWord >> 13,
STC3115_BatteryData.ConvCounter,
STC3115_BatteryData.ConvCounter * 0.5 //elapsed time since gas gauge started
);*/
SEGGER_RTT_printf(0,"Vbat=%i mV",STC3115_BatteryData.Voltage);
}
else if(status == 0) //only previous SOC, OCV and voltage are valid
{
/*printf("Battery: Previous_SoC=%i %%, Vbat=%i mV, OCV=%i mV, T=%i °C \r\n",
STC3115_BatteryData.SOC * 0.1,
STC3115_BatteryData.Voltage,
STC3115_BatteryData.OCV,
STC3115_BatteryData.Temperature);*/
SEGGER_RTT_printf(0,"Vbat=%i mV",STC3115_BatteryData.Voltage);
}
else if(status == -1) //error occured
{
if(STC3115_BatteryData.Presence == 0)
{ /* Battery disconnection has been detected */
SEGGER_RTT_WriteString(0,"STC3115 Error: Battery disconnected, or BATD pin level is over 1.61, or Vcc is below 2.7V \r\n");
}
else
{
printf("STC3115: I2C failure \r\n");
}
}
} // END Timer finished
else
{
//Do other Tasks here ...
}
} //END normal case
}//END loop

return 0;
}


/*void ChangeLowPowerMode(void)
{
static int mode = 0;
int status;

if(mode == 0)
{
mode = !mode;
status = STC3115_SetPowerSavingMode();
if(status != 0) printf("STC3115: Error in SetPowerSavingMode\n");
}
else
{
mode = !mode;
status = STC3115_StopPowerSavingMode();
if(status != 0) printf("STC3115: Error in StopPowerSavingMode\n");
}
}*/


static int GasGaugeTimerFinished(void)
{
//dummy implementation. Better use a Hardware Timer.

static unsigned int i = 1;

i--;
if( i == 0)
{
i = TIMER_LIMIT;
return 1;
}
else
{
return 0;
}
}


static void Delay_ms(unsigned int value)
{
//quick and dirty delay function implementation

unsigned int i,j;
volatile int dummy = 0;

for(i=0; i<value; i++)
{
for(j=0; j<2000; j++) //pseudo 1ms
{
// waste function, volatile makes sure it is not being optimized out by compiler
dummy++;
}
}
}


 

Parents Reply
  • Thank for your Reply Simonr

         I am also check the twi_handler. but i did not get any positive result . Received data return zero only. I also connect 4.7k resistor between nrf51822 and stc3115 i2c path.

    what is the exact problem in my scenario .How to handle my problem.

    If anyone know .please let me know

         err_code = nrf_drv_twi_init(&m_twi, &twi_lm75b_config, twi_handler, NULL);

Children
No Data
Related