Ignition monitoring by level interrupt on PB4.
This commit is contained in:
		
							
								
								
									
										41
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								README.md
									
									
									
									
									
										Normal 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
 | 
			
		||||
```
 | 
			
		||||
							
								
								
									
										110
									
								
								src/main.c
									
									
									
									
									
								
							
							
						
						
									
										110
									
								
								src/main.c
									
									
									
									
									
								
							@@ -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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user