added prescaler for 16 bit pwm in LPC1347 target

Fork of mbed-dev by mbed official

Committer:
mbed_official
Date:
Fri Jan 15 07:45:16 2016 +0000
Revision:
50:a417edff4437
Parent:
0:9b334a45a8ff
Child:
144:ef7eb2e8f9f7
Synchronized with git revision 6010f32619bfcbb01cc73747d4ff9040863482d9

Full URL: https://github.com/mbedmicro/mbed/commit/6010f32619bfcbb01cc73747d4ff9040863482d9/

Remove doubling of buffer size in realiseEndpoint()

Who changed what in which revision?

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