added prescaler for 16 bit pwm in LPC1347 target

Fork of mbed-dev by mbed official

Committer:
<>
Date:
Fri Sep 02 15:07:44 2016 +0100
Revision:
144:ef7eb2e8f9f7
Parent:
50:a417edff4437
This updates the lib to the mbed lib v125

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) */