generated from TDD-Templates/cmake_cpputest_template_avr
removed uneeded lines
This commit is contained in:
parent
ce3e50a3cb
commit
079305033a
438
src/main.c
438
src/main.c
|
@ -7,17 +7,16 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include <avr/interrupt.h>
|
|
||||||
#include <avr/eeprom.h>
|
#include <avr/eeprom.h>
|
||||||
|
#include <avr/interrupt.h>
|
||||||
#include <util/delay.h>
|
#include <util/delay.h>
|
||||||
|
|
||||||
|
// #############################
|
||||||
//#############################
|
// Globals
|
||||||
//Globals
|
// #############################
|
||||||
//#############################
|
|
||||||
|
|
||||||
/* This line isn't really quite right.*/
|
/* This line isn't really quite right.*/
|
||||||
//uint8_t saved_position EEMEM; // EEPROM storage for fader position
|
// uint8_t saved_position EEMEM; // EEPROM storage for fader position
|
||||||
|
|
||||||
btn_state btn1;
|
btn_state btn1;
|
||||||
|
|
||||||
|
@ -28,16 +27,9 @@ volatile uint8_t idx;
|
||||||
|
|
||||||
volatile uint16_t tick_count;
|
volatile uint16_t tick_count;
|
||||||
|
|
||||||
//#############################
|
// #############################
|
||||||
//Prototypes
|
// Prototypes
|
||||||
//#############################
|
// #############################
|
||||||
|
|
||||||
void led_blink(void);
|
|
||||||
|
|
||||||
uint16_t readADC(void);
|
|
||||||
void motorCoast(void);
|
|
||||||
void motorMove(int direction);
|
|
||||||
uint8_t readButton(void);
|
|
||||||
|
|
||||||
|
|
||||||
static void InitBtn(btn_state *b, uint8_t input_pin, uint8_t output_pin);
|
static void InitBtn(btn_state *b, uint8_t input_pin, uint8_t output_pin);
|
||||||
|
@ -48,230 +40,209 @@ static void CheckButtonLongpress(btn_state *b);
|
||||||
static void UpdateButtonInput(btn_state *b);
|
static void UpdateButtonInput(btn_state *b);
|
||||||
static void UpdateButtonOutput(btn_state *b);
|
static void UpdateButtonOutput(btn_state *b);
|
||||||
|
|
||||||
|
// #############################
|
||||||
|
// MAIN
|
||||||
|
// #############################
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
InitProg();
|
||||||
|
|
||||||
|
uint16_t fader_pos = ReadADC() >> 2; // Scale 10-bit ADC to 8-bit (0-255)
|
||||||
|
|
||||||
//#############################
|
while (1) {
|
||||||
//MAIN
|
fader_pos = ReadADC() >> 2;
|
||||||
//#############################
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
InitProg();
|
|
||||||
|
|
||||||
uint16_t fader_pos = ReadADC() >> 2; // Scale 10-bit ADC to 8-bit (0-255)
|
|
||||||
|
|
||||||
while(1)
|
|
||||||
{
|
|
||||||
fader_pos = ReadADC() >> 2;
|
|
||||||
|
|
||||||
/*
|
|
||||||
UpdateButtonOutput(&btn1);
|
|
||||||
UpdateButtonInput(&btn1);
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
while(1) {
|
UpdateButtonOutput(&btn1);
|
||||||
uint16_t fader_pos = readADC() >> 2; // Scale 10-bit ADC to 8-bit (0-255)
|
UpdateButtonInput(&btn1);
|
||||||
uint8_t buttonState = readButton();
|
|
||||||
|
|
||||||
if (buttonState == 2) { // Long press - Save position
|
|
||||||
eeprom_update_byte(&saved_position, fader_pos);
|
|
||||||
}
|
|
||||||
else if (buttonState == 1) { // Short press - Move to saved position
|
|
||||||
uint8_t target_pos = eeprom_read_byte(&saved_position);
|
|
||||||
if (fader_pos < target_pos - 2) motorMove(1); // Move up
|
|
||||||
else if (fader_pos > target_pos + 2) motorMove(-1); // Move down
|
|
||||||
else motorCoast(); // Stop when reached position
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
motorCoast(); // Default to coast mode
|
|
||||||
}
|
|
||||||
|
|
||||||
led_blink();
|
|
||||||
|
|
||||||
}
|
|
||||||
*/
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
/*
|
||||||
|
while(1) {
|
||||||
|
uint16_t fader_pos = readADC() >> 2; // Scale 10-bit ADC to 8-bit (0-255)
|
||||||
|
uint8_t buttonState = readButton();
|
||||||
|
|
||||||
|
if (buttonState == 2) { // Long press - Save position
|
||||||
|
eeprom_update_byte(&saved_position, fader_pos);
|
||||||
|
}
|
||||||
|
else if (buttonState == 1) { // Short press - Move to saved position
|
||||||
|
uint8_t target_pos = eeprom_read_byte(&saved_position);
|
||||||
|
if (fader_pos < target_pos - 2) motorMove(1); // Move up
|
||||||
|
else if (fader_pos > target_pos + 2) motorMove(-1); // Move down
|
||||||
|
else motorCoast(); // Stop when reached position
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
motorCoast(); // Default to coast mode
|
||||||
|
}
|
||||||
|
|
||||||
|
led_blink();
|
||||||
|
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// #############################
|
||||||
|
// FUNCTIONS
|
||||||
|
// #############################
|
||||||
|
|
||||||
//#############################
|
void InitProg(void) {
|
||||||
//FUNCTIONS
|
/*Set the debounced state to all high*/
|
||||||
//#############################
|
debounced_state = 0xFF;
|
||||||
|
|
||||||
|
init_btn(&btn1, PIN_SW1, PIN_ACTIVE1);
|
||||||
|
|
||||||
void InitProg(void)
|
/*Wait 5ms for pull-up resistors voltage to become stable.*/
|
||||||
{
|
_delay_ms(5);
|
||||||
/*Set the debounced state to all high*/
|
|
||||||
debounced_state = 0xFF;
|
|
||||||
|
|
||||||
init_btn(&btn1, PIN_SW1, PIN_ACTIVE1);
|
/*check if the eeprom has info. */
|
||||||
|
while (!eeprom_is_ready()) {
|
||||||
|
} // Blocks until eeprom is ready.
|
||||||
|
|
||||||
/*Wait 5ms for pull-up resistors voltage to become stable.*/
|
// Checks against a bit pattern we defined to represent the start of data.
|
||||||
_delay_ms(5);
|
if (eeprom_read_byte((uint8_t *)ROM_SP_ADR) == START_PATTERN) {
|
||||||
|
// Reads the two bytes representing the two states.
|
||||||
|
btn1.is_active = eeprom_read_byte((uint8_t *)ROM_SS1_ADR);
|
||||||
|
} else {
|
||||||
|
// otherwise we write the init values for the start pattern and states.
|
||||||
|
eeprom_write_byte((uint8_t *)ROM_SP_ADR, START_PATTERN);
|
||||||
|
eeprom_write_byte((uint8_t *)ROM_SS1_ADR, 0x0);
|
||||||
|
}
|
||||||
|
|
||||||
/*check if the eeprom has info. */
|
btn1.is_pressed = ((PINB & (1 << btn1.input_pin)) == 0);
|
||||||
while(! eeprom_is_ready()) {} //Blocks until eeprom is ready.
|
|
||||||
|
|
||||||
//Checks against a bit pattern we defined to represent the start of data.
|
InitTimer0();
|
||||||
if(eeprom_read_byte((uint8_t *)ROM_SP_ADR) == START_PATTERN) {
|
|
||||||
//Reads the two bytes representing the two states.
|
|
||||||
btn1.is_active = eeprom_read_byte((uint8_t *)ROM_SS1_ADR);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
//otherwise we write the init values for the start pattern and states.
|
|
||||||
eeprom_write_byte((uint8_t *)ROM_SP_ADR, START_PATTERN);
|
|
||||||
eeprom_write_byte((uint8_t *)ROM_SS1_ADR, 0x0);
|
|
||||||
}
|
|
||||||
|
|
||||||
btn1.is_pressed = ((PINB & (1<<btn1.input_pin)) == 0);
|
|
||||||
|
|
||||||
InitTimer0();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint16_t ReadADC(void);
|
uint16_t ReadADC(void);
|
||||||
{
|
{
|
||||||
// Initialize ADC
|
// Initialize ADC
|
||||||
ADMUX = (1 << MUX1) | (1 << MUX0); // Select ADC3 (PB3)
|
ADMUX = (1 << MUX1) | (1 << MUX0); // Select ADC3 (PB3)
|
||||||
ADCSRA = (1 << ADEN) | (1 << ADPS1) | (1 << ADPS0); // Enable ADC, prescaler 8
|
ADCSRA = (1 << ADEN) | (1 << ADPS1) | (1 << ADPS0); // Enable ADC, prescaler 8
|
||||||
|
|
||||||
ADCSRA |= (1 << ADSC); // Start conversion
|
ADCSRA |= (1 << ADSC); // Start conversion
|
||||||
while (ADCSRA & (1 << ADSC)); // Wait for conversion to finish
|
while (ADCSRA & (1 << ADSC))
|
||||||
return ADC;
|
; // Wait for conversion to finish
|
||||||
|
return ADC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ############################
|
* ############################
|
||||||
* Motor methods
|
* Motor methods
|
||||||
* ############################
|
* ############################
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void MotorCoast(void)
|
void MotorCoast(void) {
|
||||||
{
|
PORTB &= ~((1 << PWM_PIN1) | (1 << PWM_PIN2)); // Disable motor drive
|
||||||
PORTB &= ~((1 << PWM_PIN1) | (1 << PWM_PIN2)); // Disable motor drive
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ############################
|
* ############################
|
||||||
* BUTTON methods
|
* BUTTON methods
|
||||||
* ############################
|
* ############################
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*This is kinda like our button constructor*/
|
/*This is kinda like our button constructor*/
|
||||||
static void InitBtn(btn_state *b, uint8_t input_pin, uint8_t output_pin)
|
static void InitBtn(btn_state *b, uint8_t input_pin, uint8_t output_pin) {
|
||||||
{
|
b->is_long_pressed = 0;
|
||||||
b->is_long_pressed = 0;
|
b->is_pressed = 0;
|
||||||
b->is_pressed = 0;
|
b->is_bypassed = 0;
|
||||||
b->is_bypassed = 0;
|
b->pressed_ticks = 0;
|
||||||
b->pressed_ticks = 0;
|
b->timer_enabled = 0;
|
||||||
b->timer_enabled = 0;
|
b->input_pin = input_pin;
|
||||||
b->input_pin = input_pin;
|
b->output_pin = output_pin;
|
||||||
b->output_pin = output_pin;
|
|
||||||
|
|
||||||
/*Configure the buttons inputs and outputs*/
|
/*Configure the buttons inputs and outputs*/
|
||||||
DDRB &= ~(1<<b->input_pin);
|
DDRB &= ~(1 << b->input_pin);
|
||||||
PORTB |= (1<<b->input_pin);
|
PORTB |= (1 << b->input_pin);
|
||||||
|
|
||||||
DDRB |= (1<<b->output_pin);
|
DDRB |= (1 << b->output_pin);
|
||||||
PORTB &= ~(1<<b->output_pin);
|
PORTB &= ~(1 << b->output_pin);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*This is the fancy function to toggle output pins*/
|
/*This is the fancy function to toggle output pins*/
|
||||||
static void ToggleOutput(btn_state *b)
|
static void ToggleOutput(btn_state *b) {
|
||||||
{
|
if (!b->is_bypassed) {
|
||||||
if(!b->is_bypassed){
|
b->is_bypassed = 1;
|
||||||
b->is_bypassed = 1;
|
PORTB |= (1 << b->output_pin);
|
||||||
PORTB |= (1<<b->output_pin);
|
} else {
|
||||||
}
|
b->is_bypassed = 0;
|
||||||
else{
|
PORTB &= ~(1 << b->output_pin);
|
||||||
b->is_bypassed = 0;
|
}
|
||||||
PORTB &= ~(1<<b->output_pin);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ClearButtonTimer(btn_state *b)
|
static void ClearButtonTimer(btn_state *b) {
|
||||||
{
|
b->timer_enabled = 0;
|
||||||
|
b->is_long_pressed = 0;
|
||||||
|
b->pressed_ticks = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void StartButtonTimer(btn_state *b) {
|
||||||
|
ClearButtonTimer(b);
|
||||||
|
b->timer_enabled = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void CheckButtonLongpress(btn_state *b) {
|
||||||
|
if (b->pressed_ticks >= LONG_PRESS_TICKS) {
|
||||||
|
b->is_long_pressed = 1;
|
||||||
b->timer_enabled = 0;
|
b->timer_enabled = 0;
|
||||||
b->is_long_pressed = 0;
|
}
|
||||||
b->pressed_ticks = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void StartButtonTimer(btn_state *b)
|
static void UpdateButtonInput(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 UpdateButtonOutput(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*/
|
||||||
|
ToggleOutput(b);
|
||||||
|
StartButtonTimer(b);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*If the timer is already going.*/
|
||||||
|
else if (b->timer_enabled) {
|
||||||
|
/*Then just check if it's hit the threshold.*/
|
||||||
|
CheckButtonLongpress(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) {
|
||||||
|
ToggleOutput(b);
|
||||||
|
}
|
||||||
ClearButtonTimer(b);
|
ClearButtonTimer(b);
|
||||||
b->timer_enabled = 1;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void CheckButtonLongpress(btn_state *b)
|
|
||||||
{
|
|
||||||
if(b->pressed_ticks >= LONG_PRESS_TICKS) {
|
|
||||||
b->is_long_pressed = 1;
|
|
||||||
b->timer_enabled = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void UpdateButtonInput(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 UpdateButtonOutput(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*/
|
|
||||||
ToggleOutput(b);
|
|
||||||
StartButtonTimer(b);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*If the timer is already going.*/
|
|
||||||
else if(b->timer_enabled){
|
|
||||||
/*Then just check if it's hit the threshold.*/
|
|
||||||
CheckButtonLongpress(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){
|
|
||||||
ToggleOutput(b);
|
|
||||||
}
|
|
||||||
ClearButtonTimer(b);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ############################
|
* ############################
|
||||||
* DEBOUNCING CODE
|
* DEBOUNCING CODE
|
||||||
* ############################
|
* ############################
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* INPUT: The port to check.
|
* INPUT: The port to check.
|
||||||
|
@ -279,65 +250,58 @@ static void UpdateButtonOutput(btn_state *b)
|
||||||
* DESCRIPTION: Updates the global debounced state. This function
|
* DESCRIPTION: Updates the global debounced state. This function
|
||||||
* should be called in a ISR a set rate using the hardware timer.
|
* should be called in a ISR a set rate using the hardware timer.
|
||||||
*/
|
*/
|
||||||
static inline void DebounceSwitch()
|
static inline void DebounceSwitch() {
|
||||||
{
|
uint8_t i, j;
|
||||||
uint8_t i, j;
|
db_state[idx] = PINB & 0xFF;
|
||||||
db_state[idx] = PINB & 0xFF;
|
idx += 1;
|
||||||
idx+=1;
|
j = 0xff;
|
||||||
j = 0xff;
|
/*Loop through a number of checks*/
|
||||||
/*Loop through a number of checks*/
|
for (i = 0; i < MAX_CHECKS; i++) {
|
||||||
for(i = 0; i < MAX_CHECKS; i++) {
|
j = j & db_state[i];
|
||||||
j = j & db_state[i];
|
}
|
||||||
}
|
debounced_state = j;
|
||||||
debounced_state = j;
|
|
||||||
|
|
||||||
if(idx >= MAX_CHECKS) {
|
if (idx >= MAX_CHECKS) {
|
||||||
idx = 0;
|
idx = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*Setup the timer0 on the AVR*/
|
/*Setup the timer0 on the AVR*/
|
||||||
static inline void InitTimer0()
|
static inline void InitTimer0() {
|
||||||
{
|
/*Zero out the tick_count var*/
|
||||||
/*Zero out the tick_count var*/
|
tick_count = 0;
|
||||||
tick_count = 0;
|
|
||||||
|
|
||||||
/*config to normal mode.*/
|
/*config to normal mode.*/
|
||||||
TCCR0A = 0x00; //stop timer
|
TCCR0A = 0x00; // stop timer
|
||||||
TCCR0B = 0x00; //zero timer
|
TCCR0B = 0x00; // zero timer
|
||||||
|
|
||||||
/*set prescaler*/
|
/*set prescaler*/
|
||||||
//Set to div64
|
// Set to div64
|
||||||
TCCR0B |= (1<<CS01)|(1<<CS00);
|
TCCR0B |= (1 << CS01) | (1 << CS00);
|
||||||
|
|
||||||
|
/*Enable global interrupts*/
|
||||||
/*Enable global interrupts*/
|
sei();
|
||||||
sei();
|
|
||||||
|
|
||||||
/*Enabling timer0 interrupt*/
|
/*Enabling timer0 interrupt*/
|
||||||
TCNT0 = 0;
|
TCNT0 = 0;
|
||||||
TIMSK0 |= (1<<TOIE0);
|
TIMSK0 |= (1 << TOIE0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ISR(TIMER0_OVF_vect)
|
||||||
//ISR(TIMER0_OVF_vect)
|
|
||||||
|
|
||||||
/*The interrupt service routine for the timer0*/
|
/*The interrupt service routine for the timer0*/
|
||||||
ISR(TIM0_OVF_vect)
|
ISR(TIM0_OVF_vect) {
|
||||||
{
|
/*Disable global interrupts*/
|
||||||
/*Disable global interrupts*/
|
cli();
|
||||||
cli();
|
|
||||||
|
|
||||||
/*Check the state of the switches*/
|
/*Check the state of the switches*/
|
||||||
DebounceSwitch();
|
DebounceSwitch();
|
||||||
|
|
||||||
/*Update the tick_count*/
|
/*Update the tick_count*/
|
||||||
if(btn1.timer_enabled && btn1.pressed_ticks <= UINT8_MAX){
|
if (btn1.timer_enabled && btn1.pressed_ticks <= UINT8_MAX) {
|
||||||
btn1.pressed_ticks += 1;
|
btn1.pressed_ticks += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*Re-Enable global interrupts*/
|
/*Re-Enable global interrupts*/
|
||||||
sei();
|
sei();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue