void trainerschool_test_idle(){ generic_callback1(); if(super.keys_new.keys.down){ fmem.tst_mem->cursor++; fmem.tst_mem->cursor = (u8)(fmem.tst_mem->cursor % trainerschool_test_questions[fmem.tst_mem->current_question].answer_cnt); play_sound(5); trainerschool_test_load_answers(); }else if(super.keys_new.keys.up){ if(!fmem.tst_mem->cursor)fmem.tst_mem->cursor = (u8) (trainerschool_test_questions[fmem.tst_mem->current_question].answer_cnt - 1); else fmem.tst_mem->cursor--; play_sound(5); trainerschool_test_load_answers(); }else if(super.keys_new.keys.A){ s16 y = (s16)(fmem.tst_mem->cursor * 16 + 83); u8 question = fmem.tst_mem->current_question; if(trainerschool_test_questions[question].correct_answer == fmem.tst_mem->cursor){ //correct answer fanfare(269); play_sound(12); (*var_access(TRAINERSCHOOL_CORRECT_ANSWERS))++; fmem.tst_mem->answer_oam = oam_new_forward_search( &trainerschool_test_oam_template_correct, 168, y, 0); fmem.tst_mem->delay = 0xC0; fmem.tst_mem->frame = 0; callback1_set(trainerschool_test_question_done); }else{ fanfare(271); play_sound(12); fmem.tst_mem->answer_oam = oam_new_forward_search( &trainerschool_test_oam_template_wrong, 168, y, 0); fmem.tst_mem->delay = 0xC0; fmem.tst_mem->frame = 0; callback1_set(trainerschool_test_question_done); } } }
int main( void ) { _delay_ms(100); // set clock speed CLKPR = _BV( CLKPCE ); // enable clock prescale change CLKPR = 0; // full speed (8MHz); #if defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || \ defined(__AVR_ATtiny85__) // set up periodic timer for state machine ('script_tick') TCCR0B = _BV( CS02 ) | _BV(CS00); // start timer, prescale CLK/1024 TIFR = _BV( TOV0 ); // clear interrupt flag TIMSK = _BV( TOIE0 ); // enable overflow interrupt // set up output pins PORTB = INPI2C_MASK; // turn on pullups DDRB = LED_MASK; // set LED port pins to output #elif defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || \ defined(__AVR_ATtiny84__) // set up periodic timer for state machine ('script_tick') //TCCR0B = _BV( CS02 ) | _BV(CS00); // start timer, prescale CLK/1024 //TIFR0 = _BV( TOV0 ); // clear interrupt flag //TIMSK0 = _BV( TOIE0 ); // enable overflow interrupt // set up output pins PORTA = INPI2C_MASK; // turn on pullups DDRA = 0xFF; //LEDA_MASK; // set LED port pins to output DDRB = 0xFF; //LEDB_MASK; // set LED port pins to output #endif fanfare( 3, 300 ); #if 0 // test for ATtiny44/84 MaxM fanfare( 3, 300 ); IRsend_enableIROut(); while( 1 ) { _delay_ms(10); IRsend_iroff(); _delay_ms(10); IRsend_iron(); } /* uint8_t f = OCR1B; while( 1 ) { _delay_ms(10); f++; if( f== OCR1A ) f=0; // OCR1A == period OCR1B = f; // OCR1B == duty cycle (0-OCR1A) } */ #endif #if 0 // test timing of script_tick _delay_ms(2000); sei(); _delay_ms(500); // this should cause script_tick to equal 15 uint8_t j = script_tick; for( int i=0; i<j; i++ ) { led_flash(); _delay_ms(300); } #endif ////// begin normal startup uint8_t boot_mode = eeprom_read_byte( &ee_boot_mode ); uint8_t boot_script_id = eeprom_read_byte( &ee_boot_script_id ); uint8_t boot_reps = eeprom_read_byte( &ee_boot_reps ); //uint8_t boot_fadespeed = eeprom_read_byte( &ee_boot_fadespeed ); uint8_t boot_timeadj = eeprom_read_byte( &ee_boot_timeadj ); // initialize i2c interface uint8_t i2c_addr = eeprom_read_byte( &ee_i2c_addr ); if( i2c_addr==0 || i2c_addr>0x7f) i2c_addr = I2C_ADDR; // just in case i2c_addrs[0] = i2c_addr; for( uint8_t i = 1; i<slaveAddressesCount; i++ ) { i2c_addrs[i] = i2c_addrs[0] + i; } usiTwiSlaveInit( i2c_addrs ); timeadj = boot_timeadj; if( boot_mode == BOOT_PLAY_SCRIPT ) { play_script( boot_script_id, boot_reps, 0 ); } sei(); // enable interrupts #if 0 basic_tests(); #endif RB_Init(); // This loop runs forever. // If the TWI Transceiver is busy the execution will just // continue doing other operations. for(;;) { handle_i2c(); handle_inputs(); handle_script(); handle_ir_queue(); } } // end
int main( void ) { CLKPR = _BV( CLKPCE ); // enable clock prescale change #if F_CPU == 500000 CLKPR = _BV(CLKPS2) ; // div clock by 16 (8MHz -> 0.5MHz) #else CLKPR = 0; // full speed (8MHz) #endif #if F_CPU == 500000 TCCR1 |= _BV(CS12); // clock/8 see calc below @0.5MHz #endif #if F_CPU == 8000000 TCCR1 |= _BV(CS12)|_BV(CS11)|_BV(CS10); // clock/64 see calc below @8MHz #endif TIFR |= _BV( TOV1 ); // clear interrupt flag TIMSK |= _BV( TOIE1 ); // enable timer 1 overflow interrupt sei(); // enable interrupts LED_DDR |= _BV( LED_PIN ); // make output softuart_init(); softuart_putsP("\nfreem_p7\n"); _delay_ms(300); // wait for power to stabilize before doing i2c // load up our address freem_addr = eeprom_read_byte( &ee_freem_addr ); softuart_putsP("addr:"); softuart_printHex(freem_addr);softuart_putc('\n'); ir_init(); i2c_init(); #if DEBUG > 1 softuart_puts("300ms? "); _delay_ms(300); // timing test, just chill a bit, yo softuart_printDec16( millis-lastmillis ); // should be close to 300 #endif blinkm_turnOff(); fanfare( 3 ); mode = MODE_RANDMOOD; // start out in moodlight mode changemillis = millis - 2*MILLIS_MOOD; // loop forever for( ; ; ) { handle_key(); // read a key, maybe change mode, or hue/bri changemillisdiff = millis - changemillis; // FIXME: this could be refactored to be more efficient if( mode == MODE_RANDMOOD ) { if( changemillisdiff > MILLIS_MOOD ) { softuart_putsP("rhb:"); softuart_printHex(hue); softuart_putc(','); softuart_printHex(bri); softuart_putc('\n'); changemillis = millis; hue = rand(); } blinkm_setFadespeed( FADESPEED_RANDMOOD ); blinkm_fadeToHSB( hue, 255, bri ); } else if( mode == MODE_RANDFAST ) { if( changemillisdiff > MILLIS_FAST ) { changemillis = millis; hue = rand(); blinkm_setFadespeed( FADESPEED_RANDFAST ); blinkm_fadeToHSB( hue, 255, bri ); } blinkm_setFadespeed( FADESPEED_RANDFAST ); blinkm_fadeToHSB( hue, 255, bri ); } else if( mode == MODE_WHITE ) { blinkm_setFadespeed( FADESPEED_RANDMOOD ); blinkm_fadeToRGB( bri, bri, bri ); } else if( mode == MODE_HSB ) { blinkm_setFadespeed( FADESPEED_RANDMOOD ); blinkm_fadeToHSB( hue, 255, bri ); } else if( mode == MODE_FLASH ) { if( changemillisdiff > MILLIS_FAST ) { softuart_putsP("ms:"); softuart_printHex16(changemillisdiff); softuart_putc(','); softuart_printHex16(millis); softuart_putc('\n'); changemillis = millis; bri = (keyheld) ? 255 : (bri==0) ? 255:0; blinkm_setFadespeed( FADESPEED_RANDFAST ); blinkm_fadeToHSB( hue, 255, bri); } } else if( mode == MODE_FLASHONCE ) { if( changemillis == 0 ) { // start blinkm_setFadespeed( FADESPEED_RANDFAST ); blinkm_fadeToHSB( hue, 255, bri); changemillis = millis; } else if( changemillisdiff > MILLIS_FAST ) { //stop blinkm_fadeToHSB( 0,0,0); mode = MODE_OFF; changemillis = 0; } } } // for }
// // Parse the key presses from IR remote // static void handle_key(void) { if( (millis - keylast_millis) > KEYMILLIS_HOLD ) { keyheld = 0; } key = ir_getdata( buf ); if( key == 0 ) { // no IR data of any kind return; } else if( key == 1 ) { // got CtrlM 8-byte packet #if DEBUG >0 softuart_putsP("ctrlm:"); //softuart_printHex( buf[0] ); softuart_putc(','); // start byte 0x55 softuart_printHex( buf[1] ); softuart_putc(','); // freem_addr softuart_printHex( buf[2] ); softuart_putc(','); // blinkm_addr softuart_printHex( buf[3] ); softuart_putc(','); // blinkm_cmd softuart_printHex( buf[4] ); softuart_putc(','); // blinkm_arg1 softuart_printHex( buf[5] ); softuart_putc(','); // blinkm_arg2 softuart_printHex( buf[6] ); softuart_putc(':'); // blinkm_arg3 //softuart_printHex( buf[7] ); softuart_putc('\n'); // checksum #else statled_set(1); #endif mode = MODE_OFF; if( buf[2] == 0xff && buf[3] == 0xff ) { // set freem addr cmd softuart_putsP("new freem addr\n"); freem_addr = buf[1]; eeprom_write_byte( &ee_freem_addr, freem_addr ); // write address fanfare(5); // let people know we did the deed } else if( buf[1] == freem_addr || buf[1] == 0 ) { softuart_putsP("me!"); i2csendaddr = buf[2]; blinkm_sendCmd3( buf[3], buf[4], buf[5], buf[6] ); } #if DEBUG >0 softuart_putc('\n'); #else statled_set(0); #endif return; // done with data mode } // Otherwise, it's an RC code // okay, we have these cases: // no presses for long time, then keypress // hold-down key, same key every 50ms or so // press key, wait a little bit, press key again // press key, press another key if( key == keylast ) { // same key if( (millis - keylast_millis) < KEYMILLIS_MIN ) { // a repeat if( millis - keymillis > KEYMILLIS_HOLD ) { // since start of key keyheld = 1; } } else { // or press and press again, reset key start time keymillis = millis; } } else { // a new key, reset keymillis = millis; keyheld = 0; } keylast = key; keylast_millis = millis; #if DEBUG > 1 softuart_puts("k:"); softuart_printHex16( key ); softuart_putc('\n'); #else statled_set(1); #endif if( !(key == IRKEY_VOLUP || key == IRKEY_VOLDN) ) { blinkm_stopScript(); blinkm_setFadespeed( FADESPEED_DEFAULT ); } if( key == IRKEY_POWER ) { softuart_putsP("off\n"); mode = MODE_OFF; blinkm_turnOff(); } else if( key == IRKEY_CHUP ) { // increase hue, for current mode if( mode == MODE_OFF ) mode = MODE_HSB; hue+=2; softuart_putsP("h+:"); softuart_printHex(hue); softuart_putc('\n'); } else if( key == IRKEY_CHDN ) { // decrease hue, for current mode if( mode == MODE_OFF ) mode = MODE_HSB; softuart_putsP("h-:"); softuart_printHex(hue); softuart_putc('\n'); } else if( key == IRKEY_VOLUP ) { // increase brightness, for current mode if( mode == MODE_OFF ) mode = MODE_HSB; if( bri < 253 ) bri+=3; else bri = 255; softuart_putsP("b+:"); softuart_printHex(bri); softuart_putc('\n'); } else if( key == IRKEY_VOLDN ) { // increase brightness, for current mode if( mode == MODE_OFF ) mode = MODE_HSB; if( bri > 2 ) bri-=3; else bri = 0; softuart_putsP("b-:"); softuart_printHex(bri); softuart_putc('\n'); } else if( key == IRKEY_ONE ) { // mode: random mood light softuart_putsP("mood\n"); mode = MODE_RANDMOOD; if( bri == 0 ) bri = 255; // fix brightness on startup } else if( key == IRKEY_TWO ) { // mode: fast random softuart_putsP("rand\n"); mode = MODE_RANDFAST; if( bri == 0 ) bri = 255; // fix brightness on startup if( keyheld ) { // reset hue/bri on holding key hue = 0; bri = 255; } } else if( key == IRKEY_THREE ) { // mode: beacon flash softuart_putsP("flash\n"); mode = MODE_FLASH; if( keyheld ) { // reset hue/bri on holding key hue = 0; bri = 255; } } else if( key == IRKEY_FOUR ) { // mode: fixed color softuart_putsP("hsb\n"); mode = MODE_HSB; if( bri == 0 ) bri = 255; if( keyheld ) { // reset hue/bri on holding key softuart_putc('+'); hue+=2; } //blinkm_fadeToHSB( hue, 0xff, bri ); } else if( key == IRKEY_FIVE ) { // mode: single flash at color softuart_putsP("flash1\n"); mode = MODE_FLASHONCE; changemillis = 0; if( keyheld ) { // reset hue/bri on holding key hue = 0; bri = 255; } } else if( key == IRKEY_SIX ) { softuart_putsP("rand1\n"); mode = MODE_HSB; bri = rand(); hue = rand(); } else if( key == IRKEY_SEVEN ) { // low-white at vol up/dn brightness softuart_putsP("lwhite\n"); mode = MODE_WHITE; bri = 0x11; blinkm_fadeToRGB( bri, bri, bri ); } else if( key == IRKEY_EIGHT ) { // mid-white at vol up/dn brightness softuart_putsP("mwhite\n"); mode = MODE_WHITE; bri = 0x80; blinkm_fadeToRGB( bri, bri, bri ); } else if( key == IRKEY_NINE ) { // low-white at vol up/dn brightness softuart_putsP("white\n"); mode = MODE_WHITE; blinkm_fadeToRGB( bri, bri, bri ); if( keyheld ) { // make brighter on key hold bri += 10; // will just wrap around } } else if( key == IRKEY_ZERO ) { softuart_putsP("play0\n"); mode = MODE_PLAYSCRIPT; blinkm_setFadespeed( FADESPEED_DEFAULT ); blinkm_playScript( 0,0 ); } #if DEBUG > 0 #else statled_set(0); #endif key = 0; }