Added start of input management infrastructure.

This commit is contained in:
Andrew Lalis 2022-12-02 19:48:40 +01:00
parent 1f3e31c295
commit d561b73feb
4 changed files with 108 additions and 26 deletions

View File

@ -8,10 +8,15 @@ flash: build
build: gympal.hex
gympal.hex: src/gympal.c bin
avr-gcc -Wall -Os -DF_CPU=16000000UL -mmcu=atmega328p -c src/gympal.c -o bin/gympal.o
avr-gcc -Os -mmcu=atmega328p -o bin/gympal.elf bin/gympal.o
gympal.hex: gympal.o control.o
avr-gcc -Os -mmcu=atmega328p -o bin/gympal.elf bin/gympal.o bin/control.o
avr-objcopy -O ihex -R .eeprom bin/gympal.elf bin/gympal.hex
gympal.o: src/gympal.c bin
avr-gcc -Wall -Os -DF_CPU=16000000UL -mmcu=atmega328p -c -o bin/gympal.o src/gympal.c
control.o: src/control.c bin
avr-gcc -Wall -Os -DF_CPU=16000000UL -mmcu=atmega328p -c -o bin/control.o src/control.c
bin:
mkdir bin

47
src/control.c Normal file
View File

@ -0,0 +1,47 @@
#include "control.h"
volatile uint8_t CTL_INPUT_FLAGS = 0;
uint8_t readPin(uint8_t inputRegister, uint8_t inputPin) {
return (inputRegister & (1 << inputPin)) >> inputPin;
}
ISR(PCINT2_vect) {
cli();
uint8_t rotDt = readPin(PIND, CTL_ROTARY_ENCODER_DT_IN);
uint8_t rotClk = readPin(PIND, CTL_ROTARY_ENCODER_CLK_IN);
uint8_t buttonA = readPin(PIND, CTL_BUTTON_A_IN);
uint8_t buttonB = readPin(PIND, CTL_BUTTON_B_IN);
uint8_t buttonC = readPin(PIND, CTL_BUTTON_C_IN);
CTL_INPUT_FLAGS = (
(rotDt << CTL_ROTARY_ENCODER_DT_FLAG) |
(rotClk << CTL_ROTARY_ENCODER_CLK_FLAG) |
(buttonA << CTL_BUTTON_A_FLAG) |
(buttonB << CTL_BUTTON_B_FLAG) |
(buttonC << CTL_BUTTON_C_FLAG)
);
sei();
}
void ctl_init() {
// Set all control pins as input (0).
DDRD &= ~(
(1 << CTL_ROTARY_ENCODER_DT) |
(1 << CTL_ROTARY_ENCODER_CLK) |
(1 << CTL_BUTTON_A) |
(1 << CTL_BUTTON_B) |
(1 << CTL_BUTTON_C)
);
// Set up interrupts for handling control pin state changes.
// Luckily, all interrupts happen on PCINT[16..23] so we only need one interrupt to handle them all.
PCICR |= 1 << PCIE2; // Enable PCINT2_vector interrupts.
PCMSK2 |= (// Enable the flag for each input we want to cause interrupts on state change.
(1 << CTL_ROTARY_ENCODER_DT_INT) |
(1 << CTL_ROTARY_ENCODER_CLK_INT) |
(1 << CTL_BUTTON_A_INT) |
(1 << CTL_BUTTON_B_INT) |
(1 << CTL_BUTTON_C_INT)
);
// Enable the global interrupt flag.
sei();
}

39
src/control.h Normal file
View File

@ -0,0 +1,39 @@
#ifndef CONTROL_H
#define CONTROL_H
#include <avr/io.h>
#include <avr/interrupt.h>
#define CTL_ROTARY_ENCODER_DT PORTD2
#define CTL_ROTARY_ENCODER_DT_IN PIND2
#define CTL_ROTARY_ENCODER_DT_INT PCINT18
#define CTL_ROTARY_ENCODER_DT_FLAG 0
#define CTL_ROTARY_ENCODER_CLK PORTD3
#define CTL_ROTARY_ENCODER_CLK_IN PIND3
#define CTL_ROTARY_ENCODER_CLK_INT PCINT19
#define CTL_ROTARY_ENCODER_CLK_FLAG 1
#define CTL_BUTTON_A PORTD5
#define CTL_BUTTON_A_IN PIND5
#define CTL_BUTTON_A_INT PCINT21
#define CTL_BUTTON_A_FLAG 2
#define CTL_BUTTON_B PORTD6
#define CTL_BUTTON_B_IN PIND6
#define CTL_BUTTON_B_INT PCINT22
#define CTL_BUTTON_B_FLAG 3
#define CTL_BUTTON_C PORTD7
#define CTL_BUTTON_C_IN PIND7
#define CTL_BUTTON_C_INT PCINT23
#define CTL_BUTTON_C_FLAG 4
extern volatile uint8_t CTL_INPUT_FLAGS;
/**
* @brief Initializes the user control inputs and interrupts.
*/
void ctl_init();
#endif

View File

@ -1,33 +1,24 @@
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
volatile uint8_t a = 0;
void updatePin12(uint8_t status) {
PORTB = status << PORTB4;
}
ISR(PCINT2_vect) {
uint8_t value = (PIND & (1 << PIND5)) >> PIND5;
PORTB = value << PORTB4;
}
#include "control.h"
int main() {
PCICR |= 1 << PCIE2;
PCMSK2 |= 1 << PCINT21;
sei();
// Pin 12 == Port B4, aka 4th bit on the B register.
// Set pin 12 as output.
ctl_init();
// Just for testing the interrupts, we're setting up B4 as an indicator LED.
DDRB |= 1 << PORTB4;
// Set pin 5 as input.
DDRD &= ~(1 << PORTD5);
PORTB &= ~(1 << PORTB4);
while (1) {
// updatePin12(ledOn);
// ledOn = !ledOn;
// _delay_ms(1000.0);
// DO NOTHING! rely on interrupt.
uint8_t led = 0;
while(1) {
uint8_t v = (CTL_INPUT_FLAGS & (1 << CTL_BUTTON_B_FLAG)) >> CTL_BUTTON_A_FLAG;
if (led != v) {
led = v;
if (led) {
PORTB |= 1 << PORTB4;
} else {
PORTB &= ~(1 << PORTB4);
}
}
}
return 0;
}