aboutsummaryrefslogtreecommitdiff
path: root/tmk_core/common/uart.c
diff options
context:
space:
mode:
Diffstat (limited to 'tmk_core/common/uart.c')
-rw-r--r--tmk_core/common/uart.c132
1 files changed, 63 insertions, 69 deletions
diff --git a/tmk_core/common/uart.c b/tmk_core/common/uart.c
index c17649b08..f2e4bc4f3 100644
--- a/tmk_core/common/uart.c
+++ b/tmk_core/common/uart.c
@@ -3,17 +3,17 @@
3/* UART Example for Teensy USB Development Board 3/* UART Example for Teensy USB Development Board
4 * http://www.pjrc.com/teensy/ 4 * http://www.pjrc.com/teensy/
5 * Copyright (c) 2009 PJRC.COM, LLC 5 * Copyright (c) 2009 PJRC.COM, LLC
6 * 6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal 8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights 9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is 11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions: 12 * furnished to do so, subject to the following conditions:
13 * 13 *
14 * The above copyright notice and this permission notice shall be included in 14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software. 15 * all copies or substantial portions of the Software.
16 * 16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -26,7 +26,6 @@
26// Version 1.0: Initial Release 26// Version 1.0: Initial Release
27// Version 1.1: Add support for Teensy 2.0, minor optimizations 27// Version 1.1: Add support for Teensy 2.0, minor optimizations
28 28
29
30#include <avr/io.h> 29#include <avr/io.h>
31#include <avr/interrupt.h> 30#include <avr/interrupt.h>
32 31
@@ -44,86 +43,81 @@ static volatile uint8_t rx_buffer_head;
44static volatile uint8_t rx_buffer_tail; 43static volatile uint8_t rx_buffer_tail;
45 44
46// Initialize the UART 45// Initialize the UART
47void uart_init(uint32_t baud) 46void uart_init(uint32_t baud) {
48{ 47 cli();
49 cli(); 48 UBRR0 = (F_CPU / 4 / baud - 1) / 2;
50 UBRR0 = (F_CPU / 4 / baud - 1) / 2; 49 UCSR0A = (1 << U2X0);
51 UCSR0A = (1<<U2X0); 50 UCSR0B = (1 << RXEN0) | (1 << TXEN0) | (1 << RXCIE0);
52 UCSR0B = (1<<RXEN0) | (1<<TXEN0) | (1<<RXCIE0); 51 UCSR0C = (1 << UCSZ01) | (1 << UCSZ00);
53 UCSR0C = (1<<UCSZ01) | (1<<UCSZ00); 52 tx_buffer_head = tx_buffer_tail = 0;
54 tx_buffer_head = tx_buffer_tail = 0; 53 rx_buffer_head = rx_buffer_tail = 0;
55 rx_buffer_head = rx_buffer_tail = 0; 54 sei();
56 sei();
57} 55}
58 56
59// Transmit a byte 57// Transmit a byte
60void uart_putchar(uint8_t c) 58void uart_putchar(uint8_t c) {
61{ 59 uint8_t i;
62 uint8_t i; 60
63 61 i = tx_buffer_head + 1;
64 i = tx_buffer_head + 1; 62 if (i >= TX_BUFFER_SIZE) i = 0;
65 if (i >= TX_BUFFER_SIZE) i = 0; 63 while (tx_buffer_tail == i)
66 while (tx_buffer_tail == i) ; // wait until space in buffer 64 ; // wait until space in buffer
67 //cli(); 65 // cli();
68 tx_buffer[i] = c; 66 tx_buffer[i] = c;
69 tx_buffer_head = i; 67 tx_buffer_head = i;
70 UCSR0B = (1<<RXEN0) | (1<<TXEN0) | (1<<RXCIE0) | (1<<UDRIE0); 68 UCSR0B = (1 << RXEN0) | (1 << TXEN0) | (1 << RXCIE0) | (1 << UDRIE0);
71 //sei(); 69 // sei();
72} 70}
73 71
74// Receive a byte 72// Receive a byte
75uint8_t uart_getchar(void) 73uint8_t uart_getchar(void) {
76{ 74 uint8_t c, i;
77 uint8_t c, i; 75
78 76 while (rx_buffer_head == rx_buffer_tail)
79 while (rx_buffer_head == rx_buffer_tail) ; // wait for character 77 ; // wait for character
80 i = rx_buffer_tail + 1; 78 i = rx_buffer_tail + 1;
81 if (i >= RX_BUFFER_SIZE) i = 0; 79 if (i >= RX_BUFFER_SIZE) i = 0;
82 c = rx_buffer[i]; 80 c = rx_buffer[i];
83 rx_buffer_tail = i; 81 rx_buffer_tail = i;
84 return c; 82 return c;
85} 83}
86 84
87// Return the number of bytes waiting in the receive buffer. 85// Return the number of bytes waiting in the receive buffer.
88// Call this before uart_getchar() to check if it will need 86// Call this before uart_getchar() to check if it will need
89// to wait for a byte to arrive. 87// to wait for a byte to arrive.
90uint8_t uart_available(void) 88uint8_t uart_available(void) {
91{ 89 uint8_t head, tail;
92 uint8_t head, tail; 90
93 91 head = rx_buffer_head;
94 head = rx_buffer_head; 92 tail = rx_buffer_tail;
95 tail = rx_buffer_tail; 93 if (head >= tail) return head - tail;
96 if (head >= tail) return head - tail; 94 return RX_BUFFER_SIZE + head - tail;
97 return RX_BUFFER_SIZE + head - tail;
98} 95}
99 96
100// Transmit Interrupt 97// Transmit Interrupt
101ISR(USART_UDRE_vect) 98ISR(USART_UDRE_vect) {
102{ 99 uint8_t i;
103 uint8_t i; 100
104 101 if (tx_buffer_head == tx_buffer_tail) {
105 if (tx_buffer_head == tx_buffer_tail) { 102 // buffer is empty, disable transmit interrupt
106 // buffer is empty, disable transmit interrupt 103 UCSR0B = (1 << RXEN0) | (1 << TXEN0) | (1 << RXCIE0);
107 UCSR0B = (1<<RXEN0) | (1<<TXEN0) | (1<<RXCIE0); 104 } else {
108 } else { 105 i = tx_buffer_tail + 1;
109 i = tx_buffer_tail + 1; 106 if (i >= TX_BUFFER_SIZE) i = 0;
110 if (i >= TX_BUFFER_SIZE) i = 0; 107 UDR0 = tx_buffer[i];
111 UDR0 = tx_buffer[i]; 108 tx_buffer_tail = i;
112 tx_buffer_tail = i; 109 }
113 }
114} 110}
115 111
116// Receive Interrupt 112// Receive Interrupt
117ISR(USART_RX_vect) 113ISR(USART_RX_vect) {
118{ 114 uint8_t c, i;
119 uint8_t c, i; 115
120 116 c = UDR0;
121 c = UDR0; 117 i = rx_buffer_head + 1;
122 i = rx_buffer_head + 1; 118 if (i >= RX_BUFFER_SIZE) i = 0;
123 if (i >= RX_BUFFER_SIZE) i = 0; 119 if (i != rx_buffer_tail) {
124 if (i != rx_buffer_tail) { 120 rx_buffer[i] = c;
125 rx_buffer[i] = c; 121 rx_buffer_head = i;
126 rx_buffer_head = i; 122 }
127 }
128} 123}
129