mirror of
https://github.com/apache/nuttx.git
synced 2026-06-04 23:03:27 +08:00
arch/xmc4 Add tickless support
This commit is contained in:
committed by
Alan Carvalho de Assis
parent
be482cd830
commit
63782c7ff2
@@ -600,6 +600,7 @@ config ARCH_CHIP_XMC4
|
|||||||
select ARCH_HAVE_I2CRESET
|
select ARCH_HAVE_I2CRESET
|
||||||
select ARM_HAVE_MPU_UNIFIED
|
select ARM_HAVE_MPU_UNIFIED
|
||||||
select ARMV7M_HAVE_STACKCHECK
|
select ARMV7M_HAVE_STACKCHECK
|
||||||
|
select ARCH_HAVE_TICKLESS
|
||||||
---help---
|
---help---
|
||||||
Infineon XMC4xxx(ARM Cortex-M4) architectures
|
Infineon XMC4xxx(ARM Cortex-M4) architectures
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ include armv7-m/Make.defs
|
|||||||
CHIP_CSRCS = xmc4_allocateheap.c xmc4_clockconfig.c xmc4_clockutils.c
|
CHIP_CSRCS = xmc4_allocateheap.c xmc4_clockconfig.c xmc4_clockutils.c
|
||||||
CHIP_CSRCS += xmc4_clrpend.c xmc4_flash.c xmc4_gpio.c xmc4_irq.c
|
CHIP_CSRCS += xmc4_clrpend.c xmc4_flash.c xmc4_gpio.c xmc4_irq.c
|
||||||
CHIP_CSRCS += xmc4_lowputc.c xmc4_serial.c xmc4_start.c xmc4_usic.c
|
CHIP_CSRCS += xmc4_lowputc.c xmc4_serial.c xmc4_start.c xmc4_usic.c
|
||||||
|
CHIP_CSRCS += xmc4_ccu4.c
|
||||||
|
|
||||||
# Configuration-dependent Kinetis files
|
# Configuration-dependent Kinetis files
|
||||||
|
|
||||||
@@ -34,6 +35,8 @@ endif
|
|||||||
|
|
||||||
ifneq ($(CONFIG_SCHED_TICKLESS),y)
|
ifneq ($(CONFIG_SCHED_TICKLESS),y)
|
||||||
CHIP_CSRCS += xmc4_timerisr.c
|
CHIP_CSRCS += xmc4_timerisr.c
|
||||||
|
else
|
||||||
|
CHIP_CSRCS += xmc4_tickless.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(CONFIG_BUILD_PROTECTED),y)
|
ifeq ($(CONFIG_BUILD_PROTECTED),y)
|
||||||
|
|||||||
@@ -0,0 +1,195 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* arch/arm/src/xmc4/xmc4_ccu4.c
|
||||||
|
*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership. The
|
||||||
|
* ASF licenses this file to you 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.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* XMC CCU Driver
|
||||||
|
*
|
||||||
|
* For now, this file contains only helper methods mandatory for xmc tickless
|
||||||
|
* feature. Contibutions are welcomed.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Included Files
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <nuttx/config.h>
|
||||||
|
#include <arch/board/board.h>
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
#include "arm_internal.h"
|
||||||
|
#include "hardware/xmc4_ccu4.h"
|
||||||
|
#include "xmc4_ccu4.h"
|
||||||
|
|
||||||
|
#define CCU4_NDIVIDERS 15
|
||||||
|
|
||||||
|
static const uint8_t g_log2divider[CCU4_NDIVIDERS] =
|
||||||
|
{
|
||||||
|
1, /* TIMER_CLOCK1 -> div2 */
|
||||||
|
2, /* TIMER_CLOCK1 -> div4 */
|
||||||
|
3, /* TIMER_CLOCK2 -> div8 */
|
||||||
|
4, /* TIMER_CLOCK2 -> div16 */
|
||||||
|
5, /* TIMER_CLOCK3 -> div32 */
|
||||||
|
6, /* TIMER_CLOCK3 -> div64 */
|
||||||
|
7, /* TIMER_CLOCK4 -> div128 */
|
||||||
|
8, /* TIMER_CLOCK4 -> div256 */
|
||||||
|
9, /* TIMER_CLOCK4 -> div512 */
|
||||||
|
10, /* TIMER_CLOCK4 -> div1024 */
|
||||||
|
11, /* TIMER_CLOCK4 -> div2048 */
|
||||||
|
12, /* TIMER_CLOCK4 -> div4096 */
|
||||||
|
13, /* TIMER_CLOCK4 -> div8192 */
|
||||||
|
14, /* TIMER_CLOCK4 -> div16384 */
|
||||||
|
15 /* TIMER_CLOCK4 -> div32769 */
|
||||||
|
};
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: xmc4_ccu4_divfreq_lookup
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Given the TC input frequency (Ftcin) and a divider index, return the
|
||||||
|
* value of the divided frequency
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* ftcin - TC input frequency
|
||||||
|
* ndx - Divider index
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* The divided frequency value
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static uint32_t xmc4_ccu4_divfreq_lookup(uint32_t ftcin, int ndx)
|
||||||
|
{
|
||||||
|
return ftcin >> g_log2divider[ndx];
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: xmc4_ccu4_freqdiv_lookup
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Given the TC input frequency (Ftcin) and a divider index, return the
|
||||||
|
* value of the Ftcin divider.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* ftcin - TC input frequency
|
||||||
|
* ndx - Divider index
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* The Ftcin input divider value
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static int xmc4_ccu4_freqdiv_lookup(uint32_t ftcin, int ndx)
|
||||||
|
{
|
||||||
|
return 1 << g_log2divider[ndx];
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: xmc4_ccu4_divisor
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Finds the best MCK divisor given the timer frequency and MCK. The
|
||||||
|
* result is guaranteed to satisfy the following equation:
|
||||||
|
*
|
||||||
|
* (Ftcin / (div * 65536)) <= freq <= (Ftcin / dev)
|
||||||
|
*
|
||||||
|
* where:
|
||||||
|
* freq - the desired frequency
|
||||||
|
* Ftcin - The timer/counter input frequency
|
||||||
|
* div - With DIV being the highest possible value.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* frequency Desired timer frequency.
|
||||||
|
* div Divisor value.
|
||||||
|
* pssiv PSSIV field value for divisor.
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Zero (OK) if a proper divisor has been found, otherwise a negated errno
|
||||||
|
* value indicating the nature of the failure.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int xmc4_ccu4_divisor(uint32_t frequency, uint32_t *div, uint32_t *pssiv)
|
||||||
|
{
|
||||||
|
uint32_t ftcin = BOARD_CCU_FREQUENCY;
|
||||||
|
int ndx = 0;
|
||||||
|
|
||||||
|
tmrinfo("frequency=%" PRIu32 "\n", frequency);
|
||||||
|
|
||||||
|
/* Satisfy lower bound. That is, the value of the divider such that:
|
||||||
|
*
|
||||||
|
* frequency >= (tc_input_frequency * 65536) / divider.
|
||||||
|
*/
|
||||||
|
|
||||||
|
while (frequency < (xmc4_ccu4_divfreq_lookup(ftcin, ndx) >> 16))
|
||||||
|
{
|
||||||
|
if (++ndx > CCU4_NDIVIDERS)
|
||||||
|
{
|
||||||
|
/* If no divisor can be found, return -ERANGE */
|
||||||
|
|
||||||
|
tmrerr("ERROR: Lower bound search failed\n");
|
||||||
|
return -ERANGE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Try to maximize DIV while still satisfying upper bound. That the
|
||||||
|
* value of the divider such that:
|
||||||
|
*
|
||||||
|
* frequency < tc_input_frequency / divider.
|
||||||
|
*/
|
||||||
|
|
||||||
|
for (; ndx < (CCU4_NDIVIDERS - 1); ndx++)
|
||||||
|
{
|
||||||
|
if (frequency > xmc4_ccu4_divfreq_lookup(ftcin, ndx + 1))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the divider value */
|
||||||
|
|
||||||
|
if (div)
|
||||||
|
{
|
||||||
|
uint32_t value = xmc4_ccu4_freqdiv_lookup(ftcin, ndx);
|
||||||
|
tmrinfo("return div=%lu\n", (unsigned long)value);
|
||||||
|
*div = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the PSSIV selection */
|
||||||
|
|
||||||
|
if (pssiv)
|
||||||
|
{
|
||||||
|
tmrinfo("return pssiv=%d\n", ndx + 1);
|
||||||
|
*pssiv = ndx + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* arch/arm/src/xmc4/xmc4_ccu4.h
|
||||||
|
*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership. The
|
||||||
|
* ASF licenses this file to you 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.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __ARCH_ARM_SRC_XMC4_XMC4_CCU4_H
|
||||||
|
#define __ARCH_ARM_SRC_XMC4_XMC4_CCU4_H
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Included Files
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <nuttx/config.h>
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Functions Prototypes
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: xmc4_ccu4_divisor
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Finds the best MCK divisor given the timer frequency and MCK. The
|
||||||
|
* result is guaranteed to satisfy the following equation:
|
||||||
|
*
|
||||||
|
* (Ftcin / (div * 65536)) <= freq <= (Ftcin / dev)
|
||||||
|
*
|
||||||
|
* where:
|
||||||
|
* freq - the desired frequency
|
||||||
|
* Ftcin - The timer/counter input frequency
|
||||||
|
* div - With DIV being the highest possible value.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* frequency Desired timer frequency.
|
||||||
|
* div Divisor value.
|
||||||
|
* pssiv PSSIV field value for divisor.
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Zero (OK) if a proper divisor has been found, otherwise a negated errno
|
||||||
|
* value indicating the nature of the failure.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int xmc4_ccu4_divisor(uint32_t frequency, uint32_t *div, uint32_t *pssiv);
|
||||||
|
|
||||||
|
#endif
|
||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user