added stream system & improved LCD string handling (crlf)
This commit is contained in:
@@ -13,6 +13,12 @@
|
||||
// Start address of rows
|
||||
const uint8_t LCD_ROW_ADDR[] = {0x00, 0x40, 0x14, 0x54};
|
||||
|
||||
|
||||
// Shared stream instance
|
||||
static STREAM _lcd_singleton;
|
||||
STREAM* lcd;
|
||||
|
||||
|
||||
// Internal prototypes
|
||||
void _lcd_mode_r();
|
||||
void _lcd_mode_w();
|
||||
@@ -36,6 +42,16 @@ uint8_t _lcd_read_byte();
|
||||
// 0 W, 1 R
|
||||
bool _lcd_mode;
|
||||
|
||||
struct {
|
||||
uint8_t x;
|
||||
uint8_t y;
|
||||
} _pos;
|
||||
|
||||
enum {
|
||||
TEXT = 0,
|
||||
CG = 1
|
||||
} _addrtype;
|
||||
|
||||
|
||||
/** Initialize the display */
|
||||
void lcd_init()
|
||||
@@ -68,6 +84,16 @@ void lcd_init()
|
||||
|
||||
// mark as enabled
|
||||
lcd_enable();
|
||||
|
||||
_lcd_singleton.tx = &lcd_write;
|
||||
_lcd_singleton.rx = &lcd_read;
|
||||
|
||||
// Stream
|
||||
lcd = &_lcd_singleton;
|
||||
|
||||
_pos.x = 0;
|
||||
_pos.y = 0;
|
||||
_addrtype = TEXT;
|
||||
}
|
||||
|
||||
|
||||
@@ -75,7 +101,7 @@ void lcd_init()
|
||||
void _lcd_clk()
|
||||
{
|
||||
pin_up(LCD_E);
|
||||
delay_ns(420);
|
||||
delay_ns(450);
|
||||
pin_down(LCD_E);
|
||||
}
|
||||
|
||||
@@ -141,6 +167,24 @@ void lcd_command(uint8_t bb)
|
||||
/** Write a data byte */
|
||||
void lcd_write(uint8_t bb)
|
||||
{
|
||||
if (_addrtype == TEXT) {
|
||||
if (bb == '\r') {
|
||||
// CR
|
||||
_pos.x = 0;
|
||||
lcd_xy(_pos.x, _pos.y);
|
||||
return;
|
||||
}
|
||||
|
||||
if (bb == '\n') {
|
||||
// LF
|
||||
_pos.y++;
|
||||
lcd_xy(_pos.x, _pos.y);
|
||||
return;
|
||||
}
|
||||
|
||||
_pos.x++;
|
||||
}
|
||||
|
||||
_lcd_wait_bf();
|
||||
pin_up(LCD_RS); // select data register
|
||||
_lcd_write_byte(bb); // send data byte
|
||||
@@ -158,12 +202,14 @@ uint8_t lcd_read_bf_addr()
|
||||
/** Read CGRAM or DDRAM */
|
||||
uint8_t lcd_read()
|
||||
{
|
||||
if (_addrtype == TEXT) _pos.x++;
|
||||
|
||||
pin_up(LCD_RS);
|
||||
return _lcd_read_byte();
|
||||
}
|
||||
|
||||
|
||||
/** Write a byte using the 8-bit interface */
|
||||
/** Write a byte using the 4-bit interface */
|
||||
void _lcd_write_byte(uint8_t bb)
|
||||
{
|
||||
_lcd_mode_w(); // enter W mode
|
||||
@@ -189,13 +235,14 @@ void _lcd_wait_bf()
|
||||
/** Send a string to LCD */
|
||||
void lcd_puts(char* str_p)
|
||||
{
|
||||
while (*str_p)
|
||||
lcd_putc(*str_p++);
|
||||
char c;
|
||||
while ((c = *str_p++))
|
||||
lcd_putc(c);
|
||||
}
|
||||
|
||||
|
||||
/** Print from progmem */
|
||||
void lcd_puts_pgm(const char* str_p)
|
||||
void lcd_puts_P(const char* str_p)
|
||||
{
|
||||
char c;
|
||||
while ((c = pgm_read_byte(str_p++)))
|
||||
@@ -213,6 +260,8 @@ void lcd_putc(const char c)
|
||||
/** Set cursor position */
|
||||
void lcd_xy(const uint8_t x, const uint8_t y)
|
||||
{
|
||||
_pos.x = x;
|
||||
_pos.y = y;
|
||||
lcd_addr(LCD_ROW_ADDR[y] + (x));
|
||||
}
|
||||
|
||||
@@ -249,6 +298,9 @@ void lcd_enable()
|
||||
void lcd_home()
|
||||
{
|
||||
lcd_command(LCD_HOME);
|
||||
_pos.x = 0;
|
||||
_pos.y = 0;
|
||||
_addrtype = TEXT;
|
||||
}
|
||||
|
||||
|
||||
@@ -266,22 +318,31 @@ void lcd_glyph(const uint8_t index, const uint8_t* array)
|
||||
for (uint8_t i = 0; i < 8; ++i) {
|
||||
lcd_write(array[i]);
|
||||
}
|
||||
|
||||
// restore previous position
|
||||
lcd_xy(_pos.x, _pos.y);
|
||||
_addrtype = TEXT;
|
||||
}
|
||||
|
||||
|
||||
/** Define a glyph */
|
||||
void lcd_glyph_pgm(const uint8_t index, const uint8_t* array)
|
||||
void lcd_glyph_P(const uint8_t index, const uint8_t* array)
|
||||
{
|
||||
lcd_addr_cg(index * 8);
|
||||
for (uint8_t i = 0; i < 8; ++i) {
|
||||
lcd_write(pgm_read_byte(&array[i]));
|
||||
}
|
||||
|
||||
// restore previous position
|
||||
lcd_xy(_pos.x, _pos.y);
|
||||
_addrtype = TEXT;
|
||||
}
|
||||
|
||||
|
||||
/** Set address in CGRAM */
|
||||
void lcd_addr_cg(const uint8_t acg)
|
||||
{
|
||||
_addrtype = CG;
|
||||
lcd_command(0b01000000 | ((acg) & 0b00111111));
|
||||
}
|
||||
|
||||
@@ -289,5 +350,6 @@ void lcd_addr_cg(const uint8_t acg)
|
||||
/** Set address in DDRAM */
|
||||
void lcd_addr(const uint8_t add)
|
||||
{
|
||||
_addrtype = TEXT;
|
||||
lcd_command(0b10000000 | ((add) & 0b01111111));
|
||||
}
|
||||
|
||||
@@ -21,9 +21,18 @@
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "stream.h"
|
||||
|
||||
// File with configs
|
||||
#include "lcd_config.h"
|
||||
|
||||
|
||||
|
||||
// Shared LCD stream object
|
||||
// Can be used with functions from stream.h once LCD is initialized
|
||||
extern STREAM* lcd;
|
||||
|
||||
|
||||
// --- Commands ---
|
||||
|
||||
// Clear screen (reset)
|
||||
@@ -88,7 +97,7 @@ uint8_t lcd_read();
|
||||
void lcd_puts(char* str_p);
|
||||
|
||||
/** Send a string to LCD from program memory */
|
||||
void lcd_puts_pgm(const char* str_p);
|
||||
void lcd_puts_P(const char* str_p);
|
||||
|
||||
/** Sedn a char to LCD */
|
||||
void lcd_putc(const char c);
|
||||
@@ -97,7 +106,7 @@ void lcd_putc(const char c);
|
||||
#define lcd_puts_xy(x, y, str_p) do { lcd_xy((x), (y)); lcd_puts((str_p)); } while(0)
|
||||
|
||||
/** Show string at X, Y */
|
||||
#define lcd_puts_xy_pgm(x, y, str_p) do { lcd_xy((x), (y)); lcd_puts_pgm((str_p)); } while(0)
|
||||
#define lcd_puts_xy_P(x, y, str_p) do { lcd_xy((x), (y)); lcd_puts_P((str_p)); } while(0)
|
||||
|
||||
/** Show char at X, Y */
|
||||
#define lcd_putc_xy(x, y, c) do { lcd_xy((x), (y)); lcd_putc((c)); } while(0)
|
||||
@@ -128,7 +137,7 @@ void lcd_clear();
|
||||
void lcd_glyph(const uint8_t index, const uint8_t* array);
|
||||
|
||||
/** Define a glyph that's in PROGMEM */
|
||||
void lcd_glyph_pgm(const uint8_t index, const uint8_t* array);
|
||||
void lcd_glyph_P(const uint8_t index, const uint8_t* array);
|
||||
|
||||
/** Set address in CGRAM */
|
||||
void lcd_addr_cg(const uint8_t acg);
|
||||
|
||||
+13
-25
@@ -7,13 +7,13 @@
|
||||
#include "sonar.h"
|
||||
|
||||
// Currently measured sonar
|
||||
volatile sonar_t *_sonar_active_so;
|
||||
sonar_t* _sonar_active_so;
|
||||
|
||||
// Flag that measurement is in progress
|
||||
volatile bool _busy;
|
||||
volatile bool sonar_busy;
|
||||
|
||||
// Result of last measurement, in millimeters
|
||||
volatile int16_t _result = 0xFFFF;
|
||||
volatile int16_t sonar_result;
|
||||
|
||||
|
||||
void _sonar_init_do(sonar_t* so, PORT_P port, uint8_t ntx, PORT_P pin, uint8_t nrx)
|
||||
@@ -45,11 +45,11 @@ void _sonar_init_do(sonar_t* so, PORT_P port, uint8_t ntx, PORT_P pin, uint8_t n
|
||||
*/
|
||||
bool sonar_start(sonar_t* so)
|
||||
{
|
||||
if (_busy) return false;
|
||||
if (sonar_busy) return false;
|
||||
|
||||
_sonar_active_so = so;
|
||||
|
||||
_busy = true;
|
||||
sonar_busy = true;
|
||||
|
||||
// make sure the timer is stopped (set clock to NONE)
|
||||
TCCR1B = 0;
|
||||
@@ -114,16 +114,16 @@ void _sonar_stop()
|
||||
// Disable timer1 overflow interrupt
|
||||
TIMSK1 &= ~(1 << TOIE1);
|
||||
|
||||
_busy = false;
|
||||
sonar_busy = false;
|
||||
}
|
||||
|
||||
|
||||
/** Handle TIMER1_OVF (returns true if consumed) */
|
||||
bool sonar_handle_t1ovf()
|
||||
inline bool sonar_handle_t1ovf()
|
||||
{
|
||||
if (!_busy) return false; // nothing
|
||||
if (!sonar_busy) return false; // nothing
|
||||
|
||||
_result = -1;
|
||||
sonar_result = -1;
|
||||
_sonar_stop();
|
||||
|
||||
return true;
|
||||
@@ -131,9 +131,9 @@ bool sonar_handle_t1ovf()
|
||||
|
||||
|
||||
/** Handle pin change interrupt (returns true if consumed) */
|
||||
bool sonar_handle_pci()
|
||||
inline bool sonar_handle_pci()
|
||||
{
|
||||
if (!_busy) {
|
||||
if (!sonar_busy) {
|
||||
return false; // nothing
|
||||
}
|
||||
|
||||
@@ -146,24 +146,12 @@ bool sonar_handle_pci()
|
||||
x /= _SNR_DIV_CONST;
|
||||
x *= 100000000L;
|
||||
x /= F_CPU;
|
||||
_result = (int16_t) x;
|
||||
sonar_result = (int16_t) x;
|
||||
|
||||
// no obstacle
|
||||
if (_result > _SNR_MAX_DIST) _result = -1;
|
||||
if (sonar_result > _SNR_MAX_DIST) sonar_result = -1;
|
||||
|
||||
_sonar_stop();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool sonar_busy()
|
||||
{
|
||||
return _busy;
|
||||
}
|
||||
|
||||
|
||||
int16_t sonar_result()
|
||||
{
|
||||
return _result;
|
||||
}
|
||||
|
||||
+4
-8
@@ -34,6 +34,10 @@ typedef struct {
|
||||
} sonar_t;
|
||||
|
||||
|
||||
extern volatile bool sonar_busy;
|
||||
extern volatile int16_t sonar_result;
|
||||
|
||||
|
||||
// Create a Sonar port
|
||||
// Args: sonar_t* so, Trig pin, Echo pin
|
||||
#define sonar_init(so, trig, echo) do { \
|
||||
@@ -46,14 +50,6 @@ typedef struct {
|
||||
void _sonar_init_do(sonar_t* so, PORT_P port, uint8_t ntx, PORT_P pin, uint8_t nrx);
|
||||
|
||||
|
||||
/** Check if sonar is busy */
|
||||
bool sonar_busy();
|
||||
|
||||
|
||||
/** Get result of last measurement, in millimeters. Returns -1 if no obstacle detected */
|
||||
int16_t sonar_result();
|
||||
|
||||
|
||||
/**
|
||||
* Start sonar measurement
|
||||
* Interrupts must be enabled
|
||||
|
||||
+162
@@ -0,0 +1,162 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "stream.h"
|
||||
|
||||
|
||||
static char tmpstr[20]; // buffer for number rendering
|
||||
|
||||
|
||||
void put_str(const STREAM *p, char* str)
|
||||
{
|
||||
char c;
|
||||
while ((c = *str++))
|
||||
p->tx(c);
|
||||
}
|
||||
|
||||
|
||||
void put_str_P(const STREAM *p, const char* str)
|
||||
{
|
||||
char c;
|
||||
while ((c = pgm_read_byte(str++)))
|
||||
p->tx(c);
|
||||
}
|
||||
|
||||
|
||||
static void _putnf(const STREAM *p, const uint8_t places);
|
||||
|
||||
|
||||
/** Send signed int8 */
|
||||
void put_u8(const STREAM *p, const uint8_t num)
|
||||
{
|
||||
utoa(num, tmpstr, 10);
|
||||
put_str(p, tmpstr);
|
||||
}
|
||||
|
||||
|
||||
/** Send unsigned int8 */
|
||||
void put_i8(const STREAM *p, const int8_t num)
|
||||
{
|
||||
itoa(num, tmpstr, 10);
|
||||
put_str(p, tmpstr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** Send unsigned int */
|
||||
void put_u16(const STREAM *p, const uint16_t num)
|
||||
{
|
||||
utoa(num, tmpstr, 10);
|
||||
put_str(p, tmpstr);
|
||||
}
|
||||
|
||||
|
||||
/** Send signed int */
|
||||
void put_i16(const STREAM *p, const int16_t num)
|
||||
{
|
||||
itoa(num, tmpstr, 10);
|
||||
put_str(p, tmpstr);
|
||||
}
|
||||
|
||||
|
||||
/** Send unsigned long */
|
||||
void put_u32(const STREAM *p, const uint32_t num)
|
||||
{
|
||||
ultoa(num, tmpstr, 10);
|
||||
put_str(p, tmpstr);
|
||||
}
|
||||
|
||||
|
||||
/** Send signed long */
|
||||
void put_i32(const STREAM *p, const int32_t num)
|
||||
{
|
||||
ltoa(num, tmpstr, 10);
|
||||
put_str(p, tmpstr);
|
||||
}
|
||||
|
||||
|
||||
// float variant doesn't make sense for 8-bit int
|
||||
|
||||
/** Send unsigned int as float */
|
||||
void put_u16f(const STREAM *p, const uint16_t num, const uint8_t places)
|
||||
{
|
||||
utoa(num, tmpstr, 10);
|
||||
_putnf(p, places);
|
||||
}
|
||||
|
||||
|
||||
/** Send signed int as float */
|
||||
void put_i16f(const STREAM *p, const int16_t num, const uint8_t places)
|
||||
{
|
||||
if (num < 0) {
|
||||
p->tx('-');
|
||||
itoa(-num, tmpstr, 10);
|
||||
} else {
|
||||
itoa(num, tmpstr, 10);
|
||||
}
|
||||
|
||||
_putnf(p, places);
|
||||
}
|
||||
|
||||
|
||||
/** Send unsigned long as float */
|
||||
void put_u32f(const STREAM *p, const uint32_t num, const uint8_t places)
|
||||
{
|
||||
ultoa(num, tmpstr, 10);
|
||||
_putnf(p, places);
|
||||
}
|
||||
|
||||
|
||||
/** Send signed long as float */
|
||||
void put_i32f(const STREAM *p, const int32_t num, const uint8_t places)
|
||||
{
|
||||
if (num < 0) {
|
||||
p->tx('-');
|
||||
ltoa(-num, tmpstr, 10);
|
||||
} else {
|
||||
ltoa(num, tmpstr, 10);
|
||||
}
|
||||
|
||||
_putnf(p, places);
|
||||
}
|
||||
|
||||
|
||||
/** Print number in tmp string as float with given decimal point position */
|
||||
void _putnf(const STREAM *p, 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) {
|
||||
p->tx('0');
|
||||
p->tx('.');
|
||||
while(at <= -1) {
|
||||
p->tx('0');
|
||||
at++;
|
||||
}
|
||||
at = -1;
|
||||
}
|
||||
|
||||
// print the number
|
||||
uint8_t i = 0;
|
||||
while(i < len) {
|
||||
if (at-- == 0) {
|
||||
p->tx('.');
|
||||
}
|
||||
|
||||
p->tx(tmpstr[i++]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Print CR LF */
|
||||
void put_nl(const STREAM *p)
|
||||
{
|
||||
p->tx(13);
|
||||
p->tx(10);
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
#pragma once
|
||||
|
||||
//
|
||||
// Stream utilities - printing abstraction
|
||||
// Works with eg. UART
|
||||
//
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <avr/pgmspace.h>
|
||||
|
||||
/** Stream structure */
|
||||
typedef struct {
|
||||
void (*tx) (uint8_t b);
|
||||
uint8_t (*rx) (void);
|
||||
} STREAM;
|
||||
|
||||
|
||||
/** Print string into a stream */
|
||||
void put_str(const STREAM *p, char* str);
|
||||
|
||||
|
||||
/** Print a programspace string into a stream */
|
||||
void put_str_P(const STREAM *p, const char* str);
|
||||
|
||||
|
||||
/** Send signed int8 */
|
||||
void put_u8(const STREAM *p, const uint8_t num);
|
||||
|
||||
|
||||
/** Send unsigned int8 */
|
||||
void put_i8(const STREAM *p, const int8_t num);
|
||||
|
||||
|
||||
/** Send unsigned int */
|
||||
void put_u16(const STREAM *p, const uint16_t num);
|
||||
|
||||
|
||||
/** Send signed int */
|
||||
void put_i16(const STREAM *p, const int16_t num);
|
||||
|
||||
|
||||
/** Send unsigned long */
|
||||
void put_u32(const STREAM *p, const uint32_t num);
|
||||
|
||||
|
||||
/** Send signed long */
|
||||
void put_i32(const STREAM *p, const int32_t num);
|
||||
|
||||
|
||||
// float variant doesn't make sense for 8-bit int
|
||||
|
||||
/** Send unsigned int as float */
|
||||
void put_u16f(const STREAM *p, const uint16_t num, const uint8_t places);
|
||||
|
||||
|
||||
/** Send signed int as float */
|
||||
void put_i16f(const STREAM *p, const int16_t num, const uint8_t places);
|
||||
|
||||
|
||||
/** Send unsigned long as float */
|
||||
void put_u32f(const STREAM *p, const uint32_t num, const uint8_t places);
|
||||
|
||||
|
||||
/** Send signed long as float */
|
||||
void put_i32f(const STREAM *p, const int32_t num, const uint8_t places);
|
||||
|
||||
|
||||
/** Print CR LF */
|
||||
void put_nl(const STREAM *p);
|
||||
+11
-127
@@ -6,6 +6,11 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "uart.h"
|
||||
#include "stream.h"
|
||||
|
||||
// Shared stream instance
|
||||
static STREAM _uart_singleton;
|
||||
STREAM* uart;
|
||||
|
||||
|
||||
void _uart_init_do(uint16_t ubrr) {
|
||||
@@ -18,6 +23,11 @@ void _uart_init_do(uint16_t ubrr) {
|
||||
|
||||
// 8-bit data, 1 stop bit
|
||||
UCSR0C = (0b11 << UCSZ00);
|
||||
|
||||
_uart_singleton.tx = &uart_tx;
|
||||
_uart_singleton.rx = &uart_rx;
|
||||
|
||||
uart = &_uart_singleton;
|
||||
}
|
||||
|
||||
|
||||
@@ -84,7 +94,7 @@ void uart_puts(const char* str)
|
||||
|
||||
|
||||
/** Send progmem string over UART */
|
||||
void uart_puts_pgm(const char* str)
|
||||
void uart_puts_P(const char* str)
|
||||
{
|
||||
char c;
|
||||
while ((c = pgm_read_byte(str++))) {
|
||||
@@ -100,129 +110,3 @@ void uart_flush()
|
||||
while (UCSR0A & (1 << RXC0))
|
||||
dummy = UDR0;
|
||||
}
|
||||
|
||||
|
||||
/** Send CRLF */
|
||||
void uart_nl()
|
||||
{
|
||||
uart_tx(13);
|
||||
uart_tx(10);
|
||||
}
|
||||
|
||||
|
||||
char tmpstr[12]; // buffer for number rendering
|
||||
|
||||
void _uart_putnf(const uint8_t places);
|
||||
|
||||
|
||||
/** Send signed int8 */
|
||||
void uart_putu(const uint8_t num)
|
||||
{
|
||||
utoa(num, tmpstr, 10);
|
||||
uart_puts(tmpstr);
|
||||
}
|
||||
|
||||
|
||||
/** Send unsigned int8 */
|
||||
void uart_putn(const int8_t num)
|
||||
{
|
||||
itoa(num, tmpstr, 10);
|
||||
uart_puts(tmpstr);
|
||||
}
|
||||
|
||||
|
||||
/** Send unsigned int as float */
|
||||
void uart_putiu(const uint16_t num, const uint8_t places)
|
||||
{
|
||||
if (!places) {
|
||||
utoa(num, tmpstr, 10);
|
||||
uart_puts(tmpstr);
|
||||
} else {
|
||||
utoa(num, tmpstr, 10);
|
||||
_uart_putnf(places);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Send signed int as float */
|
||||
void uart_puti(const int16_t num, const uint8_t places)
|
||||
{
|
||||
if (!places) {
|
||||
itoa(num, tmpstr, 10);
|
||||
uart_puts(tmpstr);
|
||||
} else {
|
||||
if (num < 0) {
|
||||
uart_tx('-');
|
||||
itoa(-num, tmpstr, 10);
|
||||
} else {
|
||||
itoa(num, tmpstr, 10);
|
||||
}
|
||||
|
||||
_uart_putnf(places);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Send unsigned long as float */
|
||||
void uart_putlu(const uint32_t num, const uint8_t places)
|
||||
{
|
||||
if (!places) {
|
||||
ultoa(num, tmpstr, 10);
|
||||
uart_puts(tmpstr);
|
||||
} else {
|
||||
ultoa(num, tmpstr, 10);
|
||||
_uart_putnf(places);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Send signed long as float */
|
||||
void uart_putl(const int32_t num, const uint8_t places)
|
||||
{
|
||||
if (!places) {
|
||||
ltoa(num, tmpstr, 10);
|
||||
uart_puts(tmpstr);
|
||||
} else {
|
||||
if (num < 0) {
|
||||
uart_tx('-');
|
||||
ltoa(-num, tmpstr, 10);
|
||||
} else {
|
||||
ltoa(num, tmpstr, 10);
|
||||
}
|
||||
|
||||
_uart_putnf(places);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Print number in tmp string as float with given decimal point position */
|
||||
void _uart_putnf(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++]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+6
-26
@@ -13,6 +13,11 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "stream.h"
|
||||
|
||||
// Shared UART stream object
|
||||
// Can be used with functions from stream.h once UART is initialized
|
||||
extern STREAM* uart;
|
||||
|
||||
/** Init UART for given baudrate */
|
||||
void _uart_init_do(uint16_t ubrr); // internal, needed for the macro.
|
||||
@@ -59,30 +64,5 @@ void uart_flush();
|
||||
void uart_puts(const char* str);
|
||||
|
||||
/** Send progmem string over UART */
|
||||
void uart_puts_pgm(const char* str);
|
||||
void uart_puts_P(const char* str);
|
||||
|
||||
|
||||
// Numbers
|
||||
|
||||
/** Send unsigned int */
|
||||
void uart_putu(const uint8_t num);
|
||||
|
||||
/** Send signed int */
|
||||
void uart_putn(const int8_t num);
|
||||
|
||||
/** Send unsigned int */
|
||||
void uart_puti(const int16_t num, const uint8_t places);
|
||||
|
||||
/** Send signed int */
|
||||
void uart_putiu(const uint16_t num, const uint8_t places);
|
||||
|
||||
/** Send signed long */
|
||||
void uart_putl(const int32_t num, const uint8_t places);
|
||||
|
||||
/** Send unsigned long */
|
||||
void uart_putlu(const uint32_t num, const uint8_t places);
|
||||
|
||||
// Extras
|
||||
|
||||
/** Send CRLF */
|
||||
void uart_nl();
|
||||
|
||||
+82
-81
@@ -6,6 +6,7 @@
|
||||
|
||||
#include "uart.h"
|
||||
#include "uart_ansi.h"
|
||||
#include "stream.h"
|
||||
|
||||
void _vt_apply_style();
|
||||
void _vt_reset_attribs_do();
|
||||
@@ -15,30 +16,30 @@ void _vt_color_do();
|
||||
|
||||
void vt_goto(uint8_t x, uint8_t y)
|
||||
{
|
||||
uart_putc(27);
|
||||
uart_putc('[');
|
||||
uart_putu(y+1); // one-based !
|
||||
uart_putc(';');
|
||||
uart_putu(x+1);
|
||||
uart_putc('H');
|
||||
uart_tx(27);
|
||||
uart_tx('[');
|
||||
put_u8(uart, y+1); // one-based !
|
||||
uart_tx(';');
|
||||
put_u8(uart, x+1);
|
||||
uart_tx('H');
|
||||
}
|
||||
|
||||
|
||||
void vt_goto_x(uint8_t x)
|
||||
{
|
||||
uart_putc(27);
|
||||
uart_putc('[');
|
||||
uart_putu(x+1);
|
||||
uart_putc('`');
|
||||
uart_tx(27);
|
||||
uart_tx('[');
|
||||
put_u8(uart, x+1);
|
||||
uart_tx('`');
|
||||
}
|
||||
|
||||
|
||||
void vt_goto_y(uint8_t y)
|
||||
{
|
||||
uart_putc(27);
|
||||
uart_putc('[');
|
||||
uart_putu(y+1);
|
||||
uart_putc('d');
|
||||
uart_tx(27);
|
||||
uart_tx('[');
|
||||
put_u8(uart, y+1);
|
||||
uart_tx('d');
|
||||
}
|
||||
|
||||
|
||||
@@ -72,54 +73,54 @@ void vt_move_y(int8_t y)
|
||||
void vt_up(uint8_t y)
|
||||
{
|
||||
if (y == 0) return;
|
||||
uart_putc(27);
|
||||
uart_putc('[');
|
||||
uart_putu(y);
|
||||
uart_putc('A');
|
||||
uart_tx(27);
|
||||
uart_tx('[');
|
||||
put_u8(uart, y);
|
||||
uart_tx('A');
|
||||
}
|
||||
|
||||
|
||||
void vt_down(uint8_t y)
|
||||
{
|
||||
if (y == 0) return;
|
||||
uart_putc(27);
|
||||
uart_putc('[');
|
||||
uart_putu(y);
|
||||
uart_putc('B');
|
||||
uart_tx(27);
|
||||
uart_tx('[');
|
||||
put_u8(uart, y);
|
||||
uart_tx('B');
|
||||
}
|
||||
|
||||
|
||||
void vt_left(uint8_t x)
|
||||
{
|
||||
if (x == 0) return;
|
||||
uart_putc(27);
|
||||
uart_putc('[');
|
||||
uart_putu(x);
|
||||
uart_putc('D');
|
||||
uart_tx(27);
|
||||
uart_tx('[');
|
||||
put_u8(uart, x);
|
||||
uart_tx('D');
|
||||
}
|
||||
|
||||
|
||||
void vt_right(uint8_t x)
|
||||
{
|
||||
if (x == 0) return;
|
||||
uart_putc(27);
|
||||
uart_putc('[');
|
||||
uart_putu(x);
|
||||
uart_putc('C');
|
||||
uart_tx(27);
|
||||
uart_tx('[');
|
||||
put_u8(uart, x);
|
||||
uart_tx('C');
|
||||
}
|
||||
|
||||
|
||||
void vt_scroll(int8_t y)
|
||||
{
|
||||
while (y < 0) {
|
||||
uart_putc(27);
|
||||
uart_putc('D'); // up
|
||||
uart_tx(27);
|
||||
uart_tx('D'); // up
|
||||
y++;
|
||||
}
|
||||
|
||||
while (y > 0) {
|
||||
uart_putc(27);
|
||||
uart_putc('M'); // down
|
||||
uart_tx(27);
|
||||
uart_tx('M'); // down
|
||||
y--;
|
||||
}
|
||||
}
|
||||
@@ -127,20 +128,20 @@ void vt_scroll(int8_t y)
|
||||
|
||||
void vt_scroll_set(uint8_t from, uint8_t to)
|
||||
{
|
||||
uart_putc(27);
|
||||
uart_putc('[');
|
||||
uart_putu(from);
|
||||
uart_putc(';');
|
||||
uart_putu(to);
|
||||
uart_putc('r');
|
||||
uart_tx(27);
|
||||
uart_tx('[');
|
||||
put_u8(uart, from);
|
||||
uart_tx(';');
|
||||
put_u8(uart, to);
|
||||
uart_tx('r');
|
||||
}
|
||||
|
||||
|
||||
void vt_scroll_reset()
|
||||
{
|
||||
uart_putc(27);
|
||||
uart_putc('[');
|
||||
uart_putc('r');
|
||||
uart_tx(27);
|
||||
uart_tx('[');
|
||||
uart_tx('r');
|
||||
}
|
||||
|
||||
|
||||
@@ -156,7 +157,7 @@ vt_style_t current_style;
|
||||
|
||||
void vt_save()
|
||||
{
|
||||
uart_puts_pgm(PSTR("\x1B[s"));
|
||||
uart_puts_P(PSTR("\x1B[s"));
|
||||
|
||||
saved_style = current_style;
|
||||
}
|
||||
@@ -164,7 +165,7 @@ void vt_save()
|
||||
|
||||
void vt_restore()
|
||||
{
|
||||
uart_puts_pgm(PSTR("\x1B[u"));
|
||||
uart_puts_P(PSTR("\x1B[u"));
|
||||
|
||||
current_style = saved_style;
|
||||
}
|
||||
@@ -246,7 +247,7 @@ void vt_color_bg(uint8_t bg)
|
||||
/** Send reset command */
|
||||
inline void _vt_reset_attribs_do()
|
||||
{
|
||||
uart_puts_pgm(PSTR("\x1B[m")); // reset
|
||||
uart_puts_P(PSTR("\x1B[m")); // reset
|
||||
}
|
||||
|
||||
|
||||
@@ -254,27 +255,27 @@ inline void _vt_reset_attribs_do()
|
||||
void _vt_style_do()
|
||||
{
|
||||
if (current_style.flags & VT_BOLD) {
|
||||
uart_puts_pgm(PSTR("\x1B[1m"));
|
||||
uart_puts_P(PSTR("\x1B[1m"));
|
||||
}
|
||||
|
||||
if (current_style.flags & VT_FAINT) {
|
||||
uart_puts_pgm(PSTR("\x1B[2m"));
|
||||
uart_puts_P(PSTR("\x1B[2m"));
|
||||
}
|
||||
|
||||
if (current_style.flags & VT_ITALIC) {
|
||||
uart_puts_pgm(PSTR("\x1B[3m"));
|
||||
uart_puts_P(PSTR("\x1B[3m"));
|
||||
}
|
||||
|
||||
if (current_style.flags & VT_UNDERLINE) {
|
||||
uart_puts_pgm(PSTR("\x1B[4m"));
|
||||
uart_puts_P(PSTR("\x1B[4m"));
|
||||
}
|
||||
|
||||
if (current_style.flags & VT_BLINK) {
|
||||
uart_puts_pgm(PSTR("\x1B[5m"));
|
||||
uart_puts_P(PSTR("\x1B[5m"));
|
||||
}
|
||||
|
||||
if (current_style.flags & VT_REVERSE) {
|
||||
uart_puts_pgm(PSTR("\x1B[7m"));
|
||||
uart_puts_P(PSTR("\x1B[7m"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -282,93 +283,93 @@ void _vt_style_do()
|
||||
/** Send commands for xolor */
|
||||
void _vt_color_do()
|
||||
{
|
||||
uart_putc(27);
|
||||
uart_putc('[');
|
||||
uart_putu(30 + current_style.fg);
|
||||
uart_putc(';');
|
||||
uart_putu(40 + current_style.bg);
|
||||
uart_putc('m');
|
||||
uart_tx(27);
|
||||
uart_tx('[');
|
||||
put_u8(uart, 30 + current_style.fg);
|
||||
uart_tx(';');
|
||||
put_u8(uart, 40 + current_style.bg);
|
||||
uart_tx('m');
|
||||
}
|
||||
|
||||
|
||||
/** Insert blank lines febore the current line */
|
||||
void vt_insert_lines(uint8_t count)
|
||||
{
|
||||
uart_putc(27);
|
||||
uart_putc('[');
|
||||
uart_putu(count);
|
||||
uart_putc('L');
|
||||
uart_tx(27);
|
||||
uart_tx('[');
|
||||
put_u8(uart, count);
|
||||
uart_tx('L');
|
||||
}
|
||||
|
||||
|
||||
/** Delete lines from the current line down */
|
||||
void vt_delete_lines(uint8_t count)
|
||||
{
|
||||
uart_putc(27);
|
||||
uart_putc('[');
|
||||
uart_putu(count);
|
||||
uart_putc('M');
|
||||
uart_tx(27);
|
||||
uart_tx('[');
|
||||
put_u8(uart, count);
|
||||
uart_tx('M');
|
||||
}
|
||||
|
||||
|
||||
/** Insert empty characters at cursor */
|
||||
void vt_insert_chars(uint8_t count)
|
||||
{
|
||||
uart_putc(27);
|
||||
uart_putc('[');
|
||||
uart_putu(count);
|
||||
uart_putc('@');
|
||||
uart_tx(27);
|
||||
uart_tx('[');
|
||||
put_u8(uart, count);
|
||||
uart_tx('@');
|
||||
}
|
||||
|
||||
|
||||
/** Delete characters at cursor */
|
||||
void vt_delete_chars(uint8_t count)
|
||||
{
|
||||
uart_putc(27);
|
||||
uart_putc('[');
|
||||
uart_putu(count);
|
||||
uart_putc('P');
|
||||
uart_tx(27);
|
||||
uart_tx('[');
|
||||
put_u8(uart, count);
|
||||
uart_tx('P');
|
||||
}
|
||||
|
||||
|
||||
void vt_clear()
|
||||
{
|
||||
uart_puts_pgm(PSTR("\x1B[2J"));
|
||||
uart_puts_P(PSTR("\x1B[2J"));
|
||||
}
|
||||
|
||||
|
||||
void vt_erase_forth()
|
||||
{
|
||||
uart_puts_pgm(PSTR("\x1B[K"));
|
||||
uart_puts_P(PSTR("\x1B[K"));
|
||||
}
|
||||
|
||||
|
||||
void vt_erase_back()
|
||||
{
|
||||
uart_puts_pgm(PSTR("\x1B[1K"));
|
||||
uart_puts_P(PSTR("\x1B[1K"));
|
||||
}
|
||||
|
||||
|
||||
void vt_erase_line()
|
||||
{
|
||||
uart_puts_pgm(PSTR("\x1B[2K"));
|
||||
uart_puts_P(PSTR("\x1B[2K"));
|
||||
}
|
||||
|
||||
|
||||
void vt_erase_above()
|
||||
{
|
||||
uart_puts_pgm(PSTR("\x1B[1J"));
|
||||
uart_puts_P(PSTR("\x1B[1J"));
|
||||
}
|
||||
|
||||
void vt_erase_below()
|
||||
{
|
||||
uart_puts_pgm(PSTR("\x1B[J"));
|
||||
uart_puts_P(PSTR("\x1B[J"));
|
||||
}
|
||||
|
||||
|
||||
void vt_home()
|
||||
{
|
||||
uart_puts_pgm(PSTR("\x1B[H"));
|
||||
uart_puts_P(PSTR("\x1B[H"));
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user