diff --git a/lib/uart.c b/lib/uart.c index f16b0b5..b26b499 100644 --- a/lib/uart.c +++ b/lib/uart.c @@ -3,9 +3,11 @@ #include #include #include +#include #include "uart.h" + void _uart_init_do(uint16_t ubrr) { /*Set baud rate */ UBRR0H = (uint8_t) (ubrr >> 8); @@ -29,6 +31,7 @@ void uart_isr_rx(bool yes) } } + /** Enable or disable TX ISR (1 byte is sent) */ void uart_isr_tx(bool yes) { @@ -39,6 +42,7 @@ void uart_isr_tx(bool yes) } } + /** Enable or disable DRE ISR (all is sent) */ void uart_isr_dre(bool yes) { @@ -50,8 +54,6 @@ void uart_isr_dre(bool yes) } - - /** Send byte over UART */ void uart_tx(uint8_t data) { @@ -61,6 +63,17 @@ void uart_tx(uint8_t data) UDR0 = data; } + +/** Receive one byte over UART */ +uint8_t uart_rx() +{ + // Wait for data to be received + while (!uart_rx_ready()); + // Get and return received data from buffer + return UDR0; +} + + /** Send string over UART */ void uart_puts(const char* str) { @@ -69,6 +82,7 @@ void uart_puts(const char* str) } } + /** Send progmem string over UART */ void uart_puts_pgm(const char* str) { @@ -78,14 +92,6 @@ void uart_puts_pgm(const char* str) } } -/** Receive one byte over UART */ -uint8_t uart_rx() -{ - // Wait for data to be received - while (!uart_rx_ready()); - // Get and return received data from buffer - return UDR0; -} /** Clear receive buffer */ void uart_flush() @@ -95,3 +101,127 @@ void uart_flush() dummy = UDR0; } + + + + +/** Send CRLF */ +void uart_nl() +{ + uart_tx(13); + uart_tx(10); +} + + +char tmpstr[12]; // buffer for number rendering + +void _uart_putn(const uint8_t places); + + +/** Send unsigned int */ +void uart_puti(const int16_t num) +{ + ltoa(num, tmpstr, 10); + uart_puts(tmpstr); +} + + +/** Send signed int */ +void uart_putu(const uint16_t num) +{ + ltoa(num, tmpstr, 10); + uart_puts(tmpstr); +} + + +/** Send unsigned long */ +void uart_putlu(const uint32_t num) +{ + ltoa(num, tmpstr, 10); + uart_puts(tmpstr); +} + + +/** Send signed long */ +void uart_putl(const int32_t num) +{ + ltoa(num, tmpstr, 10); + uart_puts(tmpstr); +} + + +/** Send signed long as float */ +void uart_putlf(const int32_t num, const uint8_t places) +{ + if (num < 0) { + uart_tx('-'); + ltoa(-num, tmpstr, 10); + } else { + ltoa(num, tmpstr, 10); + } + + _uart_putn(places); +} + + +/** Send unsigned long as float */ +void uart_putluf(const uint32_t num, const uint8_t places) +{ + ltoa(num, tmpstr, 10); + _uart_putn(places); +} + + +/** Send signed int as float */ +void uart_putif(const int16_t num, const uint8_t places) +{ + if (num < 0) { + uart_tx('-'); + itoa(-num, tmpstr, 10); + } else { + itoa(num, tmpstr, 10); + } + + _uart_putn(places); +} + + +/** Send unsigned int as float */ +void uart_putuf(const uint16_t num, const uint8_t places) +{ + ltoa(num, tmpstr, 10); + _uart_putn(places); +} + + +/** Print number in tmp string as float with given decimal point position */ +void _uart_putn(const uint8_t places) +{ + // measure text length + uint8_t len = 0; + while(tmpstr[len] != 0) len++; + + int8_t at = len - places; + + // print virtual zeros + if (at <= 0) { + uart_tx('0'); + uart_tx('.'); + while(at <= -1) { + uart_tx('0'); + at++; + } + at = -1; + } + + // print the number + uint8_t i = 0; + while(i < len) { + if (at-- == 0) { + uart_tx('.'); + } + + uart_tx(tmpstr[i++]); + } +} + diff --git a/lib/uart.h b/lib/uart.h index fad3a9f..a4182e5 100644 --- a/lib/uart.h +++ b/lib/uart.h @@ -1,5 +1,12 @@ #pragma once +/* + Utilities for UART communication. + + First, init uart with desired baud rate using uart_init(). + Then, enable interrupts you want, and that's it. +*/ + #include #include #include @@ -7,16 +14,19 @@ #include /** Init UART for given baudrate */ +void _uart_init_do(uint16_t ubrr); // internal, needed for the macro. #define uart_init(baud) _uart_init_do(F_CPU / 16 / (baud) - 1) -void _uart_init_do(uint16_t ubrr); - /** Check if there's a byte in the RX register */ #define uart_rx_ready() (0 != (UCSR0A & (1 << RXC0))) /** Check if transmission of everything is done */ #define uart_tx_ready() (0 != (UCSR0A & (1 << UDRE0))) + + +// Enable UART interrupts + /** Enable or disable RX ISR */ void uart_isr_rx(bool enable); @@ -26,18 +36,59 @@ void uart_isr_tx(bool enable); /** Enable or disable DRE ISR (all is sent) */ void uart_isr_dre(bool enable); + + +// Basic IO + +/** Receive one byte over UART */ +uint8_t uart_rx(); + /** Send byte over UART */ -#define uart_putc(data) uart_tx(data) +#define uart_putc(data) uart_tx((data)) void uart_tx(uint8_t data); +/** Clear receive buffer */ +void uart_flush(); + + + +// Strings + /** Send string over UART */ void uart_puts(const char* str); /** Send progmem string over UART */ void uart_puts_pgm(const char* str); -/** Receive one byte over UART */ -uint8_t uart_rx(); -/** Clear receive buffer */ -void uart_flush(); +// Numbers + +/** Send unsigned int */ +void uart_puti(const int16_t num); + +/** Send signed int */ +void uart_putu(const uint16_t num); + +/** Send unsigned long */ +void uart_putlu(const uint32_t num); + +/** Send signed long */ +void uart_putl(const int32_t num); + +/** Send signed long as float */ +void uart_putlf(const int32_t num, const uint8_t places); + +/** Send unsigned long as float */ +void uart_putluf(const uint32_t num, const uint8_t places); + +/** Send signed int as float */ +void uart_putif(const int16_t num, const uint8_t places); + +/** Send unsigned int as float */ +void uart_putuf(const uint16_t num, const uint8_t places); + + +// Extras + +/** Send CRLF */ +void uart_nl();