1 /* ----------------------------------------------------------------------------
\r
2 * SAM Software Package License
\r
3 * ----------------------------------------------------------------------------
\r
4 * Copyright (c) 2011, 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
30 /** \addtogroup usart_module Working with USART
\r
31 * The USART driver provides the interface to configure and use the USART peripheral.\n
\r
33 * The USART supports several kinds of comminication modes such as full-duplex asynchronous/
\r
34 * synchronous serial commnunication,RS485 with driver control signal,ISO7816,SPI and Test modes.
\r
36 * To start a USART transfer with \ref dmad_module "DMA" support, the user could follow these steps:
\r
38 * <li> Configure USART with expected mode and baudrate(see \ref USART_Configure), which could be done by:
\r
39 * -# Resetting and disabling transmitter and receiver by setting US_CR(Control Register). </li>
\r
40 * -# Conifguring the USART in a specific mode by setting USART_MODE bits in US_MR(Mode Register) </li>
\r
41 * -# Setting baudrate which is different from mode to mode.
\r
43 * <li> Enable transmitter or receiver respectively by set US_CR_TXEN or US_CR_RXEN in US_CR.</li>
\r
44 * <li> Read from or write to the peripheral with \ref dmad_module </li>
\r
47 * For more accurate information, please look at the USART section of the
\r
60 * Implementation of USART (Universal Synchronous Asynchronous Receiver Transmitter)
\r
64 /*------------------------------------------------------------------------------
\r
66 *------------------------------------------------------------------------------*/
\r
72 /*------------------------------------------------------------------------------
\r
73 * Exported functions
\r
74 *------------------------------------------------------------------------------*/
\r
77 * \brief Configures an USART peripheral with the specified parameters.
\r
80 * \param usart Pointer to the USART peripheral to configure.
\r
81 * \param mode Desired value for the USART mode register (see the datasheet).
\r
82 * \param baudrate Baudrate at which the USART should operate (in Hz).
\r
83 * \param masterClock Frequency of the system master clock (in Hz).
\r
85 void USART_Configure(Usart *usart,
\r
88 uint32_t masterClock)
\r
91 uint32_t id = ID_USART0;
\r
92 maxClock = masterClock;
\r
93 /* Reset and disable receiver & transmitter*/
\r
94 usart->US_CR = US_CR_RSTRX | US_CR_RSTTX
\r
95 | US_CR_RXDIS | US_CR_TXDIS;
\r
96 if ((uint32_t)usart == (uint32_t)USART0) id = ID_USART0;
\r
97 else if ((uint32_t)usart == (uint32_t)USART1) id = ID_USART1;
\r
98 else if ((uint32_t)usart == (uint32_t)USART2) id = ID_USART2;
\r
99 else if ((uint32_t)usart == (uint32_t)USART3) id = ID_USART3;
\r
100 /* Configure mode*/
\r
101 usart->US_MR = mode;
\r
102 maxClock = PMC_SetPeriMaxClock(id, masterClock);
\r
103 /* Configure baudrate*/
\r
104 /* Asynchronous, no oversampling*/
\r
105 if (((mode & US_MR_SYNC) == 0)
\r
106 && ((mode & US_MR_OVER) == 0))
\r
108 usart->US_BRGR = (maxClock / baudrate) / 16;
\r
110 if( ((mode & US_MR_USART_MODE_SPI_MASTER) == US_MR_USART_MODE_SPI_MASTER)
\r
111 || ((mode & US_MR_SYNC) == US_MR_SYNC))
\r
113 if( (mode & US_MR_USCLKS_Msk) == US_MR_USCLKS_MCK)
\r
115 usart->US_BRGR = maxClock / baudrate;
\r
119 if ( (mode & US_MR_USCLKS_DIV) == US_MR_USCLKS_DIV)
\r
121 usart->US_BRGR = maxClock / baudrate / 8;
\r
125 /* TODO other modes*/
\r
128 * \brief Enables or disables the transmitter of an USART peripheral.
\r
131 * \param usart Pointer to an USART peripheral
\r
132 * \param enabled If true, the transmitter is enabled; otherwise it is
\r
135 void USART_SetTransmitterEnabled(Usart *usart, uint8_t enabled)
\r
139 usart->US_CR = US_CR_TXEN;
\r
143 usart->US_CR = US_CR_TXDIS;
\r
148 * \brief Enables or disables the receiver of an USART peripheral
\r
151 * \param usart Pointer to an USART peripheral
\r
152 * \param enabled If true, the receiver is enabled; otherwise it is disabled.
\r
154 void USART_SetReceiverEnabled(Usart *usart, uint8_t enabled)
\r
158 usart->US_CR = US_CR_RXEN;
\r
162 usart->US_CR = US_CR_RXDIS;
\r
167 * \brief Enables or disables the Request To Send (RTS) of an USART peripheral
\r
170 * \param usart Pointer to an USART peripheral
\r
171 * \param enabled If true, the RTS is enabled (0); otherwise it is disabled.
\r
173 void USART_SetRTSEnabled( Usart *usart, uint8_t enabled)
\r
177 usart->US_CR = US_CR_RTSEN;
\r
181 usart->US_CR = US_CR_RTSDIS;
\r
186 * \brief Sends one packet of data through the specified USART peripheral. This
\r
187 * function operates synchronously, so it only returns when the data has been
\r
191 * \param usart Pointer to an USART peripheral.
\r
192 * \param data Data to send including 9nth bit and sync field if necessary (in
\r
193 * the same format as the US_THR register in the datasheet).
\r
194 * \param timeOut Time out value (0 = no timeout).
\r
196 void USART_Write( Usart *usart, uint16_t data, volatile uint32_t timeOut)
\r
198 if (timeOut == 0) {
\r
200 while ((usart->US_CSR & US_CSR_TXEMPTY) == 0);
\r
204 while ((usart->US_CSR & US_CSR_TXEMPTY) == 0) {
\r
206 if (timeOut == 0) {
\r
208 TRACE_ERROR("USART_Write: Timed out.\n\r");
\r
215 usart->US_THR = data;
\r
220 * \brief Reads and return a packet of data on the specified USART peripheral. This
\r
221 * function operates asynchronously, so it waits until some data has been
\r
224 * \param usart Pointer to an USART peripheral.
\r
225 * \param timeOut Time out value (0 -> no timeout).
\r
227 uint16_t USART_Read( Usart *usart, volatile uint32_t timeOut)
\r
229 if (timeOut == 0) {
\r
231 while ((usart->US_CSR & US_CSR_RXRDY) == 0);
\r
235 while ((usart->US_CSR & US_CSR_RXRDY) == 0) {
\r
237 if (timeOut == 0) {
\r
239 TRACE_ERROR( "USART_Read: Timed out.\n\r" ) ;
\r
246 return usart->US_RHR;
\r
250 * \brief Returns 1 if some data has been received and can be read from an USART;
\r
251 * otherwise returns 0.
\r
253 * \param usart Pointer to an Usart instance.
\r
255 uint8_t USART_IsDataAvailable(Usart *usart)
\r
257 if ((usart->US_CSR & US_CSR_RXRDY) != 0) {
\r
268 * \brief Sets the filter value for the IRDA demodulator.
\r
270 * \param pUsart Pointer to an Usart instance.
\r
271 * \param filter Filter value.
\r
273 void USART_SetIrdaFilter(Usart *pUsart, uint8_t filter)
\r
275 assert( pUsart != NULL ) ;
\r
277 pUsart->US_IF = filter;
\r
281 * \brief Sends one packet of data through the specified USART peripheral. This
\r
282 * function operates synchronously, so it only returns when the data has been
\r
285 * \param usart Pointer to an USART peripheral.
\r
286 * \param c Character to send
\r
288 void USART_PutChar( Usart *usart, uint8_t c)
\r
290 /* Wait for the transmitter to be ready*/
\r
291 while ((usart->US_CSR & US_CSR_TXEMPTY) == 0);
\r
293 /* Send character*/
\r
296 /* Wait for the transfer to complete*/
\r
297 while ((usart->US_CSR & US_CSR_TXEMPTY) == 0);
\r
301 * \brief Return 1 if a character can be read in USART
\r
302 * \param usart Pointer to an USART peripheral.
\r
304 uint32_t USART_IsRxReady(Usart *usart)
\r
306 return (usart->US_CSR & US_CSR_RXRDY);
\r
310 * \brief Get present status
\r
311 * \param usart Pointer to an USART peripheral.
\r
313 uint32_t USART_GetStatus(Usart *usart)
\r
315 return usart->US_CSR;
\r
319 * \brief Enable interrupt
\r
320 * \param usart Pointer to an USART peripheral.
\r
321 * \param mode Interrupt mode.
\r
323 void USART_EnableIt(Usart *usart,uint32_t mode)
\r
325 usart->US_IER = mode;
\r
329 * \brief Disable interrupt
\r
330 * \param usart Pointer to an USART peripheral.
\r
331 * \param mode Interrupt mode.
\r
333 void USART_DisableIt(Usart *usart,uint32_t mode)
\r
335 usart->US_IDR = mode;
\r
339 * \brief Return interrupt mask
\r
340 * \param usart Pointer to an USART peripheral.
\r
342 uint32_t USART_GetItMask(Usart *usart)
\r
344 return usart->US_IMR;
\r
348 * \brief Reads and returns a character from the USART.
\r
350 * \note This function is synchronous (i.e. uses polling).
\r
351 * \param usart Pointer to an USART peripheral.
\r
352 * \return Character received.
\r
354 uint8_t USART_GetChar(Usart *usart)
\r
356 while ((usart->US_CSR & US_CSR_RXRDY) == 0);
\r
357 return usart->US_RHR;
\r