blob: 92f5a54b60827dbacd11e9752e11f8cf2c348330 [file] [log] [blame]
/* ----------------------------------------------------------------------------
* SAM Software Package License
* ----------------------------------------------------------------------------
* Copyright (c) 2015, Atmel Corporation
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the disclaimer below.
*
* Atmel's name may not be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* DISCLAIMED. IN NO EVENT SHALL ATMEL 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
* Implement simple PIT usage as system tick.
*/
/*----------------------------------------------------------------------------
* Headers
*----------------------------------------------------------------------------*/
#include "board.h"
#include "timer.h"
#include "peripherals/tc.h"
#include "peripherals/pit.h"
#include "peripherals/aic.h"
#include "peripherals/pmc.h"
/*----------------------------------------------------------------------------
* Local variables
*----------------------------------------------------------------------------*/
/** Tick Counter */
static volatile uint32_t _timer = 0;
static uint32_t _resolution = 0;
/*----------------------------------------------------------------------------
* Exported Functions
*----------------------------------------------------------------------------*/
/**
* \brief Handler for Sytem Tick interrupt.
*/
static void timer_increment(void)
{
uint32_t status;
/* Read the PIT status register */
status = pit_get_status() & PIT_SR_PITS;
if (status != 0) {
/* 1 = The Periodic Interval timer has reached PIV
* since the last read of PIT_PIVR. Read the PIVR to
* acknowledge interrupt and get number of ticks
* Returns the number of occurrences of periodic
* intervals since the last read of PIT_PIVR. */
_timer += (pit_get_pivr() >> 20);
}
}
uint32_t timer_configure(uint32_t resolution)
{
pit_disable_it();
if (!resolution)
resolution = BOARD_TIMER_RESOLUTION;
_timer = 0;
pmc_enable_peripheral(ID_PIT);
pit_init(resolution);
aic_set_source_vector(ID_PIT, timer_increment);
aic_enable(ID_PIT);
pit_enable_it();
pit_enable();
_resolution = resolution;
return 0;
}
uint32_t timer_get_resolution(void)
{
return _resolution;
}
uint32_t timer_get_interval(uint32_t start, uint32_t end)
{
if (end >= start)
return (end - start);
return (end + (0xFFFFFFFF - start) + 1);
}
void timer_start_timeout(struct _timeout* timeout, uint32_t count)
{
timeout->start = _timer;
timeout->count = count;
}
uint8_t timer_timeout_reached(struct _timeout* timeout)
{
return timer_get_interval(timeout->start, _timer) >= timeout->count;
}
void timer_wait(uint32_t count)
{
uint32_t start, current;
start = _timer;
do {
current = _timer;
} while (timer_get_interval(start, current) < count);
}
void timer_sleep(uint32_t count)
{
uint32_t start, current;
asm("CPSIE I");
start = _timer;
do {
asm("WFI");
current = _timer;
} while (timer_get_interval(start, current) < count);
}
uint32_t timer_get_tick(void)
{
return _timer;
}