1 /*
2 * Copyright (c) 2015, Freescale Semiconductor, Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * o Redistributions of source code must retain the above copyright notice, this list
9 * of conditions and the following disclaimer.
10 *
11 * o Redistributions in binary form must reproduce the above copyright notice, this
12 * list of conditions and the following disclaimer in the documentation and/or
13 * other materials provided with the distribution.
14 *
15 * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
16 * contributors may be used to endorse or promote products derived from this
17 * software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
26 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #include "i2c_imx.h"
32
33 /*******************************************************************************
34 * Constant
35 ******************************************************************************/
36 static const uint32_t i2cClkDivTab[][2] =
37 {
38 {22, 0x20}, {24, 0x21}, {26, 0x22}, {28, 0x23}, {30, 0x00}, {32, 0x24}, {36, 0x25}, {40, 0x26},
39 {42, 0x03}, {44, 0x27}, {48, 0x28}, {52, 0x05}, {56, 0x29}, {60, 0x06}, {64, 0x2A}, {72, 0x2B},
40 {80, 0x2C}, {88, 0x09}, {96, 0x2D}, {104, 0x0A}, {112, 0x2E}, {128, 0x2F}, {144, 0x0C}, {160, 0x30},
41 {192, 0x31}, {224, 0x32}, {240, 0x0F}, {256, 0x33}, {288, 0x10}, {320, 0x34}, {384, 0x35}, {448, 0x36},
42 {480, 0x13}, {512, 0x37}, {576, 0x14}, {640, 0x38}, {768, 0x39}, {896, 0x3A}, {960, 0x17}, {1024, 0x3B},
43 {1152, 0x18}, {1280, 0x3C}, {1536, 0x3D}, {1792, 0x3E}, {1920, 0x1B}, {2048, 0x3F}, {2304, 0x1C}, {2560, 0x1D},
44 {3072, 0x1E}, {3840, 0x1F}
45 };
46
47 /*******************************************************************************
48 * Code
49 ******************************************************************************/
50
51 /*******************************************************************************
52 * I2C Initialization and Configuration functions
53 ******************************************************************************/
54 /*FUNCTION**********************************************************************
55 *
56 * Function Name : I2C_Init
57 * Description : Initialize I2C module with given initialize structure.
58 *
59 *END**************************************************************************/
I2C_Init(I2C_Type * base,const i2c_init_config_t * initConfig)60 void I2C_Init(I2C_Type* base, const i2c_init_config_t* initConfig)
61 {
62 assert(initConfig);
63
64 /* Disable I2C Module. */
65 I2C_I2CR_REG(base) &= ~I2C_I2CR_IEN_MASK;
66
67 /* Reset I2C register to its default value. */
68 I2C_Deinit(base);
69
70 /* Set I2C Module own Slave Address. */
71 I2C_SetSlaveAddress(base, initConfig->slaveAddress);
72
73 /* Set I2C BaudRate according to i2c initialize struct. */
74 I2C_SetBaudRate(base, initConfig->clockRate, initConfig->baudRate);
75 }
76
77 /*FUNCTION**********************************************************************
78 *
79 * Function Name : I2C_Deinit
80 * Description : This function reset I2C module register content to
81 * its default value.
82 *
83 *END**************************************************************************/
I2C_Deinit(I2C_Type * base)84 void I2C_Deinit(I2C_Type* base)
85 {
86 /* Disable I2C Module */
87 I2C_I2CR_REG(base) &= ~I2C_I2CR_IEN_MASK;
88
89 /* Reset I2C Module Register content to default value */
90 I2C_IADR_REG(base) = 0x0;
91 I2C_IFDR_REG(base) = 0x0;
92 I2C_I2CR_REG(base) = 0x0;
93 }
94
95 /*FUNCTION**********************************************************************
96 *
97 * Function Name : I2C_SetBaudRate
98 * Description : This function is used to set the baud rate of I2C Module.
99 *
100 *END**************************************************************************/
I2C_SetBaudRate(I2C_Type * base,uint32_t clockRate,uint32_t baudRate)101 void I2C_SetBaudRate(I2C_Type* base, uint32_t clockRate, uint32_t baudRate)
102 {
103 uint32_t clockDiv;
104 uint8_t clkDivIndex = 0;
105
106 assert(baudRate <= 400000);
107
108 /* Calculate accurate baudRate divider. */
109 clockDiv = clockRate / baudRate;
110
111 if (clockDiv < i2cClkDivTab[0][0])
112 {
113 /* If clock divider is too small, using smallest legal divider */
114 clkDivIndex = 0;
115 }
116 else if (clockDiv > i2cClkDivTab[sizeof(i2cClkDivTab)/sizeof(i2cClkDivTab[0]) - 1][0])
117 {
118 /* If clock divider is too large, using largest legal divider */
119 clkDivIndex = sizeof(i2cClkDivTab)/sizeof(i2cClkDivTab[0]) - 1;
120 }
121 else
122 {
123 while (i2cClkDivTab[clkDivIndex][0] < clockDiv)
124 clkDivIndex++;
125 }
126
127 I2C_IFDR_REG(base) = i2cClkDivTab[clkDivIndex][1];
128 }
129
130 /*******************************************************************************
131 * I2C Bus Control functions
132 ******************************************************************************/
133 /*FUNCTION**********************************************************************
134 *
135 * Function Name : I2C_SetAckBit
136 * Description : This function is used to set the Transmit Acknowledge
137 * action when receive data from other device.
138 *
139 *END**************************************************************************/
I2C_SetAckBit(I2C_Type * base,bool ack)140 void I2C_SetAckBit(I2C_Type* base, bool ack)
141 {
142 if (ack)
143 I2C_I2CR_REG(base) &= ~I2C_I2CR_TXAK_MASK;
144 else
145 I2C_I2CR_REG(base) |= I2C_I2CR_TXAK_MASK;
146 }
147
148 /*******************************************************************************
149 * Interrupts and flags management functions
150 ******************************************************************************/
151 /*FUNCTION**********************************************************************
152 *
153 * Function Name : I2C_SetIntCmd
154 * Description : Enables or disables I2C interrupt requests.
155 *
156 *END**************************************************************************/
I2C_SetIntCmd(I2C_Type * base,bool enable)157 void I2C_SetIntCmd(I2C_Type* base, bool enable)
158 {
159 if (enable)
160 I2C_I2CR_REG(base) |= I2C_I2CR_IIEN_MASK;
161 else
162 I2C_I2CR_REG(base) &= ~I2C_I2CR_IIEN_MASK;
163 }
164
165 /*******************************************************************************
166 * EOF
167 ******************************************************************************/
168