[bsp][rockchip][rk2108]: add rk2108 base support. (#6040)

* [bsp][rockchip][rk2108]: add rk2108 base support.

Signed-off-by: Steven Liu <steven.liu@rock-chips.com>
This commit is contained in:
Steven-LiuSF
2022-06-09 14:27:30 +08:00
committed by GitHub
parent 3151d01d85
commit 8b60b58b51
135 changed files with 77902 additions and 0 deletions
+6
View File
@@ -0,0 +1,6 @@
# files format check exclude path, please follow the instructions below to modify;
# If you need to exclude an entire folder, add the folder path in dir_path;
# If you need to exclude a file, add the path to the file in file_path.
dir_path:
- rk_hal
+24
View File
@@ -0,0 +1,24 @@
import rtconfig
Import('RTT_ROOT')
Import('SOC')
from building import *
# get current directory
cwd = GetCurrentDir()
hal_lib = cwd + '/rk_hal/lib'
# The set of source files associated with this SConscript file.
src = Glob(hal_lib + '/CMSIS/Device/' + SOC + '/Source/*.c')
src += Glob(hal_lib + '/hal/src/*.c')
src += Glob(hal_lib + '/hal/src/*/*.c')
src += Glob(hal_lib + '/bsp/' + SOC + '/*.c')
#add include path
path = [hal_lib + '/hal/inc',
hal_lib + '/bsp/' + SOC,
hal_lib + '/CMSIS/Device/' + SOC + '/Include',
hal_lib + '/CMSIS/Core/Include']
group = DefineGroup(SOC + '_StdPeriph', src, depend = [''], CPPPATH = path)
Return('group')
+56
View File
@@ -0,0 +1,56 @@
menu "RT-Thread rockchip common drivers"
config RT_USING_RESET
bool "Enable reset support"
config RT_USING_CACHE
bool "Enable cache"
default y
config RT_USING_UNCACHE_HEAP
bool "Enable uncache heap"
select RT_USING_MEMHEAP
default n
if RT_USING_UNCACHE_HEAP && ARCH_ARM_CORTEX_M
config RT_UNCACHE_HEAP_ORDER
hex "For MCU uncache heap size(0x0D=16KB, 0x0E=32KB, 0x0F=64KB)"
range 0x0D 0x10
depends on RT_USING_UNCACHE_HEAP
default 0x0E
help
set uncache heap size, it in tail of sram
Examples:
0x0D => 16KB
0x0E => 32KB
0x0F => 64KB
0x10 => 128KB
endif
config RT_USING_LARGE_HEAP
bool "Enable large heap"
select RT_USING_MEMHEAP
default n
if RT_USING_LARGE_HEAP
config RT_LARGE_MALLOC_THRRESH
int "large heap malloc threshold"
default 512
depends on RT_USING_LARGE_HEAP
help
the memory will allocate in large heap while the allocated size over this
config RT_LARGE_HEAP_SIZE
int "large heap size"
default 524288
depends on RT_USING_LARGE_HEAP
help
the remaining memory must be able to accommodate this heap
endif
config RT_USING_PM_RUNTIME
bool "Enable pm runtime"
default n
endmenu
+17
View File
@@ -0,0 +1,17 @@
Import('RTT_ROOT')
Import('rtconfig')
from building import *
cwd = GetCurrentDir()
src = Glob('*.c')
CPPPATH = [cwd]
group = DefineGroup('CommonDrivers', src, depend = [''], CPPPATH = CPPPATH)
list = os.listdir(cwd)
for d in list:
path = os.path.join(cwd, d)
if os.path.isfile(os.path.join(path, 'SConscript')):
group = group + SConscript(os.path.join(d, 'SConscript'))
Return('group')
+289
View File
@@ -0,0 +1,289 @@
/**
* Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd
*
* SPDX-License-Identifier: Apache-2.0
******************************************************************************
* @file drv_cache.c
* @version V0.1
* @brief cpu cache interface
*
* Change Logs:
* Date Author Notes
* 2019-04-01 Cliff.Chen first implementation
*
******************************************************************************
*/
/** @addtogroup RKBSP_Driver_Reference
* @{
*/
/** @addtogroup Cache
* @{
*/
/** @defgroup Cache_How_To_Use How To Use
* @{
The Cache driver use to keeping data coherent between cpu and device, it can be used in the following three scenarios:
- **The cpu want to read the latest data that has been modified by device**:
- The device modify the data;
- The cpu invalidate the data by rt_hw_cpu_dcache_ops(RT_HW_CACHE_INVALIDATE,
addr, size);
- The cpu read the latest data;
- **The device want to read the latest data that was modified by cpu**:
- The cpu modify the data;
- The device flush the data by rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, addr, size);
- The device read the latest data;
- **The cpu want to execute two code section on the same memory**:
- Loading the code A in the memory from start address of ADDR;
- Executing the code A;
- Loading the code B in the memory from start address of ADDR;
- Invalidating by rt_hw_cpu_icache_ops(RT_HW_CACHE_INVALIDATE, ADDR, size);
- Executing the code B
@} */
#include <rthw.h>
#include "drv_cache.h"
#include "hal_base.h"
#if defined(ARCH_ARM_CORTEX_M)
#ifdef RT_USING_CMBACKTRACE
#include "cm_backtrace.h"
#endif
/********************* Private MACRO Definition ******************************/
/** @defgroup CACHE_Private_Macro Private Macro
* @{
*/
/** @} */ // CACHE_Private_Macro
/********************* Private Structure Definition **************************/
/** @defgroup CACHE_Private_Structure Private Structure
* @{
*/
/** @} */ // CACHE_Private_Structure
/********************* Private Variable Definition ***************************/
/** @defgroup CACHE_Private_Variable Private Variable
* @{
*/
/** @} */ // CACHE_Private_Variable
/********************* Private Function Definition ***************************/
/** @defgroup CACHE_Private_Function Private Function
* @{
*/
/** @} */ // CACHE_Private_Function
/********************* Public Function Definition ****************************/
/** @defgroup CACHE_Public_Functions Public Functions
* @{
*/
/**
* @brief Enable the icache of cpu.
* @attention The cache will be enabled when board initialization, do not dynamically switch cache
* unless specifically required.
*/
void rt_hw_cpu_icache_enable(void)
{
HAL_ICACHE_Enable();
}
/**
* @brief Disable the icache of cpu.
* @attention The cache will be enabled when board initialization, do not dynamically switch cache
* unless specifically required.
*/
void rt_hw_cpu_icache_disable(void)
{
HAL_ICACHE_Disable();
}
/**
* @brief Get icache status.
* @return 0
* @attention Not yet implemnted.
*/
rt_base_t rt_hw_cpu_icache_status(void)
{
return 0;
}
/**
* @brief Icache maintain operation.
* @param ops: RT_HW_CACHE_INVALIDATE for cache invalidate.
* @param addr: The start address of memory you want maintain.
* @param size: The length of memory you want maintain.
*/
void rt_hw_cpu_icache_ops(int ops, void *addr, int size)
{
if (ops & RT_HW_CACHE_INVALIDATE)
{
HAL_ICACHE_InvalidateByRange((uint32_t)addr, size);
}
}
/**
* @brief Enable the dcache of cpu.
* @attention The cache will be enabled when board initialization, do not dynamically switch cache
* unless specifically required.
*/
void rt_hw_cpu_dcache_enable(void)
{
HAL_DCACHE_Enable();
}
/**
* @brief Disable the dcache of cpu.
* @attention The cache will be enabled when board initialization, do not dynamically switch cache
* unless specifically required.
*/
void rt_hw_cpu_dcache_disable(void)
{
HAL_DCACHE_Disable();
}
/**
* @brief Get dcache status.
* @return 0
* @attention Not yet implemnted.
*/
rt_base_t rt_hw_cpu_dcache_status(void)
{
return 0;
}
/**
* @brief Dcache maintain operation.
* @param ops: RT_HW_CACHE_INVALIDATE for cache invalidate,
* RT_HW_CACHE_FLUSH for cache clean.
* @param addr: The start address of memory you want maintain.
* @param size: The length of memory you want maintain.
*/
void rt_hw_cpu_dcache_ops(int ops, void *addr, int size)
{
if ((ops & RT_HW_CACHE_FLUSH) && (ops & RT_HW_CACHE_INVALIDATE))
{
HAL_DCACHE_CleanInvalidateByRange((uint32_t)addr, size);
}
else if (ops & RT_HW_CACHE_FLUSH)
{
HAL_DCACHE_CleanByRange((uint32_t)addr, size);
}
else if (ops & RT_HW_CACHE_INVALIDATE)
{
HAL_DCACHE_InvalidateByRange((uint32_t)addr, size);
}
else
{
RT_ASSERT(0);
}
}
/**
* @brief Dump ahb error occur in icache & dcache, it called by cache interrupt.
* @param fault_handler_lr: The value of LR register.
* @param fault_handler_sp: The value of SP register.
*/
void cache_dump_ahb_error(uint32_t fault_handler_lr, uint32_t fault_handler_sp)
{
uint32_t addr;
if (HAL_ICACHE_GetInt())
{
addr = HAL_ICACHE_GetErrAddr();
rt_kprintf("a ahb bus error occur in icache, addr=%p\n", (void *)addr);
HAL_ICACHE_ClearInt();
}
if (HAL_DCACHE_GetInt())
{
addr = HAL_DCACHE_GetErrAddr();
rt_kprintf("a ahb bus error occur in dcache, addr=%p\n", (void *)addr);
HAL_DCACHE_ClearInt();
}
#ifdef RT_USING_CMBACKTRACE
cm_backtrace_fault(fault_handler_lr, fault_handler_sp);
#endif
}
extern void CACHE_IRQHandler(void);
/**
* @brief Enable cache interrupt and register the handler, it called by board initialization.
* @return RT_EOK
*/
int rt_hw_cpu_cache_init(void)
{
#if defined(ICACHE) || defined(DCACHE)
HAL_ICACHE_EnableInt();
HAL_DCACHE_EnableInt();
#if defined(RKMCU_PISCES) || defined(RKMCU_RK2108)
rt_hw_interrupt_install(CACHE_IRQn, (rt_isr_handler_t)CACHE_IRQHandler, RT_NULL, RT_NULL);
rt_hw_interrupt_umask(CACHE_IRQn);
#elif defined(RKMCU_RK2206)
rt_hw_interrupt_install(CACHE0_I_IRQn, (rt_isr_handler_t)CACHE_IRQHandler, RT_NULL, RT_NULL);
rt_hw_interrupt_install(CACHE0_D_IRQn, (rt_isr_handler_t)CACHE_IRQHandler, RT_NULL, RT_NULL);
rt_hw_interrupt_umask(CACHE0_I_IRQn);
rt_hw_interrupt_umask(CACHE0_D_IRQn);
#endif
#endif
return RT_EOK;
}
/** @} */ // CACHE_Public_Functions
#else
RT_WEAK void rt_hw_cpu_icache_enable(void)
{
}
RT_WEAK void rt_hw_cpu_icache_disable(void)
{
}
RT_WEAK rt_base_t rt_hw_cpu_icache_status(void)
{
return 0;
}
RT_WEAK void rt_hw_cpu_icache_ops(int ops, void *addr, int size)
{
}
RT_WEAK void rt_hw_cpu_dcache_enable(void)
{
}
RT_WEAK void rt_hw_cpu_dcache_disable(void)
{
}
RT_WEAK rt_base_t rt_hw_cpu_dcache_status(void)
{
return 0;
}
RT_WEAK void rt_hw_cpu_dcache_ops(int ops, void *addr, int size)
{
}
#endif
/** @} */ // Cache
/** @} */ // RKBSP_Driver_Reference
+22
View File
@@ -0,0 +1,22 @@
/**
* Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd
*
* SPDX-License-Identifier: Apache-2.0
******************************************************************************
* @file drv_cache.h
* @version V0.1
* @brief cpu cache interface
*
* Change Logs:
* Date Author Notes
* 2019-04-01 Cliff.Chen first implementation
*
******************************************************************************
*/
#ifndef __DRV_CACHE_H__
#define __DRV_CACHE_H__
#include <rtthread.h>
int rt_hw_cpu_cache_init(void);
#endif
@@ -0,0 +1,36 @@
/**
* Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd
*
* SPDX-License-Identifier: Apache-2.0
******************************************************************************
* @file drv_cache_arm.s
* @version V0.1
* @brief cpu cache interface
*
* Change Logs:
* Date Author Notes
* 2019-04-01 Cliff.Chen first implementation
*
******************************************************************************
*/
AREA |.text|, CODE, READONLY, ALIGN=2
THUMB
REQUIRE8
PRESERVE8
IMPORT cache_dump_ahb_error
EXPORT CACHE_IRQHandler
CACHE_IRQHandler PROC
MRS r2, PRIMASK
CPSID I
MOV r0, lr ; get lr
MOV r1, sp ; get stack pointer (current is MSP)
BL cm_backtrace_fault
Fault_Loop
BL Fault_Loop ;while(1)
ENDP
END
@@ -0,0 +1,33 @@
/**
* Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd
*
* SPDX-License-Identifier: Apache-2.0
******************************************************************************
* @file drv_cache_gcc.S
* @version V0.1
* @brief cpu cache interface
*
* Change Logs:
* Date Author Notes
* 2019-04-01 Cliff.Chen first implementation
*
******************************************************************************
*/
.cpu cortex-m4
.syntax unified
.thumb
.text
.global CACHE_IRQHandler
.type CACHE_IRQHandler, %function
CACHE_IRQHandler:
MRS r2, PRIMASK
CPSID I
MOV r0, lr /* get lr */
MOV r1, sp /* get stack pointer (current is MSP) */
BL cache_dump_ahb_error
Fault_Loop:
BL Fault_Loop /* while(1) */
@@ -0,0 +1,35 @@
/**
* Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd
*
* SPDX-License-Identifier: Apache-2.0
******************************************************************************
* @file drv_cache_iar.s
* @version V0.1
* @brief cpu cache interface
*
* Change Logs:
* Date Author Notes
* 2019-04-01 Cliff.Chen first implementation
*
******************************************************************************
*/
SECTION .text:CODE(2)
THUMB
REQUIRE8
PRESERVE8
IMPORT cache_dump_ahb_error
EXPORT CACHE_IRQHandler
CACHE_IRQHandler:
MRS r2, PRIMASK
CPSID I
MOV r0, lr ; get lr
MOV r1, sp ; get stack pointer (current is MSP)
BL cm_backtrace_fault
Fault_Loop
BL Fault_Loop ;while(1)
END
+491
View File
@@ -0,0 +1,491 @@
/**
* Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd
*
* SPDX-License-Identifier: Apache-2.0
******************************************************************************
* @file drv_clock.c
* @version V0.1
* @brief cru clock interface
*
* Change Logs:
* Date Author Notes
* 2019-07-11 Elaine.Zhang first implementation
*
******************************************************************************
*/
/** @addtogroup RKBSP_Driver_Reference
* @{
*/
/** @addtogroup Clock
* @{
*/
/** @defgroup Clock_How_To_Use How To Use
* @{
The Clock driver use to configure clock frequency, enable/disable clock output, clock reset, power on/off power domain,
it can be used in the following three scenarios:
- **Configure clock frequency**:
- The device set clock rate by clk_set_rate(eCLOCK_Name clk_id, uint32_t rate);
- The device get clock rate by clk_get_rate(eCLOCK_Name clk_id);
- **Enable/disable clock output**:
- The device get clock by get_clk_gate_from_id(int clk_id);
- The device set clock enable/disable by clk_enable(struct clk_gate *gate) or clk_disable(struct clk_gate *gate);
- **Power on/off power domain**:
- The device get pd by get_pd_from_id(int pd_id);
- The device power on/off pd by pd_power(struct pd *power, int on);
@} */
#include <rtdevice.h>
#include <rtthread.h>
#if defined(RT_USING_CRU)
#include "hal_base.h"
#include "drv_clock.h"
static const struct clk_init *g_clk_init = RT_NULL;
static rt_slist_t clk_gate_list;
static struct rt_mutex clk_lock;
static struct rt_mutex gate_lock;
#if defined(RT_USING_PMU)
static struct rt_mutex pd_lock;
static rt_slist_t pd_list;
#endif
/********************* Public Function Definition ****************************/
/** @defgroup CLOCK_Public_Functions Public Functions
* @{
*/
/**
* @brief clk set enable.
* @param gate: get_clk_gate_from_id.
* @retval -RT_EINVAL: struct gate is invalid argument
* @retval -RT_ERROR: clk enable failed.
*/
rt_err_t clk_enable(struct clk_gate *gate)
{
rt_err_t error = RT_EOK;
HAL_Status ret;
if (!gate)
{
return -RT_EINVAL;
}
rt_mutex_take(&gate_lock, RT_WAITING_FOREVER);
if (gate->enable_count == 0)
{
ret = HAL_CRU_ClkEnable(gate->gate_id);
if (ret != HAL_OK)
error = -RT_ERROR;
}
gate->enable_count++;
rt_mutex_release(&gate_lock);
return error;
}
/**
* @brief clk set disable.
* @param gate: get_clk_gate_from_id.
* @retval -RT_EINVAL: struct gate is invalid argument
* @retval -RT_ERROR: clk disable failed.
*/
rt_err_t clk_disable(struct clk_gate *gate)
{
rt_err_t error = RT_EOK;
HAL_Status ret;
if (!gate)
{
return -RT_EINVAL;
}
rt_mutex_take(&gate_lock, RT_WAITING_FOREVER);
if (gate->enable_count == 0)
{
rt_kprintf("It may be wrong to used, make enable first.(gate_id = %d)\n", __func__, gate->gate_id);
goto out;
}
if (--gate->enable_count > 0)
{
goto out;
}
ret = HAL_CRU_ClkDisable(gate->gate_id);
if (ret != HAL_OK)
error = -RT_ERROR;
out:
rt_mutex_release(&gate_lock);
return error;
}
/**
* @brief clk is enabled.
* @param gate: get_clk_gate_from_id.
* @retval 0: clk is disabled
* @retval 1: clk is enabled
*/
int clk_is_enabled(struct clk_gate *gate)
{
if (!gate)
{
return 0;
}
return HAL_CRU_ClkIsEnabled(gate->gate_id);
}
/**
* @brief get clk gate by id.
* @param gate_id: clk gate id.
* @return struct of type clk_gate
*/
struct clk_gate *get_clk_gate_from_id(int gate_id)
{
struct clk_gate *clk_gate;
rt_mutex_take(&gate_lock, RT_WAITING_FOREVER);
rt_slist_for_each_entry(clk_gate, &clk_gate_list, node)
{
if (clk_gate->gate_id == gate_id)
{
goto out;
}
}
clk_gate = rt_calloc(1, sizeof(struct clk_gate));
clk_gate->gate_id = gate_id;
clk_gate->enable_count = 0;
rt_slist_insert(&clk_gate_list, &clk_gate->node);
out:
clk_gate->ref_count++;
rt_mutex_release(&gate_lock);
return clk_gate;
}
/**
* @brief put clk gate.
* @param gate: get_clk_gate_from_id.
*/
void put_clk_gate(struct clk_gate *gate)
{
if (!gate)
return;
rt_mutex_take(&gate_lock, RT_WAITING_FOREVER);
if (--gate->ref_count > 0)
{
goto out;
}
rt_slist_remove(&clk_gate_list, &gate->node);
rt_free(gate);
out:
rt_mutex_release(&gate_lock);
}
/**
* @brief clk get rate.
* @param clk_id: clk id.
* @return the return value of HAL_CRU_ClkGetFreq, which returns the frequency value in unit hz.
*/
uint32_t clk_get_rate(eCLOCK_Name clk_id)
{
uint32_t rate;
rt_mutex_take(&clk_lock, RT_WAITING_FOREVER);
rate = HAL_CRU_ClkGetFreq(clk_id);
rt_mutex_release(&clk_lock);
return rate;
}
/**
* @brief clk set rate.
* @param clk_id: clk id.
* @param rate: frequency value hz.
* @retval RT_EOK: clk set successful
* @retval HAL_OK: HAL_CRU_ClkSetFreq set frequency successfully
* @retval HAL_ERROR: HAL_CRU_ClkSetFreq set frequency failed
* @retval HAL_INVAL: HAL_CRU_ClkSetFreq set frequency unsupported
*/
rt_err_t clk_set_rate(eCLOCK_Name clk_id, uint32_t rate)
{
rt_err_t error = RT_EOK;
if (rate == clk_get_rate(clk_id))
return error;
rt_mutex_take(&clk_lock, RT_WAITING_FOREVER);
error = HAL_CRU_ClkSetFreq(clk_id, rate);
rt_mutex_release(&clk_lock);
return error;
}
#if defined(RT_USING_PMU)
/**
* @brief pd power on.
* @param power: get_pd_from_id.
* @retval -RT_EINVAL: struct pd is invalid argument
* @retval -RT_ERROR: pd power on failed.
* @retval RT_EOK: pd power on success.
*/
rt_err_t pd_on(struct pd *power)
{
rt_err_t error = RT_EOK;
HAL_Status ret;
if (!power)
{
return -RT_EINVAL;
}
rt_mutex_take(&pd_lock, RT_WAITING_FOREVER);
if (power->enable_count == 0)
{
ret = HAL_PD_On(power->pd_id);
if (ret != HAL_OK)
error = -RT_ERROR;
}
power->enable_count++;
rt_mutex_release(&pd_lock);
return error;
}
/**
* @brief pd power off.
* @param power: get_pd_from_id.
* @retval -RT_EINVAL: struct pd is invalid argument
* @retval -RT_ERROR: pd power off failed.
* @retval RT_EOK: pd power off success.
*/
rt_err_t pd_off(struct pd *power)
{
rt_err_t error = RT_EOK;
HAL_Status ret;
if (!power)
{
return -RT_EINVAL;
}
rt_mutex_take(&pd_lock, RT_WAITING_FOREVER);
if (--power->enable_count > 0)
{
goto out;
}
ret = HAL_PD_Off(power->pd_id);
if (ret != HAL_OK)
error = -RT_ERROR;
out:
rt_mutex_release(&pd_lock);
return error;
}
/**
* @brief get pd by id.
* @param pd_id: pd id.
* @return struct of type pd
*/
struct pd *get_pd_from_id(ePD_Id pd_id)
{
struct pd *pd;
if (!pd_id)
return NULL;
rt_mutex_take(&pd_lock, RT_WAITING_FOREVER);
rt_slist_for_each_entry(pd, &pd_list, node)
{
if (pd->pd_id == pd_id)
{
goto out;
}
}
pd = rt_calloc(1, sizeof(struct pd));
pd->pd_id = pd_id;
pd->enable_count = 0;
rt_slist_insert(&pd_list, &pd->node);
out:
pd->ref_count++;
rt_mutex_release(&pd_lock);
return pd;
}
/**
* @brief put pd.
* @param power: get_pd_from_id.
*/
void put_pd(struct pd *power)
{
if (!power)
return;
rt_mutex_take(&pd_lock, RT_WAITING_FOREVER);
if (--power->ref_count > 0)
{
goto out;
}
rt_slist_remove(&pd_list, &power->node);
rt_free(power);
out:
rt_mutex_release(&pd_lock);
}
#endif
/**
* @brief clock dev init.
* @return RT_EOK
*/
int clock_dev_init(void)
{
if (rt_mutex_init(&(clk_lock), "clkLock", RT_IPC_FLAG_FIFO) != RT_EOK)
{
RT_ASSERT(0);
}
if (rt_mutex_init(&(gate_lock), "gateLock", RT_IPC_FLAG_FIFO) != RT_EOK)
{
RT_ASSERT(0);
}
rt_slist_init(&clk_gate_list);
#if defined(RT_USING_PMU)
if (rt_mutex_init(&(pd_lock), "pdLock", RT_IPC_FLAG_FIFO) != RT_EOK)
{
RT_ASSERT(0);
}
rt_slist_init(&pd_list);
#endif
return RT_EOK;
}
INIT_BOARD_EXPORT(clock_dev_init);
/**
* @brief clock init frequency.
* @param clk_inits: some need init clks.
* @param clk_dump: if need printf clk get freq after setting.
*/
void clk_init(const struct clk_init *clk_inits, bool clk_dump)
{
const struct clk_init *clks = clk_inits;
while (clks->name)
{
if (clks->init_rate)
{
HAL_CRU_ClkSetFreq(clks->clk_id, clks->init_rate);
}
if (clk_dump)
rt_kprintf("%s: %s = %d\n", __func__, clks->name, HAL_CRU_ClkGetFreq(clks->clk_id));
clks++;
}
g_clk_init = clk_inits;
}
/**
* @brief clock disable unused.
* @param clks_unused: disable some not needed clks.
*/
void clk_disable_unused(const struct clk_unused *clks_unused)
{
const struct clk_unused *clks = clks_unused;
while (clks->gate_val)
{
if (clks->is_pmucru)
{
#if defined(CRU_PMU_CLKGATE_CON0_OFFSET)
CRU->PMU_CLKGATE_CON[clks->gate_con] = clks->gate_val;
#endif
}
else
{
CRU->CRU_CLKGATE_CON[clks->gate_con] = clks->gate_val;
}
clks++;
}
}
#if defined(RT_USING_CRU_DUMP)
/**
* @brief clock dump frequency, dump cru registers, used for debug.
*/
static void clk_dump(void)
{
const struct clk_init *clks = g_clk_init;
int i;
if (clks)
{
while (clks->name)
{
rt_kprintf("%s: %s[%x] = %d\n", __func__, clks->name, clks->clk_id,
HAL_CRU_ClkGetFreq(clks->clk_id));
clks++;
}
}
for (i = 0; i < HAL_ARRAY_SIZE(CRU->CRU_CLKSEL_CON); i++)
{
rt_kprintf("%s: cru_sel_con[%d] = %lx\n", __func__, i, CRU->CRU_CLKSEL_CON[i]);
}
for (i = 0; i < HAL_ARRAY_SIZE(CRU->CRU_CLKGATE_CON); i++)
{
rt_kprintf("%s: cru_gate_con[%d] = %lx\n", __func__, i, CRU->CRU_CLKGATE_CON[i]);
}
for (i = 0; i < HAL_ARRAY_SIZE(CRU->CRU_SOFTRST_CON); i++)
{
rt_kprintf("%s: cru_softreset_con[%d] = %lx\n", __func__, i, CRU->CRU_SOFTRST_CON[i]);
}
}
#ifdef RT_USING_FINSH
#include <finsh.h>
MSH_CMD_EXPORT(clk_dump, cru drive test. e.g: clk_dump);
#endif
#endif
/** @} */
#endif
/** @} */
/** @} */
+108
View File
@@ -0,0 +1,108 @@
/**
* Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd
*
* SPDX-License-Identifier: Apache-2.0
******************************************************************************
* @file drv_clock.h
* @version V0.1
* @brief clock interface
*
* Change Logs:
* Date Author Notes
* 2019-07-11 Elaine.Zhang first implementation
*
******************************************************************************
*/
#ifndef _DRV_CLOCK_H_
#define _DRV_CLOCK_H_
#include <hal_base.h>
#ifdef RT_CONSOLE_DEVICE_NAME
#define RT_CONSOLE_DEVICE_UART(ID) \
((strcmp(RT_CONSOLE_DEVICE_NAME, "uart"#ID)) ? 0:1)
#else
#define RT_CONSOLE_DEVICE_UART(ID) 0
#endif
#define INIT_CLK(NAME, ID, RATE) \
{ .name = NAME, .clk_id = ID, .init_rate = RATE, }
struct clk_gate
{
uint32_t gate_id;
int enable_count;
int ref_count;
rt_slist_t node;
};
struct clk_init
{
const char *name;
uint32_t clk_id;
uint32_t init_rate;
};
struct clk_unused
{
uint32_t is_pmucru : 1;
uint32_t gate_con : 31;
uint32_t gate_val;
};
struct pd
{
uint32_t pd_id;
int enable_count;
int ref_count;
rt_slist_t node;
};
/**
* @brief clk set enable by id.
* @param gate_id: gate id.
* @retval RT_EOK: clk set enable success.
* @retval -RT_ERROR: clk set enable failed.
*/
static inline rt_err_t clk_enable_by_id(int gate_id)
{
#ifdef HAL_CRU_MODULE_ENABLED
return (HAL_CRU_ClkEnable(gate_id) == HAL_OK) ? RT_EOK : -RT_ERROR;
#else
return RT_EOK;
#endif
}
/**
* @brief clk set disable by id.
* @param gate_id: gate id.
* @retval RT_EOK: clk set disable success.
* @retval -RT_ERROR: clk set disable failed.
*/
static inline rt_err_t clk_disable_by_id(int gate_id)
{
#ifdef HAL_CRU_MODULE_ENABLED
return (HAL_CRU_ClkDisable(gate_id) == HAL_OK) ? RT_EOK : -RT_ERROR;
#else
return RT_EOK;
#endif
}
struct clk_gate *get_clk_gate_from_id(int gate_id);
void put_clk_gate(struct clk_gate *gate);
rt_err_t clk_enable(struct clk_gate *gate);
rt_err_t clk_disable(struct clk_gate *gate);
int clk_is_enabled(struct clk_gate *gate);
uint32_t clk_get_rate(eCLOCK_Name clk_id);
rt_err_t clk_set_rate(eCLOCK_Name clk_id, uint32_t rate);
#if defined(RT_USING_PMU)
struct pd *get_pd_from_id(ePD_Id pd_id);
void put_pd(struct pd *power);
rt_err_t pd_on(struct pd *power);
rt_err_t pd_off(struct pd *power);
#endif
void clk_init(const struct clk_init *clk_inits, bool clk_dump);
void clk_disable_unused(const struct clk_unused *clks_unused);
#endif // _DRV_CLOCK_H_
+361
View File
@@ -0,0 +1,361 @@
/**
* Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd
*
* SPDX-License-Identifier: Apache-2.0
******************************************************************************
* @file drv_gpio.c
* @author Jay Xu
* @version V0.1
* @date 2019/5/15
* @brief GPIO Driver
*
******************************************************************************
*/
/** @addtogroup RKBSP_Driver_Reference
* @{
*/
/** @addtogroup GPIO
* @{
*/
/** @defgroup GPIO_How_To_Use How To Use
* @{
The GPIO driver use to configure or control GPIO pins on SoCs, it can be used in
the following three scenarios:
- (A) The GPIO PIN APIs provide by pin component:
- 1) rt_pin_read - get pin level, pin number caculated by BANK_PIN(banknum, pinnum);
- 2) rt_pin_write- set pin level, pin number caculated by BANK_PIN(banknum, pinnum);
- 3) rt_pin_mode - set pin input/output, pin number caculated by BANK_PIN(banknum, pinnum);
- (B) The GPIO IRQ APIs provide by pin component:
- 1) pin_attach_irq;
- 2) pin_detach_irq;
- 3) pin_irq_enable;
- (C) The GPIO PIN NUMBER calculated by BANK_PIN(b,p), such as
BANK_PIN(0, 5) means GPIO0_A5
BANK_PIN(1, 8) means GPIO1_B0
See more information, click [here](http://www.rt-thread.org/document/site/programming-manual/device/pin/pin/)
@} */
#include <rthw.h>
#include <rtdevice.h>
#include <rtthread.h>
#ifdef RT_USING_PIN
#include "hal_base.h"
#include "drv_gpio.h"
/********************* Private MACRO Definition ******************************/
#define PIN_NUM(p) ((p & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT)
#define PIN_BANK(p) ((p & GPIO_BANK_MASK) >> GPIO_BANK_SHIFT)
#define BANK_PIN_DEFAULT (-1)
/********************* Private Structure Definition **************************/
static struct GPIO_REG *GPIO_GROUP[] =
{
#ifdef GPIO0
GPIO0,
#endif
#ifdef GPIO1
GPIO1,
#endif
#ifdef GPIO2
GPIO2,
#endif
#ifdef GPIO3
GPIO3,
#endif
#ifdef GPIO4
GPIO4,
#endif
};
#define GPIO_BANK_NUM HAL_ARRAY_SIZE(GPIO_GROUP)
#define get_st_gpio(p) (GPIO_GROUP[PIN_BANK(p)])
#define get_st_pin(p) (HAL_BIT(PIN_NUM(p)))
static struct rt_pin_irq_hdr pin_irq_hdr_tab[GPIO_BANK_NUM * PIN_NUMBER_PER_BANK];
/********************* Private Function Definition ***************************/
/** @defgroup GPIO_Private_Function Private Function
* @{
*/
static rt_err_t pin_attach_irq(struct rt_device *device, rt_int32_t pin,
rt_uint32_t mode, void (*hdr)(void *args), void *args)
{
rt_base_t level;
if (pin < 0 || pin >= HAL_ARRAY_SIZE(pin_irq_hdr_tab))
{
return RT_ENOSYS;
}
level = rt_hw_interrupt_disable();
if (pin_irq_hdr_tab[pin].pin == pin &&
pin_irq_hdr_tab[pin].hdr == hdr &&
pin_irq_hdr_tab[pin].mode == mode &&
pin_irq_hdr_tab[pin].args == args)
{
rt_hw_interrupt_enable(level);
return RT_EOK;
}
if (pin_irq_hdr_tab[pin].pin != BANK_PIN_DEFAULT && pin_irq_hdr_tab[pin].hdr != RT_NULL)
{
rt_hw_interrupt_enable(level);
return RT_EBUSY;
}
pin_irq_hdr_tab[pin].pin = pin;
pin_irq_hdr_tab[pin].hdr = hdr;
pin_irq_hdr_tab[pin].mode = mode;
pin_irq_hdr_tab[pin].args = args;
rt_hw_interrupt_enable(level);
return RT_EOK;
}
static rt_err_t pin_detach_irq(struct rt_device *device, rt_int32_t pin)
{
rt_base_t level;
if (pin < 0 || pin >= HAL_ARRAY_SIZE(pin_irq_hdr_tab))
{
return RT_ENOSYS;
}
level = rt_hw_interrupt_disable();
if (pin_irq_hdr_tab[pin].pin == BANK_PIN_DEFAULT)
{
rt_hw_interrupt_enable(level);
return RT_EOK;
}
pin_irq_hdr_tab[pin].pin = BANK_PIN_DEFAULT;
pin_irq_hdr_tab[pin].hdr = RT_NULL;
pin_irq_hdr_tab[pin].mode = 0;
pin_irq_hdr_tab[pin].args = RT_NULL;
rt_hw_interrupt_enable(level);
return RT_EOK;
}
static rt_err_t pin_irq_enable(struct rt_device *dev, rt_base_t pin, rt_uint32_t enabled)
{
rt_base_t level;
eGPIO_intType mode;
RT_ASSERT(PIN_BANK(pin) < GPIO_BANK_NUM);
if (enabled == PIN_IRQ_ENABLE)
{
if (pin < 0 || pin >= HAL_ARRAY_SIZE(pin_irq_hdr_tab))
{
return RT_ENOSYS;
}
level = rt_hw_interrupt_disable();
if (pin_irq_hdr_tab[pin].pin == BANK_PIN_DEFAULT)
{
rt_hw_interrupt_enable(level);
return RT_ENOSYS;
}
switch (pin_irq_hdr_tab[pin].mode)
{
case PIN_IRQ_MODE_RISING:
mode = GPIO_INT_TYPE_EDGE_RISING;
break;
case PIN_IRQ_MODE_FALLING:
mode = GPIO_INT_TYPE_EDGE_FALLING;
break;
case PIN_IRQ_MODE_RISING_FALLING:
mode = GPIO_INT_TYPE_EDGE_BOTH;
break;
case PIN_IRQ_MODE_LOW_LEVEL:
mode = GPIO_INT_TYPE_LEVEL_LOW;
break;
case PIN_IRQ_MODE_HIGH_LEVEL:
mode = GPIO_INT_TYPE_LEVEL_HIGH;
break;
default:
rt_hw_interrupt_enable(level);
return RT_EINVAL;
}
HAL_GPIO_SetIntType(get_st_gpio(pin), get_st_pin(pin), mode);
HAL_GPIO_EnableIRQ(get_st_gpio(pin), get_st_pin(pin));
rt_hw_interrupt_enable(level);
}
else if (enabled == PIN_IRQ_DISABLE)
{
HAL_GPIO_DisableIRQ(get_st_gpio(pin), get_st_pin(pin));
}
else
{
return RT_ENOSYS;
}
return RT_EOK;
}
static void pin_mode(struct rt_device *dev, rt_base_t pin, rt_base_t mode)
{
RT_ASSERT(PIN_BANK(pin) < GPIO_BANK_NUM);
switch (mode)
{
case PIN_MODE_OUTPUT:
case PIN_MODE_OUTPUT_OD:
#ifdef HAL_PINCTRL_MODULE_ENABLED
#ifdef RK_BSP_TEMP
HAL_PINCTRL_SetIOMUX(PIN_BANK(pin), HAL_BIT(pin), PIN_CONFIG_MUX_FUNC0);
#endif
#endif
HAL_GPIO_SetPinDirection(get_st_gpio(pin), get_st_pin(pin), GPIO_OUT);
break;
case PIN_MODE_INPUT:
case PIN_MODE_INPUT_PULLUP:
case PIN_MODE_INPUT_PULLDOWN:
#ifdef HAL_PINCTRL_MODULE_ENABLED
#ifdef RK_BSP_TEMP
HAL_PINCTRL_SetIOMUX(PIN_BANK(pin), HAL_BIT(pin), PIN_CONFIG_MUX_FUNC0);
#endif
#endif
HAL_GPIO_SetPinDirection(get_st_gpio(pin), get_st_pin(pin), GPIO_IN);
break;
default:
break;
}
}
static void pin_write(struct rt_device *dev, rt_base_t pin, rt_base_t value)
{
RT_ASSERT(PIN_BANK(pin) < GPIO_BANK_NUM);
HAL_GPIO_SetPinLevel(get_st_gpio(pin), get_st_pin(pin), value);
}
static int pin_read(struct rt_device *dev, rt_base_t pin)
{
RT_ASSERT(PIN_BANK(pin) < GPIO_BANK_NUM);
return HAL_GPIO_GetPinLevel(get_st_gpio(pin), get_st_pin(pin));;
}
/** @} */
#ifdef GPIO0
void pin_gpio0_handler(void)
{
rt_interrupt_enter();
HAL_GPIO_IRQHandler(GPIO0, GPIO_BANK0);
rt_interrupt_leave();
}
#endif
#ifdef GPIO1
void pin_gpio1_handler(void)
{
rt_interrupt_enter();
HAL_GPIO_IRQHandler(GPIO1, GPIO_BANK1);
rt_interrupt_leave();
}
#endif
#ifdef GPIO2
void pin_gpio2_handler(void)
{
rt_interrupt_enter();
HAL_GPIO_IRQHandler(GPIO2, GPIO_BANK2);
rt_interrupt_leave();
}
#endif
#ifdef GPIO3
void pin_gpio3_handler(void)
{
rt_interrupt_enter();
HAL_GPIO_IRQHandler(GPIO3, GPIO_BANK3);
rt_interrupt_leave();
}
#endif
#ifdef GPIO4
void pin_gpio4_handler(void)
{
rt_interrupt_enter();
HAL_GPIO_IRQHandler(GPIO4, GPIO_BANK4);
rt_interrupt_leave();
}
#endif
static const struct rt_pin_ops pin_ops =
{
pin_mode,
pin_write,
pin_read,
pin_attach_irq,
pin_detach_irq,
pin_irq_enable,
};
/** @defgroup GPIO_Public_Functions Public Functions
* @{
*/
int rt_hw_gpio_init(void)
{
#ifdef GPIO0
rt_hw_interrupt_install(GPIO0_IRQn, (void *)pin_gpio0_handler, RT_NULL, RT_NULL);
rt_hw_interrupt_umask(GPIO0_IRQn);
#endif
#ifdef GPIO1
rt_hw_interrupt_install(GPIO1_IRQn, (void *)pin_gpio1_handler, RT_NULL, RT_NULL);
rt_hw_interrupt_umask(GPIO1_IRQn);
#endif
#ifdef GPIO2
rt_hw_interrupt_install(GPIO2_IRQn, (void *)pin_gpio2_handler, RT_NULL, RT_NULL);
rt_hw_interrupt_umask(GPIO2_IRQn);
#endif
#ifdef GPIO3
rt_hw_interrupt_install(GPIO3_IRQn, (void *)pin_gpio3_handler, RT_NULL, RT_NULL);
rt_hw_interrupt_umask(GPIO3_IRQn);
#endif
#ifdef GPIO4
rt_hw_interrupt_install(GPIO4_IRQn, (void *)pin_gpio4_handler, RT_NULL, RT_NULL);
rt_hw_interrupt_umask(GPIO4_IRQn);
#endif
rt_device_pin_register("pin", &pin_ops, RT_NULL);
return 0;
}
INIT_BOARD_EXPORT(rt_hw_gpio_init);
/** @} */
static void pin_irq_hdr(uint32_t pin)
{
RT_ASSERT(pin >= 0);
RT_ASSERT(pin < HAL_ARRAY_SIZE(pin_irq_hdr_tab));
RT_ASSERT(pin_irq_hdr_tab[pin].hdr != RT_NULL);
pin_irq_hdr_tab[pin].hdr(pin_irq_hdr_tab[pin].args);
}
void HAL_GPIO_IRQDispatch(eGPIO_bankId bank, uint32_t pin)
{
RT_ASSERT(bank < GPIO_BANK_NUM);
pin_irq_hdr(BANK_PIN(bank, pin));
}
#endif
/** @} */
/** @} */
+15
View File
@@ -0,0 +1,15 @@
/**
* Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2019-05-15 Jay first implementation.
* 2019-05-31 Jay optimize driver.
*/
#ifndef __DRV_GPIO_H__
#define __DRV_GPIO_H__
#endif /* __DRV_GPIO_H__ */
+318
View File
@@ -0,0 +1,318 @@
/**
* Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd
*
* SPDX-License-Identifier: Apache-2.0
******************************************************************************
* @file drv_heap.c
* @version V0.2
* @brief heap interface
*
* Change Logs:
* Date Author Notes
* 2019-03-26 Cliff.Chen first implementation
* 2019-05-15 Cliff.Chen Add large heap
*
******************************************************************************
*/
#include <rtthread.h>
#include "drv_heap.h"
#ifdef RT_USING_UNCACHE_HEAP
static struct rt_memheap _uncache_heap;
rt_err_t rt_uncache_heap_init(void *begin_addr, void *end_addr)
{
/* initialize a default heap in the system */
return rt_memheap_init(&_uncache_heap,
"ucheap",
begin_addr,
(rt_uint32_t)end_addr - (rt_uint32_t)begin_addr);
}
void *rt_malloc_uncache(rt_size_t size)
{
return rt_memheap_alloc(&_uncache_heap, size);
}
void rt_free_uncache(void *ptr)
{
rt_memheap_free(ptr);
}
#endif
#ifdef RT_USING_LARGE_HEAP
#include "hal_base.h"
static struct rt_memheap _large_heap;
rt_err_t rt_large_heap_init(void *begin_addr, void *end_addr)
{
/* initialize a default heap in the system */
return rt_memheap_init(&_large_heap,
"large",
begin_addr,
(rt_uint32_t)end_addr - (rt_uint32_t)begin_addr);
}
void *rt_malloc_large(rt_size_t size)
{
if (size < RT_LARGE_MALLOC_THRRESH)
return NULL;
return rt_memheap_alloc(&_large_heap, size);
}
RTM_EXPORT(rt_malloc_large);
void rt_free_large(void *ptr)
{
rt_memheap_free(ptr);
}
RTM_EXPORT(rt_free_large);
void *rt_dma_malloc_large(rt_size_t size)
{
void *align_ptr;
void *ptr;
rt_size_t align, align_size;
if (size < RT_LARGE_MALLOC_THRRESH)
return NULL;
align = 4;
align_size = 0;
#ifdef CACHE_LINE_SIZE
align = CACHE_LINE_SIZE;
#endif
#ifdef DMA_ALIGN_SIZE
align = align > DMA_ALIGN_SIZE ? align : DMA_ALIGN_SIZE;
#endif
align_size = RT_ALIGN(size, align) + align;
ptr = rt_memheap_alloc(&_large_heap, align_size);
if (ptr != RT_NULL)
{
/* the allocated memory block is aligned */
if (((rt_uint32_t)ptr & (align - 1)) == 0)
{
align_ptr = (void *)((rt_uint32_t)ptr + align);
}
else
{
align_ptr = (void *)(((rt_uint32_t)ptr + (align - 1)) & ~(align - 1));
}
/* set the pointer before alignment pointer to the real pointer */
*((rt_uint32_t *)((rt_uint32_t)align_ptr - sizeof(void *))) = (rt_uint32_t)ptr;
ptr = align_ptr;
}
return ptr;
}
RTM_EXPORT(rt_dma_malloc_large);
void rt_dma_free_large(void *ptr)
{
void *real_ptr;
real_ptr = (void *) * (rt_uint32_t *)((rt_uint32_t)ptr - sizeof(void *));
rt_memheap_free(real_ptr);
}
RTM_EXPORT(rt_dma_free_large);
#endif
#ifdef RT_USING_DTCM_HEAP
#include "hal_base.h"
static struct rt_memheap _dtcm_heap;
extern int __dtcm_start__, __dtcm_end__;
#define RK_DTCM_BEGIN (&__dtcm_start__)
#define RK_DTCM_END (&__dtcm_end__)
int rt_dtcm_heap_init(void)
{
rt_err_t ret;
rt_device_t dsp;
dsp = rt_device_find("dsp0");
RT_ASSERT(dsp != RT_NULL);
ret = rt_device_open(dsp, RT_DEVICE_FLAG_RDWR);
RT_ASSERT(ret == RT_EOK);
return rt_memheap_init(&_dtcm_heap,
"dtcmheap",
RK_DTCM_BEGIN,
(rt_uint32_t)RK_DTCM_END - (rt_uint32_t)RK_DTCM_BEGIN);
return RT_EOK;
}
INIT_COMPONENT_EXPORT(rt_dtcm_heap_init);
void *rt_malloc_dtcm(rt_size_t size)
{
//rt_kprintf("rt_malloc_dtcm: size = %d\n", size);
if (size < RT_DTCM_MALLOC_THRRESH)
return NULL;
return rt_memheap_alloc(&_dtcm_heap, size);
}
RTM_EXPORT(rt_malloc_dtcm);
void rt_free_dtcm(void *ptr)
{
rt_memheap_free(ptr);
}
RTM_EXPORT(rt_free_dtcm);
void *rt_dma_malloc_dtcm(rt_size_t size)
{
void *align_ptr;
void *ptr;
rt_size_t align, align_size;
//rt_kprintf("rt_dma_malloc_dtcm: size = %d\n", size);
if (size < RT_DTCM_MALLOC_THRRESH)
return NULL;
align = 4;
align_size = 0;
#ifdef CACHE_LINE_SIZE
align = CACHE_LINE_SIZE;
#endif
#ifdef DMA_ALIGN_SIZE
align = align > DMA_ALIGN_SIZE ? align : DMA_ALIGN_SIZE;
#endif
align_size = RT_ALIGN(size, align) + align;
ptr = rt_memheap_alloc(&_dtcm_heap, align_size);
if (ptr != RT_NULL)
{
/* the allocated memory block is aligned */
if (((rt_uint32_t)ptr & (align - 1)) == 0)
{
align_ptr = (void *)((rt_uint32_t)ptr + align);
}
else
{
align_ptr = (void *)(((rt_uint32_t)ptr + (align - 1)) & ~(align - 1));
}
/* set the pointer before alignment pointer to the real pointer */
*((rt_uint32_t *)((rt_uint32_t)align_ptr - sizeof(void *))) = (rt_uint32_t)ptr;
ptr = align_ptr;
}
return ptr;
}
RTM_EXPORT(rt_dma_malloc_dtcm);
void rt_dma_free_dtcm(void *ptr)
{
void *real_ptr;
real_ptr = (void *) * (rt_uint32_t *)((rt_uint32_t)ptr - sizeof(void *));
rt_memheap_free(real_ptr);
}
RTM_EXPORT(rt_dma_free_dtcm);
#endif
#ifdef RT_USING_PSRAM_HEAP
#include "hal_base.h"
static struct rt_memheap _psram_heap;
extern int __psramheap_start__, __psramheap_end__;
#define RK_PSRAMHEAP_BEGIN (&__psramheap_start__)
#define RK_PSRAMHEAP_END (&__psramheap_end__)
int rt_psram_heap_init(void)
{
return rt_memheap_init(&_psram_heap,
"psramheap",
RK_PSRAMHEAP_BEGIN,
(rt_uint32_t)RK_PSRAMHEAP_END - (rt_uint32_t)RK_PSRAMHEAP_BEGIN);
}
INIT_COMPONENT_EXPORT(rt_psram_heap_init);
void *rt_malloc_psram(rt_size_t size)
{
//rt_kprintf("rt_malloc_dtcm: size = %d\n", size);
if (size < RT_PSRAM_MALLOC_THRRESH)
return NULL;
return rt_memheap_alloc(&_psram_heap, size);
}
RTM_EXPORT(rt_malloc_psram);
void rt_free_psram(void *ptr)
{
rt_memheap_free(ptr);
}
RTM_EXPORT(rt_free_psram);
void *rt_dma_malloc_psram(rt_size_t size)
{
void *align_ptr;
void *ptr;
rt_size_t align, align_size;
//rt_kprintf("rt_dma_malloc_dtcm: size = %d\n", size);
if (size < RT_PSRAM_MALLOC_THRRESH)
return NULL;
align = 4;
align_size = 0;
#ifdef CACHE_LINE_SIZE
align = CACHE_LINE_SIZE;
#endif
#ifdef DMA_ALIGN_SIZE
align = align > DMA_ALIGN_SIZE ? align : DMA_ALIGN_SIZE;
#endif
align_size = RT_ALIGN(size, align) + align;
ptr = rt_memheap_alloc(&_psram_heap, align_size);
if (ptr != RT_NULL)
{
/* the allocated memory block is aligned */
if (((rt_uint32_t)ptr & (align - 1)) == 0)
{
align_ptr = (void *)((rt_uint32_t)ptr + align);
}
else
{
align_ptr = (void *)(((rt_uint32_t)ptr + (align - 1)) & ~(align - 1));
}
/* set the pointer before alignment pointer to the real pointer */
*((rt_uint32_t *)((rt_uint32_t)align_ptr - sizeof(void *))) = (rt_uint32_t)ptr;
ptr = align_ptr;
}
return ptr;
}
RTM_EXPORT(rt_dma_malloc_psram);
void rt_dma_free_psram(void *ptr)
{
void *real_ptr;
real_ptr = (void *) * (rt_uint32_t *)((rt_uint32_t)ptr - sizeof(void *));
rt_memheap_free(real_ptr);
}
RTM_EXPORT(rt_dma_free_psram);
#endif
+47
View File
@@ -0,0 +1,47 @@
/**
* Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd
*
* SPDX-License-Identifier: Apache-2.0
******************************************************************************
* @file drv_heap.h
* @version V0.1
* @brief heap interface
*
* Change Logs:
* Date Author Notes
* 2019-03-26 Cliff.Chen first implementation
*
******************************************************************************
*/
#ifndef __DRV_HEAP_H
#define __DRV_HEAP_H
#ifdef RT_USING_UNCACHE_HEAP
rt_err_t rt_uncache_heap_init(void *begin_addr, void *end_addr);
void *rt_malloc_uncache(rt_size_t size);
void rt_free_uncache(void *ptr);
#endif
#ifdef RT_USING_LARGE_HEAP
rt_err_t rt_large_heap_init(void *begin_addr, void *end_addr);
void *rt_malloc_large(rt_size_t size);
void rt_free_large(void *ptr);
void *rt_dma_malloc_large(rt_size_t size);
void rt_dma_free_large(void *ptr);
#endif
#ifdef RT_USING_DTCM_HEAP
void *rt_malloc_dtcm(rt_size_t size);
void rt_free_dtcm(void *ptr);
void *rt_dma_malloc_dtcm(rt_size_t size);
void rt_dma_free_dtcm(void *ptr);
#endif
#ifdef RT_USING_PSRAM_HEAP
void *rt_malloc_psram(rt_size_t size);
void rt_free_psram(void *ptr);
void *rt_dma_malloc_psram(rt_size_t size);
void rt_dma_free_psram(void *ptr);
#endif
#endif
File diff suppressed because it is too large Load Diff
+99
View File
@@ -0,0 +1,99 @@
/**
* Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd
*
* SPDX-License-Identifier: Apache-2.0
******************************************************************************
* @file drv_uart.h
* @author Huibin Hong
* @version V0.5
* @date 10-Dec-2018
* @brief serial driver
*
******************************************************************************
*/
#ifndef __ARCH_ARM_SRC_ROCKCHIP_RK_SERIAL_H
#define __ARCH_ARM_SRC_ROCKCHIP_RK_SERIAL_H
/*******************************************************************************
* Included Files
******************************************************************************/
#include "hal_def.h"
/*******************************************************************************
* Pre-processor Definitions
******************************************************************************/
#define ROCKCHIP_UART_SUPPORT_FLAG_DEFAULT \
RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_INT_TX
#define ROCKCHIP_UART_BAUD_RATE_DEFAULT UART_BR_115200
/*******************************************************************************
* Public Types
******************************************************************************/
/* uart_board includes information on a board */
struct uart_board
{
rt_uint32_t baud_rate; /* for example 115200 */
rt_uint32_t dev_flag; /* for example RT_DEVICE_FLAG_INT_RX */
rt_uint32_t bufer_size; /* uart buffer size */
rt_bool_t en_irq_wake; /* enable uart irq wake up */
char name[8]; /* device name: /dev/xxxx */
};
/*******************************************************************************
* Public Data
******************************************************************************/
#if defined(RT_USING_UART0)
extern const struct uart_board g_uart0_board;
#endif /* RT_USING_UART0 */
#if defined(RT_USING_UART1)
extern const struct uart_board g_uart1_board;
#endif /* RT_USING_UART1 */
#if defined(RT_USING_UART2)
extern const struct uart_board g_uart2_board;
#endif /* RT_USING_UART2 */
#if defined(RT_USING_UART3)
extern const struct uart_board g_uart3_board;
#endif /* RT_USING_UART3 */
#if defined(RT_USING_UART4)
extern const struct uart_board g_uart4_board;
#endif /* RT_USING_UART4 */
#if defined(RT_USING_UART5)
extern const struct uart_board g_uart5_board;
#endif /* RT_USING_UART5 */
#if defined(RT_USING_UART6)
extern const struct uart_board g_uart6_board;
#endif /* RT_USING_UART6 */
#if defined(RT_USING_UART7)
extern const struct uart_board g_uart7_board;
#endif /* RT_USING_UART7 */
#if defined(RT_USING_UART8)
extern const struct uart_board g_uart8_board;
#endif /* RT_USING_UART8 */
#if defined(RT_USING_UART9)
extern const struct uart_board g_uart9_board;
#endif /* RT_USING_UART9 */
/*******************************************************************************
* Inline Functions
******************************************************************************/
/*******************************************************************************
* Public Functions
******************************************************************************/
void rt_hw_usart_init(void);
int rt_hw_console_channel(void);
#endif /* __ARCH_ARM_SRC_ROCKCHIP_RK_SERIAL_H */
+259
View File
@@ -0,0 +1,259 @@
/**
* Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd
*
* SPDX-License-Identifier: Apache-2.0
******************************************************************************
* @file interrupt.c
* @version V0.1
* @brief interrupt interface for rt-thread
*
* Change Logs:
* Date Author Notes
* 2019-05-08 Cliff.Chen first implementation
*
******************************************************************************
*/
#include <rthw.h>
#include "hal_base.h"
#if defined(ARCH_ARM_CORTEX_M0) || defined(ARCH_ARM_CORTEX_M3) || defined(ARCH_ARM_CORTEX_M4) || defined(ARCH_ARM_CORTEX_M7)
#if EXT_INTERRUPT
struct rk_intc
{
void *intc_base;
rt_isr_handler_t irq_handler;
};
static rt_isr_handler_t ext_vector[NUM_EXT_INTERRUPTS];
static void intc_irq_dispatch(void *intc, uint32_t offset)
{
uint32_t i, irq_no;
for (i = 0; i < NUM_EXT_INTERRUPTS; i++)
{
if (HAL_INTC_GetFinalStatus(intc, i))
{
irq_no = i + offset * NUM_INT_PER_CONTROLLER;
ext_vector[irq_no](NUM_INTERRUPTS + irq_no, NULL);
}
}
}
#define DEFINE_RK_INTC_IRQ(ID) \
static void rk_intc##ID##_irq_dispatch(int irq, void *param); \
static struct rk_intc rk_intc##ID = \
{ \
.intc_base = INTC##ID, \
.irq_handler = rk_intc##ID##_irq_dispatch, \
}; \
static void rk_intc##ID##_irq_dispatch(int irq, void *param) \
{ \
intc_irq_dispatch(INTC##ID, ID); \
}
#ifdef INTC0
DEFINE_RK_INTC_IRQ(0);
#endif
#ifdef INTC1
DEFINE_RK_INTC_IRQ(1);
#endif
#ifdef INTC2
DEFINE_RK_INTC_IRQ(2);
#endif
#ifdef INTC3
DEFINE_RK_INTC_IRQ(3);
#endif
static struct rk_intc *rk_intc_table[] =
{
#ifdef INTC0
&rk_intc0,
#endif
#ifdef INTC1
&rk_intc1,
#endif
#ifdef INTC2
&rk_intc2,
#endif
#ifdef INTC3
&rk_intc3,
#endif
};
static void rk_intc_init(void)
{
uint32_t i;
memset(ext_vector, 0, sizeof(ext_vector));
for (i = 0; i < HAL_ARRAY_SIZE(rk_intc_table); i++)
{
HAL_NVIC_SetIRQHandler(INTC0_IRQn + i, (NVIC_IRQHandler)rk_intc_table[i]->irq_handler);
HAL_NVIC_EnableIRQ(INTC0_IRQn + i);
HAL_INTC_EnableAllRQ(rk_intc_table[i]->intc_base);
}
}
static void rk_intc_mask(uint32_t vector)
{
uint32_t intc, irq;
if (vector >= TOTAL_INTERRUPTS)
return;
if (vector < NUM_INTERRUPTS)
HAL_NVIC_DisableIRQ(vector);
else
{
intc = (vector - NUM_INTERRUPTS) / NUM_INT_PER_CONTROLLER;
irq = (vector - NUM_INTERRUPTS) % NUM_INT_PER_CONTROLLER;
if (intc >= HAL_ARRAY_SIZE(rk_intc_table))
return;
HAL_INTC_MaskIRQ(rk_intc_table[intc]->intc_base, irq);
}
}
static void rk_intc_unmask(uint32_t vector)
{
uint32_t intc, irq;
if (vector >= TOTAL_INTERRUPTS)
return;
if (vector < NUM_INTERRUPTS)
HAL_NVIC_EnableIRQ(vector);
else
{
intc = (vector - NUM_INTERRUPTS) / NUM_INT_PER_CONTROLLER;
irq = (vector - NUM_INTERRUPTS) % NUM_INT_PER_CONTROLLER;
if (intc >= HAL_ARRAY_SIZE(rk_intc_table))
return;
HAL_INTC_UnmaskIRQ(rk_intc_table[intc]->intc_base, irq);
}
}
#endif /* end of EXT_INTERRUPT */
#ifdef RT_USING_PROF_IRQ
#define IRQ_AVG_COUNT 200
struct irq_summry
{
uint32_t count;
uint32_t start;
uint32_t time_total;
uint32_t time_avg;
uint32_t time_max;
};
static struct irq_summry g_irq_prof[TOTAL_INTERRUPTS];
static void irq_enter_hook(void)
{
uint32_t irq;
irq = __get_IPSR() - 16;
g_irq_prof[irq].count++;
g_irq_prof[irq].start = HAL_TIMER_GetCount(SYS_TIMER);
}
static void irq_leave_hook(void)
{
uint32_t time_cur, end, irq;
irq = __get_IPSR() - 16;
end = HAL_TIMER_GetCount(SYS_TIMER);
if (end < g_irq_prof[irq].start)
end += PLL_INPUT_OSC_RATE;
time_cur = end - g_irq_prof[irq].start;
g_irq_prof[irq].time_total += time_cur;
g_irq_prof[irq].time_max =
g_irq_prof[irq].time_max > time_cur ? g_irq_prof[irq].time_max : time_cur;
if (g_irq_prof[irq].count > 0 &&
g_irq_prof[irq].count % IRQ_AVG_COUNT == 0)
{
g_irq_prof[irq].time_avg = g_irq_prof[irq].time_total / IRQ_AVG_COUNT;
g_irq_prof[irq].time_total = 0;
}
}
static void dump_irq_summry(int argc, char **argv)
{
uint32_t i;
rt_kprintf("IRQ COUNT AVG MAX\n");
for (i = 0; i < NUM_INTERRUPTS; i++)
{
rt_kprintf("%03d %08d %08d %08d\n", i, g_irq_prof[i].count,
g_irq_prof[i].time_avg,
g_irq_prof[i].time_max);
}
}
#ifdef RT_USING_FINSH
#include <finsh.h>
MSH_CMD_EXPORT(dump_irq_summry, dump irq summry);
#endif
#endif /* end of RT_USING_PROF_IRQ */
void rt_hw_interrupt_init(void)
{
uint32_t i;
for (i = 0; i < NUM_INTERRUPTS; i++)
{
HAL_NVIC_SetPriority(i, NVIC_PERIPH_PRIO_DEFAULT, NVIC_PERIPH_SUB_PRIO_DEFAULT);
}
#if EXT_INTERRUPT
rk_intc_init();
#endif
#ifdef RT_USING_PROF_IRQ
rt_interrupt_enter_sethook(irq_enter_hook);
rt_interrupt_leave_sethook(irq_leave_hook);
#endif
}
void rt_hw_interrupt_mask(int vector)
{
#if EXT_INTERRUPT
rk_intc_mask(vector);
#else
HAL_NVIC_DisableIRQ(vector);
#endif
}
void rt_hw_interrupt_umask(int vector)
{
#if EXT_INTERRUPT
rk_intc_unmask(vector);
#else
HAL_NVIC_EnableIRQ(vector);
#endif
}
rt_isr_handler_t rt_hw_interrupt_install(int vector,
rt_isr_handler_t handler,
void *param,
const char *name)
{
#if EXT_INTERRUPT
if (vector < NUM_INTERRUPTS)
HAL_NVIC_SetIRQHandler(vector, (NVIC_IRQHandler)handler);
else
ext_vector[vector - NUM_INTERRUPTS] = handler;
#else
HAL_NVIC_SetIRQHandler(vector, (NVIC_IRQHandler)handler);
#endif
return handler;
}
#endif /* end of defined(ARCH_ARM_CORTEX_M0) || defined(ARCH_ARM_CORTEX_M3) || defined(ARCH_ARM_CORTEX_M4) || defined(ARCH_ARM_CORTEX_M7) */
+248
View File
@@ -0,0 +1,248 @@
/**
* Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd
*
* SPDX-License-Identifier: Apache-2.0
******************************************************************************
* @file io.c
* @author
* @version V0.1
* @date 10-Jun-2019
* @brief read and write memory
*
******************************************************************************
*/
#include <rtthread.h>
#ifdef RT_DEBUG_USING_IO
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include "hal_base.h"
static void usage(void)
{
rt_kprintf("Raw memory i/o utility - $Revision: 1.5 $\n\n");
rt_kprintf("io -v -1|2|4 -r|w [-l <len>] <addr> [<value>]\n\n");
rt_kprintf(" -v Verbose, asks for confirmation\n");
rt_kprintf(" -1|2|4 Sets memory access size in bytes (default byte)\n");
rt_kprintf(" -l <len> Length in bytes of area to access (defaults to\n");
rt_kprintf(" one access, or whole file length)\n");
rt_kprintf(" -r|w Read from or Write to memory (default read)\n");
rt_kprintf(" <addr> The memory address to access\n");
rt_kprintf(" <val> The value to write (implies -w)\n\n");
rt_kprintf("Examples:\n");
rt_kprintf(" io 0x1000 Reads one byte from 0x1000\n");
rt_kprintf(" io 0x1000 0x12 Writes 0x12 to location 0x1000\n");
rt_kprintf(" io -2 -l 8 0x1000 Reads 8 words from 0x1000\n\n");
rt_kprintf("Note access size (-1|2|4) does not apply to file based accesses.\n\n");
}
static void
read_memory(unsigned long phys_addr, uint8_t *addr, int len, int iosize)
{
int i;
while (len)
{
rt_kprintf("%08lx: ", phys_addr);
i = 0;
while (i < 16 && len)
{
switch (iosize)
{
case 1:
rt_kprintf(" %02x", *(uint8_t *)addr);
break;
case 2:
rt_kprintf(" %04x", *(uint16_t *)addr);
break;
case 4:
rt_kprintf(" %08lx", *(uint32_t *)addr);
break;
}
i += iosize;
addr += iosize;
len -= iosize;
}
phys_addr += 16;
rt_kprintf("\n");
}
}
static void
write_memory(uint8_t *addr, int len, int iosize, unsigned long value)
{
switch (iosize)
{
case 1:
while (len)
{
*(uint8_t *)addr = value;
len -= iosize;
addr += iosize;
}
break;
case 2:
while (len)
{
*(uint16_t *)addr = value;
len -= iosize;
addr += iosize;
}
break;
case 4:
while (len)
{
*(uint32_t *)addr = value;
len -= iosize;
addr += iosize;
}
break;
}
}
int io_mem(int argc, char **argv)
{
int req_len = 0, opt;
uint8_t *real_io;
unsigned long req_addr, req_value = 0;
char *endptr;
int memread = 1;
int iosize = 1;
int verbose = 0;
opterr = 0;
optind = 0;
if (argc == 1)
{
usage();
return 0;
}
while ((opt = getopt(argc, argv, "hv124rwl:f:")) > 0)
{
switch (opt)
{
case 'h':
usage();
case 'v':
verbose = 1;
break;
case '1':
case '2':
case '4':
iosize = opt - '0';
break;
case 'r':
memread = 1;
break;
case 'w':
memread = 0;
break;
case 'l':
req_len = strtoul(optarg, &endptr, 0);
if (*endptr)
{
rt_kprintf("Bad <size> value '%s'\n", optarg);
return 0;
}
break;
default:
rt_kprintf("Unknown option: %c\n", opt);
usage();
}
}
if (optind == argc)
{
rt_kprintf("No address given\n");
return 0;
}
req_addr = strtoul(argv[optind], &endptr, 0);
if (*endptr)
{
rt_kprintf("Bad <addr> value '%s'\n", argv[optind]);
return 0;
}
optind++;
if (optind < argc)
memread = 0;
if (!memread && optind == argc)
{
rt_kprintf("No value given for WRITE\n");
return 0;
}
if (!memread)
{
req_value = strtoul(argv[optind], &endptr, 0);
if (*endptr)
{
rt_kprintf("Bad <value> value '%s'\n", argv[optind]);
return 0;
}
if ((iosize == 1 && (req_value & 0xffffff00)) ||
(iosize == 2 && (req_value & 0xffff0000)))
{
rt_kprintf("<value> too large\n");
return 0;
}
optind++;
}
if (optind < argc)
{
rt_kprintf("Too many arguments '%s'...\n", argv[optind]);
return 0;
}
if (!req_len)
req_len = iosize;
if ((iosize == 2 && (req_addr & 1)) ||
(iosize == 4 && (req_addr & 3)))
{
rt_kprintf("Badly aligned <addr> for access size\n");
return 0;
}
if ((iosize == 2 && (req_len & 1)) ||
(iosize == 4 && (req_len & 3)))
{
rt_kprintf("Badly aligned <size> for access size\n");
return 0;
}
if (!verbose)
/* Nothing */;
else if (memread)
rt_kprintf("Request to memread 0x%x bytes from address 0x%08lx\n"
"\tusing %d byte accesses\n",
req_len, req_addr, iosize);
else
rt_kprintf("Request to write 0x%x bytes to address 0x%08lx\n"
"\tusing %d byte accesses of value 0x%0*lx\n",
req_len, req_addr, iosize, iosize * 2, req_value);
real_io = (uint8_t *)req_addr;
if (memread)
read_memory(req_addr, real_io, req_len, iosize);
else
write_memory(real_io, req_len, iosize, req_value);
return 0;
}
#ifdef RT_USING_FINSH
#include <finsh.h>
MSH_CMD_EXPORT_ALIAS(io_mem, io, memory read or write cmd);
#endif
#endif /* RT_DEBUG_USING_IO */
+42
View File
@@ -0,0 +1,42 @@
/*
* Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2019-08-30 Tao Huang The first version
*/
#include <rthw.h>
#include <rtthread.h>
#include "hal_base.h"
#include "hal_bsp.h"
#ifdef RT_USING_RESET
void rt_hw_cpu_reset(void)
{
#ifdef RT_USING_SND_GLB_RST
HAL_CRU_SetGlbSrst(GLB_SRST_SND);
#else
HAL_CRU_SetGlbSrst(GLB_SRST_FST);
#endif
while (1);
}
#ifdef RT_USING_FINSH
#include <finsh.h>
static void reboot(uint8_t argc, char **argv)
{
if (argc >= 2 && !strncmp(argv[1], "loader", 6))
{
BSP_SetLoaderFlag();
}
rt_hw_cpu_reset();
}
MSH_CMD_EXPORT(reboot, Reboot System);
#endif /* RT_USING_FINSH */
#endif /* RT_USING_RESET */
+2
View File
@@ -0,0 +1,2 @@
Last commit: a5b7b9a7b3d5617b3c03dd2d3e0fceebbeb8b0b1
Last commit date: Tue Dec 7 11:35:11 2021 +0800 by Steven Liu
+27
View File
@@ -0,0 +1,27 @@
Copyright (c) 2020 Rockchip Electronics Co., Ltd.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 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.
@@ -0,0 +1,411 @@
/******************************************************************************
* @file cachel1_armv7.h
* @brief CMSIS Level 1 Cache API for Armv7-M and later
* @version V1.0.1
* @date 19. April 2021
******************************************************************************/
/*
* Copyright (c) 2020-2021 Arm Limited. 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
*
* 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 defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#elif defined (__clang__)
#pragma clang system_header /* treat file as system include file */
#endif
#ifndef ARM_CACHEL1_ARMV7_H
#define ARM_CACHEL1_ARMV7_H
/**
\ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_CacheFunctions Cache Functions
\brief Functions that configure Instruction and Data cache.
@{
*/
/* Cache Size ID Register Macros */
#define CCSIDR_WAYS(x) (((x) & SCB_CCSIDR_ASSOCIATIVITY_Msk) >> SCB_CCSIDR_ASSOCIATIVITY_Pos)
#define CCSIDR_SETS(x) (((x) & SCB_CCSIDR_NUMSETS_Msk ) >> SCB_CCSIDR_NUMSETS_Pos )
#ifndef __SCB_DCACHE_LINE_SIZE
#define __SCB_DCACHE_LINE_SIZE 32U /*!< Cortex-M7 cache line size is fixed to 32 bytes (8 words). See also register SCB_CCSIDR */
#endif
#ifndef __SCB_ICACHE_LINE_SIZE
#define __SCB_ICACHE_LINE_SIZE 32U /*!< Cortex-M7 cache line size is fixed to 32 bytes (8 words). See also register SCB_CCSIDR */
#endif
/**
\brief Enable I-Cache
\details Turns on I-Cache
*/
__STATIC_FORCEINLINE void SCB_EnableICache (void)
{
#if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U)
if (SCB->CCR & SCB_CCR_IC_Msk) return; /* return if ICache is already enabled */
__DSB();
__ISB();
SCB->ICIALLU = 0UL; /* invalidate I-Cache */
__DSB();
__ISB();
SCB->CCR |= (uint32_t)SCB_CCR_IC_Msk; /* enable I-Cache */
__DSB();
__ISB();
#endif
}
/**
\brief Disable I-Cache
\details Turns off I-Cache
*/
__STATIC_FORCEINLINE void SCB_DisableICache (void)
{
#if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U)
__DSB();
__ISB();
SCB->CCR &= ~(uint32_t)SCB_CCR_IC_Msk; /* disable I-Cache */
SCB->ICIALLU = 0UL; /* invalidate I-Cache */
__DSB();
__ISB();
#endif
}
/**
\brief Invalidate I-Cache
\details Invalidates I-Cache
*/
__STATIC_FORCEINLINE void SCB_InvalidateICache (void)
{
#if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U)
__DSB();
__ISB();
SCB->ICIALLU = 0UL;
__DSB();
__ISB();
#endif
}
/**
\brief I-Cache Invalidate by address
\details Invalidates I-Cache for the given address.
I-Cache is invalidated starting from a 32 byte aligned address in 32 byte granularity.
I-Cache memory blocks which are part of given address + given size are invalidated.
\param[in] addr address
\param[in] isize size of memory block (in number of bytes)
*/
__STATIC_FORCEINLINE void SCB_InvalidateICache_by_Addr (volatile void *addr, int32_t isize)
{
#if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U)
if ( isize > 0 ) {
int32_t op_size = isize + (((uint32_t)addr) & (__SCB_ICACHE_LINE_SIZE - 1U));
uint32_t op_addr = (uint32_t)addr /* & ~(__SCB_ICACHE_LINE_SIZE - 1U) */;
__DSB();
do {
SCB->ICIMVAU = op_addr; /* register accepts only 32byte aligned values, only bits 31..5 are valid */
op_addr += __SCB_ICACHE_LINE_SIZE;
op_size -= __SCB_ICACHE_LINE_SIZE;
} while ( op_size > 0 );
__DSB();
__ISB();
}
#endif
}
/**
\brief Enable D-Cache
\details Turns on D-Cache
*/
__STATIC_FORCEINLINE void SCB_EnableDCache (void)
{
#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
uint32_t ccsidr;
uint32_t sets;
uint32_t ways;
if (SCB->CCR & SCB_CCR_DC_Msk) return; /* return if DCache is already enabled */
SCB->CSSELR = 0U; /* select Level 1 data cache */
__DSB();
ccsidr = SCB->CCSIDR;
/* invalidate D-Cache */
sets = (uint32_t)(CCSIDR_SETS(ccsidr));
do {
ways = (uint32_t)(CCSIDR_WAYS(ccsidr));
do {
SCB->DCISW = (((sets << SCB_DCISW_SET_Pos) & SCB_DCISW_SET_Msk) |
((ways << SCB_DCISW_WAY_Pos) & SCB_DCISW_WAY_Msk) );
#if defined ( __CC_ARM )
__schedule_barrier();
#endif
} while (ways-- != 0U);
} while(sets-- != 0U);
__DSB();
SCB->CCR |= (uint32_t)SCB_CCR_DC_Msk; /* enable D-Cache */
__DSB();
__ISB();
#endif
}
/**
\brief Disable D-Cache
\details Turns off D-Cache
*/
__STATIC_FORCEINLINE void SCB_DisableDCache (void)
{
#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
uint32_t ccsidr;
uint32_t sets;
uint32_t ways;
SCB->CSSELR = 0U; /* select Level 1 data cache */
__DSB();
SCB->CCR &= ~(uint32_t)SCB_CCR_DC_Msk; /* disable D-Cache */
__DSB();
ccsidr = SCB->CCSIDR;
/* clean & invalidate D-Cache */
sets = (uint32_t)(CCSIDR_SETS(ccsidr));
do {
ways = (uint32_t)(CCSIDR_WAYS(ccsidr));
do {
SCB->DCCISW = (((sets << SCB_DCCISW_SET_Pos) & SCB_DCCISW_SET_Msk) |
((ways << SCB_DCCISW_WAY_Pos) & SCB_DCCISW_WAY_Msk) );
#if defined ( __CC_ARM )
__schedule_barrier();
#endif
} while (ways-- != 0U);
} while(sets-- != 0U);
__DSB();
__ISB();
#endif
}
/**
\brief Invalidate D-Cache
\details Invalidates D-Cache
*/
__STATIC_FORCEINLINE void SCB_InvalidateDCache (void)
{
#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
uint32_t ccsidr;
uint32_t sets;
uint32_t ways;
SCB->CSSELR = 0U; /* select Level 1 data cache */
__DSB();
ccsidr = SCB->CCSIDR;
/* invalidate D-Cache */
sets = (uint32_t)(CCSIDR_SETS(ccsidr));
do {
ways = (uint32_t)(CCSIDR_WAYS(ccsidr));
do {
SCB->DCISW = (((sets << SCB_DCISW_SET_Pos) & SCB_DCISW_SET_Msk) |
((ways << SCB_DCISW_WAY_Pos) & SCB_DCISW_WAY_Msk) );
#if defined ( __CC_ARM )
__schedule_barrier();
#endif
} while (ways-- != 0U);
} while(sets-- != 0U);
__DSB();
__ISB();
#endif
}
/**
\brief Clean D-Cache
\details Cleans D-Cache
*/
__STATIC_FORCEINLINE void SCB_CleanDCache (void)
{
#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
uint32_t ccsidr;
uint32_t sets;
uint32_t ways;
SCB->CSSELR = 0U; /* select Level 1 data cache */
__DSB();
ccsidr = SCB->CCSIDR;
/* clean D-Cache */
sets = (uint32_t)(CCSIDR_SETS(ccsidr));
do {
ways = (uint32_t)(CCSIDR_WAYS(ccsidr));
do {
SCB->DCCSW = (((sets << SCB_DCCSW_SET_Pos) & SCB_DCCSW_SET_Msk) |
((ways << SCB_DCCSW_WAY_Pos) & SCB_DCCSW_WAY_Msk) );
#if defined ( __CC_ARM )
__schedule_barrier();
#endif
} while (ways-- != 0U);
} while(sets-- != 0U);
__DSB();
__ISB();
#endif
}
/**
\brief Clean & Invalidate D-Cache
\details Cleans and Invalidates D-Cache
*/
__STATIC_FORCEINLINE void SCB_CleanInvalidateDCache (void)
{
#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
uint32_t ccsidr;
uint32_t sets;
uint32_t ways;
SCB->CSSELR = 0U; /* select Level 1 data cache */
__DSB();
ccsidr = SCB->CCSIDR;
/* clean & invalidate D-Cache */
sets = (uint32_t)(CCSIDR_SETS(ccsidr));
do {
ways = (uint32_t)(CCSIDR_WAYS(ccsidr));
do {
SCB->DCCISW = (((sets << SCB_DCCISW_SET_Pos) & SCB_DCCISW_SET_Msk) |
((ways << SCB_DCCISW_WAY_Pos) & SCB_DCCISW_WAY_Msk) );
#if defined ( __CC_ARM )
__schedule_barrier();
#endif
} while (ways-- != 0U);
} while(sets-- != 0U);
__DSB();
__ISB();
#endif
}
/**
\brief D-Cache Invalidate by address
\details Invalidates D-Cache for the given address.
D-Cache is invalidated starting from a 32 byte aligned address in 32 byte granularity.
D-Cache memory blocks which are part of given address + given size are invalidated.
\param[in] addr address
\param[in] dsize size of memory block (in number of bytes)
*/
__STATIC_FORCEINLINE void SCB_InvalidateDCache_by_Addr (volatile void *addr, int32_t dsize)
{
#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
if ( dsize > 0 ) {
int32_t op_size = dsize + (((uint32_t)addr) & (__SCB_DCACHE_LINE_SIZE - 1U));
uint32_t op_addr = (uint32_t)addr /* & ~(__SCB_DCACHE_LINE_SIZE - 1U) */;
__DSB();
do {
SCB->DCIMVAC = op_addr; /* register accepts only 32byte aligned values, only bits 31..5 are valid */
op_addr += __SCB_DCACHE_LINE_SIZE;
op_size -= __SCB_DCACHE_LINE_SIZE;
} while ( op_size > 0 );
__DSB();
__ISB();
}
#endif
}
/**
\brief D-Cache Clean by address
\details Cleans D-Cache for the given address
D-Cache is cleaned starting from a 32 byte aligned address in 32 byte granularity.
D-Cache memory blocks which are part of given address + given size are cleaned.
\param[in] addr address
\param[in] dsize size of memory block (in number of bytes)
*/
__STATIC_FORCEINLINE void SCB_CleanDCache_by_Addr (volatile void *addr, int32_t dsize)
{
#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
if ( dsize > 0 ) {
int32_t op_size = dsize + (((uint32_t)addr) & (__SCB_DCACHE_LINE_SIZE - 1U));
uint32_t op_addr = (uint32_t)addr /* & ~(__SCB_DCACHE_LINE_SIZE - 1U) */;
__DSB();
do {
SCB->DCCMVAC = op_addr; /* register accepts only 32byte aligned values, only bits 31..5 are valid */
op_addr += __SCB_DCACHE_LINE_SIZE;
op_size -= __SCB_DCACHE_LINE_SIZE;
} while ( op_size > 0 );
__DSB();
__ISB();
}
#endif
}
/**
\brief D-Cache Clean and Invalidate by address
\details Cleans and invalidates D_Cache for the given address
D-Cache is cleaned and invalidated starting from a 32 byte aligned address in 32 byte granularity.
D-Cache memory blocks which are part of given address + given size are cleaned and invalidated.
\param[in] addr address (aligned to 32-byte boundary)
\param[in] dsize size of memory block (in number of bytes)
*/
__STATIC_FORCEINLINE void SCB_CleanInvalidateDCache_by_Addr (volatile void *addr, int32_t dsize)
{
#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
if ( dsize > 0 ) {
int32_t op_size = dsize + (((uint32_t)addr) & (__SCB_DCACHE_LINE_SIZE - 1U));
uint32_t op_addr = (uint32_t)addr /* & ~(__SCB_DCACHE_LINE_SIZE - 1U) */;
__DSB();
do {
SCB->DCCIMVAC = op_addr; /* register accepts only 32byte aligned values, only bits 31..5 are valid */
op_addr += __SCB_DCACHE_LINE_SIZE;
op_size -= __SCB_DCACHE_LINE_SIZE;
} while ( op_size > 0 );
__DSB();
__ISB();
}
#endif
}
/*@} end of CMSIS_Core_CacheFunctions */
#endif /* ARM_CACHEL1_ARMV7_H */
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,283 @@
/**************************************************************************//**
* @file cmsis_compiler.h
* @brief CMSIS compiler generic header file
* @version V5.1.0
* @date 09. October 2018
******************************************************************************/
/*
* Copyright (c) 2009-2018 Arm Limited. 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
*
* 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 __CMSIS_COMPILER_H
#define __CMSIS_COMPILER_H
#include <stdint.h>
/*
* Arm Compiler 4/5
*/
#if defined ( __CC_ARM )
#include "cmsis_armcc.h"
/*
* Arm Compiler 6.6 LTM (armclang)
*/
#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) && (__ARMCC_VERSION < 6100100)
#include "cmsis_armclang_ltm.h"
/*
* Arm Compiler above 6.10.1 (armclang)
*/
#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6100100)
#include "cmsis_armclang.h"
/*
* GNU Compiler
*/
#elif defined ( __GNUC__ )
#include "cmsis_gcc.h"
/*
* IAR Compiler
*/
#elif defined ( __ICCARM__ )
#include <cmsis_iccarm.h>
/*
* TI Arm Compiler
*/
#elif defined ( __TI_ARM__ )
#include <cmsis_ccs.h>
#ifndef __ASM
#define __ASM __asm
#endif
#ifndef __INLINE
#define __INLINE inline
#endif
#ifndef __STATIC_INLINE
#define __STATIC_INLINE static inline
#endif
#ifndef __STATIC_FORCEINLINE
#define __STATIC_FORCEINLINE __STATIC_INLINE
#endif
#ifndef __NO_RETURN
#define __NO_RETURN __attribute__((noreturn))
#endif
#ifndef __USED
#define __USED __attribute__((used))
#endif
#ifndef __WEAK
#define __WEAK __attribute__((weak))
#endif
#ifndef __PACKED
#define __PACKED __attribute__((packed))
#endif
#ifndef __PACKED_STRUCT
#define __PACKED_STRUCT struct __attribute__((packed))
#endif
#ifndef __PACKED_UNION
#define __PACKED_UNION union __attribute__((packed))
#endif
#ifndef __UNALIGNED_UINT32 /* deprecated */
struct __attribute__((packed)) T_UINT32 { uint32_t v; };
#define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v)
#endif
#ifndef __UNALIGNED_UINT16_WRITE
__PACKED_STRUCT T_UINT16_WRITE { uint16_t v; };
#define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void*)(addr))->v) = (val))
#endif
#ifndef __UNALIGNED_UINT16_READ
__PACKED_STRUCT T_UINT16_READ { uint16_t v; };
#define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v)
#endif
#ifndef __UNALIGNED_UINT32_WRITE
__PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
#define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
#endif
#ifndef __UNALIGNED_UINT32_READ
__PACKED_STRUCT T_UINT32_READ { uint32_t v; };
#define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v)
#endif
#ifndef __ALIGNED
#define __ALIGNED(x) __attribute__((aligned(x)))
#endif
#ifndef __RESTRICT
#define __RESTRICT __restrict
#endif
#ifndef __COMPILER_BARRIER
#warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored.
#define __COMPILER_BARRIER() (void)0
#endif
/*
* TASKING Compiler
*/
#elif defined ( __TASKING__ )
/*
* The CMSIS functions have been implemented as intrinsics in the compiler.
* Please use "carm -?i" to get an up to date list of all intrinsics,
* Including the CMSIS ones.
*/
#ifndef __ASM
#define __ASM __asm
#endif
#ifndef __INLINE
#define __INLINE inline
#endif
#ifndef __STATIC_INLINE
#define __STATIC_INLINE static inline
#endif
#ifndef __STATIC_FORCEINLINE
#define __STATIC_FORCEINLINE __STATIC_INLINE
#endif
#ifndef __NO_RETURN
#define __NO_RETURN __attribute__((noreturn))
#endif
#ifndef __USED
#define __USED __attribute__((used))
#endif
#ifndef __WEAK
#define __WEAK __attribute__((weak))
#endif
#ifndef __PACKED
#define __PACKED __packed__
#endif
#ifndef __PACKED_STRUCT
#define __PACKED_STRUCT struct __packed__
#endif
#ifndef __PACKED_UNION
#define __PACKED_UNION union __packed__
#endif
#ifndef __UNALIGNED_UINT32 /* deprecated */
struct __packed__ T_UINT32 { uint32_t v; };
#define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v)
#endif
#ifndef __UNALIGNED_UINT16_WRITE
__PACKED_STRUCT T_UINT16_WRITE { uint16_t v; };
#define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val))
#endif
#ifndef __UNALIGNED_UINT16_READ
__PACKED_STRUCT T_UINT16_READ { uint16_t v; };
#define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v)
#endif
#ifndef __UNALIGNED_UINT32_WRITE
__PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
#define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
#endif
#ifndef __UNALIGNED_UINT32_READ
__PACKED_STRUCT T_UINT32_READ { uint32_t v; };
#define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v)
#endif
#ifndef __ALIGNED
#define __ALIGNED(x) __align(x)
#endif
#ifndef __RESTRICT
#warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored.
#define __RESTRICT
#endif
#ifndef __COMPILER_BARRIER
#warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored.
#define __COMPILER_BARRIER() (void)0
#endif
/*
* COSMIC Compiler
*/
#elif defined ( __CSMC__ )
#include <cmsis_csm.h>
#ifndef __ASM
#define __ASM _asm
#endif
#ifndef __INLINE
#define __INLINE inline
#endif
#ifndef __STATIC_INLINE
#define __STATIC_INLINE static inline
#endif
#ifndef __STATIC_FORCEINLINE
#define __STATIC_FORCEINLINE __STATIC_INLINE
#endif
#ifndef __NO_RETURN
// NO RETURN is automatically detected hence no warning here
#define __NO_RETURN
#endif
#ifndef __USED
#warning No compiler specific solution for __USED. __USED is ignored.
#define __USED
#endif
#ifndef __WEAK
#define __WEAK __weak
#endif
#ifndef __PACKED
#define __PACKED @packed
#endif
#ifndef __PACKED_STRUCT
#define __PACKED_STRUCT @packed struct
#endif
#ifndef __PACKED_UNION
#define __PACKED_UNION @packed union
#endif
#ifndef __UNALIGNED_UINT32 /* deprecated */
@packed struct T_UINT32 { uint32_t v; };
#define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v)
#endif
#ifndef __UNALIGNED_UINT16_WRITE
__PACKED_STRUCT T_UINT16_WRITE { uint16_t v; };
#define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val))
#endif
#ifndef __UNALIGNED_UINT16_READ
__PACKED_STRUCT T_UINT16_READ { uint16_t v; };
#define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v)
#endif
#ifndef __UNALIGNED_UINT32_WRITE
__PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
#define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
#endif
#ifndef __UNALIGNED_UINT32_READ
__PACKED_STRUCT T_UINT32_READ { uint32_t v; };
#define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v)
#endif
#ifndef __ALIGNED
#warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored.
#define __ALIGNED(x)
#endif
#ifndef __RESTRICT
#warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored.
#define __RESTRICT
#endif
#ifndef __COMPILER_BARRIER
#warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored.
#define __COMPILER_BARRIER() (void)0
#endif
#else
#error Unknown compiler.
#endif
#endif /* __CMSIS_COMPILER_H */
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,39 @@
/**************************************************************************//**
* @file cmsis_version.h
* @brief CMSIS Core(M) Version definitions
* @version V5.0.4
* @date 23. July 2019
******************************************************************************/
/*
* Copyright (c) 2009-2019 ARM Limited. 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
*
* 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 defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#elif defined (__clang__)
#pragma clang system_header /* treat file as system include file */
#endif
#ifndef __CMSIS_VERSION_H
#define __CMSIS_VERSION_H
/* CMSIS Version definitions */
#define __CM_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS Core(M) main version */
#define __CM_CMSIS_VERSION_SUB ( 5U) /*!< [15:0] CMSIS Core(M) sub version */
#define __CM_CMSIS_VERSION ((__CM_CMSIS_VERSION_MAIN << 16U) | \
__CM_CMSIS_VERSION_SUB ) /*!< CMSIS Core(M) version number */
#endif
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,275 @@
/******************************************************************************
* @file mpu_armv7.h
* @brief CMSIS MPU API for Armv7-M MPU
* @version V5.1.2
* @date 25. May 2020
******************************************************************************/
/*
* Copyright (c) 2017-2020 Arm Limited. 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
*
* 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 defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#elif defined (__clang__)
#pragma clang system_header /* treat file as system include file */
#endif
#ifndef ARM_MPU_ARMV7_H
#define ARM_MPU_ARMV7_H
#define ARM_MPU_REGION_SIZE_32B ((uint8_t)0x04U) ///!< MPU Region Size 32 Bytes
#define ARM_MPU_REGION_SIZE_64B ((uint8_t)0x05U) ///!< MPU Region Size 64 Bytes
#define ARM_MPU_REGION_SIZE_128B ((uint8_t)0x06U) ///!< MPU Region Size 128 Bytes
#define ARM_MPU_REGION_SIZE_256B ((uint8_t)0x07U) ///!< MPU Region Size 256 Bytes
#define ARM_MPU_REGION_SIZE_512B ((uint8_t)0x08U) ///!< MPU Region Size 512 Bytes
#define ARM_MPU_REGION_SIZE_1KB ((uint8_t)0x09U) ///!< MPU Region Size 1 KByte
#define ARM_MPU_REGION_SIZE_2KB ((uint8_t)0x0AU) ///!< MPU Region Size 2 KBytes
#define ARM_MPU_REGION_SIZE_4KB ((uint8_t)0x0BU) ///!< MPU Region Size 4 KBytes
#define ARM_MPU_REGION_SIZE_8KB ((uint8_t)0x0CU) ///!< MPU Region Size 8 KBytes
#define ARM_MPU_REGION_SIZE_16KB ((uint8_t)0x0DU) ///!< MPU Region Size 16 KBytes
#define ARM_MPU_REGION_SIZE_32KB ((uint8_t)0x0EU) ///!< MPU Region Size 32 KBytes
#define ARM_MPU_REGION_SIZE_64KB ((uint8_t)0x0FU) ///!< MPU Region Size 64 KBytes
#define ARM_MPU_REGION_SIZE_128KB ((uint8_t)0x10U) ///!< MPU Region Size 128 KBytes
#define ARM_MPU_REGION_SIZE_256KB ((uint8_t)0x11U) ///!< MPU Region Size 256 KBytes
#define ARM_MPU_REGION_SIZE_512KB ((uint8_t)0x12U) ///!< MPU Region Size 512 KBytes
#define ARM_MPU_REGION_SIZE_1MB ((uint8_t)0x13U) ///!< MPU Region Size 1 MByte
#define ARM_MPU_REGION_SIZE_2MB ((uint8_t)0x14U) ///!< MPU Region Size 2 MBytes
#define ARM_MPU_REGION_SIZE_4MB ((uint8_t)0x15U) ///!< MPU Region Size 4 MBytes
#define ARM_MPU_REGION_SIZE_8MB ((uint8_t)0x16U) ///!< MPU Region Size 8 MBytes
#define ARM_MPU_REGION_SIZE_16MB ((uint8_t)0x17U) ///!< MPU Region Size 16 MBytes
#define ARM_MPU_REGION_SIZE_32MB ((uint8_t)0x18U) ///!< MPU Region Size 32 MBytes
#define ARM_MPU_REGION_SIZE_64MB ((uint8_t)0x19U) ///!< MPU Region Size 64 MBytes
#define ARM_MPU_REGION_SIZE_128MB ((uint8_t)0x1AU) ///!< MPU Region Size 128 MBytes
#define ARM_MPU_REGION_SIZE_256MB ((uint8_t)0x1BU) ///!< MPU Region Size 256 MBytes
#define ARM_MPU_REGION_SIZE_512MB ((uint8_t)0x1CU) ///!< MPU Region Size 512 MBytes
#define ARM_MPU_REGION_SIZE_1GB ((uint8_t)0x1DU) ///!< MPU Region Size 1 GByte
#define ARM_MPU_REGION_SIZE_2GB ((uint8_t)0x1EU) ///!< MPU Region Size 2 GBytes
#define ARM_MPU_REGION_SIZE_4GB ((uint8_t)0x1FU) ///!< MPU Region Size 4 GBytes
#define ARM_MPU_AP_NONE 0U ///!< MPU Access Permission no access
#define ARM_MPU_AP_PRIV 1U ///!< MPU Access Permission privileged access only
#define ARM_MPU_AP_URO 2U ///!< MPU Access Permission unprivileged access read-only
#define ARM_MPU_AP_FULL 3U ///!< MPU Access Permission full access
#define ARM_MPU_AP_PRO 5U ///!< MPU Access Permission privileged access read-only
#define ARM_MPU_AP_RO 6U ///!< MPU Access Permission read-only access
/** MPU Region Base Address Register Value
*
* \param Region The region to be configured, number 0 to 15.
* \param BaseAddress The base address for the region.
*/
#define ARM_MPU_RBAR(Region, BaseAddress) \
(((BaseAddress) & MPU_RBAR_ADDR_Msk) | \
((Region) & MPU_RBAR_REGION_Msk) | \
(MPU_RBAR_VALID_Msk))
/**
* MPU Memory Access Attributes
*
* \param TypeExtField Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral.
* \param IsShareable Region is shareable between multiple bus masters.
* \param IsCacheable Region is cacheable, i.e. its value may be kept in cache.
* \param IsBufferable Region is bufferable, i.e. using write-back caching. Cacheable but non-bufferable regions use write-through policy.
*/
#define ARM_MPU_ACCESS_(TypeExtField, IsShareable, IsCacheable, IsBufferable) \
((((TypeExtField) << MPU_RASR_TEX_Pos) & MPU_RASR_TEX_Msk) | \
(((IsShareable) << MPU_RASR_S_Pos) & MPU_RASR_S_Msk) | \
(((IsCacheable) << MPU_RASR_C_Pos) & MPU_RASR_C_Msk) | \
(((IsBufferable) << MPU_RASR_B_Pos) & MPU_RASR_B_Msk))
/**
* MPU Region Attribute and Size Register Value
*
* \param DisableExec Instruction access disable bit, 1= disable instruction fetches.
* \param AccessPermission Data access permissions, allows you to configure read/write access for User and Privileged mode.
* \param AccessAttributes Memory access attribution, see \ref ARM_MPU_ACCESS_.
* \param SubRegionDisable Sub-region disable field.
* \param Size Region size of the region to be configured, for example 4K, 8K.
*/
#define ARM_MPU_RASR_EX(DisableExec, AccessPermission, AccessAttributes, SubRegionDisable, Size) \
((((DisableExec) << MPU_RASR_XN_Pos) & MPU_RASR_XN_Msk) | \
(((AccessPermission) << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk) | \
(((AccessAttributes) & (MPU_RASR_TEX_Msk | MPU_RASR_S_Msk | MPU_RASR_C_Msk | MPU_RASR_B_Msk))) | \
(((SubRegionDisable) << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk) | \
(((Size) << MPU_RASR_SIZE_Pos) & MPU_RASR_SIZE_Msk) | \
(((MPU_RASR_ENABLE_Msk))))
/**
* MPU Region Attribute and Size Register Value
*
* \param DisableExec Instruction access disable bit, 1= disable instruction fetches.
* \param AccessPermission Data access permissions, allows you to configure read/write access for User and Privileged mode.
* \param TypeExtField Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral.
* \param IsShareable Region is shareable between multiple bus masters.
* \param IsCacheable Region is cacheable, i.e. its value may be kept in cache.
* \param IsBufferable Region is bufferable, i.e. using write-back caching. Cacheable but non-bufferable regions use write-through policy.
* \param SubRegionDisable Sub-region disable field.
* \param Size Region size of the region to be configured, for example 4K, 8K.
*/
#define ARM_MPU_RASR(DisableExec, AccessPermission, TypeExtField, IsShareable, IsCacheable, IsBufferable, SubRegionDisable, Size) \
ARM_MPU_RASR_EX(DisableExec, AccessPermission, ARM_MPU_ACCESS_(TypeExtField, IsShareable, IsCacheable, IsBufferable), SubRegionDisable, Size)
/**
* MPU Memory Access Attribute for strongly ordered memory.
* - TEX: 000b
* - Shareable
* - Non-cacheable
* - Non-bufferable
*/
#define ARM_MPU_ACCESS_ORDERED ARM_MPU_ACCESS_(0U, 1U, 0U, 0U)
/**
* MPU Memory Access Attribute for device memory.
* - TEX: 000b (if shareable) or 010b (if non-shareable)
* - Shareable or non-shareable
* - Non-cacheable
* - Bufferable (if shareable) or non-bufferable (if non-shareable)
*
* \param IsShareable Configures the device memory as shareable or non-shareable.
*/
#define ARM_MPU_ACCESS_DEVICE(IsShareable) ((IsShareable) ? ARM_MPU_ACCESS_(0U, 1U, 0U, 1U) : ARM_MPU_ACCESS_(2U, 0U, 0U, 0U))
/**
* MPU Memory Access Attribute for normal memory.
* - TEX: 1BBb (reflecting outer cacheability rules)
* - Shareable or non-shareable
* - Cacheable or non-cacheable (reflecting inner cacheability rules)
* - Bufferable or non-bufferable (reflecting inner cacheability rules)
*
* \param OuterCp Configures the outer cache policy.
* \param InnerCp Configures the inner cache policy.
* \param IsShareable Configures the memory as shareable or non-shareable.
*/
#define ARM_MPU_ACCESS_NORMAL(OuterCp, InnerCp, IsShareable) ARM_MPU_ACCESS_((4U | (OuterCp)), IsShareable, ((InnerCp) >> 1U), ((InnerCp) & 1U))
/**
* MPU Memory Access Attribute non-cacheable policy.
*/
#define ARM_MPU_CACHEP_NOCACHE 0U
/**
* MPU Memory Access Attribute write-back, write and read allocate policy.
*/
#define ARM_MPU_CACHEP_WB_WRA 1U
/**
* MPU Memory Access Attribute write-through, no write allocate policy.
*/
#define ARM_MPU_CACHEP_WT_NWA 2U
/**
* MPU Memory Access Attribute write-back, no write allocate policy.
*/
#define ARM_MPU_CACHEP_WB_NWA 3U
/**
* Struct for a single MPU Region
*/
typedef struct {
uint32_t RBAR; //!< The region base address register value (RBAR)
uint32_t RASR; //!< The region attribute and size register value (RASR) \ref MPU_RASR
} ARM_MPU_Region_t;
/** Enable the MPU.
* \param MPU_Control Default access permissions for unconfigured regions.
*/
__STATIC_INLINE void ARM_MPU_Enable(uint32_t MPU_Control)
{
__DMB();
MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk;
#ifdef SCB_SHCSR_MEMFAULTENA_Msk
SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk;
#endif
__DSB();
__ISB();
}
/** Disable the MPU.
*/
__STATIC_INLINE void ARM_MPU_Disable(void)
{
__DMB();
#ifdef SCB_SHCSR_MEMFAULTENA_Msk
SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk;
#endif
MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk;
__DSB();
__ISB();
}
/** Clear and disable the given MPU region.
* \param rnr Region number to be cleared.
*/
__STATIC_INLINE void ARM_MPU_ClrRegion(uint32_t rnr)
{
MPU->RNR = rnr;
MPU->RASR = 0U;
}
/** Configure an MPU region.
* \param rbar Value for RBAR register.
* \param rasr Value for RASR register.
*/
__STATIC_INLINE void ARM_MPU_SetRegion(uint32_t rbar, uint32_t rasr)
{
MPU->RBAR = rbar;
MPU->RASR = rasr;
}
/** Configure the given MPU region.
* \param rnr Region number to be configured.
* \param rbar Value for RBAR register.
* \param rasr Value for RASR register.
*/
__STATIC_INLINE void ARM_MPU_SetRegionEx(uint32_t rnr, uint32_t rbar, uint32_t rasr)
{
MPU->RNR = rnr;
MPU->RBAR = rbar;
MPU->RASR = rasr;
}
/** Memcpy with strictly ordered memory access, e.g. used by code in ARM_MPU_Load().
* \param dst Destination data is copied to.
* \param src Source data is copied from.
* \param len Amount of data words to be copied.
*/
__STATIC_INLINE void ARM_MPU_OrderedMemcpy(volatile uint32_t* dst, const uint32_t* __RESTRICT src, uint32_t len)
{
uint32_t i;
for (i = 0U; i < len; ++i)
{
dst[i] = src[i];
}
}
/** Load the given number of MPU regions from a table.
* \param table Pointer to the MPU configuration table.
* \param cnt Amount of regions to be configured.
*/
__STATIC_INLINE void ARM_MPU_Load(ARM_MPU_Region_t const* table, uint32_t cnt)
{
const uint32_t rowWordSize = sizeof(ARM_MPU_Region_t)/4U;
while (cnt > MPU_TYPE_RALIASES) {
ARM_MPU_OrderedMemcpy(&(MPU->RBAR), &(table->RBAR), MPU_TYPE_RALIASES*rowWordSize);
table += MPU_TYPE_RALIASES;
cnt -= MPU_TYPE_RALIASES;
}
ARM_MPU_OrderedMemcpy(&(MPU->RBAR), &(table->RBAR), cnt*rowWordSize);
}
#endif
@@ -0,0 +1,352 @@
/******************************************************************************
* @file mpu_armv8.h
* @brief CMSIS MPU API for Armv8-M and Armv8.1-M MPU
* @version V5.1.3
* @date 03. February 2021
******************************************************************************/
/*
* Copyright (c) 2017-2021 Arm Limited. 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
*
* 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 defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#elif defined (__clang__)
#pragma clang system_header /* treat file as system include file */
#endif
#ifndef ARM_MPU_ARMV8_H
#define ARM_MPU_ARMV8_H
/** \brief Attribute for device memory (outer only) */
#define ARM_MPU_ATTR_DEVICE ( 0U )
/** \brief Attribute for non-cacheable, normal memory */
#define ARM_MPU_ATTR_NON_CACHEABLE ( 4U )
/** \brief Attribute for normal memory (outer and inner)
* \param NT Non-Transient: Set to 1 for non-transient data.
* \param WB Write-Back: Set to 1 to use write-back update policy.
* \param RA Read Allocation: Set to 1 to use cache allocation on read miss.
* \param WA Write Allocation: Set to 1 to use cache allocation on write miss.
*/
#define ARM_MPU_ATTR_MEMORY_(NT, WB, RA, WA) \
((((NT) & 1U) << 3U) | (((WB) & 1U) << 2U) | (((RA) & 1U) << 1U) | ((WA) & 1U))
/** \brief Device memory type non Gathering, non Re-ordering, non Early Write Acknowledgement */
#define ARM_MPU_ATTR_DEVICE_nGnRnE (0U)
/** \brief Device memory type non Gathering, non Re-ordering, Early Write Acknowledgement */
#define ARM_MPU_ATTR_DEVICE_nGnRE (1U)
/** \brief Device memory type non Gathering, Re-ordering, Early Write Acknowledgement */
#define ARM_MPU_ATTR_DEVICE_nGRE (2U)
/** \brief Device memory type Gathering, Re-ordering, Early Write Acknowledgement */
#define ARM_MPU_ATTR_DEVICE_GRE (3U)
/** \brief Memory Attribute
* \param O Outer memory attributes
* \param I O == ARM_MPU_ATTR_DEVICE: Device memory attributes, else: Inner memory attributes
*/
#define ARM_MPU_ATTR(O, I) ((((O) & 0xFU) << 4U) | ((((O) & 0xFU) != 0U) ? ((I) & 0xFU) : (((I) & 0x3U) << 2U)))
/** \brief Normal memory non-shareable */
#define ARM_MPU_SH_NON (0U)
/** \brief Normal memory outer shareable */
#define ARM_MPU_SH_OUTER (2U)
/** \brief Normal memory inner shareable */
#define ARM_MPU_SH_INNER (3U)
/** \brief Memory access permissions
* \param RO Read-Only: Set to 1 for read-only memory.
* \param NP Non-Privileged: Set to 1 for non-privileged memory.
*/
#define ARM_MPU_AP_(RO, NP) ((((RO) & 1U) << 1U) | ((NP) & 1U))
/** \brief Region Base Address Register value
* \param BASE The base address bits [31:5] of a memory region. The value is zero extended. Effective address gets 32 byte aligned.
* \param SH Defines the Shareability domain for this memory region.
* \param RO Read-Only: Set to 1 for a read-only memory region.
* \param NP Non-Privileged: Set to 1 for a non-privileged memory region.
* \oaram XN eXecute Never: Set to 1 for a non-executable memory region.
*/
#define ARM_MPU_RBAR(BASE, SH, RO, NP, XN) \
(((BASE) & MPU_RBAR_BASE_Msk) | \
(((SH) << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk) | \
((ARM_MPU_AP_(RO, NP) << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk) | \
(((XN) << MPU_RBAR_XN_Pos) & MPU_RBAR_XN_Msk))
/** \brief Region Limit Address Register value
* \param LIMIT The limit address bits [31:5] for this memory region. The value is one extended.
* \param IDX The attribute index to be associated with this memory region.
*/
#define ARM_MPU_RLAR(LIMIT, IDX) \
(((LIMIT) & MPU_RLAR_LIMIT_Msk) | \
(((IDX) << MPU_RLAR_AttrIndx_Pos) & MPU_RLAR_AttrIndx_Msk) | \
(MPU_RLAR_EN_Msk))
#if defined(MPU_RLAR_PXN_Pos)
/** \brief Region Limit Address Register with PXN value
* \param LIMIT The limit address bits [31:5] for this memory region. The value is one extended.
* \param PXN Privileged execute never. Defines whether code can be executed from this privileged region.
* \param IDX The attribute index to be associated with this memory region.
*/
#define ARM_MPU_RLAR_PXN(LIMIT, PXN, IDX) \
(((LIMIT) & MPU_RLAR_LIMIT_Msk) | \
(((PXN) << MPU_RLAR_PXN_Pos) & MPU_RLAR_PXN_Msk) | \
(((IDX) << MPU_RLAR_AttrIndx_Pos) & MPU_RLAR_AttrIndx_Msk) | \
(MPU_RLAR_EN_Msk))
#endif
/**
* Struct for a single MPU Region
*/
typedef struct {
uint32_t RBAR; /*!< Region Base Address Register value */
uint32_t RLAR; /*!< Region Limit Address Register value */
} ARM_MPU_Region_t;
/** Enable the MPU.
* \param MPU_Control Default access permissions for unconfigured regions.
*/
__STATIC_INLINE void ARM_MPU_Enable(uint32_t MPU_Control)
{
__DMB();
MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk;
#ifdef SCB_SHCSR_MEMFAULTENA_Msk
SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk;
#endif
__DSB();
__ISB();
}
/** Disable the MPU.
*/
__STATIC_INLINE void ARM_MPU_Disable(void)
{
__DMB();
#ifdef SCB_SHCSR_MEMFAULTENA_Msk
SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk;
#endif
MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk;
__DSB();
__ISB();
}
#ifdef MPU_NS
/** Enable the Non-secure MPU.
* \param MPU_Control Default access permissions for unconfigured regions.
*/
__STATIC_INLINE void ARM_MPU_Enable_NS(uint32_t MPU_Control)
{
__DMB();
MPU_NS->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk;
#ifdef SCB_SHCSR_MEMFAULTENA_Msk
SCB_NS->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk;
#endif
__DSB();
__ISB();
}
/** Disable the Non-secure MPU.
*/
__STATIC_INLINE void ARM_MPU_Disable_NS(void)
{
__DMB();
#ifdef SCB_SHCSR_MEMFAULTENA_Msk
SCB_NS->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk;
#endif
MPU_NS->CTRL &= ~MPU_CTRL_ENABLE_Msk;
__DSB();
__ISB();
}
#endif
/** Set the memory attribute encoding to the given MPU.
* \param mpu Pointer to the MPU to be configured.
* \param idx The attribute index to be set [0-7]
* \param attr The attribute value to be set.
*/
__STATIC_INLINE void ARM_MPU_SetMemAttrEx(MPU_Type* mpu, uint8_t idx, uint8_t attr)
{
const uint8_t reg = idx / 4U;
const uint32_t pos = ((idx % 4U) * 8U);
const uint32_t mask = 0xFFU << pos;
if (reg >= (sizeof(mpu->MAIR) / sizeof(mpu->MAIR[0]))) {
return; // invalid index
}
mpu->MAIR[reg] = ((mpu->MAIR[reg] & ~mask) | ((attr << pos) & mask));
}
/** Set the memory attribute encoding.
* \param idx The attribute index to be set [0-7]
* \param attr The attribute value to be set.
*/
__STATIC_INLINE void ARM_MPU_SetMemAttr(uint8_t idx, uint8_t attr)
{
ARM_MPU_SetMemAttrEx(MPU, idx, attr);
}
#ifdef MPU_NS
/** Set the memory attribute encoding to the Non-secure MPU.
* \param idx The attribute index to be set [0-7]
* \param attr The attribute value to be set.
*/
__STATIC_INLINE void ARM_MPU_SetMemAttr_NS(uint8_t idx, uint8_t attr)
{
ARM_MPU_SetMemAttrEx(MPU_NS, idx, attr);
}
#endif
/** Clear and disable the given MPU region of the given MPU.
* \param mpu Pointer to MPU to be used.
* \param rnr Region number to be cleared.
*/
__STATIC_INLINE void ARM_MPU_ClrRegionEx(MPU_Type* mpu, uint32_t rnr)
{
mpu->RNR = rnr;
mpu->RLAR = 0U;
}
/** Clear and disable the given MPU region.
* \param rnr Region number to be cleared.
*/
__STATIC_INLINE void ARM_MPU_ClrRegion(uint32_t rnr)
{
ARM_MPU_ClrRegionEx(MPU, rnr);
}
#ifdef MPU_NS
/** Clear and disable the given Non-secure MPU region.
* \param rnr Region number to be cleared.
*/
__STATIC_INLINE void ARM_MPU_ClrRegion_NS(uint32_t rnr)
{
ARM_MPU_ClrRegionEx(MPU_NS, rnr);
}
#endif
/** Configure the given MPU region of the given MPU.
* \param mpu Pointer to MPU to be used.
* \param rnr Region number to be configured.
* \param rbar Value for RBAR register.
* \param rlar Value for RLAR register.
*/
__STATIC_INLINE void ARM_MPU_SetRegionEx(MPU_Type* mpu, uint32_t rnr, uint32_t rbar, uint32_t rlar)
{
mpu->RNR = rnr;
mpu->RBAR = rbar;
mpu->RLAR = rlar;
}
/** Configure the given MPU region.
* \param rnr Region number to be configured.
* \param rbar Value for RBAR register.
* \param rlar Value for RLAR register.
*/
__STATIC_INLINE void ARM_MPU_SetRegion(uint32_t rnr, uint32_t rbar, uint32_t rlar)
{
ARM_MPU_SetRegionEx(MPU, rnr, rbar, rlar);
}
#ifdef MPU_NS
/** Configure the given Non-secure MPU region.
* \param rnr Region number to be configured.
* \param rbar Value for RBAR register.
* \param rlar Value for RLAR register.
*/
__STATIC_INLINE void ARM_MPU_SetRegion_NS(uint32_t rnr, uint32_t rbar, uint32_t rlar)
{
ARM_MPU_SetRegionEx(MPU_NS, rnr, rbar, rlar);
}
#endif
/** Memcpy with strictly ordered memory access, e.g. used by code in ARM_MPU_LoadEx()
* \param dst Destination data is copied to.
* \param src Source data is copied from.
* \param len Amount of data words to be copied.
*/
__STATIC_INLINE void ARM_MPU_OrderedMemcpy(volatile uint32_t* dst, const uint32_t* __RESTRICT src, uint32_t len)
{
uint32_t i;
for (i = 0U; i < len; ++i)
{
dst[i] = src[i];
}
}
/** Load the given number of MPU regions from a table to the given MPU.
* \param mpu Pointer to the MPU registers to be used.
* \param rnr First region number to be configured.
* \param table Pointer to the MPU configuration table.
* \param cnt Amount of regions to be configured.
*/
__STATIC_INLINE void ARM_MPU_LoadEx(MPU_Type* mpu, uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt)
{
const uint32_t rowWordSize = sizeof(ARM_MPU_Region_t)/4U;
if (cnt == 1U) {
mpu->RNR = rnr;
ARM_MPU_OrderedMemcpy(&(mpu->RBAR), &(table->RBAR), rowWordSize);
} else {
uint32_t rnrBase = rnr & ~(MPU_TYPE_RALIASES-1U);
uint32_t rnrOffset = rnr % MPU_TYPE_RALIASES;
mpu->RNR = rnrBase;
while ((rnrOffset + cnt) > MPU_TYPE_RALIASES) {
uint32_t c = MPU_TYPE_RALIASES - rnrOffset;
ARM_MPU_OrderedMemcpy(&(mpu->RBAR)+(rnrOffset*2U), &(table->RBAR), c*rowWordSize);
table += c;
cnt -= c;
rnrOffset = 0U;
rnrBase += MPU_TYPE_RALIASES;
mpu->RNR = rnrBase;
}
ARM_MPU_OrderedMemcpy(&(mpu->RBAR)+(rnrOffset*2U), &(table->RBAR), cnt*rowWordSize);
}
}
/** Load the given number of MPU regions from a table.
* \param rnr First region number to be configured.
* \param table Pointer to the MPU configuration table.
* \param cnt Amount of regions to be configured.
*/
__STATIC_INLINE void ARM_MPU_Load(uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt)
{
ARM_MPU_LoadEx(MPU, rnr, table, cnt);
}
#ifdef MPU_NS
/** Load the given number of MPU regions from a table to the Non-secure MPU.
* \param rnr First region number to be configured.
* \param table Pointer to the MPU configuration table.
* \param cnt Amount of regions to be configured.
*/
__STATIC_INLINE void ARM_MPU_Load_NS(uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt)
{
ARM_MPU_LoadEx(MPU_NS, rnr, table, cnt);
}
#endif
#endif
@@ -0,0 +1,337 @@
/******************************************************************************
* @file pmu_armv8.h
* @brief CMSIS PMU API for Armv8.1-M PMU
* @version V1.0.1
* @date 15. April 2020
******************************************************************************/
/*
* Copyright (c) 2020 Arm Limited. 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
*
* 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 defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#elif defined (__clang__)
#pragma clang system_header /* treat file as system include file */
#endif
#ifndef ARM_PMU_ARMV8_H
#define ARM_PMU_ARMV8_H
/**
* \brief PMU Events
* \note See the Armv8.1-M Architecture Reference Manual for full details on these PMU events.
* */
#define ARM_PMU_SW_INCR 0x0000 /*!< Software update to the PMU_SWINC register, architecturally executed and condition code check pass */
#define ARM_PMU_L1I_CACHE_REFILL 0x0001 /*!< L1 I-Cache refill */
#define ARM_PMU_L1D_CACHE_REFILL 0x0003 /*!< L1 D-Cache refill */
#define ARM_PMU_L1D_CACHE 0x0004 /*!< L1 D-Cache access */
#define ARM_PMU_LD_RETIRED 0x0006 /*!< Memory-reading instruction architecturally executed and condition code check pass */
#define ARM_PMU_ST_RETIRED 0x0007 /*!< Memory-writing instruction architecturally executed and condition code check pass */
#define ARM_PMU_INST_RETIRED 0x0008 /*!< Instruction architecturally executed */
#define ARM_PMU_EXC_TAKEN 0x0009 /*!< Exception entry */
#define ARM_PMU_EXC_RETURN 0x000A /*!< Exception return instruction architecturally executed and the condition code check pass */
#define ARM_PMU_PC_WRITE_RETIRED 0x000C /*!< Software change to the Program Counter (PC). Instruction is architecturally executed and condition code check pass */
#define ARM_PMU_BR_IMMED_RETIRED 0x000D /*!< Immediate branch architecturally executed */
#define ARM_PMU_BR_RETURN_RETIRED 0x000E /*!< Function return instruction architecturally executed and the condition code check pass */
#define ARM_PMU_UNALIGNED_LDST_RETIRED 0x000F /*!< Unaligned memory memory-reading or memory-writing instruction architecturally executed and condition code check pass */
#define ARM_PMU_BR_MIS_PRED 0x0010 /*!< Mispredicted or not predicted branch speculatively executed */
#define ARM_PMU_CPU_CYCLES 0x0011 /*!< Cycle */
#define ARM_PMU_BR_PRED 0x0012 /*!< Predictable branch speculatively executed */
#define ARM_PMU_MEM_ACCESS 0x0013 /*!< Data memory access */
#define ARM_PMU_L1I_CACHE 0x0014 /*!< Level 1 instruction cache access */
#define ARM_PMU_L1D_CACHE_WB 0x0015 /*!< Level 1 data cache write-back */
#define ARM_PMU_L2D_CACHE 0x0016 /*!< Level 2 data cache access */
#define ARM_PMU_L2D_CACHE_REFILL 0x0017 /*!< Level 2 data cache refill */
#define ARM_PMU_L2D_CACHE_WB 0x0018 /*!< Level 2 data cache write-back */
#define ARM_PMU_BUS_ACCESS 0x0019 /*!< Bus access */
#define ARM_PMU_MEMORY_ERROR 0x001A /*!< Local memory error */
#define ARM_PMU_INST_SPEC 0x001B /*!< Instruction speculatively executed */
#define ARM_PMU_BUS_CYCLES 0x001D /*!< Bus cycles */
#define ARM_PMU_CHAIN 0x001E /*!< For an odd numbered counter, increment when an overflow occurs on the preceding even-numbered counter on the same PE */
#define ARM_PMU_L1D_CACHE_ALLOCATE 0x001F /*!< Level 1 data cache allocation without refill */
#define ARM_PMU_L2D_CACHE_ALLOCATE 0x0020 /*!< Level 2 data cache allocation without refill */
#define ARM_PMU_BR_RETIRED 0x0021 /*!< Branch instruction architecturally executed */
#define ARM_PMU_BR_MIS_PRED_RETIRED 0x0022 /*!< Mispredicted branch instruction architecturally executed */
#define ARM_PMU_STALL_FRONTEND 0x0023 /*!< No operation issued because of the frontend */
#define ARM_PMU_STALL_BACKEND 0x0024 /*!< No operation issued because of the backend */
#define ARM_PMU_L2I_CACHE 0x0027 /*!< Level 2 instruction cache access */
#define ARM_PMU_L2I_CACHE_REFILL 0x0028 /*!< Level 2 instruction cache refill */
#define ARM_PMU_L3D_CACHE_ALLOCATE 0x0029 /*!< Level 3 data cache allocation without refill */
#define ARM_PMU_L3D_CACHE_REFILL 0x002A /*!< Level 3 data cache refill */
#define ARM_PMU_L3D_CACHE 0x002B /*!< Level 3 data cache access */
#define ARM_PMU_L3D_CACHE_WB 0x002C /*!< Level 3 data cache write-back */
#define ARM_PMU_LL_CACHE_RD 0x0036 /*!< Last level data cache read */
#define ARM_PMU_LL_CACHE_MISS_RD 0x0037 /*!< Last level data cache read miss */
#define ARM_PMU_L1D_CACHE_MISS_RD 0x0039 /*!< Level 1 data cache read miss */
#define ARM_PMU_OP_COMPLETE 0x003A /*!< Operation retired */
#define ARM_PMU_OP_SPEC 0x003B /*!< Operation speculatively executed */
#define ARM_PMU_STALL 0x003C /*!< Stall cycle for instruction or operation not sent for execution */
#define ARM_PMU_STALL_OP_BACKEND 0x003D /*!< Stall cycle for instruction or operation not sent for execution due to pipeline backend */
#define ARM_PMU_STALL_OP_FRONTEND 0x003E /*!< Stall cycle for instruction or operation not sent for execution due to pipeline frontend */
#define ARM_PMU_STALL_OP 0x003F /*!< Instruction or operation slots not occupied each cycle */
#define ARM_PMU_L1D_CACHE_RD 0x0040 /*!< Level 1 data cache read */
#define ARM_PMU_LE_RETIRED 0x0100 /*!< Loop end instruction executed */
#define ARM_PMU_LE_SPEC 0x0101 /*!< Loop end instruction speculatively executed */
#define ARM_PMU_BF_RETIRED 0x0104 /*!< Branch future instruction architecturally executed and condition code check pass */
#define ARM_PMU_BF_SPEC 0x0105 /*!< Branch future instruction speculatively executed and condition code check pass */
#define ARM_PMU_LE_CANCEL 0x0108 /*!< Loop end instruction not taken */
#define ARM_PMU_BF_CANCEL 0x0109 /*!< Branch future instruction not taken */
#define ARM_PMU_SE_CALL_S 0x0114 /*!< Call to secure function, resulting in Security state change */
#define ARM_PMU_SE_CALL_NS 0x0115 /*!< Call to non-secure function, resulting in Security state change */
#define ARM_PMU_DWT_CMPMATCH0 0x0118 /*!< DWT comparator 0 match */
#define ARM_PMU_DWT_CMPMATCH1 0x0119 /*!< DWT comparator 1 match */
#define ARM_PMU_DWT_CMPMATCH2 0x011A /*!< DWT comparator 2 match */
#define ARM_PMU_DWT_CMPMATCH3 0x011B /*!< DWT comparator 3 match */
#define ARM_PMU_MVE_INST_RETIRED 0x0200 /*!< MVE instruction architecturally executed */
#define ARM_PMU_MVE_INST_SPEC 0x0201 /*!< MVE instruction speculatively executed */
#define ARM_PMU_MVE_FP_RETIRED 0x0204 /*!< MVE floating-point instruction architecturally executed */
#define ARM_PMU_MVE_FP_SPEC 0x0205 /*!< MVE floating-point instruction speculatively executed */
#define ARM_PMU_MVE_FP_HP_RETIRED 0x0208 /*!< MVE half-precision floating-point instruction architecturally executed */
#define ARM_PMU_MVE_FP_HP_SPEC 0x0209 /*!< MVE half-precision floating-point instruction speculatively executed */
#define ARM_PMU_MVE_FP_SP_RETIRED 0x020C /*!< MVE single-precision floating-point instruction architecturally executed */
#define ARM_PMU_MVE_FP_SP_SPEC 0x020D /*!< MVE single-precision floating-point instruction speculatively executed */
#define ARM_PMU_MVE_FP_MAC_RETIRED 0x0214 /*!< MVE floating-point multiply or multiply-accumulate instruction architecturally executed */
#define ARM_PMU_MVE_FP_MAC_SPEC 0x0215 /*!< MVE floating-point multiply or multiply-accumulate instruction speculatively executed */
#define ARM_PMU_MVE_INT_RETIRED 0x0224 /*!< MVE integer instruction architecturally executed */
#define ARM_PMU_MVE_INT_SPEC 0x0225 /*!< MVE integer instruction speculatively executed */
#define ARM_PMU_MVE_INT_MAC_RETIRED 0x0228 /*!< MVE multiply or multiply-accumulate instruction architecturally executed */
#define ARM_PMU_MVE_INT_MAC_SPEC 0x0229 /*!< MVE multiply or multiply-accumulate instruction speculatively executed */
#define ARM_PMU_MVE_LDST_RETIRED 0x0238 /*!< MVE load or store instruction architecturally executed */
#define ARM_PMU_MVE_LDST_SPEC 0x0239 /*!< MVE load or store instruction speculatively executed */
#define ARM_PMU_MVE_LD_RETIRED 0x023C /*!< MVE load instruction architecturally executed */
#define ARM_PMU_MVE_LD_SPEC 0x023D /*!< MVE load instruction speculatively executed */
#define ARM_PMU_MVE_ST_RETIRED 0x0240 /*!< MVE store instruction architecturally executed */
#define ARM_PMU_MVE_ST_SPEC 0x0241 /*!< MVE store instruction speculatively executed */
#define ARM_PMU_MVE_LDST_CONTIG_RETIRED 0x0244 /*!< MVE contiguous load or store instruction architecturally executed */
#define ARM_PMU_MVE_LDST_CONTIG_SPEC 0x0245 /*!< MVE contiguous load or store instruction speculatively executed */
#define ARM_PMU_MVE_LD_CONTIG_RETIRED 0x0248 /*!< MVE contiguous load instruction architecturally executed */
#define ARM_PMU_MVE_LD_CONTIG_SPEC 0x0249 /*!< MVE contiguous load instruction speculatively executed */
#define ARM_PMU_MVE_ST_CONTIG_RETIRED 0x024C /*!< MVE contiguous store instruction architecturally executed */
#define ARM_PMU_MVE_ST_CONTIG_SPEC 0x024D /*!< MVE contiguous store instruction speculatively executed */
#define ARM_PMU_MVE_LDST_NONCONTIG_RETIRED 0x0250 /*!< MVE non-contiguous load or store instruction architecturally executed */
#define ARM_PMU_MVE_LDST_NONCONTIG_SPEC 0x0251 /*!< MVE non-contiguous load or store instruction speculatively executed */
#define ARM_PMU_MVE_LD_NONCONTIG_RETIRED 0x0254 /*!< MVE non-contiguous load instruction architecturally executed */
#define ARM_PMU_MVE_LD_NONCONTIG_SPEC 0x0255 /*!< MVE non-contiguous load instruction speculatively executed */
#define ARM_PMU_MVE_ST_NONCONTIG_RETIRED 0x0258 /*!< MVE non-contiguous store instruction architecturally executed */
#define ARM_PMU_MVE_ST_NONCONTIG_SPEC 0x0259 /*!< MVE non-contiguous store instruction speculatively executed */
#define ARM_PMU_MVE_LDST_MULTI_RETIRED 0x025C /*!< MVE memory instruction targeting multiple registers architecturally executed */
#define ARM_PMU_MVE_LDST_MULTI_SPEC 0x025D /*!< MVE memory instruction targeting multiple registers speculatively executed */
#define ARM_PMU_MVE_LD_MULTI_RETIRED 0x0260 /*!< MVE memory load instruction targeting multiple registers architecturally executed */
#define ARM_PMU_MVE_LD_MULTI_SPEC 0x0261 /*!< MVE memory load instruction targeting multiple registers speculatively executed */
#define ARM_PMU_MVE_ST_MULTI_RETIRED 0x0261 /*!< MVE memory store instruction targeting multiple registers architecturally executed */
#define ARM_PMU_MVE_ST_MULTI_SPEC 0x0265 /*!< MVE memory store instruction targeting multiple registers speculatively executed */
#define ARM_PMU_MVE_LDST_UNALIGNED_RETIRED 0x028C /*!< MVE unaligned memory load or store instruction architecturally executed */
#define ARM_PMU_MVE_LDST_UNALIGNED_SPEC 0x028D /*!< MVE unaligned memory load or store instruction speculatively executed */
#define ARM_PMU_MVE_LD_UNALIGNED_RETIRED 0x0290 /*!< MVE unaligned load instruction architecturally executed */
#define ARM_PMU_MVE_LD_UNALIGNED_SPEC 0x0291 /*!< MVE unaligned load instruction speculatively executed */
#define ARM_PMU_MVE_ST_UNALIGNED_RETIRED 0x0294 /*!< MVE unaligned store instruction architecturally executed */
#define ARM_PMU_MVE_ST_UNALIGNED_SPEC 0x0295 /*!< MVE unaligned store instruction speculatively executed */
#define ARM_PMU_MVE_LDST_UNALIGNED_NONCONTIG_RETIRED 0x0298 /*!< MVE unaligned noncontiguous load or store instruction architecturally executed */
#define ARM_PMU_MVE_LDST_UNALIGNED_NONCONTIG_SPEC 0x0299 /*!< MVE unaligned noncontiguous load or store instruction speculatively executed */
#define ARM_PMU_MVE_VREDUCE_RETIRED 0x02A0 /*!< MVE vector reduction instruction architecturally executed */
#define ARM_PMU_MVE_VREDUCE_SPEC 0x02A1 /*!< MVE vector reduction instruction speculatively executed */
#define ARM_PMU_MVE_VREDUCE_FP_RETIRED 0x02A4 /*!< MVE floating-point vector reduction instruction architecturally executed */
#define ARM_PMU_MVE_VREDUCE_FP_SPEC 0x02A5 /*!< MVE floating-point vector reduction instruction speculatively executed */
#define ARM_PMU_MVE_VREDUCE_INT_RETIRED 0x02A8 /*!< MVE integer vector reduction instruction architecturally executed */
#define ARM_PMU_MVE_VREDUCE_INT_SPEC 0x02A9 /*!< MVE integer vector reduction instruction speculatively executed */
#define ARM_PMU_MVE_PRED 0x02B8 /*!< Cycles where one or more predicated beats architecturally executed */
#define ARM_PMU_MVE_STALL 0x02CC /*!< Stall cycles caused by an MVE instruction */
#define ARM_PMU_MVE_STALL_RESOURCE 0x02CD /*!< Stall cycles caused by an MVE instruction because of resource conflicts */
#define ARM_PMU_MVE_STALL_RESOURCE_MEM 0x02CE /*!< Stall cycles caused by an MVE instruction because of memory resource conflicts */
#define ARM_PMU_MVE_STALL_RESOURCE_FP 0x02CF /*!< Stall cycles caused by an MVE instruction because of floating-point resource conflicts */
#define ARM_PMU_MVE_STALL_RESOURCE_INT 0x02D0 /*!< Stall cycles caused by an MVE instruction because of integer resource conflicts */
#define ARM_PMU_MVE_STALL_BREAK 0x02D3 /*!< Stall cycles caused by an MVE chain break */
#define ARM_PMU_MVE_STALL_DEPENDENCY 0x02D4 /*!< Stall cycles caused by MVE register dependency */
#define ARM_PMU_ITCM_ACCESS 0x4007 /*!< Instruction TCM access */
#define ARM_PMU_DTCM_ACCESS 0x4008 /*!< Data TCM access */
#define ARM_PMU_TRCEXTOUT0 0x4010 /*!< ETM external output 0 */
#define ARM_PMU_TRCEXTOUT1 0x4011 /*!< ETM external output 1 */
#define ARM_PMU_TRCEXTOUT2 0x4012 /*!< ETM external output 2 */
#define ARM_PMU_TRCEXTOUT3 0x4013 /*!< ETM external output 3 */
#define ARM_PMU_CTI_TRIGOUT4 0x4018 /*!< Cross-trigger Interface output trigger 4 */
#define ARM_PMU_CTI_TRIGOUT5 0x4019 /*!< Cross-trigger Interface output trigger 5 */
#define ARM_PMU_CTI_TRIGOUT6 0x401A /*!< Cross-trigger Interface output trigger 6 */
#define ARM_PMU_CTI_TRIGOUT7 0x401B /*!< Cross-trigger Interface output trigger 7 */
/** \brief PMU Functions */
__STATIC_INLINE void ARM_PMU_Enable(void);
__STATIC_INLINE void ARM_PMU_Disable(void);
__STATIC_INLINE void ARM_PMU_Set_EVTYPER(uint32_t num, uint32_t type);
__STATIC_INLINE void ARM_PMU_CYCCNT_Reset(void);
__STATIC_INLINE void ARM_PMU_EVCNTR_ALL_Reset(void);
__STATIC_INLINE void ARM_PMU_CNTR_Enable(uint32_t mask);
__STATIC_INLINE void ARM_PMU_CNTR_Disable(uint32_t mask);
__STATIC_INLINE uint32_t ARM_PMU_Get_CCNTR(void);
__STATIC_INLINE uint32_t ARM_PMU_Get_EVCNTR(uint32_t num);
__STATIC_INLINE uint32_t ARM_PMU_Get_CNTR_OVS(void);
__STATIC_INLINE void ARM_PMU_Set_CNTR_OVS(uint32_t mask);
__STATIC_INLINE void ARM_PMU_Set_CNTR_IRQ_Enable(uint32_t mask);
__STATIC_INLINE void ARM_PMU_Set_CNTR_IRQ_Disable(uint32_t mask);
__STATIC_INLINE void ARM_PMU_CNTR_Increment(uint32_t mask);
/**
\brief Enable the PMU
*/
__STATIC_INLINE void ARM_PMU_Enable(void)
{
PMU->CTRL |= PMU_CTRL_ENABLE_Msk;
}
/**
\brief Disable the PMU
*/
__STATIC_INLINE void ARM_PMU_Disable(void)
{
PMU->CTRL &= ~PMU_CTRL_ENABLE_Msk;
}
/**
\brief Set event to count for PMU eventer counter
\param [in] num Event counter (0-30) to configure
\param [in] type Event to count
*/
__STATIC_INLINE void ARM_PMU_Set_EVTYPER(uint32_t num, uint32_t type)
{
PMU->EVTYPER[num] = type;
}
/**
\brief Reset cycle counter
*/
__STATIC_INLINE void ARM_PMU_CYCCNT_Reset(void)
{
PMU->CTRL |= PMU_CTRL_CYCCNT_RESET_Msk;
}
/**
\brief Reset all event counters
*/
__STATIC_INLINE void ARM_PMU_EVCNTR_ALL_Reset(void)
{
PMU->CTRL |= PMU_CTRL_EVENTCNT_RESET_Msk;
}
/**
\brief Enable counters
\param [in] mask Counters to enable
\note Enables one or more of the following:
- event counters (0-30)
- cycle counter
*/
__STATIC_INLINE void ARM_PMU_CNTR_Enable(uint32_t mask)
{
PMU->CNTENSET = mask;
}
/**
\brief Disable counters
\param [in] mask Counters to enable
\note Disables one or more of the following:
- event counters (0-30)
- cycle counter
*/
__STATIC_INLINE void ARM_PMU_CNTR_Disable(uint32_t mask)
{
PMU->CNTENCLR = mask;
}
/**
\brief Read cycle counter
\return Cycle count
*/
__STATIC_INLINE uint32_t ARM_PMU_Get_CCNTR(void)
{
return PMU->CCNTR;
}
/**
\brief Read event counter
\param [in] num Event counter (0-30) to read
\return Event count
*/
__STATIC_INLINE uint32_t ARM_PMU_Get_EVCNTR(uint32_t num)
{
return PMU_EVCNTR_CNT_Msk & PMU->EVCNTR[num];
}
/**
\brief Read counter overflow status
\return Counter overflow status bits for the following:
- event counters (0-30)
- cycle counter
*/
__STATIC_INLINE uint32_t ARM_PMU_Get_CNTR_OVS(void)
{
return PMU->OVSSET;
}
/**
\brief Clear counter overflow status
\param [in] mask Counter overflow status bits to clear
\note Clears overflow status bits for one or more of the following:
- event counters (0-30)
- cycle counter
*/
__STATIC_INLINE void ARM_PMU_Set_CNTR_OVS(uint32_t mask)
{
PMU->OVSCLR = mask;
}
/**
\brief Enable counter overflow interrupt request
\param [in] mask Counter overflow interrupt request bits to set
\note Sets overflow interrupt request bits for one or more of the following:
- event counters (0-30)
- cycle counter
*/
__STATIC_INLINE void ARM_PMU_Set_CNTR_IRQ_Enable(uint32_t mask)
{
PMU->INTENSET = mask;
}
/**
\brief Disable counter overflow interrupt request
\param [in] mask Counter overflow interrupt request bits to clear
\note Clears overflow interrupt request bits for one or more of the following:
- event counters (0-30)
- cycle counter
*/
__STATIC_INLINE void ARM_PMU_Set_CNTR_IRQ_Disable(uint32_t mask)
{
PMU->INTENCLR = mask;
}
/**
\brief Software increment event counter
\param [in] mask Counters to increment
\note Software increment bits for one or more event counters (0-30)
*/
__STATIC_INLINE void ARM_PMU_CNTR_Increment(uint32_t mask)
{
PMU->SWINC = mask;
}
#endif
@@ -0,0 +1,70 @@
/******************************************************************************
* @file tz_context.h
* @brief Context Management for Armv8-M TrustZone
* @version V1.0.1
* @date 10. January 2018
******************************************************************************/
/*
* Copyright (c) 2017-2018 Arm Limited. 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
*
* 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 defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#elif defined (__clang__)
#pragma clang system_header /* treat file as system include file */
#endif
#ifndef TZ_CONTEXT_H
#define TZ_CONTEXT_H
#include <stdint.h>
#ifndef TZ_MODULEID_T
#define TZ_MODULEID_T
/// \details Data type that identifies secure software modules called by a process.
typedef uint32_t TZ_ModuleId_t;
#endif
/// \details TZ Memory ID identifies an allocated memory slot.
typedef uint32_t TZ_MemoryId_t;
/// Initialize secure context memory system
/// \return execution status (1: success, 0: error)
uint32_t TZ_InitContextSystem_S (void);
/// Allocate context memory for calling secure software modules in TrustZone
/// \param[in] module identifies software modules called from non-secure mode
/// \return value != 0 id TrustZone memory slot identifier
/// \return value 0 no memory available or internal error
TZ_MemoryId_t TZ_AllocModuleContext_S (TZ_ModuleId_t module);
/// Free context memory that was previously allocated with \ref TZ_AllocModuleContext_S
/// \param[in] id TrustZone memory slot identifier
/// \return execution status (1: success, 0: error)
uint32_t TZ_FreeModuleContext_S (TZ_MemoryId_t id);
/// Load secure context (called on RTOS thread context switch)
/// \param[in] id TrustZone memory slot identifier
/// \return execution status (1: success, 0: error)
uint32_t TZ_LoadContext_S (TZ_MemoryId_t id);
/// Store secure context (called on RTOS thread context switch)
/// \param[in] id TrustZone memory slot identifier
/// \return execution status (1: success, 0: error)
uint32_t TZ_StoreContext_S (TZ_MemoryId_t id);
#endif // TZ_CONTEXT_H
File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More