test_simm30_dram

view serial.c @ 3:bd6ad00cb1bc

added licenses
author John Tsiombikas <nuclear@member.fsf.org>
date Thu, 09 Mar 2017 02:02:42 +0200
parents c47d05df0667
children
line source
1 /*
2 72pin SIMM DRAM tester.
3 Copyright (C) 2017 John Tsiombikas <nuclear@member.fsf.org>
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18 #ifdef XTAL
19 #define F_CLK XTAL
20 #define F_CPU XTAL
21 #else
22 #warning "compiled for 1mhz internal rc osc. serial comms won't work"
23 #define F_CLK 1000000
24 #define F_CPU 1000000
25 #endif
27 #include <stdio.h>
28 #include <avr/io.h>
29 #include <avr/interrupt.h>
30 #include <util/delay.h>
31 #include <avr/power.h>
33 static int uart_send_char(char c, FILE *fp);
34 static int uart_get_char(FILE *fp);
36 #define BUF_SZ 64
37 #define BUF_IDX_MASK 0x3f
38 #define NEXT_IDX(x) (((x) + 1) & BUF_IDX_MASK)
39 static char outbuf[BUF_SZ];
40 static volatile unsigned char out_rd, out_wr;
41 static char inbuf[BUF_SZ];
42 static volatile unsigned char in_rd, in_wr;
44 static FILE std_stream = FDEV_SETUP_STREAM(uart_send_char, uart_get_char, _FDEV_SETUP_RW);
48 void init_serial(long baud)
49 {
50 unsigned int ubrr_val = F_CLK / 16 / baud - 1;
52 power_usart0_enable();
54 /* set baud generator timer reset value */
55 UBRR0H = (unsigned char)(ubrr_val >> 8);
56 UBRR0L = (unsigned char)ubrr_val;
58 /* enable rx/tx and recv interrupt */
59 UCSR0B = (1 << RXEN0) | (1 << TXEN0) | (1 << RXCIE0);
60 /* set frame format: 8n1 */
61 UCSR0C = 3 << UCSZ00;
63 stdin = stdout = stderr = &std_stream;
64 }
66 int have_input(void)
67 {
68 return in_wr != in_rd;
69 }
71 static int uart_send_char(char c, FILE *fp)
72 {
73 int next;
75 if(c == '\n') {
76 uart_send_char('\r', fp);
77 }
79 next = NEXT_IDX(out_wr);
80 while(next == out_rd);
82 outbuf[out_wr] = c;
83 out_wr = next;
85 /* enable the Tx data register empty interrupt */
86 UCSR0B |= 1 << UDRIE0;
87 return 0;
88 }
90 static int uart_get_char(FILE *fp)
91 {
92 char c;
94 while(in_rd == in_wr);
96 c = inbuf[in_rd];
97 in_rd = NEXT_IDX(in_rd);
98 return c;
99 }
101 ISR(USART0_RX_vect)
102 {
103 char c = UDR0;
105 if(c == '\r') {
106 c = '\n';
107 }
109 inbuf[in_wr] = c;
110 in_wr = NEXT_IDX(in_wr);
111 }
113 /* USART Tx data register empty (can send more data) */
114 ISR(USART0_UDRE_vect)
115 {
116 if(out_rd != out_wr) {
117 UDR0 = outbuf[out_rd];
118 out_rd = NEXT_IDX(out_rd);
119 } else {
120 /* no more data to send for now, disable the interrupt */
121 UCSR0B &= ~(1 << UDRIE0);
122 }
123 }