brmpuk initial commit
[brmpuk.git] / serial.c
blob13b5e2013b1f80bacc205ae2a24e6395eeb73424
1 #include "brmpuk.h"
3 #include <avr/io.h>
4 #include <avr/interrupt.h>
5 #include "serial.h"
8 #define NOINT
9 #ifndef NOINT
11 /* Ring buffer for received data. */
13 #define BUF_SIZE 64
15 struct ring_buffer {
16 /* ........incoming.......
17 * ^head ^head+bytes */
18 unsigned char buffer[BUF_SIZE];
19 int head;
20 int bytes;
21 } buf = { { 0 }, 0, 0 };
23 static inline void store_char(uint8_t data)
25 if (buf.bytes >= BUF_SIZE)
26 return; // overflow!
28 int i = (buf.head + buf.bytes) % BUF_SIZE;
29 buf.buffer[i] = data;
30 buf.bytes++;
33 #endif
36 /* USART hardware handling. */
38 #define BAUD 38400 // Rychlost prenosu dat
39 #define MYUBRR (F_CPU/16/BAUD-1) // Konstanta pouzita pro nastaveni prenosu
41 static void USART0_Init(uint16_t ubrr) { // fukce pro inicializaci USART0 komunikace
42 UBRR0H = (uint8_t) (ubrr >> 8);
43 UBRR0L = (uint8_t) ubrr;
45 UCSR0C = (1<<UCSZ01)|(1<<UCSZ00) | (1<<UPM01)|(1<<UPM00)/* | (1<<USBS0)*/; // 8 N 1
46 UCSR0A = 0; // no special stuff
48 UCSR0B = (1<<RXEN0)|(1<<TXEN0)
49 #ifndef NOINT
50 | (1<<RXCIE0)
51 #endif
55 static void USART0_Transmit(uint8_t data) { // poslani dat po USART0
56 while (!(UCSR0A & (1<<UDRE0))) ; // cekani na odesilaci buffer
57 UDR0 = data; // zapsani dat = odeslani dat po USART0
60 #ifndef NOINT
61 SIGNAL(SIG_UART0_RECV)
63 unsigned char data = UDR0;
64 store_char(data);
65 if (data >= 'A' && data <= 'Z')
66 data ^= 0x20;
67 USART0_Transmit(data);
69 #endif
72 /* Public API. */
74 void serial_init(void)
76 USART0_Init(MYUBRR);
79 void serial_send(uint8_t data)
81 USART0_Transmit(data);
84 int serial_waiting(void)
86 #ifdef NOINT
87 return UCSR0A & _BV(RXC0);
88 #else
89 return buf.bytes;
90 #endif
93 uint8_t serial_recv(void)
95 #ifdef NOINT
96 volatile int x = 0;
97 while (!serial_waiting()) x++;
99 uint8_t data = UDR0;
100 #if 0
101 if (data >= 'A' && data <= 'Z')
102 data ^= 0x20;
103 USART0_Transmit(data);
104 #endif
105 return data;
106 #else
107 // cli-sti is actually not required, this is race-free!
108 uint8_t data = buf.buffer[buf.head];
109 buf.bytes--;
110 buf.head = (buf.head + 1) % BUF_SIZE;
111 return data;
112 #endif