Reply
Posts: 31
Registered: ‎06-04-2017

BGM121: Default handler when executing I2C

Hi,

 

I am trying to send data from C8051F990 (8-bit MCU) to  BGM121 using I2C. The I2C_IRQHandler is never executed although it is defined. The code always goes to the 'default handler' in the 'startup' file. Here is the 'main' code:

/***********************************************************************************************//**
 * \file   main.c
 * \brief  Silicon Labs Thermometer Example Application
 *
 * This Thermometer and OTA example allows the user to measure temperature
 * using the temperature sensor on the WSTK. The values can be read with the
 * Health Thermometer reader on the Blue Gecko smartphone app.
 ***************************************************************************************************
 * <b> (C) Copyright 2016 Silicon Labs, http://www.silabs.com</b>
 ***************************************************************************************************
 * This file is licensed under the Silicon Labs License Agreement. See the file
 * "Silabs_License_Agreement.txt" for details. Before using this software for
 * any purpose, you must agree to the terms of that agreement.
 **************************************************************************************************/

#ifndef GENERATION_DONE
#error You must run generate first!
#endif

#define CORE_FREQUENCY              14000000
#define RTC_MIN_TIMEOUT                32000
#define I2C_ADDRESS                     0xE2
#define I2C_RXBUFFER_SIZE                20
#define I2C_TXBUFFER_SIZE                5
/* Board Headers */
#include "boards.h"
#include "ble-configuration.h"
#include "board_features.h"

/* Bluetooth stack headers */
#include "bg_types.h"
#include "native_gecko.h"
#include "aat.h"
#include "infrastructure.h"

/* GATT database */
#include "gatt_db.h"

/* EM library (EMlib) */
#include "em_system.h"

/* Libraries containing default Gecko configuration values */
#include "em_emu.h"
#include "em_cmu.h"
#include "em_chip.h"
#ifdef FEATURE_BOARD_DETECTED
#include "bspconfig.h"
#include "pti.h"
#else
#error This sample app only works with a Silicon Labs Board
#endif

#ifdef FEATURE_IOEXPANDER
#include "bsp.h"
#include "bsp_stk_ioexp.h"
#endif /* FEATURE_IOEXPANDER */ 


/* Device initialization header */
#include "InitDevice.h"

/* Temperature sensor and I2c*/
#include "i2cspmconfig.h"
#include "i2cspm.h"
#include "si7013.h"
#include "tempsens.h"

#ifdef FEATURE_SPI_FLASH
#include "em_usart.h"
#include "mx25flash_spi.h"
#endif /* FEATURE_SPI_FLASH */


/***********************************************************************************************//**
 * @addtogroup Application
 * @{
 **************************************************************************************************/

/***********************************************************************************************//**
 * @addtogroup app
 * @{
 **************************************************************************************************/

/* Gecko configuration parameters (see gecko_configuration.h) */
#ifndef MAX_CONNECTIONS
#define MAX_CONNECTIONS 4
#endif
uint8_t bluetooth_stack_heap[DEFAULT_BLUETOOTH_HEAP(MAX_CONNECTIONS)];

#ifdef FEATURE_PTI_SUPPORT
static const RADIO_PTIInit_t ptiInit = RADIO_PTI_INIT;
#endif

static const gecko_configuration_t config = {
  .config_flags=0,
  .sleep.flags=SLEEP_FLAGS_DEEP_SLEEP_ENABLE,
  .bluetooth.max_connections=MAX_CONNECTIONS,
  .bluetooth.heap=bluetooth_stack_heap,
  .bluetooth.heap_size=sizeof(bluetooth_stack_heap),
  .bluetooth.sleep_clock_accuracy = 100, // ppm
  .gattdb=&bg_gattdb_data,
  .ota.flags=0,
  .ota.device_name_len=3,
  .ota.device_name_ptr="OTA",
  #ifdef FEATURE_PTI_SUPPORT
  .pti = &ptiInit,
  #endif
};

uint8_t i2c_txBuffer[I2C_TXBUFFER_SIZE];
uint8_t i2c_rxBuffer[I2C_RXBUFFER_SIZE];
uint8_t i2c_rxBufferIndex;

// Transmission flags
volatile bool i2c_rxInProgress;
volatile bool i2c_startTx;


uint8_t cur_crc = 0;

void setupOscillators(void)
{
  /* Enabling clock to the I2C, GPIO, LE */
  CMU_ClockEnable(cmuClock_I2C0, true);
  CMU_ClockEnable(cmuClock_GPIO, true);
  CMU_ClockEnable(cmuClock_CORELE, true);

  // Enabling USART0 (see errata)
 // CMU_ClockEnable(cmuClock_USART0, true);

  /* Starting LFXO and waiting until it is stable */
  CMU_OscillatorEnable(cmuOsc_LFXO, true, true);

  /* Routing the LFXO clock to the RTC */
  CMU_ClockSelectSet(cmuClock_LFA,cmuSelect_LFXO);
  CMU_ClockEnable(1050208, true);
}



/**************************************************************************//**
 * @brief  enables I2C slave interrupts
 *****************************************************************************/
void enableI2cSlaveInterrupts(void){
  I2C_IntClear(I2C0, I2C_IEN_ADDR | I2C_IEN_RXDATAV | I2C_IEN_SSTOP);
  I2C_IntEnable(I2C0, I2C_IEN_ADDR | I2C_IEN_RXDATAV | I2C_IEN_SSTOP);
  NVIC_EnableIRQ(I2C0_IRQn);
 }

/**************************************************************************//**
 * @brief  disables I2C interrupts
 *****************************************************************************/
void disableI2cInterrupts(void){
  NVIC_DisableIRQ(I2C0_IRQn);
  I2C_IntDisable(I2C0, I2C_IEN_ADDR | I2C_IEN_RXDATAV | I2C_IEN_SSTOP);
  I2C_IntClear(I2C0, I2C_IEN_ADDR | I2C_IEN_RXDATAV | I2C_IEN_SSTOP);
}



/**************************************************************************//**
 * @brief  Setup I2C
 *****************************************************************************/
 #define I2C_ROUTEPEN_MASK
void setupI2C(void)
{
  // Using default settings
//  I2C_Init_TypeDef i2cInit = I2C_INIT_DEFAULT;

  /* Using PC10 (SCL) and PC11 (SDA) */
  GPIO_PinModeSet(gpioPortC, 10, gpioModeWiredAndPullUpFilter, 1);//i2c0_SCL#14
  GPIO_PinModeSet(gpioPortC, 11, gpioModeWiredAndPullUpFilter, 1);//i2c0_SDA#16

  I2C0->ROUTEPEN = I2C0->ROUTEPEN | I2C_ROUTEPEN_SCLPEN;
  	I2C0->ROUTELOC0 = (I2C0->ROUTELOC0 & (~_I2C_ROUTELOC0_SCLLOC_MASK))
  			| I2C_ROUTELOC0_SCLLOC_LOC14;
  	/* Set up SDA */
  	I2C0->ROUTEPEN = I2C0->ROUTEPEN | I2C_ROUTEPEN_SDAPEN;
  	I2C0->ROUTELOC0 = (I2C0->ROUTELOC0 & (~_I2C_ROUTELOC0_SDALOC_MASK))
  			| I2C_ROUTELOC0_SDALOC_LOC16;
  	// [I2C0 I/O setup]$

  	// $[I2C0 initialization]
  	I2C_Init_TypeDef init = I2C_INIT_DEFAULT;

  	init.enable = 1;
  	//init.master = 1;
  	init.master = 0;
  	init.freq = I2C_FREQ_STANDARD_MAX;
  	init.clhr = i2cClockHLRStandard;
  	I2C_Init(I2C0, &init);

  	I2C_SlaveAddressSet(I2C0,0xE2);

  /* Setting the status flags and index */
  i2c_rxInProgress = false;
  i2c_startTx = false;
  i2c_rxBufferIndex = 0;

  /* Setting up to enable slave mode */
  I2C0->SADDR = I2C_ADDRESS;
  I2C0->CTRL |= I2C_CTRL_SLAVE | I2C_CTRL_AUTOACK | I2C_CTRL_AUTOSN;

  enableI2cSlaveInterrupts();
}



/**************************************************************************//**
 * @brief  Receiving I2C data. Along with the I2C interrupt, it will keep the
  EFM32 in EM1 while the data is received.
 *****************************************************************************/
void receiveI2CData(void){
  while(i2c_rxInProgress){
   EMU_EnterEM1();
  }
}



/**************************************************************************//**
 * @brief  Transmitting I2C data. Will busy-wait until the transfer is complete.
 *****************************************************************************/
void performI2CTransfer(uint8_t data, uint8_t data_len)
{
  /* Transfer structure */
  I2C_TransferSeq_TypeDef i2cTransfer;

   /* Initializing I2C transfer */
  i2cTransfer.addr          = I2C_ADDRESS;
  i2cTransfer.flags         = I2C_FLAG_WRITE;
  i2cTransfer.buf[0].data   = data;
  i2cTransfer.buf[0].len    = data_len;
  i2cTransfer.buf[1].data   = i2c_rxBuffer;
  i2cTransfer.buf[1].len    = I2C_RXBUFFER_SIZE;
  I2C_TransferInit(I2C0, &i2cTransfer);

  /* Sending data */
  while (I2C_Transfer(I2C0) == i2cTransferInProgress){;}

   enableI2cSlaveInterrupts(); //after line number 186, the device returns back to slave
}


/* Flag for indicating DFU Reset must be performed */
uint8_t boot_to_dfu = 0;


/**
 * @brief Function for taking a single temperature measurement with the WSTK Relative Humidity and Temperature (RHT) sensor.
 */
void temperatureMeasure()
{

  uint8_t htmTempBuffer[5]; /* Stores the temperature data in the Health Thermometer (HTM) format. */
  uint8_t flags = 0x00;   /* HTM flags set as 0 for Celsius, no time stamp and no temperature type. */
  int32_t tempData;     /* Stores the Temperature data read from the RHT sensor. */
  uint32_t rhData = 0;    /* Dummy needed for storing Relative Humidity data. */
  uint32_t temperature;   /* Stores the temperature data read from the sensor in the correct format */
  uint8_t *p = htmTempBuffer; /* Pointer to HTM temperature buffer needed for converting values to bitstream. */

  /* Convert flags to bitstream and append them in the HTM temperature data buffer (htmTempBuffer) */
  UINT8_TO_BITSTREAM(p, flags);

  /* Sensor relative humidity and temperature measurement returns 0 on success, nonzero otherwise */
  if (Si7013_MeasureRHAndTemp(I2C0, SI7021_ADDR, &rhData, &tempData) == 0) {
    /* Convert sensor data to correct temperature format */
    temperature = FLT_TO_UINT32(tempData, -3);
    /* Convert temperature to bitstream and place it in the HTM temperature data buffer (htmTempBuffer) */
    UINT32_TO_BITSTREAM(p, temperature);
    /* Send indication of the temperature in htmTempBuffer to all "listening" clients.
     * This enables the Health Thermometer in the Blue Gecko app to display the temperature.
     *  0xFF as connection ID will send indications to all connections. */
    gecko_cmd_gatt_server_send_characteristic_notification(
      0xFF, gattdb_temp_measurement, 5, htmTempBuffer);
  }
}

/**
 * @brief  Main function
 */
void main(void)
{
  /* Initialize peripherals */
  CHIP_Init();

  setupOscillators();
 // enter_DefaultMode_from_RESET();


   /* Setting up i2c */
  setupI2C();
  EMU_DCDCInit_TypeDef dcdcInit = EMU_DCDCINIT_DEFAULT;
  EMU_DCDCInit(&dcdcInit); // Check; related to POR?


  /* Initialize the Temperature Sensor */
 // Si7013_Detect(I2C0, SI7021_ADDR, NULL);

  while (1)
  {
    /* Event pointer for handling events */
   // struct gecko_cmd_packet* evt;


if (i2c_rxInProgress)
    {
    	receiveI2CData();
    }
   else if (cur_crc)
   {
    	performI2CTransfer (cur_crc, sizeof(cur_crc));
	}
   }
}


void I2C0_IRQHandler(void)
{
  int status;

  status = I2C0->IF;

  if (status & I2C_IF_ADDR){      //IF reg has 3rd bit (2nd position) as ADDR bit; set to 1 if addr matches
    /* Address Match */
    /* Indicating that reception is started */
	i2c_rxInProgress = true;
    I2C0->RXDATA;    //Reads once to clear RXDATA buffer which currently contains start bit, slave address and 'write' bit

    I2C_IntClear(I2C0, I2C_IFC_ADDR); //clears address

  }
  else if (status & I2C_IF_RXDATAV)
  {
    /* Data received */
   //if (i2c_rxBufferIndex >= I2C_RXBUFFER_SIZE)
  // {
	   //write to flash
	 //  i2c_rxBufferIndex = 0;
   //}
	i2c_rxBuffer[i2c_rxBufferIndex] = I2C0->RXDATA;
    i2c_rxBufferIndex++;
    cur_crc= i2c_rxBuffer[i2c_rxBufferIndex-1];


    //if (i2c_rxBuffer[i2c_rxBufferIndex-1]==0xFF && i2c_rxBufferIndex >=2)
   // {
    	//cur_crc= i2c_rxBuffer[i2c_rxBufferIndex-2];
   // }
  }

  if(status & I2C_IEN_SSTOP){
    /* Stop received, reception is ended */
    I2C_IntClear(I2C0, I2C_IEN_SSTOP);
    i2c_rxInProgress = false;
    i2c_rxBufferIndex = 0;
  }
}

/** @} (end addtogroup app) */
/** @} (end addtogroup Application) */

 Can someone please help me.

 

Thank you.

Posts: 2,612
Registered: ‎08-25-2015

Re: BGM121: Default handler when executing I2C

Hi,

 

I moved this to the 32-bit MCU board where you can get better support on the peripherals.

 

Regards,

Tiago