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/sleep.h> // Power Management and Sleep Modes
|
||||
|
||||
#include "uart.h" // basic UART functions
|
||||
#include "usart.h" // basic USART functions
|
||||
#include "main.h" // main definitions
|
||||
|
||||
/* help strings */
|
||||
|
@ -46,11 +46,11 @@ PGM_P const help_table[] PROGMEM = {
|
|||
};
|
||||
|
||||
/* global variables */
|
||||
char uart_in[32] = {0}; // user input from USART
|
||||
volatile uint8_t uart_in_i = 0; // how many UART characters have been input
|
||||
char usart_in[32] = {0}; // user input from USART
|
||||
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 */
|
||||
volatile bool uart_flag = false; // UART input data is available
|
||||
volatile bool usart_flag = false; // USART input data is available
|
||||
|
||||
/* switch off LED */
|
||||
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 */
|
||||
void wdt_init(void) __attribute__((naked)) __attribute__((section(".init3")));
|
||||
void wdt_init(void)
|
||||
|
@ -185,10 +175,10 @@ void wdt_init(void)
|
|||
/* initialize GPIO */
|
||||
void io_init(void)
|
||||
{
|
||||
/* use UART as terminal */
|
||||
uart_init();
|
||||
stdout = &uart_output;
|
||||
stdin = &uart_input;
|
||||
/* use USART as terminal */
|
||||
usart_init();
|
||||
stdout = &usart_output;
|
||||
stdin = &usart_input;
|
||||
|
||||
/* gpio */
|
||||
/* LED */
|
||||
|
@ -203,7 +193,7 @@ void command_action()
|
|||
{
|
||||
/* split command */
|
||||
const char* delimiter = " ";
|
||||
char* word = strtok(uart_in,delimiter);
|
||||
char* word = strtok(usart_in,delimiter);
|
||||
if (!word) {
|
||||
goto error;
|
||||
}
|
||||
|
@ -280,27 +270,27 @@ error:
|
|||
|
||||
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
|
||||
|
||||
printf(PSTR("welcome to the demo code\n"));
|
||||
while (true) { // endless loop for micro-controller
|
||||
while (uart_flag) { // new UART input
|
||||
uart_flag = false;
|
||||
while (uart_out_i<uart_in_i) {
|
||||
putchar(uart_in[uart_out_i++]); // print current character
|
||||
while (usart_flag) { // new UART input
|
||||
usart_flag = false;
|
||||
while (usart_out_i<usart_in_i) {
|
||||
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 ('\r'==uart_in[uart_in_i-1]) { // be sure to print a newline (for windows and mac EOL)
|
||||
if ('\n'==usart_in[usart_in_i-1] || '\r'==usart_in[usart_in_i-1]) { // end of line detected
|
||||
if ('\r'==usart_in[usart_in_i-1]) { // be sure to print a newline (for windows and mac EOL)
|
||||
putchar('\n');
|
||||
}
|
||||
uart_in[uart_in_i-1] = 0; // remove end of line
|
||||
if (uart_in_i>1) { // ignore empty lines
|
||||
usart_in[usart_in_i-1] = 0; // remove end of line
|
||||
if (usart_in_i>1) { // ignore empty lines
|
||||
command_action(); // process command
|
||||
}
|
||||
uart_out_i = 0; // reset output
|
||||
uart_in_i = 0; // reset input
|
||||
usart_out_i = 0; // reset output
|
||||
usart_in_i = 0; // reset input
|
||||
}
|
||||
}
|
||||
/* go to sleep and wait for next interrupt */
|
||||
|
|
Loading…
Reference in New Issue