reset implemented

This commit is contained in:
King Kévin 2013-10-19 19:51:18 +02:00
parent eeae409eae
commit 1fdf680207
3 changed files with 226 additions and 109 deletions

View File

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

View File

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

View File

@ -21,3 +21,4 @@ bool verify_settings(void);
void initialize_settings(void);
void save_settings(void);
void load_settings(void);
void reset_settings(void);