Improved UART, added Key Handler to uart_ansi
This commit is contained in:
+51
-63
@@ -112,82 +112,45 @@ void uart_nl()
|
||||
|
||||
char tmpstr[12]; // buffer for number rendering
|
||||
|
||||
void _uart_putn(const uint8_t places);
|
||||
|
||||
|
||||
/** Send unsigned int8 */
|
||||
void uart_put8i(const int8_t num)
|
||||
{
|
||||
itoa(num, tmpstr, 10);
|
||||
uart_puts(tmpstr);
|
||||
}
|
||||
void _uart_putnf(const uint8_t places);
|
||||
|
||||
|
||||
/** Send signed int8 */
|
||||
void uart_put8u(const uint8_t num)
|
||||
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 */
|
||||
void uart_put16i(const int16_t num)
|
||||
/** Send unsigned int as float */
|
||||
void uart_putiu(const uint16_t num, const uint8_t places)
|
||||
{
|
||||
itoa(num, tmpstr, 10);
|
||||
if (!places) {
|
||||
utoa(num, tmpstr, 10);
|
||||
uart_puts(tmpstr);
|
||||
}
|
||||
|
||||
|
||||
/** Send signed int */
|
||||
void uart_put16u(const uint16_t num)
|
||||
{
|
||||
itoa(num, tmpstr, 10);
|
||||
uart_puts(tmpstr);
|
||||
}
|
||||
|
||||
|
||||
/** Send unsigned long */
|
||||
void uart_put32u(const uint32_t num)
|
||||
{
|
||||
ltoa(num, tmpstr, 10);
|
||||
uart_puts(tmpstr);
|
||||
}
|
||||
|
||||
|
||||
/** Send signed long */
|
||||
void uart_put32i(const int32_t num)
|
||||
{
|
||||
ltoa(num, tmpstr, 10);
|
||||
uart_puts(tmpstr);
|
||||
}
|
||||
|
||||
|
||||
/** Send signed long as float */
|
||||
void uart_put32if(const int32_t num, const uint8_t places)
|
||||
{
|
||||
if (num < 0) {
|
||||
uart_tx('-');
|
||||
ltoa(-num, tmpstr, 10);
|
||||
} else {
|
||||
ltoa(num, tmpstr, 10);
|
||||
utoa(num, tmpstr, 10);
|
||||
_uart_putnf(places);
|
||||
}
|
||||
|
||||
_uart_putn(places);
|
||||
}
|
||||
|
||||
|
||||
/** Send unsigned long as float */
|
||||
void uart_put32uf(const uint32_t num, const uint8_t places)
|
||||
{
|
||||
ltoa(num, tmpstr, 10);
|
||||
_uart_putn(places);
|
||||
}
|
||||
|
||||
|
||||
/** Send signed int as float */
|
||||
void uart_put16if(const int16_t num, const uint8_t places)
|
||||
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);
|
||||
@@ -195,20 +158,45 @@ void uart_put16if(const int16_t num, const uint8_t places)
|
||||
itoa(num, tmpstr, 10);
|
||||
}
|
||||
|
||||
_uart_putn(places);
|
||||
_uart_putnf(places);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Send unsigned int as float */
|
||||
void uart_put16uf(const uint16_t num, const uint8_t 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_putn(places);
|
||||
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_putn(const uint8_t places)
|
||||
void _uart_putnf(const uint8_t places)
|
||||
{
|
||||
// measure text length
|
||||
uint8_t len = 0;
|
||||
|
||||
+6
-19
@@ -65,35 +65,22 @@ void uart_puts_pgm(const char* str);
|
||||
// Numbers
|
||||
|
||||
/** Send unsigned int */
|
||||
void uart_put8i(const int8_t num);
|
||||
void uart_putn(const int8_t num);
|
||||
|
||||
/** Send signed int */
|
||||
void uart_put8u(const uint8_t num);
|
||||
void uart_putu(const uint8_t num);
|
||||
|
||||
/** Send unsigned int */
|
||||
void uart_put16i(const int16_t num);
|
||||
void uart_puti(const int16_t num, const uint8_t places);
|
||||
|
||||
/** Send signed int */
|
||||
void uart_put16u(const uint16_t num);
|
||||
void uart_putiu(const uint16_t num, const uint8_t places);
|
||||
|
||||
/** Send unsigned long */
|
||||
void uart_put32u(const uint32_t num);
|
||||
void uart_putlu(const uint32_t num, const uint8_t places);
|
||||
|
||||
/** Send signed long */
|
||||
void uart_put32i(const int32_t num);
|
||||
|
||||
/** Send signed int as float */
|
||||
void uart_put16if(const int16_t num, const uint8_t places);
|
||||
|
||||
/** Send unsigned int as float */
|
||||
void uart_put16uf(const uint16_t num, const uint8_t places);
|
||||
|
||||
/** Send signed long as float */
|
||||
void uart_put32if(const int32_t num, const uint8_t places);
|
||||
|
||||
/** Send unsigned long as float */
|
||||
void uart_put32uf(const uint32_t num, const uint8_t places);
|
||||
|
||||
void uart_putl(const int32_t num, const uint8_t places);
|
||||
|
||||
// Extras
|
||||
|
||||
|
||||
+199
-16
@@ -1,5 +1,6 @@
|
||||
#include <avr/io.h>
|
||||
#include <avr/pgmspace.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -16,9 +17,9 @@ void vt_goto(uint8_t x, uint8_t y)
|
||||
{
|
||||
uart_putc(27);
|
||||
uart_putc('[');
|
||||
uart_put8u(x);
|
||||
uart_putu(x);
|
||||
uart_putc(';');
|
||||
uart_put8u(y);
|
||||
uart_putu(y);
|
||||
uart_putc('H');
|
||||
}
|
||||
|
||||
@@ -27,7 +28,7 @@ void vt_goto_x(uint8_t x)
|
||||
{
|
||||
uart_putc(27);
|
||||
uart_putc('[');
|
||||
uart_put8u(x);
|
||||
uart_putu(x);
|
||||
uart_putc('`');
|
||||
}
|
||||
|
||||
@@ -36,7 +37,7 @@ void vt_goto_y(uint8_t y)
|
||||
{
|
||||
uart_putc(27);
|
||||
uart_putc('[');
|
||||
uart_put8u(y);
|
||||
uart_putu(y);
|
||||
uart_putc('d');
|
||||
}
|
||||
|
||||
@@ -73,7 +74,7 @@ void vt_up(uint8_t y)
|
||||
if (y == 0) return;
|
||||
uart_putc(27);
|
||||
uart_putc('[');
|
||||
uart_put8u(y);
|
||||
uart_putu(y);
|
||||
uart_putc('A');
|
||||
}
|
||||
|
||||
@@ -83,7 +84,7 @@ void vt_down(uint8_t y)
|
||||
if (y == 0) return;
|
||||
uart_putc(27);
|
||||
uart_putc('[');
|
||||
uart_put8u(y);
|
||||
uart_putu(y);
|
||||
uart_putc('B');
|
||||
}
|
||||
|
||||
@@ -93,7 +94,7 @@ void vt_left(uint8_t x)
|
||||
if (x == 0) return;
|
||||
uart_putc(27);
|
||||
uart_putc('[');
|
||||
uart_put8u(x);
|
||||
uart_putu(x);
|
||||
uart_putc('D');
|
||||
}
|
||||
|
||||
@@ -103,7 +104,7 @@ void vt_right(uint8_t x)
|
||||
if (x == 0) return;
|
||||
uart_putc(27);
|
||||
uart_putc('[');
|
||||
uart_put8u(x);
|
||||
uart_putu(x);
|
||||
uart_putc('C');
|
||||
}
|
||||
|
||||
@@ -128,9 +129,9 @@ void vt_scroll_set(uint8_t from, uint8_t to)
|
||||
{
|
||||
uart_putc(27);
|
||||
uart_putc('[');
|
||||
uart_put8u(from);
|
||||
uart_putu(from);
|
||||
uart_putc(';');
|
||||
uart_put8u(to);
|
||||
uart_putu(to);
|
||||
uart_putc('r');
|
||||
}
|
||||
|
||||
@@ -283,9 +284,9 @@ void _vt_color_do()
|
||||
{
|
||||
uart_putc(27);
|
||||
uart_putc('[');
|
||||
uart_put8u(30 + current_style.fg);
|
||||
uart_putu(30 + current_style.fg);
|
||||
uart_putc(';');
|
||||
uart_put8u(40 + current_style.bg);
|
||||
uart_putu(40 + current_style.bg);
|
||||
uart_putc('m');
|
||||
}
|
||||
|
||||
@@ -295,7 +296,7 @@ void vt_insert_lines(uint8_t count)
|
||||
{
|
||||
uart_putc(27);
|
||||
uart_putc('[');
|
||||
uart_put8u(count);
|
||||
uart_putu(count);
|
||||
uart_putc('L');
|
||||
}
|
||||
|
||||
@@ -305,7 +306,7 @@ void vt_delete_lines(uint8_t count)
|
||||
{
|
||||
uart_putc(27);
|
||||
uart_putc('[');
|
||||
uart_put8u(count);
|
||||
uart_putu(count);
|
||||
uart_putc('M');
|
||||
}
|
||||
|
||||
@@ -315,7 +316,7 @@ void vt_insert_chars(uint8_t count)
|
||||
{
|
||||
uart_putc(27);
|
||||
uart_putc('[');
|
||||
uart_put8u(count);
|
||||
uart_putu(count);
|
||||
uart_putc('@');
|
||||
}
|
||||
|
||||
@@ -325,7 +326,7 @@ void vt_delete_chars(uint8_t count)
|
||||
{
|
||||
uart_putc(27);
|
||||
uart_putc('[');
|
||||
uart_put8u(count);
|
||||
uart_putu(count);
|
||||
uart_putc('P');
|
||||
}
|
||||
|
||||
@@ -395,3 +396,185 @@ void vt_reset()
|
||||
// overwrite saved state
|
||||
vt_save();
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Assigned keyhandler
|
||||
void (*_vt_kh)(uint8_t, bool) = NULL;
|
||||
|
||||
/** Assign a key handler (later used with vt_handle_key) */
|
||||
void vt_set_key_handler(void (*handler)(uint8_t, bool))
|
||||
{
|
||||
_vt_kh = handler;
|
||||
}
|
||||
|
||||
|
||||
// state machine states
|
||||
typedef enum {
|
||||
GROUND = 0,
|
||||
ESC = 1,
|
||||
BR = 2,
|
||||
O = 3,
|
||||
WAITING_TILDE = 4
|
||||
} KSTATE;
|
||||
|
||||
// code received before started to wait for a tilde
|
||||
uint8_t _before_wtilde;
|
||||
// current state
|
||||
KSTATE _kstate = GROUND;
|
||||
|
||||
|
||||
|
||||
void _vt_kh_abort()
|
||||
{
|
||||
switch (_kstate) {
|
||||
case ESC:
|
||||
_vt_kh(VK_ESC, true);
|
||||
break;
|
||||
|
||||
case BR:
|
||||
_vt_kh(VK_ESC, true);
|
||||
_vt_kh('[', false);
|
||||
break;
|
||||
|
||||
case O:
|
||||
_vt_kh(VK_ESC, true);
|
||||
_vt_kh('O', false);
|
||||
break;
|
||||
|
||||
case WAITING_TILDE:
|
||||
_vt_kh(VK_ESC, true);
|
||||
_vt_kh('[', false);
|
||||
vt_handle_key(_before_wtilde);
|
||||
break;
|
||||
|
||||
case GROUND:
|
||||
// nop
|
||||
break;
|
||||
}
|
||||
|
||||
_kstate = GROUND;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handle a key received over UART
|
||||
* Takes care of multi-byte keys and translates them to special
|
||||
* constants.
|
||||
*/
|
||||
void vt_handle_key(uint8_t c)
|
||||
{
|
||||
if (_vt_kh == NULL) return;
|
||||
|
||||
switch (_kstate) {
|
||||
case GROUND:
|
||||
switch (c) {
|
||||
case 27:
|
||||
_kstate = ESC;
|
||||
break;
|
||||
|
||||
case VK_ENTER:
|
||||
case VK_TAB:
|
||||
case VK_BACKSPACE:
|
||||
_vt_kh(c, true);
|
||||
return;
|
||||
|
||||
default:
|
||||
_vt_kh(c, false);
|
||||
return;
|
||||
}
|
||||
|
||||
break; // continue to next char
|
||||
|
||||
case ESC:
|
||||
switch (c) {
|
||||
case '[':
|
||||
_kstate = BR;
|
||||
break; // continue to next char
|
||||
|
||||
case 'O':
|
||||
_kstate = O;
|
||||
break; // continue to next char
|
||||
|
||||
default:
|
||||
// bad code
|
||||
_vt_kh_abort();
|
||||
vt_handle_key(c);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case BR:
|
||||
switch (c) {
|
||||
// arrows
|
||||
case 65:
|
||||
case 66:
|
||||
case 67:
|
||||
case 68:
|
||||
_vt_kh(c, true);
|
||||
_kstate = GROUND;
|
||||
return;
|
||||
|
||||
// ins del pgup pgdn
|
||||
case 50:
|
||||
case 51:
|
||||
case 53:
|
||||
case 54:
|
||||
// wait for terminating tilde
|
||||
_before_wtilde = c;
|
||||
_kstate = WAITING_TILDE;
|
||||
break; // continue to next char
|
||||
|
||||
// bad key
|
||||
default:
|
||||
_vt_kh_abort();
|
||||
vt_handle_key(c);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case O:
|
||||
switch (c) {
|
||||
// F keys
|
||||
case 80:
|
||||
case 81:
|
||||
case 82:
|
||||
case 83:
|
||||
// home, end
|
||||
case 72:
|
||||
case 70:
|
||||
_vt_kh(c, true);
|
||||
_kstate = GROUND;
|
||||
return;
|
||||
|
||||
// bad key
|
||||
default:
|
||||
_vt_kh_abort();
|
||||
vt_handle_key(c);
|
||||
return;
|
||||
}
|
||||
|
||||
case WAITING_TILDE:
|
||||
if (c != '~') {
|
||||
_vt_kh_abort();
|
||||
vt_handle_key(c);
|
||||
return;
|
||||
} else {
|
||||
_vt_kh(_before_wtilde, true);
|
||||
_kstate = GROUND;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// wait for next key
|
||||
if (_kstate != GROUND) {
|
||||
_delay_ms(2);
|
||||
if (!uart_rx_ready()) {
|
||||
// abort receiving
|
||||
_vt_kh_abort();
|
||||
|
||||
} else {
|
||||
vt_handle_key(uart_rx());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
//
|
||||
|
||||
#include <avr/io.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "uart.h"
|
||||
@@ -162,3 +163,30 @@ void vt_erase_above();
|
||||
|
||||
/** Erase screen above the line */
|
||||
void vt_erase_below();
|
||||
|
||||
|
||||
|
||||
// KEY HANDLER
|
||||
|
||||
// Special keys from key handler
|
||||
#define VK_LEFT 68
|
||||
#define VK_RIGHT 67
|
||||
#define VK_UP 65
|
||||
#define VK_DOWN 66
|
||||
#define VK_DELETE 51
|
||||
#define VK_INSERT 50
|
||||
#define VK_PGUP 53
|
||||
#define VK_PGDN 54
|
||||
#define VK_HOME 72
|
||||
#define VK_END 70
|
||||
#define VK_F1 80
|
||||
#define VK_F2 81
|
||||
#define VK_F3 82
|
||||
#define VK_F4 83
|
||||
#define VK_BACKSPACE 8
|
||||
#define VK_TAB 9
|
||||
#define VK_ENTER 13
|
||||
#define VK_ESC 27
|
||||
|
||||
void vt_handle_key(uint8_t c);
|
||||
void vt_set_key_handler(void (*handler)(uint8_t, bool));
|
||||
|
||||
Reference in New Issue
Block a user