Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: hello SerialTestv11 SerialTestv12 Sierpinski ... more
Diff: TARGET_EFM32LG_STK3600/TOOLCHAIN_ARM_STD/em_i2c.h
- Revision:
- 171:3a7713b1edbc
- Parent:
- 160:5571c4ff569f
diff -r e95d10626187 -r 3a7713b1edbc TARGET_EFM32LG_STK3600/TOOLCHAIN_ARM_STD/em_i2c.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/TARGET_EFM32LG_STK3600/TOOLCHAIN_ARM_STD/em_i2c.h Thu Nov 08 11:45:42 2018 +0000
@@ -0,0 +1,515 @@
+/***************************************************************************//**
+ * @file em_i2c.h
+ * @brief Inter-intergrated circuit (I2C) peripheral API
+ * @version 5.3.3
+ *******************************************************************************
+ * # License
+ * <b>Copyright 2016 Silicon Laboratories, Inc. http://www.silabs.com</b>
+ *******************************************************************************
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
+ * obligation to support this Software. Silicon Labs is providing the
+ * Software "AS IS", with no express or implied warranties of any kind,
+ * including, but not limited to, any implied warranties of merchantability
+ * or fitness for any particular purpose or warranties against infringement
+ * of any proprietary rights of a third party.
+ *
+ * Silicon Labs will not be liable for any consequential, incidental, or
+ * special damages, or any other relief, or for any claim by any third party,
+ * arising from your use of this Software.
+ *
+ ******************************************************************************/
+
+#ifndef EM_I2C_H
+#define EM_I2C_H
+
+#include "em_device.h"
+#if defined(I2C_COUNT) && (I2C_COUNT > 0)
+
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***************************************************************************//**
+ * @addtogroup emlib
+ * @{
+ ******************************************************************************/
+
+/***************************************************************************//**
+ * @addtogroup I2C
+ * @{
+ ******************************************************************************/
+
+/*******************************************************************************
+ ******************************* DEFINES ***********************************
+ ******************************************************************************/
+
+/**
+ * @brief
+ * Standard mode max frequency assuming using 4:4 ratio for Nlow:Nhigh.
+ * @details
+ * From I2C specification: Min Tlow = 4.7us, min Thigh = 4.0us,
+ * max Trise=1.0us, max Tfall=0.3us. Since ratio is 4:4, have to use
+ * worst case value of Tlow or Thigh as base.
+ *
+ * 1/(Tlow + Thigh + 1us + 0.3us) = 1/(4.7 + 4.7 + 1.3)us = 93458Hz
+ * @note
+ * Due to chip characteristics, the max value is somewhat reduced.
+ */
+#if defined(_SILICON_LABS_32B_SERIES_0) \
+ && (defined(_EFM32_GECKO_FAMILY) \
+ || defined(_EFM32_TINY_FAMILY) \
+ || defined(_EFM32_ZERO_FAMILY) \
+ || defined(_EFM32_HAPPY_FAMILY))
+#define I2C_FREQ_STANDARD_MAX 93000
+#elif defined(_SILICON_LABS_32B_SERIES_0) \
+ && (defined(_EFM32_GIANT_FAMILY) \
+ || defined(_EFM32_WONDER_FAMILY))
+#define I2C_FREQ_STANDARD_MAX 92000
+#elif defined(_SILICON_LABS_32B_SERIES_1)
+// None of the chips on this platform has been characterized on this parameter.
+// Use same value as on Wonder until further notice.
+#define I2C_FREQ_STANDARD_MAX 92000
+#else
+#error "Unknown device family."
+#endif
+
+/**
+ * @brief
+ * Fast mode max frequency assuming using 6:3 ratio for Nlow:Nhigh.
+ * @details
+ * From I2C specification: Min Tlow = 1.3us, min Thigh = 0.6us,
+ * max Trise=0.3us, max Tfall=0.3us. Since ratio is 6:3, have to use
+ * worst case value of Tlow or 2xThigh as base.
+ *
+ * 1/(Tlow + Thigh + 0.3us + 0.3us) = 1/(1.3 + 0.65 + 0.6)us = 392157Hz
+ */
+#define I2C_FREQ_FAST_MAX 392157
+
+/**
+ * @brief
+ * Fast mode+ max frequency assuming using 11:6 ratio for Nlow:Nhigh.
+ * @details
+ * From I2C specification: Min Tlow = 0.5us, min Thigh = 0.26us,
+ * max Trise=0.12us, max Tfall=0.12us. Since ratio is 11:6, have to use
+ * worst case value of Tlow or (11/6)xThigh as base.
+ *
+ * 1/(Tlow + Thigh + 0.12us + 0.12us) = 1/(0.5 + 0.273 + 0.24)us = 987167Hz
+ */
+#define I2C_FREQ_FASTPLUS_MAX 987167
+
+/**
+ * @brief
+ * Indicate plain write sequence: S+ADDR(W)+DATA0+P.
+ * @details
+ * @li S - Start
+ * @li ADDR(W) - address with W/R bit cleared
+ * @li DATA0 - Data taken from buffer with index 0
+ * @li P - Stop
+ */
+#define I2C_FLAG_WRITE 0x0001
+
+/**
+ * @brief
+ * Indicate plain read sequence: S+ADDR(R)+DATA0+P.
+ * @details
+ * @li S - Start
+ * @li ADDR(R) - address with W/R bit set
+ * @li DATA0 - Data read into buffer with index 0
+ * @li P - Stop
+ */
+#define I2C_FLAG_READ 0x0002
+
+/**
+ * @brief
+ * Indicate combined write/read sequence: S+ADDR(W)+DATA0+Sr+ADDR(R)+DATA1+P.
+ * @details
+ * @li S - Start
+ * @li Sr - Repeated start
+ * @li ADDR(W) - address with W/R bit cleared
+ * @li ADDR(R) - address with W/R bit set
+ * @li DATAn - Data written from/read into buffer with index n
+ * @li P - Stop
+ */
+#define I2C_FLAG_WRITE_READ 0x0004
+
+/**
+ * @brief
+ * Indicate write sequence using two buffers: S+ADDR(W)+DATA0+DATA1+P.
+ * @details
+ * @li S - Start
+ * @li ADDR(W) - address with W/R bit cleared
+ * @li DATAn - Data written from buffer with index n
+ * @li P - Stop
+ */
+#define I2C_FLAG_WRITE_WRITE 0x0008
+
+/** Use 10 bit address. */
+#define I2C_FLAG_10BIT_ADDR 0x0010
+
+/*******************************************************************************
+ ******************************** ENUMS ************************************
+ ******************************************************************************/
+
+/** Clock low to high ratio settings. */
+typedef enum {
+ i2cClockHLRStandard = _I2C_CTRL_CLHR_STANDARD, /**< Ratio is 4:4 */
+ i2cClockHLRAsymetric = _I2C_CTRL_CLHR_ASYMMETRIC, /**< Ratio is 6:3 */
+ i2cClockHLRFast = _I2C_CTRL_CLHR_FAST /**< Ratio is 11:3 */
+} I2C_ClockHLR_TypeDef;
+
+/** Return codes for single master mode transfer function. */
+typedef enum {
+ /* In progress code (>0) */
+ i2cTransferInProgress = 1, /**< Transfer in progress. */
+
+ /* Complete code (=0) */
+ i2cTransferDone = 0, /**< Transfer completed successfully. */
+
+ /* Transfer error codes (<0) */
+ i2cTransferNack = -1, /**< NACK received during transfer. */
+ i2cTransferBusErr = -2, /**< Bus error during transfer (misplaced START/STOP). */
+ i2cTransferArbLost = -3, /**< Arbitration lost during transfer. */
+ i2cTransferUsageFault = -4, /**< Usage fault. */
+ i2cTransferSwFault = -5 /**< SW fault. */
+} I2C_TransferReturn_TypeDef;
+
+/*******************************************************************************
+ ******************************* STRUCTS ***********************************
+ ******************************************************************************/
+
+/** I2C initialization structure. */
+typedef struct {
+ /** Enable I2C peripheral when init completed. */
+ bool enable;
+
+ /** Set to master (true) or slave (false) mode */
+ bool master;
+
+ /**
+ * I2C reference clock assumed when configuring bus frequency setup.
+ * Set it to 0 if currently configurated reference clock shall be used
+ * This parameter is only applicable if operating in master mode.
+ */
+ uint32_t refFreq;
+
+ /**
+ * (Max) I2C bus frequency to use. This parameter is only applicable
+ * if operating in master mode.
+ */
+ uint32_t freq;
+
+ /** Clock low/high ratio control. */
+ I2C_ClockHLR_TypeDef clhr;
+} I2C_Init_TypeDef;
+
+/** Suggested default config for I2C init structure. */
+#define I2C_INIT_DEFAULT \
+ { \
+ true, /* Enable when init done */ \
+ true, /* Set to master mode */ \
+ 0, /* Use currently configured reference clock */ \
+ I2C_FREQ_STANDARD_MAX, /* Set to standard rate assuring being */ \
+ /* within I2C spec */ \
+ i2cClockHLRStandard /* Set to use 4:4 low/high duty cycle */ \
+ }
+
+/**
+ * @brief
+ * Master mode transfer message structure used to define a complete
+ * I2C transfer sequence (from start to stop).
+ * @details
+ * The structure allows for defining the following types of sequences,
+ * please refer to defines for sequence details.
+ * @li #I2C_FLAG_READ - data read into buf[0].data
+ * @li #I2C_FLAG_WRITE - data written from buf[0].data
+ * @li #I2C_FLAG_WRITE_READ - data written from buf[0].data and read
+ * into buf[1].data
+ * @li #I2C_FLAG_WRITE_WRITE - data written from buf[0].data and
+ * buf[1].data
+ */
+typedef struct {
+ /**
+ * @brief
+ * Address to use after (repeated) start.
+ * @details
+ * Layout details, A = address bit, X = don't care bit (set to 0):
+ * @li 7 bit address - use format AAAA AAAX.
+ * @li 10 bit address - use format XXXX XAAX AAAA AAAA
+ */
+ uint16_t addr;
+
+ /** Flags defining sequence type and details, see I2C_FLAG_... defines. */
+ uint16_t flags;
+
+ /**
+ * Buffers used to hold data to send from or receive into depending
+ * on sequence type.
+ */
+ struct {
+ /** Buffer used for data to transmit/receive, must be @p len long. */
+ uint8_t *data;
+
+ /**
+ * Number of bytes in @p data to send or receive. Notice that when
+ * receiving data to this buffer, at least 1 byte must be received.
+ * Setting @p len to 0 in the receive case is considered a usage fault.
+ * Transmitting 0 bytes is legal, in which case only the address
+ * is transmitted after the start condition.
+ */
+ uint16_t len;
+ } buf[2];
+} I2C_TransferSeq_TypeDef;
+
+/*******************************************************************************
+ ***************************** PROTOTYPES **********************************
+ ******************************************************************************/
+
+uint32_t I2C_BusFreqGet(I2C_TypeDef *i2c);
+void I2C_BusFreqSet(I2C_TypeDef *i2c,
+ uint32_t freqRef,
+ uint32_t freqScl,
+ I2C_ClockHLR_TypeDef i2cMode);
+void I2C_Enable(I2C_TypeDef *i2c, bool enable);
+void I2C_Init(I2C_TypeDef *i2c, const I2C_Init_TypeDef *init);
+
+/***************************************************************************//**
+ * @brief
+ * Clear one or more pending I2C interrupts.
+ *
+ * @param[in] i2c
+ * Pointer to I2C peripheral register block.
+ *
+ * @param[in] flags
+ * Pending I2C interrupt source to clear. Use a bitwse logic OR combination of
+ * valid interrupt flags for the I2C module (I2C_IF_nnn).
+ ******************************************************************************/
+__STATIC_INLINE void I2C_IntClear(I2C_TypeDef *i2c, uint32_t flags)
+{
+ i2c->IFC = flags;
+}
+
+/***************************************************************************//**
+ * @brief
+ * Disable one or more I2C interrupts.
+ *
+ * @param[in] i2c
+ * Pointer to I2C peripheral register block.
+ *
+ * @param[in] flags
+ * I2C interrupt sources to disable. Use a bitwise logic OR combination of
+ * valid interrupt flags for the I2C module (I2C_IF_nnn).
+ ******************************************************************************/
+__STATIC_INLINE void I2C_IntDisable(I2C_TypeDef *i2c, uint32_t flags)
+{
+ i2c->IEN &= ~(flags);
+}
+
+/***************************************************************************//**
+ * @brief
+ * Enable one or more I2C interrupts.
+ *
+ * @note
+ * Depending on the use, a pending interrupt may already be set prior to
+ * enabling the interrupt. Consider using I2C_IntClear() prior to enabling
+ * if such a pending interrupt should be ignored.
+ *
+ * @param[in] i2c
+ * Pointer to I2C peripheral register block.
+ *
+ * @param[in] flags
+ * I2C interrupt sources to enable. Use a bitwise logic OR combination of
+ * valid interrupt flags for the I2C module (I2C_IF_nnn).
+ ******************************************************************************/
+__STATIC_INLINE void I2C_IntEnable(I2C_TypeDef *i2c, uint32_t flags)
+{
+ i2c->IEN |= flags;
+}
+
+/***************************************************************************//**
+ * @brief
+ * Get pending I2C interrupt flags.
+ *
+ * @note
+ * The event bits are not cleared by the use of this function.
+ *
+ * @param[in] i2c
+ * Pointer to I2C peripheral register block.
+ *
+ * @return
+ * I2C interrupt sources pending. A bitwise logic OR combination of valid
+ * interrupt flags for the I2C module (I2C_IF_nnn).
+ ******************************************************************************/
+__STATIC_INLINE uint32_t I2C_IntGet(I2C_TypeDef *i2c)
+{
+ return i2c->IF;
+}
+
+/***************************************************************************//**
+ * @brief
+ * Get enabled and pending I2C interrupt flags.
+ * Useful for handling more interrupt sources in the same interrupt handler.
+ *
+ * @note
+ * Interrupt flags are not cleared by the use of this function.
+ *
+ * @param[in] i2c
+ * Pointer to I2C peripheral register block.
+ *
+ * @return
+ * Pending and enabled I2C interrupt sources
+ * The return value is the bitwise AND of
+ * - the enabled interrupt sources in I2Cn_IEN and
+ * - the pending interrupt flags I2Cn_IF
+ ******************************************************************************/
+__STATIC_INLINE uint32_t I2C_IntGetEnabled(I2C_TypeDef *i2c)
+{
+ uint32_t ien;
+
+ ien = i2c->IEN;
+ return i2c->IF & ien;
+}
+
+/***************************************************************************//**
+ * @brief
+ * Set one or more pending I2C interrupts from SW.
+ *
+ * @param[in] i2c
+ * Pointer to I2C peripheral register block.
+ *
+ * @param[in] flags
+ * I2C interrupt sources to set to pending. Use a bitwise logic OR combination
+ * of valid interrupt flags for the I2C module (I2C_IF_nnn).
+ ******************************************************************************/
+__STATIC_INLINE void I2C_IntSet(I2C_TypeDef *i2c, uint32_t flags)
+{
+ i2c->IFS = flags;
+}
+
+void I2C_Reset(I2C_TypeDef *i2c);
+
+/***************************************************************************//**
+ * @brief
+ * Get slave address used for I2C peripheral (when operating in slave mode).
+ *
+ * @details
+ * For 10 bit addressing mode, the address is split in two bytes, and only
+ * the first byte setting is fetched, effectively only controlling the 2 most
+ * significant bits of the 10 bit address. Full handling of 10 bit addressing
+ * in slave mode requires additional SW handling.
+ *
+ * @param[in] i2c
+ * Pointer to I2C peripheral register block.
+ *
+ * @return
+ * I2C slave address in use. The 7 most significant bits define the actual
+ * address, the least significant bit is reserved and always returned as 0.
+ ******************************************************************************/
+__STATIC_INLINE uint8_t I2C_SlaveAddressGet(I2C_TypeDef *i2c)
+{
+ return ((uint8_t)(i2c->SADDR));
+}
+
+/***************************************************************************//**
+ * @brief
+ * Set slave address to use for I2C peripheral (when operating in slave mode).
+ *
+ * @details
+ * For 10 bit addressing mode, the address is split in two bytes, and only
+ * the first byte is set, effectively only controlling the 2 most significant
+ * bits of the 10 bit address. Full handling of 10 bit addressing in slave
+ * mode requires additional SW handling.
+ *
+ * @param[in] i2c
+ * Pointer to I2C peripheral register block.
+ *
+ * @param[in] addr
+ * I2C slave address to use. The 7 most significant bits define the actual
+ * address, the least significant bit is reserved and always set to 0.
+ ******************************************************************************/
+__STATIC_INLINE void I2C_SlaveAddressSet(I2C_TypeDef *i2c, uint8_t addr)
+{
+ i2c->SADDR = (uint32_t)addr & 0xfe;
+}
+
+/***************************************************************************//**
+ * @brief
+ * Get slave address mask used for I2C peripheral (when operating in slave
+ * mode).
+ *
+ * @details
+ * The address mask defines how the comparator works. A bit position with
+ * value 0 means that the corresponding slave address bit is ignored during
+ * comparison (don't care). A bit position with value 1 means that the
+ * corresponding slave address bit must match.
+ *
+ * For 10 bit addressing mode, the address is split in two bytes, and only
+ * the mask for the first address byte is fetched, effectively only
+ * controlling the 2 most significant bits of the 10 bit address.
+ *
+ * @param[in] i2c
+ * Pointer to I2C peripheral register block.
+ *
+ * @return
+ * I2C slave address mask in use. The 7 most significant bits define the
+ * actual address mask, the least significant bit is reserved and always
+ * returned as 0.
+ ******************************************************************************/
+__STATIC_INLINE uint8_t I2C_SlaveAddressMaskGet(I2C_TypeDef *i2c)
+{
+ return ((uint8_t)(i2c->SADDRMASK));
+}
+
+/***************************************************************************//**
+ * @brief
+ * Set slave address mask used for I2C peripheral (when operating in slave
+ * mode).
+ *
+ * @details
+ * The address mask defines how the comparator works. A bit position with
+ * value 0 means that the corresponding slave address bit is ignored during
+ * comparison (don't care). A bit position with value 1 means that the
+ * corresponding slave address bit must match.
+ *
+ * For 10 bit addressing mode, the address is split in two bytes, and only
+ * the mask for the first address byte is set, effectively only controlling
+ * the 2 most significant bits of the 10 bit address.
+ *
+ * @param[in] i2c
+ * Pointer to I2C peripheral register block.
+ *
+ * @param[in] mask
+ * I2C slave address mask to use. The 7 most significant bits define the
+ * actual address mask, the least significant bit is reserved and should
+ * be 0.
+ ******************************************************************************/
+__STATIC_INLINE void I2C_SlaveAddressMaskSet(I2C_TypeDef *i2c, uint8_t mask)
+{
+ i2c->SADDRMASK = (uint32_t)mask & 0xfe;
+}
+
+I2C_TransferReturn_TypeDef I2C_Transfer(I2C_TypeDef *i2c);
+I2C_TransferReturn_TypeDef I2C_TransferInit(I2C_TypeDef *i2c,
+ I2C_TransferSeq_TypeDef *seq);
+
+/** @} (end addtogroup I2C) */
+/** @} (end addtogroup emlib) */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* defined(I2C_COUNT) && (I2C_COUNT > 0) */
+#endif /* EM_I2C_H */


