summaryrefslogtreecommitdiff
path: root/at91lib/peripherals/usart/usart.c
diff options
context:
space:
mode:
Diffstat (limited to 'at91lib/peripherals/usart/usart.c')
-rw-r--r--at91lib/peripherals/usart/usart.c272
1 files changed, 272 insertions, 0 deletions
diff --git a/at91lib/peripherals/usart/usart.c b/at91lib/peripherals/usart/usart.c
new file mode 100644
index 0000000..3f6d0e3
--- /dev/null
+++ b/at91lib/peripherals/usart/usart.c
@@ -0,0 +1,272 @@
+/* ----------------------------------------------------------------------------
+ * 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 <utility/trace.h>
+#include <utility/assert.h>
+
+//------------------------------------------------------------------------------
+// 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;
+}
+
personal git repositories of Harald Welte. Your mileage may vary