1 /* --COPYRIGHT--,BSD\r
2 * Copyright (c) 2015, Texas Instruments Incorporated\r
3 * All rights reserved.\r
4 *\r
5 * Redistribution and use in source and binary forms, with or without\r
6 * modification, are permitted provided that the following conditions\r
7 * are met:\r
8 *\r
9 * * Redistributions of source code must retain the above copyright\r
10 * notice, this list of conditions and the following disclaimer.\r
11 *\r
12 * * Redistributions in binary form must reproduce the above copyright\r
13 * notice, this list of conditions and the following disclaimer in the\r
14 * documentation and/or other materials provided with the distribution.\r
15 *\r
16 * * Neither the name of Texas Instruments Incorporated nor the names of\r
17 * its contributors may be used to endorse or promote products derived\r
18 * from this software without specific prior written permission.\r
19 *\r
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,\r
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\r
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\r
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\r
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;\r
27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\r
28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR\r
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\r
30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
31 * --/COPYRIGHT--*/\r
32 //****************************************************************************\r
33 //\r
34 // HAL_I2C.c - Hardware abstraction layer for I2C with MSP432P401R\r
35 //\r
36 //****************************************************************************\r
37 \r
38 #include <driverlib.h>\r
39 #include <HAL_I2C.h>\r
40 \r
41 \r
42 /* I2C Master Configuration Parameter */\r
43 const eUSCI_I2C_MasterConfig i2cConfig =\r
44 {\r
45 EUSCI_B_I2C_CLOCKSOURCE_SMCLK, // SMCLK Clock Source\r
46 12000000, // SMCLK = 12MHz\r
47 EUSCI_B_I2C_SET_DATA_RATE_100KBPS, // Desired I2C Clock of 100khz\r
48 0, // No byte counter threshold\r
49 EUSCI_B_I2C_NO_AUTO_STOP // No Autostop\r
50 };\r
51 \r
52 void Init_I2C_GPIO()\r
53 {\r
54 /* Select I2C function for I2C_SCL(P3.7) */\r
55 GPIO_setAsPeripheralModuleFunctionOutputPin(\r
56 GPIO_PORT_P3,\r
57 GPIO_PIN7,\r
58 GPIO_PRIMARY_MODULE_FUNCTION);\r
59 \r
60 /* Select I2C function for I2C_SDA(P3.6) */\r
61 GPIO_setAsPeripheralModuleFunctionOutputPin(\r
62 GPIO_PORT_P3,\r
63 GPIO_PIN6,\r
64 GPIO_PRIMARY_MODULE_FUNCTION);\r
65 }\r
66 \r
67 \r
68 /***************************************************************************//**\r
69 * @brief Configures I2C\r
70 * @param none\r
71 * @return none\r
72 ******************************************************************************/\r
73 \r
74 void I2C_init(void)\r
75 {\r
76 /* Initialize USCI_B0 and I2C Master to communicate with slave devices*/\r
77 I2C_initMaster(EUSCI_B2_BASE, &i2cConfig);\r
78 //I2C_initMaster(EUSCI_B2_BASE, &i2cConfig);\r
79 \r
80 /* Disable I2C module to make changes */\r
81 I2C_disableModule(EUSCI_B2_BASE);\r
82 //I2C_disableModule(EUSCI_B2_BASE);\r
83 \r
84 /* Enable I2C Module to start operations */\r
85 I2C_enableModule(EUSCI_B2_BASE);\r
86 //I2C_enableModule(EUSCI_B2_BASE);\r
87 \r
88 return;\r
89 }\r
90 \r
91 \r
92 /***************************************************************************//**\r
93 * @brief Reads data from the sensor\r
94 * @param writeByte Address of register to read from\r
95 * @return Register contents\r
96 ******************************************************************************/\r
97 \r
98 unsigned short I2C_read16(unsigned char writeByte)\r
99 {\r
100 volatile int val = 0;\r
101 volatile int valScratch = 0;\r
102 \r
103 /* Set master to transmit mode PL */\r
104 I2C_setMode(EUSCI_B2_BASE,\r
105 EUSCI_B_I2C_TRANSMIT_MODE);\r
106 \r
107 /* Clear any existing interrupt flag PL */\r
108 I2C_clearInterruptFlag(EUSCI_B2_BASE,\r
109 EUSCI_B_I2C_TRANSMIT_INTERRUPT0);\r
110 \r
111 /* Wait until ready to write PL */\r
112 while (I2C_isBusBusy(EUSCI_B2_BASE));\r
113 \r
114 /* Initiate start and send first character */\r
115 I2C_masterSendMultiByteStart(EUSCI_B2_BASE, writeByte);\r
116 \r
117 /* Wait for TX to finish */\r
118 while(!(I2C_getInterruptStatus(EUSCI_B2_BASE,\r
119 EUSCI_B_I2C_TRANSMIT_INTERRUPT0)));\r
120 \r
121 /* Initiate stop only */\r
122 I2C_masterSendMultiByteStop(EUSCI_B2_BASE);\r
123 \r
124 /* Wait for Stop to finish */\r
125 while(!I2C_getInterruptStatus(EUSCI_B2_BASE,EUSCI_B_I2C_STOP_INTERRUPT));\r
126 \r
127 /*\r
128 * Generate Start condition and set it to receive mode.\r
129 * This sends out the slave address and continues to read\r
130 * until you issue a STOP\r
131 */\r
132 I2C_masterReceiveStart(EUSCI_B2_BASE);\r
133 \r
134 /* Wait for RX buffer to fill */\r
135 while(!(I2C_getInterruptStatus(EUSCI_B2_BASE,EUSCI_B_I2C_RECEIVE_INTERRUPT0)));\r
136 \r
137 /* Read from I2C RX register */\r
138 val = I2C_masterReceiveMultiByteNext(EUSCI_B2_BASE);\r
139 \r
140 /* Receive second byte then send STOP condition */\r
141 valScratch = I2C_masterReceiveMultiByteFinish(EUSCI_B2_BASE);\r
142 \r
143 /* Shift val to top MSB */\r
144 val = (val << 8);\r
145 /* Read from I2C RX Register and write to LSB of val */\r
146 val |= valScratch;\r
147 \r
148 /* Return temperature value */\r
149 return (int16_t)val;\r
150 }\r
151 \r
152 \r
153 \r
154 \r
155 unsigned char I2C_read8(unsigned short addr)\r
156 {\r
157 volatile int val = 0;\r
158 volatile int valScratch = 0;\r
159 \r
160 /* Set master to transmit mode PL */\r
161 I2C_setMode(EUSCI_B2_BASE,\r
162 EUSCI_B_I2C_TRANSMIT_MODE);\r
163 \r
164 /* Clear any existing interrupt flag PL */\r
165 I2C_clearInterruptFlag(EUSCI_B2_BASE,\r
166 EUSCI_B_I2C_TRANSMIT_INTERRUPT0);\r
167 \r
168 /* Wait until ready to write PL */\r
169 while (I2C_isBusBusy(EUSCI_B2_BASE));\r
170 \r
171 /* Initiate start and send first character */\r
172 I2C_masterSendMultiByteStart(EUSCI_B2_BASE,addr&0x00FF);\r
173 /* Wait for TX to finish */\r
174 while(!(I2C_getInterruptStatus(EUSCI_B2_BASE,EUSCI_B_I2C_TRANSMIT_INTERRUPT0)));\r
175 \r
176 /* Send Next Character */\r
177 //I2C_masterSendMultiByteNext(EUSCI_B2_BASE,(unsigned char)(addr&0x00FF));\r
178 /* Wait for TX to finish */\r
179 //while(!(I2C_getInterruptStatus(EUSCI_B2_BASE,EUSCI_B_I2C_TRANSMIT_INTERRUPT0)));\r
180 \r
181 /* Initiate stop only */\r
182 I2C_masterSendMultiByteStop(EUSCI_B2_BASE);\r
183 /* Wait for Stop to finish */\r
184 while(!I2C_getInterruptStatus(EUSCI_B2_BASE,EUSCI_B_I2C_STOP_INTERRUPT));\r
185 \r
186 /*\r
187 * Generate Start condition and set it to receive mode.\r
188 * This sends out the slave address and continues to read until you issue a STOP\r
189 */\r
190 \r
191 I2C_setMode(EUSCI_B2_BASE,EUSCI_B_I2C_RECEIVE_MODE);\r
192 while (I2C_isBusBusy(EUSCI_B2_BASE));\r
193 \r
194 val=I2C_masterReceiveSingleByte(EUSCI_B2_BASE);\r
195 \r
196 /* Return temperature value */\r
197 return val;\r
198 }\r
199 \r
200 \r
201 \r
202 /***************************************************************************//**\r
203 * @brief Writes data to the sensor\r
204 * @param pointer Address of register you want to modify\r
205 * @param writeByte Data to be written to the specified register\r
206 * @return none\r
207 ******************************************************************************/\r
208 \r
209 void I2C_write16(unsigned short pointer, unsigned short writeByte)\r
210 {\r
211 /* Set master to transmit mode PL */\r
212 I2C_setMode(EUSCI_B2_BASE,\r
213 EUSCI_B_I2C_TRANSMIT_MODE);\r
214 \r
215 /* Clear any existing interrupt flag PL */\r
216 I2C_clearInterruptFlag(EUSCI_B2_BASE,\r
217 EUSCI_B_I2C_TRANSMIT_INTERRUPT0);\r
218 \r
219 /* Wait until ready to write PL */\r
220 while (I2C_isBusBusy(EUSCI_B2_BASE));\r
221 \r
222 /* Initiate start and send first character */\r
223 I2C_masterSendMultiByteStart(EUSCI_B2_BASE,(unsigned char)(pointer>>8));\r
224 while(!(I2C_getInterruptStatus(EUSCI_B2_BASE,EUSCI_B_I2C_TRANSMIT_INTERRUPT0)));\r
225 \r
226 \r
227 I2C_masterSendMultiByteNext(EUSCI_B2_BASE,(unsigned char)(pointer&0x00FF));\r
228 while(!(I2C_getInterruptStatus(EUSCI_B2_BASE,EUSCI_B_I2C_TRANSMIT_INTERRUPT0)));\r
229 \r
230 \r
231 I2C_masterSendMultiByteFinish(EUSCI_B2_BASE,\r
232 (unsigned char)(writeByte&0xFF));\r
233 while(!(I2C_getInterruptStatus(EUSCI_B2_BASE,EUSCI_B_I2C_TRANSMIT_INTERRUPT0)));\r
234 \r
235 while (I2C_isBusBusy(EUSCI_B2_BASE));\r
236 \r
237 }\r
238 \r
239 \r
240 void I2C_setslave(unsigned int slaveAdr)\r
241 {\r
242 /* Specify slave address for I2C */\r
243 I2C_setSlaveAddress(EUSCI_B2_BASE,slaveAdr);\r
244 \r
245 /* Enable and clear the interrupt flag */\r
246 I2C_clearInterruptFlag(EUSCI_B2_BASE,\r
247 EUSCI_B_I2C_TRANSMIT_INTERRUPT0 + EUSCI_B_I2C_RECEIVE_INTERRUPT0);\r
248 \r
249 return;\r
250 }\r