Introduced tickles mode for ADuCM36x

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@13657 27425a3e-05d8-49a3-a47f-9c15f0e5edd8
This commit is contained in:
Rocco Marco Guglielmi 2020-05-19 11:40:34 +00:00
parent f003aa8bbd
commit 0a1f75097b
9 changed files with 527 additions and 5 deletions

View File

@ -52,7 +52,7 @@
* setting also defines the system tick time unit.
*/
#if !defined(CH_CFG_ST_FREQUENCY)
#define CH_CFG_ST_FREQUENCY 10000
#define CH_CFG_ST_FREQUENCY 62500
#endif
/**
@ -80,7 +80,7 @@
* this value.
*/
#if !defined(CH_CFG_ST_TIMEDELTA)
#define CH_CFG_ST_TIMEDELTA 0
#define CH_CFG_ST_TIMEDELTA 2
#endif
/** @} */

View File

@ -66,7 +66,6 @@
* ST driver system settings.
*/
#define ADUCM_ST_IRQ_PRIORITY 3
#define ADUCM_ST_USE_TIMER 2
/** @} */
#endif /* MCUCONF_H */

View File

@ -64,6 +64,14 @@
#define ADUCM_UART0_NUMBER 17
/** @} */
/*
* Wake Up timer.
*/
#define ADUCM_WUT_HANDLER Vector40
#define ADUCM_WUT_NUMBER 0
/** @} */
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/

View File

@ -3,8 +3,7 @@ PLATFORMSRC := $(CHIBIOS)/os/hal/ports/common/ARMCMx/nvic.c \
$(CHIBIOS)/os/hal/ports/ADUCM/ADUCM36x/aducm_isr.c \
$(CHIBIOS)/os/hal/ports/ADUCM/ADUCM36x/hal_lld.c \
$(CHIBIOS)/os/hal/ports/ADUCM/ADUCM36x/hal_pal_lld.c \
$(CHIBIOS)/os/hal/ports/ADUCM/ADUCM36x/hal_spi_lld.c \
$(CHIBIOS)/os/hal/ports/ADUCM/ADUCM36x/hal_st_lld.c
$(CHIBIOS)/os/hal/ports/ADUCM/ADUCM36x/hal_spi_lld.c
# Required include directories.
PLATFORMINC := $(CHIBIOS)/os/hal/ports/common/ARMCMx \
@ -29,6 +28,7 @@ endif
# Drivers compatible with the platform.
include $(CHIBIOS)/os/hal/ports/ADUCM/LLD/UARTv1/driver.mk
include $(CHIBIOS)/os/hal/ports/ADUCM/LLD/WUTv1/driver.mk
# Shared variables
ALLCSRC += $(PLATFORMSRC)

View File

@ -0,0 +1,160 @@
/*
ChibiOS - Copyright (C) 2006..2020 Rocco Marco Guglielmi
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.
*/
/**
* @file ADUCM/aducm_wut.h
* @brief ADUCM WUT units common header.
* @note This file requires definitions from the ADI ADUCM header file.
*
* @{
*/
#ifndef ADUCM_WUT_H
#define ADUCM_WUT_H
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
/**
* @name WUT Configuration register definitions
* @{
*/
#define ADUCM_WUT_CON_PRE_DIV1 (0 << 0)
#define ADUCM_WUT_CON_PRE_DIV4 (0 << 0)
#define ADUCM_WUT_CON_PRE_DIV16 (1 << 0)
#define ADUCM_WUT_CON_PRE_DIV256 (2 << 0)
#define ADUCM_WUT_CON_PRE_DIV32768 (3 << 0)
#define ADUCM_WUT_CON_FREEZE (1 << 3)
#define ADUCM_WUT_CON_TMODE_PERIODIC (0 << 6)
#define ADUCM_WUT_CON_TMODE_FREERUN (1 << 6)
#define ADUCM_WUT_CON_ENABLE (1 << 7)
#define ADUCM_WUT_CON_WUEN (1 << 8)
#define ADUCM_WUT_CON_CLK_PCLK (0 << 9)
#define ADUCM_WUT_CON_CLK_LFOSC (1 << 9)
#define ADUCM_WUT_CON_CLK_LFOSC1 (2 << 9)
#define ADUCM_WUT_CON_CLK_ECLKIN (3 << 9)
#define ADUCM_WUT_CON_STOP_WUFA (1 << 11)
/** @} */
/**
* @name WUT Interrupt Enable register definitions
* @{
*/
#define ADUCM_WUT_IER_WUFA (1 << 0)
#define ADUCM_WUT_IER_WUFB (1 << 1)
#define ADUCM_WUT_IER_WUFC (1 << 2)
#define ADUCM_WUT_IER_WUFD (1 << 3)
#define ADUCM_WUT_IER_ROLL (1 << 4)
/** @} */
/**
* @name WUT Status register definitions
* @{
*/
#define ADUCM_WUT_STA_WUFA (1 << 0)
#define ADUCM_WUT_STA_WUFB (1 << 1)
#define ADUCM_WUT_STA_WUFC (1 << 2)
#define ADUCM_WUT_STA_WUFD (1 << 3)
#define ADUCM_WUT_STA_ROLL (1 << 4)
#define ADUCM_WUT_STA_IRQCRY (1 << 6)
#define ADUCM_WUT_STA_FREEZE (1 << 7)
#define ADUCM_WUT_STA_PDOK (1 << 8)
/** @} */
/**
* @name WUT Clear Interrupt register definitions
* @{
*/
#define ADUCM_WUT_CLRI_WUFA (1 << 0)
#define ADUCM_WUT_CLRI_WUFB (1 << 1)
#define ADUCM_WUT_CLRI_WUFC (1 << 2)
#define ADUCM_WUT_CLRI_WUFD (1 << 3)
#define ADUCM_WUT_CLRI_ROLL (1 << 4)
/** @} */
/**
* @name WUT ports definitions
* @{
*/
#define ADUCM_WUT ((aducm_wut_t *)pADI_WUT)
/** @} */
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
/**
* @brief ADUCM41x WUT registers block.
*/
typedef struct {
volatile uint32_t VAL0;
volatile uint32_t VAL1;
volatile uint32_t CON;
volatile uint32_t INC;
volatile uint32_t WUFB0;
volatile uint32_t WUFB1;
volatile uint32_t WUFC0;
volatile uint32_t WUFC1;
volatile uint32_t WUFD0;
volatile uint32_t WUFD1;
volatile uint32_t IEN;
volatile uint32_t STA;
volatile uint32_t CLRI;
volatile uint32_t RESERVED[2];
volatile uint32_t WUFA0;
volatile uint32_t WUFA1;
} aducm_wut_t;
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
/**
* @brief Enable the Wake-Up timer.
*
* @param[in] wutp Wake-up timer identifier
*
* @notapi
*/
#define ADCUM_WUT_ENABLE(wutp) ((wutp)->CON |= ADUCM_WUT_CON_ENABLE)
/**
* @brief Enable the Wake-Up timer.
*
* @param[in] wutp Wake-up timer identifier
*
* @notapi
*/
#define ADCUM_WUT_DISABLE(wutp) ((wutp)->CON &= ~ADUCM_WUT_CON_ENABLE)
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#endif /* ADUCM_WUT_H */
/** @} */

View File

@ -0,0 +1,3 @@
PLATFORMSRC += $(CHIBIOS)/os/hal/ports/ADUCM/LLD/WUTv1/hal_st_lld.c
PLATFORMINC += $(CHIBIOS)/os/hal/ports/ADUCM/LLD/WUTv1

View File

@ -0,0 +1,179 @@
/*
ChibiOS - Copyright (C) 2006..2020 Rocco Marco Guglielmi
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.
*/
/**
* @file ADUCM36x/hal_st_lld.c
* @brief ST Driver subsystem low level driver code.
*
* @addtogroup ST
* @{
*/
#include "hal.h"
#if (OSAL_ST_MODE != OSAL_ST_MODE_NONE) || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
#if OSAL_ST_MODE == OSAL_ST_MODE_FREERUNNING
#if !defined(ADUCM_PCLK0)
#define ADUCM_PCLK0 ADUCM_PCLK
#endif
#define ST_HANDLER ADUCM_WUT_HANDLER
#define ST_NUMBER ADUCM_WUT_NUMBER
#define ST_CLOCK_SRC ADUCM_PCLK0
#if (((ST_CLOCK_SRC / OSAL_ST_FREQUENCY) % 4 == 0) && \
((ST_CLOCK_SRC / OSAL_ST_FREQUENCY) / 4 == 1))
#define ST_CLOCK_PRESC ADUCM_WUT_CON_PRE_DIV4
#elif (((ST_CLOCK_SRC / OSAL_ST_FREQUENCY) % 16 == 0) && \
((ST_CLOCK_SRC / OSAL_ST_FREQUENCY) / 16 == 1))
#define ST_CLOCK_PRESC ADUCM_WUT_CON_PRE_DIV16
#elif (((ST_CLOCK_SRC / OSAL_ST_FREQUENCY) % 256 == 0) && \
((ST_CLOCK_SRC / OSAL_ST_FREQUENCY) / 256 == 1))
#define ST_CLOCK_PRESC ADUCM_WUT_CON_PRE_DIV256
#else
#error "the selected ST frequency is not obtainable prescaler limitations"
#endif
#endif /* OSAL_ST_MODE == OSAL_ST_MODE_FREERUNNING */
#if OSAL_ST_MODE == OSAL_ST_MODE_PERIODIC
#define ST_HANDLER SysTick_Handler
#define ST_NUMBER HANDLER_SYSTICK
#define SYSTICK_CK ADUCM_HCLK
#if SYSTICK_CK % OSAL_ST_FREQUENCY != 0
#error "the selected ST frequency is not obtainable because integer rounding"
#endif
#if (SYSTICK_CK / OSAL_ST_FREQUENCY) - 1 > 0xFFFFFF
#error "the selected ST frequency is not obtainable because SysTick timer counter limits"
#endif
#endif /* OSAL_ST_MODE == OSAL_ST_MODE_PERIODIC */
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local types. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local variables and types. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
#if !defined(ADUCM_SYSTICK_SUPPRESS_ISR)
/**
* @brief Interrupt handler.
*
* @isr
*/
OSAL_IRQ_HANDLER(ST_HANDLER) {
OSAL_IRQ_PROLOGUE();
st_lld_serve_interrupt();
OSAL_IRQ_EPILOGUE();
}
#endif
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/**
* @brief Low level ST driver initialization.
*
* @notapi
*/
void st_lld_init(void) {
#if OSAL_ST_MODE == OSAL_ST_MODE_FREERUNNING
/* Free running counter mode.*/
ADUCM_ST_TIM->CON = ST_CLOCK_PRESC | ADUCM_WUT_CON_TMODE_FREERUN;
ADUCM_ST_TIM->WUFB0 = 0;
ADUCM_ST_TIM->WUFB1 = 0;
ADUCM_ST_TIM->CLRI = ADUCM_WUT_CLRI_WUFA | ADUCM_WUT_CLRI_WUFB |
ADUCM_WUT_CLRI_WUFC | ADUCM_WUT_CLRI_WUFD |
ADUCM_WUT_CLRI_ROLL;
ADUCM_ST_TIM->IEN = 0;
ADCUM_WUT_ENABLE(ADUCM_ST_TIM);
#if !defined(ADUCM_SYSTICK_SUPPRESS_ISR)
/* IRQ enabled.*/
nvicEnableVector(ST_NUMBER, ADUCM_ST_IRQ_PRIORITY);
#endif
#endif /* OSAL_ST_MODE == OSAL_ST_MODE_FREERUNNING */
#if OSAL_ST_MODE == OSAL_ST_MODE_PERIODIC
/* Periodic systick mode, the Cortex-Mx internal systick timer is used
in this mode.*/
SysTick->LOAD = (SYSTICK_CK / OSAL_ST_FREQUENCY) - 1;
SysTick->VAL = 0;
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_ENABLE_Msk |
SysTick_CTRL_TICKINT_Msk;
#if !defined(ADUCM_SYSTICK_SUPPRESS_ISR)
/* IRQ enabled.*/
nvicSetSystemHandlerPriority(ST_NUMBER, ADUCM_ST_IRQ_PRIORITY);
#endif
#endif /* OSAL_ST_MODE == OSAL_ST_MODE_PERIODIC */
}
/**
* @brief IRQ handling code.
*/
void st_lld_serve_interrupt(void) {
#if OSAL_ST_MODE == OSAL_ST_MODE_FREERUNNING
uint32_t sr;
sr = ADUCM_ST_TIM->STA;
ADUCM_ST_TIM->CLRI = ADUCM_WUT_CLRI_WUFA | ADUCM_WUT_CLRI_WUFB |
ADUCM_WUT_CLRI_WUFC | ADUCM_WUT_CLRI_WUFD |
ADUCM_WUT_CLRI_ROLL;
if((sr & ADUCM_WUT_STA_WUFB) != 0U)
#endif
{
osalSysLockFromISR();
osalOsTimerHandlerI();
osalSysUnlockFromISR();
}
__DSB();
}
#endif /* OSAL_ST_MODE != OSAL_ST_MODE_NONE */
/** @} */

View File

@ -0,0 +1,172 @@
/*
ChibiOS - Copyright (C) 2006..2020 Rocco Marco Guglielmi
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.
*/
/**
* @file ADUCM41x/hal_st_lld.h
* @brief ST Driver subsystem low level driver header.
* @details This header is designed to be include-able without having to
* include other files from the HAL.
*
* @addtogroup ST
* @{
*/
#ifndef HAL_ST_LLD_H
#define HAL_ST_LLD_H
#include "mcuconf.h"
#include "aducm_wut.h"
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/**
* @name Configuration options
* @{
*/
/**
* @brief SysTick timer IRQ priority.
*/
#if !defined(ADUCM_ST_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define ADUCM_ST_IRQ_PRIORITY 3
#endif
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
#if (OSAL_ST_MODE == OSAL_ST_MODE_FREERUNNING)
#define ADUCM_ST_TIM ADUCM_WUT
#endif
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#ifdef __cplusplus
extern "C" {
#endif
void st_lld_init(void);
void st_lld_serve_interrupt(void);
#ifdef __cplusplus
}
#endif
/*===========================================================================*/
/* Driver inline functions. */
/*===========================================================================*/
#if (OSAL_ST_MODE == OSAL_ST_MODE_FREERUNNING) || defined(__DOXYGEN__)
/**
* @brief Returns the time counter value.
*
* @return The counter value.
*
* @notapi
*/
static inline systime_t st_lld_get_counter(void) {
ADUCM_ST_TIM->CON |= ADUCM_WUT_CON_FREEZE;
systime_t cnt = (systime_t)((ADUCM_ST_TIM->VAL0 & 0X0000FFFF) |
((ADUCM_ST_TIM->VAL1 & 0X0000FFFF) << 16));
ADUCM_ST_TIM->CON &= ~ADUCM_WUT_CON_FREEZE;
return cnt;
}
/**
* @brief Starts the alarm.
* @note Makes sure that no spurious alarms are triggered after
* this call.
*
* @param[in] abstime the time to be set for the first alarm
*
* @notapi
*/
static inline void st_lld_start_alarm(systime_t abstime) {
ADUCM_ST_TIM->WUFB0 = (abstime & 0X0000FFFF);
ADUCM_ST_TIM->WUFB1 = ((abstime >> 16) & 0X0000FFFF);
ADUCM_ST_TIM->CLRI = ADUCM_WUT_CLRI_WUFA | ADUCM_WUT_CLRI_WUFB |
ADUCM_WUT_CLRI_WUFC | ADUCM_WUT_CLRI_WUFD |
ADUCM_WUT_CLRI_ROLL;
ADUCM_ST_TIM->IEN = ADUCM_WUT_IER_WUFB;
}
/**
* @brief Stops the alarm interrupt.
*
* @notapi
*/
static inline void st_lld_stop_alarm(void) {
ADUCM_ST_TIM->IEN = 0;
}
/**
* @brief Sets the alarm time.
*
* @param[in] abstime the time to be set for the next alarm
*
* @notapi
*/
static inline void st_lld_set_alarm(systime_t abstime) {
ADUCM_ST_TIM->WUFB0 = (abstime & 0X0000FFFF);
ADUCM_ST_TIM->WUFB1 = ((abstime >> 16) & 0X0000FFFF);
}
/**
* @brief Returns the current alarm time.
*
* @return The currently set alarm time.
*
* @notapi
*/
static inline systime_t st_lld_get_alarm(void) {
return (systime_t)((ADUCM_ST_TIM->WUFB0 & 0X0000FFFF) |
((ADUCM_ST_TIM->WUFB1 & 0X0000FFFF) << 16));
}
/**
* @brief Determines if the alarm is active.
*
* @return The alarm status.
* @retval false if the alarm is not active.
* @retval true is the alarm is active
*
* @notapi
*/
static inline bool st_lld_is_alarm_active(void) {
return (bool)((ADUCM_ST_TIM->IEN & ADUCM_WUT_IER_WUFB) != 0);
}
#endif /* OSAL_ST_MODE == OSAL_ST_MODE_FREERUNNING */
#endif /* HAL_ST_LLD_H */
/** @} */

View File

@ -74,6 +74,7 @@
*****************************************************************************
*** Next ***
- NEW: Implemented tickless mode on ADuCM36x family
- NEW: STM32 ICU driver now allows to setup the ARR register in the
configuration structure, the default value should be 0xFFFFFFFFU.
- NEW: More time conversion macros added to HAL OSAL.