Skip to content

Instantly share code, notes, and snippets.

@kvalv
Created April 26, 2016 11:28
Show Gist options
  • Select an option

  • Save kvalv/f23df1233e32d6a63570f8177319feb5 to your computer and use it in GitHub Desktop.

Select an option

Save kvalv/f23df1233e32d6a63570f8177319feb5 to your computer and use it in GitHub Desktop.
/*
* timer.c
*
* Created: 17.04.2016 14:28:20
* Author: mikaelpc
*/
#include <avr/interrupt.h>
#include <stdlib.h>
#include "timer.h"
#include "../LED.h"
#define OCR1A_VAL 16000
typedef struct TimerInternal
{
bool isTriggered;
uint32_t triggerValue;
uint32_t countBuffer;
bool isEnabled;
bool isRegistered;
} TimerInternal;
static volatile TimerInternal** timerArray;
static uint8_t maxNumBuffers;
void timer_setClockInterruptFrequency ( const uint16_t interruptFrequency )
{
// Set the waveform generating mode to mode 4.
//TCCR1B &= ~(1 << WGM13);
TCCR1B |= ( 1 << 3 );
//TCCR1B &= ~(1 << WGM11);
//TCCR1B &= ~(1 << WGM10);
TIMSK1 |= ( 1 << OCIE1A );
#if OCR1A_VAL != 16000
#pragma message "Warning: OCR1A-value set so interrupt frequency is not 1000Hz, as it's supposed to be - timer.h-module may not function properly"
#endif
OCR1A = OCR1A_VAL;
const uint8_t prescaler_bp = 0;
TCCR1B |= ( (uint8_t) AtmegaTimer_prescaler_1 << prescaler_bp );
}
bool timer_allocateTimerBuffers ( const uint8_t numBuffers )
{
timerArray = malloc( sizeof(TimerInternal*) * numBuffers );
if ( timerArray == NULL )
{
return false;
}
volatile TimerInternal* iTimer;
for ( uint8_t i = 0; i < numBuffers; i+= 1 )
{
*(timerArray+i) = malloc( sizeof(TimerInternal) );
if ( *(timerArray+i) == NULL )
{
return false;
}
iTimer = *(timerArray + i);
iTimer->countBuffer = 0;
iTimer->isEnabled = false;
iTimer->isRegistered = false;
iTimer->triggerValue = 0;
}
maxNumBuffers = numBuffers;
return true;
}
Timer* timer_getNewTimer ( const float triggerFrequency )
{
bool foundNewTimer = false;
volatile TimerInternal* newTimer;
for ( uint8_t i = 0; i < maxNumBuffers; i+= 1 )
{
newTimer = *(timerArray+i);
if ( !newTimer->isRegistered )
{
foundNewTimer = true;
break;
}
}
if ( !foundNewTimer )
{
return NULL;
}
else
{
newTimer->isRegistered = true;
newTimer->isTriggered = false;
timer_setFrequency( (Timer*)newTimer, triggerFrequency );
newTimer->countBuffer = rand() % newTimer->triggerValue;
return (Timer*)newTimer;
}
}
bool timer_enableTimer ( Timer* timer )
{
TimerInternal* iTimer = (TimerInternal*) timer;
// if ( iTimer->isRegistered || iTimer->triggerValue == 0 )
// {
// return false;
// }
iTimer->isEnabled = true;
iTimer->countBuffer = 0;
return true;
}
bool timer_disableTimer ( Timer* timer )
{
TimerInternal* iTimer = (TimerInternal*) timer;
if ( !iTimer->isRegistered )
{
return false;
}
iTimer->isEnabled = false;
iTimer->countBuffer = 0;
return true;
}
void timer_resetTimer ( Timer* timer )
{
volatile TimerInternal* iTimer = (TimerInternal*) timer;
volatile int myVal = timer->isTriggered + 2;
iTimer->isTriggered = false;
cli();
iTimer->countBuffer = 0;
sei();
}
bool timer_setFrequency ( Timer* timer, const float triggerFrequency )
{
TimerInternal* iTimer = (TimerInternal*) timer;
if ( !iTimer->isRegistered )
{
return false;
}
iTimer->triggerValue = (uint32_t) ( (float)1000 / triggerFrequency );
return true;
}
void timer_incrementTimers ( void )
{
volatile TimerInternal* iTimer;
for ( uint8_t i = 0; i < maxNumBuffers; i++ )
{
iTimer = *(timerArray+i);
volatile uint16_t countB;
volatile uint16_t triggV;
if ( iTimer->isRegistered && iTimer->isEnabled )
{
iTimer->countBuffer ++;
if ( iTimer->countBuffer >= iTimer->triggerValue )
{
iTimer->isTriggered = true;
//iTimer->countBuffer = 0;
}
}
}
}
/*
* timer.h
*
* Created: 17.04.2016 14:11:42
* Author: mikaelpc
*/
#ifndef TIMER_H_
#define TIMER_H_
#include <avr/io.h>
#include <stdbool.h>
typedef enum AtmegaTimer_Prescaler
{
AtmegaTimer_prescaler_1 = 1,
AtmegaTimer_prescaler_8,
AtmegaTimer_prescaler_64,
AtmegaTimer_prescaler_256,
AtmegaTimer_prescaler_1024
} AtmegaTimer_Prescaler;
typedef struct Timer {
bool isTriggered;
} Timer;
void timer_setClockInterruptFrequency ( const uint16_t interruptFrequency );
bool timer_allocateTimerBuffers ( const uint8_t maxNumBuffers );
Timer* timer_getNewTimer ( const float triggerFrequency );
bool timer_enableTimer ( Timer* timer );
bool timer_disableTimer ( Timer* timer );
void timer_resetTimer ( Timer* timer );
bool timer_setFrequency ( Timer* timer, const float triggerFrequency );
void timer_incrementTimers ( void );
#endif /* TIMER_H_ */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment