i2cspm.c

Go to the documentation of this file.
00001 /***************************************************************************/
00016 #include <stddef.h>
00017 #include "em_cmu.h"
00018 #include "em_gpio.h"
00019 #include "i2cspmconfig.h"
00020 #include "i2cspm.h"
00021 #include "em_assert.h"
00022 
00023 /*******************************************************************************
00024  **************************   GLOBAL FUNCTIONS   *******************************
00025  ******************************************************************************/
00026 
00027 /***************************************************************************/
00039 void I2CSPM_Init(I2CSPM_Init_TypeDef *init)
00040 {
00041   int i;
00042   CMU_Clock_TypeDef i2cClock;
00043   I2C_Init_TypeDef i2cInit;
00044 
00045   EFM_ASSERT(init != NULL);
00046 
00047   CMU_ClockEnable(cmuClock_HFPER, true);
00048 
00049   /* Select I2C peripheral clock */
00050   if (false)
00051   {
00052 #if defined( I2C0 )
00053   }
00054   else if (init->port == I2C0)
00055   {
00056     i2cClock = cmuClock_I2C0;
00057 #endif
00058 #if defined( I2C1 )
00059   }
00060   else if (init->port == I2C1)
00061   {
00062     i2cClock = cmuClock_I2C1;
00063 #endif
00064   }
00065   else
00066   {
00067     /* I2C clock is not defined */
00068     EFM_ASSERT(false);
00069     return;
00070   }
00071   CMU_ClockEnable(i2cClock, true);
00072 
00073   /* Output value must be set to 1 to not drive lines low. Set
00074      SCL first, to ensure it is high before changing SDA. */
00075   GPIO_PinModeSet(init->sclPort, init->sclPin, gpioModeWiredAndPullUp, 1);
00076   GPIO_PinModeSet(init->sdaPort, init->sdaPin, gpioModeWiredAndPullUp, 1);
00077 
00078   /* In some situations, after a reset during an I2C transfer, the slave
00079      device may be left in an unknown state. Send 9 clock pulses to
00080      set slave in a defined state. */
00081   for (i = 0; i < 9; i++)
00082   {
00083     GPIO_PinOutSet(init->sclPort, init->sclPin);
00084     GPIO_PinOutClear(init->sclPort, init->sclPin);
00085   }
00086 
00087   /* Enable pins and set location */
00088 #if defined (_I2C_ROUTEPEN_MASK)
00089   init->port->ROUTEPEN  = I2C_ROUTEPEN_SDAPEN | I2C_ROUTEPEN_SCLPEN;
00090   init->port->ROUTELOC0 = (init->portLocationSda << _I2C_ROUTELOC0_SDALOC_SHIFT)
00091     | (init->portLocationScl << _I2C_ROUTELOC0_SCLLOC_SHIFT);
00092 #else
00093   init->port->ROUTE = I2C_ROUTE_SDAPEN |
00094                       I2C_ROUTE_SCLPEN |
00095                       (init->portLocation << _I2C_ROUTE_LOCATION_SHIFT);
00096 #endif
00097 
00098   /* Set emlib init parameters */
00099   i2cInit.enable = true;
00100   i2cInit.master = true; /* master mode only */
00101   i2cInit.freq = init->i2cMaxFreq;
00102   i2cInit.refFreq = init->i2cRefFreq;
00103   i2cInit.clhr = init->i2cClhr;
00104 
00105   I2C_Init(init->port, &i2cInit);
00106 }
00107 
00108 
00109 /***************************************************************************/
00124 I2C_TransferReturn_TypeDef I2CSPM_Transfer(I2C_TypeDef *i2c, I2C_TransferSeq_TypeDef *seq)
00125 {
00126   I2C_TransferReturn_TypeDef ret;
00127   uint32_t timeout = I2CSPM_TRANSFER_TIMEOUT;
00128   /* Do a polled transfer */
00129   ret = I2C_TransferInit(i2c, seq);
00130   while (ret == i2cTransferInProgress && timeout--)
00131   {
00132     ret = I2C_Transfer(i2c);
00133   }
00134   return ret;
00135 }