-
-
Save kvalv/f23df1233e32d6a63570f8177319feb5 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* | |
| * 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; | |
| } | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* | |
| * 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