///********IMPORTANT DEFINES************* #define F_CPU 8000000UL //CPU-Freq. #define I2C_ADDR 0x4E //I2C-Slave-Address; #define __ZACWIRE_INT1 //Define which Interrupt and Pin to use (either INT0 with PD2 or INT1 with PD3) ///////////////////////////////////////// //#define __OPTIMIZE__ #include #include #include #include #include #define LED_PORT PORTB #define LED_DDR DDRB void Init_Zacwire(void); void Init_I2C(int address); volatile uint8_t ZACWIRE_Bits; // ZACwire bit counter volatile uint8_t TEMP_Byte1; volatile uint8_t TEMP_Byte2; volatile uint16_t strobeTimeH = 0; volatile uint16_t strobeTimeL = 0; enum TSIC_STATUS_TYPE { SYNC_NEEDED, PREPARE_STROBE, DETERMINE_STROBE, READY }; volatile enum TSIC_STATUS_TYPE TSIC_STATUS = SYNC_NEEDED; volatile uint8_t byte1; volatile uint8_t byte2; volatile uint8_t parity1; volatile uint8_t parity2; ////**********ZACWIRE DEFINES******************* #define ZACWIRE_PORT PORTD // port register (out) #define ZACWIRE_PIN PIND // pin register (in) #define ZACWIRE_DDR DDRD // data direction register #define ZACWIRE_TIMERDELAY 8 //Due to multitasking the timer doesn't always fire soon enough, so decrease the waiting time by shifting the low time right #ifdef __ZACWIRE_INT1 #define ZACWIRE_INTERRUPT INT1 //Interrupt used by Zacwire #define ZACWIRE_VEC INT1_vect //ISR for port at which ZACCwire pin is located (set corresponding to INT above) #define ZACWIRE_EICRA_FALLING (1<>2); break; //Rising edge (=ongoing packet transmission) detected and zacwire is not in sync //Reset the timer case SYNC_NEEDED: ZACWIRE_TIMER_DISABLE_OVF; ZACWIRE_TIMER_RESET; ZACWIRE_TIMER_ENABLE_OVF; break; //Falling edge within a valid packet transmission. Prepare Timer for CTC-Match //with previously determined strobe-time case READY: DEBUG_AN(0); ZACWIRE_EXTINT_DISABLE; ZACWIRE_TIMER_DISABLE_OCM; //OCR1AH = strobeTimeH; //OCR1AL = strobeTimeL; //uint16_t temp =strobeTimeH*256+strobeTimeL; //OCR1A = strobe-100; //temp-100; //strobeTimeH*256+strobeTimeL;//490; // LED_PORT = ~(temp>>8); //OCR1AH = strobeTimeH; //strobeTimeH; // OCR1AL = strobeTimeL; OCR1A = 460; ZACWIRE_TIMER_RESET; ZACWIRE_TIMER_ENABLE_OCM; break; } } //Used during synchronisation. The timer will be reset on every rising edge (=ongoing transmission) //The timer will overflow and fire when no edge (=no transmission) was detected during the last //~8ms (1 complete transmission takes ~2.7ms with ~97ms pause between transmissions). //Now we can be sure to be between 2 transmissions, the next falling edge will be the //start bit of the 1st-byte. ISR(TIMER1_OVF_vect) { ZACWIRE_Bits = 0; ZACWIRE_TIMER_DISABLE_OVF; TSIC_STATUS = PREPARE_STROBE; ZACWIRE_EXTINT_FALLING; } //increment when parity error occurs volatile uint8_t errorcounter ; //Fires when the strobetime elapsed since the last falling edge (start of bit) ISR(TIMER1_COMPA_vect) { uint8_t pinstate; ZACWIRE_TIMER_DISABLE_OCM; ZACWIRE_EXTINT_DISABLE; // sample pin (in middle of bit window) pinstate = (ZACWIRE_PIN & ZACWIRE_BUSMASK); switch (++ZACWIRE_Bits) { case 1: // bit 1 is start bit of first byte //we will never get here because this will be handled by the EXTINT ISR /* byte1=0; byte2=0; parity1=0; parity2=0;*/ break; case 10: // bit 10 is parity bit of byte 1 if (pinstate) ++parity1; //Prepare to get strobe time for next byte TSIC_STATUS = PREPARE_STROBE; break; case 11: // bit 11 is start bit of second byte (ignore) break; case 20: // bit 20 is parity bit of byte 2 (and end of packet) if (pinstate) ++parity2; // parity error? ==> RESYNC if ((parity1 & 1) || (parity2 & 1)) { LED_PORT = ~++errorcounter; ZACWIRE_PREPARE_SYNC; return; } //byte1 cant be greater than 7. If it is anyway the bytes are probably swapped due to some //strange behaviour I haven't figured out yet (this happens every few Minutes). Resync to solve this //..doesn't seem to occur anymore when interrupt flags are set back before enabling the INT if (byte1 > 7) { ZACWIRE_PREPARE_SYNC; return; } ZACWIRE_Bits = 0; TSIC_STATUS = PREPARE_STROBE; TEMP_Byte1=byte1; TEMP_Byte2=byte2; //LED_PORT = ~TEMP_Byte2; break; default: //Initalise variables on first byte if (ZACWIRE_Bits <= 2) { byte1 = 0; byte2 = 0; parity1 = 0; parity2 = 0; } // read bit 2-9 (byte 1) or bit 12-19 (byte 2) if (ZACWIRE_Bits <= 9) { byte1 <<= 1; if (pinstate) { byte1 |= 1; ++parity1; } } else { byte2 <<= 1; if (pinstate) { byte2 |= 1; ++parity2; } } } ZACWIRE_EXTINT_ENABLE; }