added prescaler for 16 bit pwm in LPC1347 target

Fork of mbed-dev by mbed official

Committer:
JojoS
Date:
Sat Sep 10 15:32:04 2016 +0000
Revision:
147:ba84b7dc41a7
Parent:
144:ef7eb2e8f9f7
added prescaler for 16 bit timers (solution as in LPC11xx), default prescaler 31 for max 28 ms period time

Who changed what in which revision?

UserRevisionLine numberNew contents of line
<> 144:ef7eb2e8f9f7 1 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 2 * @file em_usart.c
<> 144:ef7eb2e8f9f7 3 * @brief Universal synchronous/asynchronous receiver/transmitter (USART/UART)
<> 144:ef7eb2e8f9f7 4 * Peripheral API
<> 144:ef7eb2e8f9f7 5 * @version 4.2.1
<> 144:ef7eb2e8f9f7 6 *******************************************************************************
<> 144:ef7eb2e8f9f7 7 * @section License
<> 144:ef7eb2e8f9f7 8 * <b>(C) Copyright 2015 Silicon Labs, http://www.silabs.com</b>
<> 144:ef7eb2e8f9f7 9 *******************************************************************************
<> 144:ef7eb2e8f9f7 10 *
<> 144:ef7eb2e8f9f7 11 * Permission is granted to anyone to use this software for any purpose,
<> 144:ef7eb2e8f9f7 12 * including commercial applications, and to alter it and redistribute it
<> 144:ef7eb2e8f9f7 13 * freely, subject to the following restrictions:
<> 144:ef7eb2e8f9f7 14 *
<> 144:ef7eb2e8f9f7 15 * 1. The origin of this software must not be misrepresented; you must not
<> 144:ef7eb2e8f9f7 16 * claim that you wrote the original software.
<> 144:ef7eb2e8f9f7 17 * 2. Altered source versions must be plainly marked as such, and must not be
<> 144:ef7eb2e8f9f7 18 * misrepresented as being the original software.
<> 144:ef7eb2e8f9f7 19 * 3. This notice may not be removed or altered from any source distribution.
<> 144:ef7eb2e8f9f7 20 *
<> 144:ef7eb2e8f9f7 21 * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
<> 144:ef7eb2e8f9f7 22 * obligation to support this Software. Silicon Labs is providing the
<> 144:ef7eb2e8f9f7 23 * Software "AS IS", with no express or implied warranties of any kind,
<> 144:ef7eb2e8f9f7 24 * including, but not limited to, any implied warranties of merchantability
<> 144:ef7eb2e8f9f7 25 * or fitness for any particular purpose or warranties against infringement
<> 144:ef7eb2e8f9f7 26 * of any proprietary rights of a third party.
<> 144:ef7eb2e8f9f7 27 *
<> 144:ef7eb2e8f9f7 28 * Silicon Labs will not be liable for any consequential, incidental, or
<> 144:ef7eb2e8f9f7 29 * special damages, or any other relief, or for any claim by any third party,
<> 144:ef7eb2e8f9f7 30 * arising from your use of this Software.
<> 144:ef7eb2e8f9f7 31 *
<> 144:ef7eb2e8f9f7 32 ******************************************************************************/
<> 144:ef7eb2e8f9f7 33
<> 144:ef7eb2e8f9f7 34 #include "em_usart.h"
<> 144:ef7eb2e8f9f7 35 #if defined(USART_COUNT) && (USART_COUNT > 0)
<> 144:ef7eb2e8f9f7 36
<> 144:ef7eb2e8f9f7 37 #include "em_cmu.h"
<> 144:ef7eb2e8f9f7 38 #include "em_bus.h"
<> 144:ef7eb2e8f9f7 39 #include "em_assert.h"
<> 144:ef7eb2e8f9f7 40
<> 144:ef7eb2e8f9f7 41 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 42 * @addtogroup EM_Library
<> 144:ef7eb2e8f9f7 43 * @{
<> 144:ef7eb2e8f9f7 44 ******************************************************************************/
<> 144:ef7eb2e8f9f7 45
<> 144:ef7eb2e8f9f7 46 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 47 * @addtogroup USART
<> 144:ef7eb2e8f9f7 48 * @brief Universal Synchronous/Asynchronous Receiver/Transmitter
<> 144:ef7eb2e8f9f7 49 * Peripheral API
<> 144:ef7eb2e8f9f7 50 * @{
<> 144:ef7eb2e8f9f7 51 ******************************************************************************/
<> 144:ef7eb2e8f9f7 52
<> 144:ef7eb2e8f9f7 53 /*******************************************************************************
<> 144:ef7eb2e8f9f7 54 ******************************* DEFINES ***********************************
<> 144:ef7eb2e8f9f7 55 ******************************************************************************/
<> 144:ef7eb2e8f9f7 56
<> 144:ef7eb2e8f9f7 57 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
<> 144:ef7eb2e8f9f7 58
<> 144:ef7eb2e8f9f7 59
<> 144:ef7eb2e8f9f7 60 /** Validation of USART register block pointer reference for assert statements. */
<> 144:ef7eb2e8f9f7 61 #if (USART_COUNT == 1) && defined(USART0)
<> 144:ef7eb2e8f9f7 62 #define USART_REF_VALID(ref) ((ref) == USART0)
<> 144:ef7eb2e8f9f7 63
<> 144:ef7eb2e8f9f7 64 #elif (USART_COUNT == 1) && defined(USART1)
<> 144:ef7eb2e8f9f7 65 #define USART_REF_VALID(ref) ((ref) == USART1)
<> 144:ef7eb2e8f9f7 66
<> 144:ef7eb2e8f9f7 67 #elif (USART_COUNT == 2) && defined(USART2)
<> 144:ef7eb2e8f9f7 68 #define USART_REF_VALID(ref) (((ref) == USART1) || ((ref) == USART2))
<> 144:ef7eb2e8f9f7 69
<> 144:ef7eb2e8f9f7 70 #elif (USART_COUNT == 2)
<> 144:ef7eb2e8f9f7 71 #define USART_REF_VALID(ref) (((ref) == USART0) || ((ref) == USART1))
<> 144:ef7eb2e8f9f7 72
<> 144:ef7eb2e8f9f7 73 #elif (USART_COUNT == 3)
<> 144:ef7eb2e8f9f7 74 #define USART_REF_VALID(ref) (((ref) == USART0) || ((ref) == USART1) || \
<> 144:ef7eb2e8f9f7 75 ((ref) == USART2))
<> 144:ef7eb2e8f9f7 76 #elif (USART_COUNT == 4)
<> 144:ef7eb2e8f9f7 77 #define USART_REF_VALID(ref) (((ref) == USART0) || ((ref) == USART1) || \
<> 144:ef7eb2e8f9f7 78 ((ref) == USART2) || ((ref) == USART3))
<> 144:ef7eb2e8f9f7 79 #elif (USART_COUNT == 5)
<> 144:ef7eb2e8f9f7 80 #define USART_REF_VALID(ref) (((ref) == USART0) || ((ref) == USART1) || \
<> 144:ef7eb2e8f9f7 81 ((ref) == USART2) || ((ref) == USART3) || \
<> 144:ef7eb2e8f9f7 82 ((ref) == USART4))
<> 144:ef7eb2e8f9f7 83 #elif (USART_COUNT == 6)
<> 144:ef7eb2e8f9f7 84 #define USART_REF_VALID(ref) (((ref) == USART0) || ((ref) == USART1) || \
<> 144:ef7eb2e8f9f7 85 ((ref) == USART2) || ((ref) == USART3) || \
<> 144:ef7eb2e8f9f7 86 ((ref) == USART4) || ((ref) == USART5))
<> 144:ef7eb2e8f9f7 87 #else
<> 144:ef7eb2e8f9f7 88 #error "Undefined number of USARTs."
<> 144:ef7eb2e8f9f7 89 #endif
<> 144:ef7eb2e8f9f7 90
<> 144:ef7eb2e8f9f7 91 #if defined(USARTRF_COUNT) && (USARTRF_COUNT > 0)
<> 144:ef7eb2e8f9f7 92 #if (USARTRF_COUNT == 1) && defined(USARTRF0)
<> 144:ef7eb2e8f9f7 93 #define USARTRF_REF_VALID(ref) ((ref) == USARTRF0)
<> 144:ef7eb2e8f9f7 94 #elif (USARTRF_COUNT == 1) && defined(USARTRF1)
<> 144:ef7eb2e8f9f7 95 #define USARTRF_REF_VALID(ref) ((ref) == USARTRF1)
<> 144:ef7eb2e8f9f7 96 #else
<> 144:ef7eb2e8f9f7 97 #define USARTRF_REF_VALID(ref) (0)
<> 144:ef7eb2e8f9f7 98 #endif
<> 144:ef7eb2e8f9f7 99 #else
<> 144:ef7eb2e8f9f7 100 #define USARTRF_REF_VALID(ref) (0)
<> 144:ef7eb2e8f9f7 101 #endif
<> 144:ef7eb2e8f9f7 102
<> 144:ef7eb2e8f9f7 103 #if defined(_EZR32_HAPPY_FAMILY)
<> 144:ef7eb2e8f9f7 104 #define USART_IRDA_VALID(ref) ((ref) == USART0)
<> 144:ef7eb2e8f9f7 105 #elif defined(_EFM32_HAPPY_FAMILY)
<> 144:ef7eb2e8f9f7 106 #define USART_IRDA_VALID(ref) (((ref) == USART0) || ((ref) == USART1))
<> 144:ef7eb2e8f9f7 107 #elif defined(USART0)
<> 144:ef7eb2e8f9f7 108 #define USART_IRDA_VALID(ref) ((ref) == USART0)
<> 144:ef7eb2e8f9f7 109 #elif (USART_COUNT == 1) && defined(USART1)
<> 144:ef7eb2e8f9f7 110 #define USART_IRDA_VALID(ref) ((ref) == USART1)
<> 144:ef7eb2e8f9f7 111 #else
<> 144:ef7eb2e8f9f7 112 #define USART_IRDA_VALID(ref) (0)
<> 144:ef7eb2e8f9f7 113 #endif
<> 144:ef7eb2e8f9f7 114
<> 144:ef7eb2e8f9f7 115 #if defined(_EZR32_HAPPY_FAMILY)
<> 144:ef7eb2e8f9f7 116 #define USART_I2S_VALID(ref) ((ref) == USART0)
<> 144:ef7eb2e8f9f7 117 #elif defined(_EFM32_HAPPY_FAMILY)
<> 144:ef7eb2e8f9f7 118 #define USART_I2S_VALID(ref) (((ref) == USART0) || ((ref) == USART1))
<> 144:ef7eb2e8f9f7 119 #elif defined(_EFM32_TINY_FAMILY) || defined(_EFM32_ZERO_FAMILY) || defined(_SILICON_LABS_32B_PLATFORM_2)
<> 144:ef7eb2e8f9f7 120 #define USART_I2S_VALID(ref) ((ref) == USART1)
<> 144:ef7eb2e8f9f7 121 #elif defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
<> 144:ef7eb2e8f9f7 122 #define USART_I2S_VALID(ref) (((ref) == USART1) || ((ref) == USART2))
<> 144:ef7eb2e8f9f7 123 #endif
<> 144:ef7eb2e8f9f7 124
<> 144:ef7eb2e8f9f7 125 #if (UART_COUNT == 1)
<> 144:ef7eb2e8f9f7 126 #define UART_REF_VALID(ref) ((ref) == UART0)
<> 144:ef7eb2e8f9f7 127 #elif (UART_COUNT == 2)
<> 144:ef7eb2e8f9f7 128 #define UART_REF_VALID(ref) (((ref) == UART0) || ((ref) == UART1))
<> 144:ef7eb2e8f9f7 129 #else
<> 144:ef7eb2e8f9f7 130 #define UART_REF_VALID(ref) (0)
<> 144:ef7eb2e8f9f7 131 #endif
<> 144:ef7eb2e8f9f7 132
<> 144:ef7eb2e8f9f7 133 /** @endcond */
<> 144:ef7eb2e8f9f7 134
<> 144:ef7eb2e8f9f7 135
<> 144:ef7eb2e8f9f7 136 /*******************************************************************************
<> 144:ef7eb2e8f9f7 137 ************************** GLOBAL FUNCTIONS *******************************
<> 144:ef7eb2e8f9f7 138 ******************************************************************************/
<> 144:ef7eb2e8f9f7 139
<> 144:ef7eb2e8f9f7 140 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 141 * @brief
<> 144:ef7eb2e8f9f7 142 * Configure USART/UART operating in asynchronous mode to use a given
<> 144:ef7eb2e8f9f7 143 * baudrate (or as close as possible to specified baudrate).
<> 144:ef7eb2e8f9f7 144 *
<> 144:ef7eb2e8f9f7 145 * @param[in] usart
<> 144:ef7eb2e8f9f7 146 * Pointer to USART/UART peripheral register block.
<> 144:ef7eb2e8f9f7 147 *
<> 144:ef7eb2e8f9f7 148 * @param[in] refFreq
<> 144:ef7eb2e8f9f7 149 * USART/UART reference clock frequency in Hz that will be used. If set to 0,
<> 144:ef7eb2e8f9f7 150 * the currently configured reference clock is assumed.
<> 144:ef7eb2e8f9f7 151 *
<> 144:ef7eb2e8f9f7 152 * @param[in] baudrate
<> 144:ef7eb2e8f9f7 153 * Baudrate to try to achieve for USART/UART.
<> 144:ef7eb2e8f9f7 154 *
<> 144:ef7eb2e8f9f7 155 * @param[in] ovs
<> 144:ef7eb2e8f9f7 156 * Oversampling to be used. Normal is 16x oversampling, but lower oversampling
<> 144:ef7eb2e8f9f7 157 * may be used to achieve higher rates or better baudrate accuracy in some
<> 144:ef7eb2e8f9f7 158 * cases. Notice that lower oversampling frequency makes channel more
<> 144:ef7eb2e8f9f7 159 * vulnerable to bit faults during reception due to clock inaccuracies
<> 144:ef7eb2e8f9f7 160 * compared to link partner.
<> 144:ef7eb2e8f9f7 161 ******************************************************************************/
<> 144:ef7eb2e8f9f7 162 void USART_BaudrateAsyncSet(USART_TypeDef *usart,
<> 144:ef7eb2e8f9f7 163 uint32_t refFreq,
<> 144:ef7eb2e8f9f7 164 uint32_t baudrate,
<> 144:ef7eb2e8f9f7 165 USART_OVS_TypeDef ovs)
<> 144:ef7eb2e8f9f7 166 {
<> 144:ef7eb2e8f9f7 167 uint32_t clkdiv;
<> 144:ef7eb2e8f9f7 168 uint32_t oversample;
<> 144:ef7eb2e8f9f7 169
<> 144:ef7eb2e8f9f7 170 /* Inhibit divide by 0 */
<> 144:ef7eb2e8f9f7 171 EFM_ASSERT(baudrate);
<> 144:ef7eb2e8f9f7 172
<> 144:ef7eb2e8f9f7 173 /*
<> 144:ef7eb2e8f9f7 174 * We want to use integer division to avoid forcing in float division
<> 144:ef7eb2e8f9f7 175 * utils, and yet keep rounding effect errors to a minimum.
<> 144:ef7eb2e8f9f7 176 *
<> 144:ef7eb2e8f9f7 177 * CLKDIV in asynchronous mode is given by:
<> 144:ef7eb2e8f9f7 178 *
<> 144:ef7eb2e8f9f7 179 * CLKDIV = 256 * (fHFPERCLK/(oversample * br) - 1)
<> 144:ef7eb2e8f9f7 180 * or
<> 144:ef7eb2e8f9f7 181 * CLKDIV = (256 * fHFPERCLK)/(oversample * br) - 256
<> 144:ef7eb2e8f9f7 182 *
<> 144:ef7eb2e8f9f7 183 * The basic problem with integer division in the above formula is that
<> 144:ef7eb2e8f9f7 184 * the dividend (256 * fHFPERCLK) may become higher than max 32 bit
<> 144:ef7eb2e8f9f7 185 * integer. Yet, we want to evaluate dividend first before dividing in
<> 144:ef7eb2e8f9f7 186 * order to get as small rounding effects as possible. We do not want
<> 144:ef7eb2e8f9f7 187 * to make too harsh restrictions on max fHFPERCLK value either.
<> 144:ef7eb2e8f9f7 188 *
<> 144:ef7eb2e8f9f7 189 * One can possibly factorize 256 and oversample/br. However,
<> 144:ef7eb2e8f9f7 190 * since the last 6 or 3 bits of CLKDIV are don't care, we can base our
<> 144:ef7eb2e8f9f7 191 * integer arithmetic on the below formula
<> 144:ef7eb2e8f9f7 192 *
<> 144:ef7eb2e8f9f7 193 * CLKDIV / 64 = (4 * fHFPERCLK)/(oversample * br) - 4 (3 bits dont care)
<> 144:ef7eb2e8f9f7 194 * or
<> 144:ef7eb2e8f9f7 195 * CLKDIV / 8 = (32 * fHFPERCLK)/(oversample * br) - 32 (6 bits dont care)
<> 144:ef7eb2e8f9f7 196 *
<> 144:ef7eb2e8f9f7 197 * and calculate 1/64 of CLKDIV first. This allows for fHFPERCLK
<> 144:ef7eb2e8f9f7 198 * up to 1GHz without overflowing a 32 bit value!
<> 144:ef7eb2e8f9f7 199 */
<> 144:ef7eb2e8f9f7 200
<> 144:ef7eb2e8f9f7 201 /* HFPERCLK used to clock all USART/UART peripheral modules */
<> 144:ef7eb2e8f9f7 202 if (!refFreq)
<> 144:ef7eb2e8f9f7 203 {
<> 144:ef7eb2e8f9f7 204 refFreq = CMU_ClockFreqGet(cmuClock_HFPER);
<> 144:ef7eb2e8f9f7 205 }
<> 144:ef7eb2e8f9f7 206
<> 144:ef7eb2e8f9f7 207 /* Map oversampling */
<> 144:ef7eb2e8f9f7 208 switch (ovs)
<> 144:ef7eb2e8f9f7 209 {
<> 144:ef7eb2e8f9f7 210 case USART_CTRL_OVS_X16:
<> 144:ef7eb2e8f9f7 211 EFM_ASSERT(baudrate <= (refFreq / 16));
<> 144:ef7eb2e8f9f7 212 oversample = 16;
<> 144:ef7eb2e8f9f7 213 break;
<> 144:ef7eb2e8f9f7 214
<> 144:ef7eb2e8f9f7 215 case USART_CTRL_OVS_X8:
<> 144:ef7eb2e8f9f7 216 EFM_ASSERT(baudrate <= (refFreq / 8));
<> 144:ef7eb2e8f9f7 217 oversample = 8;
<> 144:ef7eb2e8f9f7 218 break;
<> 144:ef7eb2e8f9f7 219
<> 144:ef7eb2e8f9f7 220 case USART_CTRL_OVS_X6:
<> 144:ef7eb2e8f9f7 221 EFM_ASSERT(baudrate <= (refFreq / 6));
<> 144:ef7eb2e8f9f7 222 oversample = 6;
<> 144:ef7eb2e8f9f7 223 break;
<> 144:ef7eb2e8f9f7 224
<> 144:ef7eb2e8f9f7 225 case USART_CTRL_OVS_X4:
<> 144:ef7eb2e8f9f7 226 EFM_ASSERT(baudrate <= (refFreq / 4));
<> 144:ef7eb2e8f9f7 227 oversample = 4;
<> 144:ef7eb2e8f9f7 228 break;
<> 144:ef7eb2e8f9f7 229
<> 144:ef7eb2e8f9f7 230 default:
<> 144:ef7eb2e8f9f7 231 /* Invalid input */
<> 144:ef7eb2e8f9f7 232 EFM_ASSERT(0);
<> 144:ef7eb2e8f9f7 233 return;
<> 144:ef7eb2e8f9f7 234 }
<> 144:ef7eb2e8f9f7 235
<> 144:ef7eb2e8f9f7 236 /* Calculate and set CLKDIV with fractional bits.
<> 144:ef7eb2e8f9f7 237 * The addend (oversample*baudrate)/2 in the first line is to round the
<> 144:ef7eb2e8f9f7 238 * divisor up by half the divisor before the division in order to reduce the
<> 144:ef7eb2e8f9f7 239 * integer division error, which consequently results in a higher baudrate
<> 144:ef7eb2e8f9f7 240 * than desired. */
<> 144:ef7eb2e8f9f7 241 #if defined(_USART_CLKDIV_DIV_MASK) && (_USART_CLKDIV_DIV_MASK >= 0x7FFFF8UL)
<> 144:ef7eb2e8f9f7 242 clkdiv = 32 * refFreq + (oversample * baudrate) / 2;
<> 144:ef7eb2e8f9f7 243 clkdiv /= (oversample * baudrate);
<> 144:ef7eb2e8f9f7 244 clkdiv -= 32;
<> 144:ef7eb2e8f9f7 245 clkdiv *= 8;
<> 144:ef7eb2e8f9f7 246 #else
<> 144:ef7eb2e8f9f7 247 clkdiv = 4 * refFreq + (oversample * baudrate) / 2;
<> 144:ef7eb2e8f9f7 248 clkdiv /= (oversample * baudrate);
<> 144:ef7eb2e8f9f7 249 clkdiv -= 4;
<> 144:ef7eb2e8f9f7 250 clkdiv *= 64;
<> 144:ef7eb2e8f9f7 251 #endif
<> 144:ef7eb2e8f9f7 252
<> 144:ef7eb2e8f9f7 253 /* Verify that resulting clock divider is within limits */
<> 144:ef7eb2e8f9f7 254 EFM_ASSERT(clkdiv <= _USART_CLKDIV_DIV_MASK);
<> 144:ef7eb2e8f9f7 255
<> 144:ef7eb2e8f9f7 256 /* If EFM_ASSERT is not enabled, make sure we don't write to reserved bits */
<> 144:ef7eb2e8f9f7 257 clkdiv &= _USART_CLKDIV_DIV_MASK;
<> 144:ef7eb2e8f9f7 258
<> 144:ef7eb2e8f9f7 259 usart->CTRL &= ~_USART_CTRL_OVS_MASK;
<> 144:ef7eb2e8f9f7 260 usart->CTRL |= ovs;
<> 144:ef7eb2e8f9f7 261 usart->CLKDIV = clkdiv;
<> 144:ef7eb2e8f9f7 262 }
<> 144:ef7eb2e8f9f7 263
<> 144:ef7eb2e8f9f7 264
<> 144:ef7eb2e8f9f7 265 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 266 * @brief
<> 144:ef7eb2e8f9f7 267 * Calculate baudrate for USART/UART given reference frequency, clock division
<> 144:ef7eb2e8f9f7 268 * and oversampling rate (if async mode).
<> 144:ef7eb2e8f9f7 269 *
<> 144:ef7eb2e8f9f7 270 * @details
<> 144:ef7eb2e8f9f7 271 * This function returns the baudrate that a USART/UART module will use if
<> 144:ef7eb2e8f9f7 272 * configured with the given frequency, clock divisor and mode. Notice that
<> 144:ef7eb2e8f9f7 273 * this function will not use actual HW configuration. It can be used
<> 144:ef7eb2e8f9f7 274 * to determinate if a given configuration is sufficiently accurate for the
<> 144:ef7eb2e8f9f7 275 * application.
<> 144:ef7eb2e8f9f7 276 *
<> 144:ef7eb2e8f9f7 277 * @param[in] refFreq
<> 144:ef7eb2e8f9f7 278 * USART/UART HF peripheral frequency used.
<> 144:ef7eb2e8f9f7 279 *
<> 144:ef7eb2e8f9f7 280 * @param[in] clkdiv
<> 144:ef7eb2e8f9f7 281 * Clock division factor to be used.
<> 144:ef7eb2e8f9f7 282 *
<> 144:ef7eb2e8f9f7 283 * @param[in] syncmode
<> 144:ef7eb2e8f9f7 284 * @li true - synchronous mode operation.
<> 144:ef7eb2e8f9f7 285 * @li false - asynchronous mode operation.
<> 144:ef7eb2e8f9f7 286 *
<> 144:ef7eb2e8f9f7 287 * @param[in] ovs
<> 144:ef7eb2e8f9f7 288 * Oversampling used if asynchronous mode. Not used if @p syncmode is true.
<> 144:ef7eb2e8f9f7 289 *
<> 144:ef7eb2e8f9f7 290 * @return
<> 144:ef7eb2e8f9f7 291 * Baudrate with given settings.
<> 144:ef7eb2e8f9f7 292 ******************************************************************************/
<> 144:ef7eb2e8f9f7 293 uint32_t USART_BaudrateCalc(uint32_t refFreq,
<> 144:ef7eb2e8f9f7 294 uint32_t clkdiv,
<> 144:ef7eb2e8f9f7 295 bool syncmode,
<> 144:ef7eb2e8f9f7 296 USART_OVS_TypeDef ovs)
<> 144:ef7eb2e8f9f7 297 {
<> 144:ef7eb2e8f9f7 298 uint32_t oversample;
<> 144:ef7eb2e8f9f7 299 uint64_t divisor;
<> 144:ef7eb2e8f9f7 300 uint64_t factor;
<> 144:ef7eb2e8f9f7 301 uint64_t remainder;
<> 144:ef7eb2e8f9f7 302 uint64_t quotient;
<> 144:ef7eb2e8f9f7 303 uint32_t br;
<> 144:ef7eb2e8f9f7 304
<> 144:ef7eb2e8f9f7 305 /* Mask out unused bits */
<> 144:ef7eb2e8f9f7 306 clkdiv &= _USART_CLKDIV_MASK;
<> 144:ef7eb2e8f9f7 307
<> 144:ef7eb2e8f9f7 308 /* We want to use integer division to avoid forcing in float division */
<> 144:ef7eb2e8f9f7 309 /* utils, and yet keep rounding effect errors to a minimum. */
<> 144:ef7eb2e8f9f7 310
<> 144:ef7eb2e8f9f7 311 /* Baudrate calculation depends on if synchronous or asynchronous mode */
<> 144:ef7eb2e8f9f7 312 if (syncmode)
<> 144:ef7eb2e8f9f7 313 {
<> 144:ef7eb2e8f9f7 314 /*
<> 144:ef7eb2e8f9f7 315 * Baudrate is given by:
<> 144:ef7eb2e8f9f7 316 *
<> 144:ef7eb2e8f9f7 317 * br = fHFPERCLK/(2 * (1 + (CLKDIV / 256)))
<> 144:ef7eb2e8f9f7 318 *
<> 144:ef7eb2e8f9f7 319 * which can be rewritten to
<> 144:ef7eb2e8f9f7 320 *
<> 144:ef7eb2e8f9f7 321 * br = (128 * fHFPERCLK)/(256 + CLKDIV)
<> 144:ef7eb2e8f9f7 322 */
<> 144:ef7eb2e8f9f7 323 oversample = 1; /* Not used in sync mode, ie 1 */
<> 144:ef7eb2e8f9f7 324 factor = 128;
<> 144:ef7eb2e8f9f7 325 }
<> 144:ef7eb2e8f9f7 326 else
<> 144:ef7eb2e8f9f7 327 {
<> 144:ef7eb2e8f9f7 328 /*
<> 144:ef7eb2e8f9f7 329 * Baudrate in asynchronous mode is given by:
<> 144:ef7eb2e8f9f7 330 *
<> 144:ef7eb2e8f9f7 331 * br = fHFPERCLK/(oversample * (1 + (CLKDIV / 256)))
<> 144:ef7eb2e8f9f7 332 *
<> 144:ef7eb2e8f9f7 333 * which can be rewritten to
<> 144:ef7eb2e8f9f7 334 *
<> 144:ef7eb2e8f9f7 335 * br = (256 * fHFPERCLK)/(oversample * (256 + CLKDIV))
<> 144:ef7eb2e8f9f7 336 *
<> 144:ef7eb2e8f9f7 337 * First of all we can reduce the 256 factor of the dividend with
<> 144:ef7eb2e8f9f7 338 * (part of) oversample part of the divisor.
<> 144:ef7eb2e8f9f7 339 */
<> 144:ef7eb2e8f9f7 340
<> 144:ef7eb2e8f9f7 341 switch (ovs)
<> 144:ef7eb2e8f9f7 342 {
<> 144:ef7eb2e8f9f7 343 case USART_CTRL_OVS_X16:
<> 144:ef7eb2e8f9f7 344 oversample = 1;
<> 144:ef7eb2e8f9f7 345 factor = 256 / 16;
<> 144:ef7eb2e8f9f7 346 break;
<> 144:ef7eb2e8f9f7 347
<> 144:ef7eb2e8f9f7 348 case USART_CTRL_OVS_X8:
<> 144:ef7eb2e8f9f7 349 oversample = 1;
<> 144:ef7eb2e8f9f7 350 factor = 256 / 8;
<> 144:ef7eb2e8f9f7 351 break;
<> 144:ef7eb2e8f9f7 352
<> 144:ef7eb2e8f9f7 353 case USART_CTRL_OVS_X6:
<> 144:ef7eb2e8f9f7 354 oversample = 3;
<> 144:ef7eb2e8f9f7 355 factor = 256 / 2;
<> 144:ef7eb2e8f9f7 356 break;
<> 144:ef7eb2e8f9f7 357
<> 144:ef7eb2e8f9f7 358 default:
<> 144:ef7eb2e8f9f7 359 oversample = 1;
<> 144:ef7eb2e8f9f7 360 factor = 256 / 4;
<> 144:ef7eb2e8f9f7 361 break;
<> 144:ef7eb2e8f9f7 362 }
<> 144:ef7eb2e8f9f7 363 }
<> 144:ef7eb2e8f9f7 364
<> 144:ef7eb2e8f9f7 365 /*
<> 144:ef7eb2e8f9f7 366 * The basic problem with integer division in the above formula is that
<> 144:ef7eb2e8f9f7 367 * the dividend (factor * fHFPERCLK) may become larger than a 32 bit
<> 144:ef7eb2e8f9f7 368 * integer. Yet we want to evaluate dividend first before dividing in
<> 144:ef7eb2e8f9f7 369 * order to get as small rounding effects as possible. We do not want
<> 144:ef7eb2e8f9f7 370 * to make too harsh restrictions on max fHFPERCLK value either.
<> 144:ef7eb2e8f9f7 371 *
<> 144:ef7eb2e8f9f7 372 * For division a/b, we can write
<> 144:ef7eb2e8f9f7 373 *
<> 144:ef7eb2e8f9f7 374 * a = qb + r
<> 144:ef7eb2e8f9f7 375 *
<> 144:ef7eb2e8f9f7 376 * where q is the quotient and r is the remainder, both integers.
<> 144:ef7eb2e8f9f7 377 *
<> 144:ef7eb2e8f9f7 378 * The orignal baudrate formula can be rewritten as
<> 144:ef7eb2e8f9f7 379 *
<> 144:ef7eb2e8f9f7 380 * br = xa / b = x(qb + r)/b = xq + xr/b
<> 144:ef7eb2e8f9f7 381 *
<> 144:ef7eb2e8f9f7 382 * where x is 'factor', a is 'refFreq' and b is 'divisor', referring to
<> 144:ef7eb2e8f9f7 383 * variable names.
<> 144:ef7eb2e8f9f7 384 */
<> 144:ef7eb2e8f9f7 385
<> 144:ef7eb2e8f9f7 386 /* Divisor will never exceed max 32 bit value since clkdiv <= 0xFFFFF8 */
<> 144:ef7eb2e8f9f7 387 /* and 'oversample' has been reduced to <= 3. */
<> 144:ef7eb2e8f9f7 388 divisor = oversample * (256 + clkdiv);
<> 144:ef7eb2e8f9f7 389
<> 144:ef7eb2e8f9f7 390 quotient = refFreq / divisor;
<> 144:ef7eb2e8f9f7 391 remainder = refFreq % divisor;
<> 144:ef7eb2e8f9f7 392
<> 144:ef7eb2e8f9f7 393 /* factor <= 128 and since divisor >= 256, the below cannot exceed max */
<> 144:ef7eb2e8f9f7 394 /* 32 bit value. However, factor * remainder can become larger than 32-bit */
<> 144:ef7eb2e8f9f7 395 /* because of the size of _USART_CLKDIV_DIV_MASK on some families. */
<> 144:ef7eb2e8f9f7 396 br = (uint32_t)(factor * quotient);
<> 144:ef7eb2e8f9f7 397
<> 144:ef7eb2e8f9f7 398 /*
<> 144:ef7eb2e8f9f7 399 * factor <= 128 and remainder < (oversample*(256 + clkdiv)), which
<> 144:ef7eb2e8f9f7 400 * means dividend (factor * remainder) worst case is
<> 144:ef7eb2e8f9f7 401 * 128 * (3 * (256 + _USART_CLKDIV_DIV_MASK)) = 0x1_8001_7400.
<> 144:ef7eb2e8f9f7 402 */
<> 144:ef7eb2e8f9f7 403 br += (uint32_t)((factor * remainder) / divisor);
<> 144:ef7eb2e8f9f7 404
<> 144:ef7eb2e8f9f7 405 return br;
<> 144:ef7eb2e8f9f7 406 }
<> 144:ef7eb2e8f9f7 407
<> 144:ef7eb2e8f9f7 408
<> 144:ef7eb2e8f9f7 409 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 410 * @brief
<> 144:ef7eb2e8f9f7 411 * Get current baudrate for USART/UART.
<> 144:ef7eb2e8f9f7 412 *
<> 144:ef7eb2e8f9f7 413 * @details
<> 144:ef7eb2e8f9f7 414 * This function returns the actual baudrate (not considering oscillator
<> 144:ef7eb2e8f9f7 415 * inaccuracies) used by a USART/UART peripheral.
<> 144:ef7eb2e8f9f7 416 *
<> 144:ef7eb2e8f9f7 417 * @param[in] usart
<> 144:ef7eb2e8f9f7 418 * Pointer to USART/UART peripheral register block.
<> 144:ef7eb2e8f9f7 419 *
<> 144:ef7eb2e8f9f7 420 * @return
<> 144:ef7eb2e8f9f7 421 * Current baudrate.
<> 144:ef7eb2e8f9f7 422 ******************************************************************************/
<> 144:ef7eb2e8f9f7 423 uint32_t USART_BaudrateGet(USART_TypeDef *usart)
<> 144:ef7eb2e8f9f7 424 {
<> 144:ef7eb2e8f9f7 425 uint32_t freq;
<> 144:ef7eb2e8f9f7 426 USART_OVS_TypeDef ovs;
<> 144:ef7eb2e8f9f7 427 bool syncmode;
<> 144:ef7eb2e8f9f7 428
<> 144:ef7eb2e8f9f7 429 if (usart->CTRL & USART_CTRL_SYNC)
<> 144:ef7eb2e8f9f7 430 {
<> 144:ef7eb2e8f9f7 431 syncmode = true;
<> 144:ef7eb2e8f9f7 432 }
<> 144:ef7eb2e8f9f7 433 else
<> 144:ef7eb2e8f9f7 434 {
<> 144:ef7eb2e8f9f7 435 syncmode = false;
<> 144:ef7eb2e8f9f7 436 }
<> 144:ef7eb2e8f9f7 437
<> 144:ef7eb2e8f9f7 438 /* HFPERCLK used to clock all USART/UART peripheral modules */
<> 144:ef7eb2e8f9f7 439 freq = CMU_ClockFreqGet(cmuClock_HFPER);
<> 144:ef7eb2e8f9f7 440 ovs = (USART_OVS_TypeDef)(usart->CTRL & _USART_CTRL_OVS_MASK);
<> 144:ef7eb2e8f9f7 441 return USART_BaudrateCalc(freq, usart->CLKDIV, syncmode, ovs);
<> 144:ef7eb2e8f9f7 442 }
<> 144:ef7eb2e8f9f7 443
<> 144:ef7eb2e8f9f7 444
<> 144:ef7eb2e8f9f7 445 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 446 * @brief
<> 144:ef7eb2e8f9f7 447 * Configure USART operating in synchronous mode to use a given baudrate
<> 144:ef7eb2e8f9f7 448 * (or as close as possible to specified baudrate).
<> 144:ef7eb2e8f9f7 449 *
<> 144:ef7eb2e8f9f7 450 * @details
<> 144:ef7eb2e8f9f7 451 * The configuration will be set to use a baudrate <= the specified baudrate
<> 144:ef7eb2e8f9f7 452 * in order to ensure that the baudrate does not exceed the specified value.
<> 144:ef7eb2e8f9f7 453 *
<> 144:ef7eb2e8f9f7 454 * Fractional clock division is suppressed, although the HW design allows it.
<> 144:ef7eb2e8f9f7 455 * It could cause half clock cycles to exceed specified limit, and thus
<> 144:ef7eb2e8f9f7 456 * potentially violate specifications for the slave device. In some special
<> 144:ef7eb2e8f9f7 457 * situations fractional clock division may be useful even in synchronous
<> 144:ef7eb2e8f9f7 458 * mode, but in those cases it must be directly adjusted, possibly assisted
<> 144:ef7eb2e8f9f7 459 * by USART_BaudrateCalc():
<> 144:ef7eb2e8f9f7 460 *
<> 144:ef7eb2e8f9f7 461 * @param[in] usart
<> 144:ef7eb2e8f9f7 462 * Pointer to USART peripheral register block. (Cannot be used on UART
<> 144:ef7eb2e8f9f7 463 * modules.)
<> 144:ef7eb2e8f9f7 464 *
<> 144:ef7eb2e8f9f7 465 * @param[in] refFreq
<> 144:ef7eb2e8f9f7 466 * USART reference clock frequency in Hz that will be used. If set to 0,
<> 144:ef7eb2e8f9f7 467 * the currently configured reference clock is assumed.
<> 144:ef7eb2e8f9f7 468 *
<> 144:ef7eb2e8f9f7 469 * @param[in] baudrate
<> 144:ef7eb2e8f9f7 470 * Baudrate to try to achieve for USART.
<> 144:ef7eb2e8f9f7 471 ******************************************************************************/
<> 144:ef7eb2e8f9f7 472 void USART_BaudrateSyncSet(USART_TypeDef *usart, uint32_t refFreq, uint32_t baudrate)
<> 144:ef7eb2e8f9f7 473 {
<> 144:ef7eb2e8f9f7 474 #if defined(_USART_CLKDIV_DIV_MASK) && (_USART_CLKDIV_DIV_MASK >= 0x7FFFF8UL)
<> 144:ef7eb2e8f9f7 475 uint64_t clkdiv;
<> 144:ef7eb2e8f9f7 476 #else
<> 144:ef7eb2e8f9f7 477 uint32_t clkdiv;
<> 144:ef7eb2e8f9f7 478 #endif
<> 144:ef7eb2e8f9f7 479
<> 144:ef7eb2e8f9f7 480 /* Inhibit divide by 0 */
<> 144:ef7eb2e8f9f7 481 EFM_ASSERT(baudrate);
<> 144:ef7eb2e8f9f7 482
<> 144:ef7eb2e8f9f7 483 /*
<> 144:ef7eb2e8f9f7 484 * CLKDIV in synchronous mode is given by:
<> 144:ef7eb2e8f9f7 485 *
<> 144:ef7eb2e8f9f7 486 * CLKDIV = 256 * (fHFPERCLK/(2 * br) - 1)
<> 144:ef7eb2e8f9f7 487 */
<> 144:ef7eb2e8f9f7 488
<> 144:ef7eb2e8f9f7 489 /* HFPERCLK used to clock all USART/UART peripheral modules */
<> 144:ef7eb2e8f9f7 490 if (!refFreq)
<> 144:ef7eb2e8f9f7 491 {
<> 144:ef7eb2e8f9f7 492 refFreq = CMU_ClockFreqGet(cmuClock_HFPER);
<> 144:ef7eb2e8f9f7 493 }
<> 144:ef7eb2e8f9f7 494
<> 144:ef7eb2e8f9f7 495 #if defined(_USART_CLKDIV_DIV_MASK) && (_USART_CLKDIV_DIV_MASK >= 0x7FFFF8UL)
<> 144:ef7eb2e8f9f7 496 /* Calculate and set CLKDIV without fractional bits */
<> 144:ef7eb2e8f9f7 497 clkdiv = 2 * baudrate;
<> 144:ef7eb2e8f9f7 498 clkdiv = (0x100ULL * (uint64_t)refFreq) / clkdiv;
<> 144:ef7eb2e8f9f7 499
<> 144:ef7eb2e8f9f7 500 /* Round up by not subtracting 256 and mask off fractional part */
<> 144:ef7eb2e8f9f7 501 clkdiv &= ~0xFF;
<> 144:ef7eb2e8f9f7 502 #else
<> 144:ef7eb2e8f9f7 503 /* Calculate and set CLKDIV with fractional bits */
<> 144:ef7eb2e8f9f7 504 clkdiv = 2 * refFreq;
<> 144:ef7eb2e8f9f7 505 clkdiv += baudrate - 1;
<> 144:ef7eb2e8f9f7 506 clkdiv /= baudrate;
<> 144:ef7eb2e8f9f7 507 clkdiv -= 4;
<> 144:ef7eb2e8f9f7 508 clkdiv *= 64;
<> 144:ef7eb2e8f9f7 509 /* Make sure we don't use fractional bits by rounding CLKDIV */
<> 144:ef7eb2e8f9f7 510 /* up (and thus reducing baudrate, not increasing baudrate above */
<> 144:ef7eb2e8f9f7 511 /* specified value). */
<> 144:ef7eb2e8f9f7 512 clkdiv += 0xc0;
<> 144:ef7eb2e8f9f7 513 clkdiv &= 0xffffff00;
<> 144:ef7eb2e8f9f7 514 #endif
<> 144:ef7eb2e8f9f7 515
<> 144:ef7eb2e8f9f7 516 /* Verify that resulting clock divider is within limits */
<> 144:ef7eb2e8f9f7 517 EFM_ASSERT(!(clkdiv & ~_USART_CLKDIV_DIV_MASK));
<> 144:ef7eb2e8f9f7 518
<> 144:ef7eb2e8f9f7 519 /* If EFM_ASSERT is not enabled, make sure we don't write to reserved bits */
<> 144:ef7eb2e8f9f7 520 clkdiv &= _USART_CLKDIV_DIV_MASK;
<> 144:ef7eb2e8f9f7 521
<> 144:ef7eb2e8f9f7 522 BUS_RegMaskedWrite(&usart->CLKDIV, _USART_CLKDIV_DIV_MASK, clkdiv);
<> 144:ef7eb2e8f9f7 523 }
<> 144:ef7eb2e8f9f7 524
<> 144:ef7eb2e8f9f7 525
<> 144:ef7eb2e8f9f7 526 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 527 * @brief
<> 144:ef7eb2e8f9f7 528 * Enable/disable USART/UART receiver and/or transmitter.
<> 144:ef7eb2e8f9f7 529 *
<> 144:ef7eb2e8f9f7 530 * @details
<> 144:ef7eb2e8f9f7 531 * Notice that this function does not do any configuration. Enabling should
<> 144:ef7eb2e8f9f7 532 * normally be done after initialization is done (if not enabled as part
<> 144:ef7eb2e8f9f7 533 * of init).
<> 144:ef7eb2e8f9f7 534 *
<> 144:ef7eb2e8f9f7 535 * @param[in] usart
<> 144:ef7eb2e8f9f7 536 * Pointer to USART/UART peripheral register block.
<> 144:ef7eb2e8f9f7 537 *
<> 144:ef7eb2e8f9f7 538 * @param[in] enable
<> 144:ef7eb2e8f9f7 539 * Select status for receiver/transmitter.
<> 144:ef7eb2e8f9f7 540 ******************************************************************************/
<> 144:ef7eb2e8f9f7 541 void USART_Enable(USART_TypeDef *usart, USART_Enable_TypeDef enable)
<> 144:ef7eb2e8f9f7 542 {
<> 144:ef7eb2e8f9f7 543 uint32_t tmp;
<> 144:ef7eb2e8f9f7 544
<> 144:ef7eb2e8f9f7 545 /* Make sure the module exists on the selected chip */
<> 144:ef7eb2e8f9f7 546 EFM_ASSERT( USART_REF_VALID(usart)
<> 144:ef7eb2e8f9f7 547 || USARTRF_REF_VALID(usart)
<> 144:ef7eb2e8f9f7 548 || UART_REF_VALID(usart) );
<> 144:ef7eb2e8f9f7 549
<> 144:ef7eb2e8f9f7 550 /* Disable as specified */
<> 144:ef7eb2e8f9f7 551 tmp = ~((uint32_t) (enable));
<> 144:ef7eb2e8f9f7 552 tmp &= _USART_CMD_RXEN_MASK | _USART_CMD_TXEN_MASK;
<> 144:ef7eb2e8f9f7 553 usart->CMD = tmp << 1;
<> 144:ef7eb2e8f9f7 554
<> 144:ef7eb2e8f9f7 555 /* Enable as specified */
<> 144:ef7eb2e8f9f7 556 usart->CMD = (uint32_t) (enable);
<> 144:ef7eb2e8f9f7 557 }
<> 144:ef7eb2e8f9f7 558
<> 144:ef7eb2e8f9f7 559
<> 144:ef7eb2e8f9f7 560 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 561 * @brief
<> 144:ef7eb2e8f9f7 562 * Init USART/UART for normal asynchronous mode.
<> 144:ef7eb2e8f9f7 563 *
<> 144:ef7eb2e8f9f7 564 * @details
<> 144:ef7eb2e8f9f7 565 * This function will configure basic settings in order to operate in normal
<> 144:ef7eb2e8f9f7 566 * asynchronous mode.
<> 144:ef7eb2e8f9f7 567 *
<> 144:ef7eb2e8f9f7 568 * Special control setup not covered by this function must be done after
<> 144:ef7eb2e8f9f7 569 * using this function by direct modification of the CTRL register.
<> 144:ef7eb2e8f9f7 570 *
<> 144:ef7eb2e8f9f7 571 * Notice that pins used by the USART/UART module must be properly configured
<> 144:ef7eb2e8f9f7 572 * by the user explicitly, in order for the USART/UART to work as intended.
<> 144:ef7eb2e8f9f7 573 * (When configuring pins, one should remember to consider the sequence of
<> 144:ef7eb2e8f9f7 574 * configuration, in order to avoid unintended pulses/glitches on output
<> 144:ef7eb2e8f9f7 575 * pins.)
<> 144:ef7eb2e8f9f7 576 *
<> 144:ef7eb2e8f9f7 577 * @param[in] usart
<> 144:ef7eb2e8f9f7 578 * Pointer to USART/UART peripheral register block.
<> 144:ef7eb2e8f9f7 579 *
<> 144:ef7eb2e8f9f7 580 * @param[in] init
<> 144:ef7eb2e8f9f7 581 * Pointer to initialization structure used to configure basic async setup.
<> 144:ef7eb2e8f9f7 582 ******************************************************************************/
<> 144:ef7eb2e8f9f7 583 void USART_InitAsync(USART_TypeDef *usart, const USART_InitAsync_TypeDef *init)
<> 144:ef7eb2e8f9f7 584 {
<> 144:ef7eb2e8f9f7 585 /* Make sure the module exists on the selected chip */
<> 144:ef7eb2e8f9f7 586 EFM_ASSERT( USART_REF_VALID(usart)
<> 144:ef7eb2e8f9f7 587 || USARTRF_REF_VALID(usart)
<> 144:ef7eb2e8f9f7 588 || UART_REF_VALID(usart) );
<> 144:ef7eb2e8f9f7 589
<> 144:ef7eb2e8f9f7 590 /* Init USART registers to HW reset state. */
<> 144:ef7eb2e8f9f7 591 USART_Reset(usart);
<> 144:ef7eb2e8f9f7 592
<> 144:ef7eb2e8f9f7 593 #if defined(USART_INPUT_RXPRS) && defined(USART_CTRL_MVDIS)
<> 144:ef7eb2e8f9f7 594 /* Disable majority vote if specified. */
<> 144:ef7eb2e8f9f7 595 if (init->mvdis)
<> 144:ef7eb2e8f9f7 596 {
<> 144:ef7eb2e8f9f7 597 usart->CTRL |= USART_CTRL_MVDIS;
<> 144:ef7eb2e8f9f7 598 }
<> 144:ef7eb2e8f9f7 599
<> 144:ef7eb2e8f9f7 600 /* Configure PRS input mode. */
<> 144:ef7eb2e8f9f7 601 if (init->prsRxEnable)
<> 144:ef7eb2e8f9f7 602 {
<> 144:ef7eb2e8f9f7 603 usart->INPUT = (uint32_t) init->prsRxCh | USART_INPUT_RXPRS;
<> 144:ef7eb2e8f9f7 604 }
<> 144:ef7eb2e8f9f7 605 #endif
<> 144:ef7eb2e8f9f7 606
<> 144:ef7eb2e8f9f7 607 /* Configure databits, stopbits and parity */
<> 144:ef7eb2e8f9f7 608 usart->FRAME = (uint32_t)init->databits
<> 144:ef7eb2e8f9f7 609 | (uint32_t)init->stopbits
<> 144:ef7eb2e8f9f7 610 | (uint32_t)init->parity;
<> 144:ef7eb2e8f9f7 611
<> 144:ef7eb2e8f9f7 612 /* Configure baudrate */
<> 144:ef7eb2e8f9f7 613 USART_BaudrateAsyncSet(usart, init->refFreq, init->baudrate, init->oversampling);
<> 144:ef7eb2e8f9f7 614
<> 144:ef7eb2e8f9f7 615 #if defined(_USART_TIMING_CSHOLD_MASK)
<> 144:ef7eb2e8f9f7 616 usart->TIMING = ((init->autoCsHold << _USART_TIMING_CSHOLD_SHIFT)
<> 144:ef7eb2e8f9f7 617 & _USART_TIMING_CSHOLD_MASK)
<> 144:ef7eb2e8f9f7 618 | ((init->autoCsSetup << _USART_TIMING_CSSETUP_SHIFT)
<> 144:ef7eb2e8f9f7 619 & _USART_TIMING_CSSETUP_MASK);
<> 144:ef7eb2e8f9f7 620 if (init->autoCsEnable)
<> 144:ef7eb2e8f9f7 621 {
<> 144:ef7eb2e8f9f7 622 usart->CTRL |= USART_CTRL_AUTOCS;
<> 144:ef7eb2e8f9f7 623 }
<> 144:ef7eb2e8f9f7 624 #endif
<> 144:ef7eb2e8f9f7 625 /* Finally enable (as specified) */
<> 144:ef7eb2e8f9f7 626 usart->CMD = (uint32_t)init->enable;
<> 144:ef7eb2e8f9f7 627 }
<> 144:ef7eb2e8f9f7 628
<> 144:ef7eb2e8f9f7 629
<> 144:ef7eb2e8f9f7 630 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 631 * @brief
<> 144:ef7eb2e8f9f7 632 * Init USART for synchronous mode.
<> 144:ef7eb2e8f9f7 633 *
<> 144:ef7eb2e8f9f7 634 * @details
<> 144:ef7eb2e8f9f7 635 * This function will configure basic settings in order to operate in
<> 144:ef7eb2e8f9f7 636 * synchronous mode.
<> 144:ef7eb2e8f9f7 637 *
<> 144:ef7eb2e8f9f7 638 * Special control setup not covered by this function must be done after
<> 144:ef7eb2e8f9f7 639 * using this function by direct modification of the CTRL register.
<> 144:ef7eb2e8f9f7 640 *
<> 144:ef7eb2e8f9f7 641 * Notice that pins used by the USART module must be properly configured
<> 144:ef7eb2e8f9f7 642 * by the user explicitly, in order for the USART to work as intended.
<> 144:ef7eb2e8f9f7 643 * (When configuring pins, one should remember to consider the sequence of
<> 144:ef7eb2e8f9f7 644 * configuration, in order to avoid unintended pulses/glitches on output
<> 144:ef7eb2e8f9f7 645 * pins.)
<> 144:ef7eb2e8f9f7 646 *
<> 144:ef7eb2e8f9f7 647 * @param[in] usart
<> 144:ef7eb2e8f9f7 648 * Pointer to USART peripheral register block. (UART does not support this
<> 144:ef7eb2e8f9f7 649 * mode.)
<> 144:ef7eb2e8f9f7 650 *
<> 144:ef7eb2e8f9f7 651 * @param[in] init
<> 144:ef7eb2e8f9f7 652 * Pointer to initialization structure used to configure basic async setup.
<> 144:ef7eb2e8f9f7 653 ******************************************************************************/
<> 144:ef7eb2e8f9f7 654 void USART_InitSync(USART_TypeDef *usart, const USART_InitSync_TypeDef *init)
<> 144:ef7eb2e8f9f7 655 {
<> 144:ef7eb2e8f9f7 656 /* Make sure the module exists on the selected chip */
<> 144:ef7eb2e8f9f7 657 EFM_ASSERT( USART_REF_VALID(usart) || USARTRF_REF_VALID(usart) );
<> 144:ef7eb2e8f9f7 658
<> 144:ef7eb2e8f9f7 659 /* Init USART registers to HW reset state. */
<> 144:ef7eb2e8f9f7 660 USART_Reset(usart);
<> 144:ef7eb2e8f9f7 661
<> 144:ef7eb2e8f9f7 662 /* Set bits for synchronous mode */
<> 144:ef7eb2e8f9f7 663 usart->CTRL |= (USART_CTRL_SYNC)
<> 144:ef7eb2e8f9f7 664 | (uint32_t)init->clockMode
<> 144:ef7eb2e8f9f7 665 | (init->msbf ? USART_CTRL_MSBF : 0);
<> 144:ef7eb2e8f9f7 666
<> 144:ef7eb2e8f9f7 667 #if defined(_USART_CTRL_AUTOTX_MASK)
<> 144:ef7eb2e8f9f7 668 usart->CTRL |= init->autoTx ? USART_CTRL_AUTOTX : 0;
<> 144:ef7eb2e8f9f7 669 #endif
<> 144:ef7eb2e8f9f7 670
<> 144:ef7eb2e8f9f7 671 #if defined(_USART_INPUT_RXPRS_MASK)
<> 144:ef7eb2e8f9f7 672 /* Configure PRS input mode. */
<> 144:ef7eb2e8f9f7 673 if (init->prsRxEnable)
<> 144:ef7eb2e8f9f7 674 {
<> 144:ef7eb2e8f9f7 675 usart->INPUT = (uint32_t)init->prsRxCh | USART_INPUT_RXPRS;
<> 144:ef7eb2e8f9f7 676 }
<> 144:ef7eb2e8f9f7 677 #endif
<> 144:ef7eb2e8f9f7 678
<> 144:ef7eb2e8f9f7 679 /* Configure databits, leave stopbits and parity at reset default (not used) */
<> 144:ef7eb2e8f9f7 680 usart->FRAME = (uint32_t)init->databits
<> 144:ef7eb2e8f9f7 681 | USART_FRAME_STOPBITS_DEFAULT
<> 144:ef7eb2e8f9f7 682 | USART_FRAME_PARITY_DEFAULT;
<> 144:ef7eb2e8f9f7 683
<> 144:ef7eb2e8f9f7 684 /* Configure baudrate */
<> 144:ef7eb2e8f9f7 685 USART_BaudrateSyncSet(usart, init->refFreq, init->baudrate);
<> 144:ef7eb2e8f9f7 686
<> 144:ef7eb2e8f9f7 687 /* Finally enable (as specified) */
<> 144:ef7eb2e8f9f7 688 if (init->master)
<> 144:ef7eb2e8f9f7 689 {
<> 144:ef7eb2e8f9f7 690 usart->CMD = USART_CMD_MASTEREN;
<> 144:ef7eb2e8f9f7 691 }
<> 144:ef7eb2e8f9f7 692
<> 144:ef7eb2e8f9f7 693 #if defined(_USART_TIMING_CSHOLD_MASK)
<> 144:ef7eb2e8f9f7 694 usart->TIMING = ((init->autoCsHold << _USART_TIMING_CSHOLD_SHIFT)
<> 144:ef7eb2e8f9f7 695 & _USART_TIMING_CSHOLD_MASK)
<> 144:ef7eb2e8f9f7 696 | ((init->autoCsSetup << _USART_TIMING_CSSETUP_SHIFT)
<> 144:ef7eb2e8f9f7 697 & _USART_TIMING_CSSETUP_MASK);
<> 144:ef7eb2e8f9f7 698 if (init->autoCsEnable)
<> 144:ef7eb2e8f9f7 699 {
<> 144:ef7eb2e8f9f7 700 usart->CTRL |= USART_CTRL_AUTOCS;
<> 144:ef7eb2e8f9f7 701 }
<> 144:ef7eb2e8f9f7 702 #endif
<> 144:ef7eb2e8f9f7 703
<> 144:ef7eb2e8f9f7 704 usart->CMD = (uint32_t)init->enable;
<> 144:ef7eb2e8f9f7 705 }
<> 144:ef7eb2e8f9f7 706
<> 144:ef7eb2e8f9f7 707
<> 144:ef7eb2e8f9f7 708 #if defined(USART0) || ((USART_COUNT == 1) && defined(USART1))
<> 144:ef7eb2e8f9f7 709 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 710 * @brief
<> 144:ef7eb2e8f9f7 711 * Init USART0 for asynchronous IrDA mode.
<> 144:ef7eb2e8f9f7 712 *
<> 144:ef7eb2e8f9f7 713 * @details
<> 144:ef7eb2e8f9f7 714 * This function will configure basic settings in order to operate in
<> 144:ef7eb2e8f9f7 715 * asynchronous IrDA mode.
<> 144:ef7eb2e8f9f7 716 *
<> 144:ef7eb2e8f9f7 717 * Special control setup not covered by this function must be done after
<> 144:ef7eb2e8f9f7 718 * using this function by direct modification of the CTRL and IRCTRL
<> 144:ef7eb2e8f9f7 719 * registers.
<> 144:ef7eb2e8f9f7 720 *
<> 144:ef7eb2e8f9f7 721 * Notice that pins used by the USART/UART module must be properly configured
<> 144:ef7eb2e8f9f7 722 * by the user explicitly, in order for the USART/UART to work as intended.
<> 144:ef7eb2e8f9f7 723 * (When configuring pins, one should remember to consider the sequence of
<> 144:ef7eb2e8f9f7 724 * configuration, in order to avoid unintended pulses/glitches on output
<> 144:ef7eb2e8f9f7 725 * pins.)
<> 144:ef7eb2e8f9f7 726 *
<> 144:ef7eb2e8f9f7 727 * @param[in] init
<> 144:ef7eb2e8f9f7 728 * Pointer to initialization structure used to configure async IrDA setup.
<> 144:ef7eb2e8f9f7 729 *
<> 144:ef7eb2e8f9f7 730 * @note
<> 144:ef7eb2e8f9f7 731 * This function only applies to USART0 as IrDA is not supported on the other
<> 144:ef7eb2e8f9f7 732 * USART modules.
<> 144:ef7eb2e8f9f7 733 *
<> 144:ef7eb2e8f9f7 734 ******************************************************************************/
<> 144:ef7eb2e8f9f7 735 void USART_InitIrDA(const USART_InitIrDA_TypeDef *init)
<> 144:ef7eb2e8f9f7 736 {
<> 144:ef7eb2e8f9f7 737 #if (USART_COUNT == 1) && defined(USART1)
<> 144:ef7eb2e8f9f7 738 USART_TypeDef *usart = USART1;
<> 144:ef7eb2e8f9f7 739 #else
<> 144:ef7eb2e8f9f7 740 USART_TypeDef *usart = USART0;
<> 144:ef7eb2e8f9f7 741 #endif
<> 144:ef7eb2e8f9f7 742
<> 144:ef7eb2e8f9f7 743 /* Init USART as async device */
<> 144:ef7eb2e8f9f7 744 USART_InitAsync(usart, &(init->async));
<> 144:ef7eb2e8f9f7 745
<> 144:ef7eb2e8f9f7 746 /* Set IrDA modulation to RZI (return-to-zero-inverted) */
<> 144:ef7eb2e8f9f7 747 usart->CTRL |= USART_CTRL_TXINV;
<> 144:ef7eb2e8f9f7 748
<> 144:ef7eb2e8f9f7 749 /* Invert Rx signal before demodulator if enabled */
<> 144:ef7eb2e8f9f7 750 if (init->irRxInv)
<> 144:ef7eb2e8f9f7 751 {
<> 144:ef7eb2e8f9f7 752 usart->CTRL |= USART_CTRL_RXINV;
<> 144:ef7eb2e8f9f7 753 }
<> 144:ef7eb2e8f9f7 754
<> 144:ef7eb2e8f9f7 755 /* Configure IrDA */
<> 144:ef7eb2e8f9f7 756 usart->IRCTRL |= (uint32_t)init->irPw
<> 144:ef7eb2e8f9f7 757 | (uint32_t)init->irPrsSel
<> 144:ef7eb2e8f9f7 758 | ((uint32_t)init->irFilt << _USART_IRCTRL_IRFILT_SHIFT)
<> 144:ef7eb2e8f9f7 759 | ((uint32_t)init->irPrsEn << _USART_IRCTRL_IRPRSEN_SHIFT);
<> 144:ef7eb2e8f9f7 760
<> 144:ef7eb2e8f9f7 761 /* Enable IrDA */
<> 144:ef7eb2e8f9f7 762 usart->IRCTRL |= USART_IRCTRL_IREN;
<> 144:ef7eb2e8f9f7 763 }
<> 144:ef7eb2e8f9f7 764 #endif
<> 144:ef7eb2e8f9f7 765
<> 144:ef7eb2e8f9f7 766
<> 144:ef7eb2e8f9f7 767 #if defined(_USART_I2SCTRL_MASK)
<> 144:ef7eb2e8f9f7 768 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 769 * @brief
<> 144:ef7eb2e8f9f7 770 * Init USART for I2S mode.
<> 144:ef7eb2e8f9f7 771 *
<> 144:ef7eb2e8f9f7 772 * @details
<> 144:ef7eb2e8f9f7 773 * This function will configure basic settings in order to operate in I2S
<> 144:ef7eb2e8f9f7 774 * mode.
<> 144:ef7eb2e8f9f7 775 *
<> 144:ef7eb2e8f9f7 776 * Special control setup not covered by this function must be done after
<> 144:ef7eb2e8f9f7 777 * using this function by direct modification of the CTRL and I2SCTRL
<> 144:ef7eb2e8f9f7 778 * registers.
<> 144:ef7eb2e8f9f7 779 *
<> 144:ef7eb2e8f9f7 780 * Notice that pins used by the USART module must be properly configured
<> 144:ef7eb2e8f9f7 781 * by the user explicitly, in order for the USART to work as intended.
<> 144:ef7eb2e8f9f7 782 * (When configuring pins, one should remember to consider the sequence of
<> 144:ef7eb2e8f9f7 783 * configuration, in order to avoid unintended pulses/glitches on output
<> 144:ef7eb2e8f9f7 784 * pins.)
<> 144:ef7eb2e8f9f7 785 *
<> 144:ef7eb2e8f9f7 786 * @param[in] usart
<> 144:ef7eb2e8f9f7 787 * Pointer to USART peripheral register block. (UART does not support this
<> 144:ef7eb2e8f9f7 788 * mode.)
<> 144:ef7eb2e8f9f7 789 *
<> 144:ef7eb2e8f9f7 790 * @param[in] init
<> 144:ef7eb2e8f9f7 791 * Pointer to initialization structure used to configure basic I2S setup.
<> 144:ef7eb2e8f9f7 792 *
<> 144:ef7eb2e8f9f7 793 * @note
<> 144:ef7eb2e8f9f7 794 * This function does not apply to all USART's. Refer to chip manuals.
<> 144:ef7eb2e8f9f7 795 *
<> 144:ef7eb2e8f9f7 796 ******************************************************************************/
<> 144:ef7eb2e8f9f7 797 void USART_InitI2s(USART_TypeDef *usart, USART_InitI2s_TypeDef *init)
<> 144:ef7eb2e8f9f7 798 {
<> 144:ef7eb2e8f9f7 799 USART_Enable_TypeDef enable;
<> 144:ef7eb2e8f9f7 800
<> 144:ef7eb2e8f9f7 801 /* Make sure the module exists on the selected chip */
<> 144:ef7eb2e8f9f7 802 EFM_ASSERT(USART_I2S_VALID(usart));
<> 144:ef7eb2e8f9f7 803
<> 144:ef7eb2e8f9f7 804 /* Override the enable setting. */
<> 144:ef7eb2e8f9f7 805 enable = init->sync.enable;
<> 144:ef7eb2e8f9f7 806 init->sync.enable = usartDisable;
<> 144:ef7eb2e8f9f7 807
<> 144:ef7eb2e8f9f7 808 /* Init USART as a sync device. */
<> 144:ef7eb2e8f9f7 809 USART_InitSync(usart, &init->sync);
<> 144:ef7eb2e8f9f7 810
<> 144:ef7eb2e8f9f7 811 /* Configure and enable I2CCTRL register acording to selected mode. */
<> 144:ef7eb2e8f9f7 812 usart->I2SCTRL = (uint32_t)init->format
<> 144:ef7eb2e8f9f7 813 | (uint32_t)init->justify
<> 144:ef7eb2e8f9f7 814 | (init->delay ? USART_I2SCTRL_DELAY : 0)
<> 144:ef7eb2e8f9f7 815 | (init->dmaSplit ? USART_I2SCTRL_DMASPLIT : 0)
<> 144:ef7eb2e8f9f7 816 | (init->mono ? USART_I2SCTRL_MONO : 0)
<> 144:ef7eb2e8f9f7 817 | USART_I2SCTRL_EN;
<> 144:ef7eb2e8f9f7 818
<> 144:ef7eb2e8f9f7 819 if (enable != usartDisable)
<> 144:ef7eb2e8f9f7 820 {
<> 144:ef7eb2e8f9f7 821 USART_Enable(usart, enable);
<> 144:ef7eb2e8f9f7 822 }
<> 144:ef7eb2e8f9f7 823 }
<> 144:ef7eb2e8f9f7 824 #endif
<> 144:ef7eb2e8f9f7 825
<> 144:ef7eb2e8f9f7 826
<> 144:ef7eb2e8f9f7 827 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 828 * @brief
<> 144:ef7eb2e8f9f7 829 * Initialize automatic transmissions using PRS channel as trigger
<> 144:ef7eb2e8f9f7 830 * @note
<> 144:ef7eb2e8f9f7 831 * Initialize USART with USART_Init() before setting up PRS configuration
<> 144:ef7eb2e8f9f7 832 *
<> 144:ef7eb2e8f9f7 833 * @param[in] usart Pointer to USART to configure
<> 144:ef7eb2e8f9f7 834 * @param[in] init Pointer to initialization structure
<> 144:ef7eb2e8f9f7 835 ******************************************************************************/
<> 144:ef7eb2e8f9f7 836 void USART_InitPrsTrigger(USART_TypeDef *usart, const USART_PrsTriggerInit_TypeDef *init)
<> 144:ef7eb2e8f9f7 837 {
<> 144:ef7eb2e8f9f7 838 uint32_t trigctrl;
<> 144:ef7eb2e8f9f7 839
<> 144:ef7eb2e8f9f7 840 /* Clear values that will be reconfigured */
<> 144:ef7eb2e8f9f7 841 trigctrl = usart->TRIGCTRL & ~(_USART_TRIGCTRL_RXTEN_MASK
<> 144:ef7eb2e8f9f7 842 | _USART_TRIGCTRL_TXTEN_MASK
<> 144:ef7eb2e8f9f7 843 #if defined(USART_TRIGCTRL_AUTOTXTEN)
<> 144:ef7eb2e8f9f7 844 | _USART_TRIGCTRL_AUTOTXTEN_MASK
<> 144:ef7eb2e8f9f7 845 #endif
<> 144:ef7eb2e8f9f7 846 | _USART_TRIGCTRL_TSEL_MASK);
<> 144:ef7eb2e8f9f7 847
<> 144:ef7eb2e8f9f7 848 #if defined(USART_TRIGCTRL_AUTOTXTEN)
<> 144:ef7eb2e8f9f7 849 if (init->autoTxTriggerEnable)
<> 144:ef7eb2e8f9f7 850 {
<> 144:ef7eb2e8f9f7 851 trigctrl |= USART_TRIGCTRL_AUTOTXTEN;
<> 144:ef7eb2e8f9f7 852 }
<> 144:ef7eb2e8f9f7 853 #endif
<> 144:ef7eb2e8f9f7 854 if (init->txTriggerEnable)
<> 144:ef7eb2e8f9f7 855 {
<> 144:ef7eb2e8f9f7 856 trigctrl |= USART_TRIGCTRL_TXTEN;
<> 144:ef7eb2e8f9f7 857 }
<> 144:ef7eb2e8f9f7 858 if (init->rxTriggerEnable)
<> 144:ef7eb2e8f9f7 859 {
<> 144:ef7eb2e8f9f7 860 trigctrl |= USART_TRIGCTRL_RXTEN;
<> 144:ef7eb2e8f9f7 861 }
<> 144:ef7eb2e8f9f7 862 trigctrl |= init->prsTriggerChannel;
<> 144:ef7eb2e8f9f7 863
<> 144:ef7eb2e8f9f7 864 /* Enable new configuration */
<> 144:ef7eb2e8f9f7 865 usart->TRIGCTRL = trigctrl;
<> 144:ef7eb2e8f9f7 866 }
<> 144:ef7eb2e8f9f7 867
<> 144:ef7eb2e8f9f7 868
<> 144:ef7eb2e8f9f7 869 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 870 * @brief
<> 144:ef7eb2e8f9f7 871 * Reset USART/UART to same state as after a HW reset.
<> 144:ef7eb2e8f9f7 872 *
<> 144:ef7eb2e8f9f7 873 * @param[in] usart
<> 144:ef7eb2e8f9f7 874 * Pointer to USART/UART peripheral register block.
<> 144:ef7eb2e8f9f7 875 ******************************************************************************/
<> 144:ef7eb2e8f9f7 876 void USART_Reset(USART_TypeDef *usart)
<> 144:ef7eb2e8f9f7 877 {
<> 144:ef7eb2e8f9f7 878 /* Make sure the module exists on the selected chip */
<> 144:ef7eb2e8f9f7 879 EFM_ASSERT( USART_REF_VALID(usart)
<> 144:ef7eb2e8f9f7 880 || USARTRF_REF_VALID(usart)
<> 144:ef7eb2e8f9f7 881 || UART_REF_VALID(usart) );
<> 144:ef7eb2e8f9f7 882
<> 144:ef7eb2e8f9f7 883 /* Make sure disabled first, before resetting other registers */
<> 144:ef7eb2e8f9f7 884 usart->CMD = USART_CMD_RXDIS | USART_CMD_TXDIS | USART_CMD_MASTERDIS
<> 144:ef7eb2e8f9f7 885 | USART_CMD_RXBLOCKDIS | USART_CMD_TXTRIDIS | USART_CMD_CLEARTX
<> 144:ef7eb2e8f9f7 886 | USART_CMD_CLEARRX;
<> 144:ef7eb2e8f9f7 887 usart->CTRL = _USART_CTRL_RESETVALUE;
<> 144:ef7eb2e8f9f7 888 usart->FRAME = _USART_FRAME_RESETVALUE;
<> 144:ef7eb2e8f9f7 889 usart->TRIGCTRL = _USART_TRIGCTRL_RESETVALUE;
<> 144:ef7eb2e8f9f7 890 usart->CLKDIV = _USART_CLKDIV_RESETVALUE;
<> 144:ef7eb2e8f9f7 891 usart->IEN = _USART_IEN_RESETVALUE;
<> 144:ef7eb2e8f9f7 892 usart->IFC = _USART_IFC_MASK;
<> 144:ef7eb2e8f9f7 893 #if defined(_USART_ROUTEPEN_MASK) || defined(_UART_ROUTEPEN_MASK)
<> 144:ef7eb2e8f9f7 894 usart->ROUTEPEN = _USART_ROUTEPEN_RESETVALUE;
<> 144:ef7eb2e8f9f7 895 usart->ROUTELOC0 = _USART_ROUTELOC0_RESETVALUE;
<> 144:ef7eb2e8f9f7 896 usart->ROUTELOC1 = _USART_ROUTELOC1_RESETVALUE;
<> 144:ef7eb2e8f9f7 897 #else
<> 144:ef7eb2e8f9f7 898 usart->ROUTE = _USART_ROUTE_RESETVALUE;
<> 144:ef7eb2e8f9f7 899 #endif
<> 144:ef7eb2e8f9f7 900
<> 144:ef7eb2e8f9f7 901 if (USART_IRDA_VALID(usart))
<> 144:ef7eb2e8f9f7 902 {
<> 144:ef7eb2e8f9f7 903 usart->IRCTRL = _USART_IRCTRL_RESETVALUE;
<> 144:ef7eb2e8f9f7 904 }
<> 144:ef7eb2e8f9f7 905
<> 144:ef7eb2e8f9f7 906 #if defined(_USART_INPUT_RESETVALUE)
<> 144:ef7eb2e8f9f7 907 usart->INPUT = _USART_INPUT_RESETVALUE;
<> 144:ef7eb2e8f9f7 908 #endif
<> 144:ef7eb2e8f9f7 909
<> 144:ef7eb2e8f9f7 910 #if defined(_USART_I2SCTRL_RESETVALUE)
<> 144:ef7eb2e8f9f7 911 if (USART_I2S_VALID(usart))
<> 144:ef7eb2e8f9f7 912 {
<> 144:ef7eb2e8f9f7 913 usart->I2SCTRL = _USART_I2SCTRL_RESETVALUE;
<> 144:ef7eb2e8f9f7 914 }
<> 144:ef7eb2e8f9f7 915 #endif
<> 144:ef7eb2e8f9f7 916 }
<> 144:ef7eb2e8f9f7 917
<> 144:ef7eb2e8f9f7 918
<> 144:ef7eb2e8f9f7 919 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 920 * @brief
<> 144:ef7eb2e8f9f7 921 * Receive one 4-8 bit frame, (or part of 10-16 bit frame).
<> 144:ef7eb2e8f9f7 922 *
<> 144:ef7eb2e8f9f7 923 * @details
<> 144:ef7eb2e8f9f7 924 * This function is normally used to receive one frame when operating with
<> 144:ef7eb2e8f9f7 925 * frame length 4-8 bits. Please refer to @ref USART_RxExt() for reception of
<> 144:ef7eb2e8f9f7 926 * 9 bit frames.
<> 144:ef7eb2e8f9f7 927 *
<> 144:ef7eb2e8f9f7 928 * Notice that possible parity/stop bits in asynchronous mode are not
<> 144:ef7eb2e8f9f7 929 * considered part of specified frame bit length.
<> 144:ef7eb2e8f9f7 930 *
<> 144:ef7eb2e8f9f7 931 * @note
<> 144:ef7eb2e8f9f7 932 * This function will stall if the buffer is empty, until data is received.
<> 144:ef7eb2e8f9f7 933 * Alternatively the user can explicitly check whether data is available, and
<> 144:ef7eb2e8f9f7 934 * if data is avaliable, call @ref USART_RxDataGet() to read the RXDATA
<> 144:ef7eb2e8f9f7 935 * register directly.
<> 144:ef7eb2e8f9f7 936 *
<> 144:ef7eb2e8f9f7 937 * @param[in] usart
<> 144:ef7eb2e8f9f7 938 * Pointer to USART/UART peripheral register block.
<> 144:ef7eb2e8f9f7 939 *
<> 144:ef7eb2e8f9f7 940 * @return
<> 144:ef7eb2e8f9f7 941 * Data received.
<> 144:ef7eb2e8f9f7 942 ******************************************************************************/
<> 144:ef7eb2e8f9f7 943 uint8_t USART_Rx(USART_TypeDef *usart)
<> 144:ef7eb2e8f9f7 944 {
<> 144:ef7eb2e8f9f7 945 while (!(usart->STATUS & USART_STATUS_RXDATAV))
<> 144:ef7eb2e8f9f7 946 ;
<> 144:ef7eb2e8f9f7 947
<> 144:ef7eb2e8f9f7 948 return (uint8_t)usart->RXDATA;
<> 144:ef7eb2e8f9f7 949 }
<> 144:ef7eb2e8f9f7 950
<> 144:ef7eb2e8f9f7 951
<> 144:ef7eb2e8f9f7 952 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 953 * @brief
<> 144:ef7eb2e8f9f7 954 * Receive two 4-8 bit frames, or one 10-16 bit frame.
<> 144:ef7eb2e8f9f7 955 *
<> 144:ef7eb2e8f9f7 956 * @details
<> 144:ef7eb2e8f9f7 957 * This function is normally used to receive one frame when operating with
<> 144:ef7eb2e8f9f7 958 * frame length 10-16 bits. Please refer to @ref USART_RxDoubleExt() for
<> 144:ef7eb2e8f9f7 959 * reception of two 9 bit frames.
<> 144:ef7eb2e8f9f7 960 *
<> 144:ef7eb2e8f9f7 961 * Notice that possible parity/stop bits in asynchronous mode are not
<> 144:ef7eb2e8f9f7 962 * considered part of specified frame bit length.
<> 144:ef7eb2e8f9f7 963 *
<> 144:ef7eb2e8f9f7 964 * @note
<> 144:ef7eb2e8f9f7 965 * This function will stall if buffer is empty, until data is received.
<> 144:ef7eb2e8f9f7 966 * Alternatively the user can explicitly check whether data is available, and
<> 144:ef7eb2e8f9f7 967 * if data is avaliable, call @ref USART_RxDoubleGet() to read the RXDOUBLE
<> 144:ef7eb2e8f9f7 968 * register directly.
<> 144:ef7eb2e8f9f7 969 *
<> 144:ef7eb2e8f9f7 970 * @param[in] usart
<> 144:ef7eb2e8f9f7 971 * Pointer to USART/UART peripheral register block.
<> 144:ef7eb2e8f9f7 972 *
<> 144:ef7eb2e8f9f7 973 * @return
<> 144:ef7eb2e8f9f7 974 * Data received.
<> 144:ef7eb2e8f9f7 975 ******************************************************************************/
<> 144:ef7eb2e8f9f7 976 uint16_t USART_RxDouble(USART_TypeDef *usart)
<> 144:ef7eb2e8f9f7 977 {
<> 144:ef7eb2e8f9f7 978 while (!(usart->STATUS & USART_STATUS_RXFULL))
<> 144:ef7eb2e8f9f7 979 ;
<> 144:ef7eb2e8f9f7 980
<> 144:ef7eb2e8f9f7 981 return (uint16_t)usart->RXDOUBLE;
<> 144:ef7eb2e8f9f7 982 }
<> 144:ef7eb2e8f9f7 983
<> 144:ef7eb2e8f9f7 984
<> 144:ef7eb2e8f9f7 985 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 986 * @brief
<> 144:ef7eb2e8f9f7 987 * Receive two 4-9 bit frames, or one 10-16 bit frame with extended
<> 144:ef7eb2e8f9f7 988 * information.
<> 144:ef7eb2e8f9f7 989 *
<> 144:ef7eb2e8f9f7 990 * @details
<> 144:ef7eb2e8f9f7 991 * This function is normally used to receive one frame when operating with
<> 144:ef7eb2e8f9f7 992 * frame length 10-16 bits and additional RX status information is required.
<> 144:ef7eb2e8f9f7 993 *
<> 144:ef7eb2e8f9f7 994 * Notice that possible parity/stop bits in asynchronous mode are not
<> 144:ef7eb2e8f9f7 995 * considered part of specified frame bit length.
<> 144:ef7eb2e8f9f7 996 *
<> 144:ef7eb2e8f9f7 997 * @note
<> 144:ef7eb2e8f9f7 998 * This function will stall if buffer is empty, until data is received.
<> 144:ef7eb2e8f9f7 999 * Alternatively the user can explicitly check whether data is available, and
<> 144:ef7eb2e8f9f7 1000 * if data is avaliable, call @ref USART_RxDoubleXGet() to read the RXDOUBLEX
<> 144:ef7eb2e8f9f7 1001 * register directly.
<> 144:ef7eb2e8f9f7 1002 *
<> 144:ef7eb2e8f9f7 1003 * @param[in] usart
<> 144:ef7eb2e8f9f7 1004 * Pointer to USART/UART peripheral register block.
<> 144:ef7eb2e8f9f7 1005 *
<> 144:ef7eb2e8f9f7 1006 * @return
<> 144:ef7eb2e8f9f7 1007 * Data received.
<> 144:ef7eb2e8f9f7 1008 ******************************************************************************/
<> 144:ef7eb2e8f9f7 1009 uint32_t USART_RxDoubleExt(USART_TypeDef *usart)
<> 144:ef7eb2e8f9f7 1010 {
<> 144:ef7eb2e8f9f7 1011 while (!(usart->STATUS & USART_STATUS_RXFULL))
<> 144:ef7eb2e8f9f7 1012 ;
<> 144:ef7eb2e8f9f7 1013
<> 144:ef7eb2e8f9f7 1014 return usart->RXDOUBLEX;
<> 144:ef7eb2e8f9f7 1015 }
<> 144:ef7eb2e8f9f7 1016
<> 144:ef7eb2e8f9f7 1017
<> 144:ef7eb2e8f9f7 1018 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1019 * @brief
<> 144:ef7eb2e8f9f7 1020 * Receive one 4-9 bit frame, (or part of 10-16 bit frame) with extended
<> 144:ef7eb2e8f9f7 1021 * information.
<> 144:ef7eb2e8f9f7 1022 *
<> 144:ef7eb2e8f9f7 1023 * @details
<> 144:ef7eb2e8f9f7 1024 * This function is normally used to receive one frame when operating with
<> 144:ef7eb2e8f9f7 1025 * frame length 4-9 bits and additional RX status information is required.
<> 144:ef7eb2e8f9f7 1026 *
<> 144:ef7eb2e8f9f7 1027 * Notice that possible parity/stop bits in asynchronous mode are not
<> 144:ef7eb2e8f9f7 1028 * considered part of specified frame bit length.
<> 144:ef7eb2e8f9f7 1029 *
<> 144:ef7eb2e8f9f7 1030 * @note
<> 144:ef7eb2e8f9f7 1031 * This function will stall if buffer is empty, until data is received.
<> 144:ef7eb2e8f9f7 1032 * Alternatively the user can explicitly check whether data is available, and
<> 144:ef7eb2e8f9f7 1033 * if data is avaliable, call @ref USART_RxDataXGet() to read the RXDATAX
<> 144:ef7eb2e8f9f7 1034 * register directly.
<> 144:ef7eb2e8f9f7 1035 *
<> 144:ef7eb2e8f9f7 1036 * @param[in] usart
<> 144:ef7eb2e8f9f7 1037 * Pointer to USART/UART peripheral register block.
<> 144:ef7eb2e8f9f7 1038 *
<> 144:ef7eb2e8f9f7 1039 * @return
<> 144:ef7eb2e8f9f7 1040 * Data received.
<> 144:ef7eb2e8f9f7 1041 ******************************************************************************/
<> 144:ef7eb2e8f9f7 1042 uint16_t USART_RxExt(USART_TypeDef *usart)
<> 144:ef7eb2e8f9f7 1043 {
<> 144:ef7eb2e8f9f7 1044 while (!(usart->STATUS & USART_STATUS_RXDATAV))
<> 144:ef7eb2e8f9f7 1045 ;
<> 144:ef7eb2e8f9f7 1046
<> 144:ef7eb2e8f9f7 1047 return (uint16_t)usart->RXDATAX;
<> 144:ef7eb2e8f9f7 1048 }
<> 144:ef7eb2e8f9f7 1049
<> 144:ef7eb2e8f9f7 1050
<> 144:ef7eb2e8f9f7 1051 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1052 * @brief
<> 144:ef7eb2e8f9f7 1053 * Perform one 8 bit frame SPI transfer.
<> 144:ef7eb2e8f9f7 1054 *
<> 144:ef7eb2e8f9f7 1055 * @note
<> 144:ef7eb2e8f9f7 1056 * This function will stall if the transmit buffer is full. When a transmit
<> 144:ef7eb2e8f9f7 1057 * buffer becomes available, data is written and the function will wait until
<> 144:ef7eb2e8f9f7 1058 * the data is fully transmitted. The SPI return value is then read out and
<> 144:ef7eb2e8f9f7 1059 * returned.
<> 144:ef7eb2e8f9f7 1060 *
<> 144:ef7eb2e8f9f7 1061 * @param[in] usart
<> 144:ef7eb2e8f9f7 1062 * Pointer to USART peripheral register block.
<> 144:ef7eb2e8f9f7 1063 *
<> 144:ef7eb2e8f9f7 1064 * @param[in] data
<> 144:ef7eb2e8f9f7 1065 * Data to transmit.
<> 144:ef7eb2e8f9f7 1066 *
<> 144:ef7eb2e8f9f7 1067 * @return
<> 144:ef7eb2e8f9f7 1068 * Data received.
<> 144:ef7eb2e8f9f7 1069 ******************************************************************************/
<> 144:ef7eb2e8f9f7 1070 uint8_t USART_SpiTransfer(USART_TypeDef *usart, uint8_t data)
<> 144:ef7eb2e8f9f7 1071 {
<> 144:ef7eb2e8f9f7 1072 while (!(usart->STATUS & USART_STATUS_TXBL))
<> 144:ef7eb2e8f9f7 1073 ;
<> 144:ef7eb2e8f9f7 1074 usart->TXDATA = (uint32_t)data;
<> 144:ef7eb2e8f9f7 1075 while (!(usart->STATUS & USART_STATUS_TXC))
<> 144:ef7eb2e8f9f7 1076 ;
<> 144:ef7eb2e8f9f7 1077 return (uint8_t)usart->RXDATA;
<> 144:ef7eb2e8f9f7 1078 }
<> 144:ef7eb2e8f9f7 1079
<> 144:ef7eb2e8f9f7 1080
<> 144:ef7eb2e8f9f7 1081 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1082 * @brief
<> 144:ef7eb2e8f9f7 1083 * Transmit one 4-9 bit frame.
<> 144:ef7eb2e8f9f7 1084 *
<> 144:ef7eb2e8f9f7 1085 * @details
<> 144:ef7eb2e8f9f7 1086 * Depending on frame length configuration, 4-8 (least significant) bits from
<> 144:ef7eb2e8f9f7 1087 * @p data are transmitted. If frame length is 9, 8 bits are transmitted from
<> 144:ef7eb2e8f9f7 1088 * @p data and one bit as specified by CTRL register, BIT8DV field. Please
<> 144:ef7eb2e8f9f7 1089 * refer to USART_TxExt() for transmitting 9 bit frame with full control of
<> 144:ef7eb2e8f9f7 1090 * all 9 bits.
<> 144:ef7eb2e8f9f7 1091 *
<> 144:ef7eb2e8f9f7 1092 * Notice that possible parity/stop bits in asynchronous mode are not
<> 144:ef7eb2e8f9f7 1093 * considered part of specified frame bit length.
<> 144:ef7eb2e8f9f7 1094 *
<> 144:ef7eb2e8f9f7 1095 * @note
<> 144:ef7eb2e8f9f7 1096 * This function will stall if buffer is full, until buffer becomes available.
<> 144:ef7eb2e8f9f7 1097 *
<> 144:ef7eb2e8f9f7 1098 * @param[in] usart
<> 144:ef7eb2e8f9f7 1099 * Pointer to USART/UART peripheral register block.
<> 144:ef7eb2e8f9f7 1100 *
<> 144:ef7eb2e8f9f7 1101 * @param[in] data
<> 144:ef7eb2e8f9f7 1102 * Data to transmit. See details above for further info.
<> 144:ef7eb2e8f9f7 1103 ******************************************************************************/
<> 144:ef7eb2e8f9f7 1104 void USART_Tx(USART_TypeDef *usart, uint8_t data)
<> 144:ef7eb2e8f9f7 1105 {
<> 144:ef7eb2e8f9f7 1106 /* Check that transmit buffer is empty */
<> 144:ef7eb2e8f9f7 1107 while (!(usart->STATUS & USART_STATUS_TXBL))
<> 144:ef7eb2e8f9f7 1108 ;
<> 144:ef7eb2e8f9f7 1109 usart->TXDATA = (uint32_t)data;
<> 144:ef7eb2e8f9f7 1110 }
<> 144:ef7eb2e8f9f7 1111
<> 144:ef7eb2e8f9f7 1112
<> 144:ef7eb2e8f9f7 1113 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1114 * @brief
<> 144:ef7eb2e8f9f7 1115 * Transmit two 4-9 bit frames, or one 10-16 bit frame.
<> 144:ef7eb2e8f9f7 1116 *
<> 144:ef7eb2e8f9f7 1117 * @details
<> 144:ef7eb2e8f9f7 1118 * Depending on frame length configuration, 4-8 (least significant) bits from
<> 144:ef7eb2e8f9f7 1119 * each byte in @p data are transmitted. If frame length is 9, 8 bits are
<> 144:ef7eb2e8f9f7 1120 * transmitted from each byte in @p data adding one bit as specified by CTRL
<> 144:ef7eb2e8f9f7 1121 * register, BIT8DV field, to each byte. Please refer to USART_TxDoubleExt()
<> 144:ef7eb2e8f9f7 1122 * for transmitting two 9 bit frames with full control of all 9 bits.
<> 144:ef7eb2e8f9f7 1123 *
<> 144:ef7eb2e8f9f7 1124 * If frame length is 10-16, 10-16 (least significant) bits from @p data
<> 144:ef7eb2e8f9f7 1125 * are transmitted.
<> 144:ef7eb2e8f9f7 1126 *
<> 144:ef7eb2e8f9f7 1127 * Notice that possible parity/stop bits in asynchronous mode are not
<> 144:ef7eb2e8f9f7 1128 * considered part of specified frame bit length.
<> 144:ef7eb2e8f9f7 1129 *
<> 144:ef7eb2e8f9f7 1130 * @note
<> 144:ef7eb2e8f9f7 1131 * This function will stall if buffer is full, until buffer becomes available.
<> 144:ef7eb2e8f9f7 1132 *
<> 144:ef7eb2e8f9f7 1133 * @param[in] usart
<> 144:ef7eb2e8f9f7 1134 * Pointer to USART/UART peripheral register block.
<> 144:ef7eb2e8f9f7 1135 *
<> 144:ef7eb2e8f9f7 1136 * @param[in] data
<> 144:ef7eb2e8f9f7 1137 * Data to transmit, the least significant byte holds the frame transmitted
<> 144:ef7eb2e8f9f7 1138 * first. See details above for further info.
<> 144:ef7eb2e8f9f7 1139 ******************************************************************************/
<> 144:ef7eb2e8f9f7 1140 void USART_TxDouble(USART_TypeDef *usart, uint16_t data)
<> 144:ef7eb2e8f9f7 1141 {
<> 144:ef7eb2e8f9f7 1142 /* Check that transmit buffer is empty */
<> 144:ef7eb2e8f9f7 1143 while (!(usart->STATUS & USART_STATUS_TXBL))
<> 144:ef7eb2e8f9f7 1144 ;
<> 144:ef7eb2e8f9f7 1145 usart->TXDOUBLE = (uint32_t)data;
<> 144:ef7eb2e8f9f7 1146 }
<> 144:ef7eb2e8f9f7 1147
<> 144:ef7eb2e8f9f7 1148
<> 144:ef7eb2e8f9f7 1149 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1150 * @brief
<> 144:ef7eb2e8f9f7 1151 * Transmit two 4-9 bit frames, or one 10-16 bit frame with extended control.
<> 144:ef7eb2e8f9f7 1152 *
<> 144:ef7eb2e8f9f7 1153 * @details
<> 144:ef7eb2e8f9f7 1154 * Notice that possible parity/stop bits in asynchronous mode are not
<> 144:ef7eb2e8f9f7 1155 * considered part of specified frame bit length.
<> 144:ef7eb2e8f9f7 1156 *
<> 144:ef7eb2e8f9f7 1157 * @note
<> 144:ef7eb2e8f9f7 1158 * This function will stall if buffer is full, until buffer becomes available.
<> 144:ef7eb2e8f9f7 1159 *
<> 144:ef7eb2e8f9f7 1160 * @param[in] usart
<> 144:ef7eb2e8f9f7 1161 * Pointer to USART/UART peripheral register block.
<> 144:ef7eb2e8f9f7 1162 *
<> 144:ef7eb2e8f9f7 1163 * @param[in] data
<> 144:ef7eb2e8f9f7 1164 * Data to transmit with extended control. Contains two 16 bit words
<> 144:ef7eb2e8f9f7 1165 * concatenated. Least significant word holds frame transitted first. If frame
<> 144:ef7eb2e8f9f7 1166 * length is 4-9, two frames with 4-9 least significant bits from each 16 bit
<> 144:ef7eb2e8f9f7 1167 * word are transmitted.
<> 144:ef7eb2e8f9f7 1168 * @par
<> 144:ef7eb2e8f9f7 1169 * If frame length is 10-16 bits, 8 data bits are taken from the least
<> 144:ef7eb2e8f9f7 1170 * significant 16 bit word, and the remaining bits from the other 16 bit word.
<> 144:ef7eb2e8f9f7 1171 * @par
<> 144:ef7eb2e8f9f7 1172 * Additional control bits are available as documented in the reference
<> 144:ef7eb2e8f9f7 1173 * manual (set to 0 if not used). For 10-16 bit frame length, these control
<> 144:ef7eb2e8f9f7 1174 * bits are taken from the most significant 16 bit word.
<> 144:ef7eb2e8f9f7 1175 ******************************************************************************/
<> 144:ef7eb2e8f9f7 1176 void USART_TxDoubleExt(USART_TypeDef *usart, uint32_t data)
<> 144:ef7eb2e8f9f7 1177 {
<> 144:ef7eb2e8f9f7 1178 /* Check that transmit buffer is empty */
<> 144:ef7eb2e8f9f7 1179 while (!(usart->STATUS & USART_STATUS_TXBL))
<> 144:ef7eb2e8f9f7 1180 ;
<> 144:ef7eb2e8f9f7 1181 usart->TXDOUBLEX = data;
<> 144:ef7eb2e8f9f7 1182 }
<> 144:ef7eb2e8f9f7 1183
<> 144:ef7eb2e8f9f7 1184
<> 144:ef7eb2e8f9f7 1185 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1186 * @brief
<> 144:ef7eb2e8f9f7 1187 * Transmit one 4-9 bit frame with extended control.
<> 144:ef7eb2e8f9f7 1188 *
<> 144:ef7eb2e8f9f7 1189 * @details
<> 144:ef7eb2e8f9f7 1190 * Notice that possible parity/stop bits in asynchronous mode are not
<> 144:ef7eb2e8f9f7 1191 * considered part of specified frame bit length.
<> 144:ef7eb2e8f9f7 1192 *
<> 144:ef7eb2e8f9f7 1193 * @note
<> 144:ef7eb2e8f9f7 1194 * This function will stall if buffer is full, until buffer becomes available.
<> 144:ef7eb2e8f9f7 1195 *
<> 144:ef7eb2e8f9f7 1196 * @param[in] usart
<> 144:ef7eb2e8f9f7 1197 * Pointer to USART/UART peripheral register block.
<> 144:ef7eb2e8f9f7 1198 *
<> 144:ef7eb2e8f9f7 1199 * @param[in] data
<> 144:ef7eb2e8f9f7 1200 * Data to transmit with extended control. Least significant bits contains
<> 144:ef7eb2e8f9f7 1201 * frame bits, and additional control bits are available as documented in
<> 144:ef7eb2e8f9f7 1202 * the reference manual (set to 0 if not used).
<> 144:ef7eb2e8f9f7 1203 ******************************************************************************/
<> 144:ef7eb2e8f9f7 1204 void USART_TxExt(USART_TypeDef *usart, uint16_t data)
<> 144:ef7eb2e8f9f7 1205 {
<> 144:ef7eb2e8f9f7 1206 /* Check that transmit buffer is empty */
<> 144:ef7eb2e8f9f7 1207 while (!(usart->STATUS & USART_STATUS_TXBL))
<> 144:ef7eb2e8f9f7 1208 ;
<> 144:ef7eb2e8f9f7 1209 usart->TXDATAX = (uint32_t)data;
<> 144:ef7eb2e8f9f7 1210 }
<> 144:ef7eb2e8f9f7 1211
<> 144:ef7eb2e8f9f7 1212
<> 144:ef7eb2e8f9f7 1213 /** @} (end addtogroup USART) */
<> 144:ef7eb2e8f9f7 1214 /** @} (end addtogroup EM_Library) */
<> 144:ef7eb2e8f9f7 1215 #endif /* defined(USART_COUNT) && (USART_COUNT > 0) */