00001
00023 #include <stdio.h>
00024 #include <avr/io.h>
00025 #include <avr/interrupt.h>
00026 #include "uart_io.h"
00027 #include "uart_io_config.h"
00028
00029
00030
00031 #define UART_IO_CONCAT(a, b) a ## b
00032 #define UART_IO_CONCAT_EXPANDED(a, b) UART_IO_CONCAT(a, b)
00033
00034 #define UART_IO_UTIL_OUTPORT(name) UART_IO_CONCAT(PORT, name)
00035 #define UART_IO_UTIL_INPORT(name) UART_IO_CONCAT(PIN, name)
00036 #define UART_IO_UTIL_DDRPORT(name) UART_IO_CONCAT(DDR, name)
00037
00038
00039
00040 #if defined(UART_IO_TX_OUTPORT) && defined(UART_IO_TX_OUTPIN)
00041 #if defined(__AVR_ATmega8__)
00042 #define INVERTER1_IN_PORT D
00043 #define INVERTER1_IN_PIN 3
00044 #else
00045 #error "Hardware not configured for device"
00046 #endif
00047
00048
00049 #define INVERTER1_IN_OUTPORT UART_IO_UTIL_OUTPORT(INVERTER1_IN_PORT)
00050 #define INVERTER1_IN_DDRPORT UART_IO_UTIL_DDRPORT(INVERTER1_IN_PORT)
00051 #define INVERTER1_IN_INPORT UART_IO_UTIL_INPORT(INVERTER1_IN_PORT)
00052
00053
00054 #define INVERTER1_OUT_OUTPORT UART_IO_UTIL_OUTPORT(UART_IO_TX_OUTPORT)
00055 #define INVERTER1_OUT_DDRPORT UART_IO_UTIL_DDRPORT(UART_IO_TX_OUTPORT)
00056 #define INVERTER1_OUT_INPORT UART_IO_UTIL_INPORT(UART_IO_TX_OUTPORT)
00057 #define INVERTER1_OUT_PIN UART_IO_TX_OUTPIN
00058
00059
00061 static void INVERTER1_ENABLE(void)
00062 {
00063 INVERTER1_OUT_DDRPORT |= _BV(INVERTER1_OUT_PIN);
00064 INVERTER1_IN_DDRPORT &= ~_BV(INVERTER1_IN_PIN);
00065 INVERTER1_IN_OUTPORT &= ~_BV(INVERTER1_IN_PIN);
00066 MCUCR &= ~_BV(ISC11);
00067 MCUCR |= _BV(ISC10);
00068 GICR |= _BV(INT1);
00069 }
00070
00071 #define INVERTER1_IN_IS_HIGH() bit_is_set(INVERTER1_IN_INPORT,INVERTER1_IN_PIN)
00072 #define INVERTER1_OUT_HIGH() INVERTER1_OUT_OUTPORT |= _BV(INVERTER1_OUT_PIN)
00073 #define INVERTER1_OUT_LOW() INVERTER1_OUT_OUTPORT &= ~_BV(INVERTER1_OUT_PIN)
00074
00075
00076 SIGNAL(SIG_INTERRUPT1) __attribute__ ((naked));
00077 SIGNAL(SIG_INTERRUPT1)
00078 {
00079 if (INVERTER1_IN_IS_HIGH())
00080 {
00081 INVERTER1_OUT_LOW();
00082 }
00083 else
00084 {
00085 INVERTER1_OUT_HIGH();
00086 }
00087 __asm__("reti"::);
00088 }
00089
00090
00091 #else //if defined(UART_IO_TX_OUTPORT) && defined(UART_IO_TX_OUTPIN)
00092
00093 #define INVERTER1_ENABLE() (void)0
00094
00095 #endif //if defined(UART_IO_TX_OUTPORT) && defined(UART_IO_TX_OUTPIN)
00096
00097
00098 static int uart_file_ioputchar(char c, FILE *stream);
00099
00100 #define UART_IO_BUFFER_SIZE (1<<(UART_IO_BUFFER_SIZE_FACTOR))
00101
00102 typedef struct {
00103 uint8_t buffer[UART_IO_BUFFER_SIZE];
00104 uint8_t put;
00105 uint8_t get;
00106 } circular_buffer_t;
00107
00108 typedef struct {
00109 circular_buffer_t tx;
00110 circular_buffer_t rx;
00111 } uart_t;
00112
00113
00114 static uart_t uart;
00115
00116 static FILE uart_file_io = FDEV_SETUP_STREAM(uart_file_ioputchar, NULL, _FDEV_SETUP_WRITE);
00117
00118 static int uart_file_ioputchar(char c, FILE *stream)
00119 {
00120 if (c == '\n')
00121 {
00122 c = '\r';
00123 }
00124 if ((uart.tx.put + 1) % UART_IO_BUFFER_SIZE == uart.tx.get)
00125 {
00126 return 1;
00127 }
00128 uart.tx.buffer[uart.tx.put] = c;
00129 ++uart.tx.put;
00130 uart.tx.put %= UART_IO_BUFFER_SIZE;
00131
00132
00133 UCSRB |= _BV(UCSRB);
00134 return 0;
00135 }
00136
00137 SIGNAL(SIG_UART_DATA)
00138 {
00139 if (uart.tx.put == uart.tx.get)
00140 {
00141 UCSRB &= ~_BV(UCSRB);
00142 }
00143 else {
00144 UDR = uart.tx.buffer[uart.tx.get];
00145 ++uart.tx.get;
00146 uart.tx.get %= UART_IO_BUFFER_SIZE;
00147 }
00148 }
00149
00150
00151 #define UART_IO_GET_UBRR_X1(baud) ((F_CPU/((baud)*16L))-1)
00152 #define UART_IO_GET_UBRR_X2(baud) ((F_CPU/((baud)*8L))-1)
00153
00154 static void uart_io_enable_tx(void)
00155 {
00156 UCSRA = 0;
00157 #define BAUD UART_IO_BAUDRATE
00158 #include <util/setbaud.h>
00159 UBRRH = UBRRH_VALUE;
00160 UBRRL = UBRRL_VALUE;
00161 #if USE_2X
00162 UCSRA |= (1 << U2X);
00163 #else
00164 UCSRA &= ~(1 << U2X);
00165 #endif
00166 UCSRB = _BV(TXEN);
00167 UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0);
00168 (void)UDR;
00169 }
00170
00171
00172 FILE* uart_io_init(void)
00173 {
00174 uart_io_enable_tx();
00175 INVERTER1_ENABLE();
00176 return &uart_file_io;
00177 }
00178
00179 char uart_io_ok_to_powersave(void)
00180 {
00181 return 0;
00182 }
00183
00184
00185
00186