1 /* ----------------------------------------------------------------------------
\r
2 * ATMEL Microcontroller Software Support
\r
3 * ----------------------------------------------------------------------------
\r
4 * Copyright (c) 2014, Atmel Corporation
\r
6 * All rights reserved.
\r
8 * Redistribution and use in source and binary forms, with or without
\r
9 * modification, are permitted provided that the following conditions are met:
\r
11 * - Redistributions of source code must retain the above copyright notice,
\r
12 * this list of conditions and the disclaimer below.
\r
14 * Atmel's name may not be used to endorse or promote products derived from
\r
15 * this software without specific prior written permission.
\r
17 * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
\r
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
\r
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
\r
20 * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
\r
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
\r
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
\r
23 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
\r
24 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
\r
25 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
\r
26 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\r
27 * ----------------------------------------------------------------------------
\r
34 * Implementation of USART (Universal Synchronous Asynchronous Receiver Transmitter)
\r
38 /*------------------------------------------------------------------------------
\r
40 *------------------------------------------------------------------------------*/
\r
46 /*----------------------------------------------------------------------------
\r
48 *----------------------------------------------------------------------------*/
\r
51 /*------------------------------------------------------------------------------
\r
52 * Exported functions
\r
53 *------------------------------------------------------------------------------*/
\r
56 * \brief Configures an USART peripheral with the specified parameters.
\r
59 * \param usart Pointer to the USART peripheral to configure.
\r
60 * \param mode Desired value for the USART mode register (see the datasheet).
\r
61 * \param baudrate Baudrate at which the USART should operate (in Hz).
\r
62 * \param masterClock Frequency of the system master clock (in Hz).
\r
64 void USART_Configure(Usart *pUsart,
\r
67 uint32_t masterClock)
\r
70 unsigned int CD, FP, BaudError, OVER, ActualBaudRate;
\r
72 /* Reset and disable receiver & transmitter*/
\r
73 pUsart->US_CR = US_CR_RSTRX | US_CR_RSTTX
\r
74 | US_CR_RXDIS | US_CR_TXDIS | US_CR_RSTSTA;
\r
76 pUsart->US_IDR = 0xFFFFFFFF;
\r
78 /* Configure baudrate*/
\r
82 // Configure baud rate
\r
83 while (BaudError > 5)
\r
86 CD = (masterClock / (baudrate * 8*(2-OVER)));
\r
87 FP = ((masterClock / (baudrate * (2-OVER)) ) - CD * 8);
\r
88 ActualBaudRate = (masterClock/(CD*8 + FP))/(2-OVER);
\r
89 BaudError = (100-((baudrate*100/ActualBaudRate)));
\r
101 pUsart->US_BRGR = ( US_BRGR_CD(CD) | US_BRGR_FP(FP));
\r
103 /* Configure mode*/
\r
104 pUsart->US_MR = (mode | (OVER << 19) );
\r
106 // Enable receiver and transmitter
\r
107 pUsart->US_CR = US_CR_RXEN | US_CR_TXEN;
\r
110 /* Disable buffering for printf(). */
\r
111 #if ( defined (__GNUC__) && !defined (__SAMBA__) )
\r
112 setvbuf(stdout, (char *)NULL, _IONBF, 0);
\r
117 * \brief Enables or disables the transmitter of an USART peripheral.
\r
120 * \param usart Pointer to an USART peripheral
\r
121 * \param enabled If true, the transmitter is enabled; otherwise it is
\r
124 void USART_SetTransmitterEnabled(Usart *usart, uint8_t enabled)
\r
128 usart->US_CR = US_CR_TXEN;
\r
132 usart->US_CR = US_CR_TXDIS;
\r
137 * \brief Enables or disables the receiver of an USART peripheral
\r
140 * \param usart Pointer to an USART peripheral
\r
141 * \param enabled If true, the receiver is enabled; otherwise it is disabled.
\r
143 void USART_SetReceiverEnabled(Usart *usart, uint8_t enabled)
\r
147 usart->US_CR = US_CR_RXEN;
\r
151 usart->US_CR = US_CR_RXDIS;
\r
156 * \brief Enables or disables the Request To Send (RTS) of an USART peripheral
\r
159 * \param usart Pointer to an USART peripheral
\r
160 * \param enabled If true, the RTS is enabled (0); otherwise it is disabled.
\r
162 void USART_SetRTSEnabled( Usart *usart, uint8_t enabled)
\r
166 usart->US_CR = US_CR_RTSEN;
\r
170 usart->US_CR = US_CR_RTSDIS;
\r
175 * \brief Sends one packet of data through the specified USART peripheral. This
\r
176 * function operates synchronously, so it only returns when the data has been
\r
180 * \param usart Pointer to an USART peripheral.
\r
181 * \param data Data to send including 9nth bit and sync field if necessary (in
\r
182 * the same format as the US_THR register in the datasheet).
\r
183 * \param timeOut Time out value (0 = no timeout).
\r
185 void USART_Write( Usart *usart, uint16_t data, volatile uint32_t timeOut)
\r
187 if (timeOut == 0) {
\r
189 while ((usart->US_CSR & US_CSR_TXEMPTY) == 0);
\r
193 while ((usart->US_CSR & US_CSR_TXEMPTY) == 0) {
\r
195 if (timeOut == 0) {
\r
197 TRACE_ERROR("USART_Write: Timed out.\n\r");
\r
204 usart->US_THR = data;
\r
209 * \brief Reads and return a packet of data on the specified USART peripheral. This
\r
210 * function operates asynchronously, so it waits until some data has been
\r
213 * \param usart Pointer to an USART peripheral.
\r
214 * \param timeOut Time out value (0 -> no timeout).
\r
216 uint16_t USART_Read( Usart *usart, volatile uint32_t timeOut)
\r
218 if (timeOut == 0) {
\r
220 while ((usart->US_CSR & US_CSR_RXRDY) == 0);
\r
224 while ((usart->US_CSR & US_CSR_RXRDY) == 0) {
\r
226 if (timeOut == 0) {
\r
228 TRACE_ERROR( "USART_Read: Timed out.\n\r" ) ;
\r
235 return usart->US_RHR;
\r
239 * \brief Returns 1 if some data has been received and can be read from an USART;
\r
240 * otherwise returns 0.
\r
242 * \param usart Pointer to an Usart instance.
\r
244 uint8_t USART_IsDataAvailable(Usart *usart)
\r
246 if ((usart->US_CSR & US_CSR_RXRDY) != 0) {
\r
257 * \brief Sets the filter value for the IRDA demodulator.
\r
259 * \param pUsart Pointer to an Usart instance.
\r
260 * \param filter Filter value.
\r
262 void USART_SetIrdaFilter(Usart *pUsart, uint8_t filter)
\r
264 assert( pUsart != NULL ) ;
\r
266 pUsart->US_IF = filter;
\r
270 * \brief Sends one packet of data through the specified USART peripheral. This
\r
271 * function operates synchronously, so it only returns when the data has been
\r
274 * \param usart Pointer to an USART peripheral.
\r
275 * \param c Character to send
\r
277 void USART_PutChar( Usart *usart, uint8_t c)
\r
279 /* Wait for the transmitter to be ready*/
\r
280 while ((usart->US_CSR & US_CSR_TXEMPTY) == 0);
\r
282 /* Send character*/
\r
285 /* Wait for the transfer to complete*/
\r
286 while ((usart->US_CSR & US_CSR_TXEMPTY) == 0);
\r
290 * \brief Return 1 if a character can be read in USART
\r
291 * \param usart Pointer to an USART peripheral.
\r
293 uint32_t USART_IsRxReady(Usart *usart)
\r
295 return (usart->US_CSR & US_CSR_RXRDY);
\r
299 * \brief Get present status
\r
300 * \param usart Pointer to an USART peripheral.
\r
302 uint32_t USART_GetStatus(Usart *usart)
\r
304 return usart->US_CSR;
\r
308 * \brief Enable interrupt
\r
309 * \param usart Pointer to an USART peripheral.
\r
310 * \param mode Interrupt mode.
\r
312 void USART_EnableIt(Usart *usart,uint32_t mode)
\r
314 usart->US_IER = mode;
\r
318 * \brief Disable interrupt
\r
319 * \param usart Pointer to an USART peripheral.
\r
320 * \param mode Interrupt mode.
\r
322 void USART_DisableIt(Usart *usart,uint32_t mode)
\r
324 usart->US_IDR = mode;
\r
328 * \brief Return interrupt mask
\r
329 * \param usart Pointer to an USART peripheral.
\r
331 uint32_t USART_GetItMask(Usart *usart)
\r
333 return usart->US_IMR;
\r
337 * \brief Reads and returns a character from the USART.
\r
339 * \note This function is synchronous (i.e. uses polling).
\r
340 * \param usart Pointer to an USART peripheral.
\r
341 * \return Character received.
\r
343 uint8_t USART_GetChar(Usart *usart)
\r
345 while ((usart->US_CSR & US_CSR_RXRDY) == 0);
\r
346 return usart->US_RHR;
\r