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