From 0f2dca5ec7238fced521098626a387d6c69c3306 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Przemys=C5=82aw=20Pluta?= Date: Wed, 18 Nov 2020 22:39:59 +0100 Subject: [PATCH] Create UART-based AT commands library --- firmware/at.c | 198 ++++++++++++++++++++++++++++++++++++++++++++ firmware/at.h | 27 ++++++ firmware/keyboard.c | 10 +-- firmware/led.c | 14 ++++ firmware/led.h | 2 + firmware/main.c | 8 ++ firmware/rtc.c | 8 +- firmware/rtc.h | 3 +- 8 files changed, 262 insertions(+), 8 deletions(-) create mode 100644 firmware/at.c create mode 100644 firmware/at.h diff --git a/firmware/at.c b/firmware/at.c new file mode 100644 index 0000000..77a88e0 --- /dev/null +++ b/firmware/at.c @@ -0,0 +1,198 @@ +#include +#include +#include +#include +#include +#include +#include "at.h" +#include "uart.h" +#include "config.h" +#include "time.h" +#include "led.h" +#include "rtc.h" + +#define UNUSED(X) (void)(X) + +const struct AT_CMD at_commands[AT_NUM] PROGMEM = { + { "AT", cmd_at_handler }, + { "ATI", cmd_ati_handler }, + { "AT+RST", cmd_at_rst_handler }, + { "AT+TIME", cmd_at_time_handler }, + { "AT+BTNES", cmd_at_btnes_handler } +}; + +void parse_at(char* at_cmd, char* arg, uint8_t mode) +{ + uint8_t ok = 0; + int8_t (*at_handler)(uint8_t mode, char* arg); + uint8_t at_len = strlen(at_cmd); + + if(at_len) + { + for(uint8_t i=0; i= 0) ok = 1; + } + break; + } + } + } + + if(!ok) uart_puts("ERROR\n\r"); +} + +void at_handler(char* cmd) +{ + if(strpbrk(cmd, "?")) + { + char* arg; + char* at = strtok_r(cmd, "?", &arg); + parse_at(at, arg, M_GET); + } + + else if(strpbrk(cmd, "=")) + { + char* arg; + char* at = strtok_r(cmd, "=", &arg); + parse_at(at, arg, M_SET); + } + + else + { + parse_at(cmd, NULL, M_NORM); + } +} + +int8_t cmd_at_handler(uint8_t mode, char* arg) +{ + UNUSED(arg); + + if(mode != M_NORM) return -1; + + uart_puts("OK\r\n"); + + return 0; +} + +int8_t cmd_ati_handler(uint8_t mode, char* arg) +{ + UNUSED(arg); + + if(mode != M_NORM) return -1; + + uart_puts("Binary Clock v1.0 :: Bartlomiej Pluta 2020\r\n"); + uart_puts("compilation "); + uart_puts(__DATE__); + uart_putc(' '); + uart_puts(__TIME__); + uart_puts("\n\r"); + uart_puts("avr-libc v"); + uart_puts(__AVR_LIBC_VERSION_STRING__); + uart_putc(' '); + uart_puts(__AVR_LIBC_DATE_STRING__); + uart_puts("\n\r"); + + return 0; +} + +int8_t cmd_at_rst_handler(uint8_t mode, char* arg) +{ + UNUSED(arg); + + if(mode != M_NORM) return -1; + + cli(); + wdt_enable(0); + while(1); + + return 0; +} + +int8_t cmd_at_time_handler(uint8_t mode, char* arg) +{ + struct TIME time; + char* val; + char* tail; + + switch(mode) + { + case M_GET: + time = rtc_read_time(); + uart_puti(time.hour, 10); + uart_putc(':'); + uart_puti(time.minute, 10); + uart_putc(':'); + uart_puti(time.second, 10); + uart_puts("\n\r"); + break; + + case M_SET: + if(!strlen(arg)) return -1; + + val = strtok_r(arg, ",", &tail); + time.hour = atoi(val); + if(time.hour >= 24) return -1; + + val = strtok_r(NULL, ",", &tail); + time.minute = atoi(val); + if(time.minute >= 60) return -1; + + val = strtok_r(NULL, ",", &tail); + time.second = atoi(val); + if(time.second >= 60) return -1; + + rtc_set_time(&time); + + uart_puts("+TIME="); + uart_puti(time.hour, 10); + uart_puts(","); + uart_puti(time.minute, 10); + uart_puts(","); + uart_puti(time.second, 10); + uart_puts("\n\r"); + break; + + case M_NORM: + uart_puts("AT+TIME=(0-23),(0-59),(0-59)\r\n"); + } + + return 0; +} + +int8_t cmd_at_btnes_handler(uint8_t mode, char* arg) +{ + uint8_t btness; + + switch(mode) + { + case M_GET: + for(btness=0; btness<8; ++btness) if(ram_cfg.led_brightness & (1<= 8) return -1; + led_set_btness(btness); + + uart_puts("+BTNES="); + uart_puts(arg); + uart_puts("\n\r"); + + break; + + case M_NORM: + uart_puts("AT+BTNES=(0-7)\n\r"); + } + + return 0; +} diff --git a/firmware/at.h b/firmware/at.h new file mode 100644 index 0000000..5e782f2 --- /dev/null +++ b/firmware/at.h @@ -0,0 +1,27 @@ +#ifndef __AT_H__ +#define __AT_H__ + +#include + +#define M_SET 0 +#define M_GET 1 +#define M_NORM 2 + +struct AT_CMD +{ + char cmd[8]; + int8_t (*handler)(uint8_t mode, char* arg); +}; + +void at_handler(char* cmd); + +int8_t cmd_at_handler(uint8_t mode, char* arg); +int8_t cmd_ati_handler(uint8_t mode, char* arg); +int8_t cmd_at_rst_handler(uint8_t mode, char* arg); +int8_t cmd_at_time_handler(uint8_t mode, char* arg); +int8_t cmd_at_btnes_handler(uint8_t mode, char* arg); + +#define AT_NUM 5 +extern const struct AT_CMD at_commands[AT_NUM] PROGMEM; + +#endif \ No newline at end of file diff --git a/firmware/keyboard.c b/firmware/keyboard.c index 9a2466d..1a5d650 100644 --- a/firmware/keyboard.c +++ b/firmware/keyboard.c @@ -10,26 +10,24 @@ uint8_t k_inc_hour, k_inc_minute, k_inc_second, k_inc_brightness; void inc_hour(void) { led_display.hour = (led_display.hour + 1) % 24; - rtc_set_time(HOUR, led_display.hour); + rtc_set_time_part(HOUR, led_display.hour); } void inc_minute(void) { led_display.minute = (led_display.minute + 1) % 60; - rtc_set_time(MINUTE, led_display.minute); + rtc_set_time_part(MINUTE, led_display.minute); } void inc_second(void) { led_display.second = (led_display.second + 1) % 60; - rtc_set_time(SECOND, led_display.second); + rtc_set_time_part(SECOND, led_display.second); } void inc_brightness(void) { - ram_cfg.led_brightness <<= 1; - if(!ram_cfg.led_brightness) ram_cfg.led_brightness = 1; - dump_ram2eem(); + led_inc_btness(); } void keyboard_init(void) diff --git a/firmware/led.c b/firmware/led.c index 2a90cd5..4bcef2f 100644 --- a/firmware/led.c +++ b/firmware/led.c @@ -19,6 +19,20 @@ void led_init(void) TIMSK |= (1<second), DEC_2_BCD(time->minute), DEC_2_BCD(time->hour) }; + i2c_writebuf(RTC_I2C_ADDR, SECOND, 3, buf); // SECOND is the first memory cell (0x02) +} + struct TIME rtc_read_time(void) { uint8_t buffer[3]; diff --git a/firmware/rtc.h b/firmware/rtc.h index b65248f..28a551c 100644 --- a/firmware/rtc.h +++ b/firmware/rtc.h @@ -21,7 +21,8 @@ void rtc_int0_init(void); void rtc_int1_init(void); -void rtc_set_time(uint8_t part, uint8_t value); +void rtc_set_time(struct TIME* time); +void rtc_set_time_part(uint8_t part, uint8_t value); struct TIME rtc_read_time(void); #endif \ No newline at end of file