#include #include "efm32.h" #include "efm32_chip.h" #include "efm32_i2c.h" #include "efm32_rtc.h" #include "efm32_cmu.h" #include "efm32_emu.h" #include "efm32_gpio.h" #include "mag3110.h" #include "i2c.h" #include "main_program.h" /**************************************************************************//** * @brief Setup I2C *****************************************************************************/ void setupI2C(void) { // Using default settings I2C_Init_TypeDef i2cInit = I2C_INIT_DEFAULT; /* Enable GPIO clock */ CMU->HFPERCLKEN0 |= CMU_HFPERCLKEN0_GPIO; /* Using PA0 (SDA) and PA1 (SCL) */ GPIO_PinModeSet(gpioPortA, 1, gpioModeWiredAndPullUpFilter, 1); GPIO_PinModeSet(gpioPortA, 0, gpioModeWiredAndPullUpFilter, 1); /* Enable clock for I2C0 */ CMU->HFPERCLKEN0 |= CMU_HFPERCLKEN0_I2C0; /* Enable pins at location 1 */ I2C0->ROUTE = I2C_ROUTE_SDAPEN | I2C_ROUTE_SCLPEN; /* Initializing the I2C */ I2C_Init(I2C0, &i2cInit); } /***************************************************************************//** * @brief * Perform I2C transfer. * * @details * This driver only supports master mode, single bus-master. It does not * return until the transfer is complete, polling for completion. * * @param[in] seq * Pointer to sequence structure defining the I2C transfer to take place. The * referenced structure must exist until the transfer has fully completed. ******************************************************************************/ I2C_TransferReturn_TypeDef I2CDRV_Transfer(I2C_TransferSeq_TypeDef *seq) { I2C_TransferReturn_TypeDef ret; /* Do a polled transfer */ ret = I2C_TransferInit(I2C0, seq); while (ret == i2cTransferInProgress) { ret = I2C_Transfer(I2C0); } return(ret); } /***************************************************************************//** * @brief * Read sensor register content. * @param[in] i2c * Pointer to I2C peripheral register block. * * @param[in] addr * I2C address for the sensor, in 8 bit format, where LSB is reserved for R/W bit. * * @param[in] reg * Register to read. * * @param[out] val * Reference to place register read. * * @return * Returns 0 if register read, <0 if unable to read register. ******************************************************************************/ int I2C_Read_reg(I2C_TypeDef *i2c, uint8_t addr, uint16_t reg, uint16_t *val) { I2C_TransferSeq_TypeDef seq; I2C_TransferReturn_TypeDef ret; uint8_t regid[1]; uint8_t data[2]; seq.addr = addr; seq.flags = I2C_FLAG_WRITE_READ; /* Select register to be read */ regid[0] = ((uint8_t)reg); seq.buf[0].data = regid; seq.buf[0].len = 1; /* Select location/length to place register */ /* Only 1 byte reg, clear upper 8 bits */ data[0] = 0; seq.buf[1].data = data + 1; seq.buf[1].len = 1; ret = I2CDRV_Transfer(&seq); if (ret != i2cTransferDone) { return((int)ret); } *val = (((uint16_t)(data[0])) << 8) | data[1]; return(0); } /***************************************************************************//** * @brief * Write to sensor register. * * @param[in] i2c * Pointer to I2C peripheral register block. * * @param[in] addr * I2C address for the sensor, in 8 bit format, where LSB is reserved * for R/W bit. * * @param[in] reg * Register to write. * * @param[in] val * Value used when writing to register. * * @return * Returns 0 if register written, <0 if unable to write to register. ******************************************************************************/ int I2C_Write_reg(I2C_TypeDef *i2c, uint8_t addr, uint16_t reg, uint16_t val) { I2C_TransferSeq_TypeDef seq; I2C_TransferReturn_TypeDef ret; uint8_t data[3]; seq.addr = addr; seq.flags = I2C_FLAG_WRITE; /* Select register to be written */ data[0] = ((uint8_t)reg) ; seq.buf[0].data = data; /* Only 1 byte reg */ data[1] = (uint8_t)val; seq.buf[0].len = 2; ret = I2CDRV_Transfer(&seq); if (ret != i2cTransferDone) { return((int)ret); } return(ret); }