Maintool / mbed-src-v4

Fork of mbed-src by mbed official

Committer:
mbed_official
Date:
Tue Apr 28 11:45:12 2015 +0100
Revision:
525:c320967f86b9
Synchronized with git revision 299385b8331142b9dc524da7a986536f60b14553

Full URL: https://github.com/mbedmicro/mbed/commit/299385b8331142b9dc524da7a986536f60b14553/

Add in Silicon Labs targets with asynchronous API support

Who changed what in which revision?

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