avr_test_simm72_dram

annotate serial.c @ 4:1f8683589ee8

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