mirror of
https://github.com/openmv/openmv.git
synced 2025-11-04 14:49:50 +08:00
417 lines
11 KiB
C
417 lines
11 KiB
C
/* Copyright (C) 2023 Alif Semiconductor - All Rights Reserved.
|
|
* Use, distribution and modification of this code is permitted under the
|
|
* terms stated in the Alif Semiconductor Software License Agreement
|
|
*
|
|
* You should have received a copy of the Alif Semiconductor Software
|
|
* License Agreement with this file. If not, please write to:
|
|
* contact@alifsemi.com, or visit: https://alifsemi.com/license
|
|
*
|
|
*/
|
|
/**************************************************************************//**
|
|
* @file Driver_RTC.c
|
|
* @author Tanay Rami, Manoj A Murudi
|
|
* @email tanay@alifsemi.com, manoj.murudi@alifsemi.com
|
|
* @version V1.0.0
|
|
* @date 23-March-2023
|
|
* @brief CMSIS-Driver for RTC
|
|
******************************************************************************/
|
|
|
|
#include "Driver_RTC.h"
|
|
#include "Driver_RTC_Private.h"
|
|
#include "rtc.h"
|
|
#include "sys_ctrl_rtc.h"
|
|
|
|
#define ARM_RTC_DRV_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(1, 0) /* driver version */
|
|
|
|
#if !(RTE_RTC0)
|
|
#error "RTC0 is not enabled in the RTE_Device.h"
|
|
#endif
|
|
|
|
#if !defined(RTE_Drivers_RTC)
|
|
#error "RTC0 is not enabled in the RTE_Components.h"
|
|
#endif
|
|
|
|
/* Driver Version */
|
|
static const ARM_DRIVER_VERSION DriverVersion = {
|
|
ARM_RTC_API_VERSION,
|
|
ARM_RTC_DRV_VERSION
|
|
};
|
|
|
|
/* Driver Capabilities */
|
|
static const ARM_RTC_CAPABILITIES DriverCapabilities = {
|
|
1, /* supports RTC Alarm Callback */
|
|
0 /* Reserved (must be zero) */
|
|
};
|
|
|
|
/**
|
|
\fn ARM_DRIVER_VERSION RTC_GetVersion(void)
|
|
\brief get rtc version
|
|
\param none
|
|
\return driver version
|
|
*/
|
|
static ARM_DRIVER_VERSION RTC_GetVersion(void)
|
|
{
|
|
return DriverVersion;
|
|
}
|
|
|
|
/**
|
|
\fn ARM_RTC_CAPABILITIES RTC_GetCapabilities(void)
|
|
\brief get rtc capabilites
|
|
\param none
|
|
\return driver capabilites
|
|
*/
|
|
static ARM_RTC_CAPABILITIES RTC_GetCapabilities(void)
|
|
{
|
|
return DriverCapabilities;
|
|
}
|
|
|
|
/**
|
|
\fn int32_t LPRTC_Initialize (LPRTC_RESOURCES *LPRTC_RES, ARM_RTC_SignalEvent_t cb_event)
|
|
\brief Initialize the lprtc device, this does:
|
|
- Disable the counter, prescalar, and interrupts.
|
|
- Program the default prescaler value.
|
|
- Enable the counter and prescaler,
|
|
- Keep interrupt generation disabled until an alarm is set.
|
|
\param[in] cb_event : Pointer to LPRTC Event \ref LPRTC_SignalEvent
|
|
\param[in] LPRTC_RES : Pointer to lprtc device resources
|
|
\return execution_status
|
|
*/
|
|
static int32_t LPRTC_Initialize (LPRTC_RESOURCES *LPRTC_RES, ARM_RTC_SignalEvent_t cb_event)
|
|
{
|
|
if (LPRTC_RES->state.initialized == 1)
|
|
{
|
|
return ARM_DRIVER_OK;
|
|
}
|
|
|
|
if (!cb_event)
|
|
{
|
|
return ARM_DRIVER_ERROR_PARAMETER;
|
|
}
|
|
|
|
/* set the user callback event. */
|
|
LPRTC_RES->cb_event = cb_event;
|
|
|
|
/* Set rtc flag to initialized. */
|
|
LPRTC_RES->state.initialized = 1;
|
|
|
|
return ARM_DRIVER_OK;
|
|
}
|
|
|
|
/**
|
|
\fn int32_t LPRTC_PowerControl (LPRTC_RESOURCES *LPRTC_RES, ARM_POWER_STATE state)
|
|
\brief LPRTC power control
|
|
\param[in] state : Power state
|
|
\param[in] LPRTC_RES : Pointer to lprtc device resources
|
|
\return none
|
|
*/
|
|
static int32_t LPRTC_PowerControl (LPRTC_RESOURCES *LPRTC_RES, ARM_POWER_STATE state)
|
|
{
|
|
switch (state)
|
|
{
|
|
case ARM_POWER_OFF:
|
|
{
|
|
/* Disable LPRTC IRQ */
|
|
NVIC_DisableIRQ (LPRTC_RES->irq_num);
|
|
|
|
/* Clear Any Pending IRQ*/
|
|
NVIC_ClearPendingIRQ (LPRTC_RES->irq_num);
|
|
|
|
/* disable LPRTC Prescaler. */
|
|
lprtc_prescaler_disable (LPRTC_RES->regs);
|
|
|
|
/* disable LPRTC counter. */
|
|
lprtc_counter_disable (LPRTC_RES->regs);
|
|
|
|
/* disable LPRTC interrupt. */
|
|
lprtc_interrupt_disable (LPRTC_RES->regs);
|
|
|
|
/* disable LPRTC counter wrap. */
|
|
lprtc_counter_wrap_disable (LPRTC_RES->regs);
|
|
|
|
/* disable LPRTC clocks */
|
|
disable_lprtc_clk();
|
|
|
|
/* Reset lprtc power state. */
|
|
LPRTC_RES->state.powered = 0;
|
|
break;
|
|
}
|
|
|
|
case ARM_POWER_FULL:
|
|
{
|
|
if (LPRTC_RES->state.initialized == 0)
|
|
{
|
|
return ARM_DRIVER_ERROR;
|
|
}
|
|
|
|
if (LPRTC_RES->state.powered == 1)
|
|
{
|
|
return ARM_DRIVER_OK;
|
|
}
|
|
|
|
/* enable LPRTC clocks */
|
|
enable_lprtc_clk();
|
|
|
|
/* disable LPRTC counter wrap. */
|
|
lprtc_counter_wrap_disable (LPRTC_RES->regs);
|
|
|
|
/* enable LPRTC Prescaler. */
|
|
lprtc_prescaler_enable (LPRTC_RES->regs);
|
|
|
|
/* enable LPRTC counter. */
|
|
lprtc_counter_enable (LPRTC_RES->regs);
|
|
|
|
/* Enable Interrupt generation. */
|
|
lprtc_interrupt_enable (LPRTC_RES->regs);
|
|
|
|
/* Set the IRQ priority */
|
|
NVIC_SetPriority (LPRTC_RES->irq_num, LPRTC_RES->irq_priority);
|
|
|
|
/* Enable LPRTC IRQ*/
|
|
NVIC_ClearPendingIRQ (LPRTC_RES->irq_num);
|
|
NVIC_EnableIRQ (LPRTC_RES->irq_num);
|
|
|
|
/* Unmask Interrupt. */
|
|
lprtc_interrupt_unmask (LPRTC_RES->regs);
|
|
|
|
/* Set the power state enabled */
|
|
LPRTC_RES->state.powered = 1;
|
|
break;
|
|
}
|
|
|
|
case ARM_POWER_LOW:
|
|
default:
|
|
{
|
|
return ARM_DRIVER_ERROR_UNSUPPORTED;
|
|
}
|
|
}
|
|
|
|
return ARM_DRIVER_OK;
|
|
}
|
|
|
|
/**
|
|
\fn int32_t LPRTC_Uninitialize (LPRTC_RESOURCES *LPRTC_RES)
|
|
\brief Uninitialize the lprtc device, this does:
|
|
- Power-Off the LPRTC device.
|
|
- Disable the counter, prescalar, and interrupts.
|
|
\param[in] LPRTC_RES : Pointer to lprtc device resources
|
|
\return execution status
|
|
*/
|
|
static int32_t LPRTC_Uninitialize (LPRTC_RESOURCES *LPRTC_RES)
|
|
{
|
|
if (LPRTC_RES->state.initialized == 0)
|
|
{
|
|
return ARM_DRIVER_OK;
|
|
}
|
|
|
|
/* set the user callback event to NULL. */
|
|
LPRTC_RES->cb_event = NULL;
|
|
|
|
/* reset lprtc state. */
|
|
LPRTC_RES->state.initialized = 0;
|
|
|
|
return ARM_DRIVER_OK;
|
|
}
|
|
|
|
/**
|
|
\fn int32_t LPRTC_Control (LPRTC_RESOURCES *LPRTC_RES, uint32_t control, uint32_t arg)
|
|
\brief CMSIS-Driver lprtc control.
|
|
Control LPRTC Interface.
|
|
\param[in] control : Operation
|
|
\param[in] arg : Argument of operation (optional)
|
|
\param[in] LPRTC_RES : Pointer to lprtc device resources
|
|
\return execution status
|
|
*/
|
|
static int32_t LPRTC_Control (LPRTC_RESOURCES *LPRTC_RES, uint32_t control, uint32_t arg)
|
|
{
|
|
if (LPRTC_RES->state.powered == 0)
|
|
{
|
|
return ARM_DRIVER_ERROR;
|
|
}
|
|
|
|
switch (control)
|
|
{
|
|
case ARM_RTC_SET_PRESCALER:
|
|
{
|
|
/* disable LPRTC Prescaler. */
|
|
lprtc_prescaler_disable (LPRTC_RES->regs);
|
|
|
|
/* disable LPRTC counter. */
|
|
lprtc_counter_disable (LPRTC_RES->regs);
|
|
|
|
/* load LPRTC counter. */
|
|
lprtc_load_prescaler (LPRTC_RES->regs, arg);
|
|
|
|
/* enable LPRTC Prescaler. */
|
|
lprtc_prescaler_enable (LPRTC_RES->regs);
|
|
|
|
/* enable LPRTC counter. */
|
|
lprtc_counter_enable (LPRTC_RES->regs);
|
|
|
|
break;
|
|
}
|
|
case ARM_RTC_SET_ALARM:
|
|
{
|
|
/* load lprtc counter match register. */
|
|
lprtc_load_counter_match_register (LPRTC_RES->regs, arg);
|
|
|
|
/* Enable LPRTC IRQ*/
|
|
NVIC_EnableIRQ (LPRTC_RES->irq_num);
|
|
|
|
/* set lprtc alarm state. */
|
|
LPRTC_RES->state.alarm = 1;
|
|
|
|
break;
|
|
}
|
|
|
|
default:
|
|
/* Unsupported command */
|
|
return ARM_DRIVER_ERROR_UNSUPPORTED;
|
|
}
|
|
return ARM_DRIVER_OK;
|
|
}
|
|
|
|
/**
|
|
\fn int32_t LPRTC_ReadCounter (LPRTC_RESOURCES *LPRTC_RES, uint32_t *val)
|
|
\brief Read the current counter value
|
|
\param[in] val : Pointer to the address where current lprtc counter value
|
|
needs to be copied to
|
|
\param[in] LPRTC_RES : Pointer to lprtc device resources
|
|
\return execution status
|
|
*/
|
|
static int32_t LPRTC_ReadCounter (LPRTC_RESOURCES *LPRTC_RES, uint32_t *val)
|
|
{
|
|
if (LPRTC_RES->state.powered == 0)
|
|
{
|
|
return ARM_DRIVER_ERROR;
|
|
}
|
|
|
|
/* read lprtc current counter value. */
|
|
*val = lprtc_get_count (LPRTC_RES->regs);
|
|
|
|
return ARM_DRIVER_OK;
|
|
}
|
|
|
|
/**
|
|
\fn int32_t LPRTC_LoadCounter (LPRTC_RESOURCES *LPRTC_RES, uint32_t loadvalue)
|
|
\brief Load new counter value
|
|
\param[in] loadvalue : Variable which contains new counter value
|
|
\param[in] LPRTC_RES : Pointer to lprtc device resources
|
|
\return execution status
|
|
*/
|
|
static int32_t LPRTC_LoadCounter (LPRTC_RESOURCES *LPRTC_RES, uint32_t loadvalue)
|
|
{
|
|
if (LPRTC_RES->state.powered == 0)
|
|
{
|
|
return ARM_DRIVER_ERROR;
|
|
}
|
|
|
|
/* disable LPRTC counter. */
|
|
lprtc_counter_disable (LPRTC_RES->regs);
|
|
|
|
/* Load counter value */
|
|
lprtc_load_count(LPRTC_RES->regs, loadvalue);
|
|
|
|
/* enable LPRTC counter. */
|
|
lprtc_counter_enable (LPRTC_RES->regs);
|
|
|
|
return ARM_DRIVER_OK;
|
|
}
|
|
|
|
/**
|
|
\fn void RTC_IRQHandler (LPRTC_RESOURCES *LPRTC_RES)
|
|
\brief lprtc interrupt handler
|
|
\param[in] LPRTC_RES : Pointer to lprtc device resources
|
|
\return none
|
|
*/
|
|
static void RTC_IRQHandler (LPRTC_RESOURCES *LPRTC_RES)
|
|
{
|
|
uint32_t event = 0U; /* callback event */
|
|
|
|
/* Acknowledge the interrupt */
|
|
lprtc_interrupt_ack (LPRTC_RES->regs);
|
|
|
|
/* mark event as Alarm Triggered. */
|
|
event |= ARM_RTC_EVENT_ALARM_TRIGGER;
|
|
|
|
/* call the user callback if any event occurs */
|
|
if (LPRTC_RES->cb_event != NULL)
|
|
{
|
|
/* call the user callback */
|
|
LPRTC_RES->cb_event(event);
|
|
}
|
|
|
|
NVIC_DisableIRQ (LPRTC_RES->irq_num);
|
|
|
|
/* Reset lprtc Alarm state. */
|
|
LPRTC_RES->state.alarm = 0;
|
|
}
|
|
|
|
/* RTC0 Driver Instance */
|
|
#if (RTE_RTC0)
|
|
|
|
/* RTC0 device configuration */
|
|
static LPRTC_RESOURCES RTC0 = {
|
|
.regs = (LPRTC_Type*) LPRTC_BASE,
|
|
.cb_event = NULL,
|
|
.irq_num = (IRQn_Type) LPRTC_IRQ_IRQn,
|
|
.irq_priority = RTE_RTC0_IRQ_PRI,
|
|
};
|
|
|
|
/* Function Name: RTC0_Initialize */
|
|
static int32_t RTC0_Initialize (ARM_RTC_SignalEvent_t cb_event)
|
|
{
|
|
return (LPRTC_Initialize (&RTC0, cb_event));
|
|
}
|
|
|
|
/* Function Name: RTC0_Uninitialize */
|
|
static int32_t RTC0_Uninitialize (void)
|
|
{
|
|
return (LPRTC_Uninitialize (&RTC0));
|
|
}
|
|
|
|
/* Function Name: RTC0_PowerControl */
|
|
static int32_t RTC0_PowerControl(ARM_POWER_STATE state)
|
|
{
|
|
return (LPRTC_PowerControl(&RTC0, state));
|
|
}
|
|
|
|
/* Function Name: RTC0_Control */
|
|
static int32_t RTC0_Control(uint32_t control, uint32_t arg)
|
|
{
|
|
return (LPRTC_Control(&RTC0, control, arg));
|
|
}
|
|
|
|
/* Function Name: RTC0_ReadCounter */
|
|
static int32_t RTC0_ReadCounter (uint32_t *val)
|
|
{
|
|
return (LPRTC_ReadCounter (&RTC0, val));
|
|
}
|
|
|
|
/* Function Name: RTC0_LoadCounter */
|
|
static int32_t RTC0_LoadCounter (uint32_t loadval)
|
|
{
|
|
return (LPRTC_LoadCounter (&RTC0, loadval));
|
|
}
|
|
|
|
/* Function Name: RTC0_IRQHandler */
|
|
void LPRTC_IRQHandler (void)
|
|
{
|
|
RTC_IRQHandler (&RTC0);
|
|
}
|
|
|
|
extern ARM_DRIVER_RTC Driver_RTC0;
|
|
ARM_DRIVER_RTC Driver_RTC0 =
|
|
{
|
|
RTC_GetVersion,
|
|
RTC_GetCapabilities,
|
|
RTC0_Initialize,
|
|
RTC0_Uninitialize,
|
|
RTC0_PowerControl,
|
|
RTC0_Control,
|
|
RTC0_ReadCounter,
|
|
RTC0_LoadCounter
|
|
};
|
|
#endif /* End of RTE_RTC0 */
|
|
|
|
/************************ (C) COPYRIGHT ALIF SEMICONDUCTOR *****END OF FILE****/
|