diff --git a/AVR/main.c b/AVR/main.c index 64a92e1..849f32c 100644 --- a/AVR/main.c +++ b/AVR/main.c @@ -1,59 +1,47 @@ -/* I2C Echo Example */ #include "../avr-i2c-slave/I2CSlave.h" #include #include #include + #define I2C_ADDR 0x20 -volatile uint8_t data; -volatile uint8_t send=0; -void I2C_received(uint8_t received_data) -{ - data = received_data; +volatile uint8_t challenge = 0; // Use 0 as 'challenge not sent' condition + +uint8_t check_challenge(uint8_t arg) { + return (arg >> 3) ^ (arg << 3); } -void I2C_requested() { - I2C_transmitByte(send); +void I2C_received(uint8_t received_data) { + if (challenge != 0) { + if (check_challenge(received_data) == check_challenge(challenge)) { // Check validity of response + // Open lock + PORTC |= 2 << 1; + _delay_ms(5000); + PORTC = 0; + } + } + challenge = 0; } -void I2C_challenge() { - I2C_transmitByte(send); + +void I2C_requested() { + challenge = (uint8_t)(TCNT1 & 0xff); // Use content of timer as pseudo-random number + if (challenge == 0) // Prevent 'challenge' from being 0, which has a special meaning + challenge = 1; + I2C_transmitByte(challenge); } void setup() { // set received/requested callbacks I2C_setCallbacks(I2C_received, I2C_requested); - // init I2C I2C_init(I2C_ADDR); // init output gpio - DDRC = 0b00000100; // PC2 + DDRC = 0b00000100; // PC2 TCNT1 = 0; TCCR1B |= (1 << CS10) | (1 << CS11); // No prescaling - } + int main() { setup(); - int challenge = 0; - unsigned int i = 0; - // Main program loop - while(1) { - if(data == 1) { - i = TCNT1; - srand(i); - send = rand(); - while(data != send+3) { - I2C_challenge(); - } - send = 17; - I2C_challenge(); - PORTC |= 2<<1; - _delay_ms(5000); - PORTC = 0; - data = 0; - -}/* else { - send = 0; - I2C_challenge(); - }*/ - } + while (1); // All the work is done in the callbacks }