Skip to content

Instantly share code, notes, and snippets.

@SelvinPL
Last active December 15, 2024 10:54
Show Gist options
  • Select an option

  • Save SelvinPL/f7f0aeaf1d7f5e84ac31bcaeee925e4a to your computer and use it in GitHub Desktop.

Select an option

Save SelvinPL/f7f0aeaf1d7f5e84ac31bcaeee925e4a to your computer and use it in GitHub Desktop.
Copy to GBPOT catalog, ino file is empty - everything is in main.c
#ifndef DEF_H_
#define DEF_H_ 1
#include <stdbool.h>
#include <stdint.h>
#include <avr/io.h>
#include <avr/sleep.h>
#include <avr/power.h>
#include <avr/interrupt.h>
#include <avr/portpins.h>
#if defined (__AVR_ATtiny10__)
#include "deftn10.h"
#elif defined (__AVR_ATtiny85__)
#include "deftn85.h"
#elif defined (__AVR_ATmega32U4__)
#include "defm32u4.h"
#elif defined (__AVR_ATmega328__)
#include "deftm328.h"
#elif defined (__AVR_ATmega328P__)
#include "deftm328p.h"
#else
#error device not supported
#endif
#ifndef INT_REG
#define INT_REG EIMSK
#endif
#ifndef INT_TYPE_REG
#define INT_TYPE_REG EICRA
#endif
#ifndef TIMER_MASK
#define TIMER_MASK TIMER_INDEX
#endif
#define _PORT(NAME) PORT ## NAME
#define PORT(NAME) _PORT(NAME)
#define _PIN(NAME) PIN ## NAME
#define PIN(NAME) _PIN(NAME)
#define _TCCRA(NAME) TCCR ## NAME ## A
#define TCCRA(NAME) _TCCRA(NAME)
#define _TCCRB(NAME) TCCR ## NAME ## B
#define TCCRB(NAME) _TCCRB(NAME)
#define _TCNT(NAME) TCNT ## NAME
#define TCNT(NAME) _TCNT(NAME)
#define _TIMSK(NAME) TIMSK ## NAME
#define TIMERMASK(NAME) _TIMSK(NAME)
#define _OCRA(NAME) OCR ## NAME ## A
#define OCRA(NAME) _OCRA(NAME)
#define _DDR(NAME) DDR ## NAME
#define DDR(NAME) _DDR(NAME)
#define __PULLUP(REG, PORT, PIN) REG ## PORT |= _BV(PIN)
#define _PULLUP(REG, PORT, PIN) __PULLUP(REG, PORT, PIN)
#define PULLUP(PORT, PIN) _PULLUP(PORT_PULLUP_REG, PORT, PIN)
#define INT0_ANY (_BV(ISC00))
#define STATE_START 255
#define STATE_CALCULATE_PRESCALER 254
#define STATE_NORMAL (counter < 254)
#define STATE_STARTUP (counter > 15)
#endif
#ifndef DEFM32U4_H_
#define DEFM32U4_H_ 1
#ifndef F_CPU
#define F_CPU 16000000UL
#endif
//IO
//output PD3
#define OUTPUT_PORT D
#define OUTPUT_PIN 3
//button PD1
#define BUTTON_PORT D
#define BUTTON_PIN 1
//clock PD0
#define CLOCK_PORT D
#define CLOCK_PIN 0
//POR ADC0
#define POT_ADC_CHANNEL 7
#define PORT_PULLUP_REG PORT
#define TIMER_vect TIMER0_COMPA_vect
#define TIMER_INDEX 0
#define ADC_PRESCALER (_BV(ADPS2) | _BV(ADPS0) )
#define ADC_AREF (_BV(REFS0))
#define get_adc() (ADC >> 2)
#define setup_power() \
do { \
power_all_disable(); \
power_timer0_enable(); \
power_adc_enable(); \
} while (0)
#endif
#ifndef DEFM328_H_
#define DEFM328_H_ 1
#ifndef F_CPU
#define F_CPU 16000000UL
#endif
//IO
//output PD4
#define OUTPUT_PORT D
#define OUTPUT_PIN 4
//button PD2
#define BUTTON_PORT D
#define BUTTON_PIN 2
//clock PD0
#define CLOCK_PORT D
#define CLOCK_PIN 0
//POR ADC0
#define POT_ADC_CHANNEL 0
#define PORT_PULLUP_REG PORT
#define TIMER_vect TIMER0_COMPA_vect
#define TIMER_INDEX 0
#define ADC_PRESCALER (_BV(ADPS2) | _BV(ADPS0) )
#define ADC_AREF (_BV(REFS0))
#define get_adc() (ADC >> 2)
#define setup_power() \
do { \
power_all_disable(); \
power_timer1_enable(); \
power_adc_enable(); \
} while (0)
#endif
#ifndef DEFM328p_H_
#define DEFM328p_H_ 1
#ifndef F_CPU
#define F_CPU 16000000UL
#endif
//UNO
//CLOCK => 2
//BUTTON => 3
//OUTPUT => 4
//POT => A0
// POT connetion left - Vcc, right - GND, central - ADC
//IO
//output PD4
#define OUTPUT_PORT D
#define OUTPUT_PIN 4
//button PD2
#define BUTTON_PORT D
#define BUTTON_PIN 2
//clock PD0
#define CLOCK_PORT D
#define CLOCK_PIN 0
//POR ADC0
#define POT_ADC_CHANNEL 0
#define PORT_PULLUP_REG PORT
#define TIMER_vect TIMER0_COMPA_vect
#define TIMER_INDEX 0
#define ADC_PRESCALER (_BV(ADPS2) | _BV(ADPS1) | _BV(ADPS0))
#define ADC_AREF (_BV(REFS0))
#define get_adc() (ADC >> 2)
#define setup_power() \
do { \
power_all_disable(); \
power_timer1_enable(); \
power_adc_enable(); \
} while (0)
#endif
#ifndef DEFTN10_H_
#define DEFTN10_H_ 1
#ifndef F_CPU
#define F_CPU 1000000UL
#endif
//IO
//output PB0
#define OUTPUT_PORT B
#define OUTPUT_PIN 0
//button PB1
#define BUTTON_PORT B
#define BUTTON_PIN 1
//clock PB2
#define CLOCK_PORT B
#define CLOCK_PIN 2
//POR ADC3
#define POT_ADC_CHANNEL 3
#define PORT_PULLUP_REG PUE
#define TIMER_vect TIM0_COMPA_vect
#define TIMER_INDEX 0
#define ADC_PRESCALER (_BV(ADPS1))
#define ADC_AREF (0)
#define get_adc() (ADCL)
#define setup_power()
#endif
#ifndef DEFTN85_H_
#define DEFTN85_H_ 1
#ifndef F_CPU
#define F_CPU 2000000UL
#endif
//POT => 2
//GND => 4
//5V => 8
//CLOCK => 7
//OUTPUT => 6
//BUTTON => 5
//IO
//output PB0
#define OUTPUT_PORT B
#define OUTPUT_PIN 1
//button PB1
#define BUTTON_PORT B
#define BUTTON_PIN 0
//clock PB2
#define CLOCK_PORT B
#define CLOCK_PIN 2
//POR ADC3
#define POT_ADC_CHANNEL 3
#define PORT_PULLUP_REG PORT
#define TIMER_vect TIM0_COMPA_vect
#define TIMER_INDEX 0
#define TIMER_MASK
#define INT_REG GIMSK
#define INT_TYPE_REG MCUCR
#define ADC_PRESCALER (_BV(ADPS0))
#define ADC_AREF (0)
#define get_adc() (ADC >> 2)
#define setup_power() \
do { \
power_all_disable(); \
power_timer0_enable(); \
power_adc_enable(); \
} while (0)
#endif
#include "def.h"
uint8_t counter;
uint8_t data[16];
uint8_t timeout;
uint8_t prescaler;
ISR(TIMER_vect, ISR_NAKED)
{
if(STATE_NORMAL) {
PORT(OUTPUT_PORT) |= _BV(OUTPUT_PIN);
//disable timer
TCCRB(TIMER_INDEX) = 0;
//request ADC0
ADCSRA = _BV(ADSC) | _BV(ADEN) | ADC_PRESCALER | _BV(ADIE);
reti();
}
reti();
}
ISR(INT0_vect, ISR_NAKED)
{
if(STATE_NORMAL) {
if (PIN(CLOCK_PORT) & _BV(CLOCK_PIN)) {
//enable timer with prescaler
TCCRB(TIMER_INDEX) = prescaler;
//reset timer counter
TCNT(TIMER_INDEX) = 0;
reti();
}
//disable timer
TCCRB(TIMER_INDEX) = 0;
if (STATE_STARTUP) {
reti();
}
if (data[counter]) {
PORT(OUTPUT_PORT) &= ~_BV(OUTPUT_PIN);
}
else {
PORT(OUTPUT_PORT) |= _BV(OUTPUT_PIN);
}
counter++;
reti();
} else {
if (PIN(CLOCK_PORT) & _BV(CLOCK_PIN)) {
uint8_t temp = TCNT(TIMER_INDEX);
if(counter == STATE_CALCULATE_PRESCALER) {
if(temp < 32) {
--prescaler;
TCCRB(TIMER_INDEX) = prescaler;
reti();
} else {
counter--;
OCRA(TIMER_INDEX) = temp + 2;
TCCRB(TIMER_INDEX) = 0;
TCNT(TIMER_INDEX) = 0;
reti();
}
}
reti();
} else {
TCNT(TIMER_INDEX) = 0;
counter = STATE_CALCULATE_PRESCALER;
reti();
}
}
}
ISR(ADC_vect, ISR_NAKED)
{
ADCSRA = _BV(ADIF);
uint8_t value = get_adc();
for (uint8_t i = 0; i < 8; i++) {
data[i] = value & 0b10000000;
value <<= 1;
}
data[8] = !(PIN(BUTTON_PORT) & _BV(BUTTON_PIN));
counter = 0;
reti();
}
int main(void)
{
cli();
counter = STATE_START;
//starting with 1024 prescaler
prescaler = 5;
data[8] = 0;
//test bits
data[13] = 1;
data[15] = 1;
#if POWER_OPTIMIZATION
setup_power();
#endif
set_sleep_mode(SLEEP_MODE_IDLE);
sleep_enable();
//output
DDR(OUTPUT_PORT) = _BV(OUTPUT_PIN);
//pull-ups
PULLUP(CLOCK_PORT, CLOCK_PIN);
PULLUP(BUTTON_PORT, BUTTON_PIN);
PORT(OUTPUT_PORT) |= _BV(OUTPUT_PIN);
//adc
ADMUX = POT_ADC_CHANNEL | ADC_AREF;
ADCSRA = _BV(ADIF);
//init timer
TCCRA(TIMER_INDEX) = 0;
TCCRB(TIMER_INDEX) = prescaler;
//set timer compare value
OCRA(TIMER_INDEX) = 255;
//enable compare interrupt
TIMERMASK(TIMER_MASK) = _BV(OCIE0A);
//int0
INT_REG = _BV(INT0);
INT_TYPE_REG = INT0_ANY;
sei();
while (true) {
sleep_cpu();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment