diff --git a/README.md b/README.md new file mode 100644 index 0000000..9896afb --- /dev/null +++ b/README.md @@ -0,0 +1,41 @@ +# AVR Toolchain + +## Prerequisites + +```shell +apt install flex byacc bison build-essential apt install libgmp-dev libmpfr-dev libmpc-dev +``` + +## Binutils + +```shell +$ wget http://ftp.gnu.org/gnu/binutils/binutils-2.33.1.tar.xz +$ tar xvf binutils-2.33.1.tar.xz +$ cd binutils-2.33.1 +$ ./configure --target=avr --program-prefix="avr-" +$ make -j4 +$ make install +``` + +## GCC + +```shell +$ wget ftp://ftp.fu-berlin.de/unix/languages/gcc/releases/gcc-9.2.0/gcc-9.2.0.tar.xz +$ tar cvf gcc-9.2.0.tar.xz +$ mkdir avrgcc-9.2.0 +$ cd avrgcc-9.2.0 +$ ../gcc-9.2.0/configure --target=avr --enable-languages=c,c++ --disable-libssp +$ make -j4 +$ make install +``` + +## avr-libc + +```shell +$ wget http://download.savannah.gnu.org/releases/avr-libc/avr-libc-2.0.0.tar.bz2 +$ tar xvf avr-libc-2.0.0.tar.bz2 +$ cd avr-libc-2.0.0 +$ ./configure --host=avr +$ make -j4 +$ make install +``` \ No newline at end of file diff --git a/src/main.c b/src/main.c index d8623da..9e305d9 100644 --- a/src/main.c +++ b/src/main.c @@ -1,37 +1,115 @@ +#include #include #define F_CPU 1000000UL #include #include +#include #include #include -#include -volatile int tick; +#define MOSI_PIN 0 +#define MISO_PIN 1 +#define SCK_PIN 2 +#define POWER_PIN 3 +#define IGNITION_PIN 4 -int main(void) +#define SHUTDOWN_TIME_MS 5000UL + +#define ignition_on() (PINB & (1 << IGNITION_PIN)) +#define power_on() (PINB & (1 << POWER_PIN)) + +bool is_shutdown; +volatile uint32_t tick; + +enum power { + off = 0, + on +}; + +void setup_gpio() { - cli(); - tick = 0; DDRB = 0xff; + PORTB = 0; + DDRB &= ~(1 << IGNITION_PIN); + PORTB |= (1 << IGNITION_PIN); // enable pull-up + GIMSK |= (1 << PCIE); // Enable Pin Change Interrupts + PCMSK |= (1 << IGNITION_PIN); // Use PB4 as interrupt pin +} + +void setup_timer0() +{ TCCR0A = (1 << WGM01); - TCCR0B = (1 << CS01); + TCCR0B = (1 << CS01); // prescaler = 8 TIMSK |= (1 << OCIE0A); // enable compare match interrupt // ((1000000 / 8) / 1000) = 125 OCR0A = 125 - 1; +} - // TIMSK |= (1 << TOIE0); +void setup_watchdog() +{ + MCUSR &= ~(1 << WDRF); + WDTCR = (1 << WDCE) | (1 << WDE); + WDTCR = (1 << WDIE) | (1 << WDP2) | (1 << WDP1); +} + +void switch_power(enum power power) +{ + if(power) { + PORTB |= (1 << POWER_PIN); + } + else { + PORTB &= ~(1 << POWER_PIN); + } +} + +int main(void) +{ + uint32_t shutdown_expire = 0; + tick = 0; + is_shutdown = false; + setup_gpio(); + setup_timer0(); + + ADCSRA = 0; + ADCSRB = 0; + + set_sleep_mode(SLEEP_MODE_PWR_DOWN); sei(); + while(1) { - if(tick >= 1000) { - PORTB ^= (1 << PB4); - tick = 0; + if(ignition_on()) { + if(!power_on()) { + switch_power(on); + is_shutdown = false; + } + sleep_enable(); + sleep_cpu(); + sleep_disable(); + } else { + if(!is_shutdown) { + is_shutdown = true; + shutdown_expire = tick + SHUTDOWN_TIME_MS; + } + else { + if(shutdown_expire < tick) { + if(power_on()) { + switch_power(off); + } + // setup_watchdog(); + sleep_enable(); + sleep_cpu(); + sleep_disable(); + // wdt_disable(); + } + } } } + return 0; } @@ -39,3 +117,15 @@ ISR(TIM0_COMPA_vect) { tick++; } + +// wake up by level interrupt on PB4 +ISR(PCINT0_vect) +{ +} + +// wake up by watchdog interrupt +ISR(WDT_vect) +{ + WDTCR |= (1 << WDIE); +} +