void initIO(void) { //SET OUTPUTS //Servo channels as outputs DDRB |= (1 << PIN0) | (1 << PIN1) | (1 << PIN2) | (1 << PIN3) | (1 << PIN4); DDRD |= (1 << PIN0) | (1 << PIN1) | (1 << PIN2) | (1 << PIN3) | (1 << PIN4) | (1 << PIN5) | (1 << PIN6); //LED as ouput DDRB |= (1 << PIN6); //LED on PORTB |= (1 << PIN6); _delay_ms(500); PORTB &= ~(1 << PIN6); InitTimer1(); StartTimer1(); cli(); // Disable interrupts usiTwiSlaveInit(SLAVE_ADDR_ATTINY); // TWI slave init sei(); // Re-enable interrupts }
void processTWI( void ) { uint8_t b,p1,p2; b = usiTwiReceiveByte(); switch (b) { case 0x81: // set slave address p1 = usiTwiReceiveByte(); if(p1 < 128) // Address is 7 bit { eeprom_update_byte(&b_slave_address, p1); usiTwiSlaveInit(eeprom_read_byte(&b_slave_address)); } break; case 0x82: // clear led led_clear(); break; case 0x83: // set led brightness, p1=led, p2=brightness p1 = usiTwiReceiveByte(); p2 = usiTwiReceiveByte(); set_led_pulse(p1,0); // Turn off pulsing set_brightness(p1,p2); break; case 0x84: // Set to pulse led, p1=led, p2 = (0 = OFF, 1 = ON) set_led_pulse(usiTwiReceiveByte(),usiTwiReceiveByte()); break; case 0x85: // Dim up/down led to specific value, p1=led, p2=value to dim to dim_led(usiTwiReceiveByte(),usiTwiReceiveByte()); break; case 0x86: // get firmware revision usiTwiTransmitByte(FIRMWARE_REVISION); break; case 0x90: // get keyUp Event usiTwiTransmitByte(getKeyUp()); break; case 0x91: // get KeyDown Event usiTwiTransmitByte(getKeyDown()); break; case 0x92: // set keyrepeat set_keyrepeat(usiTwiReceiveByte(),usiTwiReceiveByte()); break; case 0xFE: // reset to known state led_clear(); button_init(); flushTwiBuffers(); break; case 0xFF: // flush the bus break; default: break; } }
/*############################################################################## RGB-CTL · 2011 Florian Knodt <*****@*****.**> TWI-Stuff based on: USI TWI Slave driver 1.3 Martin Junghans <*****@*****.**> Markus Schatzl RGB-Stuff based on: moodlamp-rf - fnordlicht firmware next generation Alexander Neumann <*****@*****.**> Lars Noschinski <*****@*****.**> Kiu Mazzoo Tobias Schneider([email protected]) Soft-PWM - http://www.mikrocontroller.net/articles/Soft-PWM This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. For more information on the GPL, please go to: http://www.gnu.org/copyleft/gpl.html //# CONFIGURATION ############################################################*/ // TWI Address (LSB must be 0!) // Define is inside the Makefile #define SLAVE_ADDR_ATTINY TWI_ADDRESS //# IMPORT LIBS ##############################################################*/ #include <stdlib.h> #include <avr/io.h> #include <avr/interrupt.h> #include <avr/pgmspace.h> #include <avr/wdt.h> #include <avr/sleep.h> #include "usiTwiSlave.h" #ifndef F_CPU #define F_CPU 8000000UL #endif //# MACROS ###################################################################*/ #define uniq(LOW,HEIGHT) ((HEIGHT << 8)|LOW) // Create 16 bit number from two bytes #define LOW_BYTE(x) (x & 0xff) // Get low byte from 16 bit number #define HIGH_BYTE(x) ((x >> 8) & 0xff) // Get high byte from 16 bit number #define sbi(ADDRESS,BIT) ((ADDRESS) |= (1<<(BIT))) // Set bit #define cbi(ADDRESS,BIT) ((ADDRESS) &= ~(1<<(BIT))) // Clear bit #define toggle(ADDRESS,BIT) ((ADDRESS) ^= (1<<BIT)) // Toggle bit #define bis(ADDRESS,BIT) (ADDRESS & (1<<BIT)) // Is bit set? #define bic(ADDRESS,BIT) (!(ADDRESS & (1<<BIT))) // Is bit clear? //# GLOBAL VARS ##############################################################*/ uint8_t fade[3] = {0,0,0}; //Color fade delay uint8_t target[3] = {0,0,0}; //Target color uint8_t color[3] = {0,0,0}; //Active color uint16_t colort[3] = {0,0,0}; //Timer compare for active color volatile uint8_t pwmstate=0; //Used to detect a completed PWM-Cycle volatile uint16_t pwm_cnt=0; //PWM-Cycle counter ISR(TIMER1_COMPA_vect) { TCNT1 = 0; if (colort[0] <= pwm_cnt) cbi(PORTB, PB1); if (colort[1] <= pwm_cnt) cbi(PORTB, PB3); if (colort[2] <= pwm_cnt) cbi(PORTB, PB4); if (pwm_cnt>=768) { pwm_cnt=0; pwmstate=0; if(colort[0] != 0) sbi(PORTB, PB1); if(colort[1] != 0) sbi(PORTB, PB3); if(colort[2] != 0) sbi(PORTB, PB4); } else pwm_cnt++; } void i2c_process(void) { //###Process incoming I²C-Data### //Target Colors if(twibuffer[0]<=170) target[0] = twibuffer[0]; if(twibuffer[1]<=170) target[1] = twibuffer[1]; if(twibuffer[2]<=170) target[2] = twibuffer[2]; //Fade type fade[0] = twibuffer[3]; fade[1] = twibuffer[4]; fade[2] = twibuffer[5]; //###Write new values to twibuffer so we can read current status### twibuffer[6] = color[0]; twibuffer[7] = color[1]; twibuffer[8] = color[2]; twibuffer[9] = LOW_BYTE(colort[0]); twibuffer[10] = HIGH_BYTE(colort[0]); twibuffer[11] = LOW_BYTE(colort[1]); twibuffer[12] = HIGH_BYTE(colort[1]); twibuffer[13] = LOW_BYTE(colort[2]); twibuffer[14] = HIGH_BYTE(colort[2]); } void pwm_update(void) { //wait until current pwm-sequence is completed pwmstate=1; while(pwmstate != 0) { set_sleep_mode(SLEEP_MODE_IDLE); sleep_mode(); } } //# MAIN LOOP ################################################################*/ int main(void) { /* Red = PB1 Green = PB3 Blue = PB4 */ uint8_t wait[3]={0,0,0}; //Fading delay temp storage uint8_t i=0; //Color processing loop temp storage static const uint16_t timeslot_table[] PROGMEM = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 10, 10, 11, 11, 11, 12, 13, 13, 14, 14, 15, 16, 16, 17, 18, 19, 19, 20, 21, 22, 23, 24, 25, 26, 27, 29, 30, 31, 32, 34, 35, 37, 39, 40, 42, 44, 46, 48, 50, 52, 55, 57, 60, 62, 65, 68, 71, 74, 77, 81, 84, 88, 92, 96, 100, 105, 109, 114, 119, 125, 130, 136, 142, 148, 155, 161, 169, 176, 184, 192, 200, 209, 219, 228, 238, 249, 260, 272, 284, 296, 309, 323, 337, 352, 368, 384, 401, 419, 437, 457, 477, 498, 520, 543, 567, 592, 618, 646, 674, 704, 735, 768 }; //Values 0 - 170 cli(); //Disable interrupts wdt_enable(WDTO_500MS); //Enable Watchdog DDRB = 0xFF; //Port = out PORTB = 0x00; //LEDs off usiTwiSlaveInit(SLAVE_ADDR_ATTINY); //TWI slave init sbi(TCCR1,CS10); //Timer without Prescaler OCR1A = 128; //PWM-Clock TIMSK |= (1<<OCIE1A); //Enable T1 Compare Interrupt sei(); //Enable Interrupts while(1) { wdt_reset(); //Watchdog reset i2c_process(); //Read I²C and write current status //Fading and PWM-programming for(i=0; i<=2; i++) { if(target[i] != color[i]) { if(fade[i] == 0) { color[i]=target[i]; }else{ if(wait[i] >= fade[i]) { if(target[i] > color[i]) color[i]++; else color[i]--; wait[i]=0; }else wait[i]++; } colort[i]=pgm_read_word(×lot_table[color[i]]); } } wdt_reset(); pwm_update(); //Controller waits there until one PWM-cycle has completed } }
int main() { // set digits as output and disable them all DIG1_DDR |= _BV(DIG1_PIN); DIG2_DDR |= _BV(DIG2_PIN); DIG3_DDR |= _BV(DIG3_PIN); DIG4_DDR |= _BV(DIG4_PIN); light_digit(0); // setup all segments as inputs and low SEG_A_DDR &= ~_BV(SEG_A_PIN); SEG_B_DDR &= ~_BV(SEG_B_PIN); SEG_C_DDR &= ~_BV(SEG_C_PIN); SEG_D_DDR &= ~_BV(SEG_D_PIN); SEG_E_DDR &= ~_BV(SEG_E_PIN); SEG_F_DDR &= ~_BV(SEG_F_PIN); SEG_G_DDR &= ~_BV(SEG_G_PIN); SEG_A_PORT &= ~_BV(SEG_A_PIN); SEG_B_PORT &= ~_BV(SEG_B_PIN); SEG_C_PORT &= ~_BV(SEG_C_PIN); SEG_D_PORT &= ~_BV(SEG_D_PIN); SEG_E_PORT &= ~_BV(SEG_E_PIN); SEG_F_PORT &= ~_BV(SEG_F_PIN); SEG_G_PORT &= ~_BV(SEG_G_PIN); // set DP as output and to ground SEG_DP_DDR |= _BV(SEG_DP_PIN); SEG_DP_PORT &= ~_BV(SEG_DP_PIN); // set up timer 1 as system clock TIMSK = (1 << TOIE0); // overflow interrupts TCCR0B = TIMER0_CLKDIV_488Hz; // default blink rate at 488Hz // init the TWI slave usiTwiSlaveInit(SLAVE_ADDRESS); // enable interrupts sei(); // The infinite loop while (1) { // process Twi commands while (usiTwiDataInReceiveBuffer()) { processTWI(); } } }
void setup() { // Init USI TWI Slave and enable interrupts usiTwiSlaveInit(NESPAD_SLAVE_ADDRESS, i2cReadFromRegister, i2cWriteToRegister); sei(); // clock / latch pair for gamepad 1 bit_set(DDRD, BIT(NES_CLOCK_1)); bit_set(DDRD, BIT(NES_LATCH_1)); // clock / latch pair for gamepad 2 bit_set(DDRB, BIT(NES_CLOCK_2)); bit_set(DDRB, BIT(NES_LATCH_2)); // shared data pin for all gamepads bit_clr(DDRD, BIT(NES_DATA)); }
int main() { // Set the LED pin as output. DDRB |= (1 << LED); usiTwiSlaveInit(I2C_SLAVE_ADDR, i2cReadFromRegister, i2cWriteToRegister); adcInit(); sei(); while (1) { // This is a pretty pointless example which allows me to test writing to two i2c registers: the // LED is only lit if both registers have the same value. if (i2cReg2 == i2cReg3) PORTB |= 1 << LED; else PORTB &= ~(1 << LED); } }
int main(void) { TRIG_DDR |= 1<<TRIG_BIT; HALF_DDR |= 1<<HALF_BIT; LED_DDR |= 1<<LED_BIT; DDRB |= (1<<PB3 | 1<<PB4); /* configure timer for PWM */ ICR1 = 20000; TCCR1A = (1<<COM1A1)|(1<<COM1B1)|(1<<WGM11); TCCR1B = (1<<WGM13)|(1<<WGM12)|(1<<CS11); cam.enabled = 0; cam.interval = SNAPSHOT_INTERVAL; cam.servo_pos[0] = 127; cam.servo_pos[1] = 127; usiTwiSlaveInit(TWI_ADDRESS); usiTwiSetTransmitWindow( &cam, sizeof(cam) ); sei(); while (1) { OCR1B = SERVO_MIN+((uint16_t)cam.servo_pos[0]*(SERVO_MAX-SERVO_MIN)/255); OCR1A = SERVO_MIN+((uint16_t)cam.servo_pos[1]*(SERVO_MAX-SERVO_MIN)/255); if (cam.enabled) { LED_PORT |= (1<<LED_BIT); waylay(&cam.interval); LED_PORT &= ~(1<<LED_BIT); set_btn(HALF); _delay_ms(SNAPSHOT_FOCUS_MS); set_btn(PRESSED); _delay_ms(BTN_MS); set_btn(RELEASED); LED_PORT |= (1<<LED_BIT); } else { LED_PORT &= ~(1<<LED_BIT); } } }
void init(void) { cli(); // disable interrupts led_init(); button_init(); _delay_ms(1); // Check for magic reset sequence if ((~BUTTON_PIN & (_BV(BUTTON1_BIT) | _BV(BUTTON2_BIT) | _BV(BUTTON5_BIT))) == (_BV(BUTTON1_BIT) | _BV(BUTTON2_BIT) | _BV(BUTTON5_BIT))) { // Do a reset init_EEPROM(); for(uint8_t i = 0; i < 4; i++) { cbi(LED1_PORT, LED1_BIT); _delay_ms(125); sbi(LED1_PORT, LED1_BIT); _delay_ms(125); } } uint8_t stored_address = eeprom_read_byte(&b_slave_address); // Check that stored_address is sane otherwise fallback to factory default if (stored_address >= 128) stored_address = SLAVE_ADDRESS; usiTwiSlaveInit(stored_address); // Inititalize timer0 for led multiplexing TCCR0B = (1<<CS01); // Set Prescaler to clk/8 : 1 click = 1us. CS01=1 TIMSK0 |= (1<<TOIE0); // Enable Overflow Interrupt Enable TCNT0 = 0; // Initialize counter // Inititalize timer1 for led multiplexing TCCR1B = (1<<CS11); // Set Prescaler to clk/8 : 1 click = 1us. CS01=1 TIMSK0 |= (1<<TOIE1); // Enable Overflow Interrupt Enable TCNT1 = 0; // Initialize counter sei(); // enable interrupts }
//################################################################# Main routine int main(void) { // Initiate the TWI for ATTiny cli(); // Disable interrupts usiTwiSlaveInit(SLAVE_ADDR_ATTINY); // TWI slave init sei(); // Re-enable interrupts ADC_init(); // The data you want to be sent to 328p is saved in txbuffer[] // Ex: while(1){ txbuffer[0] = Read_ADC(3); _delay_ms(1000); } }
int main(void) { uint8_t count; count = 0; usiTwiSlaveInit( SLAVE_ADRS ); // Initialize TWI hardware for Slave operation. sei(); // Enable interrupts. usiTwiSlaveEnable(); // Enable the TWI interface to receive data. while(1) { if( !usiTwiDataInTransmitBuffer() ) { usiTwiTransmitByte( count ); // stuff count into TxBuf[] ++count; // inc for next value. } } }
int main(void) { //********** Initiate variables ********* adcArray[0] = 4; // Device ID for Flexiforce 301A adcArray[1] = 0; adcArray[2] = 0; //********** Initialization ********** usiTwiSlaveInit( slaveadress ); // Enable TWI I2C and set static slave address InitADC(); // Init ADC sei(); // Init global interupt //********** Main functions ********** while(1) { if(!ADC_flag) { adcArray[1] = ADCL; adcArray[2] = ADCH; ADC_flag = 0; } while(!usiTwiDataInReceiveBuffer()); // Wait for master usiTwiTransmitByte(adcArray[0]); // Send sensor ID while(!usiTwiDataInReceiveBuffer()); // Wait for master usiTwiTransmitByte(adcArray[1]); // Send low part of sensordata while(!usiTwiDataInReceiveBuffer()); // Wait for master usiTwiTransmitByte(adcArray[2]); // Send high part of sensordata } return 0; }
void TinyWire::begin(uint8_t i2c_slave_address) { usiTwiSlaveInit(i2c_slave_address, _on_request_handler, _on_receive_handler); this->type = 0xFF; }
void USI_TWI_S::begin(uint8_t slaveAddr){ // initialize I2C lib usiTwiSlaveInit(slaveAddr); twi_attachSlaveTxEvent(onRequestService); }
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
// // called infinitely in main() along with handle_script() // static void handle_i2c(void) { //uint8_t tmp; //int8_t baddr; if( usiTwiDataInReceiveBuffer() ) { cmd = usiTwiReceiveByte(); myaddr = slaveAddressMatched; slaveAddressMatched = -1; switch(cmd) { case('@'): // set addr to send to {'@',freemaddr,i2caddr,0} case('#'): // script cmd: set ir pwm frequency & duty cycle case('%'): // IR light on/off case('&'): // packet_wait_millis, wait_after read_i2c_vals(3); // all these take 3 args handle_script_cmd(); break; case('$'): // script cmd: send ir code read_i2c_vals(5); if( cmdargs[0] == 0 ) { // FIXME: 0 == sony command type //uint32_t data = *(cmdargs+1); IRsend_sendSony( (cmdargs[1]<<8) | cmdargs[2],12 ); // FIXME } else if( cmdargs[0] == 1 ) { // 1 == RC5 IRsend_sendSony( (cmdargs[1]<<8) | cmdargs[2],12 ); // FIXME } break; case('!'): // send arbitrary i2c data read_i2c_vals(8); IRsend_sendSonyData64bit( cmdargs ); //fanfare(3, 100 ); break; case('^'): // set colorspot {'^', 13, r,g,b } read_i2c_vals(4); cmdargs[6] = cmdargs[3]; // b cmdargs[5] = cmdargs[2]; // g cmdargs[4] = cmdargs[1]; // r cmdargs[3] = cmdargs[0]; // pos cmdargs[2] = 0xfe; // 0xfe == set colorspot cmdargs[1] = freem_addr; cmdargs[0] = 0x55; // magic start byte cmdargs[7] = compute_checksum(cmdargs,7); //IRsend_sendSonyData64bit( cmdargs ); ir_queue( cmdargs ); break; case('*'): // play colorspot {'*', 13, 0, 0 } read_i2c_vals(3); handle_script_cmd(); /* tmp = blinkm_addr; // FIXME: bit of a hack here blinkm_addr = 0xfd; // 0xfd == play colorspot cmd = cmdargs[0]; cmdargs[0] = cmdargs[1]; cmdargs[1] = cmdargs[2]; //cmdargs[2] = cmdargs[3]; // no, only have 3 args to use handle_script_cmd(); blinkm_addr = tmp; */ break; // stolen from blinkm.c case('a'): // get address usiTwiTransmitByte( eeprom_read_byte(&ee_i2c_addr) ); break; case('A'): // set address cmdargs[0] = cmdargs[1] = cmdargs[2] = cmdargs[3] = 0; read_i2c_vals(4); // address, 0xD0, 0x0D, address if( cmdargs[0] != 0 && cmdargs[0] == cmdargs[3] && cmdargs[1] == 0xD0 && cmdargs[2] == 0x0D ) { // eeprom_write_byte( &ee_i2c_addr, cmdargs[0] ); // write address i2c_addrs[0] = cmdargs[0]; for( uint8_t i = 1; i<slaveAddressesCount; i++ ) { i2c_addrs[i] = i2c_addrs[0] + i; } usiTwiSlaveInit( i2c_addrs ); // re-init _delay_ms(5); // wait a bit so the USI can reset } break; case('Z'): // return protocol version usiTwiTransmitByte( BLINKM_PROTOCOL_VERSION_MAJOR ); usiTwiTransmitByte( BLINKM_PROTOCOL_VERSION_MINOR ); break; case('P'): // play ctrlm script read_i2c_vals(3); play_script(0, cmdargs[1], cmdargs[2]); break; // blinkm cmds case('n'): // script cmd: set rgb color now case('c'): // script cmd: fade to rgb color case('C'): // script cmd: fade to random rgb color case('h'): // script cmd: fade to hsv color case('H'): // script cmd: fade to random hsv color case('p'): // script cmd: play script read_i2c_vals(3); handle_script_cmd(); break; case('f'): case('t'): read_i2c_vals(1); handle_script_cmd(); case('o'): case('O'): handle_script_cmd(); break; // // new v2 commands // case('l'): // return script len & reps read_i2c_vals(1); // script_id if( cmdargs[0] == 0 ) { // eeprom script usiTwiTransmitByte( eeprom_read_byte( &ee_script.len ) ); usiTwiTransmitByte( eeprom_read_byte( &ee_script.reps ) ); } else { //script* s=(script*)pgm_read_word(&(fl_scripts[cmdargs[1]-1])); //curr_script_len = pgm_read_byte( (&s->len) ); //curr_script_reps = pgm_read_byte( (&s->reps) ); } case('i'): // return current input values //usiTwiTransmitByte( myaddr ); // FIXME FIXME TEST usiTwiTransmitByte( timesOver ); // FIXME FIXME TEST //usiTwiTransmitByte( inputs[0] ); usiTwiTransmitByte( inputs[1] ); usiTwiTransmitByte( inputs[2] ); usiTwiTransmitByte( inputs[3] ); break; } // switch(cmd) } // if(usiTwi) }
//----- Begin Code ------------------------------------------------------------ int main(void) { static uint8_t f_i2c; static bool f_recieve; static uint8_t rbuf[8], *p, temp; static uint8_t state = S_NORMAL; // TIMER1の設定 init_timer1(); f_i2c = check_I2C(); if (f_i2c) { // I2C スレーブ初期化 usiTwiSlaveInit( TWI_slaveAddress ); } else { // 2313標準UARTの初期化 uart2313_init(); } // LCD初期化 lcd_init(LCD_DISP_ON); lcdMapCustomChar(0, 0); lcdMapCustomChar(1, 1); lcdMapCustomChar(2, 2); lcdMapCustomChar(3, 3); lcdMapCustomChar(4, 4); lcdMapCustomChar(5, 5); lcdMapCustomChar(6, 6); lcdMapCustomChar(7, 7); lcd_gotoxy(0, 0); // any logos? // write something lcd_puts_P("I2CLCD"); if (f_i2c) { //1234567890123456 lcd_puts_P("-I"); } else { //1234567890123456 lcd_puts_P("-S"); } sei(); while (1) { if (f_i2c) { f_recieve = usiTwiDataInReceiveBuffer(); if (f_recieve) { temp = usiTwiReceiveByte(); } } else { f_recieve = xreadOK(); if (f_recieve) { temp = xread(); } } if (f_recieve) { switch (state) { case S_NORMAL: if (temp == ESC) { state = S_SEQUENCE; } else { lcd_putc(temp); } break; case S_SEQUENCE: p = rbuf; *p = temp; switch (temp) { case 'L': // L for Locate (X), (Y) state = S_L1; break; case 'H': // ホームポジションへカーソル移動 lcd_home(); state = S_NORMAL; break; case 'C': // 画面クリア lcd_clrscr(); state = S_NORMAL; break; case 'S': // S for Save Custom Character to EEPROM state = S_S1; break; case 'M': // M for Custom Character Mapping state = S_M1; break; case 'X': // 画面非表示 /* display off */ lcd_command(LCD_DISP_OFF); state = S_NORMAL; break; case 'N': // 画面表示・カーソル消去 /* display on, cursor off */ lcd_command(LCD_DISP_ON); state = S_NORMAL; break; case 'B': // 画面表示・カーソル非表示・ブリンク文字 /* display on, cursor off, blink char */ lcd_command(LCD_DISP_ON_BLINK); state = S_NORMAL; break; case 'D': // 画面表示・カーソル表示 /* display on, cursor on */ lcd_command(LCD_DISP_ON_CURSOR); state = S_NORMAL; break; case 'E': // 画面表示・カーソル表示・ブリンク文字 /* display on, cursor on, blink char */ lcd_command(LCD_DISP_ON_CURSOR_BLINK); state = S_NORMAL; break; case '-': // カーソル左移動 /* move cursor left (decrement) */ lcd_command(LCD_MOVE_CURSOR_LEFT); state = S_NORMAL; break; case '+': // カーソル右移動 /* move cursor right (increment) */ lcd_command(LCD_MOVE_CURSOR_RIGHT); state = S_NORMAL; break; case '<': // 画面左移動 /* shift display left */ lcd_command(LCD_MOVE_DISP_LEFT); state = S_NORMAL; break; case '>': // 画面右移動 /* shift display right */ lcd_command(LCD_MOVE_DISP_RIGHT); state = S_NORMAL; break; } break; case S_L1: *++p = temp; state = S_L2; break; case S_L2: // *++p = temp; lcd_gotoxy(rbuf[1], temp); state = S_NORMAL; break; case S_M1: *++p = temp; state = S_M2; break; case S_M2: // *++p = temp; lcdMapCustomChar(rbuf[1],temp); state = S_NORMAL; break; // ----------------------------- case S_S1: *++p = temp; state = S_S2; break; case S_S2: rCustom[0] = temp; // *++p = temp; state = S_S3; break; case S_S3: rCustom[1] = temp; // *++p = temp; state = S_S4; break; case S_S4: rCustom[2] = temp; // *++p = temp; state = S_S5; break; case S_S5: rCustom[3] = temp; // *++p = temp; state = S_S6; break; case S_S6: rCustom[4] = temp; // *++p = temp; state = S_S7; break; case S_S7: rCustom[5] = temp; // *++p = temp; state = S_S8; break; case S_S8: rCustom[6] = temp; // *++p = temp; state = S_S9; break; case S_S9: rCustom[7] = temp; // *++p = temp; lcdSaveCustomChar(rbuf[1]); state = S_NORMAL; break; } } } return 0; }
/*! @brief main program of the I2C-slave Initializes the timer/counters and the I2C. Constantly updates the duty cycles of the PPM @return int */ int main(void) { int i; cli(); // Disable interrupts usiTwiSlaveInit(SLAVE_ADDR_ATTINY); // TWI slave init //Initialize rxbuffer rxbuffer[0] = HIGH_BYTE( (dutyCycles[0] - 1*8192) ); rxbuffer[1] = LOW_BYTE( (dutyCycles[0] - 1*8192) ); rxbuffer[2] = HIGH_BYTE( (dutyCycles[1] - 2*8192) ); rxbuffer[3] = LOW_BYTE( (dutyCycles[1] - 2*8192) ); rxbuffer[4] = HIGH_BYTE( (dutyCycles[2] - 3*8192) ); rxbuffer[5] = LOW_BYTE( (dutyCycles[2] - 3*8192) ); rxbuffer[6] = HIGH_BYTE( (dutyCycles[3] - 0*8192) ); rxbuffer[7] = LOW_BYTE( (dutyCycles[3] - 0*8192) ); ppmInit(); sei(); // Re-enable interrupts while(1) { /* receivedNewValue is updated whenever a new value is written to the rxbuffer with the corresponding index As always 2 bytes are used for one dutyCycle the interesting values are 1, 3, 5, 7 Then the corresponding value in the dutyCycle array is updated The new value for a dutyCycle is calculated first in a temp-variable. In a previous version it was directly assigned within the atomic block which caused severs problems that the ucontroller stopped responding to the I2C-master. Therefore now only the assignment to dutyCycles[x] is done in atomic block */ uint16_t temp; switch (receivedNewValue) { case 1: //update dutyCycle for channel 0 receivedNewValue = 0; temp = uniq(rxbuffer[1], rxbuffer[0]) + 1 * 8192; ATOMIC_BLOCK(ATOMIC_FORCEON) { dutyCycles[0] = temp; } txbuffer[0] = rxbuffer[0]; txbuffer[1] = rxbuffer[1]; break; case 3: //update dutyCycle for channel 1 receivedNewValue = 0; temp = uniq(rxbuffer[3], rxbuffer[2]) + 2 * 8192; ATOMIC_BLOCK(ATOMIC_FORCEON) { dutyCycles[1] = temp; } txbuffer[2] = rxbuffer[2]; txbuffer[3] = rxbuffer[3]; break; case 5: //update dutyCycle for channel 2 receivedNewValue = 0; temp = uniq(rxbuffer[5], rxbuffer[4]) + 3 * 8192; ATOMIC_BLOCK(ATOMIC_FORCEON) { dutyCycles[2] = temp; } txbuffer[4] = rxbuffer[4]; txbuffer[5] = rxbuffer[5]; break; case 7: //update dutyCycle for channel 3 receivedNewValue = 0; temp = uniq(rxbuffer[7], rxbuffer[6]) + 0 * 8192; ATOMIC_BLOCK(ATOMIC_FORCEON) { dutyCycles[3] = temp; } txbuffer[6] = rxbuffer[6]; txbuffer[7] = rxbuffer[7]; break; } //end.switch } //end.while } //end.main
void USI_TWI_S::begin(uint8_t slaveAddr) { // initialize I2C lib usiTwiSlaveInit(slaveAddr); }
int main(void) { uint8_t data; uint8_t blinkDelay = BLINK_DELAY; bool blinkToggle = false; pState = PS_IDLE; mCounter = 0; mod_led_init(); st_init_tmr0(); usiTwiSlaveInit( SLAVE_ADRS ); // Initialize USI hardware for I2C Slave operation. mod_led_toggle(4); sei(); // Enable interrupts. usitwiSlaveEnable(); // Enable the USI interface to receive data. mod_led_toggle(3); // A simple loop to check for I2C Commands. // A state variable is needed to process multi-byte messages. // 01, 05 are Writes. 04 is a Read. while(1) { #if 0 // Heart Beat LED if( GPIOR0 & (1<<DEV_1MS_TIC) ) { GPIOR0 &= ~(1<<DEV_1MS_TIC); if(--blinkDelay == 0) { blinkDelay = BLINK_DELAY; if(blinkToggle) { mod_led_on(); } else { mod_led_off(); } blinkToggle = !blinkToggle; } } #endif //mod_led_toggle(2); if( usiTwiDataInReceiveBuffer() ) { data = usiTwiReceiveByte(); switch (pState) { case PS_IDLE: // Process new message ++mCounter; switch(data) { case 01: // Writing to the Control Register pState = PS_CMD01_0; // next byte is Control byte break; case 04: // Reading counter usiTwiTransmitByte(mCounter); // load up data for following read. break; case 05: // Writing to LED pState = PS_CMD05_0; // next byte controls LED break; default: break; // Ignore unknown command. } break; case PS_CMD01_0: // Process Control byte. b0=1 clears counter. if( (data & 0x01) == 0x01 ) { mCounter = 0; } pState = PS_IDLE; // reset for next message break; case PS_CMD05_0: // Change LED state // If the data is 00, then turn OFF the LED. Turn it ON for any non-zero value. // NOTE: LED hardware is wired 'Active LOW'. if( data == 0) { mod_led_off(); // Turn LED OFF. } else { mod_led_on(); // Turn LED ON. } pState = PS_IDLE; // reset for next message break; default: pState = PS_IDLE; // ERROR, restore to know state break; } } } }