--- a/car004f/main.c Sun Dec 22 00:08:46 2013 +0100 +++ b/car004f/main.c Sun Dec 22 01:50:59 2013 +0100 @@ -19,9 +19,11 @@ typedef struct { uint8_t slot; uint8_t light; - unsigned program:1; // programming mode active + uint8_t program; // 0xff = inactive ; programming mode active on slot X + uint8_t initialized; } config_t; - +config_t EEMEM eeconfig = {0,0,0xff,0}; +config_t config; volatile uint16_t data = 0; volatile uint8_t data_len = 0; @@ -36,7 +38,6 @@ uint8_t my_switch; uint8_t my_speed; -config_t config; ISR ( INT0_vect ) { GICR &= ~_BV(INT0) ; // Disable INT0 @@ -120,18 +121,21 @@ #define BRAKE_PORT PORTB #define BRAKE 0 -#define LIGHT_MODES 1 // anzahl der lichtmodi (ohne den modus "aus") +#define LIGHT_MODES 1 // anzahl der lichtmodi (ohne den modus "aus") +#define BRAKE_OFF_TIMEOUT 60 // value * 10ms +#define CAR_DEBUG 1 +#define EE_CONFIG_ADDR 64 void config_save(void) { - eeprom_write_block( (void*)&config, 0, sizeof(config) ); + eeprom_write_block( &config, &eeconfig, sizeof(config_t) ); } void brake_on(void) { LIGHT_PORT |= _BV(LIGHT_BRAKE); // brake light on BRAKE_PORT |= _BV(BRAKE); // brake on - brake_timeout = 50; + brake_timeout = BRAKE_OFF_TIMEOUT; } void brake_off(void) { @@ -140,8 +144,46 @@ brake_timeout = 0; } +uint8_t scan_id(void) { + uint8_t temp; + timeout = 1; + // scan for any key press and assign to that controller + while (car_speed[config.slot] == 0) { + for (uint8_t i=0; i<6; i++) { + if (car_switch[i] == 1) { + // wait for second key press within timeout period to assign successfully + brake_timeout = 0xff; + temp = car_switch[i]; + while (brake_timeout > 1) { + if (temp != car_switch[i]) { + temp = car_switch[i]; + if (temp == 1) { + config.slot = i; + return 1; + } + } + // toggle lights if timeout + if (timeout == 1) { + LIGHT_PORT ^= _BV(LIGHT_FRONT); + timeout = 5; + } + } + return 0; + } + } + // toggle lights if timeout + if (timeout == 1) { + LIGHT_PORT ^= _BV(LIGHT_FRONT); + timeout = 10; + } + } + return 0; +} + int main(void) { + uint8_t temp; + // setup data bit timer2 TCCR2 = (1<<CS21) | (1<<WGM21); //divide by 8, set compare match OCR2 = TIMER2_50US; @@ -156,10 +198,6 @@ DDR(LIGHT_PORT) |= _BV(LIGHT_FRONT) | _BV(LIGHT_BRAKE); DDR(BRAKE_PORT) |= _BV(BRAKE); - // config (from eeprom!) - eeprom_read_block( (void*)&config, (const void*)0, sizeof(config) ); - - TCCR1A = (1<<WGM10)|(1<<COM1A1) // Set up the two Control registers of Timer1. |(1<<COM1B1); // Wave Form Generation is Fast PWM 8 Bit, @@ -171,6 +209,7 @@ //OCR1B = 127; // Dutycycle of OC1B = 50% OCR1A = 0; OCR1B = 0; + DDRB &= ~_BV(2); // PB2 PWM Output disable // configure TIMER0 to overflow every 10ms at 4 MHz TIMSK = _BV(TOIE0); // Timer0 Overflow INT erlauben @@ -179,16 +218,56 @@ sei(); + // config (from eeprom!) + eeprom_read_block( &config, &eeconfig, sizeof(config_t) ); -config.slot = 1; + +#ifdef CAR_DEBUG + if (config.initialized == 0) { + LIGHT_PORT &= ~_BV(LIGHT_FRONT); + for (temp = 0; temp <= config.slot; temp++) { + LIGHT_PORT ^= _BV(LIGHT_FRONT); + _delay_ms(250); + LIGHT_PORT ^= _BV(LIGHT_FRONT); + _delay_ms(250); + } + } +#endif + + + + if (config.initialized != 0) { + config.slot = 0; + config.light = 0; + config.program = 0; + config.initialized = 0; + config_save(); + } + + if ((config.program != 0xff) || (config.slot > 5 )) { + temp = scan_id(); + config.program = 0xff; + config_save(); + if (temp == 1) { + // acknowledge with the engine + OCR1B = 25; + DDRB &= ~_BV(2); // PB2 PWM Output disable + for (temp = 0xff; temp > 0; temp--) { + DDRB ^= _BV(2); // PB2 PWM Output toggle + _delay_ms(5); // 50 hz + DDRB ^= _BV(2); // PB2 PWM Output toggle + _delay_ms(15); // 50 hz + } + + } + timeout = 0; + } + while (1) { // main loop - if (brake_timeout == 1) { - DDRB &= ~_BV(2); // PB2 PWM Output disable - brake_off(); - } + if (brake_timeout == 1) brake_off(); if (my_speed != car_speed[config.slot]) { my_speed = car_speed[config.slot]; @@ -209,6 +288,14 @@ if (my_switch != 0) { // cycle light if (config.light == LIGHT_MODES) config.light = 0; else config.light++; + if (timeout > 1) { + // zweiter Tastendruck, Program Mode im EEPROM setzen + config.program = 1; // TODO: hier muss der slot rein welcher doppelclicked wurde (natuerlich dann auch nicht in der Lichtschaltelogik abfragen!) + } else { + // erster Tastendruck, timeout setzen + timeout = 80; + } + config_save(); } } } @@ -223,13 +310,8 @@ } - /* - _delay_ms(100); - _delay_ms(100); - */ - - - + // timeout reset + timeout = 0; } // main loop end };