~mat_hill/avr_blinky

94fbeed8a57a66df27ecb1e2cc2b0b1da0934c09 — mat hill 2 years ago master
added to srht
7 files changed, 108 insertions(+), 0 deletions(-)

A .gitignore
A build.sh
A check_programmer_ready.sh
A configure_fuses.sh
A pcb_kicad_project.zip
A src/main.c
A upload.sh
A  => .gitignore +2 -0
@@ 1,2 @@
blinky_binary
blinky_binary.hex

A  => build.sh +5 -0
@@ 1,5 @@
avr-gcc -v \
    -mmcu=attiny85 \
    -Os -std=gnu99 -Wall \
    -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums \
    src/main.c -o blinky_binary

A  => check_programmer_ready.sh +1 -0
@@ 1,1 @@
avrdude -p attiny85 -c usbasp

A  => configure_fuses.sh +1 -0
@@ 1,1 @@
avrdude -v -p attiny85 -c usbasp -U lfuse:w:0x62:m -U hfuse:w:0xdf:m -U efuse:w:0xff:m

A  => pcb_kicad_project.zip +0 -0
A  => src/main.c +93 -0
@@ 1,93 @@
#define F_CPU 1000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/power.h>

#define EYES_STATE_OPEN 0
#define EYES_STATE_CLOSING 1
#define EYES_STATE_CLOSED 2
#define EYES_STATE_OPENING 3
uint8_t eyes_state;

#define EYES_CLOSED_DURATION_MS 200
#define EYES_OPEN_BASE_DURATION_MS 100
#define EYES_OPENING_DT_US 1500
#define EYES_CLOSING_DT_US 400
uint8_t eyes_open_duration_multipliers_index = 0;
uint16_t eyes_open_duration_multipliers[] = {
    50, 40, 79, 20, 91, 43, 68, 70, 40, 23, 33,
};
size_t eyes_open_duration_multipliers_count;

int
main(void)
{
    // Minimise power usage.
    power_all_disable();
    power_timer0_enable();

    // Drive LEDs via PB0.
    DDRB |= (1 << DDB0);

    // Set waveform mode to fast PWM.
    TCCR0A |= (1 << WGM00);
    TCCR0A |= (1 << WGM01);
    TCCR0B &= ~(1 << WGM02);

    // Set overflow / match behavior.
    TCCR0A |= (1 << COM0A1);
    TCCR0A |= (1 << COM0B0);
    TCCR0A |= (1 << COM0A0);
    TCCR0A |= (1 << COM0B1);

    // No pre-scaler.
    TCCR0B |= (1 << CS00);

    // Start with eyes open.
    OCR0A = 0;
    eyes_state = EYES_STATE_OPEN;

    // Cache array size.
    eyes_open_duration_multipliers_count = sizeof(eyes_open_duration_multipliers) / sizeof(eyes_open_duration_multipliers[0]);

    while (1) {
        switch (eyes_state) {

        case EYES_STATE_OPEN:
            OCR0A = 0x00;
            uint16_t duration = eyes_open_duration_multipliers[eyes_open_duration_multipliers_index] * EYES_OPEN_BASE_DURATION_MS;
            eyes_open_duration_multipliers_index++;
            if (eyes_open_duration_multipliers_index >= eyes_open_duration_multipliers_count) {
                eyes_open_duration_multipliers_index = 0;
            }
            for (uint16_t i = 0; i < duration; i++) {
                _delay_ms(1);
            }
            eyes_state = EYES_STATE_CLOSING;
            break;

        case EYES_STATE_CLOSING:
            OCR0A++;
            _delay_us(EYES_CLOSING_DT_US);
            if (OCR0A == 255) {
                eyes_state = EYES_STATE_CLOSED;
            }
            break;

        case EYES_STATE_CLOSED:
            OCR0A = 0xFF;
            _delay_ms(EYES_CLOSED_DURATION_MS);
            eyes_state = EYES_STATE_OPENING;
            break;

        case EYES_STATE_OPENING:
            OCR0A--;
            _delay_us(EYES_OPENING_DT_US);
            if (OCR0A == 0) {
                eyes_state = EYES_STATE_OPEN;
            }
            break;
        }
    }
    return 0;
}

A  => upload.sh +6 -0
@@ 1,6 @@
if avr-objcopy -O ihex -j.text -j.data blinky_binary blinky_binary.hex
then
    avrdude -v -p attiny85 -c usbasp -U flash:w:blinky_binary.hex:i
else
    echo "...failed :("
fi