You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

48 lines
1.1 KiB

#include "../avr-i2c-slave/I2CSlave.h"
#include <util/delay.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#define I2C_ADDR 0x20
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_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_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
TCNT1 = 0;
TCCR1B |= (1 << CS10) | (1 << CS11); // No prescaling
}
int main() {
setup();
while (1); // All the work is done in the callbacks
}