iLLD_TC27xC  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_0_1_0_10
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_enableModule(Ifx_I2C *i2c)
72 {
74 
76  i2c->CLC.B.DISR = 0U;
77 
78  while (i2c->CLC.B.DISS == 1U)
79  {}
80 
81  i2c->CLC1.B.RMC = 1U;
82 
83  while (i2c->CLC1.B.RMC != 1U)
84  {}
85 
86  i2c->CLC1.B.DISR = 0U;
87 
88  while (i2c->CLC1.B.DISS == 1U)
89  {}
90 
91  // disable all interrupts
92  i2c->ERRIRQSM.U = 0x00;
93  i2c->PIRQSM.U = 0x00;
94  i2c->IMSC.U = 0x00;
95 
97 }
98 
99 
101 {
102  uint8 inc = i2c->FDIVCFG.B.INC;
103  uint16 dec = i2c->FDIVCFG.B.DEC;
104  uint8 rmc = i2c->CLC1.B.RMC;
106 
107  return (fKernel / rmc) / ((2 * dec / inc) + 3);
108 }
109 
110 
112 {
114  IfxPort_setPinModeOutput(scl->pin.port, scl->pin.pinIndex, mode, scl->outSelect);
115  IfxPort_setPinModeOutput(sda->pin.port, sda->pin.pinIndex, mode, sda->outSelect);
116  IfxPort_setPinPadDriver(scl->pin.port, scl->pin.pinIndex, padDriver);
117  IfxPort_setPinPadDriver(sda->pin.port, sda->pin.pinIndex, padDriver);
118  IfxI2c_setPinSelection(scl->module, (IfxI2c_PinSelect)scl->inSelect); // note: uses the same PISEL register like SDA
119 }
120 
121 
122 void IfxI2c_releaseBus(Ifx_I2C *i2c)
123 {
124  // only set the set end of transmisson bit if bus is not free
125  if (i2c->BUSSTAT.B.BS != IfxI2c_BusStatus_idle)
126  {
127  i2c->ENDDCTRL.B.SETEND = 1;
128 
129  // wait until bus is free
130  while (IfxI2c_isTxEndInterrupt(i2c) == FALSE)
131  {}
132 
134  }
135 }
136 
137 
138 void IfxI2c_resetFifo(Ifx_I2C *i2c)
139 {
140  /* reset FIFO */
141  i2c->FIFOCFG.U = 0x0;
142  i2c->FIFOCFG.B.TXFC = 0U;
143  i2c->FIFOCFG.B.RXFC = 0U;
144  i2c->FIFOCFG.B.TXBS = 0U;
145  i2c->FIFOCFG.B.RXBS = 0U;
146  i2c->FIFOCFG.B.TXFA = 0U;
147  i2c->FIFOCFG.B.RXFA = 0U;
148 }
149 
150 
151 void IfxI2c_setBaudrate(Ifx_I2C *i2c, float32 baudrate)
152 {
154  uint8 rmc = i2c->CLC1.B.RMC;
155  float32 dec = (((fKernel / rmc) / baudrate) - 3) / 2; // always: Inc = 1
156 
157  // dec:inc must be at least 6
158  if (dec < 6)
159  {
160  dec = 6;
161  }
162  else if (dec > (1 << IFX_I2C_FDIVCFG_DEC_LEN) - 1)
163  {
164  dec = (1 << IFX_I2C_FDIVCFG_DEC_LEN) - 1;
165  }
166 
168 
170 
171  /* Baudrate configuration */
172  i2c->FDIVCFG.B.INC = 1;
173  i2c->FDIVCFG.B.DEC = (uint16)(dec + 0.5);
174  i2c->TIMCFG.B.SDA_DEL_HD_DAT = 0x3F;
175  i2c->TIMCFG.B.FS_SCL_LOW = 1;
176  i2c->TIMCFG.B.EN_SCL_LOW_LEN = 1;
177  i2c->TIMCFG.B.SCL_LOW_LEN = 0x20;
178 
180 }