avr-sequence-memory/main.c

110 lines
2.1 KiB
C
Raw Permalink Normal View History

2021-10-18 11:30:23 +00:00
#include <stdbool.h>
#include <avr/io.h>
#include <util/delay.h>
#include <inttypes.h>
#define PORT_LED PORTB
#define PIN_SWITCH PIND
bool do_round(uint8_t *seq, int len);
void display_seq(uint8_t *seq, int len);
bool read_input(uint8_t *seq, int len);
int main(){
// Port B LED
DDRB = 0xFF;
// Port A Switch
DDRD = 0x00;
// Values from 0-7 representing the LED position
uint8_t seq[] = {4,2,4,5,1,0,3};
if (do_round(seq,7)) {
while (true)
{
PORT_LED = 0x55;
_delay_ms(250);
PORT_LED = 0xAA;
_delay_ms(250);
}
}else{
while (true)
{
PORT_LED = 0xF0;
_delay_ms(250);
PORT_LED = 0x0F;
_delay_ms(250);
}
}
}
bool do_round(uint8_t *seq, int len){
for (int i = 2; i < len; i++)
{
display_seq(seq,i);
if (!read_input(seq,i)){
// Failed
return false;
}
}
return true;
}
void display_seq(uint8_t *seq, int len){
// Turn off all LEDs
PORT_LED = 0xFF;
_delay_ms(1000);
for (int i = 0; i < len; i++)
{
PORT_LED = (0xFF ^ (1 << seq[i] ));
_delay_ms(1000);
// Turn off LEDs
PORT_LED = 0xFF;
_delay_ms(250);
}
// Turn off all LEDs
PORT_LED = 0xFF;
}
bool read_input(uint8_t *seq, int len){
for (int i = 0; i < len; i++)
{
uint8_t expected = 0xFF ^ (1 << seq[i]);
bool run = true;
while (run)
{
uint8_t input = PIN_SWITCH;
if (input < 0xFF){
// A button is pressed
if (input == expected){
run = false;
// Wait for button to release
while (PIN_SWITCH != 0xFF)
{
}
// "debounce"
_delay_ms(50);
}else{
return false;
}
}
}
}
return true;
}