Contiki 2.6
|
00001 /* 00002 * Copyright (c) 2010, Mariano Alvira <mar@devl.org> and other contributors 00003 * to the MC1322x project (http://mc1322x.devl.org) 00004 * All rights reserved. 00005 * 00006 * Redistribution and use in source and binary forms, with or without 00007 * modification, are permitted provided that the following conditions 00008 * are met: 00009 * 1. Redistributions of source code must retain the above copyright 00010 * notice, this list of conditions and the following disclaimer. 00011 * 2. Redistributions in binary form must reproduce the above copyright 00012 * notice, this list of conditions and the following disclaimer in the 00013 * documentation and/or other materials provided with the distribution. 00014 * 3. Neither the name of the Institute nor the names of its contributors 00015 * may be used to endorse or promote products derived from this software 00016 * without specific prior written permission. 00017 * 00018 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 00019 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00020 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00021 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 00022 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00023 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 00024 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00025 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00026 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 00027 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 00028 * SUCH DAMAGE. 00029 * 00030 * This file is part of libmc1322x: see http://mc1322x.devl.org 00031 * for details. 00032 * 00033 * 00034 */ 00035 00036 #include <mc1322x.h> 00037 #include <stdint.h> 00038 00039 volatile char u1_tx_buf[UART1_TX_BUFFERSIZE]; 00040 volatile uint32_t u1_tx_head, u1_tx_tail; 00041 00042 #if UART1_RX_BUFFERSIZE > 32 00043 volatile char u1_rx_buf[UART1_RX_BUFFERSIZE-32]; 00044 volatile uint32_t u1_rx_head, u1_rx_tail; 00045 #endif 00046 00047 void uart1_isr(void) { 00048 00049 #if UART1_RX_BUFFERSIZE > 32 00050 if (*UART1_USTAT & ( 1 << 6)) { //receive interrupt 00051 while( *UART1_URXCON != 0 ) { //flush the hardware fifo into the software buffer 00052 uint32_t u1_rx_tail_next; 00053 u1_rx_tail_next = u1_rx_tail+1; 00054 if (u1_rx_tail_next >= sizeof(u1_rx_buf)) 00055 u1_rx_tail_next = 0; 00056 if (u1_rx_head != u1_rx_tail_next) { 00057 u1_rx_buf[u1_rx_tail]= *UART1_UDATA; 00058 u1_rx_tail = u1_rx_tail_next; 00059 } else { //buffer is full, flush the fifo 00060 while (*UART1_URXCON !=0) if (*UART1_UDATA); 00061 } 00062 } 00063 return; 00064 } 00065 #endif 00066 00067 while( *UART1_UTXCON != 0 ) { 00068 if (u1_tx_head == u1_tx_tail) { 00069 #if UART1_RX_BUFFERSIZE > 32 00070 *UART1_UCON |= (1 << 13); /*disable tx interrupt */ 00071 #else 00072 disable_irq(UART1); 00073 #endif 00074 return; 00075 } 00076 00077 *UART1_UDATA = u1_tx_buf[u1_tx_tail]; 00078 u1_tx_tail++; 00079 if (u1_tx_tail >= sizeof(u1_tx_buf)) 00080 u1_tx_tail = 0; 00081 } 00082 } 00083 00084 void uart1_putc(char c) { 00085 /* disable UART1 since */ 00086 /* UART1 isr modifies u1_tx_head and u1_tx_tail */ 00087 #if UART1_RX_BUFFERSIZE > 32 00088 *UART1_UCON |= (1 << 13); /*disable tx interrupt */ 00089 #else 00090 disable_irq(UART1); 00091 #endif 00092 00093 if( (u1_tx_head == u1_tx_tail) && 00094 (*UART1_UTXCON != 0)) { 00095 *UART1_UDATA = c; 00096 } else { 00097 u1_tx_buf[u1_tx_head] = c; 00098 u1_tx_head += 1; 00099 if (u1_tx_head >= sizeof(u1_tx_buf)) 00100 u1_tx_head = 0; 00101 if (u1_tx_head == u1_tx_tail) { /* drop chars when no room */ 00102 #if UART1_DROP_CHARS 00103 if (u1_tx_head) { u1_tx_head -=1; } else { u1_tx_head = sizeof(u1_tx_buf); } 00104 #else 00105 { 00106 uint32_t u1_tx_tail_save=u1_tx_tail; 00107 /* Back up head to show buffer not empty, and enable tx interrupt */ 00108 u1_tx_head--; 00109 #if UART1_RX_BUFFERSIZE > 32 00110 *UART1_UCON &= ~(1 << 13); /*enable tx interrupt */ 00111 #else 00112 enable_irq(UART1); 00113 #endif 00114 /* Tail will change after one character goes out */ 00115 while (u1_tx_tail_save == u1_tx_tail) ; 00116 /* Restore head to character we just stuffed */ 00117 u1_tx_head++; 00118 return; 00119 } 00120 #endif /* UART1_DROP_CHARS */ 00121 } 00122 00123 #if UART1_RX_BUFFERSIZE > 32 00124 *UART1_UCON &= ~(1 << 13); /*enable tx interrupt */ 00125 #else 00126 enable_irq(UART1); 00127 #endif 00128 00129 } 00130 } 00131 00132 uint8_t uart1_getc(void) { 00133 #if UART1_RX_BUFFERSIZE > 32 00134 /* First pull from the ram buffer */ 00135 uint8_t c=0; 00136 if (u1_rx_head != u1_rx_tail) { 00137 c = u1_rx_buf[u1_rx_head++]; 00138 if (u1_rx_head >= sizeof(u1_rx_buf)) 00139 u1_rx_head=0; 00140 return c; 00141 } 00142 #endif 00143 /* Then pull from the hardware fifo */ 00144 while(uart1_can_get() == 0) { continue; } 00145 return *UART1_UDATA; 00146 }