diff --git a/sketches/pendulum/color_hsv.c b/sketches/pendulum/color_hsv.c index bdd1228..d609299 100644 --- a/sketches/pendulum/color_hsv.c +++ b/sketches/pendulum/color_hsv.c @@ -40,13 +40,12 @@ rgb_t hsv2rgb(hsv_t* hsv) { switch(h) { case 0: - case 6: res.r = hsv->val; res.g = t; res.b = p; break; - case 1: res.r = q; res.g = hsv->val; res.b = p; break; - case 2: res.r = p; res.g = hsv->val; res.b = t; break; - case 3: res.r = p; res.g = q; res.b = hsv->val; break; - case 4: res.r = t; res.g = p; res.b = hsv->val; break; - case 5: res.r = hsv->hue; res.g = p; res.b = q; break; - + case 6: res.r = hsv->val; res.g = t; res.b = p; break; + case 1: res.r = q; res.g = hsv->val; res.b = p; break; + case 2: res.r = p; res.g = hsv->val; res.b = t; break; + case 3: res.r = p; res.g = q; res.b = hsv->val; break; + case 4: res.r = t; res.g = p; res.b = hsv->val; break; + case 5: res.r = hsv->hue; res.g = p; res.b = q; break; } } return res; diff --git a/sketches/pendulum/timer.c b/sketches/pendulum/timer.c new file mode 100644 index 0000000..cb9e611 --- /dev/null +++ b/sketches/pendulum/timer.c @@ -0,0 +1,53 @@ +#include "timer.h" +#include "timer_macros.h" + +void timer_init(void) +{ + //// Timer0 + // prescaler + TCCR0B &= TCCRnB_CSn_CLEAR; + TCCR0B |= TCCR0B_CS0_prescale1; + // interrupt mask + TIMSK0 &= TIMSKn_ENABLE_INTERRUPT_CLEAR; + TIMSK0 |= TIMSK0_ENABLE_INTERRUPT_on_nothing; + + //// Timer1 + // prescaler + TCCR1B &= TCCRnB_CSn_CLEAR; + TCCR1B |= TCCR1B_CS1_prescale256; + // interrupt mask + TIMSK1 &= TIMSKn_ENABLE_INTERRUPT_CLEAR; + TIMSK1 |= TIMSK1_ENABLE_INTERRUPT_on_overflow; + + SREG |= 0x80; // Status Register + // Enable global interrupts +} + +void timer_reset(void) +{ + TCNT0 = 0; + TCNT1 = 0; + highBits32 = 0; + highBits64 = 0; +} + +// ISR(TIMER1_OVF_vect) +void timer_overflow(void) +{ + highBits32 += 0x01000000; + highBits64 += 0x0000000001000000; +} + +uint32_t timer_now32(void) +{ + uint32_t lowBits = TCNT0; + uint32_t middleBits = TCNT1; + return highBits32 | (middleBits<<8) | lowBits; +} + +uint64_t timer_now64(void) +{ + uint64_t lowBits = TCNT0; + uint64_t middleBits = TCNT1; + return highBits64 | (middleBits<<8) | lowBits; +} diff --git a/sketches/pendulum/timer.h b/sketches/pendulum/timer.h new file mode 100644 index 0000000..44a7816 --- /dev/null +++ b/sketches/pendulum/timer.h @@ -0,0 +1,23 @@ +#ifndef _TIMER_H_ +#define _TIMER_H_ + +#include +#include +#include + +void timer_init(void); +void timer_reset(void); +void timer_overflow(void); + +// ISR(TIMER1_OVF_vect); + +uint32_t timer_now32(void); +uint64_t timer_now64(void); + +// counter | Timer1 | Timer0 +// 61(31)...24 | 23...8 | 7...0 <- Bits +// 838.8608ms | 12.8µs | 50ns <- each lowest Bit represents +uint32_t volatile highBits32; // max: ~214.7483648s +uint64_t volatile highBits64; // max: ~29247a + +#endif diff --git a/sketches/pendulum/timer_macros.h b/sketches/pendulum/timer_macros.h new file mode 100644 index 0000000..bd3abcf --- /dev/null +++ b/sketches/pendulum/timer_macros.h @@ -0,0 +1,123 @@ +#ifndef _AVR_MACROS_H_ +#define _AVR_MACROS_H_ + +//// Compare Output Mode for Channel A +#define TCCRnA_COMnA_disconnected 0x00 +#define TCCRnA_COMnA_toggle 0x40 +#define TCCRnA_COMnA_low 0x80 +#define TCCRnA_COMnA_high 0xf0 +#define TCCRnA_COMnA_CLEAR ~ ( TCCRnA_COMnA_disconnected \ + | TCCRnA_COMnA_toggle \ + | TCCRnA_COMnA_low \ + | TCCRnA_COMnA_high ) +// Compare Output Mode for Channel B +#define TCCRnA_COMnB_disconnected 0x00 +#define TCCRnA_COMnB_toggle 0x10 +#define TCCRnA_COMnB_low 0x20 +#define TCCRnA_COMnB_high 0x30 +#define TCCRnA_COMnB_CLEAR ~ ( TCCRnA_COMnB_disconnected \ + | TCCRnA_COMnB_toggle \ + | TCCRnA_COMnB_low \ + | TCCRnA_COMnB_high ) +#define TCCRnB_CSn_CLEAR ~ 0x07 +// Timer/CounterN Interrupt Mask Register +#define TIMSKn_ENABLE_INTERRUPT_on_nothing 0x00 +#define TIMSKn_ENABLE_INTERRUPT_on_overflow 0x01 +#define TIMSKn_ENABLE_INTERRUPT_on_compare_match_A 0x02 +#define TIMSKn_ENABLE_INTERRUPT_on_compare_match_B 0x04 +#define TIMSKn_ENABLE_INTERRUPT_CLEAR ~ ( TIMSKn_ENABLE_INTERRUPT_on_nothing \ + | TIMSKn_ENABLE_INTERRUPT_on_overflow \ + | TIMSKn_ENABLE_INTERRUPT_on_compare_match_A \ + | TIMSKn_ENABLE_INTERRUPT_on_compare_match_B ) +/**********************************************************/ + +// Timer/Counter0 Control Register A +// Compare Output Mode for Channel A +#define TCCR0A_COM0A_disconnected 0x00 +#define TCCR0A_COM0A_toggle 0x40 +#define TCCR0A_COM0A_low 0x80 +#define TCCR0A_COM0A_high 0xf0 +// Compare Output Mode for Channel B +#define TCCR0A_COM0B_disconnected 0x00 +#define TCCR0A_COM0B_toggle 0x10 +#define TCCR0A_COM0B_low 0x20 +#define TCCR0A_COM0B_high 0x30 + +// Timer/Counter0 Control Register B +// Clock Select 0 (prescaler) +#define TCCR0B_CS0_stopped 0x00 +#define TCCR0B_CS0_prescale1 0x01 +#define TCCR0B_CS0_prescale8 0x02 +#define TCCR0B_CS0_prescale64 0x03 +#define TCCR0B_CS0_prescale256 0x04 +#define TCCR0B_CS0_prescale1024 0x05 +#define TCCR0B_CS0_falling_on_T0 0x06 +#define TCCR0B_CS0_rising_on_T0 0x07 + +// Timer/Counter0 Interrupt Mask Register +#define TIMSK0_ENABLE_INTERRUPT_on_nothing 0x00 +#define TIMSK0_ENABLE_INTERRUPT_on_overflow 0x01 +#define TIMSK0_ENABLE_INTERRUPT_on_compare_match_A 0x02 +#define TIMSK0_ENABLE_INTERRUPT_on_compare_match_B 0x04 + + +// Timer/Counter1 Control Register A +// Compare Output Mode for Channel A +#define TCCR1A_COM1A_disconnected 0x00 +#define TCCR1A_COM1A_toggle 0x40 +#define TCCR1A_COM1A_low 0x80 +#define TCCR1A_COM1A_high 0xf0 +// Compare Output Mode for Channel B +#define TCCR1A_COM1B_disconnected 0x00 +#define TCCR1A_COM1B_toggle 0x10 +#define TCCR1A_COM1B_low 0x20 +#define TCCR1A_COM1B_high 0x30 + +// Timer/Counter1 Control Register B +// Clock Select 1 (prescaler) +#define TCCR1B_CS1_stopped 0x00 +#define TCCR1B_CS1_prescale1 0x01 +#define TCCR1B_CS1_prescale8 0x02 +#define TCCR1B_CS1_prescale64 0x03 +#define TCCR1B_CS1_prescale256 0x04 +#define TCCR1B_CS1_prescale1024 0x05 +#define TCCR1B_CS1_falling_on_T1 0x06 +#define TCCR1B_CS1_rising_on_T1 0x07 + +// Timer/Counter1 Interrupt Mask Register +#define TIMSK1_ENABLE_INTERRUPT_on_nothing 0x00 +#define TIMSK1_ENABLE_INTERRUPT_on_overflow 0x01 +#define TIMSK1_ENABLE_INTERRUPT_on_compare_match_A 0x02 +#define TIMSK1_ENABLE_INTERRUPT_on_compare_match_B 0x04 + + +// Timer/Counter2 Control Register A +// Compare Output Mode for Channel A +#define TCCR2A_COM2A_disconnected 0x00 +#define TCCR2A_COM2A_toggle 0x40 +#define TCCR2A_COM2A_low 0x80 +#define TCCR2A_COM2A_high 0xf0 +// Compare Output Mode for Channel B +#define TCCR2A_COM2B_disconnected 0x00 +#define TCCR2A_COM2B_toggle 0x10 +#define TCCR2A_COM2B_low 0x20 +#define TCCR2A_COM2B_high 0x30 + +// Timer/Counter1 Control Register B +// Clock Select 1 (prescaler) +#define TCCR2B_CS2_stopped 0x00 +#define TCCR2B_CS2_prescale1 0x01 +#define TCCR2B_CS2_prescale8 0x02 +#define TCCR2B_CS2_prescale32 0x03 +#define TCCR2B_CS2_prescale64 0x04 +#define TCCR2B_CS2_prescale128 0x05 +#define TCCR2B_CS2_prescale256 0x06 +#define TCCR2B_CS2_prescale1024 0x07 + +// Timer/Counter1 Interrupt Mask Register +#define TIMSK2_ENABLE_INTERRUPT_on_nothing 0x00 +#define TIMSK2_ENABLE_INTERRUPT_on_overflow 0x01 +#define TIMSK2_ENABLE_INTERRUPT_on_compare_match_A 0x02 +#define TIMSK2_ENABLE_INTERRUPT_on_compare_match_B 0x04 + +#endif