/* ---------------------------------------------------------------------------- * ATMEL Microcontroller Software Support * ---------------------------------------------------------------------------- * Copyright (c) 2008, Atmel Corporation * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the disclaimer below. * * Atmel's name may not be used to endorse or promote products derived from * this software without specific prior written permission. * * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ---------------------------------------------------------------------------- */ //------------------------------------------------------------------------------ // Headers //------------------------------------------------------------------------------ #include "usart.h" #include #include //------------------------------------------------------------------------------ // Exported functions //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ /// Configures an USART peripheral with the specified parameters. /// \param usart Pointer to the USART peripheral to configure. /// \param mode Desired value for the USART mode register (see the datasheet). /// \param baudrate Baudrate at which the USART should operate (in Hz). /// \param masterClock Frequency of the system master clock (in Hz). //------------------------------------------------------------------------------ void USART_Configure(AT91S_USART *usart, unsigned int mode, unsigned int baudrate, unsigned int masterClock) { // Reset and disable receiver & transmitter usart->US_CR = AT91C_US_RSTRX | AT91C_US_RSTTX | AT91C_US_RXDIS | AT91C_US_TXDIS; // Configure mode usart->US_MR = mode; // Configure baudrate // Asynchronous, no oversampling if (((mode & AT91C_US_SYNC) == 0) && ((mode & AT91C_US_OVER) == 0)) { usart->US_BRGR = (masterClock / baudrate) / 16; } // TODO other modes } //------------------------------------------------------------------------------ /// Enables or disables the transmitter of an USART peripheral. /// \param usart Pointer to an USART peripheral /// \param enabled If true, the transmitter is enabled; otherwise it is /// disabled. //------------------------------------------------------------------------------ void USART_SetTransmitterEnabled(AT91S_USART *usart, unsigned char enabled) { if (enabled) { usart->US_CR = AT91C_US_TXEN; } else { usart->US_CR = AT91C_US_TXDIS; } } //------------------------------------------------------------------------------ /// Enables or disables the receiver of an USART peripheral /// \param usart Pointer to an USART peripheral /// \param enabled If true, the receiver is enabled; otherwise it is disabled. //------------------------------------------------------------------------------ void USART_SetReceiverEnabled(AT91S_USART *usart, unsigned char enabled) { if (enabled) { usart->US_CR = AT91C_US_RXEN; } else { usart->US_CR = AT91C_US_RXDIS; } } //------------------------------------------------------------------------------ /// Sends one packet of data through the specified USART peripheral. This /// function operates synchronously, so it only returns when the data has been /// actually sent. /// \param usart Pointer to an USART peripheral. /// \param data Data to send including 9nth bit and sync field if necessary (in /// the same format as the US_THR register in the datasheet). /// \param timeOut Time out value (0 = no timeout). //------------------------------------------------------------------------------ void USART_Write( AT91S_USART *usart, unsigned short data, volatile unsigned int timeOut) { if (timeOut == 0) { while ((usart->US_CSR & AT91C_US_TXEMPTY) == 0); } else { while ((usart->US_CSR & AT91C_US_TXEMPTY) == 0) { if (timeOut == 0) { TRACE_ERROR("USART_Write: Timed out.\n\r"); return; } timeOut--; } } usart->US_THR = data; } //------------------------------------------------------------------------------ /// Sends the contents of a data buffer through the specified USART peripheral. /// This function returns immediately (1 if the buffer has been queued, 0 /// otherwise); poll the ENDTX and TXBUFE bits of the USART status register /// to check for the transfer completion. /// \param usart Pointer to an USART peripheral. /// \param buffer Pointer to the data buffer to send. /// \param size Size of the data buffer (in bytes). //------------------------------------------------------------------------------ unsigned char USART_WriteBuffer( AT91S_USART *usart, void *buffer, unsigned int size) { // Check if the first PDC bank is free if ((usart->US_TCR == 0) && (usart->US_TNCR == 0)) { usart->US_TPR = (unsigned int) buffer; usart->US_TCR = size; usart->US_PTCR = AT91C_PDC_TXTEN; return 1; } // Check if the second PDC bank is free else if (usart->US_TNCR == 0) { usart->US_TNPR = (unsigned int) buffer; usart->US_TNCR = size; return 1; } else { return 0; } } //------------------------------------------------------------------------------ /// Reads and return a packet of data on the specified USART peripheral. This /// function operates asynchronously, so it waits until some data has been /// received. /// \param usart Pointer to an USART peripheral. /// \param timeOut Time out value (0 -> no timeout). //------------------------------------------------------------------------------ unsigned short USART_Read( AT91S_USART *usart, volatile unsigned int timeOut) { if (timeOut == 0) { while ((usart->US_CSR & AT91C_US_RXRDY) == 0); } else { while ((usart->US_CSR & AT91C_US_RXRDY) == 0) { if (timeOut == 0) { TRACE_ERROR("USART_Read: Timed out.\n\r"); return 0; } timeOut--; } } return usart->US_RHR; } //------------------------------------------------------------------------------ /// Reads data from an USART peripheral, filling the provided buffer until it /// becomes full. This function returns immediately with 1 if the buffer has /// been queued for transmission; otherwise 0. /// \param usart Pointer to an USART peripheral. /// \param buffer Pointer to the buffer where the received data will be stored. /// \param size Size of the data buffer (in bytes). //------------------------------------------------------------------------------ unsigned char USART_ReadBuffer(AT91S_USART *usart, void *buffer, unsigned int size) { // Check if the first PDC bank is free if ((usart->US_RCR == 0) && (usart->US_RNCR == 0)) { usart->US_RPR = (unsigned int) buffer; usart->US_RCR = size; usart->US_PTCR = AT91C_PDC_RXTEN; return 1; } // Check if the second PDC bank is free else if (usart->US_RNCR == 0) { usart->US_RNPR = (unsigned int) buffer; usart->US_RNCR = size; return 1; } else { return 0; } } //------------------------------------------------------------------------------ /// Returns 1 if some data has been received and can be read from an USART; /// otherwise returns 0. /// \param usart Pointer to an AT91S_USART instance. //------------------------------------------------------------------------------ unsigned char USART_IsDataAvailable(AT91S_USART *usart) { if ((usart->US_CSR & AT91C_US_RXRDY) != 0) { return 1; } else { return 0; } } //------------------------------------------------------------------------------ /// Sets the filter value for the IRDA demodulator. /// \param pUsart Pointer to an AT91S_USART instance. /// \param filter Filter value. //------------------------------------------------------------------------------ void USART_SetIrdaFilter(AT91S_USART *pUsart, unsigned char filter) { SANITY_CHECK(pUsart); pUsart->US_IF = filter; }