mbed-os/targets/TARGET_Samsung/TARGET_SIDK_S5JS100/us_ticker.c

162 lines
5.3 KiB
C

/****************************************************************************
*
* Copyright 2020 Samsung Electronics All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the License.
*
****************************************************************************/
#if DEVICE_USTICKER
#include <stddef.h>
#include "cmsis.h"
#include "us_ticker_api.h"
#include "us_ticker.h"
#include "PeripheralNames.h"
#define TIMER_TARGET_COUNT_DEFAULT 0xFFFFFFFF
uint32_t us_ticker_initialized = 0;
uint32_t g_us_last_return = 0;
void us_ticker_enable_interrupt(void);
void us_ticker_disable_interrupt(void);
const ticker_info_t *us_ticker_get_info()
{
static const ticker_info_t info = {
26000000, //26Mhz
32 //32bit counter
};
return &info;
}
static void enable_timer0(void)
{
putreg32(0, S5JS100_TIMER0_BASE + S5JS100_TIMER_UP_DOWN_SEL); // Set Up count
putreg32(TIMER_TARGET_COUNT_DEFAULT, S5JS100_TIMER0_BASE + S5JS100_TIMER_LOAD_VALUE);
putreg32(0x1, S5JS100_TIMER0_BASE + S5JS100_TIMER_CDC_ENABLE);
putreg32(TIMER_TARGET_COUNT_DEFAULT, S5JS100_TIMER0_BASE + S5JS100_TIMER_CDC_COUNT_VALUE);
putreg32(0, S5JS100_TIMER0_BASE + S5JS100_TIMER_INT_SEL);
putreg32(0, S5JS100_TIMER0_BASE + S5JS100_TIMER_INT_ENABLE);
putreg32(3, S5JS100_TIMER0_BASE + S5JS100_TIMER_CONTROL);
}
static void disable_timer0(void)
{
putreg32(0, S5JS100_TIMER0_BASE + S5JS100_TIMER_CONTROL);
putreg32(0, S5JS100_TIMER0_BASE + S5JS100_TIMER_UP_DOWN_SEL);
putreg32(TIMER_TARGET_COUNT_DEFAULT, S5JS100_TIMER0_BASE + S5JS100_TIMER_LOAD_VALUE);
putreg32(TIMER_TARGET_COUNT_DEFAULT, S5JS100_TIMER0_BASE + S5JS100_TIMER_INT_SEL);
putreg32(0, S5JS100_TIMER0_BASE + S5JS100_TIMER_INT_ENABLE);
putreg32(0x0, S5JS100_TIMER0_BASE + S5JS100_TIMER_CDC_ENABLE);
putreg32(TIMER_TARGET_COUNT_DEFAULT, S5JS100_TIMER0_BASE + S5JS100_TIMER_CDC_COUNT_VALUE);
}
static void enable_timer1(void)
{
putreg32(0, S5JS100_TIMER1_BASE + S5JS100_TIMER_UP_DOWN_SEL); // Set Up count
putreg32(TIMER_TARGET_COUNT_DEFAULT, S5JS100_TIMER1_BASE + S5JS100_TIMER_LOAD_VALUE);
putreg32(0, S5JS100_TIMER1_BASE + S5JS100_TIMER_INT_SEL);
putreg32(0, S5JS100_TIMER1_BASE + S5JS100_TIMER_INT_ENABLE);
putreg32(3, S5JS100_TIMER1_BASE + S5JS100_TIMER_CONTROL);
}
static void disable_timer1(void)
{
putreg32(0, S5JS100_TIMER1_BASE + S5JS100_TIMER_UP_DOWN_SEL);
putreg32(TIMER_TARGET_COUNT_DEFAULT, S5JS100_TIMER1_BASE + S5JS100_TIMER_LOAD_VALUE);
putreg32(0, S5JS100_TIMER1_BASE + S5JS100_TIMER_INT_SEL);
putreg32(0, S5JS100_TIMER1_BASE + S5JS100_TIMER_CONTROL);
putreg32(0, S5JS100_TIMER1_BASE + S5JS100_TIMER_INT_ENABLE);
}
void __us_ticker_irq_handler(void)
{
us_ticker_disable_interrupt();
us_ticker_clear_interrupt();
us_ticker_irq_handler();
}
void us_ticker_init(void)
{
/**
** We use two timer, timer0 channel to be used timer and timer1 to be used compare timer
**/
if (!us_ticker_initialized) {
us_ticker_initialized = 1;
/* Enable timer0 to timer */
enable_timer0();
/* Enable timer1 to compare and Disable timer1 interrupt */
enable_timer1();
/* Install the interrupt handler(timer0) */
NVIC_SetVector((IRQn_Type)S5JS100_IRQ_TINT1, (uint32_t)__us_ticker_irq_handler);
NVIC_EnableIRQ((IRQn_Type)S5JS100_IRQ_TINT1);
return;
}
/* Re_init should Disable timer1(compare) interrupt */
us_ticker_disable_interrupt();
us_ticker_clear_interrupt();
}
uint32_t us_ticker_read()
{
/* from timer0 read count value */
if (!us_ticker_initialized) {
us_ticker_init();
}
uint32_t current_count = TIMER_TARGET_COUNT_DEFAULT - getreg32(S5JS100_TIMER0_BASE + S5JS100_TIMER_CDC_COUNT_VALUE);
g_us_last_return = current_count;
return current_count;
}
void us_ticker_set_interrupt(timestamp_t timestamp)
{
uint32_t past_tick = TIMER_TARGET_COUNT_DEFAULT - getreg32(S5JS100_TIMER0_BASE + S5JS100_TIMER_CDC_COUNT_VALUE) - g_us_last_return;
putreg32(timestamp - g_us_last_return - past_tick, S5JS100_TIMER1_BASE + S5JS100_TIMER_LOAD_CON_VALUE);
us_ticker_enable_interrupt();
}
void us_ticker_fire_interrupt(void)
{
NVIC_SetPendingIRQ((IRQn_Type)S5JS100_IRQ_TINT1);
}
void us_ticker_disable_interrupt(void)
{
putreg32(0, S5JS100_TIMER1_BASE + S5JS100_TIMER_INT_ENABLE);
}
void us_ticker_enable_interrupt(void)
{
putreg32(1, S5JS100_TIMER1_BASE + S5JS100_TIMER_INT_ENABLE);
}
void us_ticker_clear_interrupt(void)
{
putreg32(1, S5JS100_TIMER1_BASE + S5JS100_TIMER_INT_CLEAR);
NVIC_ClearPendingIRQ((IRQn_Type)S5JS100_IRQ_TINT1);
}
void us_ticker_free(void)
{
us_ticker_initialized = 0;
disable_timer1();
NVIC_DisableIRQ((IRQn_Type)S5JS100_IRQ_TINT1);
disable_timer0();
}
#endif // DEVICE_USTICKER