169 lines
5.1 KiB
C
169 lines
5.1 KiB
C
/**
|
|
* \addtogroup mbxxx-platform
|
|
*
|
|
* @{
|
|
*/
|
|
|
|
/*
|
|
* Copyright (c) 2010, STMicroelectronics.
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above
|
|
* copyright notice, this list of conditions and the following
|
|
* disclaimer in the documentation and/or other materials provided
|
|
* with the distribution.
|
|
* 3. The name of the author may not be used to endorse or promote
|
|
* products derived from this software without specific prior
|
|
* written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
|
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
|
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*
|
|
*/
|
|
|
|
/**
|
|
* \file
|
|
* Real-timer specific implementation for STM32W.
|
|
* \author
|
|
* Salvatore Pitrulli <salvopitru@users.sourceforge.net>
|
|
*/
|
|
|
|
#include "sys/energest.h"
|
|
#include "sys/rtimer.h"
|
|
|
|
#define DEBUG 0
|
|
#if DEBUG
|
|
#include <stdio.h>
|
|
#define PRINTF(...) printf(__VA_ARGS__)
|
|
#else
|
|
#define PRINTF(...)
|
|
#endif
|
|
|
|
static uint16_t saved_TIM1CFG;
|
|
static uint32_t time_msb = 0; /* Most significant bits of the current time. */
|
|
|
|
/* time of the next rtimer event. Initially is set to the max
|
|
value. */
|
|
static rtimer_clock_t next_rtimer_time = 0;
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
void
|
|
halTimer1Isr(void)
|
|
{
|
|
if(INT_TIM1FLAG & INT_TIMUIF) {
|
|
rtimer_clock_t now, clock_to_wait;
|
|
/* Overflow event. */
|
|
/* PRINTF("O %4x.\r\n", TIM1_CNT); */
|
|
/* printf("OV "); */
|
|
time_msb++;
|
|
now = ((rtimer_clock_t) time_msb << 16) | TIM1_CNT;
|
|
clock_to_wait = next_rtimer_time - now;
|
|
|
|
if(clock_to_wait <= 0x10000 && clock_to_wait > 0) {
|
|
/* We must now set the Timer Compare Register. */
|
|
TIM1_CCR1 = (uint16_t) clock_to_wait;
|
|
INT_TIM1FLAG = INT_TIMCC1IF;
|
|
INT_TIM1CFG |= INT_TIMCC1IF; /* Compare 1 interrupt enable. */
|
|
}
|
|
INT_TIM1FLAG = INT_TIMUIF;
|
|
} else {
|
|
if(INT_TIM1FLAG & INT_TIMCC1IF) {
|
|
/* Compare event. */
|
|
INT_TIM1CFG &= ~INT_TIMCC1IF; /* Disable the next compare interrupt */
|
|
PRINTF("\nCompare event %4x\r\n", TIM1_CNT);
|
|
PRINTF("INT_TIM1FLAG %2x\r\n", INT_TIM1FLAG);
|
|
ENERGEST_ON(ENERGEST_TYPE_IRQ);
|
|
rtimer_run_next();
|
|
ENERGEST_OFF(ENERGEST_TYPE_IRQ);
|
|
INT_TIM1FLAG = INT_TIMCC1IF;
|
|
}
|
|
}
|
|
}
|
|
/*---------------------------------------------------------------------------*/
|
|
void
|
|
rtimer_arch_init(void)
|
|
{
|
|
TIM1_CR1 = 0;
|
|
TIM1_PSC = RTIMER_ARCH_PRESCALER;
|
|
|
|
/* Counting from 0 to the maximum value. */
|
|
TIM1_ARR = 0xffff;
|
|
|
|
/* Bits of TIMx_CCMR1 as default. */
|
|
/* Update Generation. */
|
|
TIM1_EGR = TIM_UG;
|
|
INT_TIM1FLAG = 0xffff;
|
|
|
|
/* Update interrupt enable (interrupt on overflow).*/
|
|
INT_TIM1CFG = INT_TIMUIF;
|
|
|
|
/* Counter enable. */
|
|
TIM1_CR1 = TIM_CEN;
|
|
|
|
/* Enable top level interrupt. */
|
|
INT_CFGSET = INT_TIM1;
|
|
|
|
}
|
|
/*---------------------------------------------------------------------------*/
|
|
void
|
|
rtimer_arch_disable_irq(void)
|
|
{
|
|
ATOMIC(saved_TIM1CFG = INT_TIM1CFG; INT_TIM1CFG = 0;)
|
|
}
|
|
/*---------------------------------------------------------------------------*/
|
|
void
|
|
rtimer_arch_enable_irq(void)
|
|
{
|
|
INT_TIM1CFG = saved_TIM1CFG;
|
|
}
|
|
/*---------------------------------------------------------------------------*/
|
|
rtimer_clock_t
|
|
rtimer_arch_now(void)
|
|
{
|
|
rtimer_clock_t t;
|
|
|
|
ATOMIC(t = ((rtimer_clock_t) time_msb << 16) | TIM1_CNT;)
|
|
return t;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
void
|
|
rtimer_arch_schedule(rtimer_clock_t t)
|
|
{
|
|
rtimer_clock_t now, clock_to_wait;
|
|
PRINTF("rtimer_arch_schedule time %4x\r\n", /*((uint32_t*)&t)+1, */
|
|
(uint32_t)t);
|
|
next_rtimer_time = t;
|
|
now = rtimer_arch_now();
|
|
clock_to_wait = t - now;
|
|
|
|
PRINTF("now %2x\r\n", TIM1_CNT);
|
|
PRINTF("clock_to_wait %4x\r\n", clock_to_wait);
|
|
|
|
if(clock_to_wait <= 0x10000) {
|
|
/* We must now set the Timer Compare Register. */
|
|
TIM1_CCR1 = (uint16_t)now + (uint16_t)clock_to_wait;
|
|
INT_TIM1FLAG = INT_TIMCC1IF;
|
|
INT_TIM1CFG |= INT_TIMCC1IF; /* Compare 1 interrupt enable. */
|
|
PRINTF("2-INT_TIM1FLAG %2x\r\n", INT_TIM1FLAG);
|
|
}
|
|
/* else compare register will be set at overflow interrupt closer to
|
|
the rtimer event. */
|
|
}
|
|
/*---------------------------------------------------------------------------*/
|
|
/** @} */
|