#include <avr/io.h>
#include "global_defs.inc"
.GLOBAL main
.EQU LED_alive , 5
.EQU LED0 , 0
.EQU LED1 , 1
.EQU KEY0 , 4 ; note that "KEY0: is on the 4th PIN!
.EQU KEY1 , 5
.DATA
led_status:
.BYTE 1
key_last:
.BYTE 1
.TEXT
main:
main_initialize:
; setting LED "alive" and the lowest LED bit to be outputs
; other pins kept as inputs as they were originally
in R16, _SFR_IO_ADDR(DDRB)
ori R16, 0b00111111
out _SFR_IO_ADDR(DDRB), R16
; setting LED "alive" and the lowest LED bit to be initially ON
in R16, _SFR_IO_ADDR(PORTB)
andi R16, 0b11000000
ori R16, (1<<LED_alive | 1<<LED0)
out _SFR_IO_ADDR(PORTB), R16
; set pin 4 of port D to input with a pull-up resistor
; other pins kept as inputs as they were originally
in R16, _SFR_IO_ADDR(DDRD)
andi R16, 0b00001111
out _SFR_IO_ADDR(DDRD), R16
in R16, _SFR_IO_ADDR(PORTD)
; activates pull up resistors on used pin(s)
ori R16, 1<<KEY0
out _SFR_IO_ADDR(PORTD), R16
; Initialize variables and registers
ldi R16, 0
sts led_status, R16
sts key_last, R16
main_superloop:
; reading the button status(es)
in R16, _SFR_IO_ADDR(PIND)
lds R18, key_last
eor R18, R16
sts key_last, R16
; start updating LEDs with preserving the unused bits
in R16, _SFR_IO_ADDR(PORTB)
sts led_status, R16
; blinking the "alive" LED
ldi R17, 1<<LED_alive
lds R16, led_status
eor R16, R17
sts led_status, R16
; take care of button KEY0 -> LED0
check_b0:
mov R16, R18
andi R16, 1<<KEY0
breq skip_b0
lds R16, key_last
andi R16, 1<<KEY0
breq skip_b0
toggle_led0:
ldi R17, 1<<LED0
lds R16, led_status
eor R16, R17
sts led_status, R16
skip_b0:
; writing the updated LED output
lds R16, led_status
out _SFR_IO_ADDR(PORTB), R16
; call delay function with number of MS in R3
ldi R16, 100
mov R3, R16
rcall delay_in_ms
; note: perhaps it would be better to design the function to receive its parameter in R16 or above
; as that would allow to set constant parameter with just one instruction instead of two?
rjmp main_superloop