Add support for night mode

This commit is contained in:
2020-11-19 18:05:49 +01:00
parent 0f2dca5ec7
commit 8b47ed295e
12 changed files with 173 additions and 30 deletions

View File

@@ -7,6 +7,7 @@
#include "at.h"
#include "uart.h"
#include "config.h"
#include "nightm.h"
#include "time.h"
#include "led.h"
#include "rtc.h"
@@ -18,7 +19,8 @@ const struct AT_CMD at_commands[AT_NUM] PROGMEM = {
{ "ATI", cmd_ati_handler },
{ "AT+RST", cmd_at_rst_handler },
{ "AT+TIME", cmd_at_time_handler },
{ "AT+BTNES", cmd_at_btnes_handler }
{ "AT+BTNES", cmd_at_btnes_handler },
{ "AT+NGT", cmd_at_ngt_handler }
};
void parse_at(char* at_cmd, char* arg, uint8_t mode)
@@ -115,7 +117,7 @@ int8_t cmd_at_rst_handler(uint8_t mode, char* arg)
int8_t cmd_at_time_handler(uint8_t mode, char* arg)
{
struct TIME time;
struct TIME_HMS time;
char* val;
char* tail;
@@ -171,8 +173,7 @@ int8_t cmd_at_btnes_handler(uint8_t mode, char* arg)
switch(mode)
{
case M_GET:
for(btness=0; btness<8; ++btness) if(ram_cfg.led_brightness & (1<<btness)) break;
uart_puti(btness, 10);
uart_puti(ram_cfg.led_brightness, 10);
uart_puts("\n\r");
break;
@@ -196,3 +197,69 @@ int8_t cmd_at_btnes_handler(uint8_t mode, char* arg)
return 0;
}
int8_t cmd_at_ngt_handler(uint8_t mode, char* arg)
{
struct NIGHTM_CFG nightm_cfg;
char* val;
char* tail;
switch(mode)
{
case M_GET:
uart_puti(ram_cfg.night_mode.led_btnes, 10);
uart_puts(ram_cfg.night_mode.led_btnes >= 0 ? " (EN)\n\r" : " (DIS)\n\r");
uart_puti(ram_cfg.night_mode.begin.hour, 10);
uart_puts(":");
uart_puti(ram_cfg.night_mode.begin.minute, 10);
uart_puts("\n\r");
uart_puti(ram_cfg.night_mode.end.hour, 10);
uart_puts(":");
uart_puti(ram_cfg.night_mode.end.minute, 10);
uart_puts("\n\r");
break;
case M_SET:
if(!strlen(arg)) return -1;
val = strtok_r(arg, ",", &tail);
nightm_cfg.led_btnes = atoi(val);
if(nightm_cfg.led_btnes < -1 && 7 < nightm_cfg.led_btnes) return -1;
val = strtok_r(NULL, ",", &tail);
nightm_cfg.begin.hour = atoi(val);
if(nightm_cfg.begin.hour > 23) return -1;
val = strtok_r(NULL, ",", &tail);
nightm_cfg.begin.minute = atoi(val);
if(nightm_cfg.begin.minute > 59) return -1;
val = strtok_r(NULL, ",", &tail);
nightm_cfg.end.hour = atoi(val);
if(nightm_cfg.end.hour > 23) return -1;
val = strtok_r(NULL, ",", &tail);
nightm_cfg.end.minute = atoi(val);
if(nightm_cfg.end.minute > 59) return -1;
nightm_config(&nightm_cfg);
uart_puts("+NGT=");
uart_puti(nightm_cfg.led_btnes, 10);
uart_puts(",");
uart_puti(nightm_cfg.begin.hour, 10);
uart_puts(",");
uart_puti(nightm_cfg.begin.minute, 10);
uart_puts(",");
uart_puti(nightm_cfg.end.hour, 10);
uart_puts(",");
uart_puti(nightm_cfg.end.minute, 10);
uart_puts("\n\r");
break;
case M_NORM:
uart_puts("AT+NGT=(-1|0-7),(0-23),(0-59),(0-23),(0-59)");
}
return 0;
}

View File

@@ -20,8 +20,9 @@ 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);
int8_t cmd_at_ngt_handler(uint8_t mode, char* arg);
#define AT_NUM 5
#define AT_NUM 6
extern const struct AT_CMD at_commands[AT_NUM] PROGMEM;
#endif

View File

@@ -3,7 +3,8 @@
struct CFG ram_cfg;
struct CFG eem_cfg EEMEM;
const struct CFG pgm_cfg PROGMEM = {
LED_BRIGHTNESS
LED_BRIGHTNESS,
NIGHT_MODE
};
void map_eem2ram(void)

View File

@@ -3,12 +3,24 @@
#include <avr/eeprom.h>
#include <avr/pgmspace.h>
#include "time.h"
#define LED_BRIGHTNESS 127
#define AUTO_BTNES_SIZE 4
#define LED_BRIGHTNESS 7
#define NIGHT_MODE { -1, { 0, 0 }, { 0, 0 } }
struct NIGHTM_CFG
{
int8_t led_btnes;
struct TIME_HM begin;
struct TIME_HM end;
};
struct CFG
{
uint8_t led_brightness;
struct NIGHTM_CFG night_mode;
};
extern struct CFG ram_cfg;

View File

@@ -3,10 +3,14 @@
#include "config.h"
#include "led.h"
volatile struct TIME led_display = { 0, 0, 0 };
volatile struct TIME_HMS led_display = { 0, 0, 0 };
volatile uint8_t led_btnes;
void led_init(void)
{
// Set brightness
led_btnes = 1<<(ram_cfg.led_brightness);
// Set outputs
ANODES_DIR |= HOUR_ANODE | MINUTE_ANODE | SECOND_ANODE;
LED_DIR |= 0x3F; // 0b00111111
@@ -19,17 +23,18 @@ void led_init(void)
TIMSK |= (1<<TOIE0);
}
void led_set_btness(uint8_t btness)
void led_set_btness(uint8_t btnes)
{
ram_cfg.led_brightness = (1<<btness);
if(!ram_cfg.led_brightness) ram_cfg.led_brightness = 1;
if(btnes > 7) btnes = 0;
led_btnes = 1<<btnes;
ram_cfg.led_brightness = btnes;
dump_ram2eem();
}
void led_inc_btness(void)
{
ram_cfg.led_brightness <<= 1;
if(!ram_cfg.led_brightness) ram_cfg.led_brightness = 1;
if(++(ram_cfg.led_brightness) > 7) ram_cfg.led_brightness = 0;
led_btnes = 1<<(ram_cfg.led_brightness);
dump_ram2eem();
}
@@ -44,15 +49,15 @@ ISR(TIMER0_OVF_vect)
{
case 1:
LED_PORT = ~led_display.hour;
ANODES_PORT = ram_cfg.led_brightness >= pwm_counter ? ~HOUR_ANODE : 0xFF;
ANODES_PORT = led_btnes >= pwm_counter ? ~HOUR_ANODE : 0xFF;
break;
case 2:
LED_PORT = ~led_display.minute;
ANODES_PORT = ram_cfg.led_brightness >= pwm_counter ? ~MINUTE_ANODE : 0xFF;
ANODES_PORT = led_btnes >= pwm_counter ? ~MINUTE_ANODE : 0xFF;
break;
case 4:
LED_PORT = ~led_display.second;
ANODES_PORT = ram_cfg.led_brightness >= pwm_counter ? ~SECOND_ANODE : 0xFF;
ANODES_PORT = led_btnes >= pwm_counter ? ~SECOND_ANODE : 0xFF;
break;
}

View File

@@ -12,7 +12,8 @@
#define MINUTE_ANODE (1<<PD6)
#define SECOND_ANODE (1<<PD7)
extern volatile struct TIME led_display;
extern volatile struct TIME_HMS led_display;
extern volatile uint8_t led_btnes;
void led_init(void);
void led_set_btness(uint8_t btness);

View File

@@ -1,19 +1,19 @@
#include <avr/io.h>
#include <avr/interrupt.h>
#include "config.h"
#include <avr/io.h>
#include "keyboard.h"
#include "ptimer.h"
#include "config.h"
#include "nightm.h"
#include "time.h"
#include "uart.h"
#include "i2c.h"
#include "rtc.h"
#include "led.h"
#include "at.h"
#include "uart.h"
#define I2C_BITRATE 100000UL // 100kHz
char buffer[20];
void update_time(void);
int main()
{
@@ -28,14 +28,30 @@ int main()
sei();
char uart_buf[20];
while(1)
{
keyboard_handle_input();
uart_handle_event(buffer);
uart_handle_event(uart_buf);
update_time();
}
}
void update_time(void)
{
if(!(GIFR & (1<<INTF0)))
{
struct TIME_HMS curr_time = rtc_read_time();
led_display = curr_time;
nightm_handle(&curr_time);
}
GIFR |= 1<<INTF0;
}
ISR(INT0_vect)
{
led_display = rtc_read_time();
}

24
firmware/nightm.c Normal file
View File

@@ -0,0 +1,24 @@
#include "nightm.h"
#include "led.h"
#define TIME2INT(TIME) ((TIME).hour*60 + (TIME).minute)
void nightm_config(struct NIGHTM_CFG* cfg)
{
ram_cfg.night_mode = *cfg;
dump_ram2eem();
}
void nightm_handle(struct TIME_HMS* curr_time)
{
if(ram_cfg.night_mode.led_btnes >= 0)
{
uint16_t current = TIME2INT(*curr_time);
uint16_t begin = TIME2INT(ram_cfg.night_mode.begin);
uint16_t end = TIME2INT(ram_cfg.night_mode.end);
led_btnes = (begin <= current && current < end)
? 1<<(ram_cfg.night_mode.led_btnes)
: 1<<(ram_cfg.led_brightness);
}
}

10
firmware/nightm.h Normal file
View File

@@ -0,0 +1,10 @@
#ifndef __NIGHTM_H__
#define __NIGHTM_H__
#include "config.h"
#include "time.h"
void nightm_config(struct NIGHTM_CFG* cfg);
void nightm_handle(struct TIME_HMS* curr_time);
#endif

View File

@@ -22,18 +22,18 @@ void rtc_set_time_part(uint8_t part, uint8_t value)
i2c_writebuf(RTC_I2C_ADDR, part, 1, &bcd);
}
void rtc_set_time(struct TIME* time)
void rtc_set_time(struct TIME_HMS* time)
{
uint8_t buf[] = { DEC_2_BCD(time->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)
struct TIME_HMS rtc_read_time(void)
{
uint8_t buffer[3];
i2c_readbuf(RTC_I2C_ADDR, 0x02, 3, buffer);
struct TIME curr_time = {
struct TIME_HMS curr_time = {
BCD_2_DEC(buffer[2]),
BCD_2_DEC(buffer[1]),
BCD_2_DEC(buffer[0])

View File

@@ -21,8 +21,8 @@
void rtc_int0_init(void);
void rtc_int1_init(void);
void rtc_set_time(struct TIME* time);
void rtc_set_time(struct TIME_HMS* time);
void rtc_set_time_part(uint8_t part, uint8_t value);
struct TIME rtc_read_time(void);
struct TIME_HMS rtc_read_time(void);
#endif

View File

@@ -1,11 +1,17 @@
#ifndef __TIME_H__
#define __TIME_H__
struct TIME
struct TIME_HMS
{
uint8_t hour;
uint8_t minute;
uint8_t second;
};
struct TIME_HM
{
uint8_t hour;
uint8_t minute;
};
#endif