Reply
Posts: 2
Registered: ‎10-09-2017

I2C Stuck at busy when talking to Si7021 on Blue Gecko starter kit

I am using the Blue Gecko starter kit with the BGM121 radio board plugged in and I am trying to communicate with the Si7021 on the starter board. When I enter the I2C_TransferInit function I hit this line of code:

  /* Check if in busy state. Since this SW assumes single master, we can */
  /* just issue an abort. The BUSY state is normal after a reset. */
  if (i2c->STATE & I2C_STATE_BUSY) {
    i2c->CMD = I2C_CMD_ABORT;
  }

And the communication is aborted. I'm not sure what I'm doing wrong, I believe I have the pins correct and I have followed a few different pieces of example code that are doing the same thing. My code is as follows:

 

#define SI7021_ADDRESS 0x80

typedef enum
{
	I2C_Write	= 0,
	I2C_Read	= 1
} I2C_RW;

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


	  I2C_Init_TypeDef i2cInit =
	  {
			  .clhr = i2cClockHLRAsymetric,
			  .enable = true,
			  .freq = I2C_FREQ_STANDARD_MAX,
			  .master = true,
			  .refFreq = 0

	  };

	  GPIO_PinModeSet(gpioPortD, 9, gpioModePushPull, 1);

	  /* Using PD15 (SDA) and PD14 (SCL) */
	  GPIO_PinModeSet(gpioPortC, 10, gpioModeWiredAndPullUpFilter, 1);
	  GPIO_PinModeSet(gpioPortC, 11, gpioModeWiredAndPullUpFilter, 1);


	  /* Enable pins */
	  I2C0->ROUTELOC0 = I2C_ROUTELOC0_SCLLOC_LOC15 | I2C_ROUTELOC0_SDALOC_LOC15;
	  I2C0->ROUTEPEN = I2C_ROUTEPEN_SCLPEN | I2C_ROUTEPEN_SDAPEN;

	  /* Initializing the I2C */
	  I2C_Init(I2C0, &i2cInit);


}

void SI7021_transfer(I2C_RW rw, uint8_t numBytes)
{
  /* Transfer structure */
  I2C_TransferSeq_TypeDef i2cTransfer;

  /* Initializing I2C transfer */
  i2cTransfer.addr          = SI7021_ADDRESS;
  i2cTransfer.flags         = rw;
  i2cTransfer.buf[0].data   = i2c_txBuffer;
  i2cTransfer.buf[0].len    = BUFFER_SIZE;
  i2cTransfer.buf[1].data   = i2c_rxBuffer;
  i2cTransfer.buf[1].len    = BUFFER_SIZE;
  I2C_TransferInit(I2C0, &i2cTransfer);

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

int32_t SI7021_get_temp(void)
{
	i2c_rxBuffer[0] = 0;
	i2c_rxBuffer[1] = 0;
	i2c_rxBuffer[2] = 0;
	i2c_rxBuffer[3] = 0;

	i2c_txBuffer[0] = 0xE3;
	i2c_txBuffer[1] = 0xE3;
	i2c_txBuffer[2] = 0xE3;
	i2c_txBuffer[3] = 0xE3;


	SI7021_transfer(I2C_Write, 1);
	I2C0->CMD = I2C_CMD_START;
	SI7021_transfer(I2C_Read, 2);
	//I2C0->CMD = I2C_CMD_STOP;
	return 0;
}

I would really appreciate any help or direction that you can give me.

Thanks,

Christian

Posts: 241
Registered: ‎07-27-2016

Re: I2C Stuck at busy when talking to Si7021 on Blue Gecko starter kit

Hi @ccasadio,

 

Can you confirm that the I2C has been initialized correctly in your code? Is there a statement to enable the HFPER clock anywhere?

 

CMU_ClockEnable(cmuClock_HFPER, true);

Which example(s) did you refer to for this source code? Do you see any I2C communication at all or does it abort the very first time?

 

Best,

 

Manasa

Posts: 2
Registered: ‎10-09-2017

Re: I2C Stuck at busy when talking to Si7021 on Blue Gecko starter kit

Hi Manasa,

I can confirm that the HFPER clock is enabled, and when I call I2C_Init the I2C0 ctrl register gets the following values set:

EN	0x1	I2C Enable	
CLHR	0x1 - ASYMMETRIC (The ratio between low period and high period counters (Nlow:Nhigh) is 6:3)	Clock Low High Ratio	

All other values in the control register are left zero and the clock div register (CLKDIV) gets set to:

CLKDIV	0x2C	Clock Division Register

The ROUTEPEN and ROUTELOC0 registers are as follows:

SDAPEN	0x1	SDA Pin Enable	
SCLPEN	0x1	SCL Pin Enable	
SDALOC	0xF - LOC15 (Location 15)	I/O Location	
SCLLOC	0xF - LOC15 (Location 15)	I/O Location	

The code goes straight to the abort when busy statement in the I2C_TransferInit function so it doesn't seem to make any progress at all with the transmission.

 

The examples that I referenced are mainly the AN0011: Master and Slave Operation, but to a lesser extent the Soc-Thermometer example and a few forum posts that I can't seem to refind.

 

Also before you ask I wanted to state that I am delaying 80 ms (not shown in the posted code) after giving power to the Si7021 via:

GPIO_PinModeSet(gpioPortD, 9, gpioModePushPull, 1);

so that it has time to power up.

 

Thanks for taking the time to look at this,
Christian 

Posts: 582
Registered: ‎09-18-2015

Re: I2C Stuck at busy when talking to Si7021 on Blue Gecko starter kit

Can you confirm that the I2C has been initialized correctly in your code? Is there a statement to enable the HFPER clock anywhere?

 

HFPERCLK is enabled by default on every Gecko device (Series 0 and Series 1) so far. Here's EFR32xG1:

 

AcroRd32_2017-10-10_08-36-18.png

 

John