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