iLLD_TC27xD  1.0
IfxI2c.c
Go to the documentation of this file.
1 /**
2  * \file IfxI2c.c
3  * \brief I2C basic functionality
4  *
5  * \version iLLD_1_0_0_11_0
6  * \copyright Copyright (c) 2013 Infineon Technologies AG. All rights reserved.
7  *
8  *
9  * IMPORTANT NOTICE
10  *
11  *
12  * Infineon Technologies AG (Infineon) is supplying this file for use
13  * exclusively with Infineon's microcontroller products. This file can be freely
14  * distributed within development tools that are supporting such microcontroller
15  * products.
16  *
17  * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
18  * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
19  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
20  * INFINEON SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL,
21  * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
22  *
23  */
24 
25 /******************************************************************************/
26 /*----------------------------------Includes----------------------------------*/
27 /******************************************************************************/
28 
29 #include "IfxI2c.h"
30 
31 /******************************************************************************/
32 /*-------------------------Function Implementations---------------------------*/
33 /******************************************************************************/
34 
35 void IfxI2c_configureAsMaster(Ifx_I2C *i2c)
36 {
37  // enter config Mode
38  IfxI2c_stop(i2c);
39 
40  i2c->ADDRCFG.U = 0;
41  i2c->ADDRCFG.B.MnS = 1; // master mode
42  i2c->ADDRCFG.B.SONA = 0; // don't release the bus on NACK
43  i2c->ADDRCFG.B.SOPE = 0; // after transfer go into master restart state
44  i2c->ADDRCFG.B.TBAM = 0; // 7 bit address mode
45 
46  i2c->FIFOCFG.U = 0;
47  i2c->FIFOCFG.B.TXFC = 1; // FIFO as flow controller
48  i2c->FIFOCFG.B.RXFC = 1; // FIFO as flow controller
49  i2c->FIFOCFG.B.TXBS = 0; // Burst size 1 word
50  i2c->FIFOCFG.B.RXBS = 0; // Burst size 1 word
51  i2c->FIFOCFG.B.TXFA = 0; // fifo is byte aligned
52  i2c->FIFOCFG.B.RXFA = 0; // fifo is byte aligned
53 }
54 
55 
56 void IfxI2c_disableModule(Ifx_I2C *i2c)
57 {
59 
61 
62  i2c->CLC.B.DISR = 1;
63 
64  while (i2c->CLC.B.DISS == 0)
65  {}
66 
68 }
69 
70 
71 void IfxI2c_enableBurstDataTransferInterrupt(Ifx_I2C *i2c, IfxSrc_Tos typeOfService, uint16 priority)
72 {
73  volatile Ifx_SRC_SRCR *src;
75  IfxSrc_init(src, typeOfService, priority);
76  IfxSrc_enable(src);
77 }
78 
79 
80 void IfxI2c_enableErrorInterrupt(Ifx_I2C *i2c, IfxSrc_Tos typeOfService, uint16 priority)
81 {
82  volatile Ifx_SRC_SRCR *src;
83  src = IfxI2c_getErrorSrcPointer(i2c);
84  IfxSrc_init(src, typeOfService, priority);
85  IfxSrc_enable(src);
86 }
87 
88 
89 void IfxI2c_enableLastBurstDataTransferInterrupt(Ifx_I2C *i2c, IfxSrc_Tos typeOfService, uint16 priority)
90 {
91  volatile Ifx_SRC_SRCR *src;
93  IfxSrc_init(src, typeOfService, priority);
94  IfxSrc_enable(src);
95 }
96 
97 
98 void IfxI2c_enableLastSingleDataTransferInterrupt(Ifx_I2C *i2c, IfxSrc_Tos typeOfService, uint16 priority)
99 {
100  volatile Ifx_SRC_SRCR *src;
102  IfxSrc_init(src, typeOfService, priority);
103  IfxSrc_enable(src);
104 }
105 
106 
107 void IfxI2c_enableModule(Ifx_I2C *i2c)
108 {
110 
112  i2c->CLC.B.DISR = 0U;
113 
114  while (i2c->CLC.B.DISS == 1U)
115  {}
116 
117  i2c->CLC1.B.RMC = 1U;
118 
119  while (i2c->CLC1.B.RMC != 1U)
120  {}
121 
122  i2c->CLC1.B.DISR = 0U;
123 
124  while (i2c->CLC1.B.DISS == 1U)
125  {}
126 
127  // disable all interrupts
128  i2c->ERRIRQSM.U = 0x00;
129  i2c->PIRQSM.U = 0x00;
130  i2c->IMSC.U = 0x00;
131 
133 }
134 
135 
136 void IfxI2c_enableProtocolInterrupt(void *i2c, IfxSrc_Tos typeOfService, uint16 priority)
137 {
138  volatile Ifx_SRC_SRCR *src;
139  src = IfxI2c_getProtocolSrcPointer(i2c);
140  IfxSrc_init(src, typeOfService, priority);
141  IfxSrc_enable(src);
142 }
143 
144 
145 void IfxI2c_enableSingleDataTransferInterrupt(Ifx_I2C *i2c, IfxSrc_Tos typeOfService, uint16 priority)
146 {
147  volatile Ifx_SRC_SRCR *src;
149  IfxSrc_init(src, typeOfService, priority);
150  IfxSrc_enable(src);
151 }
152 
153 
155 {
156  uint8 inc = i2c->FDIVCFG.B.INC;
157  uint16 dec = i2c->FDIVCFG.B.DEC;
158  uint8 rmc = i2c->CLC1.B.RMC;
160 
161  return (fKernel / rmc) / ((2 * dec / inc) + 3);
162 }
163 
164 
166 {
168  IfxPort_setPinModeOutput(scl->pin.port, scl->pin.pinIndex, mode, scl->outSelect);
169  IfxPort_setPinModeOutput(sda->pin.port, sda->pin.pinIndex, mode, sda->outSelect);
170  IfxPort_setPinPadDriver(scl->pin.port, scl->pin.pinIndex, padDriver);
171  IfxPort_setPinPadDriver(sda->pin.port, sda->pin.pinIndex, padDriver);
172  IfxI2c_setPinSelection(scl->module, (IfxI2c_PinSelect)scl->inSelect); // note: uses the same PISEL register like SDA
173 }
174 
175 
176 void IfxI2c_releaseBus(Ifx_I2C *i2c)
177 {
178  // only set the set end of transmisson bit if bus is not free
179  if (i2c->BUSSTAT.B.BS != IfxI2c_BusStatus_idle)
180  {
181  i2c->ENDDCTRL.B.SETEND = 1;
182 
183  // wait until bus is free
185  {}
186 
188  }
189 }
190 
191 
192 void IfxI2c_resetFifo(Ifx_I2C *i2c)
193 {
194  /* reset FIFO */
195  i2c->FIFOCFG.U = 0x0;
196  i2c->FIFOCFG.B.TXFC = 0U;
197  i2c->FIFOCFG.B.RXFC = 0U;
198  i2c->FIFOCFG.B.TXBS = 0U;
199  i2c->FIFOCFG.B.RXBS = 0U;
200  i2c->FIFOCFG.B.TXFA = 0U;
201  i2c->FIFOCFG.B.RXFA = 0U;
202 }
203 
204 
205 void IfxI2c_resetModule(Ifx_I2C *i2c)
206 {
208 
210  i2c->KRST0.B.RST = 1; /* Only if both Kernel reset bits are set a reset is executed */
211  i2c->KRST1.B.RST = 1;
212  IfxScuWdt_setCpuEndinit(passwd);
213 
214  while (0 == i2c->KRST0.B.RSTSTAT) /* Wait until reset is executed */
215 
216  {}
217 
219  i2c->KRSTCLR.B.CLR = 1; /* Clear Kernel reset status bit */
220  IfxScuWdt_setCpuEndinit(passwd);
221 }
222 
223 
224 void IfxI2c_setBaudrate(Ifx_I2C *i2c, float32 baudrate)
225 {
227  uint8 rmc = i2c->CLC1.B.RMC;
228  float32 dec;
229  dec = (((fKernel / rmc) / baudrate) - 3) / 2; // always: Inc = 1
230 
231  // dec:inc must be at least 6
232  if (dec < 6)
233  {
234  dec = 6;
235  }
236  else if (dec > (1 << IFX_I2C_FDIVCFG_DEC_LEN) - 1)
237  {
238  dec = (1 << IFX_I2C_FDIVCFG_DEC_LEN) - 1;
239  }
240 
242 
244  /* Baudrate configuration */
245  i2c->FDIVCFG.B.INC = 1;
246  i2c->FDIVCFG.B.DEC = (uint16)(dec + 0.5);
247  i2c->TIMCFG.B.SDA_DEL_HD_DAT = 0x3F;
248  i2c->TIMCFG.B.FS_SCL_LOW = 1;
249  i2c->TIMCFG.B.EN_SCL_LOW_LEN = 1;
250  i2c->TIMCFG.B.SCL_LOW_LEN = 0x20;
251 
253 }