switch from UART to USART
This commit is contained in:
parent
f42fcc3b8f
commit
44c609699d
62
lib/uart.c
62
lib/uart.c
|
@ -1,62 +0,0 @@
|
||||||
/* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
/* This library handles the USART configuration */
|
|
||||||
|
|
||||||
#include <stdint.h> // Standard Integer Types
|
|
||||||
#include <stdio.h> // Standard IO facilities
|
|
||||||
#include <stdlib.h> // General utilities
|
|
||||||
#include <avr/io.h> // AVR device-specific IO definitions
|
|
||||||
|
|
||||||
#include "uart.h" // UART header
|
|
||||||
#include <util/setbaud.h> // Helper macros for baud rate calculations
|
|
||||||
|
|
||||||
/* assign input and output streams */
|
|
||||||
FILE uart_output = FDEV_SETUP_STREAM((int (*)(char, struct __file *)) uart_putchar, NULL, _FDEV_SETUP_WRITE);
|
|
||||||
FILE uart_input = FDEV_SETUP_STREAM(NULL, (int (*)(struct __file *)) uart_getchar, _FDEV_SETUP_READ);
|
|
||||||
FILE uart_io = FDEV_SETUP_STREAM((int (*)(char, struct __file *)) uart_putchar, (int (*)(struct __file *)) uart_getchar, _FDEV_SETUP_RW);
|
|
||||||
|
|
||||||
/* configure serial port */
|
|
||||||
void uart_init(void)
|
|
||||||
{
|
|
||||||
UBRR0H = UBRRH_VALUE; // set baurate (calculated from BAUD)
|
|
||||||
UBRR0L = UBRRL_VALUE; // set baurate (calculated from BAUD)
|
|
||||||
#if USE_2X
|
|
||||||
UCSR0A |= (1<<U2X0); // use double speed (set depending on BAUD)
|
|
||||||
#else
|
|
||||||
UCSR0A &= ~(1<<U2X0); // do not use double speed (set depending on BAUD)
|
|
||||||
#endif
|
|
||||||
UCSR0C = (1<<UCSZ01)|(1<<UCSZ00); // 8N1 bit data
|
|
||||||
UCSR0B = (1<<RXEN0)|(1<<TXEN0); // enable RX and TX
|
|
||||||
UCSR0B |= (1<<RXCIE0); // enable RX complete interrupt
|
|
||||||
}
|
|
||||||
|
|
||||||
/* put character on UART stream */
|
|
||||||
void uart_putchar(char c, FILE *stream)
|
|
||||||
{
|
|
||||||
if (c == '\n') { // add carrier return before line feed. this is recommended for most UART terminals
|
|
||||||
uart_putchar('\r', stream);
|
|
||||||
}
|
|
||||||
while (!(UCSR0A&(1<<UDRE0))); // wait for transmit register to empty
|
|
||||||
UDR0 = c; // put data in transmit register
|
|
||||||
while (!(UCSR0A&(1<<TXC0))); // wait for transmission to complete (else sleep mode can break it)
|
|
||||||
UCSR0A |= (1<<TXC0); // clear transmit flag
|
|
||||||
}
|
|
||||||
|
|
||||||
/* get character from UART stream (blocking) */
|
|
||||||
char uart_getchar(FILE *stream)
|
|
||||||
{
|
|
||||||
while (!(UCSR0A&(1<<RXC0))); // wait until data exists
|
|
||||||
return UDR0;
|
|
||||||
}
|
|
33
lib/uart.h
33
lib/uart.h
|
@ -1,33 +0,0 @@
|
||||||
/* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
/* This library handles the USART configuration */
|
|
||||||
|
|
||||||
/* set tolerance to 3% to allow 115200 baudrate with 16 MHz clock, else use 9600 for default <2% */
|
|
||||||
#define BAUD_TOL 3
|
|
||||||
/* serial baudrate, in bits per second (with 8N1 8 bits, no parity bit, 1 stop bit settings) */
|
|
||||||
#define BAUD 115200
|
|
||||||
|
|
||||||
/* input & output streams */
|
|
||||||
FILE uart_output;
|
|
||||||
FILE uart_input;
|
|
||||||
FILE uart_io;
|
|
||||||
|
|
||||||
/* configure serial port */
|
|
||||||
void uart_init(void);
|
|
||||||
/* put character on UART stream (blocking) */
|
|
||||||
void uart_putchar(char c, FILE *stream);
|
|
||||||
/* get character from UART stream (blocking) */
|
|
||||||
char uart_getchar(FILE *stream);
|
|
||||||
|
|
50
main.c
50
main.c
|
@ -26,7 +26,7 @@
|
||||||
#include <avr/pgmspace.h> // Program Space Utilities
|
#include <avr/pgmspace.h> // Program Space Utilities
|
||||||
#include <avr/sleep.h> // Power Management and Sleep Modes
|
#include <avr/sleep.h> // Power Management and Sleep Modes
|
||||||
|
|
||||||
#include "uart.h" // basic UART functions
|
#include "usart.h" // basic USART functions
|
||||||
#include "main.h" // main definitions
|
#include "main.h" // main definitions
|
||||||
|
|
||||||
/* help strings */
|
/* help strings */
|
||||||
|
@ -46,11 +46,11 @@ PGM_P const help_table[] PROGMEM = {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* global variables */
|
/* global variables */
|
||||||
char uart_in[32] = {0}; // user input from USART
|
char usart_in[32] = {0}; // user input from USART
|
||||||
volatile uint8_t uart_in_i = 0; // how many UART characters have been input
|
volatile uint8_t usart_in_i = 0; // how many USART characters have been input
|
||||||
|
|
||||||
/* flags, set in the interrupts and handled in the main program */
|
/* flags, set in the interrupts and handled in the main program */
|
||||||
volatile bool uart_flag = false; // UART input data is available
|
volatile bool usart_flag = false; // USART input data is available
|
||||||
|
|
||||||
/* switch off LED */
|
/* switch off LED */
|
||||||
void led_off(void)
|
void led_off(void)
|
||||||
|
@ -162,16 +162,6 @@ void help(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* save the UART input into a string */
|
|
||||||
ISR(USART_RX_vect) { /* UART receive interrupt */
|
|
||||||
uart_in[uart_in_i] = getchar(); // save input
|
|
||||||
if (uart_in_i<sizeof(uart_in)-1) { // go to next if there is space left (else overwrite last)
|
|
||||||
uart_in_i++; // prepare for next character
|
|
||||||
uart_in[uart_in_i] = 0; // always end the string
|
|
||||||
}
|
|
||||||
uart_flag = true; // notify new character is there
|
|
||||||
}
|
|
||||||
|
|
||||||
/* disable watchdog when booting */
|
/* disable watchdog when booting */
|
||||||
void wdt_init(void) __attribute__((naked)) __attribute__((section(".init3")));
|
void wdt_init(void) __attribute__((naked)) __attribute__((section(".init3")));
|
||||||
void wdt_init(void)
|
void wdt_init(void)
|
||||||
|
@ -185,10 +175,10 @@ void wdt_init(void)
|
||||||
/* initialize GPIO */
|
/* initialize GPIO */
|
||||||
void io_init(void)
|
void io_init(void)
|
||||||
{
|
{
|
||||||
/* use UART as terminal */
|
/* use USART as terminal */
|
||||||
uart_init();
|
usart_init();
|
||||||
stdout = &uart_output;
|
stdout = &usart_output;
|
||||||
stdin = &uart_input;
|
stdin = &usart_input;
|
||||||
|
|
||||||
/* gpio */
|
/* gpio */
|
||||||
/* LED */
|
/* LED */
|
||||||
|
@ -203,7 +193,7 @@ void command_action()
|
||||||
{
|
{
|
||||||
/* split command */
|
/* split command */
|
||||||
const char* delimiter = " ";
|
const char* delimiter = " ";
|
||||||
char* word = strtok(uart_in,delimiter);
|
char* word = strtok(usart_in,delimiter);
|
||||||
if (!word) {
|
if (!word) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
@ -280,27 +270,27 @@ error:
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
uint8_t uart_out_i = 0; // how many UART input characters have been processed
|
uint8_t usart_out_i = 0; // how many UART input characters have been processed
|
||||||
|
|
||||||
io_init(); // initialize IOs
|
io_init(); // initialize IOs
|
||||||
|
|
||||||
printf(PSTR("welcome to the demo code\n"));
|
printf(PSTR("welcome to the demo code\n"));
|
||||||
while (true) { // endless loop for micro-controller
|
while (true) { // endless loop for micro-controller
|
||||||
while (uart_flag) { // new UART input
|
while (usart_flag) { // new UART input
|
||||||
uart_flag = false;
|
usart_flag = false;
|
||||||
while (uart_out_i<uart_in_i) {
|
while (usart_out_i<usart_in_i) {
|
||||||
putchar(uart_in[uart_out_i++]); // print current character
|
putchar(usart_in[usart_out_i++]); // print current character
|
||||||
}
|
}
|
||||||
if ('\n'==uart_in[uart_in_i-1] || '\r'==uart_in[uart_in_i-1]) { // end of line detected
|
if ('\n'==usart_in[usart_in_i-1] || '\r'==usart_in[usart_in_i-1]) { // end of line detected
|
||||||
if ('\r'==uart_in[uart_in_i-1]) { // be sure to print a newline (for windows and mac EOL)
|
if ('\r'==usart_in[usart_in_i-1]) { // be sure to print a newline (for windows and mac EOL)
|
||||||
putchar('\n');
|
putchar('\n');
|
||||||
}
|
}
|
||||||
uart_in[uart_in_i-1] = 0; // remove end of line
|
usart_in[usart_in_i-1] = 0; // remove end of line
|
||||||
if (uart_in_i>1) { // ignore empty lines
|
if (usart_in_i>1) { // ignore empty lines
|
||||||
command_action(); // process command
|
command_action(); // process command
|
||||||
}
|
}
|
||||||
uart_out_i = 0; // reset output
|
usart_out_i = 0; // reset output
|
||||||
uart_in_i = 0; // reset input
|
usart_in_i = 0; // reset input
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* go to sleep and wait for next interrupt */
|
/* go to sleep and wait for next interrupt */
|
||||||
|
|
Loading…
Reference in New Issue