#include <stdio.h>
#include "em_device.h"
#include "em_chip.h"
#include "em_i2c.h"
#include "em_cmu.h"
#include "em_emu.h"
#include "em_gpio.h"
#include "bsp.h"
// Buffers
uint8_t i2c_txBuffer[] = "Gecko";
uint8_t i2c_txBufferSize = sizeof(i2c_txBuffer);
uint8_t MS_Byte;
uint8_t LS_Byte;
uint8_t checksum;
int flag_2nd_step=0;
int flag_3rd_step=0;
/**************************************************************************//**
* @brief Starting oscillators and enabling clocks
*****************************************************************************/
void initCMU(void)
{
// Enabling clock to the I2C, GPIO, LE
CMU_ClockEnable(cmuClock_I2C0, true);
CMU_ClockEnable(cmuClock_GPIO, true);
CMU_ClockEnable(cmuClock_HFLE, true);
// Starting LFXO and waiting until it is stable
CMU_OscillatorEnable(cmuOsc_LFXO, true, true);
}
/**************************************************************************//**
* @brief Setup I2C
*****************************************************************************/
void initI2C(void)
{
// Using default settings
I2C_Init_TypeDef i2cInit = I2C_INIT_DEFAULT;
// Use ~400khz SCK
i2cInit.freq = I2C_FREQ_FAST_MAX;
// Using PC10 (SDA) and PC11 (SCL)
GPIO_PinModeSet(gpioPortC, 10, gpioModeWiredAndPullUp, 1);
GPIO_PinModeSet(gpioPortC, 11, gpioModeWiredAndPullUp, 1);
//Si7021 switch on
GPIO_PinModeSet(gpioPortD, 15, gpioModePushPull, 1);
// Enable pins at location 15 as specified in datasheet
I2C0->ROUTEPEN = I2C_ROUTEPEN_SDAPEN | I2C_ROUTEPEN_SCLPEN;
I2C0->ROUTELOC0 = (I2C0->ROUTELOC0 & (~_I2C_ROUTELOC0_SDALOC_MASK)) | I2C_ROUTELOC0_SDALOC_LOC15;
I2C0->ROUTELOC0 = (I2C0->ROUTELOC0 & (~_I2C_ROUTELOC0_SCLLOC_MASK)) | I2C_ROUTELOC0_SCLLOC_LOC15;
// Initializing the I2C
I2C_Init(I2C0, &i2cInit);
}
int main(void)
{
// Chip errata
CHIP_Init();
// Configuring clocks in the Clock Management Unit (CMU)
initCMU();
// Setting up i2c
initI2C();
while(1)
{
I2C0->CMD=I2C0->CMD|(1<<0); //step 1 start CMD
I2C0->TXDATA=((I2C0->TXDATA)&(0xFF00))|(0x80); //step 2 sending sensor address with 0 write bit
while(((I2C0->IF)&(1<<4))!=1){}//wait till command transfer ends TXBL flag
if (((I2C0->IF)&(1<<6))==1)//if we recieve ACK send measure and read command //3rd step
{
I2C0->TXDATA=((I2C0->TXDATA)&(0xFF00))|(0xE3); //step 4 in diagram
while(((I2C0->IF)&(1<<4))!=1){}//wait till command transfer ends TXBL flag
if (((I2C0->IF)&(1<<6))==1)//if we recieve ACK after Measure CMD
{
flag_2nd_step=1;
}
}
else //if we recieve NACK we send the previos command again
{
I2C0->TXDATA=((I2C0->TXDATA)&(0xFF00))|(0x80); //step 2 sending sensor adress with 0 write bit
while(((I2C0->IF)&(1<<4))!=1){}//wait till command transfer ends TXBL flag
flag_2nd_step=0;
}
if (flag_2nd_step==1) //step 3 second slave adress sending
{
I2C0->CMD=I2C0->CMD|(1<<0); //step 5 start CMD
I2C0->TXDATA=((I2C0->TXDATA)&(0xFF00))|(0x81); //step 6 sending sensor adress with 1 read bit
while(((I2C0->IF)&(1<<4))!=1){}//wait till command transfer ends TXBL flag
flag_3rd_step=1;
}
if (flag_3rd_step==1)
{
while (((I2C0->IF)&(1<<11))==1){} // step 7 while bushold flag in high and We still in clock streching
MS_Byte=I2C0->RXDATA; //step 8
while(((I2C0->IF)&(1<<5))==1){}//wait till recieving is complete RXDATAV will turn to 0
I2C0->CMD=I2C0->CMD|(1<<2); //send ACK to SLAVE
LS_Byte=I2C0->RXDATA; //step 9
while(((I2C0->IF)&(1<<5))==1){}//wait till recieving is complete RXDATAV will turn to 0
I2C0->CMD=I2C0->CMD|(1<<2); //send ACK to SLAVE
checksum=I2C0->RXDATA;//recieve Checksum byte
I2C0->CMD=I2C0->CMD|(1<<3); //send NACK to SLAVE
I2C0->CMD=I2C0->CMD|(1<<1); //send STOP to SLAVE
}//end step 3 end
}//end while
}//end main