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++; } } }