XMC_uart_c

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 5

1 /**

2 * @file xmc_uart.c
3 * @date 2020-12-05
4 *
5 * @cond
6 *****************************************************************************
7 * XMClib v2.2.0 - XMC Peripheral Driver Library
8 *
9 * Copyright (c) 2015-2020, Infineon Technologies AG
10 * All rights reserved.
11 *
12 * Boost Software License - Version 1.0 - August 17th, 2003
13 *
14 * Permission is hereby granted, free of charge, to any person or organization
15 * obtaining a copy of the software and accompanying documentation covered by
16 * this license (the "Software") to use, reproduce, display, distribute,
17 * execute, and transmit the Software, and to prepare derivative works of the
18 * Software, and to permit third-parties to whom the Software is furnished to
19 * do so, all subject to the following:
20 *
21 * The copyright notices in the Software and this entire statement, including
22 * the above license grant, this restriction and the following disclaimer,
23 * must be included in all copies of the Software, in whole or in part, and
24 * all derivative works of the Software, unless such copies or derivative
25 * works are solely in the form of machine-executable object code generated by
26 * a source language processor.
27 *
28 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
29 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
30 * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
31 * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
32 * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
33 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
34 * DEALINGS IN THE SOFTWARE.
35 *
36 * To improve the quality of the software, users are encouraged to share
37 * modifications, enhancements or bug fixes with Infineon Technologies AG
38 * at XMCSupport@infineon.com.
39 *****************************************************************************
40 *
41 * Change History
42 * --------------
43 *
44 * 2015-02-20:
45 * - Initial <br>
46 *
47 * 2015-05-20:
48 * - xmc_uart_ch_stop API implementation corrected.
49 * - Modified XMC_UART_CH_Stop() API for not setting to IDLE the channel if it is
busy <br>
50 *
51 * 2015-06-20:
52 * - Removed GetDriverVersion API <br>
53 *
54 * 2015-09-01:
55 * - Modified XMC_UART_CH_EnableEvent() and XMC_UART_CH_DisableEvent() for
supporting multiple events configuration <br>
56 *
57 * 2016-07-22:
58 * - Modified XMC_UART_CH_Init() to enable transfer status BUSY
59 * - Modified XMC_UART_CH_Stop() to check for transfer status
60 *
61 * 2019-05-07:
62 * - Added XMC_UART_CH_SetBaudrateEx() which allows to select between baudrate
generator normal divider and fractional divider mode
63 *
64 * 2019-07-01:
65 * - Fix XMC_UART_CH_SetBaudrateEx() compiler warning
66 *
67 * 2019-12-16:
68 * - Fix including files following the convention: angle brackets are used for
standard includes and double quotes for everything else.
69 *
70 * 2020-12-05:
71 * - Added XMC_UART_CH_InitEx that allows user select if automatic baudrate
configuration should be done or not
72 *
73 * @endcond
74 *
75 */
76
77 /*************************************************************************************
********************************
78 * HEADER FILES
79
*************************************************************************************
********************************/
80
81 #include "xmc_scu.h"
82 #include "xmc_uart.h"
83
84 /*************************************************************************************
********************************
85 * MACROS
86
*************************************************************************************
********************************/
87
88 #define XMC_UART_CH_OVERSAMPLING (16UL)
89 #define XMC_UART_CH_OVERSAMPLING_MIN_VAL (4UL)
90
91 /*************************************************************************************
********************************
92 * API IMPLEMENTATION
93
*************************************************************************************
********************************/
94
95 void XMC_UART_CH_InitEx(XMC_USIC_CH_t *channel, const XMC_UART_CH_CONFIG_t *const
config, bool init_brg)
96 {
97 uint32_t oversampling = XMC_UART_CH_OVERSAMPLING;
98
99 /* USIC channel switched on*/
100 XMC_USIC_CH_Enable(channel);
101
102 if (config->oversampling != 0U)
103 {
104 oversampling = (uint32_t)config->oversampling;
105 }
106
107 if (init_brg)
108 {
109 /* Configure baud rate */
110 if (config->normal_divider_mode)
111 {
112 /* Normal divider mode */
113 (void)XMC_USIC_CH_SetBaudrateEx(channel, config->baudrate, oversampling);
114 }
115 else
116 {
117 /* Fractional divider mode */
118 (void)XMC_USIC_CH_SetBaudrate(channel, config->baudrate, oversampling);
119 }
120 }
121
122 /* Configure frame format
123 * Configure the number of stop bits
124 * Pulse length is set to 0 to have standard UART signaling,
125 * i.e. the 0 level is signaled during the complete bit time
126 * Sampling point set equal to the half of the oversampling period
127 * Enable Sample Majority Decision
128 * Enable Transfer Status BUSY
129 */
130 channel->PCR_ASCMode = (uint32_t)(((config->stop_bits - 1UL) <<
USIC_CH_PCR_ASCMode_STPB_Pos) |
131 (((oversampling >> 1UL) + 1UL) <<
USIC_CH_PCR_ASCMode_SP_Pos) |
132 USIC_CH_PCR_ASCMode_SMD_Msk |
133 USIC_CH_PCR_ASCMode_RSTEN_Msk |
USIC_CH_PCR_ASCMode_TSTEN_Msk);
134
135 /* Set passive data level, high
136 Set word length. Data bits - 1
137 If frame length is > 0, frame_lemgth-1; else, FLE = WLE (Data bits - 1)
138 Transmission Mode: The shift control signal is considered active if it
139 is at 1-level. This is the setting to be programmed to allow data transfers */
140 channel->SCTR = (uint32_t)((((uint32_t)config->data_bits - 1UL) <<
USIC_CH_SCTR_WLE_Pos) |
141 ((0x1UL << USIC_CH_SCTR_TRM_Pos) | USIC_CH_SCTR_PDL_Msk
));
142
143 if (config->frame_length != 0U)
144 {
145 channel->SCTR |= (uint32_t)(((uint32_t)config->frame_length - 1UL) <<
USIC_CH_SCTR_FLE_Pos);
146 }
147 else
148 {
149 channel->SCTR |= (uint32_t)(((uint32_t)config->data_bits - 1UL) <<
USIC_CH_SCTR_FLE_Pos);
150 }
151
152 /* Enable transfer buffer */
153 channel->TCSR = (0x1UL << USIC_CH_TCSR_TDEN_Pos) |
154 USIC_CH_TCSR_TDSSM_Msk;
155
156 /* Clear protocol status */
157 channel->PSCR = 0xFFFFFFFFUL;
158
159 /* Set parity settings */
160 channel->CCR = (uint32_t)config->parity_mode;
161 }
162
163 XMC_UART_CH_STATUS_t XMC_UART_CH_SetBaudrate(XMC_USIC_CH_t *const channel, uint32_t
rate, uint32_t oversampling)
164 {
165 XMC_UART_CH_STATUS_t status;
166
167 status = XMC_UART_CH_STATUS_ERROR;
168
169 if ((rate <= (XMC_SCU_CLOCK_GetPeripheralClockFrequency() >> 2U)) && (oversampling
>= XMC_UART_CH_OVERSAMPLING_MIN_VAL))
170 {
171 if (XMC_USIC_CH_SetBaudrate(channel, rate, oversampling) == XMC_USIC_CH_STATUS_OK)
172 {
173 status = XMC_UART_CH_STATUS_OK;
174 }
175 }
176 return status;
177 }
178
179 XMC_UART_CH_STATUS_t XMC_UART_CH_SetBaudrateEx(XMC_USIC_CH_t *const channel, uint32_t
rate, uint32_t oversampling, bool normal_divider_mode)
180 {
181 XMC_USIC_CH_STATUS_t status;
182
183 if ((rate <= (XMC_SCU_CLOCK_GetPeripheralClockFrequency() >> 2U)) && (oversampling
>= XMC_UART_CH_OVERSAMPLING_MIN_VAL))
184 {
185 if (normal_divider_mode)
186 {
187 /* Normal divider mode */
188 status = XMC_USIC_CH_SetBaudrateEx(channel, rate, oversampling);
189 }
190 else
191 {
192 /* Fractional divider mode */
193 status = XMC_USIC_CH_SetBaudrate(channel, rate, oversampling);
194 }
195 }
196 else
197 {
198 status = XMC_USIC_CH_STATUS_ERROR;
199 }
200
201 return (XMC_UART_CH_STATUS_t)status;
202 }
203
204 void XMC_UART_CH_Transmit(XMC_USIC_CH_t *const channel, const uint16_t data)
205 {
206 /* Check FIFO size */
207 if ((channel->TBCTR & USIC_CH_TBCTR_SIZE_Msk) == 0UL)
208 {
209 /* Wait till the Transmit Buffer is free for transmission */
210 while (XMC_USIC_CH_GetTransmitBufferStatus(channel) ==
XMC_USIC_CH_TBUF_STATUS_BUSY)
211 {
212 }
213
214 /* Clear the Transmit Buffer indication flag */
215 XMC_UART_CH_ClearStatusFlag(channel, (uint32_t)
XMC_UART_CH_STATUS_FLAG_TRANSMIT_BUFFER_INDICATION);
216
217 /*Transmit data */
218 channel->TBUF[0U] = data;
219 }
220 else
221 {
222 channel->IN[0U] = data;
223 }
224 }
225
226 uint16_t XMC_UART_CH_GetReceivedData(XMC_USIC_CH_t *const channel)
227 {
228 uint16_t retval;
229
230 /* Check FIFO size */
231 if ((channel->RBCTR & USIC_CH_RBCTR_SIZE_Msk) == 0U)
232 {
233 retval = (uint16_t)channel->RBUF;
234 }
235 else
236 {
237 retval = (uint16_t)channel->OUTR;
238 }
239
240 return retval;
241 }
242
243 XMC_UART_CH_STATUS_t XMC_UART_CH_Stop(XMC_USIC_CH_t *const channel)
244 {
245 XMC_UART_CH_STATUS_t status = XMC_UART_CH_STATUS_OK;
246
247 if (((XMC_USIC_CH_GetTransmitBufferStatus(channel) & (uint32_t)
XMC_USIC_CH_TBUF_STATUS_BUSY) != 0U) ||
248 ((XMC_UART_CH_GetStatusFlag(channel) &
XMC_UART_CH_STATUS_FLAG_TRANSFER_STATUS_BUSY) != 0))
249 {
250 status = XMC_UART_CH_STATUS_BUSY;
251 }
252 else
253 {
254 /* USIC channel in IDLE mode */
255 XMC_USIC_CH_SetMode(channel, XMC_USIC_CH_OPERATING_MODE_IDLE);
256 }
257 return status;
258 }
259
260 void XMC_UART_CH_EnableEvent(XMC_USIC_CH_t *const channel, const uint32_t event)
261 {
262 channel->CCR |= (event & 0x1fc00U);
263 channel->PCR_ASCMode |= (event & 0xf8U);
264 }
265
266 void XMC_UART_CH_DisableEvent(XMC_USIC_CH_t *const channel, const uint32_t event)
267 {
268 channel->CCR &= (uint32_t)~(event & 0x1fc00U);
269 channel->PCR_ASCMode &= (uint32_t)~(event & 0xf8U);
270 }
271

You might also like