1 /******************************************************************************
2 * Filename: i2c.c
3 * Revised: 2017-04-26 18:27:45 +0200 (Wed, 26 Apr 2017)
4 * Revision: 48852
5 *
6 * Description: Driver for the I2C module
7 *
8 * Copyright (c) 2015 - 2020, Texas Instruments Incorporated
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions are met:
13 *
14 * 1) Redistributions of source code must retain the above copyright notice,
15 * this list of conditions and the following disclaimer.
16 *
17 * 2) Redistributions in binary form must reproduce the above copyright notice,
18 * this list of conditions and the following disclaimer in the documentation
19 * and/or other materials provided with the distribution.
20 *
21 * 3) Neither the name of the ORGANIZATION nor the names of its contributors may
22 * be used to endorse or promote products derived from this software without
23 * specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
29 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
36 *
37 ******************************************************************************/
38
39 #include "i2c.h"
40
41 //*****************************************************************************
42 //
43 // Handle support for DriverLib in ROM:
44 // This section will undo prototype renaming made in the header file
45 //
46 //*****************************************************************************
47 #if !defined(DOXYGEN)
48 #undef I2CMasterInitExpClk
49 #define I2CMasterInitExpClk NOROM_I2CMasterInitExpClk
50 #undef I2CMasterErr
51 #define I2CMasterErr NOROM_I2CMasterErr
52 #undef I2CIntRegister
53 #define I2CIntRegister NOROM_I2CIntRegister
54 #undef I2CIntUnregister
55 #define I2CIntUnregister NOROM_I2CIntUnregister
56 #endif
57
58 //*****************************************************************************
59 //
60 // Initializes the I2C Master block
61 //
62 //*****************************************************************************
63 void
I2CMasterInitExpClk(uint32_t ui32Base,uint32_t ui32I2CClk,bool bFast)64 I2CMasterInitExpClk(uint32_t ui32Base, uint32_t ui32I2CClk,
65 bool bFast)
66 {
67 uint32_t ui32SCLFreq;
68 uint32_t ui32TPR;
69
70 // Check the arguments.
71 ASSERT(I2CBaseValid(ui32Base));
72
73 // Must enable the device before doing anything else.
74 I2CMasterEnable(I2C0_BASE);
75
76 // Get the desired SCL speed.
77 if(bFast == true)
78 {
79 ui32SCLFreq = 400000;
80 }
81 else
82 {
83 ui32SCLFreq = 100000;
84 }
85
86 // Compute the clock divider that achieves the fastest speed less than or
87 // equal to the desired speed. The numerator is biased to favor a larger
88 // clock divider so that the resulting clock is always less than or equal
89 // to the desired clock, never greater.
90 ui32TPR = ((ui32I2CClk + (2 * 10 * ui32SCLFreq) - 1) / (2 * 10 * ui32SCLFreq)) - 1;
91 HWREG(I2C0_BASE + I2C_O_MTPR) = ui32TPR;
92 }
93
94 //*****************************************************************************
95 //
96 // Gets the error status of the I2C Master module
97 //
98 //*****************************************************************************
99 uint32_t
I2CMasterErr(uint32_t ui32Base)100 I2CMasterErr(uint32_t ui32Base)
101 {
102 uint32_t ui32Err;
103
104 // Check the arguments.
105 ASSERT(I2CBaseValid(ui32Base));
106
107 // Get the raw error state.
108 ui32Err = HWREG(I2C0_BASE + I2C_O_MSTAT);
109
110 // If the I2C master is busy, then all the other status bits are invalid,
111 // and there is no error to report.
112 if(ui32Err & I2C_MSTAT_BUSY)
113 {
114 return(I2C_MASTER_ERR_NONE);
115 }
116
117 // Check for errors.
118 if(ui32Err & (I2C_MSTAT_ERR | I2C_MSTAT_ARBLST))
119 {
120 return(ui32Err & (I2C_MSTAT_ARBLST | I2C_MSTAT_DATACK_N | I2C_MSTAT_ADRACK_N));
121 }
122 else
123 {
124 return(I2C_MASTER_ERR_NONE);
125 }
126 }
127
128 //*****************************************************************************
129 //
130 // Registers an interrupt handler for the I2C module
131 //
132 //*****************************************************************************
133 void
I2CIntRegister(uint32_t ui32Base,void (* pfnHandler)(void))134 I2CIntRegister(uint32_t ui32Base, void (*pfnHandler)(void))
135 {
136 uint32_t ui32Int;
137
138 // Check the arguments.
139 ASSERT(I2CBaseValid(ui32Base));
140
141 // Get the interrupt number.
142 ui32Int = INT_I2C_IRQ;
143
144 // Register the interrupt handler, returning an error if an error occurs.
145 IntRegister(ui32Int, pfnHandler);
146
147 // Enable the I2C interrupt.
148 IntEnable(ui32Int);
149 }
150
151 //*****************************************************************************
152 //
153 // Unregisters an interrupt handler for the I2C module
154 //
155 //*****************************************************************************
156 void
I2CIntUnregister(uint32_t ui32Base)157 I2CIntUnregister(uint32_t ui32Base)
158 {
159 uint32_t ui32Int;
160
161 // Check the arguments.
162 ASSERT(I2CBaseValid(ui32Base));
163
164 // Get the interrupt number.
165 ui32Int = INT_I2C_IRQ;
166
167 // Disable the interrupt.
168 IntDisable(ui32Int);
169
170 // Unregister the interrupt handler.
171 IntUnregister(ui32Int);
172 }
173