@ -9,21 +9,13 @@
* Use LP timer on Kinetises , TIM14 on STM32F0 .
*/
# if defined(KL2x) || defined(K20x)
/* Use Low Power Timer (LPTMR) */
# define TIMER_INTERRUPT_VECTOR KINETIS_LPTMR0_IRQ_VECTOR
# define RESET_COUNTER LPTMR0->CSR |= LPTMRx_CSR_TCF
# elif defined(STM32F0XX)
/* Use TIM14 manually */
# define TIMER_INTERRUPT_VECTOR STM32_TIM14_HANDLER
# define RESET_COUNTER STM32_TIM14->SR &= ~STM32_TIM_SR_UIF
# ifndef SLEEP_LED_GPT_DRIVER
# if defined(STM32F0XX)
# define SLEEP_LED_GPT_DRIVER GPTD14
# endif
# endif
# if defined(KL2x) || defined(K20x) || defined(S TM32F0XX ) /* common parts for timers/interrupts */
# if defined(KL2x) || defined(K20x) || defined(SLEEP_LED_GPT_DRIVER) /* common parts for timers/interrupts */
/* Breathing Sleep LED brighness(PWM On period) table
* ( 64 [ steps ] * 4 [ duration ] ) / 64 [ PWM periods / s ] = 4 second breath cycle
@ -33,10 +25,7 @@
*/
static const uint8_t breathing_table [ 64 ] = { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 2 , 4 , 6 , 10 , 15 , 23 , 32 , 44 , 58 , 74 , 93 , 113 , 135 , 157 , 179 , 199 , 218 , 233 , 245 , 252 , 255 , 252 , 245 , 233 , 218 , 199 , 179 , 157 , 135 , 113 , 93 , 74 , 58 , 44 , 32 , 23 , 15 , 10 , 6 , 4 , 2 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ;
/* interrupt handler */
OSAL_IRQ_HANDLER ( TIMER_INTERRUPT_VECTOR ) {
OSAL_IRQ_PROLOGUE ( ) ;
void sleep_led_timer_callback ( void ) {
/* Software PWM
* timer : 1111 1111 1111 1111
* \ _____ / \ / \ _______ / ____ count ( 0 - 255 )
@ -64,17 +53,16 @@ OSAL_IRQ_HANDLER(TIMER_INTERRUPT_VECTOR) {
if ( timer . pwm . count = = breathing_table [ timer . pwm . index ] ) {
led_set ( 0 ) ;
}
/* Reset the counter */
RESET_COUNTER ;
OSAL_IRQ_EPILOGUE ( ) ;
}
# endif /* common parts for known platforms */
# if defined(KL2x) || defined(K20x) /* platform selection: familiar Kinetis chips */
/* Use Low Power Timer (LPTMR) */
# define TIMER_INTERRUPT_VECTOR KINETIS_LPTMR0_IRQ_VECTOR
# define RESET_COUNTER LPTMR0->CSR |= LPTMRx_CSR_TCF
/* LPTMR clock options */
# define LPTMR_CLOCK_MCGIRCLK 0 /* 4MHz clock */
# define LPTMR_CLOCK_LPO 1 /* 1kHz clock */
@ -86,6 +74,18 @@ OSAL_IRQ_HANDLER(TIMER_INTERRUPT_VECTOR) {
# define SIM_SCGC5_LPTMR SIM_SCGC5_LPTIMER
# endif
/* interrupt handler */
OSAL_IRQ_HANDLER ( TIMER_INTERRUPT_VECTOR ) {
OSAL_IRQ_PROLOGUE ( ) ;
sleep_led_timer_callback ( ) ;
/* Reset the counter */
RESET_COUNTER ;
OSAL_IRQ_EPILOGUE ( ) ;
}
/* Initialise the timer */
void sleep_led_init ( void ) {
/* Make sure the clock to the LPTMR is enabled */
@ -159,45 +159,23 @@ void sleep_led_toggle(void) {
LPTMR0 - > CSR ^ = LPTMRx_CSR_TEN ;
}
# elif defined(STM32F0XX) /* platform selection: STM32F0XX */
/* Initialise the timer */
void sleep_led_init ( void ) {
/* enable clock */
rccEnableTIM14 ( FALSE ) ; /* low power enable = FALSE */
rccResetTIM14 ( ) ;
/* prescale */
/* Assuming 48MHz internal clock */
/* getting cca 65484 irqs/sec */
STM32_TIM14 - > PSC = 733 ;
# elif defined(SLEEP_LED_GPT_DRIVER)
/* auto-reload */
/* 0 => interrupt every time */
STM32_TIM14 - > ARR = 3 ;
static void gptTimerCallback ( GPTDriver * gptp ) {
( void ) gptp ;
sleep_led_timer_callback ( ) ;
}
/* enable counter update event interrupt */
STM32_TIM14 - > DIER | = STM32_TIM_DIER_UIE ;
static const GPTConfig gptcfg = { 1000000 , gptTimerCallback , 0 , 0 } ;
/* register interrupt vector */
nvicEnableVector ( STM32_TIM14_NUMBER , 2 ) ; /* vector, priority */
}
/* Initialise the timer */
void sleep_led_init ( void ) { gptStart ( & SLEEP_LED_GPT_DRIVER , & gptcfg ) ; }
void sleep_led_enable ( void ) {
/* Enable the timer */
STM32_TIM14 - > CR1 = STM32_TIM_CR1_CEN | STM32_TIM_CR1_URS ;
/* URS => update event only on overflow; setting UG bit disabled */
}
void sleep_led_enable ( void ) { gptStartContinuous ( & SLEEP_LED_GPT_DRIVER , gptcfg . frequency / 0xFFFF ) ; }
void sleep_led_disable ( void ) {
/* Disable the timer */
STM32_TIM14 - > CR1 = 0 ;
}
void sleep_led_disable ( void ) { gptStopTimer ( & SLEEP_LED_GPT_DRIVER ) ; }
void sleep_led_toggle ( void ) {
/* Toggle the timer */
STM32_TIM14 - > CR1 ^ = STM32_TIM_CR1_CEN ;
}
void sleep_led_toggle ( void ) { ( SLEEP_LED_GPT_DRIVER . state = = GPT_READY ) ? sleep_led_enable ( ) : sleep_led_disable ( ) ; }
# else /* platform selection: not on familiar chips */