1 /**
2  * @file xmc_i2c.h
3  * @date 2019-05-07
4  *
5  * @cond
6  *********************************************************************************************************************
7  * XMClib v2.1.24 - XMC Peripheral Driver Library
8  *
9  * Copyright (c) 2015-2019, Infineon Technologies AG
10  * All rights reserved.
11  *
12  * Redistribution and use in source and binary forms, with or without modification,are permitted provided that the
13  * following conditions are met:
14  *
15  * Redistributions of source code must retain the above copyright notice, this list of conditions and the following
16  * disclaimer.
17  *
18  * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
19  * disclaimer in the documentation and/or other materials provided with the distribution.
20  *
21  * Neither the name of the copyright holders nor the names of its contributors may be used to endorse or promote
22  * products derived from this software without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
25  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE  FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
28  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29  * WHETHER IN CONTRACT, STRICT LIABILITY,OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  *
32  * To improve the quality of the software, users are encouraged to share modifications, enhancements or bug fixes with
33  * Infineon Technologies AG dave@infineon.com).
34  *********************************************************************************************************************
35  *
36  * Change History
37  * --------------
38  *
39  * 2015-02-20:
40  *     - Initial <br>
41  *
42  * 2015-05-20:
43  *     - Description updated <br>
44  *     - Added XMC_I2C_CH_TriggerServiceRequest() and XMC_I2C_CH_SelectInterruptNodePointer() <br>
45  *
46  * 2015-06-20:
47  *     - Removed version macros and declaration of GetDriverVersion API <br>
48  *
49  * 2015-08-27:
50  *     - Added APIs for external input for BRG configuration:XMC_I2C_CH_ConfigExternalInputSignalToBRG() <br>
51  *
52  * 2015-09-01:
53  *     - Added APIs for enabling or disabling the ACK response to a 0x00 slave address: XMC_I2C_CH_EnableSlaveAcknowledgeTo00() and
54  *       XMC_I2C_CH_DisableSlaveAcknowledgeTo00(). <br>
55  *     - Modified XMC_I2C_CH_SetInputSource() API for avoiding complete DXCR register overwriting. <br>
56  *     - Modified XMC_I2C_CH_EVENT_t enum for supporting XMC_I2C_CH_EnableEvent() and XMC_I2C_CH_DisableEvent()
57  *       for supporting multiple events configuration <br>
58  *
59  * 2015-10-02:
60  *     - Fix 10bit addressing
61  *
62  * 2015-10-07:
63  *     - Fix register access in XMC_I2C_CH_EnableSlaveAcknowledgeTo00() and XMC_I2C_CH_DisableSlaveAcknowledgeTo00() APIs.
64  *     - Naming of APIs modified: from XMC_I2C_CH_EnableSlaveAcknowledgeTo00() to  XMC_I2C_CH_EnableAcknowledgeAddress0()
65  *       and from XMC_I2C_CH_DisableSlaveAcknowledgeTo00() to XMC_I2C_CH_DisableAcknowledgeAddress0().
66  *
67  * 2016-05-20:
68  *     - Added XMC_I2C_CH_EnableDataTransmission() and XMC_I2C_CH_DisableDataTransmission()
69  *
70  * 2016-08-17:
71  *     - Improved documentation of slave address passing
72  *
73  * 2017-10-25:
74  *     - Added XMC_I2C_CH_EnableMasterClock() and XMC_I2C_CH_DisableMasterClock()
75  *
76  * 2019-05-07:
77  *     - Added normal_divider_mode to XMC_I2C_CH_CONFIG_t configuration structure.
78  *       It selects normal divider mode for baudrate generator instead of default fractional divider decreasing jitter at cost of frequency selection
79  *     - Added XMC_I2C_CH_SetBaudrateEx()
80  *
81  * @endcond
82  *
83  */
84 
85 #ifndef XMC_I2C_H
86 #define XMC_I2C_H
87 
88 /*******************************************************************************
89  * HEADER FILES
90  *******************************************************************************/
91 
92 #include "xmc_usic.h"
93 
94 /**
95  * @addtogroup XMClib XMC Peripheral Library
96  * @{
97  */
98 
99 /**
100  * @addtogroup I2C
101  * @brief Inter Integrated Circuit(IIC) driver for the XMC microcontroller family.
102  *
103  * USIC IIC Features: <br>
104  *  * Two-wire interface, with one line for shift clock transfer and synchronization (shift clock SCL), the other one for the data transfer (shift data SDA) <br>
105  *	* Communication in standard mode (100 kBit/s) or in fast mode (up to 400 kBit/s) <br>
106  *	* Support of 7-bit addressing, as well as 10-bit addressing <br>
107  *	* Master mode operation, where the IIC controls the bus transactions and provides the clock signal. <br>
108  *	* Slave mode operation, where an external master controls the bus transactions and provides the clock signal.<br>
109  *	* Multi-master mode operation, where several masters can be connected to the bus and bus arbitration can take place, i.e. the IIC module can be master or slave. <br>
110 	  The master/slave operation of an IIC bus participant can change from frame to frame. <br>
111  *	* Efficient frame handling (low software effort), also allowing DMA transfers <br>
112  *	* Powerful interrupt handling due to multitude of indication flags <br>
113  * @{
114  */
115 
116 /*******************************************************************************
117  * MACROS
118  *******************************************************************************/
119 
120 #if defined(USIC0)
121 #define XMC_I2C0_CH0 XMC_USIC0_CH0                   /**< USIC0 channel 0 base address */
122 #define XMC_I2C0_CH1 XMC_USIC0_CH1                   /**< USIC0 channel 1 base address */
123 #endif
124 
125 #if defined(USIC1)
126 #define XMC_I2C1_CH0 XMC_USIC1_CH0                   /**< USIC1 channel 0 base address */
127 #define XMC_I2C1_CH1 XMC_USIC1_CH1                   /**< USIC1 channel 1 base address */
128 #endif
129 
130 #if defined(USIC2)
131 #define XMC_I2C2_CH0 XMC_USIC2_CH0                   /**< USIC2 channel 0 base address */
132 #define XMC_I2C2_CH1 XMC_USIC2_CH1                   /**< USIC2 channel 1 base address */
133 #endif
134 
135 #define XMC_I2C_10BIT_ADDR_GROUP       (0x7800U)	 /**< Value to verify the address is 10-bit or not */
136 
137 /*******************************************************************************
138  * ENUMS
139  *******************************************************************************/
140 
141 /**
142  * @brief I2C Status
143  */
144 typedef enum XMC_I2C_CH_STATUS
145 {
146   XMC_I2C_CH_STATUS_OK,      /**< Status OK */
147   XMC_I2C_CH_STATUS_ERROR,   /**< Status ERROR */
148   XMC_I2C_CH_STATUS_BUSY     /**< Status BUSY */
149 } XMC_I2C_CH_STATUS_t;
150 
151 /**
152  * @brief I2C status
153  */
154 typedef enum XMC_I2C_CH_STATUS_FLAG
155 {
156   XMC_I2C_CH_STATUS_FLAG_SLAVE_SELECT = USIC_CH_PSR_IICMode_SLSEL_Msk,                     /**< Slave select status */
157   XMC_I2C_CH_STATUS_FLAG_WRONG_TDF_CODE_FOUND = USIC_CH_PSR_IICMode_WTDF_Msk,              /**< Wrong TDF status */
158   XMC_I2C_CH_STATUS_FLAG_START_CONDITION_RECEIVED = USIC_CH_PSR_IICMode_SCR_Msk,           /**< Start condition received status */
159   XMC_I2C_CH_STATUS_FLAG_REPEATED_START_CONDITION_RECEIVED = USIC_CH_PSR_IICMode_RSCR_Msk, /**< Repeated start condition received status */
160   XMC_I2C_CH_STATUS_FLAG_STOP_CONDITION_RECEIVED = USIC_CH_PSR_IICMode_PCR_Msk,            /**< Stop condition received status */
161   XMC_I2C_CH_STATUS_FLAG_NACK_RECEIVED = USIC_CH_PSR_IICMode_NACK_Msk,                     /**< NACK received status */
162   XMC_I2C_CH_STATUS_FLAG_ARBITRATION_LOST = USIC_CH_PSR_IICMode_ARL_Msk,                   /**< Arbitration lost status */
163   XMC_I2C_CH_STATUS_FLAG_SLAVE_READ_REQUESTED = USIC_CH_PSR_IICMode_SRR_Msk,               /**< Slave read requested status */
164   XMC_I2C_CH_STATUS_FLAG_ERROR = USIC_CH_PSR_IICMode_ERR_Msk,                              /**< Error status */
165   XMC_I2C_CH_STATUS_FLAG_ACK_RECEIVED = USIC_CH_PSR_IICMode_ACK_Msk,                       /**< ACK received status */
166   XMC_I2C_CH_STATUS_FLAG_RECEIVER_START_INDICATION = USIC_CH_PSR_IICMode_RSIF_Msk,         /**< Receive start indication status */
167   XMC_I2C_CH_STATUS_FLAG_DATA_LOST_INDICATION = USIC_CH_PSR_IICMode_DLIF_Msk,              /**< Data lost indication status */
168   XMC_I2C_CH_STATUS_FLAG_TRANSMIT_SHIFT_INDICATION = USIC_CH_PSR_IICMode_TSIF_Msk,         /**< Transmit shift indication status */
169   XMC_I2C_CH_STATUS_FLAG_TRANSMIT_BUFFER_INDICATION = USIC_CH_PSR_IICMode_TBIF_Msk,        /**< Transmit buffer indication status */
170   XMC_I2C_CH_STATUS_FLAG_RECEIVE_INDICATION = USIC_CH_PSR_IICMode_RIF_Msk,                 /**< Receive indication status */
171   XMC_I2C_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION = USIC_CH_PSR_IICMode_AIF_Msk,     /**< Alternate receive indication status */
172   XMC_I2C_CH_STATUS_FLAG_BAUD_RATE_GENERATOR_INDICATION = USIC_CH_PSR_IICMode_BRGIF_Msk    /**< Baud rate generator indication status */
173 } XMC_I2C_CH_STATUS_FLAG_t;
174 
175 /**
176  * @brief I2C receiver status. The received data byte is available at the bit
177  * positions RBUF[7:0], whereas the additional information is monitored at the bit positions
178 *  RBUF[12:8].
179  */
180 typedef enum XMC_I2C_CH_RECEIVER_STATUS_FLAG
181 {
182   XMC_I2C_CH_RECEIVER_STATUS_FLAG_ACK = 0x1U,      /**< Bit 8:  Value of Received Acknowledgement bit */
183   XMC_I2C_CH_RECEIVER_STATUS_FLAG_FIN = 0x2U,      /**< Bit 9:  A 1 at this bit position indicates that after a (repeated) start condition
184                                                                 followed by the address reception the first data byte of a new frame has
185                                                                 been received. A 0 at this bit position indicates further data bytes */
186   XMC_I2C_CH_RECEIVER_STATUS_FLAG_MODE = 0x4U,     /**< Bit 10: A 0 at this bit position indicates that the data byte has been received
187                                                                 when the device has been in slave mode, whereas a 1 indicates a reception in master mode */
188   XMC_I2C_CH_RECEIVER_STATUS_FLAG_ERR = 0x8U,      /**< Bit 11: A 1 at this bit position indicates an incomplete/erroneous
189                                                                 data byte in the receive buffer */
190   XMC_I2C_CH_RECEIVER_STATUS_FLAG_ADR = 0x10       /**< Bit 12: A 0 at this bit position indicates that the programmed address
191                                                                 has been received. A 1 indicates a general call address. */
192 } XMC_I2C_CH_RECEIVER_STATUS_FLAG_t;
193 
194 /**
195  * @brief I2C commands
196  */
197 typedef enum XMC_I2C_CH_CMD
198 {
199   XMC_I2C_CH_CMD_WRITE,                            /**< I2C Command Write */
200   XMC_I2C_CH_CMD_READ                              /**< I2C Command Read */
201 } XMC_I2C_CH_CMD_t;
202 
203 /**
204  * @brief I2C events
205  */
206 typedef enum XMC_I2C_CH_EVENT
207 {
208   XMC_I2C_CH_EVENT_RECEIVE_START       = USIC_CH_CCR_RSIEN_Msk,  /**< Receive start event */
209   XMC_I2C_CH_EVENT_DATA_LOST           = USIC_CH_CCR_DLIEN_Msk,  /**< Data lost event */
210   XMC_I2C_CH_EVENT_TRANSMIT_SHIFT      = USIC_CH_CCR_TSIEN_Msk,  /**< Transmit shift event */
211   XMC_I2C_CH_EVENT_TRANSMIT_BUFFER     = USIC_CH_CCR_TBIEN_Msk,  /**< Transmit buffer event */
212   XMC_I2C_CH_EVENT_STANDARD_RECEIVE    = USIC_CH_CCR_RIEN_Msk,   /**< Receive event */
213   XMC_I2C_CH_EVENT_ALTERNATIVE_RECEIVE = USIC_CH_CCR_AIEN_Msk,   /**< Alternate receive event */
214   XMC_I2C_CH_EVENT_BAUD_RATE_GENERATOR = USIC_CH_CCR_BRGIEN_Msk, /**< Baudrate generator event */
215 
216   XMC_I2C_CH_EVENT_START_CONDITION_RECEIVED = USIC_CH_PCR_IICMode_SCRIEN_Msk,             /**< Start condition received event */
217   XMC_I2C_CH_EVENT_REPEATED_START_CONDITION_RECEIVED = USIC_CH_PCR_IICMode_RSCRIEN_Msk,   /**< Repeated start condition received event */
218   XMC_I2C_CH_EVENT_STOP_CONDITION_RECEIVED = USIC_CH_PCR_IICMode_PCRIEN_Msk,              /**< Stop condition received event */
219   XMC_I2C_CH_EVENT_NACK = USIC_CH_PCR_IICMode_NACKIEN_Msk,                                /**< NACK received event */
220   XMC_I2C_CH_EVENT_ARBITRATION_LOST = USIC_CH_PCR_IICMode_ARLIEN_Msk,                     /**< Arbitration lost event */
221   XMC_I2C_CH_EVENT_SLAVE_READ_REQUEST = USIC_CH_PCR_IICMode_SRRIEN_Msk,                   /**< Slave read request event */
222   XMC_I2C_CH_EVENT_ERROR = USIC_CH_PCR_IICMode_ERRIEN_Msk,	                              /**< Error condition event */
223   XMC_I2C_CH_EVENT_ACK = USIC_CH_PCR_IICMode_ACKIEN_Msk                                   /**< ACK received event */
224 } XMC_I2C_CH_EVENT_t;
225 
226 /**
227  * @brief I2C input stage selection
228  */
229 typedef enum XMC_I2C_CH_INPUT
230 {
231   XMC_I2C_CH_INPUT_SDA = 0U,   /**< selection of sda input stage */
232 #if UC_FAMILY == XMC1
233   XMC_I2C_CH_INPUT_SDA1 = 3U,
234   XMC_I2C_CH_INPUT_SDA2 = 5U,
235 #endif
236   XMC_I2C_CH_INPUT_SCL = 1U,  /**< selection of scl input stage */
237 #if UC_FAMILY == XMC1
238   XMC_I2C_CH_INPUT_SCL1 = 4U
239 #endif
240 } XMC_I2C_CH_INPUT_t;
241 
242 /**
243  * I2C channel interrupt node pointers
244  */
245 typedef enum XMC_I2C_CH_INTERRUPT_NODE_POINTER
246 {
247   XMC_I2C_CH_INTERRUPT_NODE_POINTER_TRANSMIT_SHIFT      = XMC_USIC_CH_INTERRUPT_NODE_POINTER_TRANSMIT_SHIFT, /**< Node pointer for transmit shift interrupt */
248   XMC_I2C_CH_INTERRUPT_NODE_POINTER_TRANSMIT_BUFFER     = XMC_USIC_CH_INTERRUPT_NODE_POINTER_TRANSMIT_BUFFER, /**< Node pointer for transmit buffer interrupt */
249   XMC_I2C_CH_INTERRUPT_NODE_POINTER_RECEIVE             = XMC_USIC_CH_INTERRUPT_NODE_POINTER_RECEIVE,  /**< Node pointer for receive interrupt */
250   XMC_I2C_CH_INTERRUPT_NODE_POINTER_ALTERNATE_RECEIVE   = XMC_USIC_CH_INTERRUPT_NODE_POINTER_ALTERNATE_RECEIVE,  /**< Node pointer for alternate receive interrupt */
251   XMC_I2C_CH_INTERRUPT_NODE_POINTER_PROTOCOL            = XMC_USIC_CH_INTERRUPT_NODE_POINTER_PROTOCOL   /**< Node pointer for protocol related interrupts */
252 } XMC_I2C_CH_INTERRUPT_NODE_POINTER_t;
253 
254 /*******************************************************************************
255  * DATA STRUCTURES
256  *******************************************************************************/
257 /**
258  * @brief I2C_CH configuration structure
259  */
260 typedef struct XMC_I2C_CH_CONFIG
261 {
262   uint32_t baudrate;   /**< baud rate configuration upto max of 400KHz */
263   bool normal_divider_mode; /**< Selects normal divider mode for baudrate generator instead of default fractional divider decreasing jitter at cost of frequency selection */
264   uint16_t address;    /**< slave address
265                             A 7-bit address needs to be left shifted it by 1.
266                             A 10-bit address needs to be ORed with XMC_I2C_10BIT_ADDR_GROUP. */
267 } XMC_I2C_CH_CONFIG_t;
268 
269 /*******************************************************************************
270  * API PROTOTYPES
271  *******************************************************************************/
272 
273 #ifdef __cplusplus
274 extern "C" {
275 #endif
276 
277 /**
278  * @param channel Constant pointer to USIC channel structure of type @ref XMC_USIC_CH_t
279  * @param config  Constant pointer to I2C channel config structure of type @ref XMC_I2C_CH_CONFIG_t
280  *
281  * @return None<br>
282  *
283  * \par<b>Description:</b><br>
284  * Initializes the I2C \a channel.<br>
285  *
286  * \par
287  * Configures the data format in SCTR register. Sets the slave address, baud rate. Enables transmit data valid, clears status flags
288  * and disables parity generation.<br>
289  *
290  * \par<b>Related APIs:</b><br>
291  * XMC_USIC_CH_Enable()\n\n
292  */
293 
294 void XMC_I2C_CH_Init(XMC_USIC_CH_t *const channel, const XMC_I2C_CH_CONFIG_t *const config);
295 
296 /**
297  * @param channel Constant pointer to USIC channel structure of type @ref XMC_USIC_CH_t
298  * @param rate  baud rate of I2C channel
299  *
300  * @return None<br>
301  *
302  * \par<b>Description:</b><br>
303  * Sets the rate of I2C \a channel.
304  *
305  * \par<b>Note:</b><br>
306  * Standard over sampling is considered if rate <= 100KHz and fast over sampling is considered if rate > 100KHz.<br>
307  *
308  * \par<b>Related APIs:</b><br>
309  * XMC_USIC_CH_SetBaudrate()\n\n
310  */
311 XMC_I2C_CH_STATUS_t XMC_I2C_CH_SetBaudrate(XMC_USIC_CH_t *const channel, const uint32_t rate);
312 
313 /**
314  * @param channel Constant pointer to USIC channel structure of type @ref XMC_USIC_CH_t
315  * @param rate  baud rate of I2C channel
316  * @param normal_divider_mode Selects normal divider mode for baudrate generator instead of default fractional divider decreasing jitter of signal at the cost of frequency selection
317  *
318  * @return None<br>
319  *
320  * \par<b>Description:</b><br>
321  * Sets the rate of I2C \a channel.
322  *
323  * \par<b>Note:</b><br>
324  * Standard over sampling is considered if rate <= 100KHz and fast over sampling is considered if rate > 100KHz.<br>
325  *
326  * \par<b>Related APIs:</b><br>
327  * XMC_USIC_CH_SetBaudrate()\n\n
328  */
329 XMC_I2C_CH_STATUS_t XMC_I2C_CH_SetBaudrateEx(XMC_USIC_CH_t *const channel, uint32_t rate, bool normal_divider_mode);
330 
331 /**
332  * @param channel Constant pointer to USIC channel structure of type @ref XMC_USIC_CH_t
333  *
334  * @return None<br>
335  *
336  * \par<b>Description:</b><br>
337  * Starts the I2C \a channel.
338  *
339  * \par
340  * Sets the USIC input operation mode to I2C mode using CCR register.
341  *
342  * \par<b>Related APIs:</b><br>
343  * XMC_USIC_CH_SetMode()\n\n
344  */
XMC_I2C_CH_Start(XMC_USIC_CH_t * const channel)345 __STATIC_INLINE void XMC_I2C_CH_Start(XMC_USIC_CH_t *const channel)
346 {
347   XMC_USIC_CH_SetMode(channel, XMC_USIC_CH_OPERATING_MODE_I2C);
348 }
349 
350 /**
351  * @param channel Constant pointer to USIC channel structure of type @ref XMC_USIC_CH_t
352  *
353  * @return @ref XMC_I2C_CH_STATUS_t<br>
354  *
355  * \par<b>Description:</b><br>
356  * Stops the I2C \a channel.<br>
357  *
358  * \par
359  * Sets the USIC input operation to IDLE mode using CCR register.
360  *
361  * \par<b>Related APIs:</b><br>
362  * XMC_USIC_CH_SetMode()\n\n
363  */
364 XMC_I2C_CH_STATUS_t XMC_I2C_CH_Stop(XMC_USIC_CH_t *const channel);
365 
366 /**
367  * @param channel Constant pointer to USIC channel structure of type @ref XMC_USIC_CH_t
368  * @param service_request Service request number in the range of 0-5
369  * @return None<br>
370  *
371  * \par<b>Description:</b><br>
372  * Sets the interrupt node for protocol interrupt.<br>
373  *
374  * \par
375  * To generate interrupt for an event, node pointer should be configured with service request number(SR0, SR1..SR5).
376  * The NVIC node gets linked to the interrupt event by doing so.<br>
377  *
378  * \par<b>Note:</b><br>
379  * NVIC node should be separately enabled to generate the interrupt. After setting the node pointer, desired event must be enabled.
380  *
381  * \par<b>Related APIs:</b><br>
382  * XMC_I2C_CH_EnableEvent(), NVIC_SetPriority(), NVIC_EnableIRQ(), XMC_I2C_CH_SetInputSource()<br>
383  */
XMC_I2C_CH_SetInterruptNodePointer(XMC_USIC_CH_t * const channel,const uint8_t service_request)384 __STATIC_INLINE void XMC_I2C_CH_SetInterruptNodePointer(XMC_USIC_CH_t *const channel,
385                                                         const uint8_t service_request)
386 {
387   XMC_USIC_CH_SetInterruptNodePointer(channel, XMC_USIC_CH_INTERRUPT_NODE_POINTER_PROTOCOL, service_request);
388 }
389 
390 
391 /**
392  * @param channel Pointer to USIC channel handler of type @ref XMC_USIC_CH_t \n
393  * 				  \b Range: @ref XMC_I2C0_CH0, @ref XMC_I2C0_CH1,@ref XMC_I2C1_CH0,@ref XMC_I2C1_CH1,@ref XMC_I2C2_CH0,@ref XMC_I2C2_CH1 @note Availability of I2C1 and I2C2 depends on device selection
394  * @param  interrupt_node Interrupt node pointer to be configured. \n
395  * 						  \b Range: @ref XMC_I2C_CH_INTERRUPT_NODE_POINTER_TRANSMIT_SHIFT,
396  * 						  			@ref XMC_I2C_CH_INTERRUPT_NODE_POINTER_TRANSMIT_BUFFER etc.
397  * @param service_request Service request number.\n
398  * 						  \b Range: 0 to 5.
399  * @return None
400  *
401  * \par<b>Description</b><br>
402  * Sets the interrupt node for USIC channel events. \n\n
403  * For an event to generate interrupt, node pointer should be configured with service request(SR0, SR1..SR5).
404  * The NVIC node gets linked to the interrupt event by doing so.<br>
405  * Note: NVIC node should be separately enabled to generate the interrupt.
406  *
407  * \par<b>Related APIs:</b><BR>
408  * XMC_I2C_CH_EnableEvent() \n\n\n
409  */
XMC_I2C_CH_SelectInterruptNodePointer(XMC_USIC_CH_t * const channel,const XMC_I2C_CH_INTERRUPT_NODE_POINTER_t interrupt_node,const uint32_t service_request)410 __STATIC_INLINE void XMC_I2C_CH_SelectInterruptNodePointer(XMC_USIC_CH_t *const channel,
411                                                            const XMC_I2C_CH_INTERRUPT_NODE_POINTER_t interrupt_node,
412                                                            const uint32_t service_request)
413 {
414   XMC_USIC_CH_SetInterruptNodePointer(channel, (XMC_USIC_CH_INTERRUPT_NODE_POINTER_t)interrupt_node,
415 		                                       (uint32_t)service_request);
416 }
417 
418 /**
419  * @param  channel Pointer to USIC channel handler of type @ref XMC_USIC_CH_t \n
420  * 				   \b Range: @ref XMC_I2C0_CH0, @ref XMC_I2C0_CH1,@ref XMC_I2C1_CH0,@ref XMC_I2C1_CH1,@ref XMC_I2C2_CH0,@ref XMC_I2C2_CH1 @note Availability of I2C1 and I2C2 depends on device selection
421  * @param  service_request_line service request number of the event to be triggered. \n
422  * 			\b Range: 0 to 5.
423  * @return None
424  *
425  * \par<b>Description</b><br>
426  * Trigger a I2C interrupt service request.\n\n
427  * When the I2C service request is triggered, the NVIC interrupt associated with it will be
428  * generated if enabled.
429  *
430  * \par<b>Related APIs:</b><BR>
431  * XMC_I2C_CH_SelectInterruptNodePointer() \n\n\n
432  */
XMC_I2C_CH_TriggerServiceRequest(XMC_USIC_CH_t * const channel,const uint32_t service_request_line)433 __STATIC_INLINE void XMC_I2C_CH_TriggerServiceRequest(XMC_USIC_CH_t *const channel, const uint32_t service_request_line)
434 {
435   XMC_USIC_CH_TriggerServiceRequest(channel, (uint32_t)service_request_line);
436 }
437 
438 /**
439  * @param channel Constant pointer to USIC channel structure of type @ref XMC_USIC_CH_t
440  * @param input I2C channel input stage of type @ref XMC_I2C_CH_INPUT_t
441  * @param source Input source select for the input stage(0->DX0A, 1->DX1A, .. 7->DX7G)
442  * @return None<br>
443  *
444  * \par<b>Description:</b><br>
445  * Sets the input source for I2C \a channel.<br>
446  * Defines the input stage for the corresponding input line.
447  *
448  * @note After configuring the input source for corresponding channel, interrupt node pointer is set.
449  *
450  * \par<b>Related APIs:</b><br>
451  * XMC_USIC_CH_SetInptSource(), XMC_USIC_CH_SetInterruptNodePointer()
452  *
453  */
XMC_I2C_CH_SetInputSource(XMC_USIC_CH_t * const channel,const XMC_I2C_CH_INPUT_t input,const uint8_t source)454 __STATIC_INLINE void XMC_I2C_CH_SetInputSource(XMC_USIC_CH_t *const channel, const XMC_I2C_CH_INPUT_t input, const uint8_t source)
455 {
456   channel->DXCR[input] =  (uint32_t)(channel->DXCR[input] & (~USIC_CH_DX0CR_INSW_Msk)) | USIC_CH_DX0CR_DSEN_Msk;
457   XMC_USIC_CH_SetInputSource(channel, (XMC_USIC_CH_INPUT_t)input, source);
458 }
459 
460 /**
461  * @param channel Constant pointer to USIC channel structure of type @ref XMC_USIC_CH_t
462  * @param address I2C slave address
463  * @return None<br>
464  *
465  * \par<b>Description:</b><br>
466  * Sets the I2C \a channel slave address.<br>
467  *
468  * \par
469  * Address is set in PCR_IICMode register by checking if it is in 10-bit address group or 7-bit address group.
470  * (If first five bits of address are assigned with 0xF0, then address mode is 10-bit mode otherwise it is 7-bit mode)\n
471  * @note A 7-bit address should include an additional bit at the LSB for read/write indication. For example, address 0x05 should
472  * be provided as 0x0a. A 10-bit address should be provided with the identifier 0b11110xx at the most significant bits. For example,
473  * address 0x305 should be provided as 0x7b05(bitwise OR with 0x7800).
474  *
475  * \par<b>Related APIs:</b><br>
476  * XMC_I2C_CH_GetSlaveAddress()\n\n
477  */
478 void XMC_I2C_CH_SetSlaveAddress(XMC_USIC_CH_t *const channel, const uint16_t address);
479 
480 /**
481  * @param channel Constant pointer to USIC channel handler of type @ref XMC_USIC_CH_t
482  * @return uint16_t Slave address<br>
483  *
484  * \par<b>Description:</b><br>
485  * Gets the I2C \a channel slave address.<br>
486  *
487  * \par
488  * Returns the address using PCR_IICMode register by checking if it is in 10-bit address group or 7-bit address group.<br>
489  * (If first five bits of address are assigned with 0xF0, then address mode is considered as 10-bit mode otherwise it is 7-bit mode)\n
490  * @note A 7-bit address will include an additional bit at the LSB. For example, address 0x05 will be returned as 0x0a.
491  * 10-bit address will not include the 10-bit address identifier 0b11110xx at the most signifcant bits.
492  *
493  * \par<b>Related APIs:</b><br>
494  * XMC_I2C_CH_SetSlaveAddress()\n\n
495  */
496 uint16_t XMC_I2C_CH_GetSlaveAddress(const XMC_USIC_CH_t *const channel);
497 
498 /**
499  * @param channel Constant pointer to USIC channel structure of type @ref XMC_USIC_CH_t
500  * @param addr I2C master address
501  * @param command read/write command
502  * @return None<br>
503  *
504  * \par<b>Description:</b><br>
505  * Starts the I2C master \a channel.<br>
506  *
507  * \par
508  * Sends the Start condition with read/write command by updating IN/TBUF register based on FIFO/non-FIFO modes.\n
509  * @note Address(addr) should reserve an additional bit at the LSB for read/write indication. For example, address 0x05 should
510  * be provided as 0x0a. If the address is 10-bit, only most significant bits with the 10-bit identifier should be sent using this function.
511  * For example, if the 10-bit address is 0x305, the address should be provided as 0xf6(prepend with 0b11110, upper two bits of address 0b11,
512  * followed by 1-bit field for read/write).
513  *
514  * \par<b>Related APIs:</b><br>
515  * XMC_I2C_CH_MasterTransmit(), XMC_USIC_CH_GetTransmitBufferStatus()\n\n
516  */
517 void XMC_I2C_CH_MasterStart(XMC_USIC_CH_t *const channel, const uint16_t addr, const XMC_I2C_CH_CMD_t command);
518 
519 /**
520  * @param channel Constant pointer to USIC channel structure of type @ref XMC_USIC_CH_t
521  * @param addr I2C master address
522  * @param command read/write command
523  * @return None<br>
524  *
525  * \par<b>Description:</b><br>
526  * Sends the repeated start condition from I2C master \a channel.<br>
527  *
528  * \par
529  * Sends the repeated start condition with read/write command by updating IN/TBUF register based on FIFO/non-FIFO modes.\n
530  * @note Address(addr) should reserve an additional bit at the LSB for read/write indication. For example, address 0x05 should
531  * be provided as 0x0a. If the address is 10-bit, only most significant bits with the 10-bit identifier should be sent using this function.
532  * For example, if the 10-bit address is 0x305, the address should be provided as 0xf6(prepend with 0b11110, upper two bits of address 0b11,
533  * followed by 1-bit field for read/write).
534  *
535  * \par<b>Related APIs:</b><br>
536  * XMC_I2C_CH_MasterTransmit(), XMC_USIC_CH_GetTransmitBufferStatus()\n\n
537  */
538 void XMC_I2C_CH_MasterRepeatedStart(XMC_USIC_CH_t *const channel, const uint16_t addr, const XMC_I2C_CH_CMD_t command);
539 
540 /**
541  * @param channel Constant pointer to USIC channel structure of type @ref XMC_USIC_CH_t
542  * @return None<br>
543  *
544  * \par<b>Description:</b><br>
545  * Stops the I2C master \a channel.<br>
546  *
547  * \par
548   * Reads the transmit buffer status is busy or not and thereby updates IN/TBUF register based on FIFO/non-FIFO modes using Stop command.
549  *
550  * \par<b>Related APIs:</b><br>
551  * XMC_I2C_CH_MasterTransmit(), XMC_USIC_CH_GetTransmitBufferStatus()\n\n
552  */
553 void XMC_I2C_CH_MasterStop(XMC_USIC_CH_t *const channel);
554 
555 /**
556  * @param channel Constant pointer to USIC channel structure of type @ref XMC_USIC_CH_t
557  * @param data data to transmit from I2C \a channel
558  * @return None<br>
559  *
560  * \par<b>Description:</b><br>
561  * Transmit the data from the I2C master \a channel.<br>
562  *
563  * \par
564  * Reads the transmit buffer status is busy or not and thereby updates IN/TBUF register based on FIFO/non-FIFO modes using Master Send command.
565  *
566  * \par<b>Related APIs:</b><br>
567  * XMC_USIC_CH_GetTransmitBufferStatus()\n\n
568  */
569 void XMC_I2C_CH_MasterTransmit(XMC_USIC_CH_t *const channel, const uint8_t data);
570 
571 /**
572  * @param channel Constant pointer to USIC channel structure of type @ref XMC_USIC_CH_t
573  * @param data data to transmit from I2C \a channel
574  * @return None<br>
575  *
576  * \par<b>Description:</b><br>
577  * Transmit the data from the I2C slave \a channel.<br>
578  *
579  * \par
580  * Reads the transmit buffer status is busy or not and thereby updates IN/TBUF register based on FIFO/non-FIFO modes using Slave Send command.
581  *
582  * \par<b>Related APIs:</b><br>
583  * XMC_USIC_CH_GetTransmitBufferStatus(),XMC_I2C_CH_ClearStatusFlag()\n\n
584  */
585 void XMC_I2C_CH_SlaveTransmit(XMC_USIC_CH_t *const channel, const uint8_t data);
586 
587 /**
588  * @param channel Constant pointer to USIC channel structure of type @ref XMC_USIC_CH_t
589  * @return None<br>
590  *
591  * \par<b>Description:</b><br>
592  * Sends the Ack request from I2C master \a channel.<br>
593  *
594  * \par
595 * Reads the transmit buffer status is busy or not and thereby updates IN/TBUF register based on FIFO/non-FIFO modes using Master Receive Ack command.
596  *
597  * \par<b>Related APIs:</b><br>
598  * XMC_I2C_CH_MasterTransmit()\n\n
599  */
600 void XMC_I2C_CH_MasterReceiveAck(XMC_USIC_CH_t *const channel);
601 
602 /**
603  * @param channel Constant pointer to USIC channel structure of type @ref XMC_USIC_CH_t
604  * @return None<br>
605  *
606  * \par<b>Description:</b><br>
607  * Sends the Nack request from I2C master \a channel.<br>
608  *
609  * \par
610  * Reads the transmit buffer status is busy or not and thereby updates IN/TBUF register based on FIFO/non-FIFO modes using Master Receive Nack command.
611  *
612  * \par<b>Related APIs:</b><br>
613  * XMC_I2C_CH_MasterTransmit()\n\n
614  */
615 void XMC_I2C_CH_MasterReceiveNack(XMC_USIC_CH_t *const channel);
616 
617 /**
618  * @param channel Constant pointer to USIC channel structure of type @ref XMC_USIC_CH_t
619  * @return uint8_t OUTR/RBUF register data<br>
620  *
621  * \par<b>Description:</b><br>
622  * Reads the data from I2C \a channel.<br>
623  *
624  * \par
625  * Data is read by using OUTR/RBUF register based on FIFO/non-FIFO modes.
626  *
627  * \par<b>Related APIs:</b><br>
628  * XMC_I2C_CH_MasterTransmit()\n\n
629  */
630 uint8_t XMC_I2C_CH_GetReceivedData(const XMC_USIC_CH_t *const channel);
631 
632 /**
633  * @param channel Constant pointer to USIC channel structure of type @ref XMC_USIC_CH_t
634  * @return uint8_t Receiver status flag<br>
635  *
636  * \par<b>Description:</b><br>
637  * Gets the receiver status of I2C \a channel using RBUF register of bits 8-12 which gives information about receiver status.
638  *
639  * \par<b>Related APIs:</b><br>
640  * XMC_I2C_CH_MasterTransmit()\n\n
641  */
XMC_I2C_CH_GetReceiverStatusFlag(XMC_USIC_CH_t * const channel)642 __STATIC_INLINE uint8_t XMC_I2C_CH_GetReceiverStatusFlag(XMC_USIC_CH_t *const channel)
643 {
644   return((uint8_t)((channel->RBUF) >> 8U));
645 }
646 
647 /**
648  * @param channel Constant pointer to USIC channel structure of type @ref XMC_USIC_CH_t
649  * @param event ORed values of @ref XMC_I2C_CH_EVENT_t enum
650  * @return None<br>
651  *
652  * \par<b>Description:</b><br>
653  * Enables the input parameter @ref XMC_I2C_CH_EVENT_t event using PCR_IICMode register.
654  *
655  * \par<b>Related APIs:</b><br>
656  * XMC_I2C_CH_DisableEvent()\n\n
657  */
658 void XMC_I2C_CH_EnableEvent(XMC_USIC_CH_t *const channel, uint32_t event);
659 
660 /**
661  * @param channel Constant pointer to USIC channel structure of type @ref XMC_USIC_CH_t
662  * @param event ORed values of @ref XMC_I2C_CH_EVENT_t enum
663  * @return None<br>
664  *
665  * \par<b>Description:</b><br>
666  * Disables the input parameter @ref XMC_I2C_CH_EVENT_t event using PCR_IICMode register.
667  *
668  * \par<b>Related APIs:</b><br>
669  * XMC_I2C_CH_EnableEvent()\n\n
670  */
671 void XMC_I2C_CH_DisableEvent(XMC_USIC_CH_t *const channel, uint32_t event);
672 
673 /**
674  * @param channel Constant pointer to USIC channel structure of type @ref XMC_USIC_CH_t
675  * @return uint32_t Status byte<br>
676  *
677  * \par<b>Description:</b><br>
678  * Retrieves the status byte of I2C \a channel using PSR_IICMode register.\n
679  *
680  * \par<b>Related APIs:</b><br>
681  * XMC_I2C_CH_ClearStatusFlag()\n\n
682  */
XMC_I2C_CH_GetStatusFlag(XMC_USIC_CH_t * const channel)683 __STATIC_INLINE uint32_t XMC_I2C_CH_GetStatusFlag(XMC_USIC_CH_t *const channel)
684 {
685   return (channel->PSR_IICMode);
686 }
687 
688 /**
689  * @param channel Constant pointer to USIC channel structure of type @ref XMC_USIC_CH_t
690  * @param flag Status flag
691  * @return None<br>
692  *
693  * \par<b>Description:</b><br>
694  * Clears the status flag of I2C \a channel by setting the input parameter \a flag in PSCR register.
695  *
696  * \par<b>Related APIs:</b><br>
697  * XMC_I2C_CH_GetStatusFlag()\n\n
698  */
XMC_I2C_CH_ClearStatusFlag(XMC_USIC_CH_t * const channel,uint32_t flag)699 __STATIC_INLINE void XMC_I2C_CH_ClearStatusFlag(XMC_USIC_CH_t *const channel, uint32_t flag)
700 {
701   channel->PSCR |= flag;
702 }
703 
704 /**
705  * @param  channel Pointer to USIC channel handler of type @ref XMC_USIC_CH_t \n
706  * 				   \b Range: @ref XMC_I2C0_CH0, @ref XMC_I2C0_CH1,@ref XMC_I2C1_CH0,@ref XMC_I2C1_CH1,@ref XMC_I2C2_CH0,@ref XMC_I2C2_CH1 @note Availability of I2C1 and I2C2 depends on device selection
707  * @param  pdiv Desired divider for the external frequency input. \b Range: minimum value = 1, maximum value = 1024 \n
708  * @param  oversampling Required oversampling. The value indicates the number of time quanta for one symbol of data. \n
709  * 						This can be related to the number of samples for each logic state of the data signal. \n
710  * 						\b Range: 1 to 32. Value should be chosen based on the protocol used.
711  * @param  combination_mode  USIC channel input combination mode \n
712  *
713  * @return None
714  *
715  * \par<b>Description</b><br>
716  * Enables the external frequency input for the Baudrate Generator and configures the divider, oversampling and
717  * the combination mode of the USIC channel. \n\n
718  *
719  * \par<b>Related APIs:</b><BR>
720  * XMC_USIC_CH_SetBRGInputClockSource(), XMC_USIC_CH_SetInputTriggerCombinationMode() \n\n\n
721  */
XMC_I2C_CH_ConfigExternalInputSignalToBRG(XMC_USIC_CH_t * const channel,const uint16_t pdiv,const uint32_t oversampling,const XMC_USIC_CH_INPUT_COMBINATION_MODE_t combination_mode)722 __STATIC_INLINE void XMC_I2C_CH_ConfigExternalInputSignalToBRG(XMC_USIC_CH_t *const channel,
723 		                                                       const uint16_t pdiv,
724 											                   const uint32_t oversampling,
725 											                   const XMC_USIC_CH_INPUT_COMBINATION_MODE_t combination_mode)
726 {
727   XMC_USIC_CH_ConfigExternalInputSignalToBRG(channel,pdiv,oversampling,combination_mode);
728 }
729 
730 /**
731  * @param channel Constant pointer to USIC channel structure of type @ref XMC_USIC_CH_t
732  * @return None
733  *
734  * \par<b>Description:</b><br>
735  * Retrieves the status byte of I2C \a channel using PSR_IICMode register.\n
736  *
737  * \par<b>Related APIs:</b><br>
738  * XMC_I2C_CH_DisableAcknowledgeAddress0()\n\n
739  */
XMC_I2C_CH_EnableAcknowledgeAddress0(XMC_USIC_CH_t * const channel)740 __STATIC_INLINE void XMC_I2C_CH_EnableAcknowledgeAddress0(XMC_USIC_CH_t *const channel)
741 {
742   channel->PCR_IICMode |= USIC_CH_PCR_IICMode_ACK00_Msk;
743 }
744 
745 /**
746  * @param channel Constant pointer to USIC channel structure of type @ref XMC_USIC_CH_t
747  * @return None
748  *
749  * \par<b>Description:</b><br>
750  * This bit defines that slave device should not be sensitive to the slave address 00H.\n
751  *
752  * \par<b>Related APIs:</b><br>
753  * XMC_I2C_CH_EnableAcknowledgeAddress0()\n\n
754  */
XMC_I2C_CH_DisableAcknowledgeAddress0(XMC_USIC_CH_t * const channel)755 __STATIC_INLINE void XMC_I2C_CH_DisableAcknowledgeAddress0(XMC_USIC_CH_t *const channel)
756 {
757   channel->PCR_IICMode &= ~USIC_CH_PCR_IICMode_ACK00_Msk;
758 }
759 
760 /**
761  * @param channel Constant pointer to USIC channel handle of type @ref XMC_USIC_CH_t \n
762  *          \b Range: @ref XMC_I2C0_CH0, @ref XMC_I2C0_CH1,@ref XMC_I2C1_CH0,@ref XMC_I2C1_CH1,@ref XMC_I2C2_CH0,@ref XMC_I2C2_CH1 @note Availability of I2C1 and I2C2 depends on device selection
763  * @return None
764  *
765  * \par<b>Description</b><br>
766  * Enable data transmission.\n\n
767  * Use this function in combination with XMC_I2C_CH_DisableDataTransmission() to fill the FIFO and send the FIFO content without gaps in the transmission.
768  * FIFO is filled using XMC_USIC_CH_TXFIFO_PutData().
769  * @note If you need more control over the start of transmission use XMC_USIC_CH_SetStartTransmisionMode()
770  *
771  * \par<b>Related APIs:</b><BR>
772  * XMC_I2C_CH_DisableDataTransmission()\n\n\n
773  */
XMC_I2C_CH_EnableDataTransmission(XMC_USIC_CH_t * const channel)774 __STATIC_INLINE void XMC_I2C_CH_EnableDataTransmission(XMC_USIC_CH_t *const channel)
775 {
776   XMC_USIC_CH_SetStartTransmisionMode(channel, XMC_USIC_CH_START_TRANSMISION_ON_TDV);
777 }
778 
779 /**
780  * @param channel Constant pointer to USIC channel handle of type @ref XMC_USIC_CH_t \n
781  *          \b Range: @ref XMC_I2C0_CH0, @ref XMC_I2C0_CH1,@ref XMC_I2C1_CH0,@ref XMC_I2C1_CH1,@ref XMC_I2C2_CH0,@ref XMC_I2C2_CH1 @note Availability of I2C1 and I2C2 depends on device selection
782  * @return None
783  *
784  * \par<b>Description</b><br>
785  * Disable data transmission.\n\n
786  * Use this function in combination with XMC_I2C_CH_EnableDataTransmission() to fill the FIFO and send the FIFO content without gaps in the transmission.
787  * FIFO is filled using XMC_USIC_CH_TXFIFO_PutData().
788  *
789  * \par<b>Related APIs:</b><BR>
790  * XMC_I2C_CH_EnableDataTransmission()\n\n\n
791  */
XMC_I2C_CH_DisableDataTransmission(XMC_USIC_CH_t * const channel)792 __STATIC_INLINE void XMC_I2C_CH_DisableDataTransmission(XMC_USIC_CH_t *const channel)
793 {
794   XMC_USIC_CH_SetStartTransmisionMode(channel, XMC_USIC_CH_START_TRANSMISION_DISABLED);
795 }
796 
797 /**
798  * @param channel A constant pointer to XMC_USIC_CH_t, pointing to the USIC channel base address.
799  *
800  * @return None
801  *
802  * \par<b>Description:</b><br>
803  * Enables the generation of Master clock by setting PCR.MCLK bit.\n\n
804  * This clock can be used as a clock reference for external devices. This is not enabled during initialization in
805  * XMC_I2C_CH_Init(). Invoke XMC_I2C_CH_EnableMasterClock() to enable as needed in the program, or if it is disabled by
806  * XMC_I2C_CH_DisableMasterClock().
807  *
808  * \par<b>Related APIs:</b><BR>
809  * XMC_I2C_CH_DisableMasterClock()
810  */
XMC_I2C_CH_EnableMasterClock(XMC_USIC_CH_t * const channel)811 __STATIC_INLINE void XMC_I2C_CH_EnableMasterClock(XMC_USIC_CH_t *const channel)
812 {
813   channel->PCR_IICMode |= (uint32_t)USIC_CH_PCR_IICMode_MCLK_Msk;
814 }
815 
816 /**
817  * @param channel A constant pointer to XMC_USIC_CH_t, pointing to the USIC channel base address.
818  *
819  * @return None
820  *
821  * \par<b>Description:</b><br>
822  * Disables the generation of Master clock by clearing PCR.MCLK bit.\n\n
823  * This clock can be enabled by invoking XMC_I2C_CH_EnableMasterClock() as needed in the program.
824  *
825  * \par<b>Related APIs:</b><BR>
826  * XMC_I2C_CH_EnableMasterClock()
827  */
XMC_I2C_CH_DisableMasterClock(XMC_USIC_CH_t * const channel)828 __STATIC_INLINE void XMC_I2C_CH_DisableMasterClock(XMC_USIC_CH_t *const channel)
829 {
830   channel->PCR_IICMode &= (uint32_t)~USIC_CH_PCR_IICMode_MCLK_Msk;
831 }
832 
833 #ifdef __cplusplus
834 }
835 #endif
836 
837 /**
838  * @}
839  */
840 
841 /**
842  * @}
843  */
844 
845 #endif
846