reset implemented
This commit is contained in:
parent
eeae409eae
commit
1fdf680207
325
firmware/main.c
325
firmware/main.c
|
@ -26,12 +26,50 @@
|
|||
#include <avr/io.h> /* AVR device-specific IO definitions */
|
||||
#include <util/delay.h> /* Convenience functions for busy-wait delay loops */
|
||||
#include <avr/interrupt.h> /* Interrupts */
|
||||
#include <avr/wdt.h> /* Watchdog timer handling */
|
||||
//#include <avr/pgmspace.h> /* Program Space Utilities */
|
||||
|
||||
#include "main.h"
|
||||
#include "uart.h"
|
||||
#include "ir_nec.h"
|
||||
#include "settings.h"
|
||||
|
||||
/* help strings */
|
||||
/*
|
||||
const char help_00[] PROGMEM = "commands:\n";
|
||||
const char help_01[] PROGMEM = "\thelp display this help\n";
|
||||
const char help_02[] PROGMEM = "\treset reset boad and settings\n";
|
||||
const char help_03[] PROGMEM = "\tpower show power state\n";
|
||||
const char help_04[] PROGMEM = "\tpower on switch power on\n";
|
||||
const char help_05[] PROGMEM = "\tpower off switch power off\n";
|
||||
const char help_06[] PROGMEM = "\tfan show fan speed\n";
|
||||
const char help_07[] PROGMEM = "\tch X Y show channel [1-2].[1-5] brightness\n";
|
||||
const char help_08[] PROGMEM = "\tch X Y Z set channel [1-2].[1-5] brightness [0-255]\n";
|
||||
const char help_09[] PROGMEM = "\tir learn power learn the IR command to power on/off\n";
|
||||
const char help_10[] PROGMEM = "\tir learn mode learn the IR command to change between modes\n";
|
||||
const char help_11[] PROGMEM = "\tir learn brightness up learn the IR command to increase brightness\n";
|
||||
const char help_12[] PROGMEM = "\tir learn brightness down learn the IR command to decrease brightness\n";
|
||||
const char help_13[] PROGMEM = "\tir learn channel next learn the IR command to select next channel\n";
|
||||
const char help_14[] PROGMEM = "\tir learn channel previous learn the IR command to select previous channel\n";
|
||||
PGM_P const help_table[] PROGMEM = {
|
||||
help_00,
|
||||
help_01,
|
||||
help_02,
|
||||
help_03,
|
||||
help_04,
|
||||
help_05,
|
||||
help_06,
|
||||
help_07,
|
||||
help_08,
|
||||
help_09,
|
||||
help_10,
|
||||
help_11,
|
||||
help_12,
|
||||
help_13,
|
||||
help_14,
|
||||
};
|
||||
*/
|
||||
|
||||
volatile uint8_t* PORTS[CHANNELS_1+CHANNELS_2] = {&PORTC,&PORTC,&PORTC,&PORTC,&PORTC,&PORTD,&PORTD,&PORTD,&PORTD,&PORTD};
|
||||
volatile uint8_t* DDRS[CHANNELS_1+CHANNELS_2] = {&DDRC,&DDRC,&DDRC,&DDRC,&DDRC,&DDRD,&DDRD,&DDRD,&DDRD,&DDRD};
|
||||
const uint8_t BITS[CHANNELS_1+CHANNELS_2] = {PC0,PC1,PC2,PC3,PC4};
|
||||
|
@ -131,6 +169,16 @@ ISR(TIMER0_COMPA_vect) { /* timer 0 OCR0A match interrupt vector */
|
|||
pwm_flag = true;
|
||||
}
|
||||
|
||||
/* disable watched when booting */
|
||||
void wdt_init(void) __attribute__((naked)) __attribute__((section(".init3")));
|
||||
void wdt_init(void)
|
||||
{
|
||||
MCUSR = 0;
|
||||
wdt_disable();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void ioinit(void)
|
||||
{
|
||||
/* configure power */
|
||||
|
@ -195,10 +243,11 @@ void ioinit(void)
|
|||
TCCR0A |= (1<<WGM01);
|
||||
TCCR0A &= ~(1<<WGM00);
|
||||
TCCR0B &= ~(1<<WGM02);
|
||||
/* /64 prescale timer */
|
||||
/* /8 prescale timer */
|
||||
TCCR0B &= ~(1<<CS02);
|
||||
TCCR0B |= (1<<CS01)|(1<<CS00);
|
||||
OCR0A = 0xff; /* set PWM speed */
|
||||
TCCR0B |= (1<<CS01);
|
||||
TCCR0B &= ~(1<<CS00);
|
||||
OCR0A = 0xff; /* set PWM frequency (with prescale=8, 0x00=2304kHz-0xff=9kHz) */
|
||||
TIFR0 = (1<<OCF0A); /* clear timer 0 compare interrupt flag */
|
||||
TIMSK0 |= (1<<OCIE0A); /* enable timer 0 compare interrupt */
|
||||
|
||||
|
@ -212,111 +261,15 @@ void ioinit(void)
|
|||
|
||||
void help(void)
|
||||
{
|
||||
printf("commands:\n"\
|
||||
"\thelp display this help\n"\
|
||||
"\tpower show power state\n"\
|
||||
"\tpower on switch power on\n"\
|
||||
"\tpower off switch power off\n"\
|
||||
"\tfan show fan speed\n"\
|
||||
"\tch X Y show channel [1-2].[1-5] brightness\n"\
|
||||
"\tch X Y Z set channel [1-2].[1-5] brightness [0-255]\n"\
|
||||
"\tir learn power learn the IR command to power on/off\n"\
|
||||
"\tir learn mode learn the IR command to change between modes\n"\
|
||||
"\tir learn brightness up learn the IR command to increase brightness\n"\
|
||||
"\tir learn brightness down learn the IR command to decrease brightness\n"\
|
||||
"\tir learn channel next learn the IR command to select next channel\n"\
|
||||
"\tir learn channel previous learn the IR command to select previous channel\n"\
|
||||
);
|
||||
}
|
||||
|
||||
void uart_action(char* str)
|
||||
{
|
||||
const char* delimiter = " ";
|
||||
char* word = strtok(str,delimiter);
|
||||
if (!word) {
|
||||
goto error;
|
||||
/*
|
||||
char* str;
|
||||
for (uint8_t i=0; i<sizeof(help_table)/sizeof(PGM_P); i++) {
|
||||
str = malloc(strlen_PF((uint_farptr_t)pgm_read_word(&(help_table[i]))));
|
||||
strcpy_PF(str, (uint_farptr_t)pgm_read_word(&(help_table[i])));
|
||||
printf(str);
|
||||
free(str);
|
||||
}
|
||||
if (0==strcmp(word,"help")) {
|
||||
help();
|
||||
} else if (0==strcmp(word,"power")) {
|
||||
word = strtok(NULL,delimiter);
|
||||
if (!word) {
|
||||
if (PINB&(1<<nPS_ON)) {
|
||||
puts("power is off");
|
||||
} else {
|
||||
puts("power is on");
|
||||
}
|
||||
} else if (0==strcmp(word,"on")) {
|
||||
PORTB &= ~(1<<nPS_ON);
|
||||
} else if (0==strcmp(word,"off")) {
|
||||
PORTB |= (1<<nPS_ON);
|
||||
} else {
|
||||
goto error;
|
||||
}
|
||||
} else if (0==strcmp(word,"fan")) {
|
||||
if (tachometer) {
|
||||
uint16_t prescale = TIMER2_PRESCALE[TCCR2B&((1<<CS22)|(1<<CS21)|(1<<CS20))];
|
||||
if (prescale) {
|
||||
if (timer2_ovf<0xff) {
|
||||
uint32_t speed = ((60*F_CPU)/(prescale*(uint32_t)tachometer))/2; // calculate speed. 2 pulses per revolution
|
||||
printf("fan speed: %lurpm\n",speed);
|
||||
} else {
|
||||
printf("fan is off (or not detected)\n");
|
||||
}
|
||||
} else {
|
||||
printf("fan speed measurement not started\n");
|
||||
}
|
||||
} else {
|
||||
printf("fan is off (or not detected)\n");
|
||||
}
|
||||
} else if (0==strcmp(word,"ir")) {
|
||||
word = strtok(NULL,delimiter);
|
||||
if (0==strcmp(word,"learn")) {
|
||||
word = strtok(NULL,delimiter);
|
||||
if (0==strcmp(word,"power")) {
|
||||
to_learn = POWER;
|
||||
learn_flag = true;
|
||||
} else if (0==strcmp(word,"mode")) {
|
||||
to_learn = MODE;
|
||||
learn_flag = true;
|
||||
} else if (0==strcmp(word,"brightness")) {
|
||||
word = strtok(NULL,delimiter);
|
||||
if (0==strcmp(word,"up")) {
|
||||
to_learn = BRIGHTNESS_UP;
|
||||
learn_flag = true;
|
||||
} else if (0==strcmp(word,"down")) {
|
||||
to_learn = BRIGHTNESS_DOWN;
|
||||
learn_flag = true;
|
||||
} else {
|
||||
goto error;
|
||||
}
|
||||
} else if (0==strcmp(word,"channel")) {
|
||||
word = strtok(NULL,delimiter);
|
||||
if (0==strcmp(word,"next")) {
|
||||
to_learn = CHANNEL_NEXT;
|
||||
learn_flag = true;
|
||||
} else if (0==strcmp(word,"previous")) {
|
||||
to_learn = CHANNEL_PREVIOUS;
|
||||
learn_flag = true;
|
||||
} else {
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (learn_flag) {
|
||||
puts("press button on remote to learn code");
|
||||
}
|
||||
return;
|
||||
error:
|
||||
puts("command not recognized");
|
||||
*/
|
||||
}
|
||||
|
||||
int main(void)
|
||||
|
@ -337,7 +290,7 @@ int main(void)
|
|||
|
||||
puts("LED dimmer up & running");
|
||||
|
||||
// load (or initialize) settings
|
||||
/* load (or initialize) settings */
|
||||
if (!verify_settings()) {
|
||||
initialize_settings();
|
||||
save_settings();
|
||||
|
@ -351,7 +304,7 @@ int main(void)
|
|||
puts("settings loaded");
|
||||
}
|
||||
|
||||
// switch power supply as saved
|
||||
/* switch power supply as saved */
|
||||
if (power) {
|
||||
PORTB &= ~(1<<nPS_ON);
|
||||
} else {
|
||||
|
@ -404,6 +357,7 @@ int main(void)
|
|||
if (command_i>1) {
|
||||
input[command_i-1] = '\0';
|
||||
uart_action(input);
|
||||
save_settings();
|
||||
}
|
||||
input_i = command_i = 0;
|
||||
}
|
||||
|
@ -423,6 +377,9 @@ int main(void)
|
|||
}
|
||||
} else {
|
||||
puts("power off");
|
||||
for (uint8_t i=0; i<CHANNELS_1+CHANNELS_2; i++) { /* switch off output */
|
||||
*(PORTS[i]) &= ~(1<<BITS[i]);
|
||||
}
|
||||
power = 0;
|
||||
}
|
||||
save_settings();
|
||||
|
@ -463,6 +420,156 @@ int main(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void uart_action(char* str)
|
||||
{
|
||||
const char* delimiter = " ";
|
||||
char* word = strtok(str,delimiter);
|
||||
if (!word) {
|
||||
goto error;
|
||||
}
|
||||
if (0==strcmp(word,"help")) {
|
||||
help();
|
||||
} else if (0==strcmp(word,"reset")) {
|
||||
reset_settings();
|
||||
/* reset using watchdog */
|
||||
do {
|
||||
wdt_enable(WDTO_15MS);
|
||||
for(;;) {}
|
||||
} while(0);
|
||||
} else if (0==strcmp(word,"power")) {
|
||||
word = strtok(NULL,delimiter);
|
||||
if (!word) {
|
||||
if (PINB&(1<<nPS_ON)) {
|
||||
puts("power is off");
|
||||
} else {
|
||||
puts("power is on");
|
||||
}
|
||||
} else if (0==strcmp(word,"on")) {
|
||||
PORTB &= ~(1<<nPS_ON);
|
||||
} else if (0==strcmp(word,"off")) {
|
||||
PORTB |= (1<<nPS_ON);
|
||||
} else {
|
||||
goto error;
|
||||
}
|
||||
} else if (0==strcmp(word,"fan")) {
|
||||
if (tachometer) {
|
||||
uint16_t prescale = TIMER2_PRESCALE[TCCR2B&((1<<CS22)|(1<<CS21)|(1<<CS20))];
|
||||
if (prescale) {
|
||||
if (timer2_ovf<0xff) {
|
||||
uint32_t speed = ((60*F_CPU)/(prescale*(uint32_t)tachometer))/2; /* calculate speed. 2 pulses per revolution */
|
||||
printf("fan speed: %lurpm\n",speed);
|
||||
} else {
|
||||
printf("fan is off (or not detected)\n");
|
||||
}
|
||||
} else {
|
||||
printf("fan speed measurement not started\n");
|
||||
}
|
||||
} else {
|
||||
printf("fan is off (or not detected)\n");
|
||||
}
|
||||
} else if (0==strcmp(word,"ir")) {
|
||||
word = strtok(NULL,delimiter);
|
||||
if (0==strcmp(word,"learn")) {
|
||||
word = strtok(NULL,delimiter);
|
||||
if (0==strcmp(word,"power")) {
|
||||
to_learn = POWER;
|
||||
learn_flag = true;
|
||||
} else if (0==strcmp(word,"mode")) {
|
||||
to_learn = MODE;
|
||||
learn_flag = true;
|
||||
} else if (0==strcmp(word,"brightness")) {
|
||||
word = strtok(NULL,delimiter);
|
||||
if (0==strcmp(word,"up")) {
|
||||
to_learn = BRIGHTNESS_UP;
|
||||
learn_flag = true;
|
||||
} else if (0==strcmp(word,"down")) {
|
||||
to_learn = BRIGHTNESS_DOWN;
|
||||
learn_flag = true;
|
||||
} else {
|
||||
goto error;
|
||||
}
|
||||
} else if (0==strcmp(word,"channel")) {
|
||||
word = strtok(NULL,delimiter);
|
||||
if (0==strcmp(word,"next")) {
|
||||
to_learn = CHANNEL_NEXT;
|
||||
learn_flag = true;
|
||||
} else if (0==strcmp(word,"previous")) {
|
||||
to_learn = CHANNEL_PREVIOUS;
|
||||
learn_flag = true;
|
||||
} else {
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
goto error;
|
||||
}
|
||||
} else if (0==strcmp(word,"ch")) {
|
||||
word = strtok(NULL,delimiter);
|
||||
if (!word) { /* expecting channel group */
|
||||
goto error;
|
||||
}
|
||||
if (strlen(word)!=1) { /* expecting one digit channel group X */
|
||||
goto error;
|
||||
}
|
||||
uint8_t group = 0;
|
||||
switch (word[0]) { /* expecting channel group X 1 or 2 */
|
||||
case '1':
|
||||
group = 0;
|
||||
break;
|
||||
case '2':
|
||||
group = 1;
|
||||
break;
|
||||
default:
|
||||
goto error;
|
||||
}
|
||||
/* get channel output */
|
||||
word = strtok(NULL,delimiter);
|
||||
if (!word) {
|
||||
goto error;
|
||||
}
|
||||
/* expecting one digit channel output Y */
|
||||
if (strlen(word)!=1) {
|
||||
goto error;
|
||||
}
|
||||
/* expecting channel group Y 1-CHANNELS_X */
|
||||
if (word[0]<'1') {
|
||||
goto error;
|
||||
}
|
||||
uint8_t output = word[0]-'1';
|
||||
if (group==0 && output>CHANNELS_1) {
|
||||
goto error;
|
||||
} else if (group==1 && output>CHANNELS_2) {
|
||||
goto error;
|
||||
}
|
||||
uint8_t channel = group*CHANNELS_1+output;
|
||||
/* brightness setting */
|
||||
word = strtok(NULL,delimiter);
|
||||
if (!word) {
|
||||
printf("%u\n",brightness[mode][channel]);
|
||||
} else {
|
||||
if (strlen(word)>3) {
|
||||
goto error;
|
||||
}
|
||||
uint16_t br = atoi(word);
|
||||
if (br>0xff) {
|
||||
goto error;
|
||||
}
|
||||
brightness[mode][channel] = (uint8_t)br;
|
||||
}
|
||||
} else {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (learn_flag) {
|
||||
puts("press button on remote to learn code");
|
||||
}
|
||||
return;
|
||||
error:
|
||||
puts("command not recognized");
|
||||
}
|
||||
|
||||
void ir_action(uint8_t address, uint8_t command)
|
||||
{
|
||||
enum IR_ACTIONS ir_code = IR_ACTION_END;
|
||||
|
|
|
@ -22,6 +22,9 @@ bool verify_settings(void)
|
|||
uint16_t settings_size = sizeof(MAGIC)+sizeof(power)+sizeof(mode)+sizeof(brightness)+sizeof(ir_keys)+1; // the byte used for the checksum (magic header and checksum included)
|
||||
for (uint16_t i=0; i<settings_size; i++) {
|
||||
byte = eeprom_read_byte((const uint8_t*)i);
|
||||
if (0==i && byte!=MAGIC) {
|
||||
return false;
|
||||
}
|
||||
checksum ^= byte;
|
||||
}
|
||||
if (0==checksum) {
|
||||
|
@ -98,3 +101,9 @@ void load_settings(void)
|
|||
addr++;
|
||||
}
|
||||
}
|
||||
|
||||
void reset_settings(void)
|
||||
{
|
||||
/* invalidate magic header */
|
||||
eeprom_update_byte((uint8_t*)0,0);
|
||||
}
|
||||
|
|
|
@ -21,3 +21,4 @@ bool verify_settings(void);
|
|||
void initialize_settings(void);
|
||||
void save_settings(void);
|
||||
void load_settings(void);
|
||||
void reset_settings(void);
|
||||
|
|
Loading…
Reference in New Issue