avr_test_simm72_dram
diff serial.c @ 0:c47d05df0667
initial commit
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Tue, 07 Mar 2017 23:50:45 +0200 |
parents | |
children | bd6ad00cb1bc |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/serial.c Tue Mar 07 23:50:45 2017 +0200 1.3 @@ -0,0 +1,106 @@ 1.4 +#ifdef XTAL 1.5 +#define F_CLK XTAL 1.6 +#define F_CPU XTAL 1.7 +#else 1.8 +#warning "compiled for 1mhz internal rc osc. serial comms won't work" 1.9 +#define F_CLK 1000000 1.10 +#define F_CPU 1000000 1.11 +#endif 1.12 + 1.13 +#include <stdio.h> 1.14 +#include <avr/io.h> 1.15 +#include <avr/interrupt.h> 1.16 +#include <util/delay.h> 1.17 +#include <avr/power.h> 1.18 + 1.19 +static int uart_send_char(char c, FILE *fp); 1.20 +static int uart_get_char(FILE *fp); 1.21 + 1.22 +#define BUF_SZ 64 1.23 +#define BUF_IDX_MASK 0x3f 1.24 +#define NEXT_IDX(x) (((x) + 1) & BUF_IDX_MASK) 1.25 +static char outbuf[BUF_SZ]; 1.26 +static volatile unsigned char out_rd, out_wr; 1.27 +static char inbuf[BUF_SZ]; 1.28 +static volatile unsigned char in_rd, in_wr; 1.29 + 1.30 +static FILE std_stream = FDEV_SETUP_STREAM(uart_send_char, uart_get_char, _FDEV_SETUP_RW); 1.31 + 1.32 + 1.33 + 1.34 +void init_serial(long baud) 1.35 +{ 1.36 + unsigned int ubrr_val = F_CLK / 16 / baud - 1; 1.37 + 1.38 + power_usart0_enable(); 1.39 + 1.40 + /* set baud generator timer reset value */ 1.41 + UBRR0H = (unsigned char)(ubrr_val >> 8); 1.42 + UBRR0L = (unsigned char)ubrr_val; 1.43 + 1.44 + /* enable rx/tx and recv interrupt */ 1.45 + UCSR0B = (1 << RXEN0) | (1 << TXEN0) | (1 << RXCIE0); 1.46 + /* set frame format: 8n1 */ 1.47 + UCSR0C = 3 << UCSZ00; 1.48 + 1.49 + stdin = stdout = stderr = &std_stream; 1.50 +} 1.51 + 1.52 +int have_input(void) 1.53 +{ 1.54 + return in_wr != in_rd; 1.55 +} 1.56 + 1.57 +static int uart_send_char(char c, FILE *fp) 1.58 +{ 1.59 + int next; 1.60 + 1.61 + if(c == '\n') { 1.62 + uart_send_char('\r', fp); 1.63 + } 1.64 + 1.65 + next = NEXT_IDX(out_wr); 1.66 + while(next == out_rd); 1.67 + 1.68 + outbuf[out_wr] = c; 1.69 + out_wr = next; 1.70 + 1.71 + /* enable the Tx data register empty interrupt */ 1.72 + UCSR0B |= 1 << UDRIE0; 1.73 + return 0; 1.74 +} 1.75 + 1.76 +static int uart_get_char(FILE *fp) 1.77 +{ 1.78 + char c; 1.79 + 1.80 + while(in_rd == in_wr); 1.81 + 1.82 + c = inbuf[in_rd]; 1.83 + in_rd = NEXT_IDX(in_rd); 1.84 + return c; 1.85 +} 1.86 + 1.87 +ISR(USART0_RX_vect) 1.88 +{ 1.89 + char c = UDR0; 1.90 + 1.91 + if(c == '\r') { 1.92 + c = '\n'; 1.93 + } 1.94 + 1.95 + inbuf[in_wr] = c; 1.96 + in_wr = NEXT_IDX(in_wr); 1.97 +} 1.98 + 1.99 +/* USART Tx data register empty (can send more data) */ 1.100 +ISR(USART0_UDRE_vect) 1.101 +{ 1.102 + if(out_rd != out_wr) { 1.103 + UDR0 = outbuf[out_rd]; 1.104 + out_rd = NEXT_IDX(out_rd); 1.105 + } else { 1.106 + /* no more data to send for now, disable the interrupt */ 1.107 + UCSR0B &= ~(1 << UDRIE0); 1.108 + } 1.109 +}