1ee90a5e84ae2d61ddb8c7fbf2f51b89fd50c74f
[i3-mote/i3-mote.git] / Basic-Test-Package / MSP432 / Test_MSP432_I2C_Sensors / HAL_I2C.c
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