Improved UART, added Key Handler to uart_ansi

pull/1/head
Ondřej Hruška 9 years ago
parent 7caeceb05c
commit a3ecabbef9
  1. 110
      lib/uart.c
  2. 25
      lib/uart.h
  3. 215
      lib/uart_ansi.c
  4. 28
      lib/uart_ansi.h

@ -112,103 +112,91 @@ 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)
{
itoa(num, tmpstr, 10);
utoa(num, tmpstr, 10);
uart_puts(tmpstr);
}
/** Send unsigned int */
void uart_put16i(const int16_t num)
{
itoa(num, tmpstr, 10);
uart_puts(tmpstr);
}
/** Send signed int */
void uart_put16u(const uint16_t num)
/** Send unsigned int8 */
void uart_putn(const int8_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)
/** Send unsigned int as float */
void uart_putiu(const uint16_t num, const uint8_t places)
{
ltoa(num, tmpstr, 10);
uart_puts(tmpstr);
if (!places) {
utoa(num, tmpstr, 10);
uart_puts(tmpstr);
} else {
utoa(num, tmpstr, 10);
_uart_putnf(places);
}
}
/** Send signed long as float */
void uart_put32if(const int32_t num, const uint8_t places)
/** Send signed int as float */
void uart_puti(const int16_t num, const uint8_t places)
{
if (num < 0) {
uart_tx('-');
ltoa(-num, tmpstr, 10);
if (!places) {
itoa(num, tmpstr, 10);
uart_puts(tmpstr);
} else {
ltoa(num, tmpstr, 10);
}
if (num < 0) {
uart_tx('-');
itoa(-num, tmpstr, 10);
} else {
itoa(num, tmpstr, 10);
}
_uart_putn(places);
_uart_putnf(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_putlu(const uint32_t num, const uint8_t places)
{
if (num < 0) {
uart_tx('-');
itoa(-num, tmpstr, 10);
if (!places) {
ultoa(num, tmpstr, 10);
uart_puts(tmpstr);
} else {
itoa(num, tmpstr, 10);
ultoa(num, tmpstr, 10);
_uart_putnf(places);
}
_uart_putn(places);
}
/** Send unsigned int as float */
void uart_put16uf(const uint16_t num, const uint8_t places)
/** Send signed long as float */
void uart_putl(const int32_t num, const uint8_t places)
{
ltoa(num, tmpstr, 10);
_uart_putn(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_putn(const uint8_t places)
void _uart_putnf(const uint8_t places)
{
// measure text length
uint8_t len = 0;

@ -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

@ -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));

Loading…
Cancel
Save