removed the older make and exexcutable files
This commit is contained in:
parent
18009c9b1f
commit
87aae7719b
22341
avrdude.conf
22341
avrdude.conf
File diff suppressed because it is too large
Load Diff
BIN
avrdude.exe
BIN
avrdude.exe
Binary file not shown.
BIN
avrdude.pdb
BIN
avrdude.pdb
Binary file not shown.
421
main.c
421
main.c
|
@ -1,421 +0,0 @@
|
||||||
/*
|
|
||||||
* FileName: *.c
|
|
||||||
* Date: 2023
|
|
||||||
* Descripton: Program for Atiny13A controllers, controls DPDT relays and
|
|
||||||
* has options to save settings in EEPROM.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef MCU
|
|
||||||
#define MCU atiny13a
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef F_CPU
|
|
||||||
#define F_CPU 4800000UL
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#include <avr/io.h>
|
|
||||||
#include <avr/interrupt.h>
|
|
||||||
#include <util/delay.h>
|
|
||||||
#include <avr/eeprom.h>
|
|
||||||
|
|
||||||
//These are just defined in case for compatability with Arduino
|
|
||||||
#ifndef HIGH
|
|
||||||
#define HIGH 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef LOW
|
|
||||||
#define LOW 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef UINT8_MAX
|
|
||||||
#define UINT8_MAX 256
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//This is the bitpattern that should be at address 0x00
|
|
||||||
#define START_PATTERN 0xAA
|
|
||||||
#define END_PATTERN 0x55
|
|
||||||
|
|
||||||
//Addresses in the eeprom for the two bypasses
|
|
||||||
#define ROM_SP_ADR 0x0
|
|
||||||
#define ROM_BP1_ADR 0x1
|
|
||||||
#define ROM_BP2_ADR 0x2
|
|
||||||
#define ROM_EP_ADR 0x3
|
|
||||||
|
|
||||||
//Debounce check number.
|
|
||||||
#define MAX_CHECKS 10
|
|
||||||
|
|
||||||
// Define DISABLE_TEMPORARY_SWITCH to turn off the ability to hold
|
|
||||||
// the switch to temporarily engage/bypass.
|
|
||||||
//#define DISABLE_TEMPORARY_SWITCH
|
|
||||||
|
|
||||||
#define PIN_SW2 PINB3
|
|
||||||
#define PIN_BYPASS2 PB4
|
|
||||||
#define PIN_SW1 PINB2
|
|
||||||
#define PIN_BYPASS1 PB1
|
|
||||||
#define PIN_MUTE PB0
|
|
||||||
|
|
||||||
//The BLINK_QTY can be edited from 0-255 blinks
|
|
||||||
#define BLINK_QTY 2
|
|
||||||
#define BLINK_CNT 2 * BLINK_QTY
|
|
||||||
#define BLINK_DELAY 200
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*The timing of "ticks" is dependent on the AVR timer's counter register
|
|
||||||
* so for an 8bit register the maximum value is 256. Given we stick with
|
|
||||||
* a 1Mhz cpu frequency can use this formula to calculate the number of
|
|
||||||
* interrupts(timer overflows) per second:
|
|
||||||
*
|
|
||||||
* OVF_S = (F_CPU / DIV)/ (2^8)
|
|
||||||
* 61 = (1000000 / 64) / 256
|
|
||||||
*
|
|
||||||
* This is important because the ATiny13/A only have a single timer built into
|
|
||||||
* them.
|
|
||||||
*
|
|
||||||
* Ticks are used as our way of keep track of long button presses.
|
|
||||||
* */
|
|
||||||
//original sent had 60
|
|
||||||
#define LONG_PRESS_TICKS 66
|
|
||||||
|
|
||||||
|
|
||||||
/*A structure to hold the button info*/
|
|
||||||
typedef struct {
|
|
||||||
uint8_t is_pressed: 1;
|
|
||||||
uint8_t is_bypassed: 1;
|
|
||||||
uint8_t is_long_pressed: 1;
|
|
||||||
uint8_t timer_enabled: 1;
|
|
||||||
uint8_t pressed_ticks;
|
|
||||||
uint8_t input_pin;
|
|
||||||
uint8_t output_pin;
|
|
||||||
}btn_state;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ###############################
|
|
||||||
* Global Variables
|
|
||||||
* ###############################
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/*Create two diffent instances of the button state structure*/
|
|
||||||
btn_state btn1;
|
|
||||||
btn_state btn2;
|
|
||||||
|
|
||||||
/*Some variables for managing the debouncing*/
|
|
||||||
volatile uint8_t debounced_state;
|
|
||||||
volatile uint8_t db_state[MAX_CHECKS];
|
|
||||||
volatile uint8_t idx;
|
|
||||||
|
|
||||||
volatile uint16_t tick_count;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ###############################
|
|
||||||
* FUNCTION PROTOTYPES
|
|
||||||
* ###############################
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void toggle_output(btn_state *b);
|
|
||||||
static inline void init_btn(btn_state *b, uint8_t input_pin, uint8_t output_pin);
|
|
||||||
static void clear_button_timer(btn_state *b);
|
|
||||||
static inline void start_button_timer(btn_state *b);
|
|
||||||
static inline void check_button_longpress(btn_state *b);
|
|
||||||
static void update_button_output(btn_state *b);
|
|
||||||
static void update_button_input(btn_state *b);
|
|
||||||
|
|
||||||
static inline void blink_bypass1(void);
|
|
||||||
static inline void blink_bypass2(void);
|
|
||||||
|
|
||||||
static inline void init_timer0();
|
|
||||||
static inline void debounce_switch();
|
|
||||||
/*
|
|
||||||
* ###############################
|
|
||||||
* SETUP AND LOOP
|
|
||||||
* ###############################
|
|
||||||
*/
|
|
||||||
void init_prog()
|
|
||||||
{
|
|
||||||
/*Set the debounced state to all high*/
|
|
||||||
debounced_state = 0xFF;
|
|
||||||
|
|
||||||
/*Configures the PINS for the input and output.*/
|
|
||||||
init_btn(&btn1, PIN_SW1, PIN_BYPASS1);
|
|
||||||
init_btn(&btn2, PIN_SW2, PIN_BYPASS2);
|
|
||||||
|
|
||||||
/*Wait 5ms for pull-up resistors voltage to become stable.*/
|
|
||||||
_delay_ms(5);
|
|
||||||
|
|
||||||
/*check if the eeprom has info. */
|
|
||||||
while(! eeprom_is_ready()) {} //Blocks until eeprom is ready.
|
|
||||||
|
|
||||||
//Checks against a bit pattern we defined to represent the start of data.
|
|
||||||
if(eeprom_read_byte((uint8_t *)ROM_SP_ADR) == START_PATTERN) {
|
|
||||||
//Reads the two bytes representing the two states.
|
|
||||||
btn1.is_bypassed = eeprom_read_byte((uint8_t *)ROM_BP1_ADR);
|
|
||||||
btn2.is_bypassed = eeprom_read_byte((uint8_t *)ROM_BP2_ADR);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
//otherwise we write the init values for the start pattern and bypass states.
|
|
||||||
eeprom_write_byte((uint8_t *)ROM_SP_ADR, START_PATTERN);
|
|
||||||
eeprom_write_byte((uint8_t *)ROM_BP1_ADR, 0x0);
|
|
||||||
eeprom_write_byte((uint8_t *)ROM_BP2_ADR, 0x0);
|
|
||||||
}
|
|
||||||
|
|
||||||
btn1.is_pressed = ((PINB & (1<<btn1.input_pin)) == 0);
|
|
||||||
btn2.is_pressed = ((PINB & (1<<btn2.input_pin)) == 0);
|
|
||||||
|
|
||||||
|
|
||||||
/*This is to read if the user wants to change the saved states.*/
|
|
||||||
/*Manually read the current switch state*/
|
|
||||||
if(btn1.is_pressed){
|
|
||||||
btn1.is_bypassed = ! btn1.is_bypassed;
|
|
||||||
eeprom_write_byte((uint8_t *)ROM_BP1_ADR, btn1.is_bypassed);
|
|
||||||
blink_bypass1();
|
|
||||||
}
|
|
||||||
if(btn2.is_pressed){
|
|
||||||
btn2.is_bypassed = ! btn2.is_bypassed;
|
|
||||||
eeprom_write_byte((uint8_t *)ROM_BP2_ADR, btn2.is_bypassed);
|
|
||||||
blink_bypass2();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(btn1.is_bypassed){PORTB |= (1<<btn1.output_pin);}
|
|
||||||
if(btn2.is_bypassed){PORTB |= (1<<btn2.output_pin);}
|
|
||||||
|
|
||||||
init_timer0();
|
|
||||||
}
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
|
|
||||||
init_prog();
|
|
||||||
|
|
||||||
while(1){
|
|
||||||
update_button_output(&btn1);
|
|
||||||
update_button_output(&btn2);
|
|
||||||
|
|
||||||
update_button_input(&btn1);
|
|
||||||
update_button_input(&btn2);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ###############################
|
|
||||||
* FUNCTION DEFs
|
|
||||||
* ###############################
|
|
||||||
*/
|
|
||||||
|
|
||||||
void inf_blink_test(){
|
|
||||||
DDRB |= (1<<PB3);
|
|
||||||
while(1){
|
|
||||||
PORTB ^= (1<<PB3);
|
|
||||||
_delay_ms(250);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//Made heavy use of static inline functions to improve readability.
|
|
||||||
|
|
||||||
static inline void blink_bypass1(void)
|
|
||||||
{
|
|
||||||
for(uint8_t i = 0; i < BLINK_CNT; i++) {
|
|
||||||
PORTB ^= (1<<PIN_BYPASS1);
|
|
||||||
_delay_ms(BLINK_DELAY);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void blink_bypass2(void)
|
|
||||||
{
|
|
||||||
for(uint8_t i = 0; i < BLINK_CNT; i++) {
|
|
||||||
PORTB ^= (1<<PIN_BYPASS2);
|
|
||||||
_delay_ms(BLINK_DELAY);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ############################
|
|
||||||
* BUTTON methods
|
|
||||||
* ############################
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*This is kinda like our button constructor*/
|
|
||||||
static void init_btn(btn_state *b, uint8_t input_pin, uint8_t output_pin)
|
|
||||||
{
|
|
||||||
b->is_long_pressed = 0;
|
|
||||||
b->is_pressed = 0;
|
|
||||||
b->is_bypassed = 0;
|
|
||||||
b->pressed_ticks = 0;
|
|
||||||
b->timer_enabled = 0;
|
|
||||||
b->input_pin = input_pin;
|
|
||||||
b->output_pin = output_pin;
|
|
||||||
|
|
||||||
/*Configure the buttons inputs and outputs*/
|
|
||||||
DDRB &= ~(1<<b->input_pin);
|
|
||||||
PORTB |= (1<<b->input_pin);
|
|
||||||
|
|
||||||
DDRB |= (1<<b->output_pin);
|
|
||||||
PORTB &= ~(1<<b->output_pin);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*This is the fancy function to toggle output pins*/
|
|
||||||
static void toggle_output(btn_state *b)
|
|
||||||
{
|
|
||||||
if(!b->is_bypassed){
|
|
||||||
b->is_bypassed = 1;
|
|
||||||
PORTB |= (1<<b->output_pin);
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
b->is_bypassed = 0;
|
|
||||||
PORTB &= ~(1<<b->output_pin);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void clear_button_timer(btn_state *b)
|
|
||||||
{
|
|
||||||
b->timer_enabled = 0;
|
|
||||||
b->is_long_pressed = 0;
|
|
||||||
b->pressed_ticks = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void start_button_timer(btn_state *b)
|
|
||||||
{
|
|
||||||
clear_button_timer(b);
|
|
||||||
b->timer_enabled = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void check_button_longpress(btn_state *b)
|
|
||||||
{
|
|
||||||
if(b->pressed_ticks >= LONG_PRESS_TICKS) {
|
|
||||||
b->is_long_pressed = 1;
|
|
||||||
b->timer_enabled = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void update_button_input(btn_state *b)
|
|
||||||
{
|
|
||||||
/*Check from the global debounced port input*/
|
|
||||||
|
|
||||||
/*check for pin HIGH*/
|
|
||||||
if(debounced_state & (1<<b->input_pin)) {
|
|
||||||
b->is_pressed = 0;
|
|
||||||
}
|
|
||||||
/*otherwise assume pin LOW*/
|
|
||||||
else{
|
|
||||||
b->is_pressed = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void update_button_output(btn_state *b)
|
|
||||||
{
|
|
||||||
/*If the button is actually pressed.*/
|
|
||||||
if(b->is_pressed){
|
|
||||||
|
|
||||||
/*If this is a new event.*/
|
|
||||||
if(!b->is_long_pressed && !b->timer_enabled){
|
|
||||||
/*Then start the timer and update the output*/
|
|
||||||
toggle_output(b);
|
|
||||||
start_button_timer(b);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*If the timer is already going.*/
|
|
||||||
else if(b->timer_enabled){
|
|
||||||
/*Then just check if it's hit the threshold.*/
|
|
||||||
check_button_longpress(b);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
else{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Else the button was realeased*/
|
|
||||||
else if(!b->is_pressed){
|
|
||||||
/*If the button was released on a long press.*/
|
|
||||||
if(b->is_long_pressed){
|
|
||||||
toggle_output(b);
|
|
||||||
}
|
|
||||||
clear_button_timer(b);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ############################
|
|
||||||
* DEBOUNCING CODE
|
|
||||||
* ############################
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* INPUT: The port to check.
|
|
||||||
* OUTPUT: None
|
|
||||||
* DESCRIPTION: Updates the global debounced state. This function
|
|
||||||
* should be called in a ISR a set rate using the hardware timer.
|
|
||||||
*/
|
|
||||||
static inline void debounce_switch() {
|
|
||||||
uint8_t i, j;
|
|
||||||
db_state[idx] = PINB & 0xFF;
|
|
||||||
idx+=1;
|
|
||||||
j = 0xff;
|
|
||||||
/*Loop through a number of checks*/
|
|
||||||
for(i = 0; i < MAX_CHECKS; i++) {
|
|
||||||
j = j & db_state[i];
|
|
||||||
}
|
|
||||||
debounced_state = j;
|
|
||||||
|
|
||||||
if(idx >= MAX_CHECKS) {
|
|
||||||
idx = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*Setup the timer0 on the AVR*/
|
|
||||||
static inline void init_timer0() {
|
|
||||||
/*Zero out the tick_count var*/
|
|
||||||
tick_count = 0;
|
|
||||||
|
|
||||||
/*config to normal mode.*/
|
|
||||||
TCCR0A = 0x00; //stop timer
|
|
||||||
TCCR0B = 0x00; //zero timer
|
|
||||||
|
|
||||||
/*set prescaler*/
|
|
||||||
//Set to div64
|
|
||||||
TCCR0B |= (1<<CS01)|(1<<CS00);
|
|
||||||
|
|
||||||
|
|
||||||
/*Enable global interrupts*/
|
|
||||||
sei();
|
|
||||||
|
|
||||||
/*Enabling timer0 interrupt*/
|
|
||||||
TCNT0 = 0;
|
|
||||||
TIMSK0 |= (1<<TOIE0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//ISR(TIMER0_OVF_vect)
|
|
||||||
|
|
||||||
/*The interrupt service routine for the timer0*/
|
|
||||||
ISR(TIM0_OVF_vect)
|
|
||||||
{
|
|
||||||
/*Disable global interrupts*/
|
|
||||||
cli();
|
|
||||||
|
|
||||||
/*Check the state of the switches*/
|
|
||||||
debounce_switch();
|
|
||||||
|
|
||||||
/*Update the tick_count*/
|
|
||||||
if(btn1.timer_enabled && btn1.pressed_ticks <= UINT8_MAX){
|
|
||||||
btn1.pressed_ticks += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(btn2.timer_enabled && btn2.pressed_ticks <= UINT8_MAX){
|
|
||||||
btn2.pressed_ticks += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*Re-Enable global interrupts*/
|
|
||||||
sei();
|
|
||||||
}
|
|
65
makefile
65
makefile
|
@ -1,65 +0,0 @@
|
||||||
# Author: Jake Goodwin
|
|
||||||
# DATE: 2023-12-07
|
|
||||||
# Descripion: A simple makefile for building and flashing hex files
|
|
||||||
|
|
||||||
# Makefile for ATtiny13A
|
|
||||||
|
|
||||||
# Compiler
|
|
||||||
CC = avr-gcc
|
|
||||||
|
|
||||||
#Default cpu frequency is 9.8Mhz, 4.8 gives us less power consumption
|
|
||||||
#F_CPU = 1000000UL
|
|
||||||
F_CPU = 4800000UL
|
|
||||||
#F_CPU = 9800000UL
|
|
||||||
MCU = attiny13a
|
|
||||||
|
|
||||||
# Flags
|
|
||||||
CFLAGS = -g -Os -mmcu=$(MCU) -DF_CPU=$(F_CPU)
|
|
||||||
LDFLAGS = -Wl,-Map,$(TARGET).map
|
|
||||||
|
|
||||||
# Source files
|
|
||||||
SRC = main.c
|
|
||||||
|
|
||||||
# Object files
|
|
||||||
OBJ = $(SRC:.c=.o)
|
|
||||||
|
|
||||||
# Target HEX file
|
|
||||||
TARGET = main
|
|
||||||
|
|
||||||
# Flashing options
|
|
||||||
AVRDUDE = avrdude
|
|
||||||
AVRDUDE_PROGRAMMER = -c usbasp
|
|
||||||
BUADRATE = -B 125kHz
|
|
||||||
AVRDUDE_PORT = -P /dev/ttyUSB0
|
|
||||||
AVRDUDE_MCU = -p $(MCU)
|
|
||||||
|
|
||||||
|
|
||||||
# Compile and generate HEX file
|
|
||||||
all: $(TARGET).hex
|
|
||||||
|
|
||||||
$(TARGET).hex: $(TARGET).elf
|
|
||||||
avr-objcopy -j .text -j .data -O ihex $< $@
|
|
||||||
|
|
||||||
$(TARGET).elf: $(OBJ)
|
|
||||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^
|
|
||||||
|
|
||||||
%.o: %.c
|
|
||||||
$(CC) $(CFLAGS) -c $< -o $@
|
|
||||||
size: $(TARGET).o
|
|
||||||
avr-size --mcu=$(MCU) -t ./$(TARGET).o
|
|
||||||
# Default for the attiny13a is going to be 9.6Mhz
|
|
||||||
flash_defualt_fuses:
|
|
||||||
$(AVRDUDE) $(AVRDUDE_PROGRAMMER) $(AVRDUDE_PORT) $(AVRDUDE_MCU) $(BUADRATE) -U lfuse:w:0x6A:m -U hfuse:w:0xFF:m -U lock:w:0xFF:m
|
|
||||||
# This is for 4.8Mhz
|
|
||||||
flash_slow_fuse:
|
|
||||||
$(AVRDUDE) $(AVRDUDE_PROGRAMMER) $(AVRDUDE_PORT) $(AVRDUDE_MCU) $(BUADRATE) -U lfuse:w:0x69:m -U hfuse:w:0xFF:m -U lock:w:0xFF:m
|
|
||||||
flash_slow_nodiv8:
|
|
||||||
$(AVRDUDE) $(AVRDUDE_PROGRAMMER) $(AVRDUDE_PORT) $(AVRDUDE_MCU) $(BUADRATE) -U lfuse:w:0x79:m -U hfuse:w:0xFF:m -U lock:w:0xFF:m
|
|
||||||
flash: $(TARGET).hex
|
|
||||||
$(AVRDUDE) $(AVRDUDE_PROGRAMMER) $(AVRDUDE_PORT) $(AVRDUDE_MCU) $(BUADRATE) -U flash:w:$(TARGET).hex:i
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -f $(OBJ) $(TARGET).elf $(TARGET).hex $(TARGET).map
|
|
||||||
|
|
||||||
.PHONY: all clean
|
|
||||||
|
|
BIN
zadig-2.8.exe
BIN
zadig-2.8.exe
Binary file not shown.
Loading…
Reference in New Issue