Ignition monitoring by level interrupt on PB4.

This commit is contained in:
Thomas Klaehn 2019-12-25 10:03:56 +00:00
parent a8d7b7a282
commit 18913f5f6a
2 changed files with 141 additions and 10 deletions

41
README.md Normal file
View File

@ -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
```

View File

@ -1,37 +1,115 @@
#include <stdbool.h>
#include <stdint.h>
#define F_CPU 1000000UL
#include <avr/interrupt.h>
#include <avr/io.h>
#include <avr/power.h>
#include <avr/sleep.h>
#include <avr/wdt.h>
#include <util/delay.h>
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);
}