1 /* --COPYRIGHT--,BSD
2 * Copyright (c) 2017, Texas Instruments Incorporated
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * * Neither the name of Texas Instruments Incorporated nor the names of
17 * its contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 * --/COPYRIGHT--*/
32 #include <ti/devices/msp432p4xx/driverlib/uart.h>
33 #include <ti/devices/msp432p4xx/driverlib/interrupt.h>
34 #include <ti/devices/msp432p4xx/driverlib/debug.h>
35 #include <ti/devices/msp432p4xx/driverlib/eusci.h>
36
UART_initModule(uint32_t moduleInstance,const eUSCI_UART_ConfigV1 * config)37 bool UART_initModule(uint32_t moduleInstance, const eUSCI_UART_ConfigV1 *config)
38 {
39 bool retVal = true;
40
41 ASSERT(
42 (EUSCI_A_UART_MODE == config->uartMode)
43 || (EUSCI_A_UART_IDLE_LINE_MULTI_PROCESSOR_MODE
44 == config->uartMode)
45 || (EUSCI_A_UART_ADDRESS_BIT_MULTI_PROCESSOR_MODE
46 == config->uartMode)
47 || (EUSCI_A_UART_AUTOMATIC_BAUDRATE_DETECTION_MODE
48 == config->uartMode));
49
50 ASSERT(
51 (EUSCI_A_UART_CLOCKSOURCE_ACLK == config->selectClockSource)
52 || (EUSCI_A_UART_CLOCKSOURCE_SMCLK
53 == config->selectClockSource));
54
55 ASSERT(
56 (EUSCI_A_UART_MSB_FIRST == config->msborLsbFirst)
57 || (EUSCI_A_UART_LSB_FIRST == config->msborLsbFirst));
58
59 ASSERT(
60 (EUSCI_A_UART_ONE_STOP_BIT == config->numberofStopBits)
61 || (EUSCI_A_UART_TWO_STOP_BITS == config->numberofStopBits));
62
63 ASSERT(
64 (EUSCI_A_UART_NO_PARITY == config->parity)
65 || (EUSCI_A_UART_ODD_PARITY == config->parity)
66 || (EUSCI_A_UART_EVEN_PARITY == config->parity));
67 ASSERT(
68 (EUSCI_A_UART_8_BIT_LEN == config->dataLength)
69 || (EUSCI_A_UART_7_BIT_LEN == config->dataLength));
70
71 /* Disable the USCI Module */
72 BITBAND_PERI(EUSCI_A_CMSIS(moduleInstance)->CTLW0, EUSCI_A_CTLW0_SWRST_OFS) = 1;
73
74 /* Clock source select */
75 EUSCI_A_CMSIS(moduleInstance)->CTLW0 =
76 (EUSCI_A_CMSIS(moduleInstance)->CTLW0 & ~EUSCI_A_CTLW0_SSEL_MASK)
77 | config->selectClockSource;
78
79 /* MSB, LSB select */
80 if (config->msborLsbFirst)
81 BITBAND_PERI(EUSCI_A_CMSIS(moduleInstance)->CTLW0, EUSCI_A_CTLW0_MSB_OFS) = 1;
82 else
83 BITBAND_PERI(EUSCI_A_CMSIS(moduleInstance)->CTLW0, EUSCI_A_CTLW0_MSB_OFS) = 0;
84
85 /* UCSPB = 0(1 stop bit) OR 1(2 stop bits) */
86 if (config->numberofStopBits)
87 BITBAND_PERI(EUSCI_A_CMSIS(moduleInstance)->CTLW0, EUSCI_A_CTLW0_SPB_OFS) = 1;
88 else
89 BITBAND_PERI(EUSCI_A_CMSIS(moduleInstance)->CTLW0, EUSCI_A_CTLW0_SPB_OFS) = 0;
90
91 /* Parity */
92 switch (config->parity)
93 {
94 case EUSCI_A_UART_NO_PARITY:
95 BITBAND_PERI(EUSCI_A_CMSIS(moduleInstance)->CTLW0, EUSCI_A_CTLW0_PEN_OFS) = 0;
96 break;
97 case EUSCI_A_UART_ODD_PARITY:
98 BITBAND_PERI(EUSCI_A_CMSIS(moduleInstance)->CTLW0, EUSCI_A_CTLW0_PEN_OFS) = 1;
99 BITBAND_PERI(EUSCI_A_CMSIS(moduleInstance)->CTLW0, EUSCI_A_CTLW0_PAR_OFS) = 0;
100 break;
101 case EUSCI_A_UART_EVEN_PARITY:
102 BITBAND_PERI(EUSCI_A_CMSIS(moduleInstance)->CTLW0, EUSCI_A_CTLW0_PEN_OFS) = 1;
103 BITBAND_PERI(EUSCI_A_CMSIS(moduleInstance)->CTLW0, EUSCI_A_CTLW0_PAR_OFS) = 1;
104 break;
105 }
106
107 /* UC7BIT = 0(8 bit) OR 1(7 bit) */
108 if (config->dataLength)
109 BITBAND_PERI(EUSCI_A_CMSIS(moduleInstance)->CTLW0, EUSCI_B_CTLW0_SEVENBIT_OFS) = 1;
110 else
111 BITBAND_PERI(EUSCI_A_CMSIS(moduleInstance)->CTLW0, EUSCI_B_CTLW0_SEVENBIT_OFS) = 0;
112
113 /* BaudRate Control Register */
114 EUSCI_A_CMSIS(moduleInstance)->BRW = config->clockPrescalar;
115 EUSCI_A_CMSIS(moduleInstance)->MCTLW = ((config->secondModReg << 8)
116 + (config->firstModReg << 4) + config->overSampling);
117
118 /* Asynchronous mode & 8 bit character select & clear mode */
119 EUSCI_A_CMSIS(moduleInstance)->CTLW0 =
120 (EUSCI_A_CMSIS(moduleInstance)->CTLW0
121 & ~(EUSCI_A_CTLW0_SYNC | EUSCI_A_CTLW0_MODE_3 | EUSCI_A_CTLW0_RXEIE | EUSCI_A_CTLW0_BRKIE | EUSCI_A_CTLW0_DORM
122 | EUSCI_A_CTLW0_TXADDR | EUSCI_A_CTLW0_TXBRK)) | config->uartMode;
123
124 return retVal;
125 }
126
UART_transmitData(uint32_t moduleInstance,uint_fast8_t transmitData)127 void UART_transmitData(uint32_t moduleInstance, uint_fast8_t transmitData)
128 {
129 /* If interrupts are not used, poll for flags */
130 if (!BITBAND_PERI(EUSCI_A_CMSIS(moduleInstance)->IE, EUSCI_A_IE_TXIE_OFS))
131 while (!BITBAND_PERI(EUSCI_A_CMSIS(moduleInstance)->IFG, EUSCI_A_IFG_TXIFG_OFS))
132 ;
133
134 EUSCI_A_CMSIS(moduleInstance)->TXBUF = transmitData;
135 }
136
UART_receiveData(uint32_t moduleInstance)137 uint8_t UART_receiveData(uint32_t moduleInstance)
138 {
139 /* If interrupts are not used, poll for flags */
140 if (!BITBAND_PERI(EUSCI_A_CMSIS(moduleInstance)->IE, EUSCI_A_IE_RXIE_OFS))
141 while (!BITBAND_PERI(EUSCI_A_CMSIS(moduleInstance)->IFG, EUSCI_A_IFG_RXIFG_OFS))
142 ;
143
144 return EUSCI_A_CMSIS(moduleInstance)->RXBUF;
145 }
146
UART_enableModule(uint32_t moduleInstance)147 void UART_enableModule(uint32_t moduleInstance)
148 {
149 /* Reset the UCSWRST bit to enable the USCI Module */
150 BITBAND_PERI(EUSCI_A_CMSIS(moduleInstance)->CTLW0, EUSCI_A_CTLW0_SWRST_OFS) = 0;
151 }
152
UART_disableModule(uint32_t moduleInstance)153 void UART_disableModule(uint32_t moduleInstance)
154 {
155 /* Set the UCSWRST bit to disable the USCI Module */
156 BITBAND_PERI(EUSCI_A_CMSIS(moduleInstance)->CTLW0, EUSCI_A_CTLW0_SWRST_OFS) = 1;
157 }
158
UART_queryStatusFlags(uint32_t moduleInstance,uint_fast8_t mask)159 uint_fast8_t UART_queryStatusFlags(uint32_t moduleInstance, uint_fast8_t mask)
160 {
161 ASSERT(
162 0x00 != mask
163 && (EUSCI_A_UART_LISTEN_ENABLE + EUSCI_A_UART_FRAMING_ERROR
164 + EUSCI_A_UART_OVERRUN_ERROR
165 + EUSCI_A_UART_PARITY_ERROR
166 + EUSCI_A_UART_BREAK_DETECT
167 + EUSCI_A_UART_RECEIVE_ERROR
168 + EUSCI_A_UART_ADDRESS_RECEIVED
169 + EUSCI_A_UART_IDLELINE + EUSCI_A_UART_BUSY));
170
171 return EUSCI_A_CMSIS(moduleInstance)->STATW & mask;
172 }
173
UART_setDormant(uint32_t moduleInstance)174 void UART_setDormant(uint32_t moduleInstance)
175 {
176 BITBAND_PERI(EUSCI_A_CMSIS(moduleInstance)->CTLW0, EUSCI_A_CTLW0_DORM_OFS) = 1;
177 }
178
UART_resetDormant(uint32_t moduleInstance)179 void UART_resetDormant(uint32_t moduleInstance)
180 {
181 BITBAND_PERI(EUSCI_A_CMSIS(moduleInstance)->CTLW0, EUSCI_A_CTLW0_DORM_OFS) = 0;
182 }
183
UART_transmitAddress(uint32_t moduleInstance,uint_fast8_t transmitAddress)184 void UART_transmitAddress(uint32_t moduleInstance, uint_fast8_t transmitAddress)
185 {
186 /* Set UCTXADDR bit */
187 BITBAND_PERI(EUSCI_A_CMSIS(moduleInstance)->CTLW0, EUSCI_A_CTLW0_TXADDR_OFS) = 1;
188
189 /* Place next byte to be sent into the transmit buffer */
190 EUSCI_A_CMSIS(moduleInstance)->TXBUF = transmitAddress;
191 }
192
UART_transmitBreak(uint32_t moduleInstance)193 void UART_transmitBreak(uint32_t moduleInstance)
194 {
195 /* Set UCTXADDR bit */
196 BITBAND_PERI(EUSCI_A_CMSIS(moduleInstance)->CTLW0, EUSCI_A_CTLW0_TXBRK_OFS) = 1;
197
198 /* If current mode is automatic baud-rate detection */
199 if (EUSCI_A_UART_AUTOMATIC_BAUDRATE_DETECTION_MODE
200 == (EUSCI_A_CMSIS(moduleInstance)->CTLW0
201 & EUSCI_A_UART_AUTOMATIC_BAUDRATE_DETECTION_MODE))
202 EUSCI_A_CMSIS(moduleInstance)->TXBUF =
203 EUSCI_A_UART_AUTOMATICBAUDRATE_SYNC;
204 else
205 EUSCI_A_CMSIS(moduleInstance)->TXBUF = DEFAULT_SYNC;
206
207 /* If interrupts are not used, poll for flags */
208 if (!BITBAND_PERI(EUSCI_A_CMSIS(moduleInstance)->IE, EUSCI_A_IE_TXIE_OFS))
209 while (!BITBAND_PERI(EUSCI_A_CMSIS(moduleInstance)->IFG, EUSCI_A_IFG_TXIFG_OFS))
210 ;
211 }
212
UART_getReceiveBufferAddressForDMA(uint32_t moduleInstance)213 uint32_t UART_getReceiveBufferAddressForDMA(uint32_t moduleInstance)
214 {
215 return (uint32_t)&EUSCI_A_CMSIS(moduleInstance)->RXBUF;
216 }
217
UART_getTransmitBufferAddressForDMA(uint32_t moduleInstance)218 uint32_t UART_getTransmitBufferAddressForDMA(uint32_t moduleInstance)
219 {
220 return (uint32_t)&EUSCI_B_CMSIS(moduleInstance)->TXBUF;
221 }
222
UART_selectDeglitchTime(uint32_t moduleInstance,uint32_t deglitchTime)223 void UART_selectDeglitchTime(uint32_t moduleInstance, uint32_t deglitchTime)
224 {
225 ASSERT(
226 (EUSCI_A_UART_DEGLITCH_TIME_2ns == deglitchTime)
227 || (EUSCI_A_UART_DEGLITCH_TIME_50ns == deglitchTime)
228 || (EUSCI_A_UART_DEGLITCH_TIME_100ns == deglitchTime)
229 || (EUSCI_A_UART_DEGLITCH_TIME_200ns == deglitchTime));
230
231 EUSCI_A_CMSIS(moduleInstance)->CTLW1 =
232 (EUSCI_A_CMSIS(moduleInstance)->CTLW1 & ~(EUSCI_A_CTLW1_GLIT_MASK))
233 | deglitchTime;
234
235 }
236
UART_enableInterrupt(uint32_t moduleInstance,uint_fast8_t mask)237 void UART_enableInterrupt(uint32_t moduleInstance, uint_fast8_t mask)
238 {
239 uint_fast8_t locMask;
240
241 ASSERT(
242 !(mask
243 & ~(EUSCI_A_UART_RECEIVE_INTERRUPT
244 | EUSCI_A_UART_TRANSMIT_INTERRUPT
245 | EUSCI_A_UART_RECEIVE_ERRONEOUSCHAR_INTERRUPT
246 | EUSCI_A_UART_BREAKCHAR_INTERRUPT
247 | EUSCI_A_UART_STARTBIT_INTERRUPT
248 | EUSCI_A_UART_TRANSMIT_COMPLETE_INTERRUPT)));
249
250 locMask = (mask
251 & (EUSCI_A_UART_RECEIVE_INTERRUPT | EUSCI_A_UART_TRANSMIT_INTERRUPT
252 | EUSCI_A_UART_STARTBIT_INTERRUPT
253 | EUSCI_A_UART_TRANSMIT_COMPLETE_INTERRUPT));
254
255 EUSCI_A_CMSIS(moduleInstance)->IE |= locMask;
256
257 locMask = (mask
258 & (EUSCI_A_UART_RECEIVE_ERRONEOUSCHAR_INTERRUPT
259 | EUSCI_A_UART_BREAKCHAR_INTERRUPT));
260 EUSCI_A_CMSIS(moduleInstance)->CTLW0 |= locMask;
261 }
262
UART_disableInterrupt(uint32_t moduleInstance,uint_fast8_t mask)263 void UART_disableInterrupt(uint32_t moduleInstance, uint_fast8_t mask)
264 {
265 uint_fast8_t locMask;
266
267 ASSERT(
268 !(mask
269 & ~(EUSCI_A_UART_RECEIVE_INTERRUPT
270 | EUSCI_A_UART_TRANSMIT_INTERRUPT
271 | EUSCI_A_UART_RECEIVE_ERRONEOUSCHAR_INTERRUPT
272 | EUSCI_A_UART_BREAKCHAR_INTERRUPT
273 | EUSCI_A_UART_STARTBIT_INTERRUPT
274 | EUSCI_A_UART_TRANSMIT_COMPLETE_INTERRUPT)));
275
276 locMask = (mask
277 & (EUSCI_A_UART_RECEIVE_INTERRUPT | EUSCI_A_UART_TRANSMIT_INTERRUPT
278 | EUSCI_A_UART_STARTBIT_INTERRUPT
279 | EUSCI_A_UART_TRANSMIT_COMPLETE_INTERRUPT));
280 EUSCI_A_CMSIS(moduleInstance)->IE &= ~locMask;
281
282 locMask = (mask
283 & (EUSCI_A_UART_RECEIVE_ERRONEOUSCHAR_INTERRUPT
284 | EUSCI_A_UART_BREAKCHAR_INTERRUPT));
285 EUSCI_A_CMSIS(moduleInstance)->CTLW0 &= ~locMask;
286 }
287
UART_getInterruptStatus(uint32_t moduleInstance,uint8_t mask)288 uint_fast8_t UART_getInterruptStatus(uint32_t moduleInstance, uint8_t mask)
289 {
290 ASSERT(
291 !(mask
292 & ~(EUSCI_A_UART_RECEIVE_INTERRUPT_FLAG
293 | EUSCI_A_UART_TRANSMIT_INTERRUPT_FLAG
294 | EUSCI_A_UART_STARTBIT_INTERRUPT_FLAG
295 | EUSCI_A_UART_TRANSMIT_COMPLETE_INTERRUPT_FLAG)));
296
297 return EUSCI_A_CMSIS(moduleInstance)->IFG & mask;
298 }
299
UART_getEnabledInterruptStatus(uint32_t moduleInstance)300 uint_fast8_t UART_getEnabledInterruptStatus(uint32_t moduleInstance)
301 {
302 uint_fast8_t intStatus = UART_getInterruptStatus(moduleInstance,
303 EUSCI_A_UART_RECEIVE_INTERRUPT_FLAG | EUSCI_A_UART_TRANSMIT_INTERRUPT_FLAG | EUSCI_A_UART_TRANSMIT_COMPLETE_INTERRUPT_FLAG);
304 uint_fast8_t intEnabled = EUSCI_A_CMSIS(moduleInstance)->IE;
305
306 if (!(intEnabled & EUSCI_A_UART_RECEIVE_INTERRUPT))
307 {
308 intStatus &= ((uint_fast8_t)~EUSCI_A_UART_RECEIVE_INTERRUPT);
309 }
310
311 if (!(intEnabled & EUSCI_A_UART_TRANSMIT_INTERRUPT))
312 {
313 intStatus &= ((uint_fast8_t)~EUSCI_A_UART_TRANSMIT_INTERRUPT);
314 }
315 if(!(intEnabled & EUSCI_A_UART_TRANSMIT_COMPLETE_INTERRUPT))
316 {
317 intStatus &= ((uint_fast8_t)~EUSCI_A_UART_TRANSMIT_COMPLETE_INTERRUPT);
318 }
319
320 intEnabled = EUSCI_A_CMSIS(moduleInstance)->CTLW0;
321
322 if (!(intEnabled & EUSCI_A_UART_RECEIVE_ERRONEOUSCHAR_INTERRUPT))
323 {
324 intStatus &= ((uint_fast8_t)~EUSCI_A_UART_RECEIVE_ERRONEOUSCHAR_INTERRUPT);
325 }
326
327 if (!(intEnabled & EUSCI_A_UART_BREAKCHAR_INTERRUPT))
328 {
329 intStatus &= ((uint_fast8_t)~EUSCI_A_UART_BREAKCHAR_INTERRUPT);
330 }
331
332 return intStatus;
333 }
334
UART_clearInterruptFlag(uint32_t moduleInstance,uint_fast8_t mask)335 void UART_clearInterruptFlag(uint32_t moduleInstance, uint_fast8_t mask)
336 {
337 ASSERT(
338 !(mask
339 & ~(EUSCI_A_UART_RECEIVE_INTERRUPT_FLAG
340 | EUSCI_A_UART_TRANSMIT_INTERRUPT_FLAG
341 | EUSCI_A_UART_STARTBIT_INTERRUPT_FLAG
342 | EUSCI_A_UART_TRANSMIT_COMPLETE_INTERRUPT_FLAG)));
343
344 //Clear the UART interrupt source.
345 EUSCI_A_CMSIS(moduleInstance)->IFG &= ~(mask);
346 }
347
UART_registerInterrupt(uint32_t moduleInstance,void (* intHandler)(void))348 void UART_registerInterrupt(uint32_t moduleInstance, void (*intHandler)(void))
349 {
350 switch (moduleInstance)
351 {
352 case EUSCI_A0_BASE:
353 Interrupt_registerInterrupt(INT_EUSCIA0, intHandler);
354 Interrupt_enableInterrupt(INT_EUSCIA0);
355 break;
356 case EUSCI_A1_BASE:
357 Interrupt_registerInterrupt(INT_EUSCIA1, intHandler);
358 Interrupt_enableInterrupt(INT_EUSCIA1);
359 break;
360 #ifdef EUSCI_A2_BASE
361 case EUSCI_A2_BASE:
362 Interrupt_registerInterrupt(INT_EUSCIA2, intHandler);
363 Interrupt_enableInterrupt(INT_EUSCIA2);
364 break;
365 #endif
366 #ifdef EUSCI_A3_BASE
367 case EUSCI_A3_BASE:
368 Interrupt_registerInterrupt(INT_EUSCIA3, intHandler);
369 Interrupt_enableInterrupt(INT_EUSCIA3);
370 break;
371 #endif
372 default:
373 ASSERT(false);
374 }
375 }
376
UART_unregisterInterrupt(uint32_t moduleInstance)377 void UART_unregisterInterrupt(uint32_t moduleInstance)
378 {
379 switch (moduleInstance)
380 {
381 case EUSCI_A0_BASE:
382 Interrupt_disableInterrupt(INT_EUSCIA0);
383 Interrupt_unregisterInterrupt(INT_EUSCIA0);
384 break;
385 case EUSCI_A1_BASE:
386 Interrupt_disableInterrupt(INT_EUSCIA1);
387 Interrupt_unregisterInterrupt(INT_EUSCIA1);
388 break;
389 #ifdef EUSCI_A2_BASE
390 case EUSCI_A2_BASE:
391 Interrupt_disableInterrupt(INT_EUSCIA2);
392 Interrupt_unregisterInterrupt(INT_EUSCIA2);
393 break;
394 #endif
395 #ifdef EUSCI_A3_BASE
396 case EUSCI_A3_BASE:
397 Interrupt_disableInterrupt(INT_EUSCIA3);
398 Interrupt_unregisterInterrupt(INT_EUSCIA3);
399 break;
400 #endif
401 default:
402 ASSERT(false);
403 }
404 }
405