//========================================================================== // Project: Radio controlled dual 1 color led strip driver with sound sensor // Type: firmware // Name: main.c // Author: Etienne Meleard // Creation Date: 2013-02-01 // Tabsize: 4 //========================================================================== //============================== WARNING ==================================// //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!// // // // Fuses must be like SUT1 = 1, SUT0 = 1, CKSEL3 = 1, CKSEL2 = 0, // // CKSEL1 = 0 and CKSEL0 = 0 to ensure µC is using the crystal as clock // // (otherwise it uses the 8MHz internal clock), full swing mode is // // mandatory to acheive 8MHz operation. // // // // CKDIV8 fuse must not be set to avoid clock frequency divided by 8 // // // // Fuse set or = 1 means checked in ponyprog // // // //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!// //=========================================================================// // ================= Fuses ================= // /*FUSES = { // No success writing fuse this way, command line below ... .low = (FUSE_SUT1 & FUSE_SUT0 & FUSE_CKSEL3), .high = HFUSE_DEFAULT, .extended = EFUSE_DEFAULT, };*/ // Run avrdude -c usbasp -p m8 -U lfuse:w:0xc7:m -U hfuse:w:0xdf:m at first (-F may be needed) // ================ Includes =============== // #include #include #include #include // ================ Pinouts ================ // #define RX PORTD.bit0 #define RX_COMPLETE SIG_USART_RECV #define SOUND_ADC 7 #define ADDR0 PORTD.bit5 #define ADDR1 PORTD.bit6 #define ADDR2 PORTD.bit7 #define EVAL_STATE TIMER0_OVERFLOW #define OUT0 PORTB.bit1 #define LVL0 OCR1A #define OUT1 PORTB.bit2 #define LVL1 OCR1B #define LED PORTD.bit4 #define BLINK LED=1; _delay_ms(150); BLINK LED=0; _delay_ms(150) #define SDA PORTC.bit4 #define SCL PORTC.bit5 // ================ Globals ================ // #define MODE 0 #define MODE_FIXED 0 #define MODE_SOUND 1 #define FIXED_VALUE 1 #define FOO 2 // Must be big enough for 2 times the params volatile uint8_t params[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; volatile uint8_t addr = 0x00; volatile uint16_t rxbyte = 0x0000; volatile uint8_t received = 0x00; // ================ Functions ============== // void init(void) { // USART UCSRA = 0x00; UCSRB = 0x90; // Rx enable and Rx irq enable UCSRC = 0xa6; // 8 bits, 1 stop bit, even parity UBRR = 103; // 4800 baud // ADC (sound sensor) ADMUX = 0x00 | SOUND_ADC; // Ext ref and channel ADCSRA = 0xef; // Enable, start, free running, irq enable, prescaler=128 : 4807conv/s // Address inputs DDRD &= 0x1f; PORTD |= 0xe0; // Pull-up // State timer TCCR0 = 0x05; // Prescaler=1024 : 30irq/s TIMSK |= 0x01; // Irq enable // Outputs DDRB |= 0x06; // PWM Timer TCCR1A = 0xa1; // Phase and frequency correct PWM TCCR1B = 0x14; // mode, prescaler=256 : 122Hz ICR = 0x007f; // 128 levels // Led DDRB |= 0x10; // I2C DDRC |= 0x30; } // Read params from EEPROM void loadParams(void) { uint8_t param; for(param=0; param<16; idx++) { while(EECR & (1<> 4; if(rxaddr && (rxaddr != addr)) return; // not for me p = rxbyte & 0x000f; // get param index with out multiplier v = UDR & 0x7f; // get value params[p] = v; // set param writeParam(p, v); // save param for future restarts if(!rxaddr) { // if broadcast value must be set for both outputs params[8 + p] = v; writeParam(8 + p, v); } rxbyte = 0x0000; received = 1; // signal rx } // else we just had a second byte without the first one, we discard it }else rxbyte = 0xff00 + UDR; // byte 0 } SIGNAL(EVAL_STATE) { // 30Hz evalState(0); evalState(1); } // ================== Main ================= // int main(void) { uint8_t a; cli(); // WatchDog disabled AT ALL TIMES ! init(); loadParams(); sei(); BLINK; BLINK; while(1) { if(received) { // Signal received byte received = 0; BLINK; } // Get addr a = 0x00; if(!ADDR0) a += 1; if(!ADDR1) a += 2; if(!ADDR2) a += 4; addr = a; _delay_ms(10); } return 0; }