support imx8mp from wang_guowei

it is OK
This commit is contained in:
xuedongliang 2025-02-28 11:28:33 +08:00
commit fd1e44de35
81 changed files with 152594 additions and 17 deletions

View File

@ -6,7 +6,7 @@ MAKEFLAGS += --no-print-directory
riscv_support := kd233 maix-go hifive1-rev-B gapuino gd32vf103-rvstar rv32m1-vega aiit-riscv64-board xidatong-riscv64 edu-riscv64 ch32v307vct6 ch32v208rbt6 riscv_support := kd233 maix-go hifive1-rev-B gapuino gd32vf103-rvstar rv32m1-vega aiit-riscv64-board xidatong-riscv64 edu-riscv64 ch32v307vct6 ch32v208rbt6
arm_support += stm32f407-st-discovery stm32f407zgt6 stm32f103-nano nuvoton-m2354 ok1052-c imxrt1176-sbc aiit-arm32-board xidatong-arm32 xiwangtong-arm32 edu-arm32 xishutong-arm32 rzv2l-m33 rzg2ul-m33 arm_support += stm32f407-st-discovery stm32f407zgt6 stm32f103-nano nuvoton-m2354 ok1052-c imxrt1176-sbc aiit-arm32-board xidatong-arm32 xiwangtong-arm32 edu-arm32 xishutong-arm32 rzv2l-m33 rzg2ul-m33 imx8mp
emulator_support += hifive1-emulator k210-emulator cortex-m0-emulator cortex-m3-emulator cortex-m4-emulator cortex-m7-emulator emulator_support += hifive1-emulator k210-emulator cortex-m0-emulator cortex-m3-emulator cortex-m4-emulator cortex-m7-emulator
support := $(riscv_support) $(arm_support) $(emulator_support) support := $(riscv_support) $(arm_support) $(emulator_support)

View File

@ -0,0 +1,42 @@
mainmenu "XiZi_IIoT Project Configuration"
config BSP_DIR
string
option env="BSP_ROOT"
default "."
config KERNEL_DIR
string
option env="KERNEL_ROOT"
default "../.."
config BOARD_CORTEX_M7_EVB
bool
select ARCH_ARM
default y
source "$KERNEL_DIR/arch/Kconfig"
menu "imx8mp feature"
menu "config default board resources"
menu "config board app name"
config BOARD_APP_NAME
string "config board app name"
default "/XiUOS_imx8mp_app.bin"
endmenu
menu "config board service table"
config SERVICE_TABLE_ADDRESS
hex "board service table address"
default 0x20000000
endmenu
endmenu
endmenu
menu "Hardware feature"
source "$KERNEL_DIR/resources/Kconfig"
endmenu
source "$KERNEL_DIR/Kconfig"

View File

@ -0,0 +1,5 @@
SRC_FILES := board.c rsc_table.c rpmsg_remote.c
SRC_DIR := third_party_driver rpmsg_lite
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,210 @@
# 从零开始构建矽璓工业物联操作系统使用ARM架构的NXP imx8mp
[XiUOS](http://xuos.io/) (X Industrial Ubiquitous Operating System) 矽璓XiUOS是一款面向智慧车间的工业物联网操作系统主要由一个极简的微型实时操作系统内核和其上的工业物联框架构成通过高效管理工业物联网设备、支撑工业物联应用在生产车间内实现智能化的“感知环境、联网传输、知悉识别、控制调整”促进以工业设备和工业控制系统为核心的人、机、物深度互联帮助提升生产线的数字化和智能化水平。
## 1. 简介
| 硬件 | 描述 |
| -------- | ------------- |
| 芯片型号 | i.MX8MP |
| 架构 | ARM Cortex-M7 |
| 主频 | 最高主频为 800 MHz |
| 片内SRAM | 256 KB |
| 外设支持 | UART |
## 2. 开发环境搭建
### 推荐使用:
**操作系统:** ubuntu18.04 [https://ubuntu.com/download/desktop](https://ubuntu.com/download/desktop)
更新`ubuntu 18.04`源的方法:(根据自身情况而定,可以不更改)
第一步:打开sources.list文件
```c
sudo vim /etc/apt/sources.list
```
第二步:将以下内容复制到sources.list文件
```c
deb http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse
```
第三步:更新源和系统软件
```c
sudo apt-get update
sudo apt-get upgrade
```
**开发工具推荐使用 VSCode VScode下载地址为** VSCode [https://code.visualstudio.com/](https://code.visualstudio.com/),推荐下载地址为 [http://vscode.cdn.azure.cn/stable/3c4e3df9e89829dce27b7b5c24508306b151f30d/code_1.55.2-1618307277_amd64.deb](http://vscode.cdn.azure.cn/stable/3c4e3df9e89829dce27b7b5c24508306b151f30d/code_1.55.2-1618307277_amd64.deb)
### 依赖包安装:
```
$ sudo apt install build-essential pkg-config git
$ sudo apt install gcc make libncurses5-dev openssl libssl-dev bison flex libelf-dev autoconf libtool gperf libc6-dev
```
**XiUOS操作系统源码下载** XiUOS [https://www.gitlink.org.cn/xuos/xiuos](https://www.gitlink.org.cn/xuos/xiuos)
新建一个空文件夹并进入文件夹中,并下载源码,具体命令如下:
```c
mkdir test && cd test
git clone https://gitlink.org.cn/xuos/xiuos.git
```
1、打开XiUOS源码文件包可以看到以下目录
| 名称 | 说明 |
| -- | -- |
| APP_Framework | 应用代码 |
| Ubiquitous | 板级支持包,支持NuttX、RT-Thread和XiZi内核 |
2、打开XiZi内核源码文件包可以看到以下目录
| 名称 | 说明 |
| -- | -- |
| arch | 架构代码 |
| board | 板级支持包 |
| fs | 文件系统 |
| kernel | 内核源码 |
| lib | 第三方库源码 |
| resources | 驱动文件 |
| tool | 系统工具 |
使用VScode打开代码具体操作步骤为在源码文件夹下打开系统终端输入`code .`即可打开VScode开发环境如下图所示
<div align= "center">
<img src="img/vscode.jpg" width =1000>
</div>
### 裁减配置工具的下载
裁减配置工具:
**工具地址:** kconfig-frontends [https://www.gitlink.org.cn/xuos/kconfig-frontends](https://www.gitlink.org.cn/xuos/kconfig-frontends),下载与安装的具体命令如下:
```c
mkdir kfrontends && cd kfrontends
git clone https://gitlink.org.cn/xuos/kconfig-frontends.git
```
下载源码后按以下步骤执行软件安装:
```c
cd kconfig-frontends
./xs_build.sh
```
### 编译工具链:
ARM arm-none-eabi(`gcc version 6.3.1`)默认安装到Ubuntu的/usr/bin/arm-none-eabi-,使用如下命令行下载和安装。
```shell
$ sudo apt install gcc-arm-none-eabi
```
## 3. 编译说明
### 编辑环境:`Ubuntu18.04`
### 编译工具链:`arm-none-eabi-gcc`
使用`VScode`打开工程的方法有多种,本文介绍一种快捷键,在项目目录下将`code .`输入linux系统命令终端即可打开目标项目
编译步骤:
1.在VScode命令终端中执行以下命令生成配置文件
```c
cd ./Ubiquitous/XiZi
make BOARD=imx8mp distclean
make BOARD=imx8mp menuconfig
```
2.在menuconfig界面配置需要关闭和开启的功能按回车键进入下级菜单按Y键选中需要开启的功能按N键选中需要关闭的功能配置结束后保存并退出本例旨在演示简单的输出例程所以没有需要配置的选项双击快捷键ESC退出配置
<div align= "center">
<img src="img/menuconfig.png" width =1000>
</div>
退出时选择`yes`保存上面所配置的内容,如下图所示:
<div align= "center">
<img src="img/menuconfig1.png" width =1000>
</div>
3.继续执行以下命令,进行编译
```
make BOARD=imx8mp
```
4.如果编译正确无误会产生XiZi-imx8mp.elf、XiZi-imx8mp.bin文件。
## 4. 运行
### 4.1 运行方式
imx8mp开发板通过sd卡启动sd卡中需要事先烧好uboot镜像和一个文件系统并将XiZi-imx8mp.bin文件保存到文件系统中。之后启动开发板用uboot在cortex-M7核执行例程程序运行在DRAM命令如下
```
fatload mmc 1:1 0x80000000 XiZi-imx8mp.bin
dcache flush
bootaux 0x80000000
```
### 4.2 运行结果
运行起来后将会在UART4串口上看到如下信息
<div align= "center">
<img src="img/terminal.png" width =1000>
</div>
### 4.3 运行rpmsg例程
目前支持在M核上运行rpmsg例程与A核上的Linux应用程序通过RPMsg通信。具体方式如下
1. 首先通过上述步骤通过uboot在M核上运行XiUOS然后在letter shell中输入CreateRPMsgTask按下回车启动rpmsg例程。例程将等待A核上的Linux初始化RPMsg通信通道。
2. 通过uboot在A核上启动LinuxLinux启动后执行示例程序。
3. 在Linux端可观察到
<div align= "center">
<img src="img/linux.png" width =1000>
</div>
4. 在XiUOS上可观察到
<div align= "center">
<img src="img/xiuos.png" width =1000>
</div>
* 通信流程图
<div align= "center">
<img src="img/rpmsg.png" width =1000>
</div>

View File

@ -0,0 +1,229 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/*************************************************
File name: board.c
Description: support NXP.imx8mp-board init configure and driver/task/... init
Others:
History:
1. Date: 2025-02-26
Author: AIIT XUOS Lab
Modification:
1. support NXP.imx8mp-board InitBoardHardware
*************************************************/
#include "clock_config.h"
#include "board.h"
#include "fsl_rdc.h"
#include "pin_mux.h"
#include "fsl_clock.h"
#include <device.h>
#include "rsc_table.h"
#include "xs_base.h"
#include <connect_uart.h>
#define BOARD_IMX8MP
extern void MU1_M7_IRQHandler(int irqn, void *arg);
DECLARE_HW_IRQ(MU1_M7_IRQn, MU1_M7_IRQHandler, NONE);
extern int rpmsg_remote(void);
void BOARD_ConfigMPU(void)
{
/* __CACHE_REGION_START and __CACHE_REGION_SIZE are defined in the linker file */
extern uint32_t __CACHE_REGION_START[];
extern uint32_t __CACHE_REGION_SIZE[];
uint32_t cacheStart = (uint32_t)__CACHE_REGION_START;
uint32_t size = (uint32_t)__CACHE_REGION_SIZE;
uint32_t i = 0;
/* Disable I cache and D cache */
if (SCB_CCR_IC_Msk == (SCB_CCR_IC_Msk & SCB->CCR))
{
SCB_DisableICache();
}
if (SCB_CCR_DC_Msk == (SCB_CCR_DC_Msk & SCB->CCR))
{
SCB_DisableDCache();
}
/* Disable MPU */
ARM_MPU_Disable();
/* MPU configure:
* Use ARM_MPU_RASR(DisableExec, AccessPermission, TypeExtField, IsShareable, IsCacheable, IsBufferable,
* SubRegionDisable, Size)
* API in mpu_armv7.h.
* param DisableExec Instruction access (XN) disable bit,0=instruction fetches enabled, 1=instruction fetches
* disabled.
* param AccessPermission Data access permissions, allows you to configure read/write access for User and
* Privileged mode.
* Use MACROS defined in mpu_armv7.h:
* ARM_MPU_AP_NONE/ARM_MPU_AP_PRIV/ARM_MPU_AP_URO/ARM_MPU_AP_FULL/ARM_MPU_AP_PRO/ARM_MPU_AP_RO
* Combine TypeExtField/IsShareable/IsCacheable/IsBufferable to configure MPU memory access attributes.
* TypeExtField IsShareable IsCacheable IsBufferable Memory Attribtue Shareability Cache
* 0 x 0 0 Strongly Ordered shareable
* 0 x 0 1 Device shareable
* 0 0 1 0 Normal not shareable Outer and inner write
* through no write allocate
* 0 0 1 1 Normal not shareable Outer and inner write
* back no write allocate
* 0 1 1 0 Normal shareable Outer and inner write
* through no write allocate
* 0 1 1 1 Normal shareable Outer and inner write
* back no write allocate
* 1 0 0 0 Normal not shareable outer and inner
* noncache
* 1 1 0 0 Normal shareable outer and inner
* noncache
* 1 0 1 1 Normal not shareable outer and inner write
* back write/read acllocate
* 1 1 1 1 Normal shareable outer and inner write
* back write/read acllocate
* 2 x 0 0 Device not shareable
* Above are normal use settings, if your want to see more details or want to config different inner/outter cache
* policy.
* please refer to Table 4-55 /4-56 in arm cortex-M7 generic user guide <dui0646b_cortex_m7_dgug.pdf>
* param SubRegionDisable Sub-region disable field. 0=sub-region is enabled, 1=sub-region is disabled.
* param Size Region size of the region to be configured. use ARM_MPU_REGION_SIZE_xxx MACRO in
* mpu_armv7.h.
*/
/* Region 0 [0x0000_0000 - 0x4000_0000] : Memory with Device type, not executable, not shareable, non-cacheable. */
MPU->RBAR = ARM_MPU_RBAR(0, 0x00000000U);
MPU->RASR = ARM_MPU_RASR(1, ARM_MPU_AP_FULL, 0, 0, 0, 1, 0, ARM_MPU_REGION_SIZE_1GB);
/* Region 1 TCML[0x0000_0000 - 0x0001_FFFF]: Memory with Normal type, not shareable, non-cacheable */
MPU->RBAR = ARM_MPU_RBAR(1, 0x00000000U);
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 1, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_128KB);
/* Region 2 QSPI[0x0800_0000 - 0x0FFF_FFFF]: Memory with Normal type, not shareable, cacheable */
MPU->RBAR = ARM_MPU_RBAR(2, 0x08000000U);
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 1, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_128MB);
/* Region 3 TCMU[0x2000_0000 - 0x2002_0000]: Memory with Normal type, not shareable, non-cacheable */
MPU->RBAR = ARM_MPU_RBAR(3, 0x20000000U);
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 1, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_128KB);
/* Region 4 DDR[0x4000_0000 - 0x8000_0000]: Memory with Normal type, not shareable, non-cacheable */
MPU->RBAR = ARM_MPU_RBAR(4, 0x40000000U);
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 1, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_1GB);
/*
Non-cacheable area is provided in DDR memory, the DDR region [0x80000000 ~ 0x81000000](please see the
imx8mp-evk-rpmsg.dts) totally 16MB is revserved for CM7 core. You can put global or static uninitialized
variables in NonCacheable section(initialized variables in NonCacheable.init section) to make them uncacheable.
Since the base address of MPU region should be multiples of region size, to make it simple, the MPU region 5 set
the address space 0x80000000 ~ 0xBFFFFFFF to be non-cacheable. Then MPU region 6 set the text and data section to
be cacheable if the program running on DDR. The cacheable area base address should be multiples of its size in
linker file, they can be modified per your needs.
*/
/* Region 5 DDR[0x8000_0000 - 0xBFFFFFFF]: Memory with Normal type, not shareable, non-cacheable */
MPU->RBAR = ARM_MPU_RBAR(5, 0x80000000U);
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 1, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_1GB);
while ((size >> i) > 0x1U)
{
i++;
}
/* If run on DDR, configure text and data section to be cacheable */
if (i != 0)
{
/* The MPU region size should be 2^N, 5<=N<=32, region base should be multiples of size. */
assert((size & (size - 1)) == 0);
assert(!(cacheStart % size));
assert(size == (uint32_t)(1 << i));
assert(i >= 5);
/* Region 6 DDR[cacheStart]: Memory with Normal type, not shareable, cacheable */
MPU->RBAR = ARM_MPU_RBAR(6, cacheStart);
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 1, 0, 1, 1, 0, (i - 1));
}
/*
* Enable MPU and HFNMIENA feature
* HFNMIENA ensures that M7 core uses MPU configuration when in hard fault, NMI, and FAULTMASK handlers,
* otherwise all memory regions are accessed without MPU protection, which has high risks of cacheable,
* especially for AIPS systems.
*/
ARM_MPU_Enable(MPU_CTRL_PRIVDEFENA_Msk | MPU_CTRL_HFNMIENA_Msk);
/* Enable I cache and D cache */
SCB_EnableICache();
SCB_EnableDCache();
}
void BOARD_RdcInit(void)
{
/* Move M7 core to specific RDC domain 1 */
rdc_domain_assignment_t assignment = {0};
assignment.domainId = BOARD_DOMAIN_ID;
RDC_SetMasterDomainAssignment(RDC, kRDC_Master_M7, &assignment);
/*
* The M7 core is running at domain 1, now enable the clock gate of the following IP/BUS/PLL in domain 1 in the CCM.
* In this way, to ensure the clock of the peripherals used by M core not be affected by A core which is running at
* domain 0.
*/
CLOCK_EnableClock(kCLOCK_Iomux);
CLOCK_EnableClock(kCLOCK_Ipmux1);
CLOCK_EnableClock(kCLOCK_Ipmux2);
CLOCK_EnableClock(kCLOCK_Ipmux3);
#if defined(FLASH_TARGET)
CLOCK_EnableClock(kCLOCK_Qspi);
#endif
CLOCK_ControlGate(kCLOCK_SysPll1Gate, kCLOCK_ClockNeededAll); /* Enable the CCGR gate for SysPLL1 in Domain 1 */
CLOCK_ControlGate(kCLOCK_SysPll2Gate, kCLOCK_ClockNeededAll); /* Enable the CCGR gate for SysPLL2 in Domain 1 */
CLOCK_ControlGate(kCLOCK_SysPll3Gate, kCLOCK_ClockNeededAll); /* Enable the CCGR gate for SysPLL3 in Domain 1 */
CLOCK_ControlGate(kCLOCK_AudioPll1Gate, kCLOCK_ClockNeededAll); /* Enable the CCGR gate for AudioPLL1 in Domain 1 */
CLOCK_ControlGate(kCLOCK_AudioPll2Gate, kCLOCK_ClockNeededAll); /* Enable the CCGR gate for AudioPLL2 in Domain 1 */
CLOCK_ControlGate(kCLOCK_VideoPll1Gate, kCLOCK_ClockNeededAll); /* Enable the CCGR gate for VideoPLL1 in Domain 1 */
}
/* This is the timer interrupt service routine. */
void SysTick_Handler(int irqn, void *arg)
{
TickAndTaskTimesliceUpdate();
}
/**
* This function will initial imx8mp board.
*/
void InitBoardHardware()
{
char ch;
/* Init board hardware. */
/* M7 has its local cache and enabled by default,
* need to set smart subsystems (0x28000000 ~ 0x3FFFFFFF)
* non-cacheable before accessing this address region */
BOARD_ConfigMPU();
/* Board specific RDC settings */
BOARD_RdcInit();
BOARD_InitPins();
BOARD_BootClockRUN();
SysTick_Config(SystemCoreClock / TICK_PER_SECOND);
InitBoardMemory((void *)HEAP_BEGIN, (void *)HEAP_END);
HwUartInit();
InstallConsole(KERNEL_CONSOLE_BUS_NAME, KERNEL_CONSOLE_DRV_NAME, KERNEL_CONSOLE_DEVICE_NAME);
KPrintf("\nconsole init completed.\n");
copyResourceTable();
KPrintf("board init done.\n");
KPrintf("start kernel...\n");
}

View File

@ -0,0 +1,15 @@
export CROSS_COMPILE ?=/usr/bin/arm-none-eabi-
export CFLAGS := -mcpu=cortex-m7 -mthumb -ffunction-sections -fdata-sections -mfloat-abi=hard -mfpu=fpv5-sp-d16 -Dgcc -O0 -g -gdwarf-2 -fgnu89-inline -Wa,-mimplicit-it=thumb
export LFLAGS += -mcpu=cortex-m7 -mthumb -ffunction-sections -fdata-sections -mfloat-abi=hard -mfpu=fpv5-sp-d16 -Wl,--gc-sections,-Map=imx8mp.map,-cref,-u,Reset_Handler -T $(BSP_ROOT)/link.lds
export AFLAGS := -c -mcpu=cortex-m7 -mthumb -ffunction-sections -fdata-sections -mfloat-abi=hard -mfpu=fpv5-sp-d16 -x assembler-with-cpp -Wa,-mimplicit-it=thumb -gdwarf-2
export CXXFLAGS := -mcpu=cortex-m7 -mthumb -ffunction-sections -fdata-sections -Dgcc -O0 -gdwarf-2 -g
export APPLFLAGS := -mcpu=cortex-m7 -mthumb -ffunction-sections -fdata-sections -Wl,--gc-sections,-Map=XiZi-app.map,-cref,-u, -T $(BSP_ROOT)/link.lds
export DEFINES := -DHAVE_CCONFIG_H -D__STARTUP_INITIALIZE_NONCACHEDATA -D__STARTUP_CLEAR_BSS -DNDEBUG -DCPU_MIMX8ML8DVNLZ -DPRINTF_FLOAT_ENABLE=0 -DSCANF_FLOAT_ENABLE=0 -DPRINTF_ADVANCED_ENABLE=0 -DSCANF_ADVANCED_ENABLE=0 -DSERIAL_PORT_TYPE_UART=1
export ARCH = arm
export MCU = cortex-m7

Binary file not shown.

After

Width:  |  Height:  |  Size: 657 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 612 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 621 KiB

View File

@ -0,0 +1,66 @@
/*
* Copyright 2019-2020 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _BOARD_H_
#define _BOARD_H_
#include "clock_config.h"
#include "fsl_clock.h"
#include "fsl_audiomix.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @brief The board name */
#define BOARD_NAME "MIMX8MP-EVK"
#define MANUFACTURER_NAME "NXP"
#define BOARD_DOMAIN_ID (1U)
/* The UART to use for debug messages. */
#define BOARD_DEBUG_UART_TYPE kSerialPort_Uart
#define BOARD_DEBUG_UART_BAUDRATE (115200U)
#define BOARD_DEBUG_UART_BASEADDR UART4_BASE
#define BOARD_DEBUG_UART_INSTANCE (4U)
#define BOARD_DEBUG_UART_CLK_FREQ \
CLOCK_GetPllFreq(kCLOCK_SystemPll1Ctrl) / (CLOCK_GetRootPreDivider(kCLOCK_RootUart4)) / \
(CLOCK_GetRootPostDivider(kCLOCK_RootUart4)) / 10
#define BOARD_UART_IRQ UART4_IRQn
#define BOARD_UART_IRQ_HANDLER UART4_IRQHandler
#define BOARD_GPC_BASEADDR GPC
#define BOARD_MU_IRQ MU1_M7_IRQn
#define BOARD_CODEC_I2C I2C3
#define BOARD_CODEC_I2C_INSTANCE (3U)
#define BOARD_CODEC_I2C_CLOCK_FREQ (16000000U)
/* Shared memory base for RPMsg communication. */
#define VDEV0_VRING_BASE (0x55000000U)
#define RESOURCE_TABLE_OFFSET (0xFF000)
extern int __HeapBase;
extern int __HeapLimit;
#define HEAP_BEGIN (&__HeapBase)
#define HEAP_END (&__HeapLimit)
#define HEAP_SIZE ((uint32_t)HEAP_END - (uint32_t)HEAP_BEGIN)
#if defined(__cplusplus)
extern "C" {
#endif /* __cplusplus */
/*******************************************************************************
* API
******************************************************************************/
void BOARD_InitDebugConsole(void);
void BOARD_InitMemory(void);
void BOARD_RdcInit(void);
void InitBoardHardware();
#if defined(__cplusplus)
}
#endif /* __cplusplus */
#endif /* _BOARD_H_ */

View File

@ -0,0 +1,918 @@
/*
* Copyright 2019-2020 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_IOMUXC_H_
#define _FSL_IOMUXC_H_
#include "fsl_common.h"
/*!
* @addtogroup iomuxc_driver
* @{
*/
/*! @file */
/*******************************************************************************
* Definitions
******************************************************************************/
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.iomuxc"
#endif
/*! @name Driver version */
/*@{*/
/*! @brief IOMUXC driver version 2.0.4. */
#define FSL_IOMUXC_DRIVER_VERSION (MAKE_VERSION(2, 0, 4))
/*@}*/
/*!
* @name Pin function ID
* The pin function ID is a tuple of \<muxRegister muxMode inputRegister inputDaisy configRegister\>
*
* @{
*/
#define IOMUXC_BOOT_MODE0_SRC_BOOT_MODE0 0x00000000, 0x0, 0x00000000, 0x0, 0x30330250
#define IOMUXC_BOOT_MODE1_SRC_BOOT_MODE1 0x00000000, 0x0, 0x00000000, 0x0, 0x30330254
#define IOMUXC_BOOT_MODE2_SRC_BOOT_MODE2 0x00000000, 0x0, 0x00000000, 0x0, 0x30330258
#define IOMUXC_BOOT_MODE3_SRC_BOOT_MODE3 0x00000000, 0x0, 0x00000000, 0x0, 0x3033025C
#define IOMUXC_JTAG_MOD_JTAG_MODE 0x00000000, 0x0, 0x00000000, 0x0, 0x30330260
#define IOMUXC_JTAG_TDI_JTAG_TDI 0x00000000, 0x0, 0x00000000, 0x0, 0x30330264
#define IOMUXC_JTAG_TMS_JTAG_TMS 0x00000000, 0x0, 0x00000000, 0x0, 0x30330268
#define IOMUXC_JTAG_TCK_JTAG_TCK 0x00000000, 0x0, 0x00000000, 0x0, 0x3033026C
#define IOMUXC_JTAG_TDO_JTAG_TDO 0x00000000, 0x0, 0x00000000, 0x0, 0x30330270
#define IOMUXC_RTC_XTALI_SNVS_RTC 0x00000000, 0x0, 0x00000000, 0x0, 0x00000000
#define IOMUXC_PMIC_STBY_REQ_CCM_PMIC_STBY_REQ 0x00000000, 0x0, 0x00000000, 0x0, 0x00000000
#define IOMUXC_PMIC_ON_REQ_SNVS_PMIC_ON_REQ 0x00000000, 0x0, 0x00000000, 0x0, 0x00000000
#define IOMUXC_ONOFF_SNVS_ONOFF 0x00000000, 0x0, 0x00000000, 0x0, 0x00000000
#define IOMUXC_POR_B_SNVS_POR_B 0x00000000, 0x0, 0x00000000, 0x0, 0x00000000
#define IOMUXC_GPIO1_IO00_GPIO1_IO00 0x30330014, 0x0, 0x00000000, 0x0, 0x30330274
#define IOMUXC_GPIO1_IO00_CCM_ENET_PHY_REF_CLK_ROOT 0x30330014, 0x1, 0x00000000, 0x0, 0x30330274
#define IOMUXC_GPIO1_IO00_ISP_FL_TRIG_0 0x30330014, 0x3, 0x303305D4, 0x0, 0x30330274
#define IOMUXC_GPIO1_IO00_ANAMIX_REF_CLK_32K 0x30330014, 0x5, 0x00000000, 0x0, 0x30330274
#define IOMUXC_GPIO1_IO00_CCM_EXT_CLK1 0x30330014, 0x6, 0x00000000, 0x0, 0x30330274
#define IOMUXC_GPIO1_IO01_GPIO1_IO01 0x30330018, 0x0, 0x00000000, 0x0, 0x30330278
#define IOMUXC_GPIO1_IO01_PWM1_OUT 0x30330018, 0x1, 0x00000000, 0x0, 0x30330278
#define IOMUXC_GPIO1_IO01_ISP_SHUTTER_TRIG_0 0x30330018, 0x3, 0x303305DC, 0x0, 0x30330278
#define IOMUXC_GPIO1_IO01_ANAMIX_REF_CLK_24M 0x30330018, 0x5, 0x00000000, 0x0, 0x30330278
#define IOMUXC_GPIO1_IO01_CCM_EXT_CLK2 0x30330018, 0x6, 0x00000000, 0x0, 0x30330278
#define IOMUXC_GPIO1_IO02_GPIO1_IO02 0x3033001C, 0x0, 0x00000000, 0x0, 0x3033027C
#define IOMUXC_GPIO1_IO02_WDOG1_WDOG_B 0x3033001C, 0x1, 0x00000000, 0x0, 0x3033027C
#define IOMUXC_GPIO1_IO02_ISP_FLASH_TRIG_0 0x3033001C, 0x3, 0x00000000, 0x0, 0x3033027C
#define IOMUXC_GPIO1_IO02_WDOG1_WDOG_ANY 0x3033001C, 0x5, 0x00000000, 0x0, 0x3033027C
#define IOMUXC_GPIO1_IO02_SJC_DE_B 0x3033001C, 0x7, 0x00000000, 0x0, 0x3033027C
#define IOMUXC_GPIO1_IO03_GPIO1_IO03 0x30330020, 0x0, 0x00000000, 0x0, 0x30330280
#define IOMUXC_GPIO1_IO03_USDHC1_VSELECT 0x30330020, 0x1, 0x00000000, 0x0, 0x30330280
#define IOMUXC_GPIO1_IO03_ISP_PRELIGHT_TRIG_0 0x30330020, 0x3, 0x00000000, 0x0, 0x30330280
#define IOMUXC_GPIO1_IO03_SDMA1_EXT_EVENT0 0x30330020, 0x5, 0x00000000, 0x0, 0x30330280
#define IOMUXC_GPIO1_IO04_GPIO1_IO04 0x30330024, 0x0, 0x00000000, 0x0, 0x30330284
#define IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x30330024, 0x1, 0x00000000, 0x0, 0x30330284
#define IOMUXC_GPIO1_IO04_ISP_SHUTTER_OPEN_0 0x30330024, 0x3, 0x00000000, 0x0, 0x30330284
#define IOMUXC_GPIO1_IO04_SDMA1_EXT_EVENT1 0x30330024, 0x5, 0x00000000, 0x0, 0x30330284
#define IOMUXC_GPIO1_IO05_GPIO1_IO05 0x30330028, 0x0, 0x00000000, 0x0, 0x30330288
#define IOMUXC_GPIO1_IO05_M7_NMI 0x30330028, 0x1, 0x00000000, 0x0, 0x30330288
#define IOMUXC_GPIO1_IO05_ISP_FL_TRIG_1 0x30330028, 0x3, 0x303305D8, 0x0, 0x30330288
#define IOMUXC_GPIO1_IO05_CCM_PMIC_READY 0x30330028, 0x5, 0x30330554, 0x0, 0x30330288
#define IOMUXC_GPIO1_IO06_GPIO1_IO06 0x3033002C, 0x0, 0x00000000, 0x0, 0x3033028C
#define IOMUXC_GPIO1_IO06_ENET_QOS_MDC 0x3033002C, 0x1, 0x00000000, 0x0, 0x3033028C
#define IOMUXC_GPIO1_IO06_ISP_SHUTTER_TRIG_1 0x3033002C, 0x3, 0x303305E0, 0x0, 0x3033028C
#define IOMUXC_GPIO1_IO06_USDHC1_CD_B 0x3033002C, 0x5, 0x00000000, 0x0, 0x3033028C
#define IOMUXC_GPIO1_IO06_CCM_EXT_CLK3 0x3033002C, 0x6, 0x00000000, 0x0, 0x3033028C
#define IOMUXC_GPIO1_IO07_GPIO1_IO07 0x30330030, 0x0, 0x00000000, 0x0, 0x30330290
#define IOMUXC_GPIO1_IO07_ENET_QOS_MDIO 0x30330030, 0x1, 0x30330590, 0x0, 0x30330290
#define IOMUXC_GPIO1_IO07_ISP_FLASH_TRIG_1 0x30330030, 0x3, 0x00000000, 0x0, 0x30330290
#define IOMUXC_GPIO1_IO07_USDHC1_WP 0x30330030, 0x5, 0x00000000, 0x0, 0x30330290
#define IOMUXC_GPIO1_IO07_CCM_EXT_CLK4 0x30330030, 0x6, 0x00000000, 0x0, 0x30330290
#define IOMUXC_GPIO1_IO08_GPIO1_IO08 0x30330034, 0x0, 0x00000000, 0x0, 0x30330294
#define IOMUXC_GPIO1_IO08_ENET_QOS_1588_EVENT0_IN 0x30330034, 0x1, 0x00000000, 0x0, 0x30330294
#define IOMUXC_GPIO1_IO08_PWM1_OUT 0x30330034, 0x2, 0x00000000, 0x0, 0x30330294
#define IOMUXC_GPIO1_IO08_ISP_PRELIGHT_TRIG_1 0x30330034, 0x3, 0x00000000, 0x0, 0x30330294
#define IOMUXC_GPIO1_IO08_ENET_QOS_1588_EVENT0_AUX_IN 0x30330034, 0x4, 0x00000000, 0x0, 0x30330294
#define IOMUXC_GPIO1_IO08_USDHC2_RESET_B 0x30330034, 0x5, 0x00000000, 0x0, 0x30330294
#define IOMUXC_GPIO1_IO09_GPIO1_IO09 0x30330038, 0x0, 0x00000000, 0x0, 0x30330298
#define IOMUXC_GPIO1_IO09_ENET_QOS_1588_EVENT0_OUT 0x30330038, 0x1, 0x00000000, 0x0, 0x30330298
#define IOMUXC_GPIO1_IO09_PWM2_OUT 0x30330038, 0x2, 0x00000000, 0x0, 0x30330298
#define IOMUXC_GPIO1_IO09_ISP_SHUTTER_OPEN_1 0x30330038, 0x3, 0x00000000, 0x0, 0x30330298
#define IOMUXC_GPIO1_IO09_USDHC3_RESET_B 0x30330038, 0x4, 0x00000000, 0x0, 0x30330298
#define IOMUXC_GPIO1_IO09_SDMA2_EXT_EVENT0 0x30330038, 0x5, 0x00000000, 0x0, 0x30330298
#define IOMUXC_GPIO1_IO10_GPIO1_IO10 0x3033003C, 0x0, 0x00000000, 0x0, 0x3033029C
#define IOMUXC_GPIO1_IO10_USB1_ID 0x3033003C, 0x1, 0x00000000, 0x0, 0x3033029C
#define IOMUXC_GPIO1_IO10_PWM3_OUT 0x3033003C, 0x2, 0x00000000, 0x0, 0x3033029C
#define IOMUXC_GPIO1_IO11_GPIO1_IO11 0x30330040, 0x0, 0x00000000, 0x0, 0x303302A0
#define IOMUXC_GPIO1_IO11_USB2_ID 0x30330040, 0x1, 0x00000000, 0x0, 0x303302A0
#define IOMUXC_GPIO1_IO11_PWM2_OUT 0x30330040, 0x2, 0x00000000, 0x0, 0x303302A0
#define IOMUXC_GPIO1_IO11_USDHC3_VSELECT 0x30330040, 0x4, 0x00000000, 0x0, 0x303302A0
#define IOMUXC_GPIO1_IO11_CCM_PMIC_READY 0x30330040, 0x5, 0x30330554, 0x1, 0x303302A0
#define IOMUXC_GPIO1_IO12_GPIO1_IO12 0x30330044, 0x0, 0x00000000, 0x0, 0x303302A4
#define IOMUXC_GPIO1_IO12_USB1_PWR 0x30330044, 0x1, 0x00000000, 0x0, 0x303302A4
#define IOMUXC_GPIO1_IO12_SDMA2_EXT_EVENT1 0x30330044, 0x5, 0x00000000, 0x0, 0x303302A4
#define IOMUXC_GPIO1_IO13_GPIO1_IO13 0x30330048, 0x0, 0x00000000, 0x0, 0x303302A8
#define IOMUXC_GPIO1_IO13_USB1_OC 0x30330048, 0x1, 0x00000000, 0x0, 0x303302A8
#define IOMUXC_GPIO1_IO13_PWM2_OUT 0x30330048, 0x5, 0x00000000, 0x0, 0x303302A8
#define IOMUXC_GPIO1_IO14_GPIO1_IO14 0x3033004C, 0x0, 0x00000000, 0x0, 0x303302AC
#define IOMUXC_GPIO1_IO14_USB2_PWR 0x3033004C, 0x1, 0x00000000, 0x0, 0x303302AC
#define IOMUXC_GPIO1_IO14_USDHC3_CD_B 0x3033004C, 0x4, 0x30330608, 0x0, 0x303302AC
#define IOMUXC_GPIO1_IO14_PWM3_OUT 0x3033004C, 0x5, 0x00000000, 0x0, 0x303302AC
#define IOMUXC_GPIO1_IO14_CCM_CLKO1 0x3033004C, 0x6, 0x00000000, 0x0, 0x303302AC
#define IOMUXC_GPIO1_IO15_GPIO1_IO15 0x30330050, 0x0, 0x00000000, 0x0, 0x303302B0
#define IOMUXC_GPIO1_IO15_USB2_OC 0x30330050, 0x1, 0x00000000, 0x0, 0x303302B0
#define IOMUXC_GPIO1_IO15_USDHC3_WP 0x30330050, 0x4, 0x30330634, 0x0, 0x303302B0
#define IOMUXC_GPIO1_IO15_PWM4_OUT 0x30330050, 0x5, 0x00000000, 0x0, 0x303302B0
#define IOMUXC_GPIO1_IO15_CCM_CLKO2 0x30330050, 0x6, 0x00000000, 0x0, 0x303302B0
#define IOMUXC_ENET_MDC_ENET_QOS_MDC 0x30330054, 0x0, 0x00000000, 0x0, 0x303302B4
#define IOMUXC_ENET_MDC_AUDIOMIX_SAI6_TX_DATA0 0x30330054, 0x2, 0x00000000, 0x0, 0x303302B4
#define IOMUXC_ENET_MDC_GPIO1_IO16 0x30330054, 0x5, 0x00000000, 0x0, 0x303302B4
#define IOMUXC_ENET_MDC_USDHC3_STROBE 0x30330054, 0x6, 0x30330630, 0x0, 0x303302B4
#define IOMUXC_ENET_MDIO_ENET_QOS_MDIO 0x30330058, 0x0, 0x30330590, 0x1, 0x303302B8
#define IOMUXC_ENET_MDIO_AUDIOMIX_SAI6_TX_SYNC 0x30330058, 0x2, 0x30330528, 0x0, 0x303302B8
#define IOMUXC_ENET_MDIO_AUDIOMIX_PDM_BIT_STREAM3 0x30330058, 0x3, 0x303304CC, 0x0, 0x303302B8
#define IOMUXC_ENET_MDIO_GPIO1_IO17 0x30330058, 0x5, 0x00000000, 0x0, 0x303302B8
#define IOMUXC_ENET_MDIO_USDHC3_DATA5 0x30330058, 0x6, 0x30330624, 0x0, 0x303302B8
#define IOMUXC_ENET_TD3_ENET_QOS_RGMII_TD3 0x3033005C, 0x0, 0x00000000, 0x0, 0x303302BC
#define IOMUXC_ENET_TD3_AUDIOMIX_SAI6_TX_BCLK 0x3033005C, 0x2, 0x30330524, 0x0, 0x303302BC
#define IOMUXC_ENET_TD3_AUDIOMIX_PDM_BIT_STREAM2 0x3033005C, 0x3, 0x303304C8, 0x0, 0x303302BC
#define IOMUXC_ENET_TD3_GPIO1_IO18 0x3033005C, 0x5, 0x00000000, 0x0, 0x303302BC
#define IOMUXC_ENET_TD3_USDHC3_DATA6 0x3033005C, 0x6, 0x30330628, 0x0, 0x303302BC
#define IOMUXC_ENET_TD2_ENET_QOS_RGMII_TD2 0x30330060, 0x0, 0x00000000, 0x0, 0x303302C0
#define IOMUXC_ENET_TD2_CCM_ENET_QOS_CLOCK_GENERATE_REF_CLK 0x30330060, 0x1, 0x00000000, 0x0, 0x303302C0
#define IOMUXC_ENET_TD2_AUDIOMIX_SAI6_RX_DATA0 0x30330060, 0x2, 0x3033051C, 0x0, 0x303302C0
#define IOMUXC_ENET_TD2_AUDIOMIX_PDM_BIT_STREAM1 0x30330060, 0x3, 0x303304C4, 0x0, 0x303302C0
#define IOMUXC_ENET_TD2_GPIO1_IO19 0x30330060, 0x5, 0x00000000, 0x0, 0x303302C0
#define IOMUXC_ENET_TD2_USDHC3_DATA7 0x30330060, 0x6, 0x3033062C, 0x0, 0x303302C0
#define IOMUXC_ENET_TD1_ENET_QOS_RGMII_TD1 0x30330064, 0x0, 0x00000000, 0x0, 0x303302C4
#define IOMUXC_ENET_TD1_AUDIOMIX_SAI6_RX_SYNC 0x30330064, 0x2, 0x30330520, 0x0, 0x303302C4
#define IOMUXC_ENET_TD1_AUDIOMIX_PDM_BIT_STREAM0 0x30330064, 0x3, 0x303304C0, 0x0, 0x303302C4
#define IOMUXC_ENET_TD1_GPIO1_IO20 0x30330064, 0x5, 0x00000000, 0x0, 0x303302C4
#define IOMUXC_ENET_TD1_USDHC3_CD_B 0x30330064, 0x6, 0x30330608, 0x1, 0x303302C4
#define IOMUXC_ENET_TD0_ENET_QOS_RGMII_TD0 0x30330068, 0x0, 0x00000000, 0x0, 0x303302C8
#define IOMUXC_ENET_TD0_AUDIOMIX_SAI6_RX_BCLK 0x30330068, 0x2, 0x30330518, 0x0, 0x303302C8
#define IOMUXC_ENET_TD0_AUDIOMIX_PDM_CLK 0x30330068, 0x3, 0x00000000, 0x0, 0x303302C8
#define IOMUXC_ENET_TD0_GPIO1_IO21 0x30330068, 0x5, 0x00000000, 0x0, 0x303302C8
#define IOMUXC_ENET_TD0_USDHC3_WP 0x30330068, 0x6, 0x30330634, 0x1, 0x303302C8
#define IOMUXC_ENET_TX_CTL_ENET_QOS_RGMII_TX_CTL 0x3033006C, 0x0, 0x00000000, 0x0, 0x303302CC
#define IOMUXC_ENET_TX_CTL_AUDIOMIX_SAI6_MCLK 0x3033006C, 0x2, 0x30330514, 0x0, 0x303302CC
#define IOMUXC_ENET_TX_CTL_AUDIOMIX_SPDIF1_OUT 0x3033006C, 0x3, 0x00000000, 0x0, 0x303302CC
#define IOMUXC_ENET_TX_CTL_GPIO1_IO22 0x3033006C, 0x5, 0x00000000, 0x0, 0x303302CC
#define IOMUXC_ENET_TX_CTL_USDHC3_DATA0 0x3033006C, 0x6, 0x30330610, 0x0, 0x303302CC
#define IOMUXC_ENET_TXC_CCM_ENET_QOS_CLOCK_GENERATE_TX_CLK 0x30330070, 0x0, 0x00000000, 0x0, 0x303302D0
#define IOMUXC_ENET_TXC_ENET_QOS_TX_ER 0x30330070, 0x1, 0x00000000, 0x0, 0x303302D0
#define IOMUXC_ENET_TXC_AUDIOMIX_SAI7_TX_DATA0 0x30330070, 0x2, 0x00000000, 0x0, 0x303302D0
#define IOMUXC_ENET_TXC_GPIO1_IO23 0x30330070, 0x5, 0x00000000, 0x0, 0x303302D0
#define IOMUXC_ENET_TXC_USDHC3_DATA1 0x30330070, 0x6, 0x30330614, 0x0, 0x303302D0
#define IOMUXC_ENET_RX_CTL_ENET_QOS_RGMII_RX_CTL 0x30330074, 0x0, 0x00000000, 0x0, 0x303302D4
#define IOMUXC_ENET_RX_CTL_AUDIOMIX_SAI7_TX_SYNC 0x30330074, 0x2, 0x30330540, 0x0, 0x303302D4
#define IOMUXC_ENET_RX_CTL_AUDIOMIX_PDM_BIT_STREAM3 0x30330074, 0x3, 0x303304CC, 0x1, 0x303302D4
#define IOMUXC_ENET_RX_CTL_GPIO1_IO24 0x30330074, 0x5, 0x00000000, 0x0, 0x303302D4
#define IOMUXC_ENET_RX_CTL_USDHC3_DATA2 0x30330074, 0x6, 0x30330618, 0x0, 0x303302D4
#define IOMUXC_ENET_RXC_CCM_ENET_QOS_CLOCK_GENERATE_RX_CLK 0x30330078, 0x0, 0x00000000, 0x0, 0x303302D8
#define IOMUXC_ENET_RXC_ENET_QOS_RX_ER 0x30330078, 0x1, 0x00000000, 0x0, 0x303302D8
#define IOMUXC_ENET_RXC_AUDIOMIX_SAI7_TX_BCLK 0x30330078, 0x2, 0x3033053C, 0x0, 0x303302D8
#define IOMUXC_ENET_RXC_AUDIOMIX_PDM_BIT_STREAM2 0x30330078, 0x3, 0x303304C8, 0x1, 0x303302D8
#define IOMUXC_ENET_RXC_GPIO1_IO25 0x30330078, 0x5, 0x00000000, 0x0, 0x303302D8
#define IOMUXC_ENET_RXC_USDHC3_DATA3 0x30330078, 0x6, 0x3033061C, 0x0, 0x303302D8
#define IOMUXC_ENET_RD0_ENET_QOS_RGMII_RD0 0x3033007C, 0x0, 0x00000000, 0x0, 0x303302DC
#define IOMUXC_ENET_RD0_AUDIOMIX_SAI7_RX_DATA0 0x3033007C, 0x2, 0x30330534, 0x0, 0x303302DC
#define IOMUXC_ENET_RD0_AUDIOMIX_PDM_BIT_STREAM1 0x3033007C, 0x3, 0x303304C4, 0x1, 0x303302DC
#define IOMUXC_ENET_RD0_GPIO1_IO26 0x3033007C, 0x5, 0x00000000, 0x0, 0x303302DC
#define IOMUXC_ENET_RD0_USDHC3_DATA4 0x3033007C, 0x6, 0x30330620, 0x0, 0x303302DC
#define IOMUXC_ENET_RD1_ENET_QOS_RGMII_RD1 0x30330080, 0x0, 0x00000000, 0x0, 0x303302E0
#define IOMUXC_ENET_RD1_AUDIOMIX_SAI7_RX_SYNC 0x30330080, 0x2, 0x30330538, 0x0, 0x303302E0
#define IOMUXC_ENET_RD1_AUDIOMIX_PDM_BIT_STREAM0 0x30330080, 0x3, 0x303304C0, 0x1, 0x303302E0
#define IOMUXC_ENET_RD1_GPIO1_IO27 0x30330080, 0x5, 0x00000000, 0x0, 0x303302E0
#define IOMUXC_ENET_RD1_USDHC3_RESET_B 0x30330080, 0x6, 0x00000000, 0x0, 0x303302E0
#define IOMUXC_ENET_RD2_ENET_QOS_RGMII_RD2 0x30330084, 0x0, 0x00000000, 0x0, 0x303302E4
#define IOMUXC_ENET_RD2_AUDIOMIX_SAI7_RX_BCLK 0x30330084, 0x2, 0x30330530, 0x0, 0x303302E4
#define IOMUXC_ENET_RD2_AUDIOMIX_PDM_CLK 0x30330084, 0x3, 0x00000000, 0x0, 0x303302E4
#define IOMUXC_ENET_RD2_GPIO1_IO28 0x30330084, 0x5, 0x00000000, 0x0, 0x303302E4
#define IOMUXC_ENET_RD2_USDHC3_CLK 0x30330084, 0x6, 0x30330604, 0x0, 0x303302E4
#define IOMUXC_ENET_RD3_ENET_QOS_RGMII_RD3 0x30330088, 0x0, 0x00000000, 0x0, 0x303302E8
#define IOMUXC_ENET_RD3_AUDIOMIX_SAI7_MCLK 0x30330088, 0x2, 0x3033052C, 0x0, 0x303302E8
#define IOMUXC_ENET_RD3_AUDIOMIX_SPDIF1_IN 0x30330088, 0x3, 0x30330544, 0x0, 0x303302E8
#define IOMUXC_ENET_RD3_GPIO1_IO29 0x30330088, 0x5, 0x00000000, 0x0, 0x303302E8
#define IOMUXC_ENET_RD3_USDHC3_CMD 0x30330088, 0x6, 0x3033060C, 0x0, 0x303302E8
#define IOMUXC_SD1_CLK_USDHC1_CLK 0x3033008C, 0x0, 0x00000000, 0x0, 0x303302EC
#define IOMUXC_SD1_CLK_ENET1_MDC 0x3033008C, 0x1, 0x00000000, 0x0, 0x303302EC
#define IOMUXC_SD1_CLK_I2C5_SCL 0x3033008C, 0x3, 0x303305C4, 0x0, 0x303302EC
#define IOMUXC_SD1_CLK_UART1_TX 0x3033008C, 0x4, 0x00000000, 0x0, 0x303302EC
#define IOMUXC_SD1_CLK_UART1_RX 0x3033008C, 0x4, 0x303305E8, 0x0, 0x303302EC
#define IOMUXC_SD1_CLK_GPIO2_IO00 0x3033008C, 0x5, 0x00000000, 0x0, 0x303302EC
#define IOMUXC_SD1_CMD_USDHC1_CMD 0x30330090, 0x0, 0x00000000, 0x0, 0x303302F0
#define IOMUXC_SD1_CMD_ENET1_MDIO 0x30330090, 0x1, 0x3033057C, 0x0, 0x303302F0
#define IOMUXC_SD1_CMD_I2C5_SDA 0x30330090, 0x3, 0x303305C8, 0x0, 0x303302F0
#define IOMUXC_SD1_CMD_UART1_RX 0x30330090, 0x4, 0x303305E8, 0x1, 0x303302F0
#define IOMUXC_SD1_CMD_UART1_TX 0x30330090, 0x4, 0x00000000, 0x0, 0x303302F0
#define IOMUXC_SD1_CMD_GPIO2_IO01 0x30330090, 0x5, 0x00000000, 0x0, 0x303302F0
#define IOMUXC_SD1_DATA0_USDHC1_DATA0 0x30330094, 0x0, 0x00000000, 0x0, 0x303302F4
#define IOMUXC_SD1_DATA0_ENET1_RGMII_TD1 0x30330094, 0x1, 0x00000000, 0x0, 0x303302F4
#define IOMUXC_SD1_DATA0_I2C6_SCL 0x30330094, 0x3, 0x303305CC, 0x0, 0x303302F4
#define IOMUXC_SD1_DATA0_UART1_RTS_B 0x30330094, 0x4, 0x303305E4, 0x0, 0x303302F4
#define IOMUXC_SD1_DATA0_UART1_CTS_B 0x30330094, 0x4, 0x00000000, 0x0, 0x303302F4
#define IOMUXC_SD1_DATA0_GPIO2_IO02 0x30330094, 0x5, 0x00000000, 0x0, 0x303302F4
#define IOMUXC_SD1_DATA1_USDHC1_DATA1 0x30330098, 0x0, 0x00000000, 0x0, 0x303302F8
#define IOMUXC_SD1_DATA1_ENET1_RGMII_TD0 0x30330098, 0x1, 0x00000000, 0x0, 0x303302F8
#define IOMUXC_SD1_DATA1_I2C6_SDA 0x30330098, 0x3, 0x303305D0, 0x0, 0x303302F8
#define IOMUXC_SD1_DATA1_UART1_CTS_B 0x30330098, 0x4, 0x00000000, 0x0, 0x303302F8
#define IOMUXC_SD1_DATA1_UART1_RTS_B 0x30330098, 0x4, 0x303305E4, 0x1, 0x303302F8
#define IOMUXC_SD1_DATA1_GPIO2_IO03 0x30330098, 0x5, 0x00000000, 0x0, 0x303302F8
#define IOMUXC_SD1_DATA2_USDHC1_DATA2 0x3033009C, 0x0, 0x00000000, 0x0, 0x303302FC
#define IOMUXC_SD1_DATA2_ENET1_RGMII_RD0 0x3033009C, 0x1, 0x30330580, 0x0, 0x303302FC
#define IOMUXC_SD1_DATA2_I2C4_SCL 0x3033009C, 0x3, 0x303305BC, 0x0, 0x303302FC
#define IOMUXC_SD1_DATA2_UART2_TX 0x3033009C, 0x4, 0x00000000, 0x0, 0x303302FC
#define IOMUXC_SD1_DATA2_UART2_RX 0x3033009C, 0x4, 0x303305F0, 0x0, 0x303302FC
#define IOMUXC_SD1_DATA2_GPIO2_IO04 0x3033009C, 0x5, 0x00000000, 0x0, 0x303302FC
#define IOMUXC_SD1_DATA3_USDHC1_DATA3 0x303300A0, 0x0, 0x00000000, 0x0, 0x30330300
#define IOMUXC_SD1_DATA3_ENET1_RGMII_RD1 0x303300A0, 0x1, 0x30330584, 0x0, 0x30330300
#define IOMUXC_SD1_DATA3_I2C4_SDA 0x303300A0, 0x3, 0x303305C0, 0x0, 0x30330300
#define IOMUXC_SD1_DATA3_UART2_RX 0x303300A0, 0x4, 0x303305F0, 0x1, 0x30330300
#define IOMUXC_SD1_DATA3_UART2_TX 0x303300A0, 0x4, 0x00000000, 0x0, 0x30330300
#define IOMUXC_SD1_DATA3_GPIO2_IO05 0x303300A0, 0x5, 0x00000000, 0x0, 0x30330300
#define IOMUXC_SD1_DATA4_USDHC1_DATA4 0x303300A4, 0x0, 0x00000000, 0x0, 0x30330304
#define IOMUXC_SD1_DATA4_ENET1_RGMII_TX_CTL 0x303300A4, 0x1, 0x00000000, 0x0, 0x30330304
#define IOMUXC_SD1_DATA4_I2C1_SCL 0x303300A4, 0x3, 0x303305A4, 0x0, 0x30330304
#define IOMUXC_SD1_DATA4_UART2_RTS_B 0x303300A4, 0x4, 0x303305EC, 0x0, 0x30330304
#define IOMUXC_SD1_DATA4_UART2_CTS_B 0x303300A4, 0x4, 0x00000000, 0x0, 0x30330304
#define IOMUXC_SD1_DATA4_GPIO2_IO06 0x303300A4, 0x5, 0x00000000, 0x0, 0x30330304
#define IOMUXC_SD1_DATA5_USDHC1_DATA5 0x303300A8, 0x0, 0x00000000, 0x0, 0x30330308
#define IOMUXC_SD1_DATA5_ENET1_TX_ER 0x303300A8, 0x1, 0x00000000, 0x0, 0x30330308
#define IOMUXC_SD1_DATA5_I2C1_SDA 0x303300A8, 0x3, 0x303305A8, 0x0, 0x30330308
#define IOMUXC_SD1_DATA5_UART2_CTS_B 0x303300A8, 0x4, 0x00000000, 0x0, 0x30330308
#define IOMUXC_SD1_DATA5_UART2_RTS_B 0x303300A8, 0x4, 0x303305EC, 0x1, 0x30330308
#define IOMUXC_SD1_DATA5_GPIO2_IO07 0x303300A8, 0x5, 0x00000000, 0x0, 0x30330308
#define IOMUXC_SD1_DATA6_USDHC1_DATA6 0x303300AC, 0x0, 0x00000000, 0x0, 0x3033030C
#define IOMUXC_SD1_DATA6_ENET1_RGMII_RX_CTL 0x303300AC, 0x1, 0x30330588, 0x0, 0x3033030C
#define IOMUXC_SD1_DATA6_I2C2_SCL 0x303300AC, 0x3, 0x303305AC, 0x0, 0x3033030C
#define IOMUXC_SD1_DATA6_UART3_TX 0x303300AC, 0x4, 0x00000000, 0x0, 0x3033030C
#define IOMUXC_SD1_DATA6_UART3_RX 0x303300AC, 0x4, 0x303305F8, 0x0, 0x3033030C
#define IOMUXC_SD1_DATA6_GPIO2_IO08 0x303300AC, 0x5, 0x00000000, 0x0, 0x3033030C
#define IOMUXC_SD1_DATA7_USDHC1_DATA7 0x303300B0, 0x0, 0x00000000, 0x0, 0x30330310
#define IOMUXC_SD1_DATA7_ENET1_RX_ER 0x303300B0, 0x1, 0x3033058C, 0x0, 0x30330310
#define IOMUXC_SD1_DATA7_I2C2_SDA 0x303300B0, 0x3, 0x303305B0, 0x0, 0x30330310
#define IOMUXC_SD1_DATA7_UART3_RX 0x303300B0, 0x4, 0x303305F8, 0x1, 0x30330310
#define IOMUXC_SD1_DATA7_UART3_TX 0x303300B0, 0x4, 0x00000000, 0x0, 0x30330310
#define IOMUXC_SD1_DATA7_GPIO2_IO09 0x303300B0, 0x5, 0x00000000, 0x0, 0x30330310
#define IOMUXC_SD1_RESET_B_USDHC1_RESET_B 0x303300B4, 0x0, 0x00000000, 0x0, 0x30330314
#define IOMUXC_SD1_RESET_B_ENET1_TX_CLK 0x303300B4, 0x1, 0x30330578, 0x0, 0x30330314
#define IOMUXC_SD1_RESET_B_I2C3_SCL 0x303300B4, 0x3, 0x303305B4, 0x0, 0x30330314
#define IOMUXC_SD1_RESET_B_UART3_RTS_B 0x303300B4, 0x4, 0x303305F4, 0x0, 0x30330314
#define IOMUXC_SD1_RESET_B_UART3_CTS_B 0x303300B4, 0x4, 0x00000000, 0x0, 0x30330314
#define IOMUXC_SD1_RESET_B_GPIO2_IO10 0x303300B4, 0x5, 0x00000000, 0x0, 0x30330314
#define IOMUXC_SD1_STROBE_USDHC1_STROBE 0x303300B8, 0x0, 0x00000000, 0x0, 0x30330318
#define IOMUXC_SD1_STROBE_I2C3_SDA 0x303300B8, 0x3, 0x303305B8, 0x0, 0x30330318
#define IOMUXC_SD1_STROBE_UART3_CTS_B 0x303300B8, 0x4, 0x00000000, 0x0, 0x30330318
#define IOMUXC_SD1_STROBE_UART3_RTS_B 0x303300B8, 0x4, 0x303305F4, 0x1, 0x30330318
#define IOMUXC_SD1_STROBE_GPIO2_IO11 0x303300B8, 0x5, 0x00000000, 0x0, 0x30330318
#define IOMUXC_SD2_CD_B_USDHC2_CD_B 0x303300BC, 0x0, 0x00000000, 0x0, 0x3033031C
#define IOMUXC_SD2_CD_B_GPIO2_IO12 0x303300BC, 0x5, 0x00000000, 0x0, 0x3033031C
#define IOMUXC_SD2_CLK_USDHC2_CLK 0x303300C0, 0x0, 0x00000000, 0x0, 0x30330320
#define IOMUXC_SD2_CLK_ECSPI2_SCLK 0x303300C0, 0x2, 0x30330568, 0x0, 0x30330320
#define IOMUXC_SD2_CLK_UART4_RX 0x303300C0, 0x3, 0x30330600, 0x0, 0x30330320
#define IOMUXC_SD2_CLK_UART4_TX 0x303300C0, 0x3, 0x00000000, 0x0, 0x30330320
#define IOMUXC_SD2_CLK_GPIO2_IO13 0x303300C0, 0x5, 0x00000000, 0x0, 0x30330320
#define IOMUXC_SD2_CMD_USDHC2_CMD 0x303300C4, 0x0, 0x00000000, 0x0, 0x30330324
#define IOMUXC_SD2_CMD_ECSPI2_MOSI 0x303300C4, 0x2, 0x30330570, 0x0, 0x30330324
#define IOMUXC_SD2_CMD_UART4_TX 0x303300C4, 0x3, 0x00000000, 0x0, 0x30330324
#define IOMUXC_SD2_CMD_UART4_RX 0x303300C4, 0x3, 0x30330600, 0x1, 0x30330324
#define IOMUXC_SD2_CMD_AUDIOMIX_PDM_CLK 0x303300C4, 0x4, 0x00000000, 0x0, 0x30330324
#define IOMUXC_SD2_CMD_GPIO2_IO14 0x303300C4, 0x5, 0x00000000, 0x0, 0x30330324
#define IOMUXC_SD2_DATA0_USDHC2_DATA0 0x303300C8, 0x0, 0x00000000, 0x0, 0x30330328
#define IOMUXC_SD2_DATA0_I2C4_SDA 0x303300C8, 0x2, 0x303305C0, 0x1, 0x30330328
#define IOMUXC_SD2_DATA0_UART2_RX 0x303300C8, 0x3, 0x303305F0, 0x2, 0x30330328
#define IOMUXC_SD2_DATA0_UART2_TX 0x303300C8, 0x3, 0x00000000, 0x0, 0x30330328
#define IOMUXC_SD2_DATA0_AUDIOMIX_PDM_BIT_STREAM0 0x303300C8, 0x4, 0x303304C0, 0x2, 0x30330328
#define IOMUXC_SD2_DATA0_GPIO2_IO15 0x303300C8, 0x5, 0x00000000, 0x0, 0x30330328
#define IOMUXC_SD2_DATA1_USDHC2_DATA1 0x303300CC, 0x0, 0x00000000, 0x0, 0x3033032C
#define IOMUXC_SD2_DATA1_I2C4_SCL 0x303300CC, 0x2, 0x303305BC, 0x1, 0x3033032C
#define IOMUXC_SD2_DATA1_UART2_TX 0x303300CC, 0x3, 0x00000000, 0x0, 0x3033032C
#define IOMUXC_SD2_DATA1_UART2_RX 0x303300CC, 0x3, 0x303305F0, 0x3, 0x3033032C
#define IOMUXC_SD2_DATA1_AUDIOMIX_PDM_BIT_STREAM1 0x303300CC, 0x4, 0x303304C4, 0x2, 0x3033032C
#define IOMUXC_SD2_DATA1_GPIO2_IO16 0x303300CC, 0x5, 0x00000000, 0x0, 0x3033032C
#define IOMUXC_SD2_DATA2_USDHC2_DATA2 0x303300D0, 0x0, 0x00000000, 0x0, 0x30330330
#define IOMUXC_SD2_DATA2_ECSPI2_SS0 0x303300D0, 0x2, 0x30330574, 0x0, 0x30330330
#define IOMUXC_SD2_DATA2_AUDIOMIX_SPDIF1_OUT 0x303300D0, 0x3, 0x00000000, 0x0, 0x30330330
#define IOMUXC_SD2_DATA2_AUDIOMIX_PDM_BIT_STREAM2 0x303300D0, 0x4, 0x303304C8, 0x2, 0x30330330
#define IOMUXC_SD2_DATA2_GPIO2_IO17 0x303300D0, 0x5, 0x00000000, 0x0, 0x30330330
#define IOMUXC_SD2_DATA3_USDHC2_DATA3 0x303300D4, 0x0, 0x00000000, 0x0, 0x30330334
#define IOMUXC_SD2_DATA3_ECSPI2_MISO 0x303300D4, 0x2, 0x3033056C, 0x0, 0x30330334
#define IOMUXC_SD2_DATA3_AUDIOMIX_SPDIF1_IN 0x303300D4, 0x3, 0x30330544, 0x1, 0x30330334
#define IOMUXC_SD2_DATA3_AUDIOMIX_PDM_BIT_STREAM3 0x303300D4, 0x4, 0x303304CC, 0x2, 0x30330334
#define IOMUXC_SD2_DATA3_GPIO2_IO18 0x303300D4, 0x5, 0x00000000, 0x0, 0x30330334
#define IOMUXC_SD2_RESET_B_USDHC2_RESET_B 0x303300D8, 0x0, 0x00000000, 0x0, 0x30330338
#define IOMUXC_SD2_RESET_B_GPIO2_IO19 0x303300D8, 0x5, 0x00000000, 0x0, 0x30330338
#define IOMUXC_SD2_WP_USDHC2_WP 0x303300DC, 0x0, 0x00000000, 0x0, 0x3033033C
#define IOMUXC_SD2_WP_GPIO2_IO20 0x303300DC, 0x5, 0x00000000, 0x0, 0x3033033C
#define IOMUXC_SD2_WP_CORESIGHT_EVENTI 0x303300DC, 0x6, 0x00000000, 0x0, 0x3033033C
#define IOMUXC_NAND_ALE_NAND_ALE 0x303300E0, 0x0, 0x00000000, 0x0, 0x30330340
#define IOMUXC_NAND_ALE_FLEXSPI_A_SCLK 0x303300E0, 0x1, 0x00000000, 0x0, 0x30330340
#define IOMUXC_NAND_ALE_AUDIOMIX_SAI3_TX_BCLK 0x303300E0, 0x2, 0x303304E8, 0x0, 0x30330340
#define IOMUXC_NAND_ALE_ISP_FL_TRIG_0 0x303300E0, 0x3, 0x303305D4, 0x1, 0x30330340
#define IOMUXC_NAND_ALE_UART3_RX 0x303300E0, 0x4, 0x303305F8, 0x2, 0x30330340
#define IOMUXC_NAND_ALE_UART3_TX 0x303300E0, 0x4, 0x00000000, 0x0, 0x30330340
#define IOMUXC_NAND_ALE_GPIO3_IO00 0x303300E0, 0x5, 0x00000000, 0x0, 0x30330340
#define IOMUXC_NAND_ALE_CORESIGHT_TRACE_CLK 0x303300E0, 0x6, 0x00000000, 0x0, 0x30330340
#define IOMUXC_NAND_CE0_B_NAND_CE0_B 0x303300E4, 0x0, 0x00000000, 0x0, 0x30330344
#define IOMUXC_NAND_CE0_B_FLEXSPI_A_SS0_B 0x303300E4, 0x1, 0x00000000, 0x0, 0x30330344
#define IOMUXC_NAND_CE0_B_AUDIOMIX_SAI3_TX_DATA0 0x303300E4, 0x2, 0x00000000, 0x0, 0x30330344
#define IOMUXC_NAND_CE0_B_ISP_SHUTTER_TRIG_0 0x303300E4, 0x3, 0x303305DC, 0x1, 0x30330344
#define IOMUXC_NAND_CE0_B_UART3_TX 0x303300E4, 0x4, 0x00000000, 0x0, 0x30330344
#define IOMUXC_NAND_CE0_B_UART3_RX 0x303300E4, 0x4, 0x303305F8, 0x3, 0x30330344
#define IOMUXC_NAND_CE0_B_GPIO3_IO01 0x303300E4, 0x5, 0x00000000, 0x0, 0x30330344
#define IOMUXC_NAND_CE0_B_CORESIGHT_TRACE_CTL 0x303300E4, 0x6, 0x00000000, 0x0, 0x30330344
#define IOMUXC_NAND_CE1_B_NAND_CE1_B 0x303300E8, 0x0, 0x00000000, 0x0, 0x30330348
#define IOMUXC_NAND_CE1_B_FLEXSPI_A_SS1_B 0x303300E8, 0x1, 0x00000000, 0x0, 0x30330348
#define IOMUXC_NAND_CE1_B_USDHC3_STROBE 0x303300E8, 0x2, 0x30330630, 0x1, 0x30330348
#define IOMUXC_NAND_CE1_B_I2C4_SCL 0x303300E8, 0x4, 0x303305BC, 0x2, 0x30330348
#define IOMUXC_NAND_CE1_B_GPIO3_IO02 0x303300E8, 0x5, 0x00000000, 0x0, 0x30330348
#define IOMUXC_NAND_CE1_B_CORESIGHT_TRACE00 0x303300E8, 0x6, 0x00000000, 0x0, 0x30330348
#define IOMUXC_NAND_CE2_B_NAND_CE2_B 0x303300EC, 0x0, 0x00000000, 0x0, 0x3033034C
#define IOMUXC_NAND_CE2_B_FLEXSPI_B_SS0_B 0x303300EC, 0x1, 0x00000000, 0x0, 0x3033034C
#define IOMUXC_NAND_CE2_B_USDHC3_DATA5 0x303300EC, 0x2, 0x30330624, 0x1, 0x3033034C
#define IOMUXC_NAND_CE2_B_I2C4_SDA 0x303300EC, 0x4, 0x303305C0, 0x2, 0x3033034C
#define IOMUXC_NAND_CE2_B_GPIO3_IO03 0x303300EC, 0x5, 0x00000000, 0x0, 0x3033034C
#define IOMUXC_NAND_CE2_B_CORESIGHT_TRACE01 0x303300EC, 0x6, 0x00000000, 0x0, 0x3033034C
#define IOMUXC_NAND_CE3_B_NAND_CE3_B 0x303300F0, 0x0, 0x00000000, 0x0, 0x30330350
#define IOMUXC_NAND_CE3_B_FLEXSPI_B_SS1_B 0x303300F0, 0x1, 0x00000000, 0x0, 0x30330350
#define IOMUXC_NAND_CE3_B_USDHC3_DATA6 0x303300F0, 0x2, 0x30330628, 0x1, 0x30330350
#define IOMUXC_NAND_CE3_B_I2C3_SDA 0x303300F0, 0x4, 0x303305B8, 0x1, 0x30330350
#define IOMUXC_NAND_CE3_B_GPIO3_IO04 0x303300F0, 0x5, 0x00000000, 0x0, 0x30330350
#define IOMUXC_NAND_CE3_B_CORESIGHT_TRACE02 0x303300F0, 0x6, 0x00000000, 0x0, 0x30330350
#define IOMUXC_NAND_CLE_NAND_CLE 0x303300F4, 0x0, 0x00000000, 0x0, 0x30330354
#define IOMUXC_NAND_CLE_FLEXSPI_B_SCLK 0x303300F4, 0x1, 0x00000000, 0x0, 0x30330354
#define IOMUXC_NAND_CLE_USDHC3_DATA7 0x303300F4, 0x2, 0x3033062C, 0x1, 0x30330354
#define IOMUXC_NAND_CLE_UART4_RX 0x303300F4, 0x4, 0x30330600, 0x2, 0x30330354
#define IOMUXC_NAND_CLE_UART4_TX 0x303300F4, 0x4, 0x00000000, 0x0, 0x30330354
#define IOMUXC_NAND_CLE_GPIO3_IO05 0x303300F4, 0x5, 0x00000000, 0x0, 0x30330354
#define IOMUXC_NAND_CLE_CORESIGHT_TRACE03 0x303300F4, 0x6, 0x00000000, 0x0, 0x30330354
#define IOMUXC_NAND_DATA00_NAND_DATA00 0x303300F8, 0x0, 0x00000000, 0x0, 0x30330358
#define IOMUXC_NAND_DATA00_FLEXSPI_A_DATA0 0x303300F8, 0x1, 0x00000000, 0x0, 0x30330358
#define IOMUXC_NAND_DATA00_AUDIOMIX_SAI3_RX_DATA0 0x303300F8, 0x2, 0x303304E4, 0x0, 0x30330358
#define IOMUXC_NAND_DATA00_ISP_FLASH_TRIG_0 0x303300F8, 0x3, 0x00000000, 0x0, 0x30330358
#define IOMUXC_NAND_DATA00_UART4_RX 0x303300F8, 0x4, 0x30330600, 0x3, 0x30330358
#define IOMUXC_NAND_DATA00_UART4_TX 0x303300F8, 0x4, 0x00000000, 0x0, 0x30330358
#define IOMUXC_NAND_DATA00_GPIO3_IO06 0x303300F8, 0x5, 0x00000000, 0x0, 0x30330358
#define IOMUXC_NAND_DATA00_CORESIGHT_TRACE04 0x303300F8, 0x6, 0x00000000, 0x0, 0x30330358
#define IOMUXC_NAND_DATA01_NAND_DATA01 0x303300FC, 0x0, 0x00000000, 0x0, 0x3033035C
#define IOMUXC_NAND_DATA01_FLEXSPI_A_DATA1 0x303300FC, 0x1, 0x00000000, 0x0, 0x3033035C
#define IOMUXC_NAND_DATA01_AUDIOMIX_SAI3_TX_SYNC 0x303300FC, 0x2, 0x303304EC, 0x0, 0x3033035C
#define IOMUXC_NAND_DATA01_ISP_PRELIGHT_TRIG_0 0x303300FC, 0x3, 0x00000000, 0x0, 0x3033035C
#define IOMUXC_NAND_DATA01_UART4_TX 0x303300FC, 0x4, 0x00000000, 0x0, 0x3033035C
#define IOMUXC_NAND_DATA01_UART4_RX 0x303300FC, 0x4, 0x30330600, 0x4, 0x3033035C
#define IOMUXC_NAND_DATA01_GPIO3_IO07 0x303300FC, 0x5, 0x00000000, 0x0, 0x3033035C
#define IOMUXC_NAND_DATA01_CORESIGHT_TRACE05 0x303300FC, 0x6, 0x00000000, 0x0, 0x3033035C
#define IOMUXC_NAND_DATA02_NAND_DATA02 0x30330100, 0x0, 0x00000000, 0x0, 0x30330360
#define IOMUXC_NAND_DATA02_FLEXSPI_A_DATA2 0x30330100, 0x1, 0x00000000, 0x0, 0x30330360
#define IOMUXC_NAND_DATA02_USDHC3_CD_B 0x30330100, 0x2, 0x30330608, 0x2, 0x30330360
#define IOMUXC_NAND_DATA02_UART4_CTS_B 0x30330100, 0x3, 0x00000000, 0x0, 0x30330360
#define IOMUXC_NAND_DATA02_UART4_RTS_B 0x30330100, 0x3, 0x303305FC, 0x0, 0x30330360
#define IOMUXC_NAND_DATA02_I2C4_SDA 0x30330100, 0x4, 0x303305C0, 0x3, 0x30330360
#define IOMUXC_NAND_DATA02_GPIO3_IO08 0x30330100, 0x5, 0x00000000, 0x0, 0x30330360
#define IOMUXC_NAND_DATA02_CORESIGHT_TRACE06 0x30330100, 0x6, 0x00000000, 0x0, 0x30330360
#define IOMUXC_NAND_DATA03_NAND_DATA03 0x30330104, 0x0, 0x00000000, 0x0, 0x30330364
#define IOMUXC_NAND_DATA03_FLEXSPI_A_DATA3 0x30330104, 0x1, 0x00000000, 0x0, 0x30330364
#define IOMUXC_NAND_DATA03_USDHC3_WP 0x30330104, 0x2, 0x30330634, 0x2, 0x30330364
#define IOMUXC_NAND_DATA03_UART4_RTS_B 0x30330104, 0x3, 0x303305FC, 0x1, 0x30330364
#define IOMUXC_NAND_DATA03_UART4_CTS_B 0x30330104, 0x3, 0x00000000, 0x0, 0x30330364
#define IOMUXC_NAND_DATA03_ISP_FL_TRIG_1 0x30330104, 0x4, 0x303305D8, 0x1, 0x30330364
#define IOMUXC_NAND_DATA03_GPIO3_IO09 0x30330104, 0x5, 0x00000000, 0x0, 0x30330364
#define IOMUXC_NAND_DATA03_CORESIGHT_TRACE07 0x30330104, 0x6, 0x00000000, 0x0, 0x30330364
#define IOMUXC_NAND_DATA04_NAND_DATA04 0x30330108, 0x0, 0x00000000, 0x0, 0x30330368
#define IOMUXC_NAND_DATA04_FLEXSPI_B_DATA0 0x30330108, 0x1, 0x00000000, 0x0, 0x30330368
#define IOMUXC_NAND_DATA04_USDHC3_DATA0 0x30330108, 0x2, 0x30330610, 0x1, 0x30330368
#define IOMUXC_NAND_DATA04_FLEXSPI_A_DATA4 0x30330108, 0x3, 0x00000000, 0x0, 0x30330368
#define IOMUXC_NAND_DATA04_ISP_SHUTTER_TRIG_1 0x30330108, 0x4, 0x303305E0, 0x1, 0x30330368
#define IOMUXC_NAND_DATA04_GPIO3_IO10 0x30330108, 0x5, 0x00000000, 0x0, 0x30330368
#define IOMUXC_NAND_DATA04_CORESIGHT_TRACE08 0x30330108, 0x6, 0x00000000, 0x0, 0x30330368
#define IOMUXC_NAND_DATA05_NAND_DATA05 0x3033010C, 0x0, 0x00000000, 0x0, 0x3033036C
#define IOMUXC_NAND_DATA05_FLEXSPI_B_DATA1 0x3033010C, 0x1, 0x00000000, 0x0, 0x3033036C
#define IOMUXC_NAND_DATA05_USDHC3_DATA1 0x3033010C, 0x2, 0x30330614, 0x1, 0x3033036C
#define IOMUXC_NAND_DATA05_FLEXSPI_A_DATA5 0x3033010C, 0x3, 0x00000000, 0x0, 0x3033036C
#define IOMUXC_NAND_DATA05_ISP_FLASH_TRIG_1 0x3033010C, 0x4, 0x00000000, 0x0, 0x3033036C
#define IOMUXC_NAND_DATA05_GPIO3_IO11 0x3033010C, 0x5, 0x00000000, 0x0, 0x3033036C
#define IOMUXC_NAND_DATA05_CORESIGHT_TRACE09 0x3033010C, 0x6, 0x00000000, 0x0, 0x3033036C
#define IOMUXC_NAND_DATA06_NAND_DATA06 0x30330110, 0x0, 0x00000000, 0x0, 0x30330370
#define IOMUXC_NAND_DATA06_FLEXSPI_B_DATA2 0x30330110, 0x1, 0x00000000, 0x0, 0x30330370
#define IOMUXC_NAND_DATA06_USDHC3_DATA2 0x30330110, 0x2, 0x30330618, 0x1, 0x30330370
#define IOMUXC_NAND_DATA06_FLEXSPI_A_DATA6 0x30330110, 0x3, 0x00000000, 0x0, 0x30330370
#define IOMUXC_NAND_DATA06_ISP_PRELIGHT_TRIG_1 0x30330110, 0x4, 0x00000000, 0x0, 0x30330370
#define IOMUXC_NAND_DATA06_GPIO3_IO12 0x30330110, 0x5, 0x00000000, 0x0, 0x30330370
#define IOMUXC_NAND_DATA06_CORESIGHT_TRACE10 0x30330110, 0x6, 0x00000000, 0x0, 0x30330370
#define IOMUXC_NAND_DATA07_NAND_DATA07 0x30330114, 0x0, 0x00000000, 0x0, 0x30330374
#define IOMUXC_NAND_DATA07_FLEXSPI_B_DATA3 0x30330114, 0x1, 0x00000000, 0x0, 0x30330374
#define IOMUXC_NAND_DATA07_USDHC3_DATA3 0x30330114, 0x2, 0x3033061C, 0x1, 0x30330374
#define IOMUXC_NAND_DATA07_FLEXSPI_A_DATA7 0x30330114, 0x3, 0x00000000, 0x0, 0x30330374
#define IOMUXC_NAND_DATA07_ISP_SHUTTER_OPEN_1 0x30330114, 0x4, 0x00000000, 0x0, 0x30330374
#define IOMUXC_NAND_DATA07_GPIO3_IO13 0x30330114, 0x5, 0x00000000, 0x0, 0x30330374
#define IOMUXC_NAND_DATA07_CORESIGHT_TRACE11 0x30330114, 0x6, 0x00000000, 0x0, 0x30330374
#define IOMUXC_NAND_DQS_NAND_DQS 0x30330118, 0x0, 0x00000000, 0x0, 0x30330378
#define IOMUXC_NAND_DQS_FLEXSPI_A_DQS 0x30330118, 0x1, 0x00000000, 0x0, 0x30330378
#define IOMUXC_NAND_DQS_AUDIOMIX_SAI3_MCLK 0x30330118, 0x2, 0x303304E0, 0x0, 0x30330378
#define IOMUXC_NAND_DQS_ISP_SHUTTER_OPEN_0 0x30330118, 0x3, 0x00000000, 0x0, 0x30330378
#define IOMUXC_NAND_DQS_I2C3_SCL 0x30330118, 0x4, 0x303305B4, 0x1, 0x30330378
#define IOMUXC_NAND_DQS_GPIO3_IO14 0x30330118, 0x5, 0x00000000, 0x0, 0x30330378
#define IOMUXC_NAND_DQS_CORESIGHT_TRACE12 0x30330118, 0x6, 0x00000000, 0x0, 0x30330378
#define IOMUXC_NAND_RE_B_NAND_RE_B 0x3033011C, 0x0, 0x00000000, 0x0, 0x3033037C
#define IOMUXC_NAND_RE_B_FLEXSPI_B_DQS 0x3033011C, 0x1, 0x00000000, 0x0, 0x3033037C
#define IOMUXC_NAND_RE_B_USDHC3_DATA4 0x3033011C, 0x2, 0x30330620, 0x1, 0x3033037C
#define IOMUXC_NAND_RE_B_UART4_TX 0x3033011C, 0x4, 0x00000000, 0x0, 0x3033037C
#define IOMUXC_NAND_RE_B_UART4_RX 0x3033011C, 0x4, 0x30330600, 0x5, 0x3033037C
#define IOMUXC_NAND_RE_B_GPIO3_IO15 0x3033011C, 0x5, 0x00000000, 0x0, 0x3033037C
#define IOMUXC_NAND_RE_B_CORESIGHT_TRACE13 0x3033011C, 0x6, 0x00000000, 0x0, 0x3033037C
#define IOMUXC_NAND_READY_B_NAND_READY_B 0x30330120, 0x0, 0x00000000, 0x0, 0x30330380
#define IOMUXC_NAND_READY_B_USDHC3_RESET_B 0x30330120, 0x2, 0x00000000, 0x0, 0x30330380
#define IOMUXC_NAND_READY_B_I2C3_SCL 0x30330120, 0x4, 0x303305B4, 0x2, 0x30330380
#define IOMUXC_NAND_READY_B_GPIO3_IO16 0x30330120, 0x5, 0x00000000, 0x0, 0x30330380
#define IOMUXC_NAND_READY_B_CORESIGHT_TRACE14 0x30330120, 0x6, 0x00000000, 0x0, 0x30330380
#define IOMUXC_NAND_WE_B_NAND_WE_B 0x30330124, 0x0, 0x00000000, 0x0, 0x30330384
#define IOMUXC_NAND_WE_B_USDHC3_CLK 0x30330124, 0x2, 0x30330604, 0x1, 0x30330384
#define IOMUXC_NAND_WE_B_I2C3_SDA 0x30330124, 0x4, 0x303305B8, 0x2, 0x30330384
#define IOMUXC_NAND_WE_B_GPIO3_IO17 0x30330124, 0x5, 0x00000000, 0x0, 0x30330384
#define IOMUXC_NAND_WE_B_CORESIGHT_TRACE15 0x30330124, 0x6, 0x00000000, 0x0, 0x30330384
#define IOMUXC_NAND_WP_B_NAND_WP_B 0x30330128, 0x0, 0x00000000, 0x0, 0x30330388
#define IOMUXC_NAND_WP_B_USDHC3_CMD 0x30330128, 0x2, 0x3033060C, 0x1, 0x30330388
#define IOMUXC_NAND_WP_B_I2C4_SCL 0x30330128, 0x4, 0x303305BC, 0x3, 0x30330388
#define IOMUXC_NAND_WP_B_GPIO3_IO18 0x30330128, 0x5, 0x00000000, 0x0, 0x30330388
#define IOMUXC_NAND_WP_B_CORESIGHT_EVENTO 0x30330128, 0x6, 0x00000000, 0x0, 0x30330388
#define IOMUXC_SAI5_RXFS_AUDIOMIX_SAI5_RX_SYNC 0x3033012C, 0x0, 0x30330508, 0x0, 0x3033038C
#define IOMUXC_SAI5_RXFS_AUDIOMIX_SAI1_TX_DATA0 0x3033012C, 0x1, 0x00000000, 0x0, 0x3033038C
#define IOMUXC_SAI5_RXFS_PWM4_OUT 0x3033012C, 0x2, 0x00000000, 0x0, 0x3033038C
#define IOMUXC_SAI5_RXFS_I2C6_SCL 0x3033012C, 0x3, 0x303305CC, 0x1, 0x3033038C
#define IOMUXC_SAI5_RXFS_GPIO3_IO19 0x3033012C, 0x5, 0x00000000, 0x0, 0x3033038C
#define IOMUXC_SAI5_RXC_AUDIOMIX_SAI5_RX_BCLK 0x30330130, 0x0, 0x303304F4, 0x0, 0x30330390
#define IOMUXC_SAI5_RXC_AUDIOMIX_SAI1_TX_DATA1 0x30330130, 0x1, 0x00000000, 0x0, 0x30330390
#define IOMUXC_SAI5_RXC_PWM3_OUT 0x30330130, 0x2, 0x00000000, 0x0, 0x30330390
#define IOMUXC_SAI5_RXC_I2C6_SDA 0x30330130, 0x3, 0x303305D0, 0x1, 0x30330390
#define IOMUXC_SAI5_RXC_AUDIOMIX_PDM_CLK 0x30330130, 0x4, 0x00000000, 0x0, 0x30330390
#define IOMUXC_SAI5_RXC_GPIO3_IO20 0x30330130, 0x5, 0x00000000, 0x0, 0x30330390
#define IOMUXC_SAI5_RXD0_AUDIOMIX_SAI5_RX_DATA0 0x30330134, 0x0, 0x303304F8, 0x0, 0x30330394
#define IOMUXC_SAI5_RXD0_AUDIOMIX_SAI1_TX_DATA2 0x30330134, 0x1, 0x00000000, 0x0, 0x30330394
#define IOMUXC_SAI5_RXD0_PWM2_OUT 0x30330134, 0x2, 0x00000000, 0x0, 0x30330394
#define IOMUXC_SAI5_RXD0_I2C5_SCL 0x30330134, 0x3, 0x303305C4, 0x1, 0x30330394
#define IOMUXC_SAI5_RXD0_AUDIOMIX_PDM_BIT_STREAM0 0x30330134, 0x4, 0x303304C0, 0x3, 0x30330394
#define IOMUXC_SAI5_RXD0_GPIO3_IO21 0x30330134, 0x5, 0x00000000, 0x0, 0x30330394
#define IOMUXC_SAI5_RXD1_AUDIOMIX_SAI5_RX_DATA1 0x30330138, 0x0, 0x303304FC, 0x0, 0x30330398
#define IOMUXC_SAI5_RXD1_AUDIOMIX_SAI1_TX_DATA3 0x30330138, 0x1, 0x00000000, 0x0, 0x30330398
#define IOMUXC_SAI5_RXD1_AUDIOMIX_SAI1_TX_SYNC 0x30330138, 0x2, 0x303304D8, 0x0, 0x30330398
#define IOMUXC_SAI5_RXD1_AUDIOMIX_SAI5_TX_SYNC 0x30330138, 0x3, 0x30330510, 0x0, 0x30330398
#define IOMUXC_SAI5_RXD1_AUDIOMIX_PDM_BIT_STREAM1 0x30330138, 0x4, 0x303304C4, 0x3, 0x30330398
#define IOMUXC_SAI5_RXD1_GPIO3_IO22 0x30330138, 0x5, 0x00000000, 0x0, 0x30330398
#define IOMUXC_SAI5_RXD1_CAN1_TX 0x30330138, 0x6, 0x00000000, 0x0, 0x30330398
#define IOMUXC_SAI5_RXD2_AUDIOMIX_SAI5_RX_DATA2 0x3033013C, 0x0, 0x30330500, 0x0, 0x3033039C
#define IOMUXC_SAI5_RXD2_AUDIOMIX_SAI1_TX_DATA4 0x3033013C, 0x1, 0x00000000, 0x0, 0x3033039C
#define IOMUXC_SAI5_RXD2_AUDIOMIX_SAI1_TX_SYNC 0x3033013C, 0x2, 0x303304D8, 0x1, 0x3033039C
#define IOMUXC_SAI5_RXD2_AUDIOMIX_SAI5_TX_BCLK 0x3033013C, 0x3, 0x3033050C, 0x0, 0x3033039C
#define IOMUXC_SAI5_RXD2_AUDIOMIX_PDM_BIT_STREAM2 0x3033013C, 0x4, 0x303304C8, 0x3, 0x3033039C
#define IOMUXC_SAI5_RXD2_GPIO3_IO23 0x3033013C, 0x5, 0x00000000, 0x0, 0x3033039C
#define IOMUXC_SAI5_RXD2_CAN1_RX 0x3033013C, 0x6, 0x3033054C, 0x0, 0x3033039C
#define IOMUXC_SAI5_RXD3_AUDIOMIX_SAI5_RX_DATA3 0x30330140, 0x0, 0x30330504, 0x0, 0x303303A0
#define IOMUXC_SAI5_RXD3_AUDIOMIX_SAI1_TX_DATA5 0x30330140, 0x1, 0x00000000, 0x0, 0x303303A0
#define IOMUXC_SAI5_RXD3_AUDIOMIX_SAI1_TX_SYNC 0x30330140, 0x2, 0x303304D8, 0x2, 0x303303A0
#define IOMUXC_SAI5_RXD3_AUDIOMIX_SAI5_TX_DATA0 0x30330140, 0x3, 0x00000000, 0x0, 0x303303A0
#define IOMUXC_SAI5_RXD3_AUDIOMIX_PDM_BIT_STREAM3 0x30330140, 0x4, 0x303304CC, 0x3, 0x303303A0
#define IOMUXC_SAI5_RXD3_GPIO3_IO24 0x30330140, 0x5, 0x00000000, 0x0, 0x303303A0
#define IOMUXC_SAI5_RXD3_CAN2_TX 0x30330140, 0x6, 0x00000000, 0x0, 0x303303A0
#define IOMUXC_SAI5_MCLK_AUDIOMIX_SAI5_MCLK 0x30330144, 0x0, 0x303304F0, 0x0, 0x303303A4
#define IOMUXC_SAI5_MCLK_AUDIOMIX_SAI1_TX_BCLK 0x30330144, 0x1, 0x303304D4, 0x0, 0x303303A4
#define IOMUXC_SAI5_MCLK_PWM1_OUT 0x30330144, 0x2, 0x00000000, 0x0, 0x303303A4
#define IOMUXC_SAI5_MCLK_I2C5_SDA 0x30330144, 0x3, 0x303305C8, 0x1, 0x303303A4
#define IOMUXC_SAI5_MCLK_GPIO3_IO25 0x30330144, 0x5, 0x00000000, 0x0, 0x303303A4
#define IOMUXC_SAI5_MCLK_CAN2_RX 0x30330144, 0x6, 0x30330550, 0x0, 0x303303A4
#define IOMUXC_SAI1_RXFS_AUDIOMIX_SAI1_RX_SYNC 0x30330148, 0x0, 0x303304D0, 0x0, 0x303303A8
#define IOMUXC_SAI1_RXFS_ENET1_1588_EVENT0_IN 0x30330148, 0x4, 0x00000000, 0x0, 0x303303A8
#define IOMUXC_SAI1_RXFS_GPIO4_IO00 0x30330148, 0x5, 0x00000000, 0x0, 0x303303A8
#define IOMUXC_SAI1_RXC_AUDIOMIX_SAI1_RX_BCLK 0x3033014C, 0x0, 0x00000000, 0x0, 0x303303AC
#define IOMUXC_SAI1_RXC_AUDIOMIX_PDM_CLK 0x3033014C, 0x3, 0x00000000, 0x0, 0x303303AC
#define IOMUXC_SAI1_RXC_ENET1_1588_EVENT0_OUT 0x3033014C, 0x4, 0x00000000, 0x0, 0x303303AC
#define IOMUXC_SAI1_RXC_GPIO4_IO01 0x3033014C, 0x5, 0x00000000, 0x0, 0x303303AC
#define IOMUXC_SAI1_RXD0_AUDIOMIX_SAI1_RX_DATA0 0x30330150, 0x0, 0x00000000, 0x0, 0x303303B0
#define IOMUXC_SAI1_RXD0_AUDIOMIX_SAI1_TX_DATA1 0x30330150, 0x2, 0x00000000, 0x0, 0x303303B0
#define IOMUXC_SAI1_RXD0_AUDIOMIX_PDM_BIT_STREAM0 0x30330150, 0x3, 0x303304C0, 0x4, 0x303303B0
#define IOMUXC_SAI1_RXD0_ENET1_1588_EVENT1_IN 0x30330150, 0x4, 0x00000000, 0x0, 0x303303B0
#define IOMUXC_SAI1_RXD0_GPIO4_IO02 0x30330150, 0x5, 0x00000000, 0x0, 0x303303B0
#define IOMUXC_SAI1_RXD1_AUDIOMIX_SAI1_RX_DATA1 0x30330154, 0x0, 0x00000000, 0x0, 0x303303B4
#define IOMUXC_SAI1_RXD1_AUDIOMIX_PDM_BIT_STREAM1 0x30330154, 0x3, 0x303304C4, 0x4, 0x303303B4
#define IOMUXC_SAI1_RXD1_ENET1_1588_EVENT1_OUT 0x30330154, 0x4, 0x00000000, 0x0, 0x303303B4
#define IOMUXC_SAI1_RXD1_GPIO4_IO03 0x30330154, 0x5, 0x00000000, 0x0, 0x303303B4
#define IOMUXC_SAI1_RXD2_AUDIOMIX_SAI1_RX_DATA2 0x30330158, 0x0, 0x00000000, 0x0, 0x303303B8
#define IOMUXC_SAI1_RXD2_AUDIOMIX_PDM_BIT_STREAM2 0x30330158, 0x3, 0x303304C8, 0x4, 0x303303B8
#define IOMUXC_SAI1_RXD2_ENET1_MDC 0x30330158, 0x4, 0x00000000, 0x0, 0x303303B8
#define IOMUXC_SAI1_RXD2_GPIO4_IO04 0x30330158, 0x5, 0x00000000, 0x0, 0x303303B8
#define IOMUXC_SAI1_RXD3_AUDIOMIX_SAI1_RX_DATA3 0x3033015C, 0x0, 0x00000000, 0x0, 0x303303BC
#define IOMUXC_SAI1_RXD3_AUDIOMIX_PDM_BIT_STREAM3 0x3033015C, 0x3, 0x303304CC, 0x4, 0x303303BC
#define IOMUXC_SAI1_RXD3_ENET1_MDIO 0x3033015C, 0x4, 0x3033057C, 0x1, 0x303303BC
#define IOMUXC_SAI1_RXD3_GPIO4_IO05 0x3033015C, 0x5, 0x00000000, 0x0, 0x303303BC
#define IOMUXC_SAI1_RXD4_AUDIOMIX_SAI1_RX_DATA4 0x30330160, 0x0, 0x00000000, 0x0, 0x303303C0
#define IOMUXC_SAI1_RXD4_AUDIOMIX_SAI6_TX_BCLK 0x30330160, 0x1, 0x30330524, 0x1, 0x303303C0
#define IOMUXC_SAI1_RXD4_AUDIOMIX_SAI6_RX_BCLK 0x30330160, 0x2, 0x30330518, 0x1, 0x303303C0
#define IOMUXC_SAI1_RXD4_ENET1_RGMII_RD0 0x30330160, 0x4, 0x30330580, 0x1, 0x303303C0
#define IOMUXC_SAI1_RXD4_GPIO4_IO06 0x30330160, 0x5, 0x00000000, 0x0, 0x303303C0
#define IOMUXC_SAI1_RXD5_AUDIOMIX_SAI1_RX_DATA5 0x30330164, 0x0, 0x00000000, 0x0, 0x303303C4
#define IOMUXC_SAI1_RXD5_AUDIOMIX_SAI6_TX_DATA0 0x30330164, 0x1, 0x00000000, 0x0, 0x303303C4
#define IOMUXC_SAI1_RXD5_AUDIOMIX_SAI6_RX_DATA0 0x30330164, 0x2, 0x3033051C, 0x1, 0x303303C4
#define IOMUXC_SAI1_RXD5_AUDIOMIX_SAI1_RX_SYNC 0x30330164, 0x3, 0x303304D0, 0x1, 0x303303C4
#define IOMUXC_SAI1_RXD5_ENET1_RGMII_RD1 0x30330164, 0x4, 0x30330584, 0x1, 0x303303C4
#define IOMUXC_SAI1_RXD5_GPIO4_IO07 0x30330164, 0x5, 0x00000000, 0x0, 0x303303C4
#define IOMUXC_SAI1_RXD6_AUDIOMIX_SAI1_RX_DATA6 0x30330168, 0x0, 0x00000000, 0x0, 0x303303C8
#define IOMUXC_SAI1_RXD6_AUDIOMIX_SAI6_TX_SYNC 0x30330168, 0x1, 0x30330528, 0x1, 0x303303C8
#define IOMUXC_SAI1_RXD6_AUDIOMIX_SAI6_RX_SYNC 0x30330168, 0x2, 0x30330520, 0x1, 0x303303C8
#define IOMUXC_SAI1_RXD6_ENET1_RGMII_RD2 0x30330168, 0x4, 0x00000000, 0x0, 0x303303C8
#define IOMUXC_SAI1_RXD6_GPIO4_IO08 0x30330168, 0x5, 0x00000000, 0x0, 0x303303C8
#define IOMUXC_SAI1_RXD7_AUDIOMIX_SAI1_RX_DATA7 0x3033016C, 0x0, 0x00000000, 0x0, 0x303303CC
#define IOMUXC_SAI1_RXD7_AUDIOMIX_SAI6_MCLK 0x3033016C, 0x1, 0x30330514, 0x1, 0x303303CC
#define IOMUXC_SAI1_RXD7_AUDIOMIX_SAI1_TX_SYNC 0x3033016C, 0x2, 0x303304D8, 0x3, 0x303303CC
#define IOMUXC_SAI1_RXD7_AUDIOMIX_SAI1_TX_DATA4 0x3033016C, 0x3, 0x00000000, 0x0, 0x303303CC
#define IOMUXC_SAI1_RXD7_ENET1_RGMII_RD3 0x3033016C, 0x4, 0x00000000, 0x0, 0x303303CC
#define IOMUXC_SAI1_RXD7_GPIO4_IO09 0x3033016C, 0x5, 0x00000000, 0x0, 0x303303CC
#define IOMUXC_SAI1_TXFS_AUDIOMIX_SAI1_TX_SYNC 0x30330170, 0x0, 0x303304D8, 0x4, 0x303303D0
#define IOMUXC_SAI1_TXFS_ENET1_RGMII_RX_CTL 0x30330170, 0x4, 0x30330588, 0x1, 0x303303D0
#define IOMUXC_SAI1_TXFS_GPIO4_IO10 0x30330170, 0x5, 0x00000000, 0x0, 0x303303D0
#define IOMUXC_SAI1_TXC_AUDIOMIX_SAI1_TX_BCLK 0x30330174, 0x0, 0x303304D4, 0x1, 0x303303D4
#define IOMUXC_SAI1_TXC_ENET1_RGMII_RXC 0x30330174, 0x4, 0x00000000, 0x0, 0x303303D4
#define IOMUXC_SAI1_TXC_GPIO4_IO11 0x30330174, 0x5, 0x00000000, 0x0, 0x303303D4
#define IOMUXC_SAI1_TXD0_AUDIOMIX_SAI1_TX_DATA0 0x30330178, 0x0, 0x00000000, 0x0, 0x303303D8
#define IOMUXC_SAI1_TXD0_ENET1_RGMII_TD0 0x30330178, 0x4, 0x00000000, 0x0, 0x303303D8
#define IOMUXC_SAI1_TXD0_GPIO4_IO12 0x30330178, 0x5, 0x00000000, 0x0, 0x303303D8
#define IOMUXC_SAI1_TXD1_AUDIOMIX_SAI1_TX_DATA1 0x3033017C, 0x0, 0x00000000, 0x0, 0x303303DC
#define IOMUXC_SAI1_TXD1_ENET1_RGMII_TD1 0x3033017C, 0x4, 0x00000000, 0x0, 0x303303DC
#define IOMUXC_SAI1_TXD1_GPIO4_IO13 0x3033017C, 0x5, 0x00000000, 0x0, 0x303303DC
#define IOMUXC_SAI1_TXD2_AUDIOMIX_SAI1_TX_DATA2 0x30330180, 0x0, 0x00000000, 0x0, 0x303303E0
#define IOMUXC_SAI1_TXD2_ENET1_RGMII_TD2 0x30330180, 0x4, 0x00000000, 0x0, 0x303303E0
#define IOMUXC_SAI1_TXD2_GPIO4_IO14 0x30330180, 0x5, 0x00000000, 0x0, 0x303303E0
#define IOMUXC_SAI1_TXD3_AUDIOMIX_SAI1_TX_DATA3 0x30330184, 0x0, 0x00000000, 0x0, 0x303303E4
#define IOMUXC_SAI1_TXD3_ENET1_RGMII_TD3 0x30330184, 0x4, 0x00000000, 0x0, 0x303303E4
#define IOMUXC_SAI1_TXD3_GPIO4_IO15 0x30330184, 0x5, 0x00000000, 0x0, 0x303303E4
#define IOMUXC_SAI1_TXD4_AUDIOMIX_SAI1_TX_DATA4 0x30330188, 0x0, 0x00000000, 0x0, 0x303303E8
#define IOMUXC_SAI1_TXD4_AUDIOMIX_SAI6_RX_BCLK 0x30330188, 0x1, 0x30330518, 0x2, 0x303303E8
#define IOMUXC_SAI1_TXD4_AUDIOMIX_SAI6_TX_BCLK 0x30330188, 0x2, 0x30330524, 0x2, 0x303303E8
#define IOMUXC_SAI1_TXD4_ENET1_RGMII_TX_CTL 0x30330188, 0x4, 0x00000000, 0x0, 0x303303E8
#define IOMUXC_SAI1_TXD4_GPIO4_IO16 0x30330188, 0x5, 0x00000000, 0x0, 0x303303E8
#define IOMUXC_SAI1_TXD5_AUDIOMIX_SAI1_TX_DATA5 0x3033018C, 0x0, 0x00000000, 0x0, 0x303303EC
#define IOMUXC_SAI1_TXD5_AUDIOMIX_SAI6_RX_DATA0 0x3033018C, 0x1, 0x3033051C, 0x2, 0x303303EC
#define IOMUXC_SAI1_TXD5_AUDIOMIX_SAI6_TX_DATA0 0x3033018C, 0x2, 0x00000000, 0x0, 0x303303EC
#define IOMUXC_SAI1_TXD5_ENET1_RGMII_TXC 0x3033018C, 0x4, 0x00000000, 0x0, 0x303303EC
#define IOMUXC_SAI1_TXD5_GPIO4_IO17 0x3033018C, 0x5, 0x00000000, 0x0, 0x303303EC
#define IOMUXC_SAI1_TXD6_AUDIOMIX_SAI1_TX_DATA6 0x30330190, 0x0, 0x00000000, 0x0, 0x303303F0
#define IOMUXC_SAI1_TXD6_AUDIOMIX_SAI6_RX_SYNC 0x30330190, 0x1, 0x30330520, 0x2, 0x303303F0
#define IOMUXC_SAI1_TXD6_AUDIOMIX_SAI6_TX_SYNC 0x30330190, 0x2, 0x30330528, 0x2, 0x303303F0
#define IOMUXC_SAI1_TXD6_ENET1_RX_ER 0x30330190, 0x4, 0x3033058C, 0x1, 0x303303F0
#define IOMUXC_SAI1_TXD6_GPIO4_IO18 0x30330190, 0x5, 0x00000000, 0x0, 0x303303F0
#define IOMUXC_SAI1_TXD7_AUDIOMIX_SAI1_TX_DATA7 0x30330194, 0x0, 0x00000000, 0x0, 0x303303F4
#define IOMUXC_SAI1_TXD7_AUDIOMIX_SAI6_MCLK 0x30330194, 0x1, 0x30330514, 0x2, 0x303303F4
#define IOMUXC_SAI1_TXD7_AUDIOMIX_PDM_CLK 0x30330194, 0x3, 0x00000000, 0x0, 0x303303F4
#define IOMUXC_SAI1_TXD7_ENET1_TX_ER 0x30330194, 0x4, 0x00000000, 0x0, 0x303303F4
#define IOMUXC_SAI1_TXD7_GPIO4_IO19 0x30330194, 0x5, 0x00000000, 0x0, 0x303303F4
#define IOMUXC_SAI1_MCLK_AUDIOMIX_SAI1_MCLK 0x30330198, 0x0, 0x00000000, 0x0, 0x303303F8
#define IOMUXC_SAI1_MCLK_AUDIOMIX_SAI1_TX_BCLK 0x30330198, 0x2, 0x303304D4, 0x2, 0x303303F8
#define IOMUXC_SAI1_MCLK_ENET1_TX_CLK 0x30330198, 0x4, 0x30330578, 0x1, 0x303303F8
#define IOMUXC_SAI1_MCLK_GPIO4_IO20 0x30330198, 0x5, 0x00000000, 0x0, 0x303303F8
#define IOMUXC_SAI2_RXFS_AUDIOMIX_SAI2_RX_SYNC 0x3033019C, 0x0, 0x00000000, 0x0, 0x303303FC
#define IOMUXC_SAI2_RXFS_AUDIOMIX_SAI5_TX_SYNC 0x3033019C, 0x1, 0x30330510, 0x2, 0x303303FC
#define IOMUXC_SAI2_RXFS_AUDIOMIX_SAI5_TX_DATA1 0x3033019C, 0x2, 0x00000000, 0x0, 0x303303FC
#define IOMUXC_SAI2_RXFS_AUDIOMIX_SAI2_RX_DATA1 0x3033019C, 0x3, 0x303304DC, 0x0, 0x303303FC
#define IOMUXC_SAI2_RXFS_UART1_TX 0x3033019C, 0x4, 0x00000000, 0x0, 0x303303FC
#define IOMUXC_SAI2_RXFS_UART1_RX 0x3033019C, 0x4, 0x303305E8, 0x2, 0x303303FC
#define IOMUXC_SAI2_RXFS_GPIO4_IO21 0x3033019C, 0x5, 0x00000000, 0x0, 0x303303FC
#define IOMUXC_SAI2_RXFS_AUDIOMIX_PDM_BIT_STREAM2 0x3033019C, 0x6, 0x303304C8, 0x5, 0x303303FC
#define IOMUXC_SAI2_RXC_AUDIOMIX_SAI2_RX_BCLK 0x303301A0, 0x0, 0x00000000, 0x0, 0x30330400
#define IOMUXC_SAI2_RXC_AUDIOMIX_SAI5_TX_BCLK 0x303301A0, 0x1, 0x3033050C, 0x2, 0x30330400
#define IOMUXC_SAI2_RXC_CAN1_TX 0x303301A0, 0x3, 0x00000000, 0x0, 0x30330400
#define IOMUXC_SAI2_RXC_UART1_RX 0x303301A0, 0x4, 0x303305E8, 0x3, 0x30330400
#define IOMUXC_SAI2_RXC_UART1_TX 0x303301A0, 0x4, 0x00000000, 0x0, 0x30330400
#define IOMUXC_SAI2_RXC_GPIO4_IO22 0x303301A0, 0x5, 0x00000000, 0x0, 0x30330400
#define IOMUXC_SAI2_RXC_AUDIOMIX_PDM_BIT_STREAM1 0x303301A0, 0x6, 0x303304C4, 0x5, 0x30330400
#define IOMUXC_SAI2_RXD0_AUDIOMIX_SAI2_RX_DATA0 0x303301A4, 0x0, 0x00000000, 0x0, 0x30330404
#define IOMUXC_SAI2_RXD0_AUDIOMIX_SAI5_TX_DATA0 0x303301A4, 0x1, 0x00000000, 0x0, 0x30330404
#define IOMUXC_SAI2_RXD0_ENET_QOS_1588_EVENT2_OUT 0x303301A4, 0x2, 0x00000000, 0x0, 0x30330404
#define IOMUXC_SAI2_RXD0_AUDIOMIX_SAI2_TX_DATA1 0x303301A4, 0x3, 0x00000000, 0x0, 0x30330404
#define IOMUXC_SAI2_RXD0_UART1_RTS_B 0x303301A4, 0x4, 0x303305E4, 0x2, 0x30330404
#define IOMUXC_SAI2_RXD0_UART1_CTS_B 0x303301A4, 0x4, 0x00000000, 0x0, 0x30330404
#define IOMUXC_SAI2_RXD0_GPIO4_IO23 0x303301A4, 0x5, 0x00000000, 0x0, 0x30330404
#define IOMUXC_SAI2_RXD0_AUDIOMIX_PDM_BIT_STREAM3 0x303301A4, 0x6, 0x303304CC, 0x5, 0x30330404
#define IOMUXC_SAI2_TXFS_AUDIOMIX_SAI2_TX_SYNC 0x303301A8, 0x0, 0x00000000, 0x0, 0x30330408
#define IOMUXC_SAI2_TXFS_AUDIOMIX_SAI5_TX_DATA1 0x303301A8, 0x1, 0x00000000, 0x0, 0x30330408
#define IOMUXC_SAI2_TXFS_ENET_QOS_1588_EVENT3_OUT 0x303301A8, 0x2, 0x00000000, 0x0, 0x30330408
#define IOMUXC_SAI2_TXFS_AUDIOMIX_SAI2_TX_DATA1 0x303301A8, 0x3, 0x00000000, 0x0, 0x30330408
#define IOMUXC_SAI2_TXFS_UART1_CTS_B 0x303301A8, 0x4, 0x00000000, 0x0, 0x30330408
#define IOMUXC_SAI2_TXFS_UART1_RTS_B 0x303301A8, 0x4, 0x303305E4, 0x3, 0x30330408
#define IOMUXC_SAI2_TXFS_GPIO4_IO24 0x303301A8, 0x5, 0x00000000, 0x0, 0x30330408
#define IOMUXC_SAI2_TXFS_AUDIOMIX_PDM_BIT_STREAM2 0x303301A8, 0x6, 0x303304C8, 0x6, 0x30330408
#define IOMUXC_SAI2_TXC_AUDIOMIX_SAI2_TX_BCLK 0x303301AC, 0x0, 0x00000000, 0x0, 0x3033040C
#define IOMUXC_SAI2_TXC_AUDIOMIX_SAI5_TX_DATA2 0x303301AC, 0x1, 0x00000000, 0x0, 0x3033040C
#define IOMUXC_SAI2_TXC_CAN1_RX 0x303301AC, 0x3, 0x3033054C, 0x1, 0x3033040C
#define IOMUXC_SAI2_TXC_GPIO4_IO25 0x303301AC, 0x5, 0x00000000, 0x0, 0x3033040C
#define IOMUXC_SAI2_TXC_AUDIOMIX_PDM_BIT_STREAM1 0x303301AC, 0x6, 0x303304C4, 0x6, 0x3033040C
#define IOMUXC_SAI2_TXD0_AUDIOMIX_SAI2_TX_DATA0 0x303301B0, 0x0, 0x00000000, 0x0, 0x30330410
#define IOMUXC_SAI2_TXD0_AUDIOMIX_SAI5_TX_DATA3 0x303301B0, 0x1, 0x00000000, 0x0, 0x30330410
#define IOMUXC_SAI2_TXD0_ENET_QOS_1588_EVENT2_IN 0x303301B0, 0x2, 0x00000000, 0x0, 0x30330410
#define IOMUXC_SAI2_TXD0_CAN2_TX 0x303301B0, 0x3, 0x00000000, 0x0, 0x30330410
#define IOMUXC_SAI2_TXD0_ENET_QOS_1588_EVENT2_AUX_IN 0x303301B0, 0x4, 0x00000000, 0x0, 0x30330410
#define IOMUXC_SAI2_TXD0_GPIO4_IO26 0x303301B0, 0x5, 0x00000000, 0x0, 0x30330410
#define IOMUXC_SAI2_MCLK_AUDIOMIX_SAI2_MCLK 0x303301B4, 0x0, 0x00000000, 0x0, 0x30330414
#define IOMUXC_SAI2_MCLK_AUDIOMIX_SAI5_MCLK 0x303301B4, 0x1, 0x303304F0, 0x2, 0x30330414
#define IOMUXC_SAI2_MCLK_ENET_QOS_1588_EVENT3_IN 0x303301B4, 0x2, 0x00000000, 0x0, 0x30330414
#define IOMUXC_SAI2_MCLK_CAN2_RX 0x303301B4, 0x3, 0x30330550, 0x1, 0x30330414
#define IOMUXC_SAI2_MCLK_ENET_QOS_1588_EVENT3_AUX_IN 0x303301B4, 0x4, 0x00000000, 0x0, 0x30330414
#define IOMUXC_SAI2_MCLK_GPIO4_IO27 0x303301B4, 0x5, 0x00000000, 0x0, 0x30330414
#define IOMUXC_SAI2_MCLK_AUDIOMIX_SAI3_MCLK 0x303301B4, 0x6, 0x303304E0, 0x1, 0x30330414
#define IOMUXC_SAI3_RXFS_AUDIOMIX_SAI3_RX_SYNC 0x303301B8, 0x0, 0x00000000, 0x0, 0x30330418
#define IOMUXC_SAI3_RXFS_AUDIOMIX_SAI2_RX_DATA1 0x303301B8, 0x1, 0x303304DC, 0x1, 0x30330418
#define IOMUXC_SAI3_RXFS_AUDIOMIX_SAI5_RX_SYNC 0x303301B8, 0x2, 0x30330508, 0x2, 0x30330418
#define IOMUXC_SAI3_RXFS_AUDIOMIX_SAI3_RX_DATA1 0x303301B8, 0x3, 0x00000000, 0x0, 0x30330418
#define IOMUXC_SAI3_RXFS_AUDIOMIX_SPDIF1_IN 0x303301B8, 0x4, 0x30330544, 0x2, 0x30330418
#define IOMUXC_SAI3_RXFS_GPIO4_IO28 0x303301B8, 0x5, 0x00000000, 0x0, 0x30330418
#define IOMUXC_SAI3_RXFS_AUDIOMIX_PDM_BIT_STREAM0 0x303301B8, 0x6, 0x303304C0, 0x5, 0x30330418
#define IOMUXC_SAI3_RXC_AUDIOMIX_SAI3_RX_BCLK 0x303301BC, 0x0, 0x00000000, 0x0, 0x3033041C
#define IOMUXC_SAI3_RXC_AUDIOMIX_SAI2_RX_DATA2 0x303301BC, 0x1, 0x00000000, 0x0, 0x3033041C
#define IOMUXC_SAI3_RXC_AUDIOMIX_SAI5_RX_BCLK 0x303301BC, 0x2, 0x303304F4, 0x2, 0x3033041C
#define IOMUXC_SAI3_RXC_GPT1_CLK 0x303301BC, 0x3, 0x3033059C, 0x0, 0x3033041C
#define IOMUXC_SAI3_RXC_UART2_CTS_B 0x303301BC, 0x4, 0x00000000, 0x0, 0x3033041C
#define IOMUXC_SAI3_RXC_UART2_RTS_B 0x303301BC, 0x4, 0x303305EC, 0x2, 0x3033041C
#define IOMUXC_SAI3_RXC_GPIO4_IO29 0x303301BC, 0x5, 0x00000000, 0x0, 0x3033041C
#define IOMUXC_SAI3_RXC_AUDIOMIX_PDM_CLK 0x303301BC, 0x6, 0x00000000, 0x0, 0x3033041C
#define IOMUXC_SAI3_RXD_AUDIOMIX_SAI3_RX_DATA0 0x303301C0, 0x0, 0x303304E4, 0x1, 0x30330420
#define IOMUXC_SAI3_RXD_AUDIOMIX_SAI2_RX_DATA3 0x303301C0, 0x1, 0x00000000, 0x0, 0x30330420
#define IOMUXC_SAI3_RXD_AUDIOMIX_SAI5_RX_DATA0 0x303301C0, 0x2, 0x303304F8, 0x2, 0x30330420
#define IOMUXC_SAI3_RXD_UART2_RTS_B 0x303301C0, 0x4, 0x303305EC, 0x3, 0x30330420
#define IOMUXC_SAI3_RXD_UART2_CTS_B 0x303301C0, 0x4, 0x00000000, 0x0, 0x30330420
#define IOMUXC_SAI3_RXD_GPIO4_IO30 0x303301C0, 0x5, 0x00000000, 0x0, 0x30330420
#define IOMUXC_SAI3_RXD_AUDIOMIX_PDM_BIT_STREAM1 0x303301C0, 0x6, 0x303304C4, 0x7, 0x30330420
#define IOMUXC_SAI3_TXFS_AUDIOMIX_SAI3_TX_SYNC 0x303301C4, 0x0, 0x303304EC, 0x1, 0x30330424
#define IOMUXC_SAI3_TXFS_AUDIOMIX_SAI2_TX_DATA1 0x303301C4, 0x1, 0x00000000, 0x0, 0x30330424
#define IOMUXC_SAI3_TXFS_AUDIOMIX_SAI5_RX_DATA1 0x303301C4, 0x2, 0x303304FC, 0x2, 0x30330424
#define IOMUXC_SAI3_TXFS_AUDIOMIX_SAI3_TX_DATA1 0x303301C4, 0x3, 0x00000000, 0x0, 0x30330424
#define IOMUXC_SAI3_TXFS_UART2_RX 0x303301C4, 0x4, 0x303305F0, 0x4, 0x30330424
#define IOMUXC_SAI3_TXFS_UART2_TX 0x303301C4, 0x4, 0x00000000, 0x0, 0x30330424
#define IOMUXC_SAI3_TXFS_GPIO4_IO31 0x303301C4, 0x5, 0x00000000, 0x0, 0x30330424
#define IOMUXC_SAI3_TXFS_AUDIOMIX_PDM_BIT_STREAM3 0x303301C4, 0x6, 0x303304CC, 0x6, 0x30330424
#define IOMUXC_SAI3_TXC_AUDIOMIX_SAI3_TX_BCLK 0x303301C8, 0x0, 0x303304E8, 0x1, 0x30330428
#define IOMUXC_SAI3_TXC_AUDIOMIX_SAI2_TX_DATA2 0x303301C8, 0x1, 0x00000000, 0x0, 0x30330428
#define IOMUXC_SAI3_TXC_AUDIOMIX_SAI5_RX_DATA2 0x303301C8, 0x2, 0x30330500, 0x2, 0x30330428
#define IOMUXC_SAI3_TXC_GPT1_CAPTURE1 0x303301C8, 0x3, 0x30330594, 0x0, 0x30330428
#define IOMUXC_SAI3_TXC_UART2_TX 0x303301C8, 0x4, 0x00000000, 0x0, 0x30330428
#define IOMUXC_SAI3_TXC_UART2_RX 0x303301C8, 0x4, 0x303305F0, 0x5, 0x30330428
#define IOMUXC_SAI3_TXC_GPIO5_IO00 0x303301C8, 0x5, 0x00000000, 0x0, 0x30330428
#define IOMUXC_SAI3_TXC_AUDIOMIX_PDM_BIT_STREAM2 0x303301C8, 0x6, 0x303304C8, 0x7, 0x30330428
#define IOMUXC_SAI3_TXD_AUDIOMIX_SAI3_TX_DATA0 0x303301CC, 0x0, 0x00000000, 0x0, 0x3033042C
#define IOMUXC_SAI3_TXD_AUDIOMIX_SAI2_TX_DATA3 0x303301CC, 0x1, 0x00000000, 0x0, 0x3033042C
#define IOMUXC_SAI3_TXD_AUDIOMIX_SAI5_RX_DATA3 0x303301CC, 0x2, 0x30330504, 0x2, 0x3033042C
#define IOMUXC_SAI3_TXD_GPT1_CAPTURE2 0x303301CC, 0x3, 0x30330598, 0x0, 0x3033042C
#define IOMUXC_SAI3_TXD_AUDIOMIX_SPDIF1_EXT_CLK 0x303301CC, 0x4, 0x30330548, 0x0, 0x3033042C
#define IOMUXC_SAI3_TXD_GPIO5_IO01 0x303301CC, 0x5, 0x00000000, 0x0, 0x3033042C
#define IOMUXC_SAI3_MCLK_AUDIOMIX_SAI3_MCLK 0x303301D0, 0x0, 0x303304E0, 0x2, 0x30330430
#define IOMUXC_SAI3_MCLK_PWM4_OUT 0x303301D0, 0x1, 0x00000000, 0x0, 0x30330430
#define IOMUXC_SAI3_MCLK_AUDIOMIX_SAI5_MCLK 0x303301D0, 0x2, 0x303304F0, 0x3, 0x30330430
#define IOMUXC_SAI3_MCLK_AUDIOMIX_SPDIF1_OUT 0x303301D0, 0x4, 0x00000000, 0x0, 0x30330430
#define IOMUXC_SAI3_MCLK_GPIO5_IO02 0x303301D0, 0x5, 0x00000000, 0x0, 0x30330430
#define IOMUXC_SAI3_MCLK_AUDIOMIX_SPDIF1_IN 0x303301D0, 0x6, 0x30330544, 0x3, 0x30330430
#define IOMUXC_SPDIF_TX_AUDIOMIX_SPDIF1_OUT 0x303301D4, 0x0, 0x00000000, 0x0, 0x30330434
#define IOMUXC_SPDIF_TX_PWM3_OUT 0x303301D4, 0x1, 0x00000000, 0x0, 0x30330434
#define IOMUXC_SPDIF_TX_I2C5_SCL 0x303301D4, 0x2, 0x303305C4, 0x2, 0x30330434
#define IOMUXC_SPDIF_TX_GPT1_COMPARE1 0x303301D4, 0x3, 0x00000000, 0x0, 0x30330434
#define IOMUXC_SPDIF_TX_CAN1_TX 0x303301D4, 0x4, 0x00000000, 0x0, 0x30330434
#define IOMUXC_SPDIF_TX_GPIO5_IO03 0x303301D4, 0x5, 0x00000000, 0x0, 0x30330434
#define IOMUXC_SPDIF_RX_AUDIOMIX_SPDIF1_IN 0x303301D8, 0x0, 0x30330544, 0x4, 0x30330438
#define IOMUXC_SPDIF_RX_PWM2_OUT 0x303301D8, 0x1, 0x00000000, 0x0, 0x30330438
#define IOMUXC_SPDIF_RX_I2C5_SDA 0x303301D8, 0x2, 0x303305C8, 0x2, 0x30330438
#define IOMUXC_SPDIF_RX_GPT1_COMPARE2 0x303301D8, 0x3, 0x00000000, 0x0, 0x30330438
#define IOMUXC_SPDIF_RX_CAN1_RX 0x303301D8, 0x4, 0x3033054C, 0x2, 0x30330438
#define IOMUXC_SPDIF_RX_GPIO5_IO04 0x303301D8, 0x5, 0x00000000, 0x0, 0x30330438
#define IOMUXC_SPDIF_EXT_CLK_AUDIOMIX_SPDIF1_EXT_CLK 0x303301DC, 0x0, 0x30330548, 0x1, 0x3033043C
#define IOMUXC_SPDIF_EXT_CLK_PWM1_OUT 0x303301DC, 0x1, 0x00000000, 0x0, 0x3033043C
#define IOMUXC_SPDIF_EXT_CLK_GPT1_COMPARE3 0x303301DC, 0x3, 0x00000000, 0x0, 0x3033043C
#define IOMUXC_SPDIF_EXT_CLK_GPIO5_IO05 0x303301DC, 0x5, 0x00000000, 0x0, 0x3033043C
#define IOMUXC_ECSPI1_SCLK_ECSPI1_SCLK 0x303301E0, 0x0, 0x30330558, 0x0, 0x30330440
#define IOMUXC_ECSPI1_SCLK_UART3_RX 0x303301E0, 0x1, 0x303305F8, 0x4, 0x30330440
#define IOMUXC_ECSPI1_SCLK_UART3_TX 0x303301E0, 0x1, 0x00000000, 0x0, 0x30330440
#define IOMUXC_ECSPI1_SCLK_I2C1_SCL 0x303301E0, 0x2, 0x303305A4, 0x1, 0x30330440
#define IOMUXC_ECSPI1_SCLK_AUDIOMIX_SAI7_RX_SYNC 0x303301E0, 0x3, 0x30330538, 0x1, 0x30330440
#define IOMUXC_ECSPI1_SCLK_GPIO5_IO06 0x303301E0, 0x5, 0x00000000, 0x0, 0x30330440
#define IOMUXC_ECSPI1_MOSI_ECSPI1_MOSI 0x303301E4, 0x0, 0x30330560, 0x0, 0x30330444
#define IOMUXC_ECSPI1_MOSI_UART3_TX 0x303301E4, 0x1, 0x00000000, 0x0, 0x30330444
#define IOMUXC_ECSPI1_MOSI_UART3_RX 0x303301E4, 0x1, 0x303305F8, 0x5, 0x30330444
#define IOMUXC_ECSPI1_MOSI_I2C1_SDA 0x303301E4, 0x2, 0x303305A8, 0x1, 0x30330444
#define IOMUXC_ECSPI1_MOSI_AUDIOMIX_SAI7_RX_BCLK 0x303301E4, 0x3, 0x30330530, 0x1, 0x30330444
#define IOMUXC_ECSPI1_MOSI_GPIO5_IO07 0x303301E4, 0x5, 0x00000000, 0x0, 0x30330444
#define IOMUXC_ECSPI1_MISO_ECSPI1_MISO 0x303301E8, 0x0, 0x3033055C, 0x0, 0x30330448
#define IOMUXC_ECSPI1_MISO_UART3_CTS_B 0x303301E8, 0x1, 0x00000000, 0x0, 0x30330448
#define IOMUXC_ECSPI1_MISO_UART3_RTS_B 0x303301E8, 0x1, 0x303305F4, 0x2, 0x30330448
#define IOMUXC_ECSPI1_MISO_I2C2_SCL 0x303301E8, 0x2, 0x303305AC, 0x1, 0x30330448
#define IOMUXC_ECSPI1_MISO_AUDIOMIX_SAI7_RX_DATA0 0x303301E8, 0x3, 0x30330534, 0x1, 0x30330448
#define IOMUXC_ECSPI1_MISO_GPIO5_IO08 0x303301E8, 0x5, 0x00000000, 0x0, 0x30330448
#define IOMUXC_ECSPI1_SS0_ECSPI1_SS0 0x303301EC, 0x0, 0x30330564, 0x0, 0x3033044C
#define IOMUXC_ECSPI1_SS0_UART3_RTS_B 0x303301EC, 0x1, 0x303305F4, 0x3, 0x3033044C
#define IOMUXC_ECSPI1_SS0_UART3_CTS_B 0x303301EC, 0x1, 0x00000000, 0x0, 0x3033044C
#define IOMUXC_ECSPI1_SS0_I2C2_SDA 0x303301EC, 0x2, 0x303305B0, 0x1, 0x3033044C
#define IOMUXC_ECSPI1_SS0_AUDIOMIX_SAI7_TX_SYNC 0x303301EC, 0x3, 0x30330540, 0x1, 0x3033044C
#define IOMUXC_ECSPI1_SS0_GPIO5_IO09 0x303301EC, 0x5, 0x00000000, 0x0, 0x3033044C
#define IOMUXC_ECSPI2_SCLK_ECSPI2_SCLK 0x303301F0, 0x0, 0x30330568, 0x1, 0x30330450
#define IOMUXC_ECSPI2_SCLK_UART4_RX 0x303301F0, 0x1, 0x30330600, 0x6, 0x30330450
#define IOMUXC_ECSPI2_SCLK_UART4_TX 0x303301F0, 0x1, 0x00000000, 0x0, 0x30330450
#define IOMUXC_ECSPI2_SCLK_I2C3_SCL 0x303301F0, 0x2, 0x303305B4, 0x3, 0x30330450
#define IOMUXC_ECSPI2_SCLK_AUDIOMIX_SAI7_TX_BCLK 0x303301F0, 0x3, 0x3033053C, 0x1, 0x30330450
#define IOMUXC_ECSPI2_SCLK_GPIO5_IO10 0x303301F0, 0x5, 0x00000000, 0x0, 0x30330450
#define IOMUXC_ECSPI2_MOSI_ECSPI2_MOSI 0x303301F4, 0x0, 0x30330570, 0x1, 0x30330454
#define IOMUXC_ECSPI2_MOSI_UART4_TX 0x303301F4, 0x1, 0x00000000, 0x0, 0x30330454
#define IOMUXC_ECSPI2_MOSI_UART4_RX 0x303301F4, 0x1, 0x30330600, 0x7, 0x30330454
#define IOMUXC_ECSPI2_MOSI_I2C3_SDA 0x303301F4, 0x2, 0x303305B8, 0x3, 0x30330454
#define IOMUXC_ECSPI2_MOSI_AUDIOMIX_SAI7_TX_DATA0 0x303301F4, 0x3, 0x00000000, 0x0, 0x30330454
#define IOMUXC_ECSPI2_MOSI_GPIO5_IO11 0x303301F4, 0x5, 0x00000000, 0x0, 0x30330454
#define IOMUXC_ECSPI2_MISO_ECSPI2_MISO 0x303301F8, 0x0, 0x3033056C, 0x1, 0x30330458
#define IOMUXC_ECSPI2_MISO_UART4_CTS_B 0x303301F8, 0x1, 0x00000000, 0x0, 0x30330458
#define IOMUXC_ECSPI2_MISO_UART4_RTS_B 0x303301F8, 0x1, 0x303305FC, 0x2, 0x30330458
#define IOMUXC_ECSPI2_MISO_I2C4_SCL 0x303301F8, 0x2, 0x303305BC, 0x4, 0x30330458
#define IOMUXC_ECSPI2_MISO_AUDIOMIX_SAI7_MCLK 0x303301F8, 0x3, 0x3033052C, 0x1, 0x30330458
#define IOMUXC_ECSPI2_MISO_CCM_CLKO1 0x303301F8, 0x4, 0x00000000, 0x0, 0x30330458
#define IOMUXC_ECSPI2_MISO_GPIO5_IO12 0x303301F8, 0x5, 0x00000000, 0x0, 0x30330458
#define IOMUXC_ECSPI2_SS0_ECSPI2_SS0 0x303301FC, 0x0, 0x30330574, 0x1, 0x3033045C
#define IOMUXC_ECSPI2_SS0_UART4_RTS_B 0x303301FC, 0x1, 0x303305FC, 0x3, 0x3033045C
#define IOMUXC_ECSPI2_SS0_UART4_CTS_B 0x303301FC, 0x1, 0x00000000, 0x0, 0x3033045C
#define IOMUXC_ECSPI2_SS0_I2C4_SDA 0x303301FC, 0x2, 0x303305C0, 0x4, 0x3033045C
#define IOMUXC_ECSPI2_SS0_CCM_CLKO2 0x303301FC, 0x4, 0x00000000, 0x0, 0x3033045C
#define IOMUXC_ECSPI2_SS0_GPIO5_IO13 0x303301FC, 0x5, 0x00000000, 0x0, 0x3033045C
#define IOMUXC_I2C1_SCL_I2C1_SCL 0x30330200, 0x0, 0x303305A4, 0x2, 0x30330460
#define IOMUXC_I2C1_SCL_ENET_QOS_MDC 0x30330200, 0x1, 0x00000000, 0x0, 0x30330460
#define IOMUXC_I2C1_SCL_ECSPI1_SCLK 0x30330200, 0x3, 0x30330558, 0x1, 0x30330460
#define IOMUXC_I2C1_SCL_GPIO5_IO14 0x30330200, 0x5, 0x00000000, 0x0, 0x30330460
#define IOMUXC_I2C1_SDA_I2C1_SDA 0x30330204, 0x0, 0x303305A8, 0x2, 0x30330464
#define IOMUXC_I2C1_SDA_ENET_QOS_MDIO 0x30330204, 0x1, 0x30330590, 0x2, 0x30330464
#define IOMUXC_I2C1_SDA_ECSPI1_MOSI 0x30330204, 0x3, 0x30330560, 0x1, 0x30330464
#define IOMUXC_I2C1_SDA_GPIO5_IO15 0x30330204, 0x5, 0x00000000, 0x0, 0x30330464
#define IOMUXC_I2C2_SCL_I2C2_SCL 0x30330208, 0x0, 0x303305AC, 0x2, 0x30330468
#define IOMUXC_I2C2_SCL_ENET_QOS_1588_EVENT1_IN 0x30330208, 0x1, 0x00000000, 0x0, 0x30330468
#define IOMUXC_I2C2_SCL_USDHC3_CD_B 0x30330208, 0x2, 0x30330608, 0x3, 0x30330468
#define IOMUXC_I2C2_SCL_ECSPI1_MISO 0x30330208, 0x3, 0x3033055C, 0x1, 0x30330468
#define IOMUXC_I2C2_SCL_ENET_QOS_1588_EVENT1_AUX_IN 0x30330208, 0x4, 0x00000000, 0x0, 0x30330468
#define IOMUXC_I2C2_SCL_GPIO5_IO16 0x30330208, 0x5, 0x00000000, 0x0, 0x30330468
#define IOMUXC_I2C2_SDA_I2C2_SDA 0x3033020C, 0x0, 0x303305B0, 0x2, 0x3033046C
#define IOMUXC_I2C2_SDA_ENET_QOS_1588_EVENT1_OUT 0x3033020C, 0x1, 0x00000000, 0x0, 0x3033046C
#define IOMUXC_I2C2_SDA_USDHC3_WP 0x3033020C, 0x2, 0x30330634, 0x3, 0x3033046C
#define IOMUXC_I2C2_SDA_ECSPI1_SS0 0x3033020C, 0x3, 0x30330564, 0x1, 0x3033046C
#define IOMUXC_I2C2_SDA_GPIO5_IO17 0x3033020C, 0x5, 0x00000000, 0x0, 0x3033046C
#define IOMUXC_I2C3_SCL_I2C3_SCL 0x30330210, 0x0, 0x303305B4, 0x4, 0x30330470
#define IOMUXC_I2C3_SCL_PWM4_OUT 0x30330210, 0x1, 0x00000000, 0x0, 0x30330470
#define IOMUXC_I2C3_SCL_GPT2_CLK 0x30330210, 0x2, 0x00000000, 0x0, 0x30330470
#define IOMUXC_I2C3_SCL_ECSPI2_SCLK 0x30330210, 0x3, 0x30330568, 0x2, 0x30330470
#define IOMUXC_I2C3_SCL_GPIO5_IO18 0x30330210, 0x5, 0x00000000, 0x0, 0x30330470
#define IOMUXC_I2C3_SDA_I2C3_SDA 0x30330214, 0x0, 0x303305B8, 0x4, 0x30330474
#define IOMUXC_I2C3_SDA_PWM3_OUT 0x30330214, 0x1, 0x00000000, 0x0, 0x30330474
#define IOMUXC_I2C3_SDA_GPT3_CLK 0x30330214, 0x2, 0x00000000, 0x0, 0x30330474
#define IOMUXC_I2C3_SDA_ECSPI2_MOSI 0x30330214, 0x3, 0x30330570, 0x2, 0x30330474
#define IOMUXC_I2C3_SDA_GPIO5_IO19 0x30330214, 0x5, 0x00000000, 0x0, 0x30330474
#define IOMUXC_I2C4_SCL_I2C4_SCL 0x30330218, 0x0, 0x303305BC, 0x5, 0x30330478
#define IOMUXC_I2C4_SCL_PWM2_OUT 0x30330218, 0x1, 0x00000000, 0x0, 0x30330478
#define IOMUXC_I2C4_SCL_PCIE_CLKREQ_B 0x30330218, 0x2, 0x303305A0, 0x0, 0x30330478
#define IOMUXC_I2C4_SCL_ECSPI2_MISO 0x30330218, 0x3, 0x3033056C, 0x2, 0x30330478
#define IOMUXC_I2C4_SCL_GPIO5_IO20 0x30330218, 0x5, 0x00000000, 0x0, 0x30330478
#define IOMUXC_I2C4_SDA_I2C4_SDA 0x3033021C, 0x0, 0x303305C0, 0x5, 0x3033047C
#define IOMUXC_I2C4_SDA_PWM1_OUT 0x3033021C, 0x1, 0x00000000, 0x0, 0x3033047C
#define IOMUXC_I2C4_SDA_ECSPI2_SS0 0x3033021C, 0x3, 0x30330574, 0x2, 0x3033047C
#define IOMUXC_I2C4_SDA_GPIO5_IO21 0x3033021C, 0x5, 0x00000000, 0x0, 0x3033047C
#define IOMUXC_UART1_RXD_UART1_RX 0x30330220, 0x0, 0x303305E8, 0x4, 0x30330480
#define IOMUXC_UART1_RXD_UART1_TX 0x30330220, 0x0, 0x00000000, 0x0, 0x30330480
#define IOMUXC_UART1_RXD_ECSPI3_SCLK 0x30330220, 0x1, 0x00000000, 0x0, 0x30330480
#define IOMUXC_UART1_RXD_GPIO5_IO22 0x30330220, 0x5, 0x00000000, 0x0, 0x30330480
#define IOMUXC_UART1_TXD_UART1_TX 0x30330224, 0x0, 0x00000000, 0x0, 0x30330484
#define IOMUXC_UART1_TXD_UART1_RX 0x30330224, 0x0, 0x303305E8, 0x5, 0x30330484
#define IOMUXC_UART1_TXD_ECSPI3_MOSI 0x30330224, 0x1, 0x00000000, 0x0, 0x30330484
#define IOMUXC_UART1_TXD_GPIO5_IO23 0x30330224, 0x5, 0x00000000, 0x0, 0x30330484
#define IOMUXC_UART2_RXD_UART2_RX 0x30330228, 0x0, 0x303305F0, 0x6, 0x30330488
#define IOMUXC_UART2_RXD_UART2_TX 0x30330228, 0x0, 0x00000000, 0x0, 0x30330488
#define IOMUXC_UART2_RXD_ECSPI3_MISO 0x30330228, 0x1, 0x00000000, 0x0, 0x30330488
#define IOMUXC_UART2_RXD_GPT1_COMPARE3 0x30330228, 0x3, 0x00000000, 0x0, 0x30330488
#define IOMUXC_UART2_RXD_GPIO5_IO24 0x30330228, 0x5, 0x00000000, 0x0, 0x30330488
#define IOMUXC_UART2_TXD_UART2_TX 0x3033022C, 0x0, 0x00000000, 0x0, 0x3033048C
#define IOMUXC_UART2_TXD_UART2_RX 0x3033022C, 0x0, 0x303305F0, 0x7, 0x3033048C
#define IOMUXC_UART2_TXD_ECSPI3_SS0 0x3033022C, 0x1, 0x00000000, 0x0, 0x3033048C
#define IOMUXC_UART2_TXD_GPT1_COMPARE2 0x3033022C, 0x3, 0x00000000, 0x0, 0x3033048C
#define IOMUXC_UART2_TXD_GPIO5_IO25 0x3033022C, 0x5, 0x00000000, 0x0, 0x3033048C
#define IOMUXC_UART3_RXD_UART3_RX 0x30330230, 0x0, 0x303305F8, 0x6, 0x30330490
#define IOMUXC_UART3_RXD_UART3_TX 0x30330230, 0x0, 0x00000000, 0x0, 0x30330490
#define IOMUXC_UART3_RXD_UART1_CTS_B 0x30330230, 0x1, 0x00000000, 0x0, 0x30330490
#define IOMUXC_UART3_RXD_UART1_RTS_B 0x30330230, 0x1, 0x303305E4, 0x4, 0x30330490
#define IOMUXC_UART3_RXD_USDHC3_RESET_B 0x30330230, 0x2, 0x00000000, 0x0, 0x30330490
#define IOMUXC_UART3_RXD_GPT1_CAPTURE2 0x30330230, 0x3, 0x30330598, 0x1, 0x30330490
#define IOMUXC_UART3_RXD_CAN2_TX 0x30330230, 0x4, 0x00000000, 0x0, 0x30330490
#define IOMUXC_UART3_RXD_GPIO5_IO26 0x30330230, 0x5, 0x00000000, 0x0, 0x30330490
#define IOMUXC_UART3_TXD_UART3_TX 0x30330234, 0x0, 0x00000000, 0x0, 0x30330494
#define IOMUXC_UART3_TXD_UART3_RX 0x30330234, 0x0, 0x303305F8, 0x7, 0x30330494
#define IOMUXC_UART3_TXD_UART1_RTS_B 0x30330234, 0x1, 0x303305E4, 0x5, 0x30330494
#define IOMUXC_UART3_TXD_UART1_CTS_B 0x30330234, 0x1, 0x00000000, 0x0, 0x30330494
#define IOMUXC_UART3_TXD_USDHC3_VSELECT 0x30330234, 0x2, 0x00000000, 0x0, 0x30330494
#define IOMUXC_UART3_TXD_GPT1_CLK 0x30330234, 0x3, 0x3033059C, 0x1, 0x30330494
#define IOMUXC_UART3_TXD_CAN2_RX 0x30330234, 0x4, 0x30330550, 0x2, 0x30330494
#define IOMUXC_UART3_TXD_GPIO5_IO27 0x30330234, 0x5, 0x00000000, 0x0, 0x30330494
#define IOMUXC_UART4_RXD_UART4_RX 0x30330238, 0x0, 0x30330600, 0x8, 0x30330498
#define IOMUXC_UART4_RXD_UART4_TX 0x30330238, 0x0, 0x00000000, 0x0, 0x30330498
#define IOMUXC_UART4_RXD_UART2_CTS_B 0x30330238, 0x1, 0x00000000, 0x0, 0x30330498
#define IOMUXC_UART4_RXD_UART2_RTS_B 0x30330238, 0x1, 0x303305EC, 0x4, 0x30330498
#define IOMUXC_UART4_RXD_PCIE_CLKREQ_B 0x30330238, 0x2, 0x303305A0, 0x1, 0x30330498
#define IOMUXC_UART4_RXD_GPT1_COMPARE1 0x30330238, 0x3, 0x00000000, 0x0, 0x30330498
#define IOMUXC_UART4_RXD_I2C6_SCL 0x30330238, 0x4, 0x303305CC, 0x2, 0x30330498
#define IOMUXC_UART4_RXD_GPIO5_IO28 0x30330238, 0x5, 0x00000000, 0x0, 0x30330498
#define IOMUXC_UART4_TXD_UART4_TX 0x3033023C, 0x0, 0x00000000, 0x0, 0x3033049C
#define IOMUXC_UART4_TXD_UART4_RX 0x3033023C, 0x0, 0x30330600, 0x9, 0x3033049C
#define IOMUXC_UART4_TXD_UART2_RTS_B 0x3033023C, 0x1, 0x303305EC, 0x5, 0x3033049C
#define IOMUXC_UART4_TXD_UART2_CTS_B 0x3033023C, 0x1, 0x00000000, 0x0, 0x3033049C
#define IOMUXC_UART4_TXD_GPT1_CAPTURE1 0x3033023C, 0x3, 0x30330594, 0x1, 0x3033049C
#define IOMUXC_UART4_TXD_I2C6_SDA 0x3033023C, 0x4, 0x303305D0, 0x2, 0x3033049C
#define IOMUXC_UART4_TXD_GPIO5_IO29 0x3033023C, 0x5, 0x00000000, 0x0, 0x3033049C
#define IOMUXC_HDMI_DDC_SCL_HDMIMIX_HDMI_SCL 0x30330240, 0x0, 0x00000000, 0x0, 0x303304A0
#define IOMUXC_HDMI_DDC_SCL_I2C5_SCL 0x30330240, 0x3, 0x303305C4, 0x3, 0x303304A0
#define IOMUXC_HDMI_DDC_SCL_CAN1_TX 0x30330240, 0x4, 0x00000000, 0x0, 0x303304A0
#define IOMUXC_HDMI_DDC_SCL_GPIO3_IO26 0x30330240, 0x5, 0x00000000, 0x0, 0x303304A0
#define IOMUXC_HDMI_DDC_SCL_EARC_TEST_OUT0 0x30330240, 0x6, 0x00000000, 0x0, 0x303304A0
#define IOMUXC_HDMI_DDC_SDA_HDMIMIX_HDMI_SDA 0x30330244, 0x0, 0x00000000, 0x0, 0x303304A4
#define IOMUXC_HDMI_DDC_SDA_I2C5_SDA 0x30330244, 0x3, 0x303305C8, 0x3, 0x303304A4
#define IOMUXC_HDMI_DDC_SDA_CAN1_RX 0x30330244, 0x4, 0x3033054C, 0x3, 0x303304A4
#define IOMUXC_HDMI_DDC_SDA_GPIO3_IO27 0x30330244, 0x5, 0x00000000, 0x0, 0x303304A4
#define IOMUXC_HDMI_DDC_SDA_EARC_TEST_OUT1 0x30330244, 0x6, 0x00000000, 0x0, 0x303304A4
#define IOMUXC_HDMI_CEC_HDMIMIX_HDMI_CEC 0x30330248, 0x0, 0x00000000, 0x0, 0x303304A8
#define IOMUXC_HDMI_CEC_I2C6_SCL 0x30330248, 0x3, 0x303305CC, 0x3, 0x303304A8
#define IOMUXC_HDMI_CEC_CAN2_TX 0x30330248, 0x4, 0x00000000, 0x0, 0x303304A8
#define IOMUXC_HDMI_CEC_GPIO3_IO28 0x30330248, 0x5, 0x00000000, 0x0, 0x303304A8
#define IOMUXC_HDMI_HPD_HDMIMIX_HDMI_HPD 0x3033024C, 0x0, 0x00000000, 0x0, 0x303304AC
#define IOMUXC_HDMI_HPD_AUDIOMIX_HDMI_HPD_O 0x3033024C, 0x1, 0x00000000, 0x0, 0x303304AC
#define IOMUXC_HDMI_HPD_I2C6_SDA 0x3033024C, 0x3, 0x303305D0, 0x3, 0x303304AC
#define IOMUXC_HDMI_HPD_CAN2_RX 0x3033024C, 0x4, 0x30330550, 0x3, 0x303304AC
#define IOMUXC_HDMI_HPD_GPIO3_IO29 0x3033024C, 0x5, 0x00000000, 0x0, 0x303304AC
/*@}*/
#if defined(__cplusplus)
extern "C" {
#endif /*__cplusplus */
/*! @name Configuration */
/*@{*/
/*!
* @brief Sets the IOMUXC pin mux mode.
* @note The first five parameters can be filled with the pin function ID macros.
*
* This is an example to set the I2C4_SDA as the pwm1_OUT:
* @code
* IOMUXC_SetPinMux(IOMUXC_I2C4_SDA_PWM1_OUT, 0);
* @endcode
*
*
* @param muxRegister The pin mux register_
* @param muxMode The pin mux mode_
* @param inputRegister The select input register_
* @param inputDaisy The input daisy_
* @param configRegister The config register_
* @param inputOnfield The pad->module input inversion_
*/
static inline void IOMUXC_SetPinMux(uint32_t muxRegister,
uint32_t muxMode,
uint32_t inputRegister,
uint32_t inputDaisy,
uint32_t configRegister,
uint32_t inputOnfield)
{
*((volatile uint32_t *)muxRegister) =
IOMUXC_SW_MUX_CTL_PAD_MUX_MODE(muxMode) | IOMUXC_SW_MUX_CTL_PAD_SION(inputOnfield);
if (inputRegister)
{
*((volatile uint32_t *)inputRegister) = IOMUXC_SELECT_INPUT_DAISY(inputDaisy);
}
}
/*!
* @brief Sets the IOMUXC pin configuration.
* @note The previous five parameters can be filled with the pin function ID macros.
*
* This is an example to set pin configuration for IOMUXC_I2C4_SDA_PWM1_OUT:
* @code
* IOMUXC_SetPinConfig(IOMUXC_I2C4_SDA_PWM1_OUT, IOMUXC_SW_PAD_CTL_PAD_ODE_MASK | IOMUXC0_SW_PAD_CTL_PAD_DSE(2U))
* @endcode
*
* @param muxRegister The pin mux register_
* @param muxMode The pin mux mode_
* @param inputRegister The select input register_
* @param inputDaisy The input daisy_
* @param configRegister The config register_
* @param configValue The pin config value_
*/
static inline void IOMUXC_SetPinConfig(uint32_t muxRegister,
uint32_t muxMode,
uint32_t inputRegister,
uint32_t inputDaisy,
uint32_t configRegister,
uint32_t configValue)
{
if (configRegister)
{
*((volatile uint32_t *)configRegister) = configValue;
}
}
/*@}*/
#if defined(__cplusplus)
}
#endif /*__cplusplus */
/*! @}*/
#endif /* _FSL_IOMUXC_H_ */

View File

@ -0,0 +1,372 @@
/*
* Remoteproc Framework
*
* Copyright 2020 NXP.
* Copyright(c) 2018 Xilinx Ltd.
* Copyright(c) 2011 Texas Instruments, Inc.
* Copyright(c) 2011 Google, Inc.
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef REMOTEPROC_H
#define REMOTEPROC_H
#include <stdint.h>
#if defined __cplusplus
extern "C" {
#endif
#define RSC_NOTIFY_ID_ANY 0xFFFFFFFFUL
#define RPROC_MAX_NAME_LEN 32
/* IAR ARM build tools */
#if defined(__ICCARM__)
#ifndef METAL_PACKED_BEGIN
#define METAL_PACKED_BEGIN __packed
#endif
#ifndef METAL_PACKED_END
#define METAL_PACKED_END
#endif
/* GNUC */
#elif defined(__GNUC__)
#ifndef METAL_PACKED_BEGIN
#define METAL_PACKED_BEGIN
#endif
#ifndef METAL_PACKED_END
#define METAL_PACKED_END __attribute__((__packed__))
#endif
/* ARMCC */
#elif defined(__CC_ARM) || defined(__ARMCC_VERSION)
#ifndef METAL_PACKED_BEGIN
#define METAL_PACKED_BEGIN _Pragma("pack(1U)")
#endif
#ifndef METAL_PACKED_END
#define METAL_PACKED_END _Pragma("pack()")
#endif
#else
/* There is no default definition here to avoid wrong structures packing in case of not supported compiler */
#error Please implement the structure packing macros for your compiler here!
#endif
/**
* struct resource_table - firmware resource table header
* @ver: version number
* @num: number of resource entries
* @reserved: reserved (must be zero)
* @offset: array of offsets pointing at the various resource entries
*
* A resource table is essentially a list of system resources required
* by the remote remoteproc. It may also include configuration entries.
* If needed, the remote remoteproc firmware should contain this table
* as a dedicated ".resource_table" ELF section.
*
* Some resources entries are mere announcements, where the host is informed
* of specific remoteproc configuration. Other entries require the host to
* do something (e.g. allocate a system resource). Sometimes a negotiation
* is expected, where the firmware requests a resource, and once allocated,
* the host should provide back its details (e.g. address of an allocated
* memory region).
*
* The header of the resource table, as expressed by this structure,
* contains a version number (should we need to change this format in the
* future), the number of available resource entries, and their offsets
* in the table.
*
* Immediately following this header are the resource entries themselves,
* each of which begins with a resource entry header (as described below).
*/
METAL_PACKED_BEGIN
struct resource_table
{
uint32_t ver;
uint32_t num;
uint32_t reserved[2];
uint32_t offset[0];
} METAL_PACKED_END;
/**
* struct fw_rsc_hdr - firmware resource entry header
* @type: resource type
* @data: resource data
*
* Every resource entry begins with a 'struct fw_rsc_hdr' header providing
* its @type. The content of the entry itself will immediately follow
* this header, and it should be parsed according to the resource type.
*/
METAL_PACKED_BEGIN
struct fw_rsc_hdr
{
uint32_t type;
uint8_t data[0];
} METAL_PACKED_END;
/**
* enum fw_resource_type - types of resource entries
*
* @RSC_CARVEOUT: request for allocation of a physically contiguous
* memory region.
* @RSC_DEVMEM: request to iommu_map a memory-based peripheral.
* @RSC_TRACE: announces the availability of a trace buffer into which
* the remote remoteproc will be writing logs.
* @RSC_VDEV: declare support for a virtio device, and serve as its
* virtio header.
* @RSC_VENDOR_START: start of the vendor specific resource types range
* @RSC_VENDOR_END : end of the vendor specific resource types range
* @RSC_LAST: just keep this one at the end
*
* For more details regarding a specific resource type, please see its
* dedicated structure below.
*
* Please note that these values are used as indices to the rproc_handle_rsc
* lookup table, so please keep them sane. Moreover, @RSC_LAST is used to
* check the validity of an index before the lookup table is accessed, so
* please update it as needed.
*/
enum fw_resource_type
{
RSC_CARVEOUT = 0,
RSC_DEVMEM = 1,
RSC_TRACE = 2,
RSC_VDEV = 3,
RSC_LAST = 4,
RSC_VENDOR_START = 128,
RSC_VENDOR_END = 512,
};
#define FW_RSC_U64_ADDR_ANY 0xFFFFFFFFFFFFFFFFUL
#define FW_RSC_U32_ADDR_ANY 0xFFFFFFFFUL
/**
* struct fw_rsc_carveout - physically contiguous memory request
* @da: device address
* @pa: physical address
* @len: length (in bytes)
* @flags: iommu protection flags
* @reserved: reserved (must be zero)
* @name: human-readable name of the requested memory region
*
* This resource entry requests the host to allocate a physically contiguous
* memory region.
*
* These request entries should precede other firmware resource entries,
* as other entries might request placing other data objects inside
* these memory regions (e.g. data/code segments, trace resource entries, ...).
*
* Allocating memory this way helps utilizing the reserved physical memory
* (e.g. CMA) more efficiently, and also minimizes the number of TLB entries
* needed to map it (in case @rproc is using an IOMMU). Reducing the TLB
* pressure is important; it may have a substantial impact on performance.
*
* If the firmware is compiled with static addresses, then @da should specify
* the expected device address of this memory region. If @da is set to
* FW_RSC_ADDR_ANY, then the host will dynamically allocate it, and then
* overwrite @da with the dynamically allocated address.
*
* We will always use @da to negotiate the device addresses, even if it
* isn't using an iommu. In that case, though, it will obviously contain
* physical addresses.
*
* Some remote remoteprocs needs to know the allocated physical address
* even if they do use an iommu. This is needed, e.g., if they control
* hardware accelerators which access the physical memory directly (this
* is the case with OMAP4 for instance). In that case, the host will
* overwrite @pa with the dynamically allocated physical address.
* Generally we don't want to expose physical addresses if we don't have to
* (remote remoteprocs are generally _not_ trusted), so we might want to
* change this to happen _only_ when explicitly required by the hardware.
*
* @flags is used to provide IOMMU protection flags, and @name should
* (optionally) contain a human readable name of this carveout region
* (mainly for debugging purposes).
*/
METAL_PACKED_BEGIN
struct fw_rsc_carveout
{
uint32_t type;
uint32_t da;
uint32_t pa;
uint32_t len;
uint32_t flags;
uint32_t reserved;
uint8_t name[RPROC_MAX_NAME_LEN];
} METAL_PACKED_END;
/**
* struct fw_rsc_devmem - iommu mapping request
* @da: device address
* @pa: physical address
* @len: length (in bytes)
* @flags: iommu protection flags
* @reserved: reserved (must be zero)
* @name: human-readable name of the requested region to be mapped
*
* This resource entry requests the host to iommu map a physically contiguous
* memory region. This is needed in case the remote remoteproc requires
* access to certain memory-based peripherals; _never_ use it to access
* regular memory.
*
* This is obviously only needed if the remote remoteproc is accessing memory
* via an iommu.
*
* @da should specify the required device address, @pa should specify
* the physical address we want to map, @len should specify the size of
* the mapping and @flags is the IOMMU protection flags. As always, @name may
* (optionally) contain a human readable name of this mapping (mainly for
* debugging purposes).
*
* Note: at this point we just "trust" those devmem entries to contain valid
* physical addresses, but this isn't safe and will be changed: eventually we
* want remoteproc implementations to provide us ranges of physical addresses
* the firmware is allowed to request, and not allow firmwares to request
* access to physical addresses that are outside those ranges.
*/
METAL_PACKED_BEGIN
struct fw_rsc_devmem
{
uint32_t type;
uint32_t da;
uint32_t pa;
uint32_t len;
uint32_t flags;
uint32_t reserved;
uint8_t name[RPROC_MAX_NAME_LEN];
} METAL_PACKED_END;
/**
* struct fw_rsc_trace - trace buffer declaration
* @da: device address
* @len: length (in bytes)
* @reserved: reserved (must be zero)
* @name: human-readable name of the trace buffer
*
* This resource entry provides the host information about a trace buffer
* into which the remote remoteproc will write log messages.
*
* @da specifies the device address of the buffer, @len specifies
* its size, and @name may contain a human readable name of the trace buffer.
*
* After booting the remote remoteproc, the trace buffers are exposed to the
* user via debugfs entries (called trace0, trace1, etc..).
*/
METAL_PACKED_BEGIN
struct fw_rsc_trace
{
uint32_t type;
uint32_t da;
uint32_t len;
uint32_t reserved;
uint8_t name[RPROC_MAX_NAME_LEN];
} METAL_PACKED_END;
/**
* struct fw_rsc_vdev_vring - vring descriptor entry
* @da: device address
* @align: the alignment between the consumer and producer parts of the vring
* @num: num of buffers supported by this vring (must be power of two)
* @notifyid is a unique rproc-wide notify index for this vring. This notify
* index is used when kicking a remote remoteproc, to let it know that this
* vring is triggered.
* @reserved: reserved (must be zero)
*
* This descriptor is not a resource entry by itself; it is part of the
* vdev resource type (see below).
*
* Note that @da should either contain the device address where
* the remote remoteproc is expecting the vring, or indicate that
* dynamically allocation of the vring's device address is supported.
*/
METAL_PACKED_BEGIN
struct fw_rsc_vdev_vring
{
uint32_t da;
uint32_t align;
uint32_t num;
uint32_t notifyid;
uint32_t reserved;
} METAL_PACKED_END;
/**
* struct fw_rsc_vdev - virtio device header
* @id: virtio device id (as in virtio_ids.h)
* @notifyid is a unique rproc-wide notify index for this vdev. This notify
* index is used when kicking a remote remoteproc, to let it know that the
* status/features of this vdev have changes.
* @dfeatures specifies the virtio device features supported by the firmware
* @gfeatures is a place holder used by the host to write back the
* negotiated features that are supported by both sides.
* @config_len is the size of the virtio config space of this vdev. The config
* space lies in the resource table immediate after this vdev header.
* @status is a place holder where the host will indicate its virtio progress.
* @num_of_vrings indicates how many vrings are described in this vdev header
* @reserved: reserved (must be zero)
* @vring is an array of @num_of_vrings entries of 'struct fw_rsc_vdev_vring'.
*
* This resource is a virtio device header: it provides information about
* the vdev, and is then used by the host and its peer remote remoteprocs
* to negotiate and share certain virtio properties.
*
* By providing this resource entry, the firmware essentially asks remoteproc
* to statically allocate a vdev upon registration of the rproc (dynamic vdev
* allocation is not yet supported).
*
* Note: unlike virtualization systems, the term 'host' here means
* the Linux side which is running remoteproc to control the remote
* remoteprocs. We use the name 'gfeatures' to comply with virtio's terms,
* though there isn't really any virtualized guest OS here: it's the host
* which is responsible for negotiating the final features.
* Yeah, it's a bit confusing.
*
* Note: immediately following this structure is the virtio config space for
* this vdev (which is specific to the vdev; for more info, read the virtio
* spec). the size of the config space is specified by @config_len.
*/
METAL_PACKED_BEGIN
struct fw_rsc_vdev
{
uint32_t type;
uint32_t id;
uint32_t notifyid;
uint32_t dfeatures;
uint32_t gfeatures;
uint32_t config_len;
uint8_t status;
uint8_t num_of_vrings;
uint8_t reserved[2];
struct fw_rsc_vdev_vring vring[0];
} METAL_PACKED_END;
/**
* struct fw_rsc_vendor - remote processor vendor specific resource
* @len: length of the resource
*
* This resource entry tells the host the vendor specific resource
* required by the remote.
*
* These request entries should precede other shared resource entries
* such as vdevs, vrings.
*/
METAL_PACKED_BEGIN
struct fw_rsc_vendor
{
uint32_t type;
uint32_t len;
} METAL_PACKED_END;
#if defined __cplusplus
}
#endif
#endif /* REMOTEPROC_H_ */

View File

@ -0,0 +1,52 @@
/*
* Copyright (c) 2014, Mentor Graphics Corporation
* All rights reserved.
* Copyright (c) 2015 Xilinx, Inc. All rights reserved.
* Copyright 2020 NXP.
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/* This file populates resource table for BM remote
* for use by the Linux Master */
#ifndef RSC_TABLE_H_
#define RSC_TABLE_H_
#include <stddef.h>
#include <remoteproc.h>
#if defined __cplusplus
extern "C" {
#endif
#define NO_RESOURCE_ENTRIES (1)
#define RSC_VDEV_FEATURE_NS (1) /* Support name service announcement */
/* Resource table for the given remote */
METAL_PACKED_BEGIN
struct remote_resource_table
{
uint32_t version;
uint32_t num;
uint32_t reserved[2];
uint32_t offset[NO_RESOURCE_ENTRIES];
/* rpmsg vdev entry for user app communication */
struct fw_rsc_vdev user_vdev;
struct fw_rsc_vdev_vring user_vring0;
struct fw_rsc_vdev_vring user_vring1;
} METAL_PACKED_END;
/*
* Copy resource table to shared memory base for early M4 boot case.
* In M4 early boot case, Linux kernel need to get resource table before file system gets loaded.
*/
void copyResourceTable(void);
#if defined __cplusplus
}
#endif
#endif /* RSC_TABLE_H_ */

View File

@ -0,0 +1,260 @@
/*
** ###################################################################
** Processors: MIMX8ML8CVNKZ
** MIMX8ML8DVNLZ
**
** Compiler: GNU C Compiler
** Reference manual: IMX8MPRM, Rev.D, 10/2020
** Version: rev. 4.0, 2020-11-16
** Build: b201031
**
** Abstract:
** Linker file for the GNU C Compiler
**
** Copyright 2016 Freescale Semiconductor, Inc.
** Copyright 2016-2020 NXP
** All rights reserved.
**
** SPDX-License-Identifier: BSD-3-Clause
**
** http: www.nxp.com
** mail: support@nxp.com
**
** ###################################################################
*/
/*************************************************
File name: link.lds
Description: imx8mp linker script
History:
1. Date: 2025-02-26
Author: AIIT XUOS Lab
Modification:
1. add imx8mp linker script
*************************************************/
/* Entry Point */
ENTRY(Reset_Handler)
HEAP_SIZE = DEFINED(__heap_size__) ? __heap_size__ : 0x20000;
STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x20000;
/* Specify the memory areas */
MEMORY
{
m_interrupts (RX) : ORIGIN = 0x80000000, LENGTH = 0x00000400
m_text (RX) : ORIGIN = 0x80000400, LENGTH = 0x001FFC00
m_data (RW) : ORIGIN = 0x80200000, LENGTH = 0x00200000
m_data2 (RW) : ORIGIN = 0x80400000, LENGTH = 0x00C00000
}
/* Define output sections */
SECTIONS
{
/* The startup code goes first into internal RAM */
.interrupts :
{
__VECTOR_TABLE = .;
__Vectors = .;
. = ALIGN(4);
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(4);
} > m_interrupts
.resource_table :
{
. = ALIGN(8);
KEEP(*(.resource_table)) /* Resource table */
. = ALIGN(8);
} > m_text
/* The program code and other data goes into internal RAM */
.text :
{
. = ALIGN(4);
*(.text) /* .text sections (code) */
*(.text*) /* .text* sections (code) */
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
*(.glue_7) /* glue arm to thumb code */
*(.glue_7t) /* glue thumb to arm code */
*(.eh_frame)
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN(4);
/* section information for shell */
. = ALIGN(4);
_shell_command_start = .;
KEEP (*(shellCommand))
_shell_command_end = .;
. = ALIGN(4);
__isrtbl_idx_start = .;
KEEP(*(.isrtbl.idx))
__isrtbl_start = .;
KEEP(*(.isrtbl))
__isrtbl_end = .;
. = ALIGN(4);
PROVIDE(g_service_table_start = ABSOLUTE(.));
KEEP(*(.g_service_table))
PROVIDE(g_service_table_end = ABSOLUTE(.));
} > m_text
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > m_text
.ARM :
{
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
} > m_text
.ctors :
{
__CTOR_LIST__ = .;
/* gcc uses crtbegin.o to find the start of
the constructors, so we make sure it is
first. Because this is a wildcard, it
doesn't matter if the user does not
actually link against crtbegin.o; the
linker won't look for a file to match a
wildcard. The wildcard also means that it
doesn't matter which directory crtbegin.o
is in. */
KEEP (*crtbegin.o(.ctors))
KEEP (*crtbegin?.o(.ctors))
/* We don't want to include the .ctor section from
from the crtend.o file until after the sorted ctors.
The .ctor section from the crtend file contains the
end of ctors marker and it must be last */
KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
__CTOR_END__ = .;
} > m_text
.dtors :
{
__DTOR_LIST__ = .;
KEEP (*crtbegin.o(.dtors))
KEEP (*crtbegin?.o(.dtors))
KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
__DTOR_END__ = .;
} > m_text
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array*))
PROVIDE_HIDDEN (__preinit_array_end = .);
} > m_text
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array*))
PROVIDE_HIDDEN (__init_array_end = .);
} > m_text
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT(.fini_array.*)))
KEEP (*(.fini_array*))
PROVIDE_HIDDEN (__fini_array_end = .);
} > m_text
__etext = .; /* define a global symbol at end of code */
__DATA_ROM = .; /* Symbol is used by startup for data initialization */
.data : AT(__DATA_ROM)
{
. = ALIGN(4);
__DATA_RAM = .;
__data_start__ = .; /* create a global symbol at data start */
*(.data) /* .data sections */
*(.data*) /* .data* sections */
KEEP(*(.jcr*))
. = ALIGN(4);
__data_end__ = .; /* define a global symbol at data end */
} > m_data
__CACHE_REGION_START = ORIGIN(m_interrupts);
__CACHE_REGION_SIZE = LENGTH(m_interrupts) + LENGTH(m_text) + LENGTH(m_data);
__NDATA_ROM = __DATA_ROM + SIZEOF(.data); /* Symbol is used by startup for ncache data initialization */
.ncache.init : AT(__NDATA_ROM)
{
__noncachedata_start__ = .; /* create a global symbol at ncache data start */
*(NonCacheable.init)
. = ALIGN(4);
__noncachedata_init_end__ = .; /* create a global symbol at initialized ncache data end */
} > m_data2
. = __noncachedata_init_end__;
.ncache :
{
*(NonCacheable)
. = ALIGN(4);
__noncachedata_end__ = .; /* define a global symbol at ncache data end */
} > m_data2
__DATA_END = __DATA_ROM + (__data_end__ - __data_start__);
text_end = ORIGIN(m_text) + LENGTH(m_text);
ASSERT(__DATA_END <= text_end, "region m_text overflowed with text and data")
/* Uninitialized data section */
.bss :
{
/* This is used by the startup in order to initialize the .bss section */
. = ALIGN(4);
__START_BSS = .;
__bss_start__ = .;
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
__bss_end__ = .;
__END_BSS = .;
} > m_data
.heap :
{
. = ALIGN(8);
__end__ = .;
PROVIDE(end = .);
__HeapBase = .;
. += HEAP_SIZE;
__HeapLimit = .;
__heap_limit = .; /* Add for _sbrk */
} > m_data
.stack :
{
. = ALIGN(8);
/* __HeapLimit = .; */
/* __heap_limit = .; Add for _sbrk */
. += STACK_SIZE;
} > m_data
/* Initializes stack on the end of block */
__StackTop = ORIGIN(m_data) + LENGTH(m_data);
__StackLimit = __StackTop - STACK_SIZE;
PROVIDE(__stack = __StackTop);
.ARM.attributes 0 : { *(.ARM.attributes) }
ASSERT(__StackLimit >= __HeapLimit, "region m_data overflowed with stack and heap")
}

View File

@ -0,0 +1,3 @@
SRC_DIR := lib
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,5 @@
SRC_DIR := virtio
SRC_DIR += rpmsg_lite
SRC_DIR += common
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,5 @@
SRC_DIR :=
SRC_FILES := $(wildcard *.c)
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,113 @@
/*
* Copyright (c) 2014, Mentor Graphics Corporation
* Copyright 2019 NXP
* 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 Mentor Graphics Corporation 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.
*/
/**************************************************************************
* FILE NAME
*
* llist.c
*
* COMPONENT
*
* OpenAMP stack.
*
* DESCRIPTION
*
* Source file for basic linked list service.
*
**************************************************************************/
#include "llist.h"
#define LIST_NULL ((void *)0)
/*!
* add_to_list
*
* Places new element at the start of the list.
*
* @param head - list head
* @param node - new element to add
*
*/
void add_to_list(struct llist **head, struct llist *node)
{
if (node == LIST_NULL)
{
return;
}
if (*head != LIST_NULL)
{
/* Place the new element at the start of list. */
node->next = *head;
node->prev = LIST_NULL;
(*head)->prev = node;
*head = node;
}
else
{
/* List is empty - assign new element to list head. */
*head = node;
(*head)->next = LIST_NULL;
(*head)->prev = LIST_NULL;
}
}
/*!
* remove_from_list
*
* Removes the given element from the list.
*
* @param head - list head
* @param element - element to remove from list
*
*/
void remove_from_list(struct llist **head, struct llist *node)
{
if ((*head == LIST_NULL) || (node == LIST_NULL))
{
return;
}
if (node == *head)
{
/* First element has to be removed. */
*head = (*head)->next;
}
else if (node->next == LIST_NULL)
{
/* Last element has to be removed. */
node->prev->next = node->next;
}
else
{
/* Intermediate element has to be removed. */
node->prev->next = node->next;
node->next->prev = node->prev;
}
}

View File

@ -0,0 +1,62 @@
/*
* Copyright (c) 2014, Mentor Graphics Corporation
* Copyright 2019 NXP
* 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 Mentor Graphics Corporation 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.
*/
/**************************************************************************
* FILE NAME
*
* llist.h
*
* COMPONENT
*
* OpenAMP stack.
*
* DESCRIPTION
*
* Header file for linked list service.
*
**************************************************************************/
#ifndef LLIST_H_
#define LLIST_H_
#include <stdint.h>
struct llist
{
void *data;
uint32_t attr;
struct llist *next;
struct llist *prev;
};
void add_to_list(struct llist **head, struct llist *node);
void remove_from_list(struct llist **head, struct llist *node);
#endif /* LLIST_H_ */

View File

@ -0,0 +1,60 @@
/*
* Copyright 2019 NXP
* All rights reserved.
*
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef RPMSG_PLATFORM_H_
#define RPMSG_PLATFORM_H_
#include <stdint.h>
/* RPMSG MU channel index */
#define RPMSG_MU_CHANNEL (1)
/*
* Linux requires the ALIGN to 0x1000(4KB) instead of 0x80
*/
#ifndef VRING_ALIGN
#define VRING_ALIGN (0x1000U)
#endif
/* contains pool of descriptors and two circular buffers */
#ifndef VRING_SIZE
#define VRING_SIZE (0x8000UL)
#endif
/* size of shared memory + 2*VRING size */
#define RL_VRING_OVERHEAD (2UL * VRING_SIZE)
#define RL_GET_VQ_ID(link_id, queue_id) (((queue_id)&0x1U) | (((link_id) << 1U) & 0xFFFFFFFEU))
#define RL_GET_LINK_ID(id) (((id)&0xFFFFFFFEU) >> 1U)
#define RL_GET_Q_ID(id) ((id)&0x1U)
#define RL_PLATFORM_IMX8MP_M7_USER_LINK_ID (0U)
#define RL_PLATFORM_HIGHEST_LINK_ID (15U)
/* platform interrupt related functions */
int32_t platform_init_interrupt(uint32_t vector_id, void *isr_data);
int32_t platform_deinit_interrupt(uint32_t vector_id);
int32_t platform_interrupt_enable(uint32_t vector_id);
int32_t platform_interrupt_disable(uint32_t vector_id);
int32_t platform_in_isr(void);
void platform_notify(uint32_t vector_id);
/* platform low-level time-delay (busy loop) */
void platform_time_delay(uint32_t num_msec);
/* platform memory functions */
void platform_map_mem_region(uint32_t vrt_addr, uint32_t phy_addr, uint32_t size, uint32_t flags);
void platform_cache_all_flush_invalidate(void);
void platform_cache_disable(void);
uint32_t platform_vatopa(void *addr);
void *platform_patova(uint32_t addr);
/* platform init/deinit */
int32_t platform_init(void);
int32_t platform_deinit(void);
#endif /* RPMSG_PLATFORM_H_ */

View File

@ -0,0 +1,114 @@
/*
* Copyright (c) 2014, Mentor Graphics Corporation
* Copyright (c) 2016 Freescale Semiconductor, Inc.
* Copyright 2016 NXP
* 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.
*/
/**************************************************************************
* FILE NAME
*
* rpmsg_compiler.h
*
* DESCRIPTION
*
* This file defines compiler-specific macros.
*
***************************************************************************/
#ifndef RPMSG_COMPILER_H_
#define RPMSG_COMPILER_H_
/* IAR ARM build tools */
#if defined(__ICCARM__)
#include <intrinsics.h>
#define MEM_BARRIER() __DSB()
#ifndef RL_PACKED_BEGIN
#define RL_PACKED_BEGIN __packed
#endif
#ifndef RL_PACKED_END
#define RL_PACKED_END
#endif
/* ARM GCC */
#elif defined(__CC_ARM) || (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050))
#if (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050))
#include <arm_compat.h>
#endif
#define MEM_BARRIER() __schedule_barrier()
#ifndef RL_PACKED_BEGIN
#define RL_PACKED_BEGIN _Pragma("pack(1U)")
#endif
#ifndef RL_PACKED_END
#define RL_PACKED_END _Pragma("pack()")
#endif
/* XCC HiFi4 */
#elif defined(__XCC__)
/*
* The XCC HiFi4 compiler is compatible with GNU compiler, with restrictions.
* For ARM __schedule_barrier, there's no identical intrinsic in HiFi4.
* A complete synchronization barrier would require initialize and wait ops.
* Here use NOP instead, similar to ARM __nop.
*/
#define MEM_BARRIER() __asm__ __volatile__("nop" : : : "memory")
#ifndef RL_PACKED_BEGIN
#define RL_PACKED_BEGIN
#endif
#ifndef RL_PACKED_END
#define RL_PACKED_END __attribute__((__packed__))
#endif
/* GNUC */
#elif defined(__GNUC__)
#define MEM_BARRIER() __asm__ volatile("dsb" : : : "memory")
#ifndef RL_PACKED_BEGIN
#define RL_PACKED_BEGIN
#endif
#ifndef RL_PACKED_END
#define RL_PACKED_END __attribute__((__packed__))
#endif
#else
/* There is no default definition here to avoid wrong structures packing in case of not supported compiler */
#error Please implement the structure packing macros for your compiler here!
#endif
#endif /* RPMSG_COMPILER_H_ */

View File

@ -0,0 +1,138 @@
// /*
// * Copyright (c) 2014, Mentor Graphics Corporation
// * All rights reserved.
// * Copyright (c) 2015 Xilinx, Inc. All rights reserved.
// * Copyright 2016 Freescale Semiconductor, Inc. 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 Mentor Graphics Corporation 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.
// */
// #ifndef _RPMSG_CONFIG_H
// #define _RPMSG_CONFIG_H
// /* RPMsg config values */
// /* START { */
// #define RL_MS_PER_INTERVAL (1)
// #define RL_BUFFER_PAYLOAD_SIZE (496)
// #define RL_API_HAS_ZEROCOPY (1)
// #define RL_USE_STATIC_API (1)
// #define RL_USE_MCMGR_IPC_ISR_HANDLER (1)
// #define RL_ASSERT(x) \
// do \
// { \
// if (!(x)) \
// while (1) \
// ; \
// } while (0);
// /* } END */
// #endif /* _RPMSG_CONFIG_H */
/*
* Copyright (c) 2014, Mentor Graphics Corporation
* Copyright (c) 2015 Xilinx, Inc.
* Copyright 2019-2020 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef RPMSG_CONFIG_H_
#define RPMSG_CONFIG_H_
/*!
* @addtogroup config
* @{
* @file
*/
//! @name Configuration options
//@{
//! @def RL_MS_PER_INTERVAL
//!
//! Delay in milliseconds used in non-blocking API functions for polling.
//! The default value is 1.
#define RL_MS_PER_INTERVAL (1)
//! @def RL_BUFFER_PAYLOAD_SIZE
//!
//! Size of the buffer payload, it must be equal to (240, 496, 1008, ...)
//! [2^n - 16].
//! The default value is 496U.
#define RL_BUFFER_PAYLOAD_SIZE (496U)
//! @def RL_BUFFER_COUNT
//!
//! Number of the buffers, it must be power of two (2, 4, ...).
//! The default value is 2U.
#define RL_BUFFER_COUNT (256U)
//! @def RL_API_HAS_ZEROCOPY
//!
//! Zero-copy API functions enabled/disabled.
//! The default value is 1 (enabled).
#define RL_API_HAS_ZEROCOPY (1)
//! @def RL_USE_STATIC_API
//!
//! Static API functions (no dynamic allocation) enabled/disabled.
//! The default value is 0 (static API disabled).
#define RL_USE_STATIC_API (0)
//! @def RL_CLEAR_USED_BUFFERS
//!
//! Clearing used buffers before returning back to the pool of free buffers
//! enabled/disabled.
//! The default value is 0 (disabled).
#define RL_CLEAR_USED_BUFFERS (0)
//! @def RL_USE_MCMGR_IPC_ISR_HANDLER
//!
//! When enabled IPC interrupts are managed by the Multicore Manager (IPC
//! interrupts router), when disabled RPMsg-Lite manages IPC interrupts
//! by itself.
//! The default value is 0 (no MCMGR IPC ISR handler used).
#define RL_USE_MCMGR_IPC_ISR_HANDLER (0)
//! @def RL_USE_ENVIRONMENT_CONTEXT
//!
//! When enabled the environment layer uses its own context.
//! Added for QNX port mainly, but can be used if required.
//! The default value is 0 (no context, saves some RAM).
#define RL_USE_ENVIRONMENT_CONTEXT (0)
//! @def RL_DEBUG_CHECK_BUFFERS
//!
//! Do not use in RPMsg-Lite to Linux configuration
#define RL_DEBUG_CHECK_BUFFERS (0)
//@}
#endif /* RPMSG_CONFIG_H_ */

View File

@ -0,0 +1,165 @@
/*
* Copyright (c) 2014, Mentor Graphics Corporation
* Copyright (c) 2015 Xilinx, Inc.
* Copyright (c) 2016 Freescale Semiconductor, Inc.
* Copyright 2016-2020 NXP
* 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.
*/
#ifndef RPMSG_DEFAULT_CONFIG_H_
#define RPMSG_DEFAULT_CONFIG_H_
#define RL_USE_CUSTOM_CONFIG (1)
#if RL_USE_CUSTOM_CONFIG
#include "rpmsg_config.h"
#endif
/*!
* @addtogroup config
* @{
* @file
*/
//! @name Configuration options
//@{
//! @def RL_MS_PER_INTERVAL
//!
//! Delay in milliseconds used in non-blocking API functions for polling.
//! The default value is 1.
#ifndef RL_MS_PER_INTERVAL
#define RL_MS_PER_INTERVAL (1)
#endif
//! @def RL_BUFFER_PAYLOAD_SIZE
//!
//! Size of the buffer payload, it must be equal to (240, 496, 1008, ...)
//! [2^n - 16].
//! The default value is 496U.
#ifndef RL_BUFFER_PAYLOAD_SIZE
#define RL_BUFFER_PAYLOAD_SIZE (496U)
#endif
//! @def RL_BUFFER_COUNT
//!
//! Number of the buffers, it must be power of two (2, 4, ...).
//! The default value is 2U.
#ifndef RL_BUFFER_COUNT
#define RL_BUFFER_COUNT (2U)
#endif
//! @def RL_API_HAS_ZEROCOPY
//!
//! Zero-copy API functions enabled/disabled.
//! The default value is 1 (enabled).
#ifndef RL_API_HAS_ZEROCOPY
#define RL_API_HAS_ZEROCOPY (1)
#endif
//! @def RL_USE_STATIC_API
//!
//! Static API functions (no dynamic allocation) enabled/disabled.
//! The default value is 0 (static API disabled).
#ifndef RL_USE_STATIC_API
#define RL_USE_STATIC_API (0)
#endif
//! @def RL_CLEAR_USED_BUFFERS
//!
//! Clearing used buffers before returning back to the pool of free buffers
//! enabled/disabled.
//! The default value is 0 (disabled).
#ifndef RL_CLEAR_USED_BUFFERS
#define RL_CLEAR_USED_BUFFERS (0)
#endif
//! @def RL_USE_MCMGR_IPC_ISR_HANDLER
//!
//! When enabled IPC interrupts are managed by the Multicore Manager (IPC
//! interrupts router), when disabled RPMsg-Lite manages IPC interrupts
//! by itself.
//! The default value is 0 (no MCMGR IPC ISR handler used).
#ifndef RL_USE_MCMGR_IPC_ISR_HANDLER
#define RL_USE_MCMGR_IPC_ISR_HANDLER (0)
#endif
//! @def RL_USE_ENVIRONMENT_CONTEXT
//!
//! When enabled the environment layer uses its own context.
//! Added for QNX port mainly, but can be used if required.
//! The default value is 0 (no context, saves some RAM).
#ifndef RL_USE_ENVIRONMENT_CONTEXT
#define RL_USE_ENVIRONMENT_CONTEXT (0)
#endif
//! @def RL_DEBUG_CHECK_BUFFERS
//!
//! Do not use in RPMsg-Lite to Linux configuration
#ifndef RL_DEBUG_CHECK_BUFFERS
#define RL_DEBUG_CHECK_BUFFERS (0)
#endif
//! @def RL_ALLOW_CONSUMED_BUFFERS_NOTIFICATION
//!
//! When enabled the opposite side is notified each time received buffers
//! are consumed and put into the queue of available buffers.
//! Enable this option in RPMsg-Lite to Linux configuration to allow unblocking
//! of the Linux blocking send.
//! The default value is 0 (RPMsg-Lite to RPMsg-Lite communication).
#ifndef RL_ALLOW_CONSUMED_BUFFERS_NOTIFICATION
#define RL_ALLOW_CONSUMED_BUFFERS_NOTIFICATION (0)
#endif
//! @def RL_HANG
//!
//! Default implementation of hang assert function
static inline void RL_HANG(void)
{
for (;;)
{
}
}
//! @def RL_ASSERT
//!
//! Assert implementation.
#ifndef RL_ASSERT
#define RL_ASSERT_BOOL(b) \
do \
{ \
if (!(b)) \
{ \
RL_HANG(); \
} \
} while (0 == 1);
#define RL_ASSERT(x) RL_ASSERT_BOOL((int32_t)(x) != 0)
#endif
//@}
#endif /* RPMSG_DEFAULT_CONFIG_H_ */

View File

@ -0,0 +1,571 @@
/*
* Copyright (c) 2014, Mentor Graphics Corporation
* Copyright (c) 2015 Xilinx, Inc.
* Copyright (c) 2016 Freescale Semiconductor, Inc.
* Copyright 2016-2019 NXP
* 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.
*/
/**************************************************************************
* FILE NAME
*
* rpmsg_env.h
*
* COMPONENT
*
* OpenAMP stack.
*
* DESCRIPTION
*
* This file defines abstraction layer for OpenAMP stack. The implementor
* must provide definition of all the functions.
*
* DATA STRUCTURES
*
* none
*
* FUNCTIONS
*
* env_allocate_memory
* env_free_memory
* env_memset
* env_memcpy
* env_strncpy
* env_print
* env_map_vatopa
* env_map_patova
* env_mb
* env_rmb
* env_wmb
* env_create_mutex
* env_delete_mutex
* env_lock_mutex
* env_unlock_mutex
* env_sleep_msec
* env_disable_interrupt
* env_enable_interrupt
* env_create_queue
* env_delete_queue
* env_put_queue
* env_get_queue
*
**************************************************************************/
#ifndef RPMSG_ENV_H_
#define RPMSG_ENV_H_
#include <stdio.h>
#include <stdint.h>
#include "rpmsg_default_config.h"
#include "rpmsg_platform.h"
/*!
* env_init_rpmsg
*
* Initializes OS/BM environment.
*
* @param env_context Pointer to preallocated environment context data
* @param env_init_data Initialization data for the environment layer
*
* @returns - execution status
*/
#if defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1)
int32_t env_init_rpmsg(void **env_context, void *env_init_data);
#else
int32_t env_init_rpmsg(void);
#endif
/*!
* env_deinit
*
* Uninitializes OS/BM environment.
*
* @param env_context Pointer to environment context data
*
* @returns - execution status
*/
#if defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1)
int32_t env_deinit(void *env_context);
#else
int32_t env_deinit(void);
#endif
/*!
* -------------------------------------------------------------------------
*
* Dynamic memory management functions. The parameters
* are similar to standard c functions.
*
*-------------------------------------------------------------------------
**/
/*!
* env_allocate_memory
*
* Allocates memory with the given size.
*
* @param size - size of memory to allocate
*
* @return - pointer to allocated memory
*/
void *env_allocate_memory(uint32_t size);
/*!
* env_free_memory
*
* Frees memory pointed by the given parameter.
*
* @param ptr - pointer to memory to free
*/
void env_free_memory(void *ptr);
/*!
* -------------------------------------------------------------------------
*
* RTL Functions
*
*-------------------------------------------------------------------------
*/
void env_memset(void *ptr, int32_t value, uint32_t size);
void env_memcpy(void *dst, void const *src, uint32_t len);
int32_t env_strcmp(const char *dst, const char *src);
void env_strncpy(char *dest, const char *src, uint32_t len);
int32_t env_strncmp(char *dest, const char *src, uint32_t len);
#define env_print(...) printf(__VA_ARGS__)
/*!
*-----------------------------------------------------------------------------
*
* Functions to convert physical address to virtual address and vice versa.
*
*-----------------------------------------------------------------------------
*/
/*!
* env_map_vatopa
*
* Converts logical address to physical address
*
* @param env Pointer to environment context data
* @param address Pointer to logical address
*
* @return - physical address
*/
#if defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1)
uint32_t env_map_vatopa(void *env, void *address);
#else
uint32_t env_map_vatopa(void *address);
#endif
/*!
* env_map_patova
*
* Converts physical address to logical address
*
* @param env_context Pointer to environment context data
* @param address Pointer to physical address
*
* @return - logical address
*
*/
#if defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1)
void *env_map_patova(void *env, uint32_t address);
#else
void *env_map_patova(uint32_t address);
#endif
/*!
*-----------------------------------------------------------------------------
*
* Abstractions for memory barrier instructions.
*
*-----------------------------------------------------------------------------
*/
/*!
* env_mb
*
* Inserts memory barrier.
*/
void env_mb(void);
/*!
* env_rmb
*
* Inserts read memory barrier
*/
void env_rmb(void);
/*!
* env_wmb
*
* Inserts write memory barrier
*/
void env_wmb(void);
/*!
*-----------------------------------------------------------------------------
*
* Abstractions for OS lock primitives.
*
*-----------------------------------------------------------------------------
*/
/*!
* env_create_mutex
*
* Creates a mutex with given initial count.
*
* @param lock - pointer to created mutex
* @param count - initial count 0 or 1
*
* @return - status of function execution
*/
int32_t env_create_mutex(void **lock, int32_t count);
/*!
* env_delete_mutex
*
* Deletes the given lock.
*
* @param lock - mutex to delete
*/
void env_delete_mutex(void *lock);
/*!
* env_lock_mutex
*
* Tries to acquire the lock, if lock is not available then call to
* this function will suspend.
*
* @param lock - mutex to lock
*
*/
void env_lock_mutex(void *lock);
/*!
* env_unlock_mutex
*
* Releases the given lock.
*
* @param lock - mutex to unlock
*/
void env_unlock_mutex(void *lock);
/*!
* env_create_sync_lock
*
* Creates a synchronization lock primitive. It is used
* when signal has to be sent from the interrupt context to main
* thread context.
*
* @param lock - pointer to created sync lock object
* @param state - initial state , lock or unlocked
*
* @returns - status of function execution
*/
#define LOCKED 0
#define UNLOCKED 1
int32_t env_create_sync_lock(void **lock, int32_t state);
/*!
* env_create_sync_lock
*
* Deletes given sync lock object.
*
* @param lock - sync lock to delete.
*
*/
void env_delete_sync_lock(void *lock);
/*!
* env_acquire_sync_lock
*
* Tries to acquire the sync lock.
*
* @param lock - sync lock to acquire.
*/
void env_acquire_sync_lock(void *lock);
/*!
* env_release_sync_lock
*
* Releases synchronization lock.
*
* @param lock - sync lock to release.
*/
void env_release_sync_lock(void *lock);
/*!
* env_sleep_msec
*
* Suspends the calling thread for given time in msecs.
*
* @param num_msec - delay in msecs
*/
void env_sleep_msec(uint32_t num_msec);
/*!
* env_register_isr
*
* Registers interrupt handler data for the given interrupt vector.
*
* @param env Pointer to environment context data
* @param vector_id Virtual interrupt vector number
* @param data Interrupt handler data (virtqueue)
*/
#if defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1)
void env_register_isr(void *env, uint32_t vector_id, void *data);
#else
void env_register_isr(uint32_t vector_id, void *data);
#endif
/*!
* env_unregister_isr
*
* Unregisters interrupt handler data for the given interrupt vector.
*
* @param env Pointer to environment context data
* @param vector_id Virtual interrupt vector number
*/
#if defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1)
void env_unregister_isr(void *env, uint32_t vector_id);
#else
void env_unregister_isr(uint32_t vector_id);
#endif
/*!
* env_enable_interrupt
*
* Enables the given interrupt
*
* @param env Pointer to environment context data
* @param vector_id Virtual interrupt vector number
*/
#if defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1)
void env_enable_interrupt(void *env, uint32_t vector_id);
#else
void env_enable_interrupt(uint32_t vector_id);
#endif
/*!
* env_disable_interrupt
*
* Disables the given interrupt.
*
* @param env Pointer to environment context data
* @param vector_id Virtual interrupt vector number
*/
#if defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1)
void env_disable_interrupt(void *env, uint32_t vector_id);
#else
void env_disable_interrupt(uint32_t vector_id);
#endif
/*!
* env_map_memory
*
* Enables memory mapping for given memory region.
*
* @param pa - physical address of memory
* @param va - logical address of memory
* @param size - memory size
* param flags - flags for cache/uncached and access type
*
* Currently only first byte of flag parameter is used and bits mapping is defined as follow;
*
* Cache bits
* 0x0000_0001 = No cache
* 0x0000_0010 = Write back
* 0x0000_0100 = Write through
* 0x0000_x000 = Not used
*
* Memory types
*
* 0x0001_xxxx = Memory Mapped
* 0x0010_xxxx = IO Mapped
* 0x0100_xxxx = Shared
* 0x1000_xxxx = TLB
*/
/* Macros for caching scheme used by the shared memory */
#define UNCACHED (1 << 0)
#define WB_CACHE (1 << 1)
#define WT_CACHE (1 << 2)
/* Memory Types */
#define MEM_MAPPED (1 << 4)
#define IO_MAPPED (1 << 5)
#define SHARED_MEM (1 << 6)
#define TLB_MEM (1 << 7)
void env_map_memory(uint32_t pa, uint32_t va, uint32_t size, uint32_t flags);
/*!
* env_get_timestamp
*
* Returns a 64 bit time stamp.
*
*
*/
uint64_t env_get_timestamp(void);
/*!
* env_disable_cache
*
* Disables system caches.
*
*/
void env_disable_cache(void);
typedef void LOCK;
/*!
* env_create_queue
*
* Creates a message queue.
*
* @param queue Pointer to created queue
* @param length Maximum number of elements in the queue
* @param item_size Queue element size in bytes
*
* @return - status of function execution
*/
int32_t env_create_queue(void **queue, int32_t length, int32_t element_size);
/*!
* env_delete_queue
*
* Deletes the message queue.
*
* @param queue Queue to delete
*/
void env_delete_queue(void *queue);
/*!
* env_put_queue
*
* Put an element in a queue.
*
* @param queue Queue to put element in
* @param msg Pointer to the message to be put into the queue
* @param timeout_ms Timeout in ms
*
* @return - status of function execution
*/
int32_t env_put_queue(void *queue, void *msg, uint32_t timeout_ms);
/*!
* env_get_queue
*
* Get an element out of a queue.
*
* @param queue Queue to get element from
* @param msg Pointer to a memory to save the message
* @param timeout_ms Timeout in ms
*
* @return - status of function execution
*/
int32_t env_get_queue(void *queue, void *msg, uint32_t timeout_ms);
/*!
* env_get_current_queue_size
*
* Get current queue size.
*
* @param queue Queue pointer
*
* @return - Number of queued items in the queue
*/
int32_t env_get_current_queue_size(void *queue);
/*!
* env_isr
*
* Invoke RPMSG/IRQ callback
*
* @param env Pointer to environment context data
* @param vector RPMSG IRQ vector ID.
*/
#if defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1)
void env_isr(void *env, uint32_t vector);
#else
void env_isr(uint32_t vector);
#endif
#if defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1)
/*!
* env_get_platform_context
*
* Get the platform layer context from the environment platform context
*
* @param env Pointer to environment context data
*
* @return Pointer to platform context data
*/
void *env_get_platform_context(void *env_context);
/*!
* env_init_interrupt
*
* Initialize the ISR data for given virtqueue interrupt
*
* @param env Pointer to environment context data
* @param vq_id Virtqueue ID
* @param isr_data Pointer to initial ISR data
*
* @return Execution status, 0 on success
*/
int32_t env_init_interrupt(void *env, int32_t vq_id, void *isr_data);
/*!
* env_deinit_interrupt
*
* Deinitialize the ISR data for given virtqueue interrupt
*
* @param env Pointer to environment context data
* @param vq_id Virtqueue ID
*
* @return Execution status, 0 on success
*/
int32_t env_deinit_interrupt(void *env, int32_t vq_id);
#endif
#endif /* RPMSG_ENV_H_ */

View File

@ -0,0 +1,361 @@
/*
* Copyright (c) 2014, Mentor Graphics Corporation
* Copyright (c) 2015 Xilinx, Inc.
* Copyright (c) 2016 Freescale Semiconductor, Inc.
* Copyright 2016-2020 NXP
* 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.
*/
#ifndef RPMSG_LITE_H_
#define RPMSG_LITE_H_
#if defined(__cplusplus)
extern "C" {
#endif
#include <stddef.h>
#include "virtqueue.h"
#include "rpmsg_env.h"
#include "llist.h"
#include "rpmsg_compiler.h"
#include "rpmsg_default_config.h"
//! @addtogroup rpmsg_lite
//! @{
/*******************************************************************************
* Definitions
******************************************************************************/
#define RL_VERSION "3.1.1" /*!< Current RPMsg Lite version */
/* Shared memory "allocator" parameters */
#define RL_WORD_SIZE (sizeof(uint32_t))
#define RL_WORD_ALIGN_UP(a) \
(((((uint32_t)a) & (RL_WORD_SIZE - 1U)) != 0U) ? ((((uint32_t)a) & (~(RL_WORD_SIZE - 1U))) + 4U) : ((uint32_t)a))
#define RL_WORD_ALIGN_DOWN(a) \
(((((uint32_t)a) & (RL_WORD_SIZE - 1U)) != 0U) ? (((uint32_t)a) & (~(RL_WORD_SIZE - 1U))) : ((uint32_t)a))
/* Definitions for device types , null pointer, etc.*/
#define RL_SUCCESS (0)
#define RL_NULL ((void *)0)
#define RL_REMOTE (0)
#define RL_MASTER (1)
#define RL_TRUE (1U)
#define RL_FALSE (0U)
#define RL_ADDR_ANY (0xFFFFFFFFU)
#define RL_RELEASE (0)
#define RL_HOLD (1)
#define RL_DONT_BLOCK (0)
#define RL_BLOCK (0xFFFFFFFFU)
/* Error macros. */
#define RL_ERRORS_BASE (-5000)
#define RL_ERR_NO_MEM (RL_ERRORS_BASE - 1)
#define RL_ERR_BUFF_SIZE (RL_ERRORS_BASE - 2)
#define RL_ERR_PARAM (RL_ERRORS_BASE - 3)
#define RL_ERR_DEV_ID (RL_ERRORS_BASE - 4)
#define RL_ERR_MAX_VQ (RL_ERRORS_BASE - 5)
#define RL_ERR_NO_BUFF (RL_ERRORS_BASE - 6)
#define RL_NOT_READY (RL_ERRORS_BASE - 7)
#define RL_ALREADY_DONE (RL_ERRORS_BASE - 8)
/* Init flags */
#define RL_NO_FLAGS (0)
/*! \typedef rl_ept_rx_cb_t
\brief Receive callback function type.
*/
typedef int32_t (*rl_ept_rx_cb_t)(void *payload, uint32_t payload_len, uint32_t src, void *priv);
/*!
* RPMsg Lite Endpoint structure
*/
struct rpmsg_lite_endpoint
{
uint32_t addr; /*!< endpoint address */
rl_ept_rx_cb_t rx_cb; /*!< ISR callback function */
void *rx_cb_data; /*!< ISR callback data */
void *rfu; /*!< reserved for future usage */
/* 16 bytes aligned on 32bit architecture */
};
/*!
* RPMsg Lite Endpoint static context
*/
struct rpmsg_lite_ept_static_context
{
struct rpmsg_lite_endpoint ept; /*!< memory for endpoint structure */
struct llist node; /*!< memory for linked list node structure */
};
/*!
* Structure describing the local instance
* of RPMSG lite communication stack and
* holds all runtime variables needed internally
* by the stack.
*/
struct rpmsg_lite_instance
{
struct virtqueue *rvq; /*!< receive virtqueue */
struct virtqueue *tvq; /*!< transmit virtqueue */
struct llist *rl_endpoints; /*!< linked list of endpoints */
LOCK *lock; /*!< local RPMsg Lite mutex lock */
uint32_t link_state; /*!< state of the link, up/down*/
char *sh_mem_base; /*!< base address of the shared memory */
uint32_t sh_mem_remaining; /*!< amount of remaining unused buffers in shared memory */
uint32_t sh_mem_total; /*!< total amount of buffers in shared memory */
struct virtqueue_ops const *vq_ops; /*!< ops functions table pointer */
#if defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1)
void *env; /*!< pointer to the environment layer context */
#endif
#if defined(RL_USE_STATIC_API) && (RL_USE_STATIC_API == 1)
struct vq_static_context vq_ctxt[2];
#endif
};
/*******************************************************************************
* API
******************************************************************************/
/* Exported API functions */
/*!
* @brief Initializes the RPMsg-Lite communication stack.
* Must be called prior to any other RPMSG lite API.
* To be called by the master side.
*
* @param shmem_addr Shared memory base used for this instance of RPMsg-Lite
* @param shmem_length Length of memory area given by previous parameter
* @param link_id Link ID used to define the rpmsg-lite instance, see rpmsg_platform.h
* @param init_flags Initialization flags
* @param env_cfg Initialization data for the environement RPMsg-Lite layer, used when
* the environment layer uses its own context (RL_USE_ENVIRONMENT_CONTEXT)
* @param static_context RPMsg-Lite preallocated context pointer, used in case of static api (RL_USE_STATIC_API)
*
* @return New RPMsg-Lite instance pointer or RL_NULL.
*
*/
#if defined(RL_USE_STATIC_API) && (RL_USE_STATIC_API == 1)
struct rpmsg_lite_instance *rpmsg_lite_master_init(void *shmem_addr,
size_t shmem_length,
uint32_t link_id,
uint32_t init_flags,
struct rpmsg_lite_instance *static_context);
#elif defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1)
struct rpmsg_lite_instance *rpmsg_lite_master_init(
void *shmem_addr, size_t shmem_length, uint32_t link_id, uint32_t init_flags, void *env_cfg);
#else
struct rpmsg_lite_instance *rpmsg_lite_master_init(void *shmem_addr,
size_t shmem_length,
uint32_t link_id,
uint32_t init_flags);
#endif
/**
* @brief Initializes the RPMsg-Lite communication stack.
* Must be called prior to any other RPMsg-Lite API.
* To be called by the remote side.
*
* @param shmem_addr Shared memory base used for this instance of RPMsg-Lite
* @param link_id Link ID used to define the rpmsg-lite instance, see rpmsg_platform.h
* @param init_flags Initialization flags
* @param env_cfg Initialization data for the environement RPMsg-Lite layer, used when
* the environment layer uses its own context (RL_USE_ENVIRONMENT_CONTEXT)
* @param static_context RPMsg-Lite preallocated context pointer, used in case of static api (RL_USE_STATIC_API)
*
* @return New RPMsg-Lite instance pointer or RL_NULL.
*
*/
#if defined(RL_USE_STATIC_API) && (RL_USE_STATIC_API == 1)
struct rpmsg_lite_instance *rpmsg_lite_remote_init(void *shmem_addr,
uint32_t link_id,
uint32_t init_flags,
struct rpmsg_lite_instance *static_context);
#elif defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1)
struct rpmsg_lite_instance *rpmsg_lite_remote_init(void *shmem_addr,
uint32_t link_id,
uint32_t init_flags,
void *env_cfg);
#else
struct rpmsg_lite_instance *rpmsg_lite_remote_init(void *shmem_addr, uint32_t link_id, uint32_t init_flags);
#endif
/*!
*
* @brief Deinitialized the RPMsg-Lite communication stack
* This function always succeeds.
* rpmsg_lite_init() can be called again after this
* function has been called.
*
* @param rpmsg_lite_dev RPMsg-Lite instance
*
* @return Status of function execution, RL_SUCCESS on success.
*/
int32_t rpmsg_lite_deinit(struct rpmsg_lite_instance *rpmsg_lite_dev);
/*!
* @brief Create a new rpmsg endpoint, which can be used
* for communication.
*
* @param rpmsg_lite_dev RPMsg-Lite instance
* @param addr Desired address, RL_ADDR_ANY for automatic selection
* @param rx_cb Callback function called on receive
* @param rx_cb_data Callback data pointer, passed to rx_cb
* @param ept_context Endpoint preallocated context pointer, used in case of static api (RL_USE_STATIC_API)
*
* @return RL_NULL on error, new endpoint pointer on success.
*
*/
#if defined(RL_USE_STATIC_API) && (RL_USE_STATIC_API == 1)
struct rpmsg_lite_endpoint *rpmsg_lite_create_ept(struct rpmsg_lite_instance *rpmsg_lite_dev,
uint32_t addr,
rl_ept_rx_cb_t rx_cb,
void *rx_cb_data,
struct rpmsg_lite_ept_static_context *ept_context);
#else
struct rpmsg_lite_endpoint *rpmsg_lite_create_ept(struct rpmsg_lite_instance *rpmsg_lite_dev,
uint32_t addr,
rl_ept_rx_cb_t rx_cb,
void *rx_cb_data);
#endif
/*!
* @brief This function deletes rpmsg endpoint and performs cleanup.
*
* @param rpmsg_lite_dev RPMsg-Lite instance
* @param rl_ept Pointer to endpoint to destroy
*
*/
int32_t rpmsg_lite_destroy_ept(struct rpmsg_lite_instance *rpmsg_lite_dev, struct rpmsg_lite_endpoint *rl_ept);
/*!
*
* @brief Sends a message contained in data field of length size
* to the remote endpoint with address dst.
* ept->addr is used as source address in the rpmsg header
* of the message being sent.
*
* @param rpmsg_lite_dev RPMsg-Lite instance
* @param ept Sender endpoint
* @param dst Remote endpoint address
* @param data Payload buffer
* @param size Size of payload, in bytes
* @param timeout Timeout in ms, 0 if nonblocking
*
* @return Status of function execution, RL_SUCCESS on success.
*
*/
int32_t rpmsg_lite_send(struct rpmsg_lite_instance *rpmsg_lite_dev,
struct rpmsg_lite_endpoint *ept,
uint32_t dst,
char *data,
uint32_t size,
uint32_t timeout);
/*!
* @brief Function to get the link state
*
* @param rpmsg_lite_dev RPMsg-Lite instance
*
* @return True when link up, false when down.
*
*/
int32_t rpmsg_lite_is_link_up(struct rpmsg_lite_instance *rpmsg_lite_dev);
#if defined(RL_API_HAS_ZEROCOPY) && (RL_API_HAS_ZEROCOPY == 1)
/*!
* @brief Releases the rx buffer for future reuse in vring.
* This API can be called at process context when the
* message in rx buffer is processed.
*
* @param rpmsg_lite_dev RPMsg-Lite instance
* @param rxbuf Rx buffer with message payload
*
* @return Status of function execution, RL_SUCCESS on success.
*/
int32_t rpmsg_lite_release_rx_buffer(struct rpmsg_lite_instance *rpmsg_lite_dev, void *rxbuf);
/*!
* @brief Allocates the tx buffer for message payload.
*
* This API can only be called at process context to get the tx buffer in vring. By this way, the
* application can directly put its message into the vring tx buffer without copy from an application buffer.
* It is the application responsibility to correctly fill the allocated tx buffer by data and passing correct
* parameters to the rpmsg_lite_send_nocopy() function to perform data no-copy-send mechanism.
*
* @param rpmsg_lite_dev RPMsg-Lite instance
* @param[in] size Pointer to store maximum payload size available
* @param[in] timeout Integer, wait upto timeout ms or not for buffer to become available
*
* @return The tx buffer address on success and RL_NULL on failure.
*
* @see rpmsg_lite_send_nocopy
*/
void *rpmsg_lite_alloc_tx_buffer(struct rpmsg_lite_instance *rpmsg_lite_dev, uint32_t *size, uint32_t timeout);
/*!
* @brief Sends a message in tx buffer allocated by rpmsg_lite_alloc_tx_buffer()
*
* This function sends txbuf of length len to the remote dst address,
* and uses ept->addr as the source address.
* The application has to take the responsibility for:
* 1. tx buffer allocation (rpmsg_lite_alloc_tx_buffer())
* 2. filling the data to be sent into the pre-allocated tx buffer
* 3. not exceeding the buffer size when filling the data
* 4. data cache coherency
*
* After the rpmsg_lite_send_nocopy() function is issued the tx buffer is no more owned
* by the sending task and must not be touched anymore unless the rpmsg_lite_send_nocopy()
* function fails and returns an error.
*
* @param rpmsg_lite_dev RPMsg-Lite instance
* @param[in] ept Sender endpoint pointer
* @param[in] dst Destination address
* @param[in] data TX buffer with message filled
* @param[in] size Length of payload
*
* @return 0 on success and an appropriate error value on failure.
*
* @see rpmsg_lite_alloc_tx_buffer
*/
int32_t rpmsg_lite_send_nocopy(struct rpmsg_lite_instance *rpmsg_lite_dev,
struct rpmsg_lite_endpoint *ept,
uint32_t dst,
void *data,
uint32_t size);
#endif /* RL_API_HAS_ZEROCOPY */
//! @}
#if defined(__cplusplus)
}
#endif
#endif /* RPMSG_LITE_H_ */

View File

@ -0,0 +1,140 @@
/*
* Copyright (c) 2014, Mentor Graphics Corporation
* Copyright (c) 2015 Xilinx, Inc.
* Copyright (c) 2016 Freescale Semiconductor, Inc.
* Copyright 2016 NXP
* 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.
*/
#ifndef RPMSG_NS_H_
#define RPMSG_NS_H_
#include "rpmsg_lite.h"
//! @addtogroup rpmsg_ns
//! @{
#define RL_NS_EPT_ADDR (0x35u)
/* Up to 32 flags available */
enum rpmsg_ns_flags
{
RL_NS_CREATE = 0,
RL_NS_DESTROY = 1,
};
/*! \typedef rpmsg_ns_new_ept_cb
\brief New endpoint NS callback function type.
*/
typedef void (*rpmsg_ns_new_ept_cb)(uint32_t new_ept, const char *new_ept_name, uint32_t flags, void *user_data);
struct rpmsg_ns_callback_data
{
rpmsg_ns_new_ept_cb cb;
void *user_data;
};
struct rpmsg_ns_context
{
struct rpmsg_lite_endpoint *ept;
struct rpmsg_ns_callback_data *cb_ctxt;
};
typedef struct rpmsg_ns_context *rpmsg_ns_handle;
struct rpmsg_ns_static_context_container
{
struct rpmsg_lite_ept_static_context ept_ctxt;
struct rpmsg_ns_callback_data cb_ctxt;
struct rpmsg_ns_context ns_ctxt;
};
typedef struct rpmsg_ns_static_context_container rpmsg_ns_static_context;
#if defined(__cplusplus)
extern "C" {
#endif
/*******************************************************************************
* API
******************************************************************************/
/* Exported API functions */
/*!
* @brief Registers application nameservice callback
*
* @param rpmsg_lite_dev RPMsg-Lite instance
* @param app_cb Application nameservice callback
* @param user_data Application nameservice callback data
*
* @return RL_NULL on error, NameService handle on success.
*
*/
#if defined(RL_USE_STATIC_API) && (RL_USE_STATIC_API == 1)
rpmsg_ns_handle rpmsg_ns_bind(struct rpmsg_lite_instance *rpmsg_lite_dev,
rpmsg_ns_new_ept_cb app_cb,
void *user_data,
rpmsg_ns_static_context *ns_ept_ctxt);
#else
rpmsg_ns_handle rpmsg_ns_bind(struct rpmsg_lite_instance *rpmsg_lite_dev, rpmsg_ns_new_ept_cb app_cb, void *user_data);
#endif /* RL_USE_STATIC_API */
/*!
* @brief Unregisters application nameservice callback and cleans up
*
* @param rpmsg_lite_dev RPMsg-Lite instance
* @param handle NameService handle
*
* @return Status of function execution, RL_SUCCESS on success.
*
*/
int32_t rpmsg_ns_unbind(struct rpmsg_lite_instance *rpmsg_lite_dev, rpmsg_ns_handle handle);
/*!
* @brief Sends name service announcement to remote device
*
* @param rpmsg_lite_dev RPMsg-Lite instance
* @param new_ept New endpoint to announce
* @param ept_name Name for the announced endpoint
* @param flags Channel creation/deletion flags
*
* @return Status of function execution, RL_SUCCESS on success
*
*/
int32_t rpmsg_ns_announce(struct rpmsg_lite_instance *rpmsg_lite_dev,
struct rpmsg_lite_endpoint *new_ept,
const char *ept_name,
uint32_t flags);
//! @}
#if defined(__cplusplus)
}
#endif
#endif /* RPMSG_NS_H_ */

View File

@ -0,0 +1,194 @@
/*
* Copyright (c) 2014, Mentor Graphics Corporation
* Copyright (c) 2015 Xilinx, Inc.
* Copyright (c) 2016 Freescale Semiconductor, Inc.
* Copyright 2016 NXP
* 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.
*/
#ifndef RPMSG_QUEUE_H_
#define RPMSG_QUEUE_H_
#include "rpmsg_lite.h"
//! @addtogroup rpmsg_queue
//! @{
/*! \typedef rpmsg_queue_handle
\brief Rpmsg queue handle type.
*/
typedef void *rpmsg_queue_handle;
/* RL_API_HAS_ZEROCOPY has to be enabled for RPMsg Queue to work */
#if defined(RL_API_HAS_ZEROCOPY) && (RL_API_HAS_ZEROCOPY == 1)
/*******************************************************************************
* API
******************************************************************************/
/* Exported API functions */
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @brief
* This callback needs to be registered with an endpoint
*
* @param payload Pointer to the buffer containing received data
* @param payload_len Size of data received, in bytes
* @param src Pointer to address of the endpoint from which data is received
* @param priv Private data provided during endpoint creation
*
* @return RL_HOLD or RL_RELEASE to release or hold the buffer in payload
*/
int32_t rpmsg_queue_rx_cb(void *payload, uint32_t payload_len, uint32_t src, void *priv);
/*!
* @brief
* Create a RPMsg queue which can be used
* for blocking reception.
*
* @param rpmsg_lite_dev RPMsg Lite instance
*
* @return RPMsg queue handle or RL_NULL
*
*/
rpmsg_queue_handle rpmsg_queue_create(struct rpmsg_lite_instance *rpmsg_lite_dev);
/*!
* @brief
* Destroy a queue and clean up.
* Do not destroy a queue which is registered with an active endpoint!
*
* @param rpmsg_lite_dev RPMsg-Lite instance
* @param[in] q RPMsg queue handle to destroy
*
* @return Status of function execution
*
*/
int32_t rpmsg_queue_destroy(struct rpmsg_lite_instance *rpmsg_lite_dev, rpmsg_queue_handle q);
/*!
* @brief
* blocking receive function - blocking version of the received function that can be called from an RTOS task.
* The data is copied from the receive buffer into the user supplied buffer.
*
* This is the "receive with copy" version of the RPMsg receive function. This version is simple
* to use but it requires copying data from shared memory into the user space buffer.
* The user has no obligation or burden to manage the shared memory buffers.
*
* @param rpmsg_lite_dev RPMsg-Lite instance
* @param[in] q RPMsg queue handle to listen on
* @param[in] data Pointer to the user buffer the received data are copied to
* @param[out] len Pointer to an int variable that will contain the number of bytes actually copied into the
* buffer
* @param[in] maxlen Maximum number of bytes to copy (received buffer size)
* @param[out] src Pointer to address of the endpoint from which data is received
* @param[in] timeout Timeout, in milliseconds, to wait for a message. A value of 0 means don't wait (non-blocking
* call).
* A value of 0xffffffff means wait forever (blocking call).
*
* @return Status of function execution
*
* @see rpmsg_queue_recv_nocopy
*/
int32_t rpmsg_queue_recv(struct rpmsg_lite_instance *rpmsg_lite_dev,
rpmsg_queue_handle q,
uint32_t *src,
char *data,
uint32_t maxlen,
uint32_t *len,
uint32_t timeout);
/*!
* @brief
* blocking receive function - blocking version of the received function that can be called from an RTOS task.
* The data is NOT copied into the user-app. buffer.
*
* This is the "zero-copy receive" version of the RPMsg receive function. No data is copied.
* Only the pointer to the data is returned. This version is fast, but it requires the user to manage
* buffer allocation. Specifically, the user must decide when a buffer is no longer in use and
* make the appropriate API call to free it, see rpmsg_queue_nocopy_free().
*
* @param rpmsg_lite_dev RPMsg Lite instance
* @param[in] q RPMsg queue handle to listen on
* @param[out] data Pointer to the RPMsg buffer of the shared memory where the received data is stored
* @param[out] len Pointer to an int variable that that will contain the number of valid bytes in the RPMsg
* buffer
* @param[out] src Pointer to address of the endpoint from which data is received
* @param[in] timeout Timeout, in milliseconds, to wait for a message. A value of 0 means don't wait (non-blocking
* call).
* A value of 0xffffffff means wait forever (blocking call).
*
* @return Status of function execution.
*
* @see rpmsg_queue_nocopy_free
* @see rpmsg_queue_recv
*/
int32_t rpmsg_queue_recv_nocopy(struct rpmsg_lite_instance *rpmsg_lite_dev,
rpmsg_queue_handle q,
uint32_t *src,
char **data,
uint32_t *len,
uint32_t timeout);
/*!
* @brief This function frees a buffer previously returned by rpmsg_queue_recv_nocopy().
*
* Once the zero-copy mechanism of receiving data is used, this function
* has to be called to free a buffer and to make it available for the next data
* transfer.
*
* @param rpmsg_lite_dev RPMsg-Lite instance
* @param[in] data Pointer to the RPMsg buffer of the shared memory that has to be freed
*
* @return Status of function execution.
*
* @see rpmsg_queue_recv_nocopy
*/
int32_t rpmsg_queue_nocopy_free(struct rpmsg_lite_instance *rpmsg_lite_dev, void *data);
/*!
* @brief This function returns the number of pending messages in the queue.
*
* @param[in] q RPMsg queue handle
*
* @return Number of pending messages in the queue.
*/
int32_t rpmsg_queue_get_current_size(rpmsg_queue_handle q);
//! @}
#if defined(__cplusplus)
}
#endif
#endif /* RL_API_HAS_ZEROCOPY */
#endif /* RPMSG_QUEUE_H_ */

View File

@ -0,0 +1,168 @@
/*-
* Copyright Rusty Russell IBM Corporation 2007.
* Copyright 2019 NXP
* This header is BSD licensed so anyone can use the definitions to implement
* compatible drivers/servers.
*
* 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 IBM 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 IBM 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.
*
* $FreeBSD$
*/
#ifndef VIRTIO_RING_H
#define VIRTIO_RING_H
/* This marks a buffer as continuing via the next field. */
#define VRING_DESC_F_NEXT 1U
/* This marks a buffer as write-only (otherwise read-only). */
#define VRING_DESC_F_WRITE 2U
/* This means the buffer contains a list of buffer descriptors. */
#define VRING_DESC_F_INDIRECT 4U
/* The Host uses this in used->flags to advise the Guest: don't kick me
* when you add a buffer. It's unreliable, so it's simply an
* optimization. Guest will still kick if it's out of buffers. */
#define VRING_USED_F_NO_NOTIFY 1U
/* The Guest uses this in avail->flags to advise the Host: don't
* interrupt me when you consume a buffer. It's unreliable, so it's
* simply an optimization. */
#define VRING_AVAIL_F_NO_INTERRUPT 1U
/* VirtIO ring descriptors: 16 bytes.
* These can chain together via "next". */
struct vring_desc
{
/* Address (guest-physical). */
uint64_t addr;
/* Length. */
uint32_t len;
/* The flags as indicated above. */
uint16_t flags;
/* We chain unused descriptors via this, too. */
uint16_t next;
};
struct vring_avail
{
uint16_t flags;
uint16_t idx;
uint16_t ring[1];
};
/* uint32_t is used here for ids for padding reasons. */
struct vring_used_elem
{
/* Index of start of used descriptor chain. */
uint32_t id;
/* Total length of the descriptor chain which was written to. */
uint32_t len;
};
struct vring_used
{
uint16_t flags;
uint16_t idx;
struct vring_used_elem ring[1];
};
struct vring
{
uint32_t num;
struct vring_desc *desc;
struct vring_avail *avail;
struct vring_used *used;
};
/* The standard layout for the ring is a continuous chunk of memory which
* looks like this. We assume num is a power of 2.
*
* struct vring {
* # The actual descriptors (16 bytes each)
* struct vring_desc desc[num];
*
* # A ring of available descriptor heads with free-running index.
* __u16 avail_flags;
* __u16 avail_idx;
* __u16 available[num];
* __u16 used_event_idx;
*
* # Padding to the next align boundary.
* char pad[];
*
* # A ring of used descriptor heads with free-running index.
* __u16 used_flags;
* __u16 used_idx;
* struct vring_used_elem used[num];
* __u16 avail_event_idx;
* };
*
* NOTE: for VirtIO PCI, align is 4096.
*/
/*
* We publish the used event index at the end of the available ring, and vice
* versa. They are at the end for backwards compatibility.
*/
#define vring_used_event(vr) ((vr)->avail->ring[(vr)->num])
#define vring_avail_event(vr) ((vr)->used->ring[(vr)->num].id)
static inline int32_t vring_size(uint32_t num, uint32_t align)
{
uint32_t size;
size = num * sizeof(struct vring_desc);
size += sizeof(struct vring_avail) + (num * sizeof(uint16_t)) + sizeof(uint16_t);
size = (size + align - 1UL) & ~(align - 1UL);
size += sizeof(struct vring_used) + (num * sizeof(struct vring_used_elem)) + sizeof(uint16_t);
return ((int32_t)size);
}
static inline void vring_init(struct vring *vr, uint32_t num, uint8_t *p, uint32_t align)
{
vr->num = num;
vr->desc = (struct vring_desc *)(void *)p;
vr->avail = (struct vring_avail *)(void *)(p + num * sizeof(struct vring_desc));
vr->used = (struct vring_used *)(((uint32_t)&vr->avail->ring[num] + align - 1UL) & ~(align - 1UL));
}
/*
* The following is used with VIRTIO_RING_F_EVENT_IDX.
*
* Assuming a given event_idx value from the other size, if we have
* just incremented index from old to new_idx, should we trigger an
* event?
*/
static inline int32_t vring_need_event(uint16_t event_idx, uint16_t new_idx, uint16_t old)
{
if ((uint16_t)(new_idx - event_idx - 1U) < (uint16_t)(new_idx - old))
{
return 1;
}
else
{
return 0;
}
}
#endif /* VIRTIO_RING_H */

View File

@ -0,0 +1,247 @@
#ifndef VIRTQUEUE_H_
#define VIRTQUEUE_H_
/*-
* Copyright (c) 2011, Bryan Venteicher <bryanv@FreeBSD.org>
* Copyright (c) 2016 Freescale Semiconductor, Inc.
* Copyright 2016-2019 NXP
* 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 unmodified, 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
*
* $FreeBSD$
*/
#include <stdbool.h>
#include <stdint.h>
#include "rpmsg_default_config.h"
typedef uint8_t boolean;
#include "virtio_ring.h"
#include "llist.h"
/*Error Codes*/
#define VQ_ERROR_BASE (-3000)
#define ERROR_VRING_FULL (VQ_ERROR_BASE - 1)
#define ERROR_INVLD_DESC_IDX (VQ_ERROR_BASE - 2)
#define ERROR_EMPTY_RING (VQ_ERROR_BASE - 3)
#define ERROR_NO_MEM (VQ_ERROR_BASE - 4)
#define ERROR_VRING_MAX_DESC (VQ_ERROR_BASE - 5)
#define ERROR_VRING_ALIGN (VQ_ERROR_BASE - 6)
#define ERROR_VRING_NO_BUFF (VQ_ERROR_BASE - 7)
#define ERROR_VQUEUE_INVLD_PARAM (VQ_ERROR_BASE - 8)
#define VQUEUE_SUCCESS (0)
#define VQUEUE_DEBUG (false)
/* This is temporary macro to replace C NULL support.
* At the moment all the RTL specific functions are present in env.
* */
#define VQ_NULL ((void *)0)
/* The maximum virtqueue size is 2^15. Use that value as the end of
* descriptor chain terminator since it will never be a valid index
* in the descriptor table. This is used to verify we are correctly
* handling vq_free_cnt.
*/
#define VQ_RING_DESC_CHAIN_END (32768)
#define VIRTQUEUE_FLAG_INDIRECT (0x0001U)
#define VIRTQUEUE_FLAG_EVENT_IDX (0x0002U)
#define VIRTQUEUE_MAX_NAME_SZ (32) /* mind the alignment */
/* Support for indirect buffer descriptors. */
#define VIRTIO_RING_F_INDIRECT_DESC (1 << 28)
/* Support to suppress interrupt until specific index is reached. */
#define VIRTIO_RING_F_EVENT_IDX (1 << 29)
/*
* Hint on how long the next interrupt should be postponed. This is
* only used when the EVENT_IDX feature is negotiated.
*/
typedef enum
{
VQ_POSTPONE_SHORT,
VQ_POSTPONE_LONG,
VQ_POSTPONE_EMPTIED /* Until all available desc are used. */
} vq_postpone_t;
/* local virtqueue representation, not in shared memory */
struct virtqueue
{
/* 32bit aligned { */
char vq_name[VIRTQUEUE_MAX_NAME_SZ];
uint32_t vq_flags;
int32_t vq_alignment;
int32_t vq_ring_size;
void *vq_ring_mem;
void (*callback_fc)(struct virtqueue *vq);
void (*notify_fc)(struct virtqueue *vq);
int32_t vq_max_indirect_size;
int32_t vq_indirect_mem_size;
struct vring vq_ring;
/* } 32bit aligned */
/* 16bit aligned { */
uint16_t vq_queue_index;
uint16_t vq_nentries;
uint16_t vq_free_cnt;
uint16_t vq_queued_cnt;
/*
* Head of the free chain in the descriptor table. If
* there are no free descriptors, this will be set to
* VQ_RING_DESC_CHAIN_END.
*/
uint16_t vq_desc_head_idx;
/*
* Last consumed descriptor in the used table,
* trails vq_ring.used->idx.
*/
uint16_t vq_used_cons_idx;
/*
* Last consumed descriptor in the available table -
* used by the consumer side.
*/
uint16_t vq_available_idx;
/* } 16bit aligned */
boolean avail_read; /* 8bit wide */
boolean avail_write; /* 8bit wide */
boolean used_read; /* 8bit wide */
boolean used_write; /* 8bit wide */
uint16_t padd; /* aligned to 32bits after this: */
void *priv; /* private pointer, upper layer instance pointer */
#if defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1)
void *env; /* private pointer to environment layer internal context */
#endif
};
/* struct to hold vring specific information */
struct vring_alloc_info
{
void *phy_addr;
uint32_t align;
uint16_t num_descs;
uint16_t pad;
};
struct vq_static_context
{
struct virtqueue vq;
};
typedef void vq_callback(struct virtqueue *vq);
typedef void vq_notify(struct virtqueue *vq);
#if (VQUEUE_DEBUG == true)
#define VQASSERT_BOOL(_vq, _exp, _msg) \
do \
{ \
if (!(_exp)) \
{ \
env_print("%s: %s - " _msg, __func__, (_vq)->vq_name); \
while (1) \
; \
} \
} while (0)
#define VQASSERT(_vq, _exp, _msg) VQASSERT_BOOL(_vq, (_exp) != 0, _msg)
#define VQ_RING_ASSERT_VALID_IDX(_vq, _idx) VQASSERT((_vq), (_idx) < (_vq)->vq_nentries, "invalid ring index")
#define VQ_PARAM_CHK(condition, status_var, status_err) \
if ((status_var == 0) && (condition)) \
{ \
status_var = status_err; \
}
#define VQUEUE_BUSY(vq, dir) \
if ((vq)->dir == false) \
(vq)->dir = true; \
else \
VQASSERT(vq, (vq)->dir == false, "VirtQueue already in use")
#define VQUEUE_IDLE(vq, dir) ((vq)->dir = false)
#else
#define KASSERT(cond, str)
#define VQASSERT(_vq, _exp, _msg)
#define VQ_RING_ASSERT_VALID_IDX(_vq, _idx)
#define VQ_PARAM_CHK(condition, status_var, status_err)
#define VQUEUE_BUSY(vq, dir)
#define VQUEUE_IDLE(vq, dir)
#endif
int32_t virtqueue_create(uint16_t id,
const char *name,
struct vring_alloc_info *ring,
void (*callback_fc)(struct virtqueue *vq),
void (*notify_fc)(struct virtqueue *vq),
struct virtqueue **v_queue);
int32_t virtqueue_create_static(uint16_t id,
const char *name,
struct vring_alloc_info *ring,
void (*callback_fc)(struct virtqueue *vq),
void (*notify_fc)(struct virtqueue *vq),
struct virtqueue **v_queue,
struct vq_static_context *vq_ctxt);
int32_t virtqueue_add_buffer(struct virtqueue *vq, uint16_t head_idx);
int32_t virtqueue_fill_used_buffers(struct virtqueue *vq, void *buffer, uint32_t len);
int32_t virtqueue_fill_avail_buffers(struct virtqueue *vq, void *buffer, uint32_t len);
void *virtqueue_get_buffer(struct virtqueue *vq, uint32_t *len, uint16_t *idx);
void *virtqueue_get_available_buffer(struct virtqueue *vq, uint16_t *avail_idx, uint32_t *len);
int32_t virtqueue_add_consumed_buffer(struct virtqueue *vq, uint16_t head_idx, uint32_t len);
void virtqueue_disable_cb(struct virtqueue *vq);
int32_t virtqueue_enable_cb(struct virtqueue *vq);
void virtqueue_kick(struct virtqueue *vq);
void virtqueue_free(struct virtqueue *vq);
void virtqueue_free_static(struct virtqueue *vq);
void virtqueue_dump(struct virtqueue *vq);
void virtqueue_notification(struct virtqueue *vq);
uint32_t virtqueue_get_desc_size(struct virtqueue *vq);
uint32_t virtqueue_get_buffer_length(struct virtqueue *vq, uint16_t idx);
void vq_ring_init(struct virtqueue *vq);
#endif /* VIRTQUEUE_H_ */

View File

@ -0,0 +1,5 @@
SRC_DIR := porting
SRC_FILES := $(wildcard *.c)
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,5 @@
SRC_DIR := environment platform/imx8mp_m7
SRC_FILES := $(wildcard *.c)
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,5 @@
SRC_DIR :=
SRC_FILES := rpmsg_env_bm.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,414 @@
/*
* Copyright (c) 2014, Mentor Graphics Corporation
* Copyright (c) 2015 Xilinx, Inc.
* Copyright (c) 2016 Freescale Semiconductor, Inc.
* Copyright 2016-2019 NXP
* 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.
*/
/**************************************************************************
* FILE NAME
*
* rpmsg_env_bm.c
*
*
* DESCRIPTION
*
* This file is Bare Metal Implementation of env layer for OpenAMP.
*
*
**************************************************************************/
#include "rpmsg_env.h"
#include "rpmsg_platform.h"
#include "virtqueue.h"
#include "rpmsg_compiler.h"
#include <stdlib.h>
#include <string.h>
#include <xizi.h>
static int32_t env_init_counter = 0;
/* Max supported ISR counts */
#define ISR_COUNT (12U) /* Change for multiple remote cores */
/*!
* Structure to keep track of registered ISR's.
*/
struct isr_info
{
void *data;
};
static struct isr_info isr_table[ISR_COUNT];
#if defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1)
#error "This RPMsg-Lite port requires RL_USE_ENVIRONMENT_CONTEXT set to 0"
#endif
/*!
* env_init_rpmsg
*
* Initializes OS/BM environment.
*
*/
int32_t env_init_rpmsg(void)
{
// verify 'env_init_counter'
RL_ASSERT(env_init_counter >= 0);
if (env_init_counter < 0)
{
return -1;
}
env_init_counter++;
// multiple call of 'env_init_rpmsg' - return ok
if (1 < env_init_counter)
{
return 0;
}
// first call
(void)memset(isr_table, 0, sizeof(isr_table));
return platform_init();
}
/*!
* env_deinit
*
* Uninitializes OS/BM environment.
*
* @returns Execution status
*/
int32_t env_deinit(void)
{
// verify 'env_init_counter'
RL_ASSERT(env_init_counter > 0);
if (env_init_counter <= 0)
{
return -1;
}
// counter on zero - call platform deinit
env_init_counter--;
// multiple call of 'env_deinit' - return ok
if (0 < env_init_counter)
{
return 0;
}
// last call
return platform_deinit();
}
/*!
* env_allocate_memory - implementation
*
* @param size
*/
void *env_allocate_memory(uint32_t size)
{
return (x_malloc(size));
}
/*!
* env_free_memory - implementation
*
* @param ptr
*/
void env_free_memory(void *ptr)
{
if (ptr != ((void *)0))
{
x_free(ptr);
}
}
/*!
*
* env_memset - implementation
*
* @param ptr
* @param value
* @param size
*/
void env_memset(void *ptr, int32_t value, uint32_t size)
{
(void)memset(ptr, value, size);
}
/*!
*
* env_memcpy - implementation
*
* @param dst
* @param src
* @param len
*/
void env_memcpy(void *dst, void const *src, uint32_t len)
{
(void)memcpy(dst, src, len);
}
/*!
*
* env_strcmp - implementation
*
* @param dst
* @param src
*/
int32_t env_strcmp(const char *dst, const char *src)
{
return (strcmp(dst, src));
}
/*!
*
* env_strncpy - implementation
*
* @param dest
* @param src
* @param len
*/
void env_strncpy(char *dest, const char *src, uint32_t len)
{
(void)strncpy(dest, src, len);
}
/*!
*
* env_strncmp - implementation
*
* @param dest
* @param src
* @param len
*/
int32_t env_strncmp(char *dest, const char *src, uint32_t len)
{
return (strncmp(dest, src, len));
}
/*!
*
* env_mb - implementation
*
*/
void env_mb(void)
{
MEM_BARRIER();
}
/*!
* env_rmb - implementation
*/
void env_rmb(void)
{
MEM_BARRIER();
}
/*!
* env_wmb - implementation
*/
void env_wmb(void)
{
MEM_BARRIER();
}
/*!
* env_map_vatopa - implementation
*
* @param address
*/
uint32_t env_map_vatopa(void *address)
{
return platform_vatopa(address);
}
/*!
* env_map_patova - implementation
*
* @param address
*/
void *env_map_patova(uint32_t address)
{
return platform_patova(address);
}
/*!
* env_create_mutex
*
* Creates a mutex with the given initial count.
*
*/
int32_t env_create_mutex(void **lock, int32_t count)
{
/* make the mutex pointer point to itself
* this marks the mutex handle as initialized.
*/
*lock = lock;
return 0;
}
/*!
* env_delete_mutex
*
* Deletes the given lock
*
*/
void env_delete_mutex(void *lock)
{
}
/*!
* env_lock_mutex
*
* Tries to acquire the lock, if lock is not available then call to
* this function will suspend.
*/
void env_lock_mutex(void *lock)
{
/* No mutex needed for RPMsg-Lite in BM environment,
* since the API is not shared with ISR context. */
}
/*!
* env_unlock_mutex
*
* Releases the given lock.
*/
void env_unlock_mutex(void *lock)
{
/* No mutex needed for RPMsg-Lite in BM environment,
* since the API is not shared with ISR context. */
}
/*!
* env_sleep_msec
*
* Suspends the calling thread for given time , in msecs.
*/
void env_sleep_msec(uint32_t num_msec)
{
platform_time_delay(num_msec);
}
/*!
* env_register_isr
*
* Registers interrupt handler data for the given interrupt vector.
*
* @param vector_id - virtual interrupt vector number
* @param data - interrupt handler data (virtqueue)
*/
void env_register_isr(uint32_t vector_id, void *data)
{
RL_ASSERT(vector_id < ISR_COUNT);
if (vector_id < ISR_COUNT)
{
isr_table[vector_id].data = data;
}
}
/*!
* env_unregister_isr
*
* Unregisters interrupt handler data for the given interrupt vector.
*
* @param vector_id - virtual interrupt vector number
*/
void env_unregister_isr(uint32_t vector_id)
{
RL_ASSERT(vector_id < ISR_COUNT);
if (vector_id < ISR_COUNT)
{
isr_table[vector_id].data = ((void *)0);
}
}
/*!
* env_enable_interrupt
*
* Enables the given interrupt
*
* @param vector_id - virtual interrupt vector number
*/
void env_enable_interrupt(uint32_t vector_id)
{
(void)platform_interrupt_enable(vector_id);
}
/*!
* env_disable_interrupt
*
* Disables the given interrupt
*
* @param vector_id - virtual interrupt vector number
*/
void env_disable_interrupt(uint32_t vector_id)
{
(void)platform_interrupt_disable(vector_id);
}
/*!
* env_map_memory
*
* Enables memory mapping for given memory region.
*
* @param pa - physical address of memory
* @param va - logical address of memory
* @param size - memory size
* param flags - flags for cache/uncached and access type
*/
void env_map_memory(uint32_t pa, uint32_t va, uint32_t size, uint32_t flags)
{
platform_map_mem_region(va, pa, size, flags);
}
/*!
* env_disable_cache
*
* Disables system caches.
*
*/
void env_disable_cache(void)
{
platform_cache_all_flush_invalidate();
platform_cache_disable();
}
/*========================================================= */
/* Util data / functions for BM */
void env_isr(uint32_t vector)
{
struct isr_info *info;
RL_ASSERT(vector < ISR_COUNT);
if (vector < ISR_COUNT)
{
info = &isr_table[vector];
virtqueue_notification((struct virtqueue *)info->data);
}
}

View File

@ -0,0 +1,5 @@
SRC_DIR :=
SRC_FILES := $(wildcard *.c)
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,284 @@
/*
* Copyright 2019 NXP
* All rights reserved.
*
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <stdio.h>
#include <string.h>
#include "rpmsg_platform.h"
#include "rpmsg_env.h"
#include "fsl_device_registers.h"
#include "fsl_mu.h"
#if defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1)
#error "This RPMsg-Lite port requires RL_USE_ENVIRONMENT_CONTEXT set to 0"
#endif
#define APP_MU_IRQ_PRIORITY (3U)
static int32_t isr_counter = 0;
static int32_t disable_counter = 0;
static void *platform_lock;
static void platform_global_isr_disable(void)
{
__asm volatile("cpsid i");
}
static void platform_global_isr_enable(void)
{
__asm volatile("cpsie i");
}
int32_t platform_init_interrupt(uint32_t vector_id, void *isr_data)
{
/* Register ISR to environment layer */
env_register_isr(vector_id, isr_data);
/* Prepare the MU Hardware, enable channel 1 interrupt */
env_lock_mutex(platform_lock);
RL_ASSERT(0 <= isr_counter);
if (isr_counter == 0)
{
MU_EnableInterrupts(MUB, (1UL << 27U) >> RPMSG_MU_CHANNEL);
}
isr_counter++;
env_unlock_mutex(platform_lock);
return 0;
}
int32_t platform_deinit_interrupt(uint32_t vector_id)
{
/* Prepare the MU Hardware */
env_lock_mutex(platform_lock);
RL_ASSERT(0 < isr_counter);
isr_counter--;
if (isr_counter == 0)
{
MU_DisableInterrupts(MUB, (1UL << 27U) >> RPMSG_MU_CHANNEL);
}
/* Unregister ISR from environment layer */
env_unregister_isr(vector_id);
env_unlock_mutex(platform_lock);
return 0;
}
void platform_notify(uint32_t vector_id)
{
/* As Linux suggests, use MU->Data Channel 1 as communication channel */
uint32_t msg = (uint32_t)(vector_id << 16);
env_lock_mutex(platform_lock);
MU_SendMsg(MUB, RPMSG_MU_CHANNEL, msg);
env_unlock_mutex(platform_lock);
}
#define __CORTEX_M (7U)
/*
* MU Interrrupt RPMsg handler
*/
void MU1_M7_IRQHandler(int irqn, void *arg)
{
uint32_t channel;
if ((((1UL << 27U) >> RPMSG_MU_CHANNEL) & MU_GetStatusFlags(MUB)) != 0UL)
{
channel = MU_ReceiveMsgNonBlocking(MUB, RPMSG_MU_CHANNEL); // Read message from RX register.
env_isr(channel >> 16);
}
/* ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
* exception return operation might vector to incorrect interrupt.
* For Cortex-M7, if core speed much faster than peripheral register write speed,
* the peripheral interrupt flags may be still set after exiting ISR, this results to
* the same error similar with errata 83869 */
#if (defined __CORTEX_M) && ((__CORTEX_M == 4U) || (__CORTEX_M == 7U))
__DSB();
#endif
}
/**
* platform_time_delay
*
* @param num_msec Delay time in ms.
*
* This is not an accurate delay, it ensures at least num_msec passed when return.
*/
void platform_time_delay(uint32_t num_msec)
{
uint32_t loop;
/* Recalculate the CPU frequency */
SystemCoreClockUpdate();
/* Calculate the CPU loops to delay, each loop has 3 cycles */
loop = SystemCoreClock / 3U / 1000U * num_msec;
/* There's some difference among toolchains, 3 or 4 cycles each loop */
while (loop > 0U)
{
__NOP();
loop--;
}
}
/**
* platform_in_isr
*
* Return whether CPU is processing IRQ
*
* @return True for IRQ, false otherwise.
*
*/
int32_t platform_in_isr(void)
{
return (((SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk) != 0UL) ? 1 : 0);
}
/**
* platform_interrupt_enable
*
* Enable peripheral-related interrupt
*
* @param vector_id Virtual vector ID that needs to be converted to IRQ number
*
* @return vector_id Return value is never checked.
*
*/
int32_t platform_interrupt_enable(uint32_t vector_id)
{
RL_ASSERT(0 < disable_counter);
platform_global_isr_disable();
disable_counter--;
if (disable_counter == 0)
{
NVIC_EnableIRQ(MU1_M7_IRQn);
}
platform_global_isr_enable();
return ((int32_t)vector_id);
}
/**
* platform_interrupt_disable
*
* Disable peripheral-related interrupt.
*
* @param vector_id Virtual vector ID that needs to be converted to IRQ number
*
* @return vector_id Return value is never checked.
*
*/
int32_t platform_interrupt_disable(uint32_t vector_id)
{
RL_ASSERT(0 <= disable_counter);
platform_global_isr_disable();
/* virtqueues use the same NVIC vector
if counter is set - the interrupts are disabled */
if (disable_counter == 0)
{
NVIC_DisableIRQ(MU1_M7_IRQn);
}
disable_counter++;
platform_global_isr_enable();
return ((int32_t)vector_id);
}
/**
* platform_map_mem_region
*
* Dummy implementation
*
*/
void platform_map_mem_region(uint32_t vrt_addr, uint32_t phy_addr, uint32_t size, uint32_t flags)
{
}
/**
* platform_cache_all_flush_invalidate
*
* Dummy implementation
*
*/
void platform_cache_all_flush_invalidate(void)
{
}
/**
* platform_cache_disable
*
* Dummy implementation
*
*/
void platform_cache_disable(void)
{
}
/**
* platform_vatopa
*
* Dummy implementation
*
*/
uint32_t platform_vatopa(void *addr)
{
return ((uint32_t)(char *)addr);
}
/**
* platform_patova
*
* Dummy implementation
*
*/
void *platform_patova(uint32_t addr)
{
return ((void *)(char *)addr);
}
/**
* platform_init
*
* platform/environment init
*/
int32_t platform_init(void)
{
/*
* Prepare for the MU Interrupt
* MU must be initialized before rpmsg init is called
*/
MU_Init(MUB);
NVIC_SetPriority(MU1_M7_IRQn, APP_MU_IRQ_PRIORITY);
NVIC_EnableIRQ(MU1_M7_IRQn);
/* Create lock used in multi-instanced RPMsg */
if (0 != env_create_mutex(&platform_lock, 1))
{
return -1;
}
return 0;
}
/**
* platform_deinit
*
* platform/environment deinit process
*/
int32_t platform_deinit(void)
{
/* Delete lock used in multi-instanced RPMsg */
env_delete_mutex(platform_lock);
platform_lock = ((void *)0);
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,189 @@
/*
* Copyright (c) 2014, Mentor Graphics Corporation
* Copyright (c) 2015 Xilinx, Inc.
* Copyright (c) 2016 Freescale Semiconductor, Inc.
* Copyright 2016-2019 NXP
* 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.
*/
#include "rpmsg_lite.h"
#include "rpmsg_ns.h"
#include <stdint.h>
#define RL_NS_NAME_SIZE (32)
/*!
* struct rpmsg_ns_msg - dynamic name service announcement message
* @name: name of remote service that is published
* @addr: address of remote service that is published
* @flags: indicates whether service is created or destroyed
*
* This message is sent across to publish a new service, or announce
* about its removal. When we receive these messages, an appropriate
* rpmsg channel (i.e device) is created/destroyed. In turn, the ->probe()
* or ->remove() handler of the appropriate rpmsg driver will be invoked
* (if/as-soon-as one is registered).
*/
RL_PACKED_BEGIN
struct rpmsg_ns_msg
{
char name[RL_NS_NAME_SIZE];
uint32_t addr;
uint32_t flags;
} RL_PACKED_END;
/*!
* @brief
* Nameservice callback, called in interrupt context
*
* @param payload Pointer to the buffer containing received data
* @param payload_len Size of data received, in bytes
* @param src Pointer to address of the endpoint from which data is received
* @param priv Private data provided during endpoint creation
*
* @return RL_RELEASE, message is always freed
*
*/
static int32_t rpmsg_ns_rx_cb(void *payload, uint32_t payload_len, uint32_t src, void *priv)
{
struct rpmsg_ns_msg *ns_msg_ptr = payload;
struct rpmsg_ns_callback_data *cb_ctxt = priv;
RL_ASSERT(priv != RL_NULL);
RL_ASSERT(cb_ctxt->cb != RL_NULL);
/* Drop likely bad messages received at nameservice address */
if (payload_len == sizeof(struct rpmsg_ns_msg))
{
cb_ctxt->cb(ns_msg_ptr->addr, ns_msg_ptr->name, ns_msg_ptr->flags, cb_ctxt->user_data);
}
return RL_RELEASE;
}
#if defined(RL_USE_STATIC_API) && (RL_USE_STATIC_API == 1)
rpmsg_ns_handle rpmsg_ns_bind(struct rpmsg_lite_instance *rpmsg_lite_dev,
rpmsg_ns_new_ept_cb app_cb,
void *user_data,
rpmsg_ns_static_context *ns_ept_ctxt)
#else
rpmsg_ns_handle rpmsg_ns_bind(struct rpmsg_lite_instance *rpmsg_lite_dev, rpmsg_ns_new_ept_cb app_cb, void *user_data)
#endif /* RL_USE_STATIC_API */
{
struct rpmsg_ns_context *ns_ctxt;
if (app_cb == RL_NULL)
{
return RL_NULL;
}
#if defined(RL_USE_STATIC_API) && (RL_USE_STATIC_API == 1)
if (ns_ept_ctxt == RL_NULL)
{
return RL_NULL;
}
ns_ctxt = &ns_ept_ctxt->ns_ctxt;
/* Set-up the nameservice callback context */
ns_ept_ctxt->cb_ctxt.user_data = user_data;
ns_ept_ctxt->cb_ctxt.cb = app_cb;
ns_ctxt->cb_ctxt = &ns_ept_ctxt->cb_ctxt;
ns_ctxt->ept = rpmsg_lite_create_ept(rpmsg_lite_dev, RL_NS_EPT_ADDR, rpmsg_ns_rx_cb, (void *)ns_ctxt->cb_ctxt,
&ns_ept_ctxt->ept_ctxt);
#else
{
struct rpmsg_ns_callback_data *cb_ctxt;
cb_ctxt = env_allocate_memory(sizeof(struct rpmsg_ns_callback_data));
if (cb_ctxt == RL_NULL)
{
return RL_NULL;
}
ns_ctxt = env_allocate_memory(sizeof(struct rpmsg_ns_context));
if (ns_ctxt == RL_NULL)
{
env_free_memory(cb_ctxt);
return RL_NULL;
}
/* Set-up the nameservice callback context */
cb_ctxt->user_data = user_data;
cb_ctxt->cb = app_cb;
ns_ctxt->cb_ctxt = cb_ctxt;
ns_ctxt->ept = rpmsg_lite_create_ept(rpmsg_lite_dev, RL_NS_EPT_ADDR, rpmsg_ns_rx_cb, (void *)ns_ctxt->cb_ctxt);
}
#endif /* RL_USE_STATIC_API */
return (rpmsg_ns_handle)ns_ctxt;
}
int32_t rpmsg_ns_unbind(struct rpmsg_lite_instance *rpmsg_lite_dev, rpmsg_ns_handle handle)
{
struct rpmsg_ns_context *ns_ctxt = (struct rpmsg_ns_context *)handle;
#if defined(RL_USE_STATIC_API) && (RL_USE_STATIC_API == 1)
return rpmsg_lite_destroy_ept(rpmsg_lite_dev, ns_ctxt->ept);
#else
{
int32_t retval;
retval = rpmsg_lite_destroy_ept(rpmsg_lite_dev, ns_ctxt->ept);
env_free_memory(ns_ctxt->cb_ctxt);
env_free_memory(ns_ctxt);
return retval;
}
#endif
}
int32_t rpmsg_ns_announce(struct rpmsg_lite_instance *rpmsg_lite_dev,
struct rpmsg_lite_endpoint *new_ept,
const char *ept_name,
uint32_t flags)
{
struct rpmsg_ns_msg ns_msg;
if (ept_name == RL_NULL)
{
return RL_ERR_PARAM;
}
if (new_ept == RL_NULL)
{
return RL_ERR_PARAM;
}
env_strncpy(ns_msg.name, ept_name, RL_NS_NAME_SIZE);
ns_msg.flags = flags;
ns_msg.addr = new_ept->addr;
return rpmsg_lite_send(rpmsg_lite_dev, new_ept, RL_NS_EPT_ADDR, (char *)&ns_msg, sizeof(struct rpmsg_ns_msg),
RL_BLOCK);
}

View File

@ -0,0 +1,5 @@
SRC_DIR :=
SRC_FILES := $(wildcard *.c)
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,736 @@
/*-
* Copyright (c) 2011, Bryan Venteicher <bryanv@FreeBSD.org>
* Copyright (c) 2016 Freescale Semiconductor, Inc.
* Copyright 2016-2019 NXP
* 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 unmodified, 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
*/
#include "rpmsg_env.h"
#include "virtqueue.h"
/* Prototype for internal functions. */
static void vq_ring_update_avail(struct virtqueue *vq, uint16_t desc_idx);
static void vq_ring_update_used(struct virtqueue *vq, uint16_t head_idx, uint32_t len);
static uint16_t vq_ring_add_buffer(
struct virtqueue *vq, struct vring_desc *desc, uint16_t head_idx, void *buffer, uint32_t length);
static int32_t vq_ring_enable_interrupt(struct virtqueue *vq, uint16_t ndesc);
static int32_t vq_ring_must_notify_host(struct virtqueue *vq);
static void vq_ring_notify_host(struct virtqueue *vq);
static uint16_t virtqueue_nused(struct virtqueue *vq);
/*!
* virtqueue_create - Creates new VirtIO queue
*
* @param id - VirtIO queue ID , must be unique
* @param name - Name of VirtIO queue
* @param ring - Pointer to vring_alloc_info control block
* @param callback - Pointer to callback function, invoked
* when message is available on VirtIO queue
* @param notify - Pointer to notify function, used to notify
* other side that there is job available for it
* @param v_queue - Created VirtIO queue.
*
* @return - Function status
*/
int32_t virtqueue_create(uint16_t id,
const char *name,
struct vring_alloc_info *ring,
void (*callback_fc)(struct virtqueue *vq),
void (*notify_fc)(struct virtqueue *vq),
struct virtqueue **v_queue)
{
struct virtqueue *vq = VQ_NULL;
volatile int32_t status = VQUEUE_SUCCESS;
uint32_t vq_size = 0;
VQ_PARAM_CHK(ring == VQ_NULL, status, ERROR_VQUEUE_INVLD_PARAM);
VQ_PARAM_CHK(ring->num_descs == 0, status, ERROR_VQUEUE_INVLD_PARAM);
VQ_PARAM_CHK(ring->num_descs & (ring->num_descs - 1), status, ERROR_VRING_ALIGN);
if (status == VQUEUE_SUCCESS)
{
vq_size = sizeof(struct virtqueue);
vq = (struct virtqueue *)env_allocate_memory(vq_size);
if (vq == VQ_NULL)
{
return (ERROR_NO_MEM);
}
env_memset(vq, 0x00, vq_size);
env_strncpy(vq->vq_name, name, VIRTQUEUE_MAX_NAME_SZ);
vq->vq_queue_index = id;
vq->vq_alignment = (int32_t)(ring->align);
vq->vq_nentries = ring->num_descs;
vq->callback_fc = callback_fc;
vq->notify_fc = notify_fc;
// indirect addition is not supported
vq->vq_ring_size = vring_size(ring->num_descs, ring->align);
vq->vq_ring_mem = (void *)ring->phy_addr;
vring_init(&vq->vq_ring, vq->vq_nentries, vq->vq_ring_mem, (uint32_t)vq->vq_alignment);
*v_queue = vq;
}
return (status);
}
/*!
* virtqueue_create_static - Creates new VirtIO queue - static version
*
* @param id - VirtIO queue ID , must be unique
* @param name - Name of VirtIO queue
* @param ring - Pointer to vring_alloc_info control block
* @param callback - Pointer to callback function, invoked
* when message is available on VirtIO queue
* @param notify - Pointer to notify function, used to notify
* other side that there is job available for it
* @param v_queue - Created VirtIO queue.
* @param vq_ctxt - Statically allocated virtqueue context
*
* @return - Function status
*/
int32_t virtqueue_create_static(uint16_t id,
const char *name,
struct vring_alloc_info *ring,
void (*callback_fc)(struct virtqueue *vq),
void (*notify_fc)(struct virtqueue *vq),
struct virtqueue **v_queue,
struct vq_static_context *vq_ctxt)
{
struct virtqueue *vq = VQ_NULL;
volatile int32_t status = VQUEUE_SUCCESS;
uint32_t vq_size = 0;
VQ_PARAM_CHK(vq_ctxt == VQ_NULL, status, ERROR_VQUEUE_INVLD_PARAM);
VQ_PARAM_CHK(ring == VQ_NULL, status, ERROR_VQUEUE_INVLD_PARAM);
VQ_PARAM_CHK(ring->num_descs == 0, status, ERROR_VQUEUE_INVLD_PARAM);
VQ_PARAM_CHK(ring->num_descs & (ring->num_descs - 1), status, ERROR_VRING_ALIGN);
if (status == VQUEUE_SUCCESS)
{
vq_size = sizeof(struct virtqueue);
vq = &vq_ctxt->vq;
env_memset(vq, 0x00, vq_size);
env_strncpy(vq->vq_name, name, VIRTQUEUE_MAX_NAME_SZ);
vq->vq_queue_index = id;
vq->vq_alignment = (int32_t)(ring->align);
vq->vq_nentries = ring->num_descs;
vq->callback_fc = callback_fc;
vq->notify_fc = notify_fc;
// indirect addition is not supported
vq->vq_ring_size = vring_size(ring->num_descs, ring->align);
vq->vq_ring_mem = (void *)ring->phy_addr;
vring_init(&vq->vq_ring, vq->vq_nentries, vq->vq_ring_mem, (uint32_t)vq->vq_alignment);
*v_queue = vq;
}
return (status);
}
/*!
* virtqueue_add_buffer() - Enqueues new buffer in vring for consumption
* by other side.
*
* @param vq - Pointer to VirtIO queue control block.
* @param head_idx - Index of buffer to be added to the avail ring
*
* @return - Function status
*/
int32_t virtqueue_add_buffer(struct virtqueue *vq, uint16_t head_idx)
{
volatile int32_t status = VQUEUE_SUCCESS;
VQ_PARAM_CHK(vq == VQ_NULL, status, ERROR_VQUEUE_INVLD_PARAM);
VQUEUE_BUSY(vq, avail_write);
if (status == VQUEUE_SUCCESS)
{
VQ_RING_ASSERT_VALID_IDX(vq, head_idx);
/*
* Update vring_avail control block fields so that other
* side can get buffer using it.
*/
vq_ring_update_avail(vq, head_idx);
}
VQUEUE_IDLE(vq, avail_write);
return (status);
}
/*!
* virtqueue_fill_avail_buffers - Enqueues single buffer in vring, updates avail
*
* @param vq - Pointer to VirtIO queue control block
* @param buffer - Address of buffer
* @param len - Length of buffer
*
* @return - Function status
*/
int32_t virtqueue_fill_avail_buffers(struct virtqueue *vq, void *buffer, uint32_t len)
{
struct vring_desc *dp;
uint16_t head_idx;
volatile int32_t status = VQUEUE_SUCCESS;
VQ_PARAM_CHK(vq == VQ_NULL, status, ERROR_VQUEUE_INVLD_PARAM);
VQUEUE_BUSY(vq, avail_write);
if (status == VQUEUE_SUCCESS)
{
head_idx = vq->vq_desc_head_idx;
dp = &vq->vq_ring.desc[head_idx];
#if defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1)
dp->addr = env_map_vatopa(vq->env, buffer);
#else
dp->addr = env_map_vatopa(buffer);
#endif
dp->len = len;
dp->flags = VRING_DESC_F_WRITE;
vq->vq_desc_head_idx++;
vq_ring_update_avail(vq, head_idx);
}
VQUEUE_IDLE(vq, avail_write);
return (status);
}
/*!
* virtqueue_get_buffer - Returns used buffers from VirtIO queue
*
* @param vq - Pointer to VirtIO queue control block
* @param len - Length of consumed buffer
* @param idx - Index to buffer descriptor pool
*
* @return - Pointer to used buffer
*/
void *virtqueue_get_buffer(struct virtqueue *vq, uint32_t *len, uint16_t *idx)
{
struct vring_used_elem *uep;
uint16_t used_idx, desc_idx;
if ((vq == VQ_NULL) || (vq->vq_used_cons_idx == vq->vq_ring.used->idx))
{
return (VQ_NULL);
}
VQUEUE_BUSY(vq, used_read);
used_idx = (uint16_t)(vq->vq_used_cons_idx & ((uint16_t)(vq->vq_nentries - 1U)));
uep = &vq->vq_ring.used->ring[used_idx];
env_rmb();
desc_idx = (uint16_t)uep->id;
if (len != VQ_NULL)
{
*len = uep->len;
}
if (idx != VQ_NULL)
{
*idx = desc_idx;
}
vq->vq_used_cons_idx++;
VQUEUE_IDLE(vq, used_read);
#if defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1)
return env_map_patova(vq->env, ((uint32_t)(vq->vq_ring.desc[desc_idx].addr)));
#else
return env_map_patova((uint32_t)(vq->vq_ring.desc[desc_idx].addr));
#endif
}
/*!
* virtqueue_get_buffer_length - Returns size of a buffer
*
* @param vq - Pointer to VirtIO queue control block
* @param idx - Index to buffer descriptor pool
*
* @return - Buffer length
*/
uint32_t virtqueue_get_buffer_length(struct virtqueue *vq, uint16_t idx)
{
return vq->vq_ring.desc[idx].len;
}
/*!
* virtqueue_free - Frees VirtIO queue resources
*
* @param vq - Pointer to VirtIO queue control block
*
*/
void virtqueue_free(struct virtqueue *vq)
{
if (vq != VQ_NULL)
{
if (vq->vq_ring_mem != VQ_NULL)
{
vq->vq_ring_size = 0;
vq->vq_ring_mem = VQ_NULL;
}
env_free_memory(vq);
}
}
/*!
* virtqueue_free - Frees VirtIO queue resources - static version
*
* @param vq - Pointer to VirtIO queue control block
*
*/
void virtqueue_free_static(struct virtqueue *vq)
{
if (vq != VQ_NULL)
{
if (vq->vq_ring_mem != VQ_NULL)
{
vq->vq_ring_size = 0;
vq->vq_ring_mem = VQ_NULL;
}
}
}
/*!
* virtqueue_get_available_buffer - Returns buffer available for use in the
* VirtIO queue
*
* @param vq - Pointer to VirtIO queue control block
* @param avail_idx - Pointer to index used in vring desc table
* @param len - Length of buffer
*
* @return - Pointer to available buffer
*/
void *virtqueue_get_available_buffer(struct virtqueue *vq, uint16_t *avail_idx, uint32_t *len)
{
uint16_t head_idx = 0;
void *buffer;
if (vq->vq_available_idx == vq->vq_ring.avail->idx)
{
return (VQ_NULL);
}
VQUEUE_BUSY(vq, avail_read);
head_idx = (uint16_t)(vq->vq_available_idx++ & ((uint16_t)(vq->vq_nentries - 1U)));
*avail_idx = vq->vq_ring.avail->ring[head_idx];
env_rmb();
#if defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1)
buffer = env_map_patova(vq->env, ((uint32_t)(vq->vq_ring.desc[*avail_idx].addr));
#else
buffer = env_map_patova((uint32_t)(vq->vq_ring.desc[*avail_idx].addr));
#endif
*len = vq->vq_ring.desc[*avail_idx].len;
VQUEUE_IDLE(vq, avail_read);
return (buffer);
}
/*!
* virtqueue_add_consumed_buffer - Returns consumed buffer back to VirtIO queue
*
* @param vq - Pointer to VirtIO queue control block
* @param head_idx - Index of vring desc containing used buffer
* @param len - Length of buffer
*
* @return - Function status
*/
int32_t virtqueue_add_consumed_buffer(struct virtqueue *vq, uint16_t head_idx, uint32_t len)
{
if (head_idx > vq->vq_nentries)
{
return (ERROR_VRING_NO_BUFF);
}
VQUEUE_BUSY(vq, used_write);
vq_ring_update_used(vq, head_idx, len);
VQUEUE_IDLE(vq, used_write);
return (VQUEUE_SUCCESS);
}
/*!
* virtqueue_fill_used_buffers - Fill used buffer ring
*
* @param vq - Pointer to VirtIO queue control block
* @param buffer - Buffer to add
* @param len - Length of buffer
*
* @return - Function status
*/
int32_t virtqueue_fill_used_buffers(struct virtqueue *vq, void *buffer, uint32_t len)
{
uint16_t head_idx;
uint16_t idx;
VQUEUE_BUSY(vq, used_write);
head_idx = vq->vq_desc_head_idx;
VQ_RING_ASSERT_VALID_IDX(vq, head_idx);
/* Enqueue buffer onto the ring. */
idx = vq_ring_add_buffer(vq, vq->vq_ring.desc, head_idx, buffer, len);
vq->vq_desc_head_idx = idx;
vq_ring_update_used(vq, head_idx, len);
VQUEUE_IDLE(vq, used_write);
return (VQUEUE_SUCCESS);
}
/*!
* virtqueue_enable_cb - Enables callback generation
*
* @param vq - Pointer to VirtIO queue control block
*
* @return - Function status
*/
int32_t virtqueue_enable_cb(struct virtqueue *vq)
{
return (vq_ring_enable_interrupt(vq, 0));
}
/*!
* virtqueue_enable_cb - Disables callback generation
*
* @param vq - Pointer to VirtIO queue control block
*
*/
void virtqueue_disable_cb(struct virtqueue *vq)
{
VQUEUE_BUSY(vq, avail_write);
if ((vq->vq_flags & VIRTQUEUE_FLAG_EVENT_IDX) != 0UL)
{
vring_used_event(&vq->vq_ring) = vq->vq_used_cons_idx - vq->vq_nentries - 1U;
}
else
{
vq->vq_ring.avail->flags |= (uint16_t)VRING_AVAIL_F_NO_INTERRUPT;
}
VQUEUE_IDLE(vq, avail_write);
}
/*!
* virtqueue_kick - Notifies other side that there is buffer available for it.
*
* @param vq - Pointer to VirtIO queue control block
*/
void virtqueue_kick(struct virtqueue *vq)
{
VQUEUE_BUSY(vq, avail_write);
/* Ensure updated avail->idx is visible to host. */
env_mb();
if (0 != vq_ring_must_notify_host(vq))
{
vq_ring_notify_host(vq);
}
vq->vq_queued_cnt = 0;
VQUEUE_IDLE(vq, avail_write);
}
/*!
* virtqueue_dump Dumps important virtqueue fields , use for debugging purposes
*
* @param vq - Pointer to VirtIO queue control block
*/
void virtqueue_dump(struct virtqueue *vq)
{
if (vq == VQ_NULL)
{
return;
}
(void)env_print(
"VQ: %s - size=%d; used=%d; queued=%d; "
"desc_head_idx=%d; avail.idx=%d; used_cons_idx=%d; "
"used.idx=%d; avail.flags=0x%x; used.flags=0x%x\r\n",
vq->vq_name, vq->vq_nentries, virtqueue_nused(vq), vq->vq_queued_cnt, vq->vq_desc_head_idx,
vq->vq_ring.avail->idx, vq->vq_used_cons_idx, vq->vq_ring.used->idx, vq->vq_ring.avail->flags,
vq->vq_ring.used->flags);
}
/*!
* virtqueue_get_desc_size - Returns vring descriptor size
*
* @param vq - Pointer to VirtIO queue control block
*
* @return - Descriptor length
*/
uint32_t virtqueue_get_desc_size(struct virtqueue *vq)
{
uint16_t head_idx;
uint16_t avail_idx;
uint32_t len;
if (vq->vq_available_idx == vq->vq_ring.avail->idx)
{
return 0;
}
head_idx = (uint16_t)(vq->vq_available_idx & ((uint16_t)(vq->vq_nentries - 1U)));
avail_idx = vq->vq_ring.avail->ring[head_idx];
len = vq->vq_ring.desc[avail_idx].len;
return (len);
}
/**************************************************************************
* Helper Functions *
**************************************************************************/
/*!
*
* vq_ring_add_buffer
*
*/
static uint16_t vq_ring_add_buffer(
struct virtqueue *vq, struct vring_desc *desc, uint16_t head_idx, void *buffer, uint32_t length)
{
struct vring_desc *dp;
if (buffer == VQ_NULL)
{
return head_idx;
}
VQASSERT(vq, head_idx != VQ_RING_DESC_CHAIN_END, "premature end of free desc chain");
dp = &desc[head_idx];
#if defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1)
dp->addr = env_map_vatopa(vq->env, buffer);
#else
dp->addr = env_map_vatopa(buffer);
#endif
dp->len = length;
dp->flags = VRING_DESC_F_WRITE;
return (head_idx + 1U);
}
/*!
*
* vq_ring_init
*
*/
void vq_ring_init(struct virtqueue *vq)
{
struct vring *vr;
uint32_t i, size;
size = (uint32_t)(vq->vq_nentries);
vr = &vq->vq_ring;
for (i = 0U; i < size - 1U; i++)
{
vr->desc[i].next = (uint16_t)(i + 1U);
}
vr->desc[i].next = (uint16_t)VQ_RING_DESC_CHAIN_END;
}
/*!
*
* vq_ring_update_avail
*
*/
static void vq_ring_update_avail(struct virtqueue *vq, uint16_t desc_idx)
{
uint16_t avail_idx;
/*
* Place the head of the descriptor chain into the next slot and make
* it usable to the host. The chain is made available now rather than
* deferring to virtqueue_notify() in the hopes that if the host is
* currently running on another CPU, we can keep it processing the new
* descriptor.
*/
avail_idx = (uint16_t)(vq->vq_ring.avail->idx & ((uint16_t)(vq->vq_nentries - 1U)));
vq->vq_ring.avail->ring[avail_idx] = desc_idx;
env_wmb();
vq->vq_ring.avail->idx++;
/* Keep pending count until virtqueue_notify(). */
vq->vq_queued_cnt++;
}
/*!
*
* vq_ring_update_used
*
*/
static void vq_ring_update_used(struct virtqueue *vq, uint16_t head_idx, uint32_t len)
{
uint16_t used_idx;
struct vring_used_elem *used_desc = VQ_NULL;
/*
* Place the head of the descriptor chain into the next slot and make
* it usable to the host. The chain is made available now rather than
* deferring to virtqueue_notify() in the hopes that if the host is
* currently running on another CPU, we can keep it processing the new
* descriptor.
*/
used_idx = vq->vq_ring.used->idx & (vq->vq_nentries - 1U);
used_desc = &(vq->vq_ring.used->ring[used_idx]);
used_desc->id = head_idx;
used_desc->len = len;
env_wmb();
vq->vq_ring.used->idx++;
}
/*!
*
* vq_ring_enable_interrupt
*
*/
static int32_t vq_ring_enable_interrupt(struct virtqueue *vq, uint16_t ndesc)
{
/*
* Enable interrupts, making sure we get the latest index of
* what's already been consumed.
*/
if ((vq->vq_flags & VIRTQUEUE_FLAG_EVENT_IDX) != 0UL)
{
vring_used_event(&vq->vq_ring) = vq->vq_used_cons_idx + ndesc;
}
else
{
vq->vq_ring.avail->flags &= ~(uint16_t)VRING_AVAIL_F_NO_INTERRUPT;
}
env_mb();
/*
* Enough items may have already been consumed to meet our threshold
* since we last checked. Let our caller know so it processes the new
* entries.
*/
if (virtqueue_nused(vq) > ndesc)
{
return (1);
}
return (0);
}
/*!
*
* virtqueue_interrupt
*
*/
void virtqueue_notification(struct virtqueue *vq)
{
if (vq != VQ_NULL)
{
if (vq->callback_fc != VQ_NULL)
{
vq->callback_fc(vq);
}
}
}
/*!
*
* vq_ring_must_notify_host
*
*/
static int32_t vq_ring_must_notify_host(struct virtqueue *vq)
{
uint16_t new_idx, prev_idx;
uint16_t event_idx;
if ((vq->vq_flags & VIRTQUEUE_FLAG_EVENT_IDX) != 0UL)
{
new_idx = vq->vq_ring.avail->idx;
prev_idx = new_idx - vq->vq_queued_cnt;
event_idx = (uint16_t)vring_avail_event(&vq->vq_ring);
return ((vring_need_event(event_idx, new_idx, prev_idx) != 0) ? 1 : 0);
}
return (((vq->vq_ring.used->flags & ((uint16_t)VRING_USED_F_NO_NOTIFY)) == 0U) ? 1 : 0);
}
/*!
*
* vq_ring_notify_host
*
*/
static void vq_ring_notify_host(struct virtqueue *vq)
{
if (vq->notify_fc != VQ_NULL)
{
vq->notify_fc(vq);
}
}
/*!
*
* virtqueue_nused
*
*/
static uint16_t virtqueue_nused(struct virtqueue *vq)
{
uint16_t used_idx, nused;
used_idx = vq->vq_ring.used->idx;
nused = (uint16_t)(used_idx - vq->vq_used_cons_idx);
VQASSERT(vq, nused <= vq->vq_nentries, "used more than available");
return (nused);
}

View File

@ -0,0 +1,10 @@
multicore/rpmsg_lite/readme.txt
The RPMsg Lite component is a lightweight implementation of the RPMsg protocol.
The RPMsg protocol defines a standardized binary interface used to communicate between
multiple cores in a heterogeneous multicore system.
Directory Structure
doc - Holds the documentation.
lib - Holds source code for rpmsg_lite.

View File

@ -0,0 +1,94 @@
#include "rpmsg_lite.h"
#include "rpmsg_ns.h"
#include "board.h"
#include <device.h>
#include <xizi.h>
#include <shell.h>
/*******************************************************************************
* Definitions
******************************************************************************/
#define RPMSG_LITE_LINK_ID (RL_PLATFORM_IMX8MP_M7_USER_LINK_ID)
#define RPMSG_LITE_SHMEM_BASE (VDEV0_VRING_BASE)
#define RPMSG_LITE_NS_ANNOUNCE_STRING "rpmsg-remote-m7"
#define RPMSG_LITE_MASTER_IS_LINUX
#define APP_DEBUG_UART_BAUDRATE (115200U) /* Debug console baud rate. */
#define APP_TASK_STACK_SIZE (256U)
#define TC_LOCAL_EPT_ADDR (30)
#define TC_REMOTE_EPT_ADDR (40)
#define APP_RPMSG_READY_EVENT_DATA (1U)
#define DATA_LEN 45
struct rpmsg_lite_endpoint *volatile my_ept = NULL;
struct rpmsg_lite_instance *volatile my_rpmsg = NULL;
rpmsg_ns_handle ns_handle = NULL;
int rc_finish = 0;
static void app_nameservice_isr_cb(uint32_t new_ept, const char *new_ept_name, uint32_t flags, void *user_data)
{
KPrintf("get new name: %s\n", new_ept_name);
}
int32_t ept_cb(void *data, uint32_t len, uint32_t src, void *priv) {
int32_t result = 0;
if (src != TC_REMOTE_EPT_ADDR) KPrintf("receive error!, src is %d\n", src);
KPrintf("receive msg: ");
for(int i=0; i<len; i++) {
KPrintf("%c", ((char *)data)[i]);
}
KPrintf("\n");
rc_finish = 1;
return 0;
}
void RPMsgTask_Entry(void *param)
{
KPrintf("M7 rpmsg task begins!\n");
my_rpmsg = rpmsg_lite_remote_init((void *)RPMSG_LITE_SHMEM_BASE, RPMSG_LITE_LINK_ID, RL_NO_FLAGS);
while (0 == rpmsg_lite_is_link_up(my_rpmsg)) { }
KPrintf("Link is up!\n");
KPrintf("nameservice bind begin\n");
ns_handle = rpmsg_ns_bind(my_rpmsg, app_nameservice_isr_cb, ((void *)0));
SDK_DelayAtLeastUs(1000000U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
my_ept = rpmsg_lite_create_ept(my_rpmsg, TC_LOCAL_EPT_ADDR, ept_cb, NULL);
// announce a new endpoint to communicate with remote, the channel name is RPMSG_LITE_NS_ANNOUNCE_STRING
rpmsg_ns_announce(my_rpmsg, my_ept, RPMSG_LITE_NS_ANNOUNCE_STRING, (uint32_t)RL_NS_CREATE);
KPrintf("rpmsg_ns_announce succeeds\n");
while(rc_finish == 0) {}
KPrintf("begin to send msg\n");
char data[DATA_LEN] = "Hello, here is M7!";
rpmsg_lite_send(my_rpmsg, my_ept, TC_REMOTE_EPT_ADDR, data, strlen(data)+1, RL_DONT_BLOCK);
KPrintf("send msg %s\n", data);
/* wait a while to process the last message on the opposite side */
env_sleep_msec(1000);
KPrintf("M7 Finish!\n");
rpmsg_lite_destroy_ept(my_rpmsg, my_ept);
rpmsg_ns_unbind(my_rpmsg, ns_handle);
rpmsg_lite_deinit(my_rpmsg);
}
void CreateRPMsgTask(void)
{
int32 rpmsg_task_id = KTaskCreate("rpmsg_task",RPMsgTask_Entry,NULL,2048,SHELL_TASK_PRIORITY + 1);
if (rpmsg_task_id < 0)
{
KPrintf("CreateRPMsgTask: create rpmsg task fail!\n");
return ;
}
KPrintf("CreateRPMsgTask: create rpmsg task success!\n");
int32 start_up_result = StartupKTask(rpmsg_task_id);
if (start_up_result != 0)
{
KPrintf("CreateRPMsgTask: startup rpmsg task fail\n");
}
KPrintf("CreateRPMsgTask: startup rpmsg task success\n");
}
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_PARAM_NUM(0)|SHELL_CMD_DISABLE_RETURN, CreateRPMsgTask, CreateRPMsgTask, create rpmsg listener task);

View File

@ -0,0 +1,74 @@
/*
* Copyright (c) 2014, Mentor Graphics Corporation
* All rights reserved.
* Copyright (c) 2015 Xilinx, Inc. All rights reserved.
* Copyright 2020 NXP.
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/* This file populates resource table for BM remote
* for use by the Linux Master */
#include "board.h"
#include "rsc_table.h"
#include "rpmsg_lite.h"
#include <string.h>
#define NUM_VRINGS 0x02
/* Place resource table in special ELF section */
#if defined(__ARMCC_VERSION) || defined(__GNUC__)
__attribute__((section(".resource_table")))
#elif defined(__ICCARM__)
#pragma location = ".resource_table"
#else
#error Compiler not supported!
#endif
const struct remote_resource_table resources = {
/* Version */
1,
/* NUmber of table entries */
NO_RESOURCE_ENTRIES,
/* reserved fields */
{
0,
0,
},
/* Offsets of rsc entries */
{
offsetof(struct remote_resource_table, user_vdev),
},
/* SRTM virtio device entry */
{
RSC_VDEV,
7,
0,
RSC_VDEV_FEATURE_NS,
0,
0,
0,
NUM_VRINGS,
{0, 0},
},
/* Vring rsc entry - part of vdev rsc entry */
{VDEV0_VRING_BASE, VRING_ALIGN, RL_BUFFER_COUNT, 0, 0},
{VDEV0_VRING_BASE + VRING_SIZE, VRING_ALIGN, RL_BUFFER_COUNT, 1, 0},
};
void copyResourceTable(void)
{
/*
* Resource table should be copied to VDEV0_VRING_BASE + RESOURCE_TABLE_OFFSET.
* VDEV0_VRING_BASE is temperorily kept for backward compatibility, will be
* removed in future release
*/
memcpy((void *)VDEV0_VRING_BASE, &resources, sizeof(resources));
memcpy((void *)(VDEV0_VRING_BASE + RESOURCE_TABLE_OFFSET), &resources, sizeof(resources));
}

View File

@ -0,0 +1,2 @@
SRC_FILES := $(wildcard *.c)
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,134 @@
/*
* Copyright 2019-2020 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_common.h"
#include "clock_config.h"
#include "fsl_audiomix.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/* Fractional PLLs: Fout = ((mainDiv+dsm/65536) * refSel) / (preDiv * 2^ postDiv) */
/* AUDIO PLL1 configuration */
const ccm_analog_frac_pll_config_t g_audioPll1Config = {
.refSel = kANALOG_PllRefOsc24M, /*!< PLL reference OSC24M */
.mainDiv = 262U,
.dsm = 9437U,
.preDiv = 2U,
.postDiv = 3U, /*!< AUDIO PLL1 frequency = 393216000HZ */
};
/* AUDIO PLL2 configuration */
const ccm_analog_frac_pll_config_t g_audioPll2Config = {
.refSel = kANALOG_PllRefOsc24M, /*!< PLL reference OSC24M */
.mainDiv = 361U,
.dsm = 17511U,
.preDiv = 3U,
.postDiv = 3U, /*!< AUDIO PLL2 frequency = 361267200HZ */
};
/* AUDIOMIX SAI PLL configuration */
const ccm_analog_frac_pll_config_t g_saiPLLConfig = {
.refSel = kANALOG_PllRefOsc24M, /*!< PLL reference OSC24M */
.mainDiv = 361U,
.dsm = 17511U,
.preDiv = 3U,
.postDiv = 3U, /*!< SAI PLL frequency = 361267200HZ */
};
/* Integer PLLs: Fout = (mainDiv * refSel) / (preDiv * 2^ postDiv) */
/* SYSTEM PLL1 configuration */
const ccm_analog_integer_pll_config_t g_sysPll1Config = {
.refSel = kANALOG_PllRefOsc24M, /*!< PLL reference OSC24M */
.mainDiv = 400U,
.preDiv = 3U,
.postDiv = 2U, /*!< SYSTEM PLL1 frequency = 800MHZ */
};
/* SYSTEM PLL2 configuration */
const ccm_analog_integer_pll_config_t g_sysPll2Config = {
.refSel = kANALOG_PllRefOsc24M, /*!< PLL reference OSC24M */
.mainDiv = 250U,
.preDiv = 3U,
.postDiv = 1U, /*!< SYSTEM PLL2 frequency = 1000MHZ */
};
/* SYSTEM PLL3 configuration */
const ccm_analog_integer_pll_config_t g_sysPll3Config = {
.refSel = kANALOG_PllRefOsc24M, /*!< PLL reference OSC24M */
.mainDiv = 300,
.preDiv = 3U,
.postDiv = 2U, /*!< SYSTEM PLL3 frequency = 600MHZ */
};
/*******************************************************************************
* Variables
******************************************************************************/
/*******************************************************************************
* Code
******************************************************************************/
void BOARD_BootClockRUN(void)
{
/* * The following steps just show how to configure the PLL clock sources using the clock driver on M7 core side .
* Please note that the ROM has already configured the SYSTEM PLL1 to 800Mhz when power up the SOC, meanwhile A core
* would enable SYSTEM PLL1, SYSTEM PLL2 and SYSTEM PLL3 by U-Boot.
* Therefore, there is no need to configure the system PLL again on M7 side, otherwise it would have a risk to make
* the SOC hang.
*/
/* switch AHB NOC root to 24M first in order to configure the SYSTEM PLL1. */
CLOCK_SetRootMux(kCLOCK_RootAhb, kCLOCK_AhbRootmuxOsc24M);
/* switch AXI M7 root to 24M first in order to configure the SYSTEM PLL2. */
CLOCK_SetRootMux(kCLOCK_RootM7, kCLOCK_M7RootmuxOsc24M);
// CLOCK_InitSysPll2(&g_sysPll2Config); /* init SYSTEM PLL2 run at 1000MHZ */
// CLOCK_InitSysPll3(&g_sysPll3Config); /* init SYSTEM PLL3 run at 600MHZ */
CLOCK_InitAudioPll1(&g_audioPll1Config); /* init AUDIO PLL1 run at 393216000HZ */
CLOCK_InitAudioPll2(&g_audioPll2Config); /* init AUDIO PLL2 run at 361267200HZ */
CLOCK_SetRootDivider(kCLOCK_RootM7, 1U, 1U); /* Set root clock to 800M */
CLOCK_SetRootMux(kCLOCK_RootM7, kCLOCK_M7RootmuxSysPll1); /* switch cortex-m7 to SYSTEM PLL1 */
// CLOCK_SetRootDivider(kCLOCK_RootQspi, 1U, 2U); /* Set root clock to 800M */
// CLOCK_SetRootMux(kCLOCK_RootM7, kCLOCK_M7RootmuxSysPll1); /* switch QSPI to SYSTEM PLL1 */
CLOCK_SetRootDivider(kCLOCK_RootAhb, 1U, 1U); /* Set root clock freq to 133M / 1= 133MHZ */
CLOCK_SetRootMux(kCLOCK_RootAhb, kCLOCK_AhbRootmuxSysPll1Div6); /* switch AHB to SYSTEM PLL1 DIV6 */
CLOCK_SetRootDivider(kCLOCK_RootAudioAhb, 1U, 2U); /* Set root clock freq to 800MHZ/ 2= 400MHZ*/
CLOCK_SetRootMux(kCLOCK_RootAudioAhb, kCLOCK_AudioAhbRootmuxSysPll1); /* switch AUDIO AHB to SYSTEM PLL1 */
CLOCK_SetRootMux(kCLOCK_RootUart4, kCLOCK_UartRootmuxSysPll1Div10); /* Set UART source to SysPLL1 Div10 80MHZ */
CLOCK_SetRootDivider(kCLOCK_RootUart4, 1U, 1U); /* Set root clock to 80MHZ/ 1= 80MHZ */
CLOCK_EnableClock(kCLOCK_Rdc); /* Enable RDC clock */
CLOCK_EnableClock(kCLOCK_Ocram); /* Enable Ocram clock */
CLOCK_EnableClock(kCLOCK_Audio); /* Enable Audio clock to power on the audiomix domain*/
/* The purpose to enable the following modules clock is to make sure the M7 core could work normally when A53 core
* enters the low power status.*/
CLOCK_EnableClock(kCLOCK_Sim_m);
CLOCK_EnableClock(kCLOCK_Sim_main);
CLOCK_EnableClock(kCLOCK_Sim_s);
CLOCK_EnableClock(kCLOCK_Sim_wakeup);
CLOCK_EnableClock(kCLOCK_Debug);
CLOCK_EnableClock(kCLOCK_Dram);
CLOCK_EnableClock(kCLOCK_Sec_Debug);
/* Power up the audiomix domain by M7 core.*/
GPC->PGC_CPU_M7_MAPPING |= 1U << GPC_PGC_CPU_M7_MAPPING_AUDIOMIX_DOMAIN_SHIFT; /* Map the audiomix domain to M7 */
GPC->PU_PGC_SW_PUP_REQ |= 1U << GPC_PU_PGC_SW_PUP_REQ_AUDIOMIX_SW_PUP_REQ_SHIFT; /* Software request to trigger power up the domain */
while(GPC->PU_PGC_SW_PUP_REQ & (1U << GPC_PU_PGC_SW_PUP_REQ_AUDIOMIX_SW_PUP_REQ_SHIFT)); /* Waiting the GPC_PU_PGC_SW_PUP_REQ_AUDIOMIX_SW_PUP_REQ bit self-cleared after power up */
/* Do the handshake to make sure the NOC bus ready after power up the AUDIOMIX domain. */
GPC->PU_PWRHSK |= 1U << GPC_PU_PWRHSK_GPC_AUDIOMIX_NOC_PWRDNREQN_SHIFT;
while(!(GPC->PU_PWRHSK & (1U << GPC_PU_PWRHSK_GPC_AUDIOMIX_PWRDNACKN_SHIFT))) ;
AUDIOMIX_InitAudioPll(AUDIOMIX, &g_saiPLLConfig); /* init SAI PLL run at 361267200HZ */
/* Update core clock */
SystemCoreClockUpdate();
}

View File

@ -0,0 +1,207 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/*************************************************
File name: connect_uart.c
Description: support imx8mp-board uart configure and uart bus register function
History:
1. Date: 2025-02-26
Author: AIIT XUOS Lab
Modification:
1. support imx8mp-board uart configure, write and read
2. support imx8mp-board uart bus device and driver register
*************************************************/
#include <board.h>
#include <connect_uart.h>
#include <stdint.h>
#include "fsl_debug_console.h"
#include "fsl_uart.h"
#include "xs_base.h"
struct SerialBus serial_bus_1;
struct SerialDriver serial_driver_1;
struct SerialHardwareDevice serial_device_1;
static uint32 SerialInit(struct SerialDriver *serial_drv, struct BusConfigureInfo *configure_info)
{
NULL_PARAM_CHECK(serial_drv);
// struct SerialCfgParam *serial_cfg = (struct SerialCfgParam *)serial_drv->private_data;
struct SerialHardwareDevice *serial_dev = (struct SerialHardwareDevice *)serial_drv->driver.owner_bus->owner_haldev;
struct SerialDevParam *dev_param = (struct SerialDevParam *)serial_dev->haldev.private_data;
dev_param->serial_timeout = WAITING_FOREVER;
uint32_t uartClkSrcFreq = BOARD_DEBUG_UART_CLK_FREQ;
DbgConsole_Init(BOARD_DEBUG_UART_INSTANCE, BOARD_DEBUG_UART_BAUDRATE, BOARD_DEBUG_UART_TYPE, uartClkSrcFreq);
return EOK;
}
// Now for imx8mp, shell uses polling for reading, so each time before `SerialDevRead`
// function is executed, we need to set the sem value to a nonzero value so that
// shell can enter `SerialDevPollingRead` function
static void SerialSemInit() {
int ret = KSemaphoreSetValue(serial_device_1.haldev.dev_sem, 100);
if (ret != EOK) {
KPrintf("SerialSemInit error %d\n", ret);
}
}
static uint32 SerialConfigure(struct SerialDriver *serial_drv, int serial_operation_cmd)
{
// This function is used to change the interrupt status of serial device, now we don't support interrupt for uart4.
return EINVALED;
}
static UART_Type *const s_UartAdapterBase[] = UART_BASE_PTRS;
static int SerialPutChar(struct SerialHardwareDevice *serial_dev, char c)
{
SerialSemInit();
(void)UART_WriteBlocking(s_UartAdapterBase[BOARD_DEBUG_UART_INSTANCE], (uint8_t *)(&c), 1);
return 1;
}
static int SerialGetChar(struct SerialHardwareDevice *serial_dev)
{
int c = -1;
SerialSemInit();
uint8_t buf;
(void)UART_ReadBlocking(s_UartAdapterBase[BOARD_DEBUG_UART_INSTANCE], &buf, 1);
c = (int)buf;
return c;
}
/*manage the serial device operations*/
static const struct SerialDrvDone drv_done =
{
.init = SerialInit,
.configure = SerialConfigure,
};
/*manage the serial device hal operations*/
static struct SerialHwDevDone hwdev_done =
{
.put_char = SerialPutChar,
.get_char = SerialGetChar,
};
static uint32 SerialDrvConfigure(void *drv, struct BusConfigureInfo *configure_info)
{
NULL_PARAM_CHECK(drv);
NULL_PARAM_CHECK(configure_info);
x_err_t ret = EOK;
int serial_operation_cmd;
struct SerialDriver *serial_drv = (struct SerialDriver *)drv;
switch (configure_info->configure_cmd)
{
case OPE_INT:
ret = SerialInit(serial_drv, configure_info);
break;
case OPE_CFG:
serial_operation_cmd = *(int *)configure_info->private_data;
ret = SerialConfigure(serial_drv, serial_operation_cmd);
break;
default:
break;
}
return ret;
}
static int BoardSerialBusInit(struct SerialBus *serial_bus, struct SerialDriver *serial_driver, const char *bus_name, const char *drv_name)
{
x_err_t ret = EOK;
/*Init the serial bus */
ret = SerialBusInit(serial_bus, bus_name);
if (EOK != ret) {
KPrintf("HwUartInit SerialBusInit error %d\n", ret);
return ERROR;
}
/*Init the serial driver*/
ret = SerialDriverInit(serial_driver, drv_name);
if (EOK != ret) {
KPrintf("HwUartInit SerialDriverInit error %d\n", ret);
return ERROR;
}
/*Attach the serial driver to the serial bus*/
ret = SerialDriverAttachToBus(drv_name, bus_name);
if (EOK != ret) {
KPrintf("HwUartInit SerialDriverAttachToBus error %d\n", ret);
return ERROR;
}
return ret;
}
/*Attach the serial device to the serial bus*/
static int BoardSerialDevBend(struct SerialHardwareDevice *serial_device, void *serial_param, const char *bus_name, const char *dev_name)
{
x_err_t ret = EOK;
ret = SerialDeviceRegister(serial_device, serial_param, dev_name);
if (EOK != ret) {
KPrintf("HwUartInit SerialDeviceInit device %s error %d\n", dev_name, ret);
return ERROR;
}
ret = SerialDeviceAttachToBus(dev_name, bus_name);
if (EOK != ret) {
KPrintf("HwUartInit SerialDeviceAttachToBus device %s error %d\n", dev_name, ret);
return ERROR;
}
return ret;
}
int HwUartInit(void)
{
x_err_t ret = EOK;
static struct SerialCfgParam serial_cfg_1;
memset(&serial_cfg_1, 0, sizeof(struct SerialCfgParam));
static struct SerialDevParam serial_dev_param_1;
memset(&serial_dev_param_1, 0, sizeof(struct SerialDevParam));
serial_driver_1.drv_done = &drv_done;
serial_driver_1.configure = &SerialDrvConfigure;
serial_device_1.hwdev_done = &hwdev_done;
serial_driver_1.private_data = (void *)&serial_cfg_1;
serial_dev_param_1.serial_work_mode = 0;
serial_device_1.haldev.private_data = (void *)&serial_dev_param_1;
ret = BoardSerialBusInit(&serial_bus_1, &serial_driver_1, KERNEL_CONSOLE_BUS_NAME, KERNEL_CONSOLE_DRV_NAME);
if (EOK != ret) {
KPrintf("Imxrt1052HwUartInit uart error ret %u\n", ret);
return ERROR;
}
ret = BoardSerialDevBend(&serial_device_1, (void *)&serial_cfg_1, KERNEL_CONSOLE_BUS_NAME, KERNEL_CONSOLE_DEVICE_NAME);
if (EOK != ret) {
KPrintf("Imxrt1052HwUartInit uart error ret %u\n", ret);
return ERROR;
}
return ret;
}

View File

@ -0,0 +1,715 @@
/*
* Copyright 2018 NXP
* All rights reserved.
*
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_common.h"
#include "fsl_uart.h"
#include "fsl_adapter_uart.h"
/*******************************************************************************
* Definitions
******************************************************************************/
#ifndef NDEBUG
#if (defined(DEBUG_CONSOLE_ASSERT_DISABLE) && (DEBUG_CONSOLE_ASSERT_DISABLE > 0U))
#undef assert
#define assert(n)
#endif
#endif
#if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U))
/*! @brief uart RX state structure. */
typedef struct _hal_uart_receive_state
{
volatile uint8_t *buffer;
volatile uint32_t bufferLength;
volatile uint32_t bufferSofar;
} hal_uart_receive_state_t;
/*! @brief uart TX state structure. */
typedef struct _hal_uart_send_state
{
volatile uint8_t *buffer;
volatile uint32_t bufferLength;
volatile uint32_t bufferSofar;
} hal_uart_send_state_t;
#endif
/*! @brief uart state structure. */
typedef struct _hal_uart_state
{
#if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U))
hal_uart_transfer_callback_t callback;
void *callbackParam;
#if (defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U))
uart_handle_t hardwareHandle;
#endif
hal_uart_receive_state_t rx;
hal_uart_send_state_t tx;
#endif
uint8_t instance;
} hal_uart_state_t;
/*******************************************************************************
* Prototypes
******************************************************************************/
/*******************************************************************************
* Variables
******************************************************************************/
static UART_Type *const s_UartAdapterBase[] = UART_BASE_PTRS;
#if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U))
#if !(defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U))
/* Array of UART IRQ number. */
static const IRQn_Type s_UartIRQ[] = UART_IRQS;
static hal_uart_state_t *s_UartState[sizeof(s_UartAdapterBase) / sizeof(UART_Type *)];
#endif
#endif
/*******************************************************************************
* Code
******************************************************************************/
#if (defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U))
static hal_uart_status_t HAL_UartGetStatus(status_t status)
{
hal_uart_status_t uartStatus = kStatus_HAL_UartError;
switch (status)
{
case kStatus_Success:
uartStatus = kStatus_HAL_UartSuccess;
break;
case kStatus_UART_TxBusy:
uartStatus = kStatus_HAL_UartTxBusy;
break;
case kStatus_UART_RxBusy:
uartStatus = kStatus_HAL_UartRxBusy;
break;
case kStatus_UART_TxIdle:
uartStatus = kStatus_HAL_UartTxIdle;
break;
case kStatus_UART_RxIdle:
uartStatus = kStatus_HAL_UartRxIdle;
break;
case kStatus_UART_BaudrateNotSupport:
uartStatus = kStatus_HAL_UartBaudrateNotSupport;
break;
case kStatus_UART_NoiseError:
case kStatus_UART_FramingError:
case kStatus_UART_ParityError:
uartStatus = kStatus_HAL_UartProtocolError;
break;
default:
/* This comments for MISRA C-2012 Rule 16.4 */
break;
}
return uartStatus;
}
#else
static hal_uart_status_t HAL_UartGetStatus(status_t status)
{
if (kStatus_Success == status)
{
return kStatus_HAL_UartSuccess;
}
else
{
return kStatus_HAL_UartError;
}
}
#endif
#if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U))
#if (defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U))
static void HAL_UartCallback(UART_Type *base, uart_handle_t *handle, status_t status, void *callbackParam)
{
hal_uart_state_t *uartHandle;
hal_uart_status_t uartStatus = HAL_UartGetStatus(status);
assert(callbackParam);
uartHandle = (hal_uart_state_t *)callbackParam;
if (kStatus_HAL_UartProtocolError == uartStatus)
{
if (uartHandle->hardwareHandle.rxDataSize)
{
uartStatus = kStatus_HAL_UartError;
}
}
if (uartHandle->callback)
{
uartHandle->callback(uartHandle, uartStatus, uartHandle->callbackParam);
}
}
#else
static void HAL_UartInterruptHandle(uint8_t instance)
{
hal_uart_state_t *uartHandle = s_UartState[instance];
if (NULL == uartHandle)
{
return;
}
/* Receive data register full */
if (UART_GetStatusFlag(s_UartAdapterBase[instance], kUART_RxReadyFlag))
{
UART_ClearStatusFlag(s_UartAdapterBase[instance], kUART_RxReadyFlag);
if (UART_GetEnabledInterrupts(s_UartAdapterBase[instance]) & kUART_RxReadyEnable)
{
if (uartHandle->rx.buffer)
{
uartHandle->rx.buffer[uartHandle->rx.bufferSofar++] = UART_ReadByte(s_UartAdapterBase[instance]);
if (uartHandle->rx.bufferSofar >= uartHandle->rx.bufferLength)
{
/* Disable RX interrupt/overrun interrupt/framing error interrupt */
UART_DisableInterrupts(s_UartAdapterBase[instance],
kUART_RxReadyEnable | kUART_AgingTimerEnable | kUART_RxOverrunEnable |
kUART_ParityErrorEnable | kUART_FrameErrorEnable);
uartHandle->rx.buffer = NULL;
if (uartHandle->callback)
{
uartHandle->callback(uartHandle, kStatus_HAL_UartRxIdle, uartHandle->callbackParam);
}
}
}
}
}
/* Send data register empty and the interrupt is enabled. */
if (UART_GetStatusFlag(s_UartAdapterBase[instance], kUART_TxEmptyFlag))
{
UART_ClearStatusFlag(s_UartAdapterBase[instance], kUART_TxEmptyFlag);
if (UART_GetEnabledInterrupts(s_UartAdapterBase[instance]) & kUART_TxReadyEnable)
{
if (uartHandle->tx.buffer)
{
UART_WriteByte(s_UartAdapterBase[instance], uartHandle->tx.buffer[uartHandle->tx.bufferSofar++]);
if (uartHandle->tx.bufferSofar >= uartHandle->tx.bufferLength)
{
UART_DisableInterrupts(s_UartAdapterBase[uartHandle->instance], kUART_TxReadyEnable);
uartHandle->tx.buffer = NULL;
if (uartHandle->callback)
{
uartHandle->callback(uartHandle, kStatus_HAL_UartTxIdle, uartHandle->callbackParam);
}
}
}
}
}
}
#endif
#endif
hal_uart_status_t HAL_UartInit(hal_uart_handle_t handle, const hal_uart_config_t *config)
{
hal_uart_state_t *uartHandle;
uart_config_t uartConfig;
status_t status;
assert(handle);
assert(config);
assert(config->instance < (sizeof(s_UartAdapterBase) / sizeof(UART_Type *)));
assert(s_UartAdapterBase[config->instance]);
assert(HAL_UART_HANDLE_SIZE >= sizeof(hal_uart_state_t));
UART_GetDefaultConfig(&uartConfig);
uartConfig.baudRate_Bps = config->baudRate_Bps;
if (kHAL_UartParityEven == config->parityMode)
{
uartConfig.parityMode = kUART_ParityEven;
}
else if (kHAL_UartParityOdd == config->parityMode)
{
uartConfig.parityMode = kUART_ParityOdd;
}
else
{
uartConfig.parityMode = kUART_ParityDisabled;
}
if (kHAL_UartTwoStopBit == config->stopBitCount)
{
uartConfig.stopBitCount = kUART_TwoStopBit;
}
else
{
uartConfig.stopBitCount = kUART_OneStopBit;
}
uartConfig.enableRx = (bool)config->enableRx;
uartConfig.enableTx = (bool)config->enableTx;
status = UART_Init(s_UartAdapterBase[config->instance], &uartConfig, config->srcClock_Hz);
if (kStatus_Success != status)
{
return HAL_UartGetStatus(status);
}
uartHandle = (hal_uart_state_t *)handle;
uartHandle->instance = config->instance;
#if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U))
#if (defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U))
UART_TransferCreateHandle(s_UartAdapterBase[config->instance], &uartHandle->hardwareHandle,
(uart_transfer_callback_t)HAL_UartCallback, handle);
#else
s_UartState[uartHandle->instance] = uartHandle;
/* Enable interrupt in NVIC. */
NVIC_SetPriority((IRQn_Type)s_UartIRQ[config->instance], HAL_UART_ISR_PRIORITY);
EnableIRQ(s_UartIRQ[config->instance]);
#endif
#endif
return kStatus_HAL_UartSuccess;
}
hal_uart_status_t HAL_UartDeinit(hal_uart_handle_t handle)
{
hal_uart_state_t *uartHandle;
assert(handle);
uartHandle = (hal_uart_state_t *)handle;
UART_Deinit(s_UartAdapterBase[uartHandle->instance]);
#if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U))
#if !(defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U))
s_UartState[uartHandle->instance] = NULL;
#endif
#endif
return kStatus_HAL_UartSuccess;
}
hal_uart_status_t HAL_UartReceiveBlocking(hal_uart_handle_t handle, uint8_t *data, size_t length)
{
hal_uart_state_t *uartHandle;
status_t status;
assert(handle);
assert(data);
assert(length);
uartHandle = (hal_uart_state_t *)handle;
#if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U))
if (uartHandle->rx.buffer)
{
return kStatus_HAL_UartRxBusy;
}
#endif
status = UART_ReadBlocking(s_UartAdapterBase[uartHandle->instance], data, length);
return HAL_UartGetStatus(status);
}
hal_uart_status_t HAL_UartSendBlocking(hal_uart_handle_t handle, const uint8_t *data, size_t length)
{
hal_uart_state_t *uartHandle;
assert(handle);
assert(data);
assert(length);
uartHandle = (hal_uart_state_t *)handle;
#if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U))
if (uartHandle->tx.buffer)
{
return kStatus_HAL_UartTxBusy;
}
#endif
(void)UART_WriteBlocking(s_UartAdapterBase[uartHandle->instance], data, length);
return kStatus_HAL_UartSuccess;
}
hal_uart_status_t HAL_UartEnterLowpower(hal_uart_handle_t handle)
{
assert(handle);
return kStatus_HAL_UartSuccess;
}
hal_uart_status_t HAL_UartExitLowpower(hal_uart_handle_t handle)
{
assert(handle);
return kStatus_HAL_UartSuccess;
}
#if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U))
#if (defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U))
hal_uart_status_t HAL_UartTransferInstallCallback(hal_uart_handle_t handle,
hal_uart_transfer_callback_t callback,
void *callbackParam)
{
hal_uart_state_t *uartHandle;
assert(handle);
assert(HAL_UART_TRANSFER_MODE);
uartHandle = (hal_uart_state_t *)handle;
uartHandle->callbackParam = callbackParam;
uartHandle->callback = callback;
return kStatus_HAL_UartSuccess;
}
hal_uart_status_t HAL_UartTransferReceiveNonBlocking(hal_uart_handle_t handle, hal_uart_transfer_t *transfer)
{
hal_uart_state_t *uartHandle;
status_t status;
assert(handle);
assert(transfer);
assert(HAL_UART_TRANSFER_MODE);
uartHandle = (hal_uart_state_t *)handle;
status = UART_TransferReceiveNonBlocking(s_UartAdapterBase[uartHandle->instance], &uartHandle->hardwareHandle,
(uart_transfer_t *)transfer, NULL);
return HAL_UartGetStatus(status);
}
hal_uart_status_t HAL_UartTransferSendNonBlocking(hal_uart_handle_t handle, hal_uart_transfer_t *transfer)
{
hal_uart_state_t *uartHandle;
status_t status;
assert(handle);
assert(transfer);
assert(HAL_UART_TRANSFER_MODE);
uartHandle = (hal_uart_state_t *)handle;
status = UART_TransferSendNonBlocking(s_UartAdapterBase[uartHandle->instance], &uartHandle->hardwareHandle,
(uart_transfer_t *)transfer);
return HAL_UartGetStatus(status);
}
hal_uart_status_t HAL_UartTransferGetReceiveCount(hal_uart_handle_t handle, uint32_t *count)
{
hal_uart_state_t *uartHandle;
status_t status;
assert(handle);
assert(count);
assert(HAL_UART_TRANSFER_MODE);
uartHandle = (hal_uart_state_t *)handle;
status = UART_TransferGetReceiveCount(s_UartAdapterBase[uartHandle->instance], &uartHandle->hardwareHandle, count);
return HAL_UartGetStatus(status);
}
hal_uart_status_t HAL_UartTransferGetSendCount(hal_uart_handle_t handle, uint32_t *count)
{
hal_uart_state_t *uartHandle;
status_t status;
assert(handle);
assert(count);
assert(HAL_UART_TRANSFER_MODE);
uartHandle = (hal_uart_state_t *)handle;
status = UART_TransferGetSendCount(s_UartAdapterBase[uartHandle->instance], &uartHandle->hardwareHandle, count);
return HAL_UartGetStatus(status);
}
hal_uart_status_t HAL_UartTransferAbortReceive(hal_uart_handle_t handle)
{
hal_uart_state_t *uartHandle;
assert(handle);
assert(HAL_UART_TRANSFER_MODE);
uartHandle = (hal_uart_state_t *)handle;
UART_TransferAbortReceive(s_UartAdapterBase[uartHandle->instance], &uartHandle->hardwareHandle);
return kStatus_HAL_UartSuccess;
}
hal_uart_status_t HAL_UartTransferAbortSend(hal_uart_handle_t handle)
{
hal_uart_state_t *uartHandle;
assert(handle);
assert(HAL_UART_TRANSFER_MODE);
uartHandle = (hal_uart_state_t *)handle;
UART_TransferAbortSend(s_UartAdapterBase[uartHandle->instance], &uartHandle->hardwareHandle);
return kStatus_HAL_UartSuccess;
}
#else
/* None transactional API with non-blocking mode. */
hal_uart_status_t HAL_UartInstallCallback(hal_uart_handle_t handle,
hal_uart_transfer_callback_t callback,
void *callbackParam)
{
hal_uart_state_t *uartHandle;
assert(handle);
assert(!HAL_UART_TRANSFER_MODE);
uartHandle = (hal_uart_state_t *)handle;
uartHandle->callbackParam = callbackParam;
uartHandle->callback = callback;
return kStatus_HAL_UartSuccess;
}
hal_uart_status_t HAL_UartReceiveNonBlocking(hal_uart_handle_t handle, uint8_t *data, size_t length)
{
hal_uart_state_t *uartHandle;
assert(handle);
assert(data);
assert(length);
assert(!HAL_UART_TRANSFER_MODE);
uartHandle = (hal_uart_state_t *)handle;
if (uartHandle->rx.buffer)
{
return kStatus_HAL_UartRxBusy;
}
uartHandle->rx.bufferLength = length;
uartHandle->rx.bufferSofar = 0;
uartHandle->rx.buffer = data;
/* Enable RX/Rx overrun/framing error interrupt. */
UART_EnableInterrupts(s_UartAdapterBase[uartHandle->instance],
kUART_RxReadyEnable | kUART_AgingTimerEnable | kUART_RxOverrunEnable);
return kStatus_HAL_UartSuccess;
}
hal_uart_status_t HAL_UartSendNonBlocking(hal_uart_handle_t handle, uint8_t *data, size_t length)
{
hal_uart_state_t *uartHandle;
assert(handle);
assert(data);
assert(length);
assert(!HAL_UART_TRANSFER_MODE);
uartHandle = (hal_uart_state_t *)handle;
if (uartHandle->tx.buffer)
{
return kStatus_HAL_UartTxBusy;
}
uartHandle->tx.bufferLength = length;
uartHandle->tx.bufferSofar = 0;
uartHandle->tx.buffer = (volatile uint8_t *)data;
UART_EnableInterrupts(s_UartAdapterBase[uartHandle->instance], kUART_TxReadyEnable);
return kStatus_HAL_UartSuccess;
}
hal_uart_status_t HAL_UartGetReceiveCount(hal_uart_handle_t handle, uint32_t *reCount)
{
hal_uart_state_t *uartHandle;
assert(handle);
assert(reCount);
assert(!HAL_UART_TRANSFER_MODE);
uartHandle = (hal_uart_state_t *)handle;
if (uartHandle->rx.buffer)
{
*reCount = uartHandle->rx.bufferSofar;
return kStatus_HAL_UartSuccess;
}
return kStatus_HAL_UartError;
}
hal_uart_status_t HAL_UartGetSendCount(hal_uart_handle_t handle, uint32_t *seCount)
{
hal_uart_state_t *uartHandle;
assert(handle);
assert(seCount);
assert(!HAL_UART_TRANSFER_MODE);
uartHandle = (hal_uart_state_t *)handle;
if (uartHandle->tx.buffer)
{
*seCount = uartHandle->tx.bufferSofar;
return kStatus_HAL_UartSuccess;
}
return kStatus_HAL_UartError;
}
hal_uart_status_t HAL_UartAbortReceive(hal_uart_handle_t handle)
{
hal_uart_state_t *uartHandle;
assert(handle);
assert(!HAL_UART_TRANSFER_MODE);
uartHandle = (hal_uart_state_t *)handle;
if (uartHandle->rx.buffer)
{
/* Disable RX interrupt/overrun interrupt/framing error interrupt */
UART_DisableInterrupts(s_UartAdapterBase[uartHandle->instance],
kUART_RxReadyEnable | kUART_AgingTimerEnable | kUART_RxOverrunEnable |
kUART_ParityErrorEnable | kUART_FrameErrorEnable);
uartHandle->rx.buffer = NULL;
}
return kStatus_HAL_UartSuccess;
}
hal_uart_status_t HAL_UartAbortSend(hal_uart_handle_t handle)
{
hal_uart_state_t *uartHandle;
assert(handle);
assert(!HAL_UART_TRANSFER_MODE);
uartHandle = (hal_uart_state_t *)handle;
if (uartHandle->tx.buffer)
{
UART_DisableInterrupts(s_UartAdapterBase[uartHandle->instance], kUART_TxReadyEnable);
uartHandle->tx.buffer = NULL;
}
return kStatus_HAL_UartSuccess;
}
#endif
#if (defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U))
void HAL_UartIsrFunction(hal_uart_handle_t handle)
{
hal_uart_state_t *uartHandle;
assert(handle);
assert(HAL_UART_TRANSFER_MODE);
uartHandle = (hal_uart_state_t *)handle;
#if 0
DisableIRQ(s_UartIRQ[uartHandle->instance]);
#endif
UART_TransferHandleIRQ(s_UartAdapterBase[uartHandle->instance], &uartHandle->hardwareHandle);
#if 0
NVIC_SetPriority((IRQn_Type)s_UartIRQ[uartHandle->instance], HAL_UART_ISR_PRIORITY);
EnableIRQ(s_UartIRQ[uartHandle->instance]);
#endif
}
#else
void HAL_UartIsrFunction(hal_uart_handle_t handle)
{
hal_uart_state_t *uartHandle;
assert(handle);
assert(!HAL_UART_TRANSFER_MODE);
uartHandle = (hal_uart_state_t *)handle;
#if 0
DisableIRQ(s_UartIRQ[uartHandle->instance]);
#endif
HAL_UartInterruptHandle(uartHandle->instance);
#if 0
NVIC_SetPriority((IRQn_Type)s_UartIRQ[uartHandle->instance], HAL_UART_ISR_PRIORITY);
EnableIRQ(s_UartIRQ[uartHandle->instance]);
#endif
}
#if defined(UART1)
void UART1_IRQHandler(void)
{
HAL_UartInterruptHandle(1);
SDK_ISR_EXIT_BARRIER;
}
#endif
#if defined(UART2)
void UART2_IRQHandler(void)
{
HAL_UartInterruptHandle(2);
SDK_ISR_EXIT_BARRIER;
}
#endif
#if defined(UART3)
void UART3_IRQHandler(void)
{
HAL_UartInterruptHandle(3);
SDK_ISR_EXIT_BARRIER;
}
#endif
#if defined(UART4)
void UART4_IRQHandler(void)
{
HAL_UartInterruptHandle(4);
SDK_ISR_EXIT_BARRIER;
}
#endif
#if defined(UART5)
void UART5_IRQHandler(void)
{
HAL_UartInterruptHandle(5);
SDK_ISR_EXIT_BARRIER;
}
#endif
#if defined(UART6)
void UART6_IRQHandler(void)
{
HAL_UartInterruptHandle(6);
SDK_ISR_EXIT_BARRIER;
}
#endif
#if defined(UART7)
void UART7_IRQHandler(void)
{
HAL_UartInterruptHandle(7);
SDK_ISR_EXIT_BARRIER;
}
#endif
#if defined(UART8)
void UART8_IRQHandler(void)
{
HAL_UartInterruptHandle(8);
SDK_ISR_EXIT_BARRIER;
}
#endif
#endif
#endif

View File

@ -0,0 +1,116 @@
/*
* Copyright 2020 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_audiomix.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.audiomix"
#endif
/*******************************************************************************
* Prototypes
******************************************************************************/
/*******************************************************************************
* Variables
******************************************************************************/
/*******************************************************************************
* Code
******************************************************************************/
/*!
* brief audiomix attach clock.
*
* param base audiomix base address.
* param id attach clock id.
*/
void AUDIOMIX_AttachClk(AUDIOMIX_Type *base, audiomix_attch_clk_t id)
{
/* extract offset, mask, value */
uint32_t offset = GET_AUDIOMIX_ATTACH_ID_OFFSET(id);
uint32_t mask = GET_AUDIOMIX_ATTACH_ID_MASK(id);
uint32_t value = GET_AUDIOMIX_ATTACH_ID_value(id);
volatile uint32_t *baseAddr = (volatile uint32_t *)((uint32_t)base + offset);
/* load to register */
*baseAddr = (*baseAddr & ~mask) | value;
}
/*!
* brief Initializes the SAI PLL.
* note This function can't detect whether the AUDIO PLL has been enabled and
* used by some IPs.
*
* param config Pointer to the configuration structure(see ref ccm_analog_frac_pll_config_t enumeration).
*
*/
void AUDIOMIX_InitAudioPll(AUDIOMIX_Type *base, const ccm_analog_frac_pll_config_t *config)
{
assert(config != NULL);
uint32_t fracCfg1 = base->SAI_PLL_FDIV_CTL0;
uint32_t fracCfg2 = base->SAI_PLL_FDIV_CTL1;
/* PLL power down and no bypass */
base->SAI_PLL_GNRL_CTL =
base->SAI_PLL_GNRL_CTL & (~(AUDIOMIX_SAI_PLL_GNRL_CTL_RESETB_MASK | AUDIOMIX_SAI_PLL_GNRL_CTL_BYPASS_MASK));
base->SAI_PLL_FDIV_CTL0 =
(fracCfg1 & (~(AUDIOMIX_SAI_PLL_FDIV_CTL0_MAIN_DIV_MASK | AUDIOMIX_SAI_PLL_FDIV_CTL0_PRE_DIV_MASK |
AUDIOMIX_SAI_PLL_FDIV_CTL0_POST_DIV_MASK))) |
AUDIOMIX_SAI_PLL_FDIV_CTL0_MAIN_DIV(config->mainDiv) | AUDIOMIX_SAI_PLL_FDIV_CTL0_PRE_DIV(config->preDiv) |
AUDIOMIX_SAI_PLL_FDIV_CTL0_POST_DIV(config->postDiv);
base->SAI_PLL_FDIV_CTL1 =
(fracCfg2 & (~(AUDIOMIX_SAI_PLL_FDIV_CTL1_DSM_MASK))) | AUDIOMIX_SAI_PLL_FDIV_CTL1_DSM(config->dsm);
base->SAI_PLL_GNRL_CTL |=
AUDIOMIX_SAI_PLL_GNRL_CTL_RESETB_MASK | AUDIOMIX_SAI_PLL_GNRL_CTL_CKE_MASK; /* Enable and power up PLL clock. */
/* Wait for PLL to be locked. */
while ((base->SAI_PLL_GNRL_CTL & AUDIOMIX_SAI_PLL_GNRL_CTL_LOCK_MASK) == 0U)
{
}
}
/*!
* brief De-initialize the SAI PLL.
*/
void AUDIOMIX_DeinitAudioPll1(AUDIOMIX_Type *base)
{
base->SAI_PLL_GNRL_CTL &= ~AUDIOMIX_SAI_PLL_GNRL_CTL_RESETB_MASK;
}
/*!
* brief Get the sai PLL output freq.
*
* retval sai pll output freq.
*/
uint32_t AUDIOMIX_GetAudioPllFreq(AUDIOMIX_Type *base)
{
uint32_t fracCfg1 = base->SAI_PLL_FDIV_CTL0;
uint32_t fracCfg2 = base->SAI_PLL_FDIV_CTL1;
uint64_t fracClk = 0U;
/* get reference clock freq */
uint32_t refClkFreq =
(base->SAI_PLL_GNRL_CTL & AUDIOMIX_SAI_PLL_GNRL_CTL_REF_CLK_SEL_MASK) != 0U ? CLKPAD_FREQ : OSC24M_CLK_FREQ;
/* main divider */
uint32_t mainDiv =
(fracCfg1 & AUDIOMIX_SAI_PLL_FDIV_CTL0_MAIN_DIV_MASK) >> AUDIOMIX_SAI_PLL_FDIV_CTL0_MAIN_DIV_SHIFT;
/* pre divider */
uint32_t preDiv = (fracCfg1 & AUDIOMIX_SAI_PLL_FDIV_CTL0_PRE_DIV_MASK) >> AUDIOMIX_SAI_PLL_FDIV_CTL0_PRE_DIV_SHIFT;
/* post divider */
uint32_t postDiv =
((fracCfg1 & AUDIOMIX_SAI_PLL_FDIV_CTL0_POST_DIV_MASK) >> AUDIOMIX_SAI_PLL_FDIV_CTL0_POST_DIV_SHIFT);
uint32_t dsm = (fracCfg2 & AUDIOMIX_SAI_PLL_FDIV_CTL1_DSM_MASK) >> AUDIOMIX_SAI_PLL_FDIV_CTL1_DSM_SHIFT;
/* calculate the audio pll frequ */
fracClk = (uint64_t)refClkFreq * ((uint64_t)mainDiv * 65536UL + dsm) / (65536UL * preDiv * (1UL << postDiv));
return (uint32_t)fracClk;
}

View File

@ -0,0 +1,810 @@
/*
* Copyright 2019 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_common.h"
#include "fsl_clock.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.clock"
#endif
#define FracPLL_GNRL_CTL_Offset (0U)
#define FracPLL_FDIV_CTL0_Offset (4U)
#define FracPLL_FDIV_CTL1_Offset (8U)
#define IntegerPLL_GNRL_CTL_Offset (0U)
#define IntegerPLL_DIV_CTL_Offset (4U)
/*******************************************************************************
* Prototypes
******************************************************************************/
/*******************************************************************************
* Variables
******************************************************************************/
/*******************************************************************************
* Code
******************************************************************************/
/*!
* brief Gets the clock frequency for a specific clock name.
*
* This function checks the current clock configurations and then calculates
* the clock frequency for a specific clock name defined in clock_name_t.
*
* param clockName Clock names defined in clock_name_t
* return Clock frequency value in hertz
*/
uint32_t CLOCK_GetFreq(clock_name_t clockName)
{
uint32_t freq;
uint32_t temp;
switch (clockName)
{
case kCLOCK_CoreM7Clk:
freq = CLOCK_GetCoreM7Freq();
break;
case kCLOCK_AxiClk:
freq = CLOCK_GetAxiFreq();
break;
case kCLOCK_AhbClk:
freq = CLOCK_GetAhbFreq();
break;
case kCLOCK_IpgClk:
{
temp = CLOCK_GetAhbFreq();
freq = temp / CLOCK_GetRootPostDivider(kCLOCK_RootIpg);
break;
}
default:
freq = 0U;
break;
}
return freq;
}
/*!
* brief Get the CCM Cortex M7 core frequency.
*
* return Clock frequency; If the clock is invalid, returns 0.
*/
uint32_t CLOCK_GetCoreM7Freq(void)
{
uint32_t freq;
uint32_t pre = CLOCK_GetRootPreDivider(kCLOCK_RootM7);
uint32_t post = CLOCK_GetRootPostDivider(kCLOCK_RootM7);
switch (CLOCK_GetRootMux(kCLOCK_RootM7))
{
case (uint32_t)kCLOCK_M7RootmuxOsc24M:
freq = OSC24M_CLK_FREQ;
break;
case (uint32_t)kCLOCK_M7RootmuxSysPll2Div5:
freq = CLOCK_GetPllFreq(kCLOCK_SystemPll2Ctrl) / 5U;
break;
case (uint32_t)kCLOCK_M7RootmuxSysPll2Div4:
freq = CLOCK_GetPllFreq(kCLOCK_SystemPll2Ctrl) / 4U;
break;
case (uint32_t)kCLOCK_M7RootmuxSysVpuPll:
freq = CLOCK_GetPllFreq(kCLOCK_VpuPllCtrl);
break;
case (uint32_t)kCLOCK_M7RootmuxSysPll1:
freq = CLOCK_GetPllFreq(kCLOCK_SystemPll1Ctrl);
break;
case (uint32_t)kCLOCK_M7RootmuxAudioPll1:
freq = CLOCK_GetPllFreq(kCLOCK_AudioPll1Ctrl);
break;
case (uint32_t)kCLOCK_M7RootmuxVideoPll1:
freq = CLOCK_GetPllFreq(kCLOCK_VideoPll1Ctrl);
break;
case (uint32_t)kCLOCK_M7RootmuxSysPll3:
freq = CLOCK_GetPllFreq(kCLOCK_SystemPll3Ctrl);
break;
default:
freq = 0U;
break;
}
return freq / pre / post;
}
/*!
* brief Get the CCM Axi bus frequency.
*
* return Clock frequency; If the clock is invalid, returns 0.
*/
uint32_t CLOCK_GetAxiFreq(void)
{
uint32_t freq;
uint32_t pre = CLOCK_GetRootPreDivider(kCLOCK_RootMainAxi);
uint32_t post = CLOCK_GetRootPostDivider(kCLOCK_RootMainAxi);
switch (CLOCK_GetRootMux(kCLOCK_RootMainAxi))
{
case (uint32_t)kCLOCK_AxiRootmuxOsc24M:
freq = OSC24M_CLK_FREQ;
break;
case (uint32_t)kCLOCK_AxiRootmuxSysPll2Div3:
freq = CLOCK_GetPllFreq(kCLOCK_SystemPll2Ctrl) / 3U;
break;
case (uint32_t)kCLOCK_AxiRootmuxSysPll2Div4:
freq = CLOCK_GetPllFreq(kCLOCK_SystemPll2Ctrl) / 4U;
break;
case (uint32_t)kCLOCK_AxiRootmuxSysPll2:
freq = CLOCK_GetPllFreq(kCLOCK_SystemPll2Ctrl);
break;
case (uint32_t)kCLOCK_AxiRootmuxAudioPll1:
freq = CLOCK_GetPllFreq(kCLOCK_AudioPll1Ctrl);
break;
case (uint32_t)kCLOCK_AxiRootmuxVideoPll1:
freq = CLOCK_GetPllFreq(kCLOCK_VideoPll1Ctrl);
break;
case (uint32_t)kCLOCK_AxiRootmuxSysPll1Div8:
freq = CLOCK_GetPllFreq(kCLOCK_SystemPll1Ctrl) / 8UL;
break;
case (uint32_t)kCLOCK_AxiRootmuxSysPll1:
freq = CLOCK_GetPllFreq(kCLOCK_SystemPll1Ctrl);
break;
default:
freq = 0U;
break;
}
return freq / pre / post;
}
/*!
* brief Get the CCM Ahb bus frequency.
*
* return Clock frequency; If the clock is invalid, returns 0.
*/
uint32_t CLOCK_GetAhbFreq(void)
{
uint32_t freq;
uint32_t pre = CLOCK_GetRootPreDivider(kCLOCK_RootAhb);
uint32_t post = CLOCK_GetRootPostDivider(kCLOCK_RootAhb);
switch (CLOCK_GetRootMux(kCLOCK_RootAhb))
{
case (uint32_t)kCLOCK_AhbRootmuxOsc24M:
freq = OSC24M_CLK_FREQ;
break;
case (uint32_t)kCLOCK_AhbRootmuxSysPll1Div6:
freq = CLOCK_GetPllFreq(kCLOCK_SystemPll1Ctrl) / 6U;
break;
case (uint32_t)kCLOCK_AhbRootmuxSysPll1Div2:
freq = CLOCK_GetPllFreq(kCLOCK_SystemPll1Ctrl) / 2U;
break;
case (uint32_t)kCLOCK_AhbRootmuxSysPll1:
freq = CLOCK_GetPllFreq(kCLOCK_SystemPll1Ctrl);
break;
case (uint32_t)kCLOCK_AhbRootmuxSysPll2Div8:
freq = CLOCK_GetPllFreq(kCLOCK_SystemPll2Ctrl) / 8U;
break;
case (uint32_t)kCLOCK_AhbRootmuxSysPll3:
freq = CLOCK_GetPllFreq(kCLOCK_SystemPll3Ctrl);
break;
case (uint32_t)kCLOCK_AhbRootmuxAudioPll1:
freq = CLOCK_GetPllFreq(kCLOCK_AudioPll1Ctrl);
break;
case (uint32_t)kCLOCK_AhbRootmuxVideoPll1:
freq = CLOCK_GetPllFreq(kCLOCK_VideoPll1Ctrl);
break;
default:
freq = 0U;
break;
}
return freq / pre / post;
}
/*!
* brief Gets PLL reference clock frequency.
*
* param type fractional pll type.
* return Clock frequency
*/
uint32_t CLOCK_GetPllRefClkFreq(clock_pll_ctrl_t ctrl)
{
uint32_t refClkFreq = 0U;
uint8_t clkSel = 0U;
if (ctrl < kCLOCK_ArmPllCtrl)
{
clkSel =
(uint8_t)((CCM_ANALOG_TUPLE_REG(CCM_ANALOG, ctrl) & CCM_ANALOG_AUDIO_PLL1_GEN_CTRL_PLL_REF_CLK_SEL_MASK));
}
else
{
clkSel = (uint8_t)(CCM_ANALOG_TUPLE_REG(CCM_ANALOG, ctrl) & CCM_ANALOG_SYS_PLL1_GEN_CTRL_PLL_REF_CLK_SEL_MASK);
}
switch (clkSel)
{
case kANALOG_PllRefOsc24M:
refClkFreq = OSC24M_CLK_FREQ;
break;
case kANALOG_PllPadClk:
/* The value of PAD CLK need user to define according to the actual condition. */
refClkFreq = CLKPAD_FREQ;
break;
default:
refClkFreq = 0U;
break;
}
return refClkFreq;
}
/*!
* brief Gets PLL clock frequency.
*
* param type fractional pll type.
* return Clock frequency
*/
uint32_t CLOCK_GetPllFreq(clock_pll_ctrl_t pll)
{
uint32_t pllFreq = 0U;
uint32_t pllRefFreq = 0U;
bool intergerPllBypass = false;
bool fracPllBypass = false;
pllRefFreq = CLOCK_GetPllRefClkFreq(pll);
switch (pll)
{
/* Integer PLL frequency */
case kCLOCK_ArmPllCtrl:
intergerPllBypass = CLOCK_IsPllBypassed(CCM_ANALOG, kCLOCK_ArmPllPwrBypassCtrl);
break;
case kCLOCK_SystemPll1Ctrl:
intergerPllBypass = CLOCK_IsPllBypassed(CCM_ANALOG, kCLOCK_SysPll1InternalPll1BypassCtrl);
break;
case kCLOCK_SystemPll2Ctrl:
intergerPllBypass = CLOCK_IsPllBypassed(CCM_ANALOG, kCLOCK_SysPll2InternalPll1BypassCtrl);
break;
case kCLOCK_SystemPll3Ctrl:
intergerPllBypass = CLOCK_IsPllBypassed(CCM_ANALOG, kCLOCK_SysPll3InternalPll1BypassCtrl);
break;
/* Fractional PLL frequency */
case kCLOCK_AudioPll1Ctrl:
fracPllBypass = CLOCK_IsPllBypassed(CCM_ANALOG, kCLOCK_AudioPll1BypassCtrl);
break;
case kCLOCK_AudioPll2Ctrl:
fracPllBypass = CLOCK_IsPllBypassed(CCM_ANALOG, kCLOCK_AudioPll2BypassCtrl);
break;
case kCLOCK_VideoPll1Ctrl:
fracPllBypass = CLOCK_IsPllBypassed(CCM_ANALOG, kCLOCK_VideoPll1BypassCtrl);
break;
case kCLOCK_DramPllCtrl:
fracPllBypass = CLOCK_IsPllBypassed(CCM_ANALOG, kCLOCK_DramPllInternalPll1BypassCtrl);
break;
default:
fracPllBypass = false;
break;
}
if (pll < kCLOCK_ArmPllCtrl)
{
if (fracPllBypass)
{
pllFreq = pllRefFreq;
}
else
{
pllFreq = CLOCK_GetFracPllFreq(CCM_ANALOG, pll, pllRefFreq);
}
}
else
{
if (intergerPllBypass)
{
/* if PLL is bypass, return reference clock directly */
pllFreq = pllRefFreq;
}
else
{
pllFreq = CLOCK_GetIntegerPllFreq(CCM_ANALOG, pll, pllRefFreq, false);
}
}
return (uint32_t)pllFreq;
}
/*!
* brief Initializes the ANALOG ARM PLL.
*
* param config Pointer to the configuration structure(see ref ccm_analog_integer_pll_config_t enumeration).
*
* note This function can't detect whether the Arm PLL has been enabled and
* used by some IPs.
*/
void CLOCK_InitArmPll(const ccm_analog_integer_pll_config_t *config)
{
assert(config != NULL);
/* Integer PLL configuration */
CLOCK_InitIntegerPll(CCM_ANALOG, config, kCLOCK_ArmPllCtrl);
/* Disable PLL bypass */
CLOCK_SetPllBypass(CCM_ANALOG, kCLOCK_ArmPllPwrBypassCtrl, false);
/* Enable and power up PLL clock. */
CLOCK_EnableAnalogClock(CCM_ANALOG, kCLOCK_ArmPllClke);
/* Wait for PLL to be locked. */
while (!CLOCK_IsPllLocked(CCM_ANALOG, kCLOCK_ArmPllCtrl))
{
}
}
/*!
* brief De-initialize the ARM PLL.
*/
void CLOCK_DeinitArmPll(void)
{
CLOCK_PowerDownPll(CCM_ANALOG, kCLOCK_ArmPllCtrl);
}
/*!
* brief Initializes the ANALOG AUDIO PLL1.
*
* param config Pointer to the configuration structure(see ref ccm_analog_frac_pll_config_t enumeration).
*
* note This function can't detect whether the AUDIO PLL has been enabled and
* used by some IPs.
*/
void CLOCK_InitAudioPll1(const ccm_analog_frac_pll_config_t *config)
{
assert(config != NULL);
/* Disable PLL bypass */
CLOCK_SetPllBypass(CCM_ANALOG, kCLOCK_AudioPll1BypassCtrl, false);
/* Fractional pll configuration */
CLOCK_InitFracPll(CCM_ANALOG, config, kCLOCK_AudioPll1Ctrl);
/* Enable and power up PLL clock. */
CLOCK_EnableAnalogClock(CCM_ANALOG, kCLOCK_AudioPll1Clke);
/* Wait for PLL to be locked. */
while (!CLOCK_IsPllLocked(CCM_ANALOG, kCLOCK_AudioPll1Ctrl))
{
}
}
/*!
* brief De-initialize the Audio PLL1.
*/
void CLOCK_DeinitAudioPll1(void)
{
CLOCK_PowerDownPll(CCM_ANALOG, kCLOCK_AudioPll1Ctrl);
}
/*!
* brief Initializes the ANALOG AUDIO PLL2.
*
* param config Pointer to the configuration structure(see ref ccm_analog_frac_pll_config_t enumeration).
*
* note This function can't detect whether the AUDIO PLL has been enabled and
* used by some IPs.
*/
void CLOCK_InitAudioPll2(const ccm_analog_frac_pll_config_t *config)
{
assert(config != NULL);
/* Disable PLL bypass */
CLOCK_SetPllBypass(CCM_ANALOG, kCLOCK_AudioPll2BypassCtrl, false);
/* Fractional pll configuration */
CLOCK_InitFracPll(CCM_ANALOG, config, kCLOCK_AudioPll2Ctrl);
/* Enable and power up PLL clock. */
CLOCK_EnableAnalogClock(CCM_ANALOG, kCLOCK_AudioPll2Clke);
/* Wait for PLL to be locked. */
while (!CLOCK_IsPllLocked(CCM_ANALOG, kCLOCK_AudioPll2Ctrl))
{
}
}
/*!
* brief De-initialize the Audio PLL2.
*/
void CLOCK_DeinitAudioPll2(void)
{
CLOCK_PowerDownPll(CCM_ANALOG, kCLOCK_AudioPll2Ctrl);
}
/*!
* brief Initializes the ANALOG VIDEO PLL1.
*
* param config Pointer to the configuration structure(see ref ccm_analog_frac_pll_config_t enumeration).
*
*/
void CLOCK_InitVideoPll1(const ccm_analog_frac_pll_config_t *config)
{
assert(config != NULL);
/* Disable PLL bypass */
CLOCK_SetPllBypass(CCM_ANALOG, kCLOCK_VideoPll1BypassCtrl, false);
/* Fractional pll configuration */
CLOCK_InitFracPll(CCM_ANALOG, config, kCLOCK_VideoPll1Ctrl);
/* Enable and power up PLL clock. */
CLOCK_EnableAnalogClock(CCM_ANALOG, kCLOCK_VideoPll1Clke);
/* Wait for PLL to be locked. */
while (!CLOCK_IsPllLocked(CCM_ANALOG, kCLOCK_VideoPll1Ctrl))
{
}
}
/*!
* brief De-initialize the Video PLL1.
*/
void CLOCK_DeinitVideoPll1(void)
{
CLOCK_PowerDownPll(CCM_ANALOG, kCLOCK_VideoPll1Ctrl);
}
/*!
* brief Initializes the ANALOG SYS PLL1.
*
* param config Pointer to the configuration structure(see ref ccm_analog_integer_pll_config_t enumeration).
*
* note This function can't detect whether the SYS PLL has been enabled and
* used by some IPs.
*/
void CLOCK_InitSysPll1(const ccm_analog_integer_pll_config_t *config)
{
assert(config != NULL);
/* Integer PLL configuration */
CLOCK_InitIntegerPll(CCM_ANALOG, config, kCLOCK_SystemPll1Ctrl);
/* Disable PLL bypass */
CLOCK_SetPllBypass(CCM_ANALOG, kCLOCK_SysPll1InternalPll1BypassCtrl, false);
/* Enable and power up PLL clock. */
CLOCK_EnableAnalogClock(CCM_ANALOG, kCLOCK_SystemPll1Clke);
/* Wait for PLL to be locked. */
while (!CLOCK_IsPllLocked(CCM_ANALOG, kCLOCK_SystemPll1Ctrl))
{
}
}
/*!
* brief De-initialize the System PLL1.
*/
void CLOCK_DeinitSysPll1(void)
{
CLOCK_PowerDownPll(CCM_ANALOG, kCLOCK_SystemPll1Ctrl);
}
/*!
* brief Initializes the ANALOG SYS PLL2.
*
* param config Pointer to the configuration structure(see ref ccm_analog_integer_pll_config_t enumeration).
*
* note This function can't detect whether the SYS PLL has been enabled and
* used by some IPs.
*/
void CLOCK_InitSysPll2(const ccm_analog_integer_pll_config_t *config)
{
assert(config != NULL);
/* Integer PLL configuration */
CLOCK_InitIntegerPll(CCM_ANALOG, config, kCLOCK_SystemPll2Ctrl);
/* Disable PLL bypass */
CLOCK_SetPllBypass(CCM_ANALOG, kCLOCK_SysPll2InternalPll1BypassCtrl, false);
/* Enable and power up PLL clock. */
CLOCK_EnableAnalogClock(CCM_ANALOG, kCLOCK_SystemPll2Clke);
/* Wait for PLL to be locked. */
while (!CLOCK_IsPllLocked(CCM_ANALOG, kCLOCK_SystemPll2Ctrl))
{
}
}
/*!
* brief De-initialize the System PLL2.
*/
void CLOCK_DeinitSysPll2(void)
{
CLOCK_PowerDownPll(CCM_ANALOG, kCLOCK_SystemPll2Ctrl);
}
/*!
* brief Initializes the ANALOG SYS PLL3.
*
* param config Pointer to the configuration structure(see ref ccm_analog_integer_pll_config_t enumeration).
*
* note This function can't detect whether the SYS PLL has been enabled and
* used by some IPs.
*/
void CLOCK_InitSysPll3(const ccm_analog_integer_pll_config_t *config)
{
assert(config != NULL);
/* Integer PLL configuration */
CLOCK_InitIntegerPll(CCM_ANALOG, config, kCLOCK_SystemPll3Ctrl);
/* Disable PLL bypass */
CLOCK_SetPllBypass(CCM_ANALOG, kCLOCK_SysPll3InternalPll1BypassCtrl, false);
/* Enable and power up PLL clock. */
CLOCK_EnableAnalogClock(CCM_ANALOG, kCLOCK_SystemPll3Clke);
/* Wait for PLL to be locked. */
while (!CLOCK_IsPllLocked(CCM_ANALOG, kCLOCK_SystemPll3Ctrl))
{
}
}
/*!
* brief De-initialize the System PLL3.
*/
void CLOCK_DeinitSysPll3(void)
{
CLOCK_PowerDownPll(CCM_ANALOG, kCLOCK_SystemPll3Ctrl);
}
/*!
* brief Initializes the ANALOG Fractional PLL.
*
* param base CCM ANALOG base address.
* param config Pointer to the configuration structure(see ref ccm_analog_frac_pll_config_t enumeration).
* param type fractional pll type.
*
*/
void CLOCK_InitFracPll(CCM_ANALOG_Type *base, const ccm_analog_frac_pll_config_t *config, clock_pll_ctrl_t type)
{
assert(config != NULL);
assert((config->mainDiv >= 64U) && (config->mainDiv <= 1023U));
assert((config->preDiv >= 1U) && (config->preDiv <= 63U));
assert(config->postDiv <= 6U);
assert(type < kCLOCK_ArmPllCtrl);
uint32_t fracCfg0 = CCM_ANALOG_TUPLE_REG_OFF(base, type, FracPLL_GNRL_CTL_Offset) &
~((uint32_t)1 << CCM_ANALOG_AUDIO_PLL1_GEN_CTRL_PLL_RST_SHIFT);
uint32_t fracCfg1 = CCM_ANALOG_TUPLE_REG_OFF(base, type, FracPLL_FDIV_CTL0_Offset);
uint32_t fracCfg2 = CCM_ANALOG_TUPLE_REG_OFF(base, type, FracPLL_FDIV_CTL1_Offset);
/* power down the fractional PLL first */
CCM_ANALOG_TUPLE_REG_OFF(base, type, FracPLL_GNRL_CTL_Offset) = fracCfg0;
CCM_ANALOG_TUPLE_REG_OFF(base, type, FracPLL_FDIV_CTL0_Offset) =
(fracCfg1 &
(~(CCM_ANALOG_AUDIO_PLL1_FDIV_CTL0_PLL_MAIN_DIV_MASK | CCM_ANALOG_AUDIO_PLL1_FDIV_CTL0_PLL_PRE_DIV_MASK |
CCM_ANALOG_AUDIO_PLL1_FDIV_CTL0_PLL_POST_DIV_MASK))) |
CCM_ANALOG_AUDIO_PLL1_FDIV_CTL0_PLL_MAIN_DIV(config->mainDiv) |
CCM_ANALOG_AUDIO_PLL1_FDIV_CTL0_PLL_PRE_DIV(config->preDiv) |
CCM_ANALOG_AUDIO_PLL1_FDIV_CTL0_PLL_POST_DIV(config->postDiv);
CCM_ANALOG_TUPLE_REG_OFF(base, type, FracPLL_FDIV_CTL1_Offset) =
(fracCfg2 & (~(CCM_ANALOG_AUDIO_PLL1_FDIV_CTL1_PLL_DSM_MASK))) |
CCM_ANALOG_AUDIO_PLL1_FDIV_CTL1_PLL_DSM(config->dsm);
/* power up the fractional pll */
CCM_ANALOG_TUPLE_REG_OFF(base, type, FracPLL_GNRL_CTL_Offset) |= CCM_ANALOG_AUDIO_PLL1_GEN_CTRL_PLL_RST_MASK;
}
/*!
* brief Gets the ANALOG Fractional PLL clock frequency.
*
* param base CCM_ANALOG base pointer.
* param type fractional pll type.
* param fractional pll reference clock frequency
*
* return Clock frequency
*/
uint32_t CLOCK_GetFracPllFreq(CCM_ANALOG_Type *base, clock_pll_ctrl_t type, uint32_t refClkFreq)
{
assert(type < kCLOCK_ArmPllCtrl);
uint32_t fracCfg1 = CCM_ANALOG_TUPLE_REG_OFF(base, type, FracPLL_FDIV_CTL0_Offset);
uint32_t fracCfg2 = CCM_ANALOG_TUPLE_REG_OFF(base, type, FracPLL_FDIV_CTL1_Offset);
uint64_t fracClk = 0U;
uint32_t mainDiv = CCM_BIT_FIELD_EXTRACTION(fracCfg1, CCM_ANALOG_AUDIO_PLL1_FDIV_CTL0_PLL_MAIN_DIV_MASK,
CCM_ANALOG_AUDIO_PLL1_FDIV_CTL0_PLL_MAIN_DIV_SHIFT);
uint8_t preDiv = (uint8_t)CCM_BIT_FIELD_EXTRACTION(fracCfg1, CCM_ANALOG_AUDIO_PLL1_FDIV_CTL0_PLL_PRE_DIV_MASK,
CCM_ANALOG_AUDIO_PLL1_FDIV_CTL0_PLL_PRE_DIV_SHIFT);
uint8_t postDiv = (uint8_t)CCM_BIT_FIELD_EXTRACTION(fracCfg1, CCM_ANALOG_AUDIO_PLL1_FDIV_CTL0_PLL_POST_DIV_MASK,
CCM_ANALOG_AUDIO_PLL1_FDIV_CTL0_PLL_POST_DIV_SHIFT);
uint32_t dsm = CCM_BIT_FIELD_EXTRACTION(fracCfg2, CCM_ANALOG_AUDIO_PLL1_FDIV_CTL1_PLL_DSM_MASK,
CCM_ANALOG_AUDIO_PLL1_FDIV_CTL1_PLL_DSM_SHIFT);
fracClk = (uint64_t)((uint64_t)refClkFreq * ((uint64_t)mainDiv * 65536ULL + dsm) /
(65536ULL * (uint32_t)preDiv * (1ULL << postDiv)));
return (uint32_t)fracClk;
}
/*!
* brief Initializes the ANALOG Integer PLL.
*
* param base CCM ANALOG base address
* param config Pointer to the configuration structure(see ref ccm_analog_integer_pll_config_t enumeration).
* param type integer pll type
*
*/
void CLOCK_InitIntegerPll(CCM_ANALOG_Type *base, const ccm_analog_integer_pll_config_t *config, clock_pll_ctrl_t type)
{
assert(config != NULL);
assert((config->mainDiv >= 64U) && (config->mainDiv <= 1023U));
assert((config->preDiv >= 1U) && (config->preDiv <= 63U));
assert(config->postDiv <= 6U);
assert(type >= kCLOCK_SystemPll1Ctrl);
uint32_t integerCfg0 = CCM_ANALOG_TUPLE_REG_OFF(base, type, IntegerPLL_GNRL_CTL_Offset) &
~((uint32_t)1 << CCM_ANALOG_SYS_PLL1_GEN_CTRL_PLL_RST_SHIFT);
uint32_t integerCfg1 = CCM_ANALOG_TUPLE_REG_OFF(base, type, IntegerPLL_DIV_CTL_Offset);
/* power down the Integer PLL first */
CCM_ANALOG_TUPLE_REG_OFF(base, type, IntegerPLL_GNRL_CTL_Offset) = integerCfg0;
/* pll mux configuration */
CCM_ANALOG_TUPLE_REG_OFF(base, type, IntegerPLL_GNRL_CTL_Offset) =
(integerCfg0 & (~CCM_ANALOG_SYS_PLL1_GEN_CTRL_PLL_REF_CLK_SEL_MASK)) | config->refSel;
/* divider configuration */
CCM_ANALOG_TUPLE_REG_OFF(base, type, IntegerPLL_DIV_CTL_Offset) =
(integerCfg1 &
(~(CCM_ANALOG_SYS_PLL1_FDIV_CTL0_PLL_MAIN_DIV_MASK | CCM_ANALOG_SYS_PLL1_FDIV_CTL0_PLL_PRE_DIV_MASK |
CCM_ANALOG_SYS_PLL1_FDIV_CTL0_PLL_POST_DIV_MASK))) |
CCM_ANALOG_SYS_PLL1_FDIV_CTL0_PLL_MAIN_DIV(config->mainDiv) |
CCM_ANALOG_SYS_PLL1_FDIV_CTL0_PLL_PRE_DIV(config->preDiv) |
CCM_ANALOG_SYS_PLL1_FDIV_CTL0_PLL_POST_DIV(config->postDiv);
/* power up the Integer PLL */
CCM_ANALOG_TUPLE_REG_OFF(base, type, IntegerPLL_GNRL_CTL_Offset) |= CCM_ANALOG_SYS_PLL1_GEN_CTRL_PLL_RST_MASK;
}
/*!
* brief Get the ANALOG Integer PLL clock frequency.
*
* param base CCM ANALOG base address.
* param type integer pll type
* param pll1Bypass pll1 bypass flag
*
* return Clock frequency
*/
uint32_t CLOCK_GetIntegerPllFreq(CCM_ANALOG_Type *base, clock_pll_ctrl_t type, uint32_t refClkFreq, bool pll1Bypass)
{
assert(type >= kCLOCK_SystemPll1Ctrl);
uint32_t integerCfg1 = CCM_ANALOG_TUPLE_REG_OFF(base, type, IntegerPLL_DIV_CTL_Offset);
uint64_t pllOutClock = 0U;
uint32_t mainDiv = CCM_BIT_FIELD_EXTRACTION(integerCfg1, CCM_ANALOG_SYS_PLL1_FDIV_CTL0_PLL_MAIN_DIV_MASK,
CCM_ANALOG_SYS_PLL1_FDIV_CTL0_PLL_MAIN_DIV_SHIFT);
uint8_t preDiv = (uint8_t)CCM_BIT_FIELD_EXTRACTION(integerCfg1, CCM_ANALOG_SYS_PLL1_FDIV_CTL0_PLL_PRE_DIV_MASK,
CCM_ANALOG_SYS_PLL1_FDIV_CTL0_PLL_PRE_DIV_SHIFT);
uint8_t postDiv = (uint8_t)CCM_BIT_FIELD_EXTRACTION(integerCfg1, CCM_ANALOG_SYS_PLL1_FDIV_CTL0_PLL_POST_DIV_MASK,
CCM_ANALOG_SYS_PLL1_FDIV_CTL0_PLL_POST_DIV_SHIFT);
if (pll1Bypass)
{
pllOutClock = refClkFreq;
}
else
{
pllOutClock = (uint64_t)refClkFreq * mainDiv / (((uint64_t)(1U) << postDiv) * preDiv);
}
return (uint32_t)pllOutClock;
}
/*!
* brief Set root clock divider
* Note: The PRE and POST dividers in this function are the actually divider, software will map it to register value
*
* param ccmRootClk Root control (see ref clock_root_control_t enumeration)
* param pre Pre divider value (1-8)
* param post Post divider value (1-64)
*/
void CLOCK_SetRootDivider(clock_root_control_t ccmRootClk, uint32_t pre, uint32_t post)
{
assert((pre <= 8U) && (pre != 0U));
assert((post <= 64U) && (post != 0U));
CCM_REG(ccmRootClk) = (CCM_REG(ccmRootClk) & (~(CCM_TARGET_ROOT_PRE_PODF_MASK | CCM_TARGET_ROOT_POST_PODF_MASK))) |
CCM_TARGET_ROOT_PRE_PODF(pre - 1U) | CCM_TARGET_ROOT_POST_PODF(post - 1U);
}
/*!
* brief Update clock root in one step, for dynamical clock switching
* Note: The PRE and POST dividers in this function are the actually divider, software will map it to register value
*
* param ccmRootClk Root control (see ref clock_root_control_t enumeration)
* param root mux value (see ref _ccm_rootmux_xxx enumeration)
* param pre Pre divider value (0-7, divider=n+1)
* param post Post divider value (0-63, divider=n+1)
*/
void CLOCK_UpdateRoot(clock_root_control_t ccmRootClk, uint32_t mux, uint32_t pre, uint32_t post)
{
assert((pre <= 8U) && (pre != 0U));
assert((post <= 64U) && (post != 0U));
CCM_REG(ccmRootClk) =
(CCM_REG(ccmRootClk) &
(~(CCM_TARGET_ROOT_MUX_MASK | CCM_TARGET_ROOT_PRE_PODF_MASK | CCM_TARGET_ROOT_POST_PODF_MASK))) |
CCM_TARGET_ROOT_MUX(mux) | CCM_TARGET_ROOT_PRE_PODF(pre - 1U) | CCM_TARGET_ROOT_POST_PODF(post - 1U);
}
/*!
* brief Enable CCGR clock gate and root clock gate for each module
* User should set specific gate for each module according to the description
* of the table of system clocks, gating and override in CCM chapter of
* reference manual. Take care of that one module may need to set more than
* one clock gate.
*
* param ccmGate Gate control for each module (see ref clock_ip_name_t enumeration).
*/
void CLOCK_EnableClock(clock_ip_name_t ccmGate)
{
uint32_t clockType = CLOCK_GATE_TYPE(ccmGate);
uint32_t ccgr = CCM_TUPLE_CCGR(ccmGate);
uint32_t rootClk = 0U;
if (CLOCK_GATE_IN_AUDIOMIX == clockType)
{
uint32_t offset = AUDIOMIX_TUPLE_OFFSET(ccmGate);
uint32_t gate = AUDIOMIX_TUPLE_GATE(ccmGate);
rootClk = AUDIOMIX_TUPLE_ROOT(ccmGate);
*(volatile uint32_t *)((uint32_t)AUDIOMIX + offset) |= (uint32_t)1U << gate;
}
else
{
CCM_REG_SET(ccgr) = (uint32_t)kCLOCK_ClockNeededAll;
rootClk = CCM_TUPLE_ROOT(ccmGate);
}
/* if root clock is 0xFFFFU, then skip enable root clock */
if (rootClk != 0xFFFFU)
{
CCM_REG_SET(rootClk) = CCM_TARGET_ROOT_SET_ENABLE_MASK;
}
}
/*!
* brief Disable CCGR clock gate for the each module
* User should set specific gate for each module according to the description
* of the table of system clocks, gating and override in CCM chapter of
* reference manual. Take care of that one module may need to set more than
* one clock gate.
*
* param ccmGate Gate control for each module (see ref clock_ip_name_t enumeration).
*/
void CLOCK_DisableClock(clock_ip_name_t ccmGate)
{
uint32_t ccgr = CCM_TUPLE_CCGR(ccmGate);
uint32_t clockType = CLOCK_GATE_TYPE(ccmGate);
uint32_t rootClk = 0U;
if (CLOCK_GATE_IN_AUDIOMIX == clockType)
{
uint32_t offset = AUDIOMIX_TUPLE_OFFSET(ccmGate);
uint32_t gate = AUDIOMIX_TUPLE_GATE(ccmGate);
rootClk = AUDIOMIX_TUPLE_ROOT(ccmGate);
*(volatile uint32_t *)((uint32_t)AUDIOMIX + offset) &= ~((uint32_t)1U << gate);
}
else
{
CCM_REG(ccgr) = (uint32_t)kCLOCK_ClockNotNeeded;
rootClk = CCM_TUPLE_ROOT(ccmGate);
}
/* if root clock is 0xFFFFU, then skip disable root clock */
if (rootClk != 0xFFFFU)
{
CCM_REG_CLR(rootClk) = CCM_TARGET_ROOT_CLR_ENABLE_MASK;
}
}

View File

@ -0,0 +1,296 @@
/*
* Copyright (c) 2015-2016, Freescale Semiconductor, Inc.
* Copyright 2016-2020 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_common.h"
#define SDK_MEM_MAGIC_NUMBER 12345U
typedef struct _mem_align_control_block
{
uint16_t identifier; /*!< Identifier for the memory control block. */
uint16_t offset; /*!< offset from aligned address to real address */
} mem_align_cb_t;
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.common"
#endif
#ifndef __GIC_PRIO_BITS
#if defined(ENABLE_RAM_VECTOR_TABLE)
uint32_t InstallIRQHandler(IRQn_Type irq, uint32_t irqHandler)
{
#ifdef __VECTOR_TABLE
#undef __VECTOR_TABLE
#endif
/* Addresses for VECTOR_TABLE and VECTOR_RAM come from the linker file */
#if defined(__CC_ARM) || defined(__ARMCC_VERSION)
extern uint32_t Image$$VECTOR_ROM$$Base[];
extern uint32_t Image$$VECTOR_RAM$$Base[];
extern uint32_t Image$$RW_m_data$$Base[];
#define __VECTOR_TABLE Image$$VECTOR_ROM$$Base
#define __VECTOR_RAM Image$$VECTOR_RAM$$Base
#define __RAM_VECTOR_TABLE_SIZE (((uint32_t)Image$$RW_m_data$$Base - (uint32_t)Image$$VECTOR_RAM$$Base))
#elif defined(__ICCARM__)
extern uint32_t __RAM_VECTOR_TABLE_SIZE[];
extern uint32_t __VECTOR_TABLE[];
extern uint32_t __VECTOR_RAM[];
#elif defined(__GNUC__)
extern uint32_t __VECTOR_TABLE[];
extern uint32_t __VECTOR_RAM[];
extern uint32_t __RAM_VECTOR_TABLE_SIZE_BYTES[];
uint32_t __RAM_VECTOR_TABLE_SIZE = (uint32_t)(__RAM_VECTOR_TABLE_SIZE_BYTES);
#endif /* defined(__CC_ARM) || defined(__ARMCC_VERSION) */
uint32_t n;
uint32_t ret;
uint32_t irqMaskValue;
irqMaskValue = DisableGlobalIRQ();
if (SCB->VTOR != (uint32_t)__VECTOR_RAM)
{
/* Copy the vector table from ROM to RAM */
for (n = 0; n < ((uint32_t)__RAM_VECTOR_TABLE_SIZE) / sizeof(uint32_t); n++)
{
__VECTOR_RAM[n] = __VECTOR_TABLE[n];
}
/* Point the VTOR to the position of vector table */
SCB->VTOR = (uint32_t)__VECTOR_RAM;
}
ret = __VECTOR_RAM[(int32_t)irq + 16];
/* make sure the __VECTOR_RAM is noncachable */
__VECTOR_RAM[(int32_t)irq + 16] = irqHandler;
EnableGlobalIRQ(irqMaskValue);
SDK_ISR_EXIT_BARRIER;
return ret;
}
#endif /* ENABLE_RAM_VECTOR_TABLE. */
#endif /* __GIC_PRIO_BITS. */
#if (defined(FSL_FEATURE_SOC_SYSCON_COUNT) && (FSL_FEATURE_SOC_SYSCON_COUNT > 0))
/*
* When FSL_FEATURE_POWERLIB_EXTEND is defined to non-zero value,
* powerlib should be used instead of these functions.
*/
#if !(defined(FSL_FEATURE_POWERLIB_EXTEND) && (FSL_FEATURE_POWERLIB_EXTEND != 0))
/*
* When the SYSCON STARTER registers are discontinuous, these functions are
* implemented in fsl_power.c.
*/
#if !(defined(FSL_FEATURE_SYSCON_STARTER_DISCONTINUOUS) && FSL_FEATURE_SYSCON_STARTER_DISCONTINUOUS)
void EnableDeepSleepIRQ(IRQn_Type interrupt)
{
uint32_t intNumber = (uint32_t)interrupt;
uint32_t index = 0;
while (intNumber >= 32u)
{
index++;
intNumber -= 32u;
}
SYSCON->STARTERSET[index] = 1UL << intNumber;
(void)EnableIRQ(interrupt); /* also enable interrupt at NVIC */
}
void DisableDeepSleepIRQ(IRQn_Type interrupt)
{
uint32_t intNumber = (uint32_t)interrupt;
(void)DisableIRQ(interrupt); /* also disable interrupt at NVIC */
uint32_t index = 0;
while (intNumber >= 32u)
{
index++;
intNumber -= 32u;
}
SYSCON->STARTERCLR[index] = 1UL << intNumber;
}
#endif /* FSL_FEATURE_SYSCON_STARTER_DISCONTINUOUS */
#endif /* FSL_FEATURE_POWERLIB_EXTEND */
#endif /* FSL_FEATURE_SOC_SYSCON_COUNT */
void *SDK_Malloc(size_t size, size_t alignbytes)
{
mem_align_cb_t *p_cb = NULL;
uint32_t alignedsize = SDK_SIZEALIGN(size, alignbytes) + alignbytes + sizeof(mem_align_cb_t);
union
{
void *pointer_value;
uint32_t unsigned_value;
} p_align_addr, p_addr;
p_addr.pointer_value = malloc(alignedsize);
if (p_addr.pointer_value == NULL)
{
return NULL;
}
p_align_addr.unsigned_value = SDK_SIZEALIGN(p_addr.unsigned_value + sizeof(mem_align_cb_t), alignbytes);
p_cb = (mem_align_cb_t *)(p_align_addr.unsigned_value - 4U);
p_cb->identifier = SDK_MEM_MAGIC_NUMBER;
p_cb->offset = (uint16_t)(p_align_addr.unsigned_value - p_addr.unsigned_value);
return p_align_addr.pointer_value;
}
void SDK_Free(void *ptr)
{
union
{
void *pointer_value;
uint32_t unsigned_value;
} p_free;
p_free.pointer_value = ptr;
mem_align_cb_t *p_cb = (mem_align_cb_t *)(p_free.unsigned_value - 4U);
if (p_cb->identifier != SDK_MEM_MAGIC_NUMBER)
{
return;
}
p_free.unsigned_value = p_free.unsigned_value - p_cb->offset;
free(p_free.pointer_value);
}
/*!
* @brief Delay function bases on while loop, every loop includes three instructions.
*
* @param count Counts of loop needed for dalay.
*/
#if defined(SDK_DELAY_USE_DWT) && defined(DWT)
static void enableCpuCycleCounter(void)
{
/* Make sure the DWT trace fucntion is enabled. */
if (CoreDebug_DEMCR_TRCENA_Msk != (CoreDebug_DEMCR_TRCENA_Msk & CoreDebug->DEMCR))
{
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
}
/* CYCCNT not supported on this device. */
assert(DWT_CTRL_NOCYCCNT_Msk != (DWT->CTRL & DWT_CTRL_NOCYCCNT_Msk));
/* Read CYCCNT directly if CYCCENT has already been enabled, otherwise enable CYCCENT first. */
if (DWT_CTRL_CYCCNTENA_Msk != (DWT_CTRL_CYCCNTENA_Msk & DWT->CTRL))
{
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
}
}
static uint32_t getCpuCycleCount(void)
{
return DWT->CYCCNT;
}
#elif defined __XCC__
extern uint32_t xthal_get_ccount(void);
static void enableCpuCycleCounter(void)
{
/* do nothing */
}
static uint32_t getCpuCycleCount(void)
{
return xthal_get_ccount();
}
#endif
#ifndef __XCC__
#if (!defined(SDK_DELAY_USE_DWT)) || (!defined(DWT))
#if defined(__CC_ARM) /* This macro is arm v5 specific */
/* clang-format off */
__ASM static void DelayLoop(uint32_t count)
{
loop
SUBS R0, R0, #1
CMP R0, #0
BNE loop
BX LR
}
/* clang-format on */
#elif defined(__ARMCC_VERSION) || defined(__ICCARM__) || defined(__GNUC__)
/* Cortex-M0 has a smaller instruction set, SUBS isn't supported in thumb-16 mode reported from __GNUC__ compiler,
* use SUB and CMP here for compatibility */
static void DelayLoop(uint32_t count)
{
__ASM volatile(" MOV R0, %0" : : "r"(count));
__ASM volatile(
"loop: \n"
#if defined(__GNUC__) && !defined(__ARMCC_VERSION)
" SUB R0, R0, #1 \n"
#else
" SUBS R0, R0, #1 \n"
#endif
" CMP R0, #0 \n"
" BNE loop \n");
}
#endif /* defined(__CC_ARM) */
#endif /* (!defined(SDK_DELAY_USE_DWT)) || (!defined(DWT)) */
#endif /* __XCC__ */
/*!
* @brief Delay at least for some time.
* Please note that, if not uses DWT, this API will use while loop for delay, different run-time environments have
* effect on the delay time. If precise delay is needed, please enable DWT delay. The two parmeters delayTime_us and
* coreClock_Hz have limitation. For example, in the platform with 1GHz coreClock_Hz, the delayTime_us only supports
* up to 4294967 in current code. If long time delay is needed, please implement a new delay function.
*
* @param delayTime_us Delay time in unit of microsecond.
* @param coreClock_Hz Core clock frequency with Hz.
*/
void SDK_DelayAtLeastUs(uint32_t delayTime_us, uint32_t coreClock_Hz)
{
assert(0U != delayTime_us);
uint64_t count = USEC_TO_COUNT(delayTime_us, coreClock_Hz);
assert(count <= UINT32_MAX);
#if defined(SDK_DELAY_USE_DWT) && defined(DWT) || (defined __XCC__) /* Use DWT for better accuracy */
enableCpuCycleCounter();
/* Calculate the count ticks. */
count += getCpuCycleCount();
if (count > UINT32_MAX)
{
count -= UINT32_MAX;
/* Wait for cyccnt overflow. */
while (count < getCpuCycleCount())
{
}
}
/* Wait for cyccnt reach count value. */
while (count > getCpuCycleCount())
{
}
#else
/* Divide value may be different in various environment to ensure delay is precise.
* Every loop count includes three instructions, due to Cortex-M7 sometimes executes
* two instructions in one period, through test here set divide 1.5. Other M cores use
* divide 4. By the way, divide 1.5 or 4 could let the count lose precision, but it does
* not matter because other instructions outside while loop is enough to fill the time.
*/
#if (__CORTEX_M == 7)
count = count / 3U * 2U;
#else
count = count / 4U;
#endif
DelayLoop((uint32_t)count);
#endif /* defined(SDK_DELAY_USE_DWT) && defined(DWT) || (defined __XCC__) */
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,414 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016-2020 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_mu.h"
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.mu"
#endif
/*******************************************************************************
* Variables
******************************************************************************/
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/*! @brief Pointers to mu clocks for each instance. */
static const clock_ip_name_t s_muClocks[] = MU_CLOCKS;
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/*! @brief Pointers to mu bases for each instance. */
static MU_Type *const s_muBases[] = MU_BASE_PTRS;
/******************************************************************************
* Code
*****************************************************************************/
static uint32_t MU_GetInstance(MU_Type *base)
{
uint32_t instance;
/* Find the instance index from base address mappings. */
for (instance = 0U; instance < (sizeof(s_muBases) / sizeof(s_muBases[0])); instance++)
{
if (s_muBases[instance] == base)
{
break;
}
}
assert(instance < (sizeof(s_muBases) / sizeof(s_muBases[0])));
return instance;
}
/*!
* brief Initializes the MU module.
*
* This function enables the MU clock only.
*
* param base MU peripheral base address.
*/
void MU_Init(MU_Type *base)
{
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
(void)CLOCK_EnableClock(s_muClocks[MU_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
}
/*!
* brief De-initializes the MU module.
*
* This function disables the MU clock only.
*
* param base MU peripheral base address.
*/
void MU_Deinit(MU_Type *base)
{
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
(void)CLOCK_DisableClock(s_muClocks[MU_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
}
/*!
* brief Blocks to send a message.
*
* This function waits until the TX register is empty and sends the message.
*
* param base MU peripheral base address.
* param regIndex TX register index.
* param msg Message to send.
*/
void MU_SendMsg(MU_Type *base, uint32_t regIndex, uint32_t msg)
{
assert(regIndex < MU_TR_COUNT);
/* Wait TX register to be empty. */
while (0U == (base->SR & (((uint32_t)kMU_Tx0EmptyFlag) >> regIndex)))
{
; /* Intentional empty while*/
}
base->TR[regIndex] = msg;
}
/*!
* brief Blocks to receive a message.
*
* This function waits until the RX register is full and receives the message.
*
* param base MU peripheral base address.
* param regIndex RX register index.
* return The received message.
*/
uint32_t MU_ReceiveMsg(MU_Type *base, uint32_t regIndex)
{
assert(regIndex < MU_TR_COUNT);
/* Wait RX register to be full. */
while (0U == (base->SR & (((uint32_t)kMU_Rx0FullFlag) >> regIndex)))
{
; /* Intentional empty while*/
}
return base->RR[regIndex];
}
/*!
* brief Blocks setting the 3-bit MU flags reflect on the other MU side.
*
* This function blocks setting the 3-bit MU flags. Every time the 3-bit MU flags are changed,
* the status flag \c kMU_FlagsUpdatingFlag asserts indicating the 3-bit MU flags are
* updating to the other side. After the 3-bit MU flags are updated, the status flag
* \c kMU_FlagsUpdatingFlag is cleared by hardware. During the flags updating period,
* the flags cannot be changed. This function waits for the MU status flag
* \c kMU_FlagsUpdatingFlag cleared and sets the 3-bit MU flags.
*
* param base MU peripheral base address.
* param flags The 3-bit MU flags to set.
*/
void MU_SetFlags(MU_Type *base, uint32_t flags)
{
/* Wait for update finished. */
while (0U != (base->SR & ((uint32_t)MU_SR_FUP_MASK)))
{
; /* Intentional empty while*/
}
MU_SetFlagsNonBlocking(base, flags);
}
/*!
* brief Triggers interrupts to the other core.
*
* This function triggers the specific interrupts to the other core. The interrupts
* to trigger are passed in as bit mask. See \ref _mu_interrupt_trigger.
* The MU should not trigger an interrupt to the other core when the previous interrupt
* has not been processed by the other core. This function checks whether the
* previous interrupts have been processed. If not, it returns an error.
*
* code
* if (kStatus_Success != MU_TriggerInterrupts(base, kMU_GenInt0InterruptTrigger | kMU_GenInt2InterruptTrigger))
* {
* Previous general purpose interrupt 0 or general purpose interrupt 2
* has not been processed by the other core.
* }
* endcode
*
* param base MU peripheral base address.
* param mask Bit mask of the interrupts to trigger. See _mu_interrupt_trigger.
* retval kStatus_Success Interrupts have been triggered successfully.
* retval kStatus_Fail Previous interrupts have not been accepted.
*/
status_t MU_TriggerInterrupts(MU_Type *base, uint32_t mask)
{
status_t status = kStatus_Success;
uint32_t reg = base->CR;
/* Previous interrupt has been accepted. */
if (0U == (reg & mask))
{
/* All interrupts have been accepted, trigger now. */
reg = (reg & ~(MU_CR_GIRn_MASK | MU_CR_NMI_MASK)) | mask;
base->CR = reg;
status = kStatus_Success;
}
else
{
status = kStatus_Fail;
}
return status;
}
#if !(defined(FSL_FEATURE_MU_NO_RSTH) && FSL_FEATURE_MU_NO_RSTH)
/*!
* brief Boots the core at B side.
*
* This function sets the B side core's boot configuration and releases the
* core from reset.
*
* param base MU peripheral base address.
* param mode Core B boot mode.
* note Only MU side A can use this function.
*/
void MU_BootCoreB(MU_Type *base, mu_core_boot_mode_t mode)
{
#if (defined(FSL_FEATURE_MU_HAS_RESET_DEASSERT_INT) && FSL_FEATURE_MU_HAS_RESET_ASSERT_INT)
/* Clean the reset de-assert pending flag. */
base->SR = MU_SR_RDIP_MASK;
#endif
#if (defined(FSL_FEATURE_MU_HAS_CCR) && FSL_FEATURE_MU_HAS_CCR)
uint32_t reg = base->CCR;
reg = (reg & ~(MU_CCR_HR_MASK | MU_CCR_RSTH_MASK | MU_CCR_BOOT_MASK)) | MU_CCR_BOOT(mode);
base->CCR = reg;
#else
uint32_t reg = base->CR;
reg = (reg & ~((MU_CR_GIRn_MASK | MU_CR_NMI_MASK) | MU_CR_HR_MASK | MU_CR_RSTH_MASK | MU_CR_BBOOT_MASK)) |
MU_CR_BBOOT(mode);
base->CR = reg;
#endif
}
/*!
* brief Boots the other core.
*
* This function boots the other core with a boot configuration.
*
* param base MU peripheral base address.
* param mode The other core boot mode.
*/
void MU_BootOtherCore(MU_Type *base, mu_core_boot_mode_t mode)
{
/*
* MU_BootOtherCore and MU_BootCoreB are the same, MU_BootCoreB is kept
* for compatible with older platforms.
*/
MU_BootCoreB(base, mode);
}
#endif /* FSL_FEATURE_MU_NO_RSTH */
#if !(defined(FSL_FEATURE_MU_NO_HR) && FSL_FEATURE_MU_NO_HR)
#if (defined(FSL_FEATURE_MU_HAS_CCR) && FSL_FEATURE_MU_HAS_CCR)
/*!
* brief Hardware reset the other core.
*
* This function resets the other core, the other core could mask the
* hardware reset by calling ref MU_MaskHardwareReset. The hardware reset
* mask feature is only available for some platforms.
* This function could be used together with MU_BootOtherCore to control the
* other core reset workflow.
*
* Example 1: Reset the other core, and no hold reset
* code
* MU_HardwareResetOtherCore(MU_A, true, false, bootMode);
* endcode
* In this example, the core at MU side B will reset with the specified boot mode.
*
* Example 2: Reset the other core and hold it, then boot the other core later.
* code
* Here the other core enters reset, and the reset is hold
* MU_HardwareResetOtherCore(MU_A, true, true, modeDontCare);
* Current core boot the other core when necessary.
* MU_BootOtherCore(MU_A, bootMode);
* endcode
*
* param base MU peripheral base address.
* param waitReset Wait the other core enters reset.
* - true: Wait until the other core enters reset, if the other
* core has masked the hardware reset, then this function will
* be blocked.
* - false: Don't wait the reset.
* param holdReset Hold the other core reset or not.
* - true: Hold the other core in reset, this function returns
* directly when the other core enters reset.
* - false: Don't hold the other core in reset, this function
* waits until the other core out of reset.
* param bootMode Boot mode of the other core, if p holdReset is true, this
* parameter is useless.
*/
void MU_HardwareResetOtherCore(MU_Type *base, bool waitReset, bool holdReset, mu_core_boot_mode_t bootMode)
{
#if (defined(FSL_FEATURE_MU_NO_RSTH) && FSL_FEATURE_MU_NO_RSTH)
/* If MU does not support hold reset, then the parameter must be false. */
assert(false == holdReset);
#endif
uint32_t ccr = base->CCR & ~(MU_CCR_HR_MASK | MU_CCR_RSTH_MASK | MU_CCR_BOOT_MASK);
ccr |= MU_CCR_BOOT(bootMode);
if (holdReset)
{
ccr |= MU_CCR_RSTH_MASK;
}
/* Clean the reset assert pending flag. */
base->SR = (MU_SR_RAIP_MASK | MU_SR_RDIP_MASK);
/* Set CCR[HR] to trigger hardware reset. */
base->CCR = ccr | MU_CCR_HR_MASK;
/* If wait the other core enters reset. */
if (waitReset)
{
/* Wait for the other core go to reset. */
while (0U == (base->SR & MU_SR_RAIP_MASK))
{
; /* Intentional empty while*/
}
if (!holdReset)
{
/* Clear CCR[HR]. */
base->CCR = ccr;
/* Wait for the other core out of reset. */
while (0U == (base->SR & MU_SR_RDIP_MASK))
{
; /* Intentional empty while*/
}
}
}
}
#else /* FSL_FEATURE_MU_HAS_CCR */
/*!
* brief Hardware reset the other core.
*
* This function resets the other core, the other core could mask the
* hardware reset by calling ref MU_MaskHardwareReset. The hardware reset
* mask feature is only available for some platforms.
* This function could be used together with MU_BootOtherCore to control the
* other core reset workflow.
*
* Example 1: Reset the other core, and no hold reset
* code
* MU_HardwareResetOtherCore(MU_A, true, false, bootMode);
* endcode
* In this example, the core at MU side B will reset with the specified boot mode.
*
* Example 2: Reset the other core and hold it, then boot the other core later.
* code
* Here the other core enters reset, and the reset is hold
* MU_HardwareResetOtherCore(MU_A, true, true, modeDontCare);
* Current core boot the other core when necessary.
* MU_BootOtherCore(MU_A, bootMode);
* endcode
*
* param base MU peripheral base address.
* param waitReset Wait the other core enters reset.
* - true: Wait until the other core enters reset, if the other
* core has masked the hardware reset, then this function will
* be blocked.
* - false: Don't wait the reset.
* param holdReset Hold the other core reset or not.
* - true: Hold the other core in reset, this function returns
* directly when the other core enters reset.
* - false: Don't hold the other core in reset, this function
* waits until the other core out of reset.
* param bootMode Boot mode of the other core, if p holdReset is true, this
* parameter is useless.
*/
void MU_HardwareResetOtherCore(MU_Type *base, bool waitReset, bool holdReset, mu_core_boot_mode_t bootMode)
{
#if (defined(FSL_FEATURE_MU_NO_RSTH) && FSL_FEATURE_MU_NO_RSTH)
/* If MU does not support hold reset, then the parameter must be false. */
assert(false == holdReset);
#endif
uint32_t resetFlag = 0;
uint32_t cr = base->CR & ~(MU_CR_HR_MASK | MU_CR_RSTH_MASK | MU_CR_BOOT_MASK | MU_CR_GIRn_MASK | MU_CR_NMI_MASK);
cr |= MU_CR_BOOT(bootMode);
if (holdReset)
{
cr |= MU_CR_RSTH_MASK;
}
#if (defined(FSL_FEATURE_MU_HAS_RESET_ASSERT_INT) && FSL_FEATURE_MU_HAS_RESET_ASSERT_INT)
resetFlag |= MU_SR_RAIP_MASK;
#endif
#if (defined(FSL_FEATURE_MU_HAS_RESET_DEASSERT_INT) && FSL_FEATURE_MU_HAS_RESET_ASSERT_INT)
resetFlag |= MU_SR_RDIP_MASK;
#endif
/* Clean the reset assert pending flag. */
base->SR = resetFlag;
/* Set CR[HR] to trigger hardware reset. */
base->CR = cr | MU_CR_HR_MASK;
/* If wait the other core enters reset. */
if (waitReset)
{
#if (defined(FSL_FEATURE_MU_HAS_RESET_ASSERT_INT) && FSL_FEATURE_MU_HAS_RESET_ASSERT_INT)
/* Wait for the other core go to reset. */
while (0U == (base->SR & MU_SR_RAIP_MASK))
{
; /* Intentional empty while*/
}
#endif
if (!holdReset)
{
/* Clear CR[HR]. */
base->CR = cr;
#if (defined(FSL_FEATURE_MU_HAS_RESET_DEASSERT_INT) && FSL_FEATURE_MU_HAS_RESET_ASSERT_INT)
/* Wait for the other core out of reset. */
while (0U == (base->SR & MU_SR_RDIP_MASK))
{
; /* Intentional empty while*/
}
#endif
}
}
}
#endif /* FSL_FEATURE_MU_HAS_CCR */
#endif /* FSL_FEATURE_MU_NO_HR */

View File

@ -0,0 +1,310 @@
/*
* Copyright 2017-2020 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_rdc.h"
/******************************************************************************
* Definitions
*****************************************************************************/
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.rdc"
#endif
typedef union
{
rdc_domain_assignment_t _mda;
uint32_t _u32;
} rdc_mda_reg_t;
typedef union
{
rdc_hardware_config_t _vir;
uint32_t _u32;
} rdc_vir_reg_t;
/*******************************************************************************
* Prototypes
******************************************************************************/
/*!
* @brief Get instance number for RDC module.
*
* @param base RDC peripheral base address.
*/
uint32_t RDC_GetInstance(RDC_Type *base);
/*******************************************************************************
* Variables
******************************************************************************/
/*! @brief Pointers to rdc bases for each instance. */
static RDC_Type *const s_rdcBases[] = RDC_BASE_PTRS;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/*! @brief Pointers to rdc clocks for each instance. */
static const clock_ip_name_t s_rdcClocks[] = RDC_CLOCKS;
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/******************************************************************************
* CODE
*****************************************************************************/
uint32_t RDC_GetInstance(RDC_Type *base)
{
uint32_t instance;
/* Find the instance index from base address mappings. */
for (instance = 0; instance < ARRAY_SIZE(s_rdcBases); instance++)
{
if (s_rdcBases[instance] == base)
{
break;
}
}
assert(instance < ARRAY_SIZE(s_rdcBases));
return instance;
}
/*!
* brief Initializes the RDC module.
*
* This function enables the RDC clock.
*
* param base RDC peripheral base address.
*/
void RDC_Init(RDC_Type *base)
{
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
CLOCK_EnableClock(s_rdcClocks[RDC_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
}
/*!
* brief De-initializes the RDC module.
*
* This function disables the RDC clock.
*
* param base RDC peripheral base address.
*/
void RDC_Deinit(RDC_Type *base)
{
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
CLOCK_DisableClock(s_rdcClocks[RDC_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
}
/*!
* brief Gets the RDC hardware configuration.
*
* This function gets the RDC hardware configurations, including number of bus
* masters, number of domains, number of memory regions and number of peripherals.
*
* param base RDC peripheral base address.
* param config Pointer to the structure to get the configuration.
*/
void RDC_GetHardwareConfig(RDC_Type *base, rdc_hardware_config_t *config)
{
assert(NULL != config);
rdc_vir_reg_t vir;
vir._u32 = base->VIR;
*config = vir._vir;
}
/*!
* brief Set master domain assignment
*
* param base RDC peripheral base address.
* param master Which master to set.
* param domainAssignment Pointer to the assignment.
*/
void RDC_SetMasterDomainAssignment(RDC_Type *base, rdc_master_t master, const rdc_domain_assignment_t *domainAssignment)
{
assert((uint32_t)master < RDC_MDA_COUNT);
rdc_mda_reg_t mda;
mda._mda = *domainAssignment;
base->MDA[master] = mda._u32;
}
/*!
* brief Get default master domain assignment
*
* The default configuration is:
* code
assignment->domainId = 0U;
assignment->lock = 0U;
endcode
*
* param domainAssignment Pointer to the assignment.
*/
void RDC_GetDefaultMasterDomainAssignment(rdc_domain_assignment_t *domainAssignment)
{
assert(NULL != domainAssignment);
rdc_mda_reg_t mda;
mda._u32 = 0U;
*domainAssignment = mda._mda;
}
/*!
* brief Set peripheral access policy.
*
* param base RDC peripheral base address.
* param config Pointer to the policy configuration.
*/
void RDC_SetPeriphAccessConfig(RDC_Type *base, const rdc_periph_access_config_t *config)
{
assert((uint32_t)config->periph < RDC_PDAP_COUNT);
uint32_t periph = (uint32_t)config->periph;
uint32_t regPDAP = config->policy;
if (config->lock)
{
regPDAP |= RDC_PDAP_LCK_MASK;
}
if (config->enableSema)
{
regPDAP |= RDC_PDAP_SREQ_MASK;
}
base->PDAP[periph] = regPDAP;
__DSB();
}
/*!
* brief Get default peripheral access policy.
*
* The default configuration is:
* code
config->lock = false;
config->enableSema = false;
config->policy = RDC_ACCESS_POLICY(0, kRDC_ReadWrite) |
RDC_ACCESS_POLICY(1, kRDC_ReadWrite) |
RDC_ACCESS_POLICY(2, kRDC_ReadWrite) |
RDC_ACCESS_POLICY(3, kRDC_ReadWrite);
endcode
*
* param config Pointer to the policy configuration.
*/
void RDC_GetDefaultPeriphAccessConfig(rdc_periph_access_config_t *config)
{
assert(NULL != config);
/* Initializes the configure structure to zero. */
(void)memset(config, 0, sizeof(*config));
config->lock = false;
config->enableSema = false;
config->policy = RDC_ACCESS_POLICY(0U, kRDC_ReadWrite) | RDC_ACCESS_POLICY(1U, kRDC_ReadWrite) |
RDC_ACCESS_POLICY(2U, kRDC_ReadWrite) | RDC_ACCESS_POLICY(3U, kRDC_ReadWrite);
}
/*!
* brief Set memory region access policy.
*
* Note that when setting the baseAddress and endAddress in p config,
* should be aligned to the region resolution, see rdc_mem_t
* definitions.
*
* param base RDC peripheral base address.
* param config Pointer to the policy configuration.
*/
void RDC_SetMemAccessConfig(RDC_Type *base, const rdc_mem_access_config_t *config)
{
assert((uint32_t)config->mem < RDC_MRC_COUNT);
uint32_t mem = (uint32_t)config->mem;
/* The configuration is enabled by default. */
uint32_t regMRC = config->policy | RDC_MRC_ENA_MASK;
if (config->lock)
{
regMRC |= RDC_MRC_LCK_MASK;
}
#if (defined(FSL_FEATURE_RDC_MEM_REGION_ADDR_SHIFT) && FSL_FEATURE_RDC_MEM_REGION_ADDR_SHIFT)
base->MR[mem].MRSA = (uint32_t)(config->baseAddress >> (uint32_t)FSL_FEATURE_RDC_MEM_REGION_ADDR_SHIFT);
base->MR[mem].MREA = (uint32_t)(config->endAddress >> (uint32_t)FSL_FEATURE_RDC_MEM_REGION_ADDR_SHIFT);
#else
base->MR[mem].MRSA = (uint32_t)config->baseAddress;
base->MR[mem].MREA = (uint32_t)config->endAddress;
#endif
base->MR[mem].MRC = regMRC;
__DSB();
}
/*!
* brief Get default memory region access policy.
*
* The default configuration is:
* code
config->lock = false;
config->baseAddress = 0;
config->endAddress = 0;
config->policy = RDC_ACCESS_POLICY(0, kRDC_ReadWrite) |
RDC_ACCESS_POLICY(1, kRDC_ReadWrite) |
RDC_ACCESS_POLICY(2, kRDC_ReadWrite) |
RDC_ACCESS_POLICY(3, kRDC_ReadWrite);
endcode
*
* param config Pointer to the policy configuration.
*/
void RDC_GetDefaultMemAccessConfig(rdc_mem_access_config_t *config)
{
assert(NULL != config);
/* Initializes the configure structure to zero. */
(void)memset(config, 0, sizeof(*config));
config->lock = false;
config->baseAddress = 0;
config->endAddress = 0;
config->policy = RDC_ACCESS_POLICY(0U, kRDC_ReadWrite) | RDC_ACCESS_POLICY(1U, kRDC_ReadWrite) |
RDC_ACCESS_POLICY(2U, kRDC_ReadWrite) | RDC_ACCESS_POLICY(3U, kRDC_ReadWrite);
}
/*!
* brief Get the memory region violation status.
*
* The first access violation is captured. Subsequent violations are ignored
* until the status register is cleared. Contents are cleared upon reading the
* register. Clearing of contents occurs only when the status is read by the
* memory region's associated domain ID(s).
*
* param base RDC peripheral base address.
* param mem Which memory region to get.
* param status The returned status.
*/
void RDC_GetMemViolationStatus(RDC_Type *base, rdc_mem_t mem, rdc_mem_status_t *status)
{
assert((uint32_t)mem < RDC_MRC_COUNT);
uint32_t regMRVS = base->MR[mem].MRVS;
status->hasViolation = ((regMRVS & RDC_MRVS_AD_MASK) != 0U);
status->domainID = (uint8_t)((regMRVS & RDC_MRVS_VDID_MASK) >> RDC_MRVS_VDID_SHIFT);
#if (defined(FSL_FEATURE_RDC_MEM_REGION_ADDR_SHIFT) && FSL_FEATURE_RDC_MEM_REGION_ADDR_SHIFT)
regMRVS &= RDC_MRVS_VADR_MASK;
status->address = ((uint64_t)regMRVS) << (uint32_t)FSL_FEATURE_RDC_MEM_REGION_ADDR_SHIFT;
#else
regMRVS &= RDC_MRVS_VADR_MASK;
status->address = (uint64_t)regMRVS;
#endif
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,441 @@
/*
** ###################################################################
** Version: rev. 4.0, 2020-11-16
** Build: b201104
**
** Abstract:
** Chip specific module features.
**
** Copyright 2016 Freescale Semiconductor, Inc.
** Copyright 2016-2020 NXP
** All rights reserved.
**
** SPDX-License-Identifier: BSD-3-Clause
**
** http: www.nxp.com
** mail: support@nxp.com
**
** Revisions:
** - rev. 1.0 (2019-10-11)
** Initial version.
** - rev. 2.0 (2020-02-21)
** Rev.B Header.
** - rev. 3.0 (2020-06-22)
** Rev.C Header.
** - rev. 4.0 (2020-11-16)
** Rev.D Header.
**
** ###################################################################
*/
#ifndef _MIMX8ML8_cm7_FEATURES_H_
#define _MIMX8ML8_cm7_FEATURES_H_
/* SOC module features */
/* @brief AIPSTZ availability on the SoC. */
#define FSL_FEATURE_SOC_AIPSTZ_COUNT (5)
/* @brief APBH availability on the SoC. */
#define FSL_FEATURE_SOC_APBH_COUNT (1)
/* @brief ASRC availability on the SoC. */
#define FSL_FEATURE_SOC_ASRC_COUNT (1)
/* @brief BCH availability on the SoC. */
#define FSL_FEATURE_SOC_BCH_COUNT (1)
/* @brief CCM availability on the SoC. */
#define FSL_FEATURE_SOC_CCM_COUNT (1)
/* @brief CCM_ANALOG availability on the SoC. */
#define FSL_FEATURE_SOC_CCM_ANALOG_COUNT (1)
/* @brief DDRC availability on the SoC. */
#define FSL_FEATURE_SOC_DDRC_COUNT (1)
/* @brief ECSPI availability on the SoC. */
#define FSL_FEATURE_SOC_ECSPI_COUNT (3)
/* @brief EDMA availability on the SoC. */
#define FSL_FEATURE_SOC_EDMA_COUNT (1)
/* @brief ENET availability on the SoC. */
#define FSL_FEATURE_SOC_ENET_COUNT (1)
/* @brief ENET_QOS availability on the SoC. */
#define FSL_FEATURE_SOC_ENET_QOS_COUNT (1)
/* @brief FLEXCAN availability on the SoC. */
#define FSL_FEATURE_SOC_FLEXCAN_COUNT (2)
/* @brief FLEXSPI availability on the SoC. */
#define FSL_FEATURE_SOC_FLEXSPI_COUNT (1)
/* @brief GPC availability on the SoC. */
#define FSL_FEATURE_SOC_GPC_COUNT (1)
/* @brief GPC_PGC availability on the SoC. */
#define FSL_FEATURE_SOC_GPC_PGC_COUNT (1)
/* @brief GPMI availability on the SoC. */
#define FSL_FEATURE_SOC_GPMI_COUNT (1)
/* @brief GPT availability on the SoC. */
#define FSL_FEATURE_SOC_GPT_COUNT (6)
/* @brief I2S availability on the SoC. */
#define FSL_FEATURE_SOC_I2S_COUNT (6)
/* @brief IGPIO availability on the SoC. */
#define FSL_FEATURE_SOC_IGPIO_COUNT (5)
/* @brief II2C availability on the SoC. */
#define FSL_FEATURE_SOC_II2C_COUNT (6)
/* @brief IOMUXC availability on the SoC. */
#define FSL_FEATURE_SOC_IOMUXC_COUNT (1)
/* @brief IOMUXC_GPR availability on the SoC. */
#define FSL_FEATURE_SOC_IOMUXC_GPR_COUNT (1)
/* @brief IPWM availability on the SoC. */
#define FSL_FEATURE_SOC_IPWM_COUNT (4)
/* @brief IRQSTEER availability on the SoC. */
#define FSL_FEATURE_SOC_IRQSTEER_COUNT (2)
/* @brief ISI availability on the SoC. */
#define FSL_FEATURE_SOC_ISI_COUNT (1)
/* @brief IUART availability on the SoC. */
#define FSL_FEATURE_SOC_IUART_COUNT (4)
/* @brief LCDIF availability on the SoC. */
#define FSL_FEATURE_SOC_LCDIF_COUNT (3)
/* @brief MU availability on the SoC. */
#define FSL_FEATURE_SOC_MU_COUNT (1)
/* @brief NPU availability on the SoC. */
#define FSL_FEATURE_SOC_NPU_COUNT (1)
/* @brief OCOTP availability on the SoC. */
#define FSL_FEATURE_SOC_OCOTP_COUNT (1)
/* @brief PDM availability on the SoC. */
#define FSL_FEATURE_SOC_PDM_COUNT (1)
/* @brief RDC availability on the SoC. */
#define FSL_FEATURE_SOC_RDC_COUNT (1)
/* @brief RDC_SEMAPHORE availability on the SoC. */
#define FSL_FEATURE_SOC_RDC_SEMAPHORE_COUNT (2)
/* @brief SDMA availability on the SoC. */
#define FSL_FEATURE_SOC_SDMA_COUNT (3)
/* @brief SEMA4 availability on the SoC. */
#define FSL_FEATURE_SOC_SEMA4_COUNT (1)
/* @brief SNVS availability on the SoC. */
#define FSL_FEATURE_SOC_SNVS_COUNT (1)
/* @brief SPBA availability on the SoC. */
#define FSL_FEATURE_SOC_SPBA_COUNT (2)
/* @brief SRC availability on the SoC. */
#define FSL_FEATURE_SOC_SRC_COUNT (1)
/* @brief USB availability on the SoC. */
#define FSL_FEATURE_SOC_USB_COUNT (2)
/* @brief USDHC availability on the SoC. */
#define FSL_FEATURE_SOC_USDHC_COUNT (3)
/* @brief WDOG availability on the SoC. */
#define FSL_FEATURE_SOC_WDOG_COUNT (3)
/* @brief XTALOSC availability on the SoC. */
#define FSL_FEATURE_SOC_XTALOSC_COUNT (1)
/* CACHE module features */
/* @brief L1 ICACHE line size in byte. */
#define FSL_FEATURE_L1ICACHE_LINESIZE_BYTE (32)
/* @brief L1 DCACHE line size in byte. */
#define FSL_FEATURE_L1DCACHE_LINESIZE_BYTE (32)
/* CCM module features */
/* @brief Is affected by errata with ID 50235 (Incorrect clock setting for CAN affects by LPUART clock gate). */
#define FSL_FEATURE_CCM_HAS_ERRATA_50235 (0)
/* ECSPI module features */
/* @brief ECSPI Tx FIFO Size. */
#define FSL_FEATURE_ECSPI_TX_FIFO_SIZEn(x) (64)
/* EDMA module features */
/* @brief Number of DMA channels (related to number of registers TCD, DCHPRI, bit fields ERQ[ERQn], EEI[EEIn],
* INT[INTn], ERR[ERRn], HRS[HRSn] and bit field widths ES[ERRCHN], CEEI[CEEI], SEEI[SEEI], CERQ[CERQ], SERQ[SERQ],
* CDNE[CDNE], SSRT[SSRT], CERR[CERR], CINT[CINT], TCDn_CITER_ELINKYES[LINKCH], TCDn_CSR[MAJORLINKCH],
* TCDn_BITER_ELINKYES[LINKCH]). (Valid only for eDMA modules.) */
#define FSL_FEATURE_EDMA_MODULE_CHANNEL (32)
/* @brief Total number of DMA channels on all modules. */
#define FSL_FEATURE_EDMA_DMAMUX_CHANNELS (32)
/* @brief Number of DMA channel groups (register bit fields CR[ERGA], CR[GRPnPRI], ES[GPE], DCHPRIn[GRPPRI]). (Valid
* only for eDMA modules.) */
#define FSL_FEATURE_EDMA_CHANNEL_GROUP_COUNT (1)
/* @brief Has DMA_Error interrupt vector. */
#define FSL_FEATURE_EDMA_HAS_ERROR_IRQ (1)
/* @brief Number of DMA channels with asynchronous request capability (register EARS). (Valid only for eDMA modules.) */
#define FSL_FEATURE_EDMA_ASYNCHRO_REQUEST_CHANNEL_COUNT (32)
/* @brief If channel clock controlled independently */
#define FSL_FEATURE_EDMA_CHANNEL_HAS_OWN_CLOCK_GATE (1)
/* @brief Number of channel for each EDMA instance, (only defined for soc with different channel numbers for difference
* instance) */
#define FSL_FEATURE_EDMA_INSTANCE_CHANNELn(x) (32)
/* @brief Has no register bit fields MP_CSR[EBW]. */
#define FSL_FEATURE_EDMA_HAS_NO_MP_CSR_EBW (1)
/* ENET module features */
/* @brief Support Interrupt Coalesce */
#define FSL_FEATURE_ENET_HAS_INTERRUPT_COALESCE (1)
/* @brief Queue Size. */
#define FSL_FEATURE_ENET_QUEUE (3)
/* @brief Has AVB Support. */
#define FSL_FEATURE_ENET_HAS_AVB (1)
/* @brief Has Timer Pulse Width control. */
#define FSL_FEATURE_ENET_HAS_TIMER_PWCONTROL (0)
/* @brief Has Extend MDIO Support. */
#define FSL_FEATURE_ENET_HAS_EXTEND_MDIO (1)
/* @brief Has Additional 1588 Timer Channel Interrupt. */
#define FSL_FEATURE_ENET_HAS_ADD_1588_TIMER_CHN_INT (1)
/* @brief Support Interrupt Coalesce for each instance */
#define FSL_FEATURE_ENET_INSTANCE_HAS_INTERRUPT_COALESCEn(x) (0)
/* @brief Queue Size for each instance. */
#define FSL_FEATURE_ENET_INSTANCE_QUEUEn(x) (3)
/* @brief Has AVB Support for each instance. */
#define FSL_FEATURE_ENET_INSTANCE_HAS_AVBn(x) (1)
/* @brief Has Timer Pulse Width control for each instance. */
#define FSL_FEATURE_ENET_INSTANCE_HAS_TIMER_PWCONTROLn(x) (0)
/* @brief Has Extend MDIO Support for each instance. */
#define FSL_FEATURE_ENET_INSTANCE_HAS_EXTEND_MDIOn(x) (1)
/* @brief Has Additional 1588 Timer Channel Interrupt for each instance. */
#define FSL_FEATURE_ENET_INSTANCE_HAS_ADD_1588_TIMER_CHN_INTn(x) (1)
/* @brief Has threshold for the number of frames in the receive FIFO (register bit field RSEM[STAT_SECTION_EMPTY]). */
#define FSL_FEATURE_ENET_HAS_RECEIVE_STATUS_THRESHOLD (1)
/* @brief Has trasfer clock delay (register bit field ECR[TXC_DLY]). */
#define FSL_FEATURE_ENET_HAS_RGMII_TXC_DELAY (1)
/* @brief Has receive clock delay (register bit field ECR[RXC_DLY]). */
#define FSL_FEATURE_ENET_HAS_RGMII_RXC_DELAY (1)
/* ENET_QOS module features */
/* No feature definitions */
/* FLEXCAN module features */
/* @brief Message buffer size */
#define FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(x) (64)
/* @brief Has doze mode support (register bit field MCR[DOZE]). */
#define FSL_FEATURE_FLEXCAN_HAS_DOZE_MODE_SUPPORT (1)
/* @brief Insatnce has doze mode support (register bit field MCR[DOZE]). */
#define FSL_FEATURE_FLEXCAN_INSTANCE_HAS_DOZE_MODE_SUPPORTn(x) (1)
/* @brief Has a glitch filter on the receive pin (register bit field MCR[WAKSRC]). */
#define FSL_FEATURE_FLEXCAN_HAS_GLITCH_FILTER (1)
/* @brief Has extended interrupt mask and flag register (register IMASK2, IFLAG2). */
#define FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER (1)
/* @brief Instance has extended bit timing register (register CBT). */
#define FSL_FEATURE_FLEXCAN_INSTANCE_HAS_EXTENDED_TIMING_REGISTERn(x) (1)
/* @brief Has a receive FIFO DMA feature (register bit field MCR[DMA]). */
#define FSL_FEATURE_FLEXCAN_HAS_RX_FIFO_DMA (1)
/* @brief Instance has a receive FIFO DMA feature (register bit field MCR[DMA]). */
#define FSL_FEATURE_FLEXCAN_INSTANCE_HAS_RX_FIFO_DMAn(x) (1)
/* @brief Remove CAN Engine Clock Source Selection from unsupported part. */
#define FSL_FEATURE_FLEXCAN_SUPPORT_ENGINE_CLK_SEL_REMOVE (0)
/* @brief Instance remove CAN Engine Clock Source Selection from unsupported part. */
#define FSL_FEATURE_FLEXCAN_INSTANCE_SUPPORT_ENGINE_CLK_SEL_REMOVEn(x) (0)
/* @brief Is affected by errata with ID 5641 (Module does not transmit a message that is enabled to be transmitted at a
* specific moment during the arbitration process). */
#define FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641 (0)
/* @brief Is affected by errata with ID 5829 (FlexCAN: FlexCAN does not transmit a message that is enabled to be
* transmitted in a specific moment during the arbitration process). */
#define FSL_FEATURE_FLEXCAN_HAS_ERRATA_5829 (0)
/* @brief Is affected by errata with ID 6032 (FlexCAN: A frame with wrong ID or payload is transmitted into the CAN bus
* when the Message Buffer under transmission is either aborted or deactivated while the CAN bus is in the Bus Idle
* state). */
#define FSL_FEATURE_FLEXCAN_HAS_ERRATA_6032 (0)
/* @brief Is affected by errata with ID 9595 (FlexCAN: Corrupt frame possible if the Freeze Mode or the Low-Power Mode
* are entered during a Bus-Off state). */
#define FSL_FEATURE_FLEXCAN_HAS_ERRATA_9595 (0)
/* @brief Has CAN with Flexible Data rate (CAN FD) protocol. */
#define FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE (1)
/* @brief CAN instance support Flexible Data rate (CAN FD) protocol. */
#define FSL_FEATURE_FLEXCAN_INSTANCE_HAS_FLEXIBLE_DATA_RATEn(x) (1)
/* @brief Has extra MB interrupt or common one. */
#define FSL_FEATURE_FLEXCAN_HAS_EXTRA_MB_INT (0)
/* @brief Has memory error control (register MECR). */
#define FSL_FEATURE_FLEXCAN_HAS_MEMORY_ERROR_CONTROL (1)
/* IGPIO module features */
/* @brief Has data register set DR_SET. */
#define FSL_FEATURE_IGPIO_HAS_DR_SET (0)
/* @brief Has data register clear DR_CLEAR. */
#define FSL_FEATURE_IGPIO_HAS_DR_CLEAR (0)
/* @brief Has data register toggle DR_TOGGLE. */
#define FSL_FEATURE_IGPIO_HAS_DR_TOGGLE (0)
/* SAI module features */
/* @brief Receive/transmit FIFO size in item count (register bit fields TCSR[FRDE], TCSR[FRIE], TCSR[FRF], TCR1[TFW],
* RCSR[FRDE], RCSR[FRIE], RCSR[FRF], RCR1[RFW], registers TFRn, RFRn). */
#define FSL_FEATURE_SAI_FIFO_COUNT (128)
/* @brief Receive/transmit channel number (register bit fields TCR3[TCE], RCR3[RCE], registers TDRn and RDRn). */
#define FSL_FEATURE_SAI_CHANNEL_COUNTn(x) (8)
/* @brief Maximum words per frame (register bit fields TCR3[WDFL], TCR4[FRSZ], TMR[TWM], RCR3[WDFL], RCR4[FRSZ],
* RMR[RWM]). */
#define FSL_FEATURE_SAI_MAX_WORDS_PER_FRAME (32)
/* @brief Has support of combining multiple data channel FIFOs into single channel FIFO (register bit fields TCR3[CFR],
* TCR4[FCOMB], TFR0[WCP], TFR1[WCP], RCR3[CFR], RCR4[FCOMB], RFR0[RCP], RFR1[RCP]). */
#define FSL_FEATURE_SAI_HAS_FIFO_COMBINE_MODE (1)
/* @brief Has packing of 8-bit and 16-bit data into each 32-bit FIFO word (register bit fields TCR4[FPACK],
* RCR4[FPACK]). */
#define FSL_FEATURE_SAI_HAS_FIFO_PACKING (1)
/* @brief Configures when the SAI will continue transmitting after a FIFO error has been detected (register bit fields
* TCR4[FCONT], RCR4[FCONT]). */
#define FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR (1)
/* @brief Configures if the frame sync is generated internally, a frame sync is only generated when the FIFO warning
* flag is clear or continuously (register bit fields TCR4[ONDEM], RCR4[ONDEM]). */
#define FSL_FEATURE_SAI_HAS_ON_DEMAND_MODE (1)
/* @brief Simplified bit clock source and asynchronous/synchronous mode selection (register bit fields TCR2[CLKMODE],
* RCR2[CLKMODE]), in comparison with the exclusively implemented TCR2[SYNC,BCS,BCI,MSEL], RCR2[SYNC,BCS,BCI,MSEL]. */
#define FSL_FEATURE_SAI_HAS_CLOCKING_MODE (0)
/* @brief Has register for configuration of the MCLK divide ratio (register bit fields MDR[FRACT], MDR[DIVIDE]). */
#define FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER (0)
/* @brief Interrupt source number */
#define FSL_FEATURE_SAI_INT_SOURCE_NUM (1)
/* @brief Has register of MCR. */
#define FSL_FEATURE_SAI_HAS_MCR (1)
/* @brief Has bit field MICS of the MCR register. */
#define FSL_FEATURE_SAI_HAS_NO_MCR_MICS (1)
/* @brief Has register of MDR */
#define FSL_FEATURE_SAI_HAS_MDR (0)
/* @brief Has support the BCLK bypass mode when BCLK = MCLK. */
#define FSL_FEATURE_SAI_HAS_BCLK_BYPASS (1)
/* @brief Has DIV bit fields of MCR register (register bit fields MCR[DIV]. */
#define FSL_FEATURE_SAI_HAS_MCR_MCLK_POST_DIV (1)
/* @brief Support Channel Mode (register bit fields TCR4[CHMOD]). */
#define FSL_FEATURE_SAI_HAS_CHANNEL_MODE (1)
/* @brief SAI5 AND SAI6 SHARE ONE IRQNUMBER. */
#define FSL_FEATURE_SAI_SAI5_SAI6_SHARE_IRQ (1)
/* ISI module features */
/* No feature definitions */
/* MEMORY module features */
/* @brief Memory map has offset between subsystems. */
#define FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET (1)
/* MU module features */
/* @brief MU side for current core */
#define FSL_FEATURE_MU_SIDE_B (1)
/* @brief MU Has register CCR */
#define FSL_FEATURE_MU_HAS_CCR (0)
/* @brief MU Has register SR[RS], BSR[ARS] */
#define FSL_FEATURE_MU_HAS_SR_RS (1)
/* @brief MU Has register CR[RDIE], CR[RAIE], SR[RDIP], SR[RAIP] */
#define FSL_FEATURE_MU_HAS_RESET_INT (0)
/* @brief MU Has register SR[MURIP] */
#define FSL_FEATURE_MU_HAS_SR_MURIP (0)
/* @brief MU Has register SR[HRIP] */
#define FSL_FEATURE_MU_HAS_SR_HRIP (0)
/* @brief MU does not support enable clock of the other core, CR[CLKE] or CCR[CLKE]. */
#define FSL_FEATURE_MU_NO_CLKE (1)
/* @brief MU does not support NMI, CR[NMI]. */
#define FSL_FEATURE_MU_NO_NMI (1)
/* @brief MU does not support hold the other core reset. CR[RSTH] or CCR[RSTH]. */
#define FSL_FEATURE_MU_NO_RSTH (1)
/* @brief MU does not supports MU reset, CR[MUR]. */
#define FSL_FEATURE_MU_NO_MUR (1)
/* @brief MU does not supports hardware reset, CR[HR] or CCR[HR]. */
#define FSL_FEATURE_MU_NO_HR (1)
/* @brief MU supports mask the hardware reset. CR[HRM] or CCR[HRM]. */
#define FSL_FEATURE_MU_HAS_HRM (1)
/* @brief MU does not support check the other core power mode. SR[PM]. */
#define FSL_FEATURE_MU_NO_PM (1)
/* @brief MU supports reset assert interrupt. CR[RAIE] or BCR[RAIE]. */
#define FSL_FEATURE_MU_HAS_RESET_ASSERT_INT (0)
/* @brief MU supports reset de-assert interrupt. CR[RDIE] or BCR[RDIE]. */
#define FSL_FEATURE_MU_HAS_RESET_DEASSERT_INT (0)
/* interrupt module features */
/* @brief Lowest interrupt request number. */
#define FSL_FEATURE_INTERRUPT_IRQ_MIN (-14)
/* @brief Highest interrupt request number. */
#define FSL_FEATURE_INTERRUPT_IRQ_MAX (105)
/* PDM module features */
/* @brief PDM FIFO offset */
#define FSL_FEATURE_PDM_FIFO_OFFSET (4)
/* @brief PDM Channel Number */
#define FSL_FEATURE_PDM_CHANNEL_NUM (8)
/* @brief PDM FIFO WIDTH Size */
#define FSL_FEATURE_PDM_FIFO_WIDTH (4)
/* @brief PDM FIFO DEPTH Size */
#define FSL_FEATURE_PDM_FIFO_DEPTH (32)
/* @brief PDM has RANGE_CTRL register */
#define FSL_FEATURE_PDM_HAS_RANGE_CTRL (1)
/* RDC module features */
/* @brief Memory address need shift when configure the RDC. */
#define FSL_FEATURE_RDC_MEM_REGION_ADDR_SHIFT (1)
/* SDMA module features */
/* @brief SDMA module channel number. */
#define FSL_FEATURE_SDMA_MODULE_CHANNEL (32)
/* @brief SDMA module event number. */
#define FSL_FEATURE_SDMA_EVENT_NUM (48)
/* @brief SDMA ROM memory to memory script start address. */
#define FSL_FEATURE_SDMA_M2M_ADDR (644)
/* @brief SDMA ROM peripheral to memory script start address. */
#define FSL_FEATURE_SDMA_P2M_ADDR (685)
/* @brief SDMA ROM memory to peripheral script start address. */
#define FSL_FEATURE_SDMA_M2P_ADDR (749)
/* @brief SDMA ROM uart to memory script start address. */
#define FSL_FEATURE_SDMA_UART2M_ADDR (819)
/* @brief SDMA ROM peripheral on SPBA to memory script start address. */
#define FSL_FEATURE_SDMA_SHP2M_ADDR (893)
/* @brief SDMA ROM memory to peripheral on SPBA script start address. */
#define FSL_FEATURE_SDMA_M2SHP_ADDR (962)
/* @brief SDMA ROM UART on SPBA to memory script start address. */
#define FSL_FEATURE_SDMA_UARTSH2M_ADDR (1034)
/* @brief SDMA ROM SPDIF to memory script start address. */
#define FSL_FEATURE_SDMA_SPDIF2M_ADDR (1102)
/* @brief SDMA ROM memory to SPDIF script start address. */
#define FSL_FEATURE_SDMA_M2SPDIF_ADDR (1136)
/* @brief SDMA ROM memory to MULTI_FIFO_SAI_TX script start address. */
#define FSL_FEATURE_SDMA_MULTI_FIFO_SAI_TX_ADDR (6235)
/* @brief SDMA ROM memory to MULTI_FIFO_SAI_RX script start address. */
#define FSL_FEATURE_SDMA_MULTI_FIFO_SAI_RX_ADDR (6729)
/* SEMA4 module features */
/* @brief Gate counts */
#define FSL_FEATURE_SEMA4_GATE_COUNT (16)
/* SPBA module features */
/* @brief SPBA module start address. */
#define FSL_FEATURE_SPBA_STARTn(x) (((x) == SPBA1) ? (0x30800000) : (((x) == SPBA2) ? (0x30C00000) : (-1)))
/* @brief SPBA module end address. */
#define FSL_FEATURE_SPBA_ENDn(x) (((x) == SPBA1) ? (0x308FFFFF) : (((x) == SPBA2) ? (0x30CFFFFF) : (-1)))
/* SysTick module features */
/* @brief Systick has external reference clock. */
#define FSL_FEATURE_SYSTICK_HAS_EXT_REF (0)
/* @brief Systick external reference clock is core clock divided by this value. */
#define FSL_FEATURE_SYSTICK_EXT_REF_CORE_DIV (0)
/* IUART module features */
/* @brief UART Transmit/Receive FIFO Size */
#define FSL_FEATURE_IUART_FIFO_SIZEn(x) (32)
/* @brief UART RX MUXed input selected option */
#define FSL_FEATURE_IUART_RXDMUXSEL (1)
/* USDHC module features */
/* @brief Has external DMA support (VEND_SPEC[EXT_DMA_EN]) */
#define FSL_FEATURE_USDHC_HAS_EXT_DMA (1)
/* @brief Has HS400 mode (MIX_CTRL[HS400_MODE]) */
#define FSL_FEATURE_USDHC_HAS_HS400_MODE (1)
/* @brief Has SDR50 support (HOST_CTRL_CAP[SDR50_SUPPORT]) */
#define FSL_FEATURE_USDHC_HAS_SDR50_MODE (1)
/* @brief Has SDR104 support (HOST_CTRL_CAP[SDR104_SUPPORT]) */
#define FSL_FEATURE_USDHC_HAS_SDR104_MODE (1)
/* @brief USDHC has reset control */
#define FSL_FEATURE_USDHC_HAS_RESET (0)
/* @brief USDHC has no bitfield WTMK_LVL[WR_BRST_LEN] and WTMK_LVL[RD_BRST_LEN] */
#define FSL_FEATURE_USDHC_HAS_NO_RW_BURST_LEN (1)
/* @brief If USDHC instance support 8 bit width */
#define FSL_FEATURE_USDHC_INSTANCE_SUPPORT_8_BIT_WIDTHn(x) (1)
/* @brief If USDHC instance support HS400 mode */
#define FSL_FEATURE_USDHC_INSTANCE_SUPPORT_HS400_MODEn(x) (0)
/* @brief If USDHC instance support 1v8 signal */
#define FSL_FEATURE_USDHC_INSTANCE_SUPPORT_1V8_SIGNALn(x) (1)
/* @brief Has no retuning time counter (HOST_CTRL_CAP[TIME_COUNT_RETURNING]) */
#define FSL_FEATURE_USDHC_REGISTER_HOST_CTRL_CAP_HAS_NO_RETUNING_TIME_COUNTER (1)
#endif /* _MIMX8ML8_cm7_FEATURES_H_ */

View File

@ -0,0 +1,27 @@
/*
* Copyright 2019 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _CLOCK_CONFIG_H_
#define _CLOCK_CONFIG_H_
/*******************************************************************************
* Definitions
******************************************************************************/
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif /* __cplusplus*/
void BOARD_BootClockRUN(void);
#if defined(__cplusplus)
}
#endif /* __cplusplus*/
#endif /* _CLOCK_CONFIG_H_ */

View File

@ -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

View File

@ -0,0 +1,39 @@
/**************************************************************************//**
* @file cmsis_version.h
* @brief CMSIS Core(M) Version definitions
* @version V5.0.3
* @date 24. June 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 ( 3U) /*!< [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

View File

@ -0,0 +1,31 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
#ifndef CONNECT_UART_H
#define CONNECT_UART_H
#include <device.h>
#ifdef __cplusplus
extern "C" {
#endif
#define KERNEL_CONSOLE_BUS_NAME "uart4"
#define KERNEL_CONSOLE_DRV_NAME "uart4_drv"
#define KERNEL_CONSOLE_DEVICE_NAME "uart4_dev"
int HwUartInit(void);
#ifdef __cplusplus
}
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,554 @@
/*
* Copyright 2018-2020 NXP
* All rights reserved.
*
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef __HAL_UART_ADAPTER_H__
#define __HAL_UART_ADAPTER_H__
#include "fsl_common.h"
#if defined(FSL_RTOS_FREE_RTOS)
#include "FreeRTOS.h"
#endif
/*!
* @addtogroup UART_Adapter
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @brief Enable or disable UART adapter non-blocking mode (1 - enable, 0 - disable) */
#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING
#define UART_ADAPTER_NON_BLOCKING_MODE (1U)
#else
#ifndef SERIAL_MANAGER_NON_BLOCKING_MODE
#define UART_ADAPTER_NON_BLOCKING_MODE (0U)
#else
#define UART_ADAPTER_NON_BLOCKING_MODE SERIAL_MANAGER_NON_BLOCKING_MODE
#endif
#endif
#if defined(__GIC_PRIO_BITS)
#ifndef HAL_UART_ISR_PRIORITY
#define HAL_UART_ISR_PRIORITY (25U)
#endif
#else
#if defined(configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY)
#ifndef HAL_UART_ISR_PRIORITY
#define HAL_UART_ISR_PRIORITY (configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY)
#endif
#else
/* The default value 3 is used to support different ARM Core, such as CM0P, CM4, CM7, and CM33, etc.
* The minimum number of priority bits implemented in the NVIC is 2 on these SOCs. The value of mininum
* priority is 3 (2^2 - 1). So, the default value is 3.
*/
#ifndef HAL_UART_ISR_PRIORITY
#define HAL_UART_ISR_PRIORITY (3U)
#endif
#endif
#endif
#ifndef HAL_UART_ADAPTER_LOWPOWER
#define HAL_UART_ADAPTER_LOWPOWER (0U)
#endif /* HAL_UART_ADAPTER_LOWPOWER */
#ifndef HAL_UART_ADAPTER_FIFO
#define HAL_UART_ADAPTER_FIFO (0U)
#endif /* HAL_UART_ADAPTER_FIFO */
/*! @brief Definition of uart adapter handle size. */
#if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U))
#define HAL_UART_HANDLE_SIZE (92U + HAL_UART_ADAPTER_LOWPOWER * 16U)
#define HAL_UART_BLOCK_HANDLE_SIZE (8U + HAL_UART_ADAPTER_LOWPOWER * 16U)
#else
#define HAL_UART_HANDLE_SIZE (8U + HAL_UART_ADAPTER_LOWPOWER * 16U)
#endif
/*!
* @brief Defines the uart handle
*
* This macro is used to define a 4 byte aligned uart handle.
* Then use "(hal_uart_handle_t)name" to get the uart handle.
*
* The macro should be global and could be optional. You could also define uart handle by yourself.
*
* This is an example,
* @code
* UART_HANDLE_DEFINE(uartHandle);
* @endcode
*
* @param name The name string of the uart handle.
*/
#define UART_HANDLE_DEFINE(name) uint32_t name[((HAL_UART_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t))]
/*! @brief Whether enable transactional function of the UART. (0 - disable, 1 - enable) */
#ifndef HAL_UART_TRANSFER_MODE
#define HAL_UART_TRANSFER_MODE (0U)
#endif
/*! @brief The handle of uart adapter. */
typedef void *hal_uart_handle_t;
/*! @brief UART status */
typedef enum _hal_uart_status
{
kStatus_HAL_UartSuccess = kStatus_Success, /*!< Successfully */
kStatus_HAL_UartTxBusy = MAKE_STATUS(kStatusGroup_HAL_UART, 1), /*!< TX busy */
kStatus_HAL_UartRxBusy = MAKE_STATUS(kStatusGroup_HAL_UART, 2), /*!< RX busy */
kStatus_HAL_UartTxIdle = MAKE_STATUS(kStatusGroup_HAL_UART, 3), /*!< HAL UART transmitter is idle. */
kStatus_HAL_UartRxIdle = MAKE_STATUS(kStatusGroup_HAL_UART, 4), /*!< HAL UART receiver is idle */
kStatus_HAL_UartBaudrateNotSupport =
MAKE_STATUS(kStatusGroup_HAL_UART, 5), /*!< Baudrate is not support in current clock source */
kStatus_HAL_UartProtocolError = MAKE_STATUS(
kStatusGroup_HAL_UART,
6), /*!< Error occurs for Noise, Framing, Parity, etc.
For transactional transfer, The up layer needs to abort the transfer and then starts again */
kStatus_HAL_UartError = MAKE_STATUS(kStatusGroup_HAL_UART, 7), /*!< Error occurs on HAL UART */
} hal_uart_status_t;
/*! @brief UART parity mode. */
typedef enum _hal_uart_parity_mode
{
kHAL_UartParityDisabled = 0x0U, /*!< Parity disabled */
kHAL_UartParityEven = 0x2U, /*!< Parity even enabled */
kHAL_UartParityOdd = 0x3U, /*!< Parity odd enabled */
} hal_uart_parity_mode_t;
#if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U))
/*! @brief UART Block Mode. */
typedef enum _hal_uart_block_mode
{
kHAL_UartNonBlockMode = 0x0U, /*!< Uart NonBlock Mode */
kHAL_UartBlockMode = 0x1U, /*!< Uart Block Mode */
} hal_uart_block_mode_t;
#endif /* UART_ADAPTER_NON_BLOCKING_MODE */
/*! @brief UART stop bit count. */
typedef enum _hal_uart_stop_bit_count
{
kHAL_UartOneStopBit = 0U, /*!< One stop bit */
kHAL_UartTwoStopBit = 1U, /*!< Two stop bits */
} hal_uart_stop_bit_count_t;
/*! @brief UART configuration structure. */
typedef struct _hal_uart_config
{
uint32_t srcClock_Hz; /*!< Source clock */
uint32_t baudRate_Bps; /*!< Baud rate */
hal_uart_parity_mode_t parityMode; /*!< Parity mode, disabled (default), even, odd */
hal_uart_stop_bit_count_t stopBitCount; /*!< Number of stop bits, 1 stop bit (default) or 2 stop bits */
uint8_t enableRx; /*!< Enable RX */
uint8_t enableTx; /*!< Enable TX */
uint8_t enableRxRTS; /*!< Enable RX RTS */
uint8_t enableTxCTS; /*!< Enable TX CTS */
uint8_t instance; /*!< Instance (0 - UART0, 1 - UART1, ...), detail information please refer to the
SOC corresponding RM.
Invalid instance value will cause initialization failure. */
#if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U))
hal_uart_block_mode_t mode; /*!< Uart block mode */
#endif /* UART_ADAPTER_NON_BLOCKING_MODE */
} hal_uart_config_t;
/*! @brief UART transfer callback function. */
typedef void (*hal_uart_transfer_callback_t)(hal_uart_handle_t handle, hal_uart_status_t status, void *callbackParam);
/*! @brief UART transfer structure. */
typedef struct _hal_uart_transfer
{
uint8_t *data; /*!< The buffer of data to be transfer.*/
size_t dataSize; /*!< The byte count to be transfer. */
} hal_uart_transfer_t;
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif /* _cplusplus */
/*!
* @name Initialization and deinitialization
* @{
*/
/*!
* @brief Initializes a UART instance with the UART handle and the user configuration structure.
*
* This function configures the UART module with user-defined settings. The user can configure the configuration
* structure. The parameter handle is a pointer to point to a memory space of size #HAL_UART_HANDLE_SIZE allocated by
* the caller. Example below shows how to use this API to configure the UART.
* @code
* UART_HANDLE_DEFINE(g_UartHandle);
* hal_uart_config_t config;
* config.srcClock_Hz = 48000000;
* config.baudRate_Bps = 115200U;
* config.parityMode = kHAL_UartParityDisabled;
* config.stopBitCount = kHAL_UartOneStopBit;
* config.enableRx = 1;
* config.enableTx = 1;
* config.enableRxRTS = 0;
* config.enableTxCTS = 0;
* config.instance = 0;
* HAL_UartInit((hal_uart_handle_t)g_UartHandle, &config);
* @endcode
*
* @param handle Pointer to point to a memory space of size #HAL_UART_HANDLE_SIZE allocated by the caller.
* The handle should be 4 byte aligned, because unaligned access doesn't be supported on some devices.
* You can define the handle in the following two ways:
* #UART_HANDLE_DEFINE(handle);
* or
* uint32_t handle[((HAL_UART_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t))];
* @param config Pointer to user-defined configuration structure.
* @retval kStatus_HAL_UartBaudrateNotSupport Baudrate is not support in current clock source.
* @retval kStatus_HAL_UartSuccess UART initialization succeed
*/
hal_uart_status_t HAL_UartInit(hal_uart_handle_t handle, const hal_uart_config_t *config);
/*!
* @brief Deinitializes a UART instance.
*
* This function waits for TX complete, disables TX and RX, and disables the UART clock.
*
* @param handle UART handle pointer.
* @retval kStatus_HAL_UartSuccess UART de-initialization succeed
*/
hal_uart_status_t HAL_UartDeinit(hal_uart_handle_t handle);
/*! @}*/
/*!
* @name Blocking bus Operations
* @{
*/
/*!
* @brief Reads RX data register using a blocking method.
*
* This function polls the RX register, waits for the RX register to be full or for RX FIFO to
* have data, and reads data from the RX register.
*
* @note The function #HAL_UartReceiveBlocking and the function HAL_UartTransferReceiveNonBlocking
* cannot be used at the same time.
* And, the function HAL_UartTransferAbortReceive cannot be used to abort the transmission of this function.
*
* @param handle UART handle pointer.
* @param data Start address of the buffer to store the received data.
* @param length Size of the buffer.
* @retval kStatus_HAL_UartError An error occurred while receiving data.
* @retval kStatus_HAL_UartParityError A parity error occurred while receiving data.
* @retval kStatus_HAL_UartSuccess Successfully received all data.
*/
hal_uart_status_t HAL_UartReceiveBlocking(hal_uart_handle_t handle, uint8_t *data, size_t length);
/*!
* @brief Writes to the TX register using a blocking method.
*
* This function polls the TX register, waits for the TX register to be empty or for the TX FIFO
* to have room and writes data to the TX buffer.
*
* @note The function #HAL_UartSendBlocking and the function HAL_UartTransferSendNonBlocking
* cannot be used at the same time.
* And, the function HAL_UartTransferAbortSend cannot be used to abort the transmission of this function.
*
* @param handle UART handle pointer.
* @param data Start address of the data to write.
* @param length Size of the data to write.
* @retval kStatus_HAL_UartSuccess Successfully sent all data.
*/
hal_uart_status_t HAL_UartSendBlocking(hal_uart_handle_t handle, const uint8_t *data, size_t length);
/*! @}*/
#if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U))
#if (defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U))
/*!
* @name Transactional
* @note The transactional API and the functional API cannot be used at the same time. The macro
* #HAL_UART_TRANSFER_MODE is used to set which one will be used. If #HAL_UART_TRANSFER_MODE is zero, the
* functional API with non-blocking mode will be used. Otherwise, transactional API will be used.
* @{
*/
/*!
* @brief Installs a callback and callback parameter.
*
* This function is used to install the callback and callback parameter for UART module.
* When any status of the UART changed, the driver will notify the upper layer by the installed callback
* function. And the status is also passed as status parameter when the callback is called.
*
* @param handle UART handle pointer.
* @param callback The callback function.
* @param callbackParam The parameter of the callback function.
* @retval kStatus_HAL_UartSuccess Successfully install the callback.
*/
hal_uart_status_t HAL_UartTransferInstallCallback(hal_uart_handle_t handle,
hal_uart_transfer_callback_t callback,
void *callbackParam);
/*!
* @brief Receives a buffer of data using an interrupt method.
*
* This function receives data using an interrupt method. This is a non-blocking function, which
* returns directly without waiting for all data to be received.
* The receive request is saved by the UART driver.
* When the new data arrives, the receive request is serviced first.
* When all data is received, the UART driver notifies the upper layer
* through a callback function and passes the status parameter @ref kStatus_UART_RxIdle.
*
* @note The function #HAL_UartReceiveBlocking and the function #HAL_UartTransferReceiveNonBlocking
* cannot be used at the same time.
*
* @param handle UART handle pointer.
* @param transfer UART transfer structure, see #hal_uart_transfer_t.
* @retval kStatus_HAL_UartSuccess Successfully queue the transfer into transmit queue.
* @retval kStatus_HAL_UartRxBusy Previous receive request is not finished.
* @retval kStatus_HAL_UartError An error occurred.
*/
hal_uart_status_t HAL_UartTransferReceiveNonBlocking(hal_uart_handle_t handle, hal_uart_transfer_t *transfer);
/*!
* @brief Transmits a buffer of data using the interrupt method.
*
* This function sends data using an interrupt method. This is a non-blocking function, which
* returns directly without waiting for all data to be written to the TX register. When
* all data is written to the TX register in the ISR, the UART driver calls the callback
* function and passes the @ref kStatus_UART_TxIdle as status parameter.
*
* @note The function #HAL_UartSendBlocking and the function #HAL_UartTransferSendNonBlocking
* cannot be used at the same time.
*
* @param handle UART handle pointer.
* @param transfer UART transfer structure. See #hal_uart_transfer_t.
* @retval kStatus_HAL_UartSuccess Successfully start the data transmission.
* @retval kStatus_HAL_UartTxBusy Previous transmission still not finished; data not all written to TX register yet.
* @retval kStatus_HAL_UartError An error occurred.
*/
hal_uart_status_t HAL_UartTransferSendNonBlocking(hal_uart_handle_t handle, hal_uart_transfer_t *transfer);
/*!
* @brief Gets the number of bytes that have been received.
*
* This function gets the number of bytes that have been received.
*
* @param handle UART handle pointer.
* @param count Receive bytes count.
* @retval kStatus_HAL_UartError An error occurred.
* @retval kStatus_Success Get successfully through the parameter \p count.
*/
hal_uart_status_t HAL_UartTransferGetReceiveCount(hal_uart_handle_t handle, uint32_t *count);
/*!
* @brief Gets the number of bytes written to the UART TX register.
*
* This function gets the number of bytes written to the UART TX
* register by using the interrupt method.
*
* @param handle UART handle pointer.
* @param count Send bytes count.
* @retval kStatus_HAL_UartError An error occurred.
* @retval kStatus_Success Get successfully through the parameter \p count.
*/
hal_uart_status_t HAL_UartTransferGetSendCount(hal_uart_handle_t handle, uint32_t *count);
/*!
* @brief Aborts the interrupt-driven data receiving.
*
* This function aborts the interrupt-driven data receiving. The user can get the remainBytes to know
* how many bytes are not received yet.
*
* @note The function #HAL_UartTransferAbortReceive cannot be used to abort the transmission of
* the function #HAL_UartReceiveBlocking.
*
* @param handle UART handle pointer.
* @retval kStatus_Success Get successfully abort the receiving.
*/
hal_uart_status_t HAL_UartTransferAbortReceive(hal_uart_handle_t handle);
/*!
* @brief Aborts the interrupt-driven data sending.
*
* This function aborts the interrupt-driven data sending. The user can get the remainBytes to find out
* how many bytes are not sent out.
*
* @note The function #HAL_UartTransferAbortSend cannot be used to abort the transmission of
* the function #HAL_UartSendBlocking.
*
* @param handle UART handle pointer.
* @retval kStatus_Success Get successfully abort the sending.
*/
hal_uart_status_t HAL_UartTransferAbortSend(hal_uart_handle_t handle);
/*! @}*/
#else
/*!
* @name Functional API with non-blocking mode.
* @note The functional API and the transactional API cannot be used at the same time. The macro
* #HAL_UART_TRANSFER_MODE is used to set which one will be used. If #HAL_UART_TRANSFER_MODE is zero, the
* functional API with non-blocking mode will be used. Otherwise, transactional API will be used.
* @{
*/
/*!
* @brief Installs a callback and callback parameter.
*
* This function is used to install the callback and callback parameter for UART module.
* When non-blocking sending or receiving finished, the adapter will notify the upper layer by the installed callback
* function. And the status is also passed as status parameter when the callback is called.
*
* @param handle UART handle pointer.
* @param callback The callback function.
* @param callbackParam The parameter of the callback function.
* @retval kStatus_HAL_UartSuccess Successfully install the callback.
*/
hal_uart_status_t HAL_UartInstallCallback(hal_uart_handle_t handle,
hal_uart_transfer_callback_t callback,
void *callbackParam);
/*!
* @brief Receives a buffer of data using an interrupt method.
*
* This function receives data using an interrupt method. This is a non-blocking function, which
* returns directly without waiting for all data to be received.
* The receive request is saved by the UART adapter.
* When the new data arrives, the receive request is serviced first.
* When all data is received, the UART adapter notifies the upper layer
* through a callback function and passes the status parameter @ref kStatus_UART_RxIdle.
*
* @note The function #HAL_UartReceiveBlocking and the function #HAL_UartReceiveNonBlocking
* cannot be used at the same time.
*
* @param handle UART handle pointer.
* @param data Start address of the data to write.
* @param length Size of the data to write.
* @retval kStatus_HAL_UartSuccess Successfully queue the transfer into transmit queue.
* @retval kStatus_HAL_UartRxBusy Previous receive request is not finished.
* @retval kStatus_HAL_UartError An error occurred.
*/
hal_uart_status_t HAL_UartReceiveNonBlocking(hal_uart_handle_t handle, uint8_t *data, size_t length);
/*!
* @brief Transmits a buffer of data using the interrupt method.
*
* This function sends data using an interrupt method. This is a non-blocking function, which
* returns directly without waiting for all data to be written to the TX register. When
* all data is written to the TX register in the ISR, the UART driver calls the callback
* function and passes the @ref kStatus_UART_TxIdle as status parameter.
*
* @note The function #HAL_UartSendBlocking and the function #HAL_UartSendNonBlocking
* cannot be used at the same time.
*
* @param handle UART handle pointer.
* @param data Start address of the data to write.
* @param length Size of the data to write.
* @retval kStatus_HAL_UartSuccess Successfully start the data transmission.
* @retval kStatus_HAL_UartTxBusy Previous transmission still not finished; data not all written to TX register yet.
* @retval kStatus_HAL_UartError An error occurred.
*/
hal_uart_status_t HAL_UartSendNonBlocking(hal_uart_handle_t handle, uint8_t *data, size_t length);
/*!
* @brief Gets the number of bytes that have been received.
*
* This function gets the number of bytes that have been received.
*
* @param handle UART handle pointer.
* @param count Receive bytes count.
* @retval kStatus_HAL_UartError An error occurred.
* @retval kStatus_Success Get successfully through the parameter \p count.
*/
hal_uart_status_t HAL_UartGetReceiveCount(hal_uart_handle_t handle, uint32_t *reCount);
/*!
* @brief Gets the number of bytes written to the UART TX register.
*
* This function gets the number of bytes written to the UART TX
* register by using the interrupt method.
*
* @param handle UART handle pointer.
* @param count Send bytes count.
* @retval kStatus_HAL_UartError An error occurred.
* @retval kStatus_Success Get successfully through the parameter \p count.
*/
hal_uart_status_t HAL_UartGetSendCount(hal_uart_handle_t handle, uint32_t *seCount);
/*!
* @brief Aborts the interrupt-driven data receiving.
*
* This function aborts the interrupt-driven data receiving. The user can get the remainBytes to know
* how many bytes are not received yet.
*
* @note The function #HAL_UartAbortReceive cannot be used to abort the transmission of
* the function #HAL_UartReceiveBlocking.
*
* @param handle UART handle pointer.
* @retval kStatus_Success Get successfully abort the receiving.
*/
hal_uart_status_t HAL_UartAbortReceive(hal_uart_handle_t handle);
/*!
* @brief Aborts the interrupt-driven data sending.
*
* This function aborts the interrupt-driven data sending. The user can get the remainBytes to find out
* how many bytes are not sent out.
*
* @note The function #HAL_UartAbortSend cannot be used to abort the transmission of
* the function #HAL_UartSendBlocking.
*
* @param handle UART handle pointer.
* @retval kStatus_Success Get successfully abort the sending.
*/
hal_uart_status_t HAL_UartAbortSend(hal_uart_handle_t handle);
/*! @}*/
#endif
#endif
/*!
* @brief Prepares to enter low power consumption.
*
* This function is used to prepare to enter low power consumption.
*
* @param handle UART handle pointer.
* @retval kStatus_HAL_UartSuccess Successful operation.
* @retval kStatus_HAL_UartError An error occurred.
*/
hal_uart_status_t HAL_UartEnterLowpower(hal_uart_handle_t handle);
/*!
* @brief Restores from low power consumption.
*
* This function is used to restore from low power consumption.
*
* @param handle UART handle pointer.
* @retval kStatus_HAL_UartSuccess Successful operation.
* @retval kStatus_HAL_UartError An error occurred.
*/
hal_uart_status_t HAL_UartExitLowpower(hal_uart_handle_t handle);
#if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U))
/*!
* @brief UART IRQ handle function.
*
* This function handles the UART transmit and receive IRQ request.
*
* @param handle UART handle pointer.
*/
void HAL_UartIsrFunction(hal_uart_handle_t handle);
#endif
#if defined(__cplusplus)
}
#endif
/*! @}*/
#endif /* __HAL_UART_ADAPTER_H__ */

View File

@ -0,0 +1,359 @@
/*
* Copyright 2020 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_AUDIOMIX_H_
#define _FSL_AUDIOMIX_H_
#include "fsl_common.h"
/*!
* @addtogroup audiomix
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @name Driver version */
/*@{*/
/*! @brief AUDIOMIX driver version 2.0.1. */
#define FSL_AUDIOMIX_DRIVER_VERSION (MAKE_VERSION(2, 0, 1))
/*@}*/
/*!@brief AUDIOMIX attach id combination */
#define AUDIOMIX_ATTACH_ID(offset, mask, value) \
((uint32_t)(offset) | ((uint32_t)(mask) << 16U) | ((uint32_t)(value) << 24U))
#define GET_AUDIOMIX_ATTACH_ID_OFFSET(id) ((uint32_t)(id)&0xFFFFU)
#define GET_AUDIOMIX_ATTACH_ID_MASK(id) (((uint32_t)(id) >> 16U) & 0xFFU)
#define GET_AUDIOMIX_ATTACH_ID_value(id) (((uint32_t)(id) >> 24U) & 0xFFU)
/*!@brief audio mix attch clk id */
typedef enum _audiomix_attch_clk
{
kAUDIOMIX_Attach_SAI1_MCLK2_To_SAI1_ROOT =
AUDIOMIX_ATTACH_ID(0X300U, 0x1EU, 0U << 1U), /*!< attach SAI1 MCLK2 to SAI1 root */
kAUDIOMIX_Attach_SAI1_MCLK2_To_SAI2_ROOT =
AUDIOMIX_ATTACH_ID(0X300U, 0x1EU, 1U << 1U), /*!< attach SAI1 MCLK2 to SAI2 root */
kAUDIOMIX_Attach_SAI1_MCLK2_To_SAI3_ROOT =
AUDIOMIX_ATTACH_ID(0X300U, 0x1EU, 2U << 1U), /*!< attach SAI1 MCLK2 to SAI3 root */
kAUDIOMIX_Attach_SAI1_MCLK2_To_SAI5_ROOT =
AUDIOMIX_ATTACH_ID(0X300U, 0x1EU, 4U << 1U), /*!< attach SAI1 MCLK2 to SAI5 root */
kAUDIOMIX_Attach_SAI1_MCLK2_To_SAI6_ROOT =
AUDIOMIX_ATTACH_ID(0X300U, 0x1EU, 5U << 1U), /*!< attach SAI1 MCLK2 to SAI6 root */
kAUDIOMIX_Attach_SAI1_MCLK2_To_SAI7_ROOT =
AUDIOMIX_ATTACH_ID(0X300U, 0x1EU, 6U << 1U), /*!< attach SAI1 MCLK2 to SAI7 root */
kAUDIOMIX_Attach_SAI1_MCLK2_To_SAI1_MCLK =
AUDIOMIX_ATTACH_ID(0X300U, 0x1EU, 7U << 1U), /*!< attach SAI1 MCLK2 to SAI1 MCLK */
kAUDIOMIX_Attach_SAI1_MCLK2_To_SAI2_MCLK =
AUDIOMIX_ATTACH_ID(0X300U, 0x1EU, 8U << 1U), /*!< attach SAI1 MCLK2 to SAI2 MCLK */
kAUDIOMIX_Attach_SAI1_MCLK2_To_SAI3_MCLK =
AUDIOMIX_ATTACH_ID(0X300U, 0x1EU, 9U << 1U), /*!< attach SAI1 MCLK2 to SAI3 MCLK */
kAUDIOMIX_Attach_SAI1_MCLK2_To_SAI5_MCLK =
AUDIOMIX_ATTACH_ID(0X300U, 0x1EU, 11U << 1U), /*!< attach SAI1 MCLK2 to SAI5 MCLK */
kAUDIOMIX_Attach_SAI1_MCLK2_To_SAI6_MCLK =
AUDIOMIX_ATTACH_ID(0X300U, 0x1EU, 12U << 1U), /*!< attach SAI1 MCLK2 to SAI6 MCLK */
kAUDIOMIX_Attach_SAI1_MCLK2_To_SAI7_MCLK =
AUDIOMIX_ATTACH_ID(0X300U, 0x1EU, 13U << 1U), /*!< attach SAI1 MCLK2 to SAI7 MCLK */
kAUDIOMIX_Attach_SAI1_MCLK1_To_SAI1_ROOT =
AUDIOMIX_ATTACH_ID(0X300U, 0x1U, 0U), /*!< attach SAI1 MCLK1 to SAI1 root */
kAUDIOMIX_Attach_SAI1_MCLK1_To_SAI1_MCLK =
AUDIOMIX_ATTACH_ID(0X300U, 0x1U, 1U), /*!< attach SAI1 MCLK1 to SAI1 MCLK */
kAUDIOMIX_Attach_SAI2_MCLK2_To_SAI1_ROOT =
AUDIOMIX_ATTACH_ID(0X304U, 0x1EU, 0U << 1U), /*!< attach SAI2 MCLK2 to SAI1 root */
kAUDIOMIX_Attach_SAI2_MCLK2_To_SAI2_ROOT =
AUDIOMIX_ATTACH_ID(0X304U, 0x1EU, 1U << 1U), /*!< attach SAI2 MCLK2 to SAI2 root */
kAUDIOMIX_Attach_SAI2_MCLK2_To_SAI3_ROOT =
AUDIOMIX_ATTACH_ID(0X304U, 0x1EU, 2U << 1U), /*!< attach SAI2 MCLK2 to SAI3 root */
kAUDIOMIX_Attach_SAI2_MCLK2_To_SAI5_ROOT =
AUDIOMIX_ATTACH_ID(0X304U, 0x1EU, 4U << 1U), /*!< attach SAI2 MCLK2 to SAI5 root */
kAUDIOMIX_Attach_SAI2_MCLK2_To_SAI6_ROOT =
AUDIOMIX_ATTACH_ID(0X304U, 0x1EU, 5U << 1U), /*!< attach SAI2 MCLK2 to SAI6 root */
kAUDIOMIX_Attach_SAI2_MCLK2_To_SAI7_ROOT =
AUDIOMIX_ATTACH_ID(0X304U, 0x1EU, 6U << 1U), /*!< attach SAI2 MCLK2 to SAI7 root */
kAUDIOMIX_Attach_SAI2_MCLK2_To_SAI1_MCLK =
AUDIOMIX_ATTACH_ID(0X304U, 0x1EU, 7U << 1U), /*!< attach SAI2 MCLK2 to SAI1 MCLK */
kAUDIOMIX_Attach_SAI2_MCLK2_To_SAI2_MCLK =
AUDIOMIX_ATTACH_ID(0X304U, 0x1EU, 8U << 1U), /*!< attach SAI2 MCLK2 to SAI2 MCLK */
kAUDIOMIX_Attach_SAI2_MCLK2_To_SAI3_MCLK =
AUDIOMIX_ATTACH_ID(0X304U, 0x1EU, 9U << 1U), /*!< attach SAI2 MCLK2 to SAI3 MCLK */
kAUDIOMIX_Attach_SAI2_MCLK2_To_SAI5_MCLK =
AUDIOMIX_ATTACH_ID(0X304U, 0x1EU, 11U << 1U), /*!< attach SAI2 MCLK2 to SAI5 MCLK */
kAUDIOMIX_Attach_SAI2_MCLK2_To_SAI6_MCLK =
AUDIOMIX_ATTACH_ID(0X304U, 0x1EU, 12U << 1U), /*!< attach SAI2 MCLK2 to SAI6 MCLK */
kAUDIOMIX_Attach_SAI2_MCLK2_To_SAI7_MCLK =
AUDIOMIX_ATTACH_ID(0X304U, 0x1EU, 13U << 1U), /*!< attach SAI2 MCLK2 to SAI7 MCLK */
kAUDIOMIX_Attach_SAI2_MCLK2_To_SPDIF_ExtCLK =
AUDIOMIX_ATTACH_ID(0X304U, 0x1EU, 14U << 1U), /*!< attach SAI2 MCLK2 to SPDIF EXTCLK */
kAUDIOMIX_Attach_SAI2_MCLK1_To_SAI2_ROOT =
AUDIOMIX_ATTACH_ID(0X304U, 0x1U, 0U), /*!< attach SAI2 MCLK1 to SAI2 root */
kAUDIOMIX_Attach_SAI2_MCLK1_To_SAI2_MCLK =
AUDIOMIX_ATTACH_ID(0X304U, 0x1U, 1U), /*!< attach SAI2 MCLK1 to SAI2 MCLK */
kAUDIOMIX_Attach_SAI3_MCLK2_To_SAI1_ROOT =
AUDIOMIX_ATTACH_ID(0X308U, 0x1EU, 0U << 1U), /*!< attach SAI3 MCLK2 to SAI1 root */
kAUDIOMIX_Attach_SAI3_MCLK2_To_SAI2_ROOT =
AUDIOMIX_ATTACH_ID(0X308U, 0x1EU, 1U << 1U), /*!< attach SAI3 MCLK2 to SAI2 root */
kAUDIOMIX_Attach_SAI3_MCLK2_To_SAI3_ROOT =
AUDIOMIX_ATTACH_ID(0X308U, 0x1EU, 2U << 1U), /*!< attach SAI3 MCLK2 to SAI3 root */
kAUDIOMIX_Attach_SAI3_MCLK2_To_SAI5_ROOT =
AUDIOMIX_ATTACH_ID(0X308U, 0x1EU, 4U << 1U), /*!< attach SAI3 MCLK2 to SAI5 root */
kAUDIOMIX_Attach_SAI3_MCLK2_To_SAI6_ROOT =
AUDIOMIX_ATTACH_ID(0X308U, 0x1EU, 5U << 1U), /*!< attach SAI3 MCLK2 to SAI6 root */
kAUDIOMIX_Attach_SAI3_MCLK2_To_SAI7_ROOT =
AUDIOMIX_ATTACH_ID(0X308U, 0x1EU, 6U << 1U), /*!< attach SAI3 MCLK2 to SAI7 root */
kAUDIOMIX_Attach_SAI3_MCLK2_To_SAI1_MCLK =
AUDIOMIX_ATTACH_ID(0X308U, 0x1EU, 7U << 1U), /*!< attach SAI3 MCLK2 to SAI1 MCLK */
kAUDIOMIX_Attach_SAI3_MCLK2_To_SAI2_MCLK =
AUDIOMIX_ATTACH_ID(0X308U, 0x1EU, 8U << 1U), /*!< attach SAI3 MCLK2 to SAI2 MCLK */
kAUDIOMIX_Attach_SAI3_MCLK2_To_SAI3_MCLK =
AUDIOMIX_ATTACH_ID(0X308U, 0x1EU, 9U << 1U), /*!< attach SAI3 MCLK2 to SAI3 MCLK */
kAUDIOMIX_Attach_SAI3_MCLK2_To_SAI5_MCLK =
AUDIOMIX_ATTACH_ID(0X308U, 0x1EU, 11U << 1U), /*!< attach SAI3 MCLK2 to SAI5 MCLK */
kAUDIOMIX_Attach_SAI3_MCLK2_To_SAI6_MCLK =
AUDIOMIX_ATTACH_ID(0X308U, 0x1EU, 12U << 1U), /*!< attach SAI3 MCLK2 to SAI6 MCLK */
kAUDIOMIX_Attach_SAI3_MCLK2_To_SAI7_MCLK =
AUDIOMIX_ATTACH_ID(0X308U, 0x1EU, 13U << 1U), /*!< attach SAI3 MCLK2 to SAI7 MCLK */
kAUDIOMIX_Attach_SAI3_MCLK2_To_SPDIF_ExtCLK =
AUDIOMIX_ATTACH_ID(0X308U, 0x1EU, 14U << 1U), /*!< attach SAI3 MCLK2 to SPDIF EXTCLK */
kAUDIOMIX_Attach_SAI3_MCLK1_To_SAI3_ROOT =
AUDIOMIX_ATTACH_ID(0X308U, 0x1U, 0U), /*!< attach SAI3 MCLK1 to SAI3 root */
kAUDIOMIX_Attach_SAI3_MCLK1_To_SAI3_MCLK =
AUDIOMIX_ATTACH_ID(0X308U, 0x1U, 1U), /*!< attach SAI3 MCLK1 to SAI3 MCLK */
kAUDIOMIX_Attach_SAI5_MCLK2_To_SAI1_ROOT =
AUDIOMIX_ATTACH_ID(0X30CU, 0x1EU, 0U << 1U), /*!< attach SAI5 MCLK2 to SAI1 root */
kAUDIOMIX_Attach_SAI5_MCLK2_To_SAI2_ROOT =
AUDIOMIX_ATTACH_ID(0X30CU, 0x1EU, 1U << 1U), /*!< attach SAI5 MCLK2 to SAI2 root */
kAUDIOMIX_Attach_SAI5_MCLK2_To_SAI3_ROOT =
AUDIOMIX_ATTACH_ID(0X30CU, 0x1EU, 2U << 1U), /*!< attach SAI5 MCLK2 to SAI3 root */
kAUDIOMIX_Attach_SAI5_MCLK2_To_SAI5_ROOT =
AUDIOMIX_ATTACH_ID(0X30CU, 0x1EU, 4U << 1U), /*!< attach SAI5 MCLK2 to SAI5 root */
kAUDIOMIX_Attach_SAI5_MCLK2_To_SAI6_ROOT =
AUDIOMIX_ATTACH_ID(0X30CU, 0x1EU, 5U << 1U), /*!< attach SAI5 MCLK2 to SAI6 root */
kAUDIOMIX_Attach_SAI5_MCLK2_To_SAI7_ROOT =
AUDIOMIX_ATTACH_ID(0X30CU, 0x1EU, 6U << 1U), /*!< attach SAI5 MCLK2 to SAI7 root */
kAUDIOMIX_Attach_SAI5_MCLK2_To_SAI1_MCLK =
AUDIOMIX_ATTACH_ID(0X30CU, 0x1EU, 7U << 1U), /*!< attach SAI5 MCLK2 to SAI1 MCLK */
kAUDIOMIX_Attach_SAI5_MCLK2_To_SAI2_MCLK =
AUDIOMIX_ATTACH_ID(0X30CU, 0x1EU, 8U << 1U), /*!< attach SAI5 MCLK2 to SAI2 MCLK */
kAUDIOMIX_Attach_SAI5_MCLK2_To_SAI3_MCLK =
AUDIOMIX_ATTACH_ID(0X30CU, 0x1EU, 9U << 1U), /*!< attach SAI5 MCLK2 to SAI3 MCLK */
kAUDIOMIX_Attach_SAI5_MCLK2_To_SAI5_MCLK =
AUDIOMIX_ATTACH_ID(0X30CU, 0x1EU, 11U << 1U), /*!< attach SAI5 MCLK2 to SAI5 MCLK */
kAUDIOMIX_Attach_SAI5_MCLK2_To_SAI6_MCLK =
AUDIOMIX_ATTACH_ID(0X30CU, 0x1EU, 12U << 1U), /*!< attach SAI5 MCLK2 to SAI6 MCLK */
kAUDIOMIX_Attach_SAI5_MCLK2_To_SAI7_MCLK =
AUDIOMIX_ATTACH_ID(0X30CU, 0x1EU, 13U << 1U), /*!< attach SAI5 MCLK2 to SAI7 MCLK */
kAUDIOMIX_Attach_SAI5_MCLK2_To_SPDIF_ExtCLK =
AUDIOMIX_ATTACH_ID(0X30CU, 0x1EU, 14U << 1U), /*!< attach SAI5 MCLK2 to SPDIF EXTCLK */
kAUDIOMIX_Attach_SAI5_MCLK1_To_SAI5_ROOT =
AUDIOMIX_ATTACH_ID(0X30CU, 0x1U, 0U), /*!< attach SAI5 MCLK1 to SAI5 root */
kAUDIOMIX_Attach_SAI5_MCLK1_To_SAI5_MCLK =
AUDIOMIX_ATTACH_ID(0X30CU, 0x1U, 1U), /*!< attach SAI5 MCLK1 to SAI5 MCLK */
kAUDIOMIX_Attach_SAI6_MCLK2_To_SAI1_ROOT =
AUDIOMIX_ATTACH_ID(0X310U, 0x1EU, 0U << 1U), /*!< attach SAI6 MCLK2 to SAI1 root */
kAUDIOMIX_Attach_SAI6_MCLK2_To_SAI2_ROOT =
AUDIOMIX_ATTACH_ID(0X310U, 0x1EU, 1U << 1U), /*!< attach SAI6 MCLK2 to SAI2 root */
kAUDIOMIX_Attach_SAI6_MCLK2_To_SAI3_ROOT =
AUDIOMIX_ATTACH_ID(0X310U, 0x1EU, 2U << 1U), /*!< attach SAI6 MCLK2 to SAI3 root */
kAUDIOMIX_Attach_SAI6_MCLK2_To_SAI5_ROOT =
AUDIOMIX_ATTACH_ID(0X310U, 0x1EU, 4U << 1U), /*!< attach SAI6 MCLK2 to SAI5 root */
kAUDIOMIX_Attach_SAI6_MCLK2_To_SAI6_ROOT =
AUDIOMIX_ATTACH_ID(0X310U, 0x1EU, 5U << 1U), /*!< attach SAI6 MCLK2 to SAI6 root */
kAUDIOMIX_Attach_SAI6_MCLK2_To_SAI7_ROOT =
AUDIOMIX_ATTACH_ID(0X310U, 0x1EU, 6U << 1U), /*!< attach SAI6 MCLK2 to SAI7 root */
kAUDIOMIX_Attach_SAI6_MCLK2_To_SAI1_MCLK =
AUDIOMIX_ATTACH_ID(0X310U, 0x1EU, 7U << 1U), /*!< attach SAI6 MCLK2 to SAI1 MCLK */
kAUDIOMIX_Attach_SAI6_MCLK2_To_SAI2_MCLK =
AUDIOMIX_ATTACH_ID(0X310U, 0x1EU, 8U << 1U), /*!< attach SAI6 MCLK2 to SAI2 MCLK */
kAUDIOMIX_Attach_SAI6_MCLK2_To_SAI3_MCLK =
AUDIOMIX_ATTACH_ID(0X310U, 0x1EU, 9U << 1U), /*!< attach SAI6 MCLK2 to SAI3 MCLK */
kAUDIOMIX_Attach_SAI6_MCLK2_To_SAI5_MCLK =
AUDIOMIX_ATTACH_ID(0X310U, 0x1EU, 11U << 1U), /*!< attach SAI6 MCLK2 to SAI5 MCLK */
kAUDIOMIX_Attach_SAI6_MCLK2_To_SAI6_MCLK =
AUDIOMIX_ATTACH_ID(0X310U, 0x1EU, 12U << 1U), /*!< attach SAI6 MCLK2 to SAI6 MCLK */
kAUDIOMIX_Attach_SAI6_MCLK2_To_SAI7_MCLK =
AUDIOMIX_ATTACH_ID(0X310U, 0x1EU, 13U << 1U), /*!< attach SAI6 MCLK2 to SAI7 MCLK */
kAUDIOMIX_Attach_SAI6_MCLK2_To_SPDIF_ExtCLK =
AUDIOMIX_ATTACH_ID(0X310U, 0x1EU, 14U << 1U), /*!< attach SAI6 MCLK2 to SPDIF EXTCLK */
kAUDIOMIX_Attach_SAI6_MCLK1_To_SAI6_ROOT =
AUDIOMIX_ATTACH_ID(0X310U, 0x1U, 0U), /*!< attach SAI6 MCLK2 to SAI6 root */
kAUDIOMIX_Attach_SAI6_MCLK1_To_SAI6_MCLK =
AUDIOMIX_ATTACH_ID(0X310U, 0x1U, 1U), /*!< attach SAI6 MCLK2 to SAI6 MCLK */
kAUDIOMIX_Attach_SAI7_MCLK2_To_SAI1_ROOT =
AUDIOMIX_ATTACH_ID(0X314U, 0x1EU, 0U << 1U), /*!< attach SAI7 MCLK2 to SAI1 root */
kAUDIOMIX_Attach_SAI7_MCLK2_To_SAI2_ROOT =
AUDIOMIX_ATTACH_ID(0X314U, 0x1EU, 1U << 1U), /*!< attach SAI7 MCLK2 to SAI2 root */
kAUDIOMIX_Attach_SAI7_MCLK2_To_SAI3_ROOT =
AUDIOMIX_ATTACH_ID(0X314U, 0x1EU, 2U << 1U), /*!< attach SAI7 MCLK2 to SAI3 root */
kAUDIOMIX_Attach_SAI7_MCLK2_To_SAI5_ROOT =
AUDIOMIX_ATTACH_ID(0X314U, 0x1EU, 4U << 1U), /*!< attach SAI7 MCLK2 to SAI5 root */
kAUDIOMIX_Attach_SAI7_MCLK2_To_SAI6_ROOT =
AUDIOMIX_ATTACH_ID(0X314U, 0x1EU, 5U << 1U), /*!< attach SAI7 MCLK2 to SAI6 root */
kAUDIOMIX_Attach_SAI7_MCLK2_To_SAI7_ROOT =
AUDIOMIX_ATTACH_ID(0X314U, 0x1EU, 6U << 1U), /*!< attach SAI7 MCLK2 to SAI7 root */
kAUDIOMIX_Attach_SAI7_MCLK2_To_SAI1_MCLK =
AUDIOMIX_ATTACH_ID(0X314U, 0x1EU, 7U << 1U), /*!< attach SAI7 MCLK2 to SAI1 MCLK */
kAUDIOMIX_Attach_SAI7_MCLK2_To_SAI2_MCLK =
AUDIOMIX_ATTACH_ID(0X314U, 0x1EU, 8U << 1U), /*!< attach SAI7 MCLK2 to SAI2 MCLK */
kAUDIOMIX_Attach_SAI7_MCLK2_To_SAI3_MCLK =
AUDIOMIX_ATTACH_ID(0X314U, 0x1EU, 9U << 1U), /*!< attach SAI7 MCLK2 to SAI3 MCLK */
kAUDIOMIX_Attach_SAI7_MCLK2_To_SAI5_MCLK =
AUDIOMIX_ATTACH_ID(0X314U, 0x1EU, 11U << 1U), /*!< attach SAI7 MCLK2 to SAI5 MCLK */
kAUDIOMIX_Attach_SAI7_MCLK2_To_SAI6_MCLK =
AUDIOMIX_ATTACH_ID(0X314U, 0x1EU, 12U << 1U), /*!< attach SAI7 MCLK2 to SAI6 MCLK */
kAUDIOMIX_Attach_SAI7_MCLK2_To_SAI7_MCLK =
AUDIOMIX_ATTACH_ID(0X314U, 0x1EU, 13U << 1U), /*!< attach SAI7 MCLK2 to SAI7 MCLK */
kAUDIOMIX_Attach_SAI7_MCLK2_To_SPDIF_ExtCLK =
AUDIOMIX_ATTACH_ID(0X314U, 0x1EU, 14U << 1U), /*!< attach SAI7 MCLK2 to SPDIF_ExtCLK */
kAUDIOMIX_Attach_SAI7_MCLK1_To_SAI7_ROOT =
AUDIOMIX_ATTACH_ID(0X314U, 0x1U, 0U), /*!< attach SAI7 MCLK1 to SAI7 root */
kAUDIOMIX_Attach_SAI7_MCLK1_To_SAI7_MCLK =
AUDIOMIX_ATTACH_ID(0X314U, 0x1U, 1U), /*!< attach SAI7 MCLK1 to SAI7 MCLK */
kAUDIOMIX_Attach_PDM_Root_to_CCM_PDM =
AUDIOMIX_ATTACH_ID(0X318U, 0x3U, 0U), /*!< attach PDM ROOT to CCM PDM clock */
kAUDIOMIX_Attach_PDM_Root_to_SAI_PLL_DVI2 =
AUDIOMIX_ATTACH_ID(0X318U, 0x3U, 1U), /*!< attach PDM ROOT to sai pll div2 */
kAUDIOMIX_Attach_PDM_Root_to_SAI1_MCLK = AUDIOMIX_ATTACH_ID(0X318U, 0x3U, 2U), /*!< attach PDM ROOT to SAI1 mclk */
} audiomix_attch_clk_t;
/*!@brief audio mix power control */
enum _audiomix_power_ctrl
{
kAUDIOMIX_PowerCtrlEDMA = 1U, /*!< edma power control */
kAUDIOMIX_PowerCtrlSDMA2 = 2U, /*!< SDMA2 power control */
kAUDIOMIX_PowerCtrlSDMA3 = 4U, /*!< SDMA3 power control */
kAUDIOMIX_PowerCtrlPDM = 8U, /*!< PDM power control */
kAUDIOMIX_PowerCtrlSAI1 = 16U, /*!< SAI1 power control */
kAUDIOMIX_PowerCtrlSAI2 = 32U, /*!< SAI2 power control */
kAUDIOMIX_PowerCtrlSAI3 = 64U, /*!< SAI3 power control */
kAUDIOMIX_PowerCtrlSAI5 = 128U, /*!< SAI5 power control */
kAUDIOMIX_PowerCtrlSAI6 = 256U, /*!< SAI6 power control */
kAUDIOMIX_PowerCtrlSAI7 = 512U, /*!< SAI7 power control */
};
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @name AUDIOMIX clock Setting
* @{
*/
/*!
* @brief audiomix attach clock.
*
* @param base audiomix base address.
* @param id attach clock id.
*/
void AUDIOMIX_AttachClk(AUDIOMIX_Type *base, audiomix_attch_clk_t id);
/*!
* @brief audiomix low power ack bit status.
*
* @param base audiomix base address.
* @param ip reference _audiomix_power_ctrl, can be a value or combine value in _audiomix_power_ctrl
*/
static inline uint32_t AUDIOMIX_GetIPStopAck(AUDIOMIX_Type *base, uint32_t ip)
{
uint32_t reg = base->IPG_LP_CTRL;
return reg & (ip << 10U);
}
/*!
* @brief audiomix low power stop mode
*
* @param base audiomix base address.
* @param ip reference _audiomix_power_ctrl, can be a value or combine value in _audiomix_power_ctrl
*/
static inline void AUDIOMIX_SetIPStop(AUDIOMIX_Type *base, uint32_t ip)
{
base->IPG_LP_CTRL |= ip & 0x3FFU;
}
/*!
* @brief audiomix earc reset
*
* @param base audiomix base address.
* @param enable true is reset, flase is release.
*/
static inline void AUDIOMIX_SetEARCReset(AUDIOMIX_Type *base, bool enable)
{
if (enable)
{
base->EARC &= ~AUDIOMIX_EARC_RESETB_MASK;
}
else
{
base->EARC |= AUDIOMIX_EARC_RESETB_MASK;
}
}
/*!
* @brief audiomix earc PHY reset
*
* @param base audiomix base address.
* @param enable true is reset, flase is release.
*/
static inline void AUDIOMIX_SetEARCPhyReset(AUDIOMIX_Type *base, bool enable)
{
if (enable)
{
base->EARC &= ~AUDIOMIX_EARC_PHY_RESETB_MASK;
}
else
{
base->EARC |= AUDIOMIX_EARC_PHY_RESETB_MASK;
}
}
/*!
* @brief Initializes the SAI PLL.
* note This function can't detect whether the AUDIO PLL has been enabled and
* used by some IPs.
*
* @param base audiomix base address.
* @param config Pointer to the configuration structure(see ref ccm_analog_frac_pll_config_t enumeration).
*
*/
void AUDIOMIX_InitAudioPll(AUDIOMIX_Type *base, const ccm_analog_frac_pll_config_t *config);
/*!
* brief De-initialize the SAI PLL.
*/
void AUDIOMIX_DeinitAudioPll1(AUDIOMIX_Type *base);
/*!
* @brief Get the sai PLL output freq.
*
* @retval sai pll output freq.
*/
uint32_t AUDIOMIX_GetAudioPllFreq(AUDIOMIX_Type *base);
/* @} */
#if defined(__cplusplus)
}
#endif
/* @} */
#endif /* _FSL_AUDIOMIX_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,954 @@
/*
* Copyright (c) 2015-2016, Freescale Semiconductor, Inc.
* Copyright 2016-2020 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_COMMON_H_
#define _FSL_COMMON_H_
#include <assert.h>
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#if defined(__ICCARM__) || (defined(__CC_ARM) || defined(__ARMCC_VERSION)) || defined(__GNUC__)
#include <stddef.h>
#endif
/*
* For CMSIS pack RTE.
* CMSIS pack RTE generates "RTC_Components.h" which contains the statements
* of the related <RTE_Components_h> element for all selected software components.
*/
#ifdef _RTE_
#include "RTE_Components.h"
#endif
#include "fsl_device_registers.h"
/*!
* @addtogroup ksdk_common
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @brief Construct a status code value from a group and code number. */
#define MAKE_STATUS(group, code) ((((group)*100) + (code)))
/*! @brief Construct the version number for drivers. */
#define MAKE_VERSION(major, minor, bugfix) (((major) << 16) | ((minor) << 8) | (bugfix))
/*! @name Driver version */
/*@{*/
/*! @brief common driver version. */
#define FSL_COMMON_DRIVER_VERSION (MAKE_VERSION(2, 2, 9))
/*@}*/
/* Debug console type definition. */
#define DEBUG_CONSOLE_DEVICE_TYPE_NONE 0U /*!< No debug console. */
#define DEBUG_CONSOLE_DEVICE_TYPE_UART 1U /*!< Debug console based on UART. */
#define DEBUG_CONSOLE_DEVICE_TYPE_LPUART 2U /*!< Debug console based on LPUART. */
#define DEBUG_CONSOLE_DEVICE_TYPE_LPSCI 3U /*!< Debug console based on LPSCI. */
#define DEBUG_CONSOLE_DEVICE_TYPE_USBCDC 4U /*!< Debug console based on USBCDC. */
#define DEBUG_CONSOLE_DEVICE_TYPE_FLEXCOMM 5U /*!< Debug console based on FLEXCOMM. */
#define DEBUG_CONSOLE_DEVICE_TYPE_IUART 6U /*!< Debug console based on i.MX UART. */
#define DEBUG_CONSOLE_DEVICE_TYPE_VUSART 7U /*!< Debug console based on LPC_VUSART. */
#define DEBUG_CONSOLE_DEVICE_TYPE_MINI_USART 8U /*!< Debug console based on LPC_USART. */
#define DEBUG_CONSOLE_DEVICE_TYPE_SWO 9U /*!< Debug console based on SWO. */
/*! @brief Status group numbers. */
enum _status_groups
{
kStatusGroup_Generic = 0, /*!< Group number for generic status codes. */
kStatusGroup_FLASH = 1, /*!< Group number for FLASH status codes. */
kStatusGroup_LPSPI = 4, /*!< Group number for LPSPI status codes. */
kStatusGroup_FLEXIO_SPI = 5, /*!< Group number for FLEXIO SPI status codes. */
kStatusGroup_DSPI = 6, /*!< Group number for DSPI status codes. */
kStatusGroup_FLEXIO_UART = 7, /*!< Group number for FLEXIO UART status codes. */
kStatusGroup_FLEXIO_I2C = 8, /*!< Group number for FLEXIO I2C status codes. */
kStatusGroup_LPI2C = 9, /*!< Group number for LPI2C status codes. */
kStatusGroup_UART = 10, /*!< Group number for UART status codes. */
kStatusGroup_I2C = 11, /*!< Group number for UART status codes. */
kStatusGroup_LPSCI = 12, /*!< Group number for LPSCI status codes. */
kStatusGroup_LPUART = 13, /*!< Group number for LPUART status codes. */
kStatusGroup_SPI = 14, /*!< Group number for SPI status code.*/
kStatusGroup_XRDC = 15, /*!< Group number for XRDC status code.*/
kStatusGroup_SEMA42 = 16, /*!< Group number for SEMA42 status code.*/
kStatusGroup_SDHC = 17, /*!< Group number for SDHC status code */
kStatusGroup_SDMMC = 18, /*!< Group number for SDMMC status code */
kStatusGroup_SAI = 19, /*!< Group number for SAI status code */
kStatusGroup_MCG = 20, /*!< Group number for MCG status codes. */
kStatusGroup_SCG = 21, /*!< Group number for SCG status codes. */
kStatusGroup_SDSPI = 22, /*!< Group number for SDSPI status codes. */
kStatusGroup_FLEXIO_I2S = 23, /*!< Group number for FLEXIO I2S status codes */
kStatusGroup_FLEXIO_MCULCD = 24, /*!< Group number for FLEXIO LCD status codes */
kStatusGroup_FLASHIAP = 25, /*!< Group number for FLASHIAP status codes */
kStatusGroup_FLEXCOMM_I2C = 26, /*!< Group number for FLEXCOMM I2C status codes */
kStatusGroup_I2S = 27, /*!< Group number for I2S status codes */
kStatusGroup_IUART = 28, /*!< Group number for IUART status codes */
kStatusGroup_CSI = 29, /*!< Group number for CSI status codes */
kStatusGroup_MIPI_DSI = 30, /*!< Group number for MIPI DSI status codes */
kStatusGroup_SDRAMC = 35, /*!< Group number for SDRAMC status codes. */
kStatusGroup_POWER = 39, /*!< Group number for POWER status codes. */
kStatusGroup_ENET = 40, /*!< Group number for ENET status codes. */
kStatusGroup_PHY = 41, /*!< Group number for PHY status codes. */
kStatusGroup_TRGMUX = 42, /*!< Group number for TRGMUX status codes. */
kStatusGroup_SMARTCARD = 43, /*!< Group number for SMARTCARD status codes. */
kStatusGroup_LMEM = 44, /*!< Group number for LMEM status codes. */
kStatusGroup_QSPI = 45, /*!< Group number for QSPI status codes. */
kStatusGroup_DMA = 50, /*!< Group number for DMA status codes. */
kStatusGroup_EDMA = 51, /*!< Group number for EDMA status codes. */
kStatusGroup_DMAMGR = 52, /*!< Group number for DMAMGR status codes. */
kStatusGroup_FLEXCAN = 53, /*!< Group number for FlexCAN status codes. */
kStatusGroup_LTC = 54, /*!< Group number for LTC status codes. */
kStatusGroup_FLEXIO_CAMERA = 55, /*!< Group number for FLEXIO CAMERA status codes. */
kStatusGroup_LPC_SPI = 56, /*!< Group number for LPC_SPI status codes. */
kStatusGroup_LPC_USART = 57, /*!< Group number for LPC_USART status codes. */
kStatusGroup_DMIC = 58, /*!< Group number for DMIC status codes. */
kStatusGroup_SDIF = 59, /*!< Group number for SDIF status codes.*/
kStatusGroup_SPIFI = 60, /*!< Group number for SPIFI status codes. */
kStatusGroup_OTP = 61, /*!< Group number for OTP status codes. */
kStatusGroup_MCAN = 62, /*!< Group number for MCAN status codes. */
kStatusGroup_CAAM = 63, /*!< Group number for CAAM status codes. */
kStatusGroup_ECSPI = 64, /*!< Group number for ECSPI status codes. */
kStatusGroup_USDHC = 65, /*!< Group number for USDHC status codes.*/
kStatusGroup_LPC_I2C = 66, /*!< Group number for LPC_I2C status codes.*/
kStatusGroup_DCP = 67, /*!< Group number for DCP status codes.*/
kStatusGroup_MSCAN = 68, /*!< Group number for MSCAN status codes.*/
kStatusGroup_ESAI = 69, /*!< Group number for ESAI status codes. */
kStatusGroup_FLEXSPI = 70, /*!< Group number for FLEXSPI status codes. */
kStatusGroup_MMDC = 71, /*!< Group number for MMDC status codes. */
kStatusGroup_PDM = 72, /*!< Group number for MIC status codes. */
kStatusGroup_SDMA = 73, /*!< Group number for SDMA status codes. */
kStatusGroup_ICS = 74, /*!< Group number for ICS status codes. */
kStatusGroup_SPDIF = 75, /*!< Group number for SPDIF status codes. */
kStatusGroup_LPC_MINISPI = 76, /*!< Group number for LPC_MINISPI status codes. */
kStatusGroup_HASHCRYPT = 77, /*!< Group number for Hashcrypt status codes */
kStatusGroup_LPC_SPI_SSP = 78, /*!< Group number for LPC_SPI_SSP status codes. */
kStatusGroup_I3C = 79, /*!< Group number for I3C status codes */
kStatusGroup_LPC_I2C_1 = 97, /*!< Group number for LPC_I2C_1 status codes. */
kStatusGroup_NOTIFIER = 98, /*!< Group number for NOTIFIER status codes. */
kStatusGroup_DebugConsole = 99, /*!< Group number for debug console status codes. */
kStatusGroup_SEMC = 100, /*!< Group number for SEMC status codes. */
kStatusGroup_ApplicationRangeStart = 101, /*!< Starting number for application groups. */
kStatusGroup_IAP = 102, /*!< Group number for IAP status codes */
kStatusGroup_SFA = 103, /*!< Group number for SFA status codes*/
kStatusGroup_SPC = 104, /*!< Group number for SPC status codes. */
kStatusGroup_PUF = 105, /*!< Group number for PUF status codes. */
kStatusGroup_TOUCH_PANEL = 106, /*!< Group number for touch panel status codes */
kStatusGroup_HAL_GPIO = 121, /*!< Group number for HAL GPIO status codes. */
kStatusGroup_HAL_UART = 122, /*!< Group number for HAL UART status codes. */
kStatusGroup_HAL_TIMER = 123, /*!< Group number for HAL TIMER status codes. */
kStatusGroup_HAL_SPI = 124, /*!< Group number for HAL SPI status codes. */
kStatusGroup_HAL_I2C = 125, /*!< Group number for HAL I2C status codes. */
kStatusGroup_HAL_FLASH = 126, /*!< Group number for HAL FLASH status codes. */
kStatusGroup_HAL_PWM = 127, /*!< Group number for HAL PWM status codes. */
kStatusGroup_HAL_RNG = 128, /*!< Group number for HAL RNG status codes. */
kStatusGroup_TIMERMANAGER = 135, /*!< Group number for TiMER MANAGER status codes. */
kStatusGroup_SERIALMANAGER = 136, /*!< Group number for SERIAL MANAGER status codes. */
kStatusGroup_LED = 137, /*!< Group number for LED status codes. */
kStatusGroup_BUTTON = 138, /*!< Group number for BUTTON status codes. */
kStatusGroup_EXTERN_EEPROM = 139, /*!< Group number for EXTERN EEPROM status codes. */
kStatusGroup_SHELL = 140, /*!< Group number for SHELL status codes. */
kStatusGroup_MEM_MANAGER = 141, /*!< Group number for MEM MANAGER status codes. */
kStatusGroup_LIST = 142, /*!< Group number for List status codes. */
kStatusGroup_OSA = 143, /*!< Group number for OSA status codes. */
kStatusGroup_COMMON_TASK = 144, /*!< Group number for Common task status codes. */
kStatusGroup_MSG = 145, /*!< Group number for messaging status codes. */
kStatusGroup_SDK_OCOTP = 146, /*!< Group number for OCOTP status codes. */
kStatusGroup_SDK_FLEXSPINOR = 147, /*!< Group number for FLEXSPINOR status codes.*/
kStatusGroup_CODEC = 148, /*!< Group number for codec status codes. */
kStatusGroup_ASRC = 149, /*!< Group number for codec status ASRC. */
kStatusGroup_OTFAD = 150, /*!< Group number for codec status codes. */
kStatusGroup_SDIOSLV = 151, /*!< Group number for SDIOSLV status codes. */
kStatusGroup_MECC = 152, /*!< Group number for MECC status codes. */
kStatusGroup_ENET_QOS = 153, /*!< Group number for ENET_QOS status codes. */
kStatusGroup_LOG = 154, /*!< Group number for LOG status codes. */
};
/*! \public
* @brief Generic status return codes.
*/
enum
{
kStatus_Success = MAKE_STATUS(kStatusGroup_Generic, 0), /*!< Generic status for Success. */
kStatus_Fail = MAKE_STATUS(kStatusGroup_Generic, 1), /*!< Generic status for Fail. */
kStatus_ReadOnly = MAKE_STATUS(kStatusGroup_Generic, 2), /*!< Generic status for read only failure. */
kStatus_OutOfRange = MAKE_STATUS(kStatusGroup_Generic, 3), /*!< Generic status for out of range access. */
kStatus_InvalidArgument = MAKE_STATUS(kStatusGroup_Generic, 4), /*!< Generic status for invalid argument check. */
kStatus_Timeout = MAKE_STATUS(kStatusGroup_Generic, 5), /*!< Generic status for timeout. */
kStatus_NoTransferInProgress = MAKE_STATUS(kStatusGroup_Generic, 6), /*!< Generic status for no transfer in progress. */
};
/*! @brief Type used for all status and error return values. */
typedef int32_t status_t;
/*
* Macro guard for whether to use default weak IRQ implementation in drivers
*/
#ifndef FSL_DRIVER_TRANSFER_DOUBLE_WEAK_IRQ
#define FSL_DRIVER_TRANSFER_DOUBLE_WEAK_IRQ 1
#endif
/*! @name Min/max macros */
/* @{ */
#if !defined(MIN)
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#endif
#if !defined(MAX)
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#endif
/* @} */
/*! @brief Computes the number of elements in an array. */
#if !defined(ARRAY_SIZE)
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
#endif
/*! @name UINT16_MAX/UINT32_MAX value */
/* @{ */
#if !defined(UINT16_MAX)
#define UINT16_MAX ((uint16_t)-1)
#endif
#if !defined(UINT32_MAX)
#define UINT32_MAX ((uint32_t)-1)
#endif
/* @} */
/*! @name Timer utilities */
/* @{ */
/*! Macro to convert a microsecond period to raw count value */
#define USEC_TO_COUNT(us, clockFreqInHz) (uint64_t)(((uint64_t)(us) * (clockFreqInHz)) / 1000000U)
/*! Macro to convert a raw count value to microsecond */
#define COUNT_TO_USEC(count, clockFreqInHz) (uint64_t)((uint64_t)(count) * 1000000U / (clockFreqInHz))
/*! Macro to convert a millisecond period to raw count value */
#define MSEC_TO_COUNT(ms, clockFreqInHz) (uint64_t)((uint64_t)(ms) * (clockFreqInHz) / 1000U)
/*! Macro to convert a raw count value to millisecond */
#define COUNT_TO_MSEC(count, clockFreqInHz) (uint64_t)((uint64_t)(count) * 1000U / (clockFreqInHz))
/* @} */
/*! @name ISR exit barrier
* @{
*
* ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
* exception return operation might vector to incorrect interrupt.
* For Cortex-M7, if core speed much faster than peripheral register write speed,
* the peripheral interrupt flags may be still set after exiting ISR, this results to
* the same error similar with errata 83869.
*/
#if (defined __CORTEX_M) && ((__CORTEX_M == 4U) || (__CORTEX_M == 7U))
#define SDK_ISR_EXIT_BARRIER __DSB()
#else
#define SDK_ISR_EXIT_BARRIER
#endif
/* @} */
/*! @name Alignment variable definition macros */
/* @{ */
#if (defined(__ICCARM__))
/**
* Workaround to disable MISRA C message suppress warnings for IAR compiler.
* http:/ /supp.iar.com/Support/?note=24725
*/
_Pragma("diag_suppress=Pm120")
#define SDK_PRAGMA(x) _Pragma(#x)
_Pragma("diag_error=Pm120")
/*! Macro to define a variable with alignbytes alignment */
#define SDK_ALIGN(var, alignbytes) SDK_PRAGMA(data_alignment = alignbytes) var
/*! Macro to define a variable with L1 d-cache line size alignment */
#if defined(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE)
#define SDK_L1DCACHE_ALIGN(var) SDK_PRAGMA(data_alignment = FSL_FEATURE_L1DCACHE_LINESIZE_BYTE) var
#endif
/*! Macro to define a variable with L2 cache line size alignment */
#if defined(FSL_FEATURE_L2CACHE_LINESIZE_BYTE)
#define SDK_L2CACHE_ALIGN(var) SDK_PRAGMA(data_alignment = FSL_FEATURE_L2CACHE_LINESIZE_BYTE) var
#endif
#elif defined(__CC_ARM) || defined(__ARMCC_VERSION)
/*! Macro to define a variable with alignbytes alignment */
#define SDK_ALIGN(var, alignbytes) __attribute__((aligned(alignbytes))) var
/*! Macro to define a variable with L1 d-cache line size alignment */
#if defined(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE)
#define SDK_L1DCACHE_ALIGN(var) __attribute__((aligned(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE))) var
#endif
/*! Macro to define a variable with L2 cache line size alignment */
#if defined(FSL_FEATURE_L2CACHE_LINESIZE_BYTE)
#define SDK_L2CACHE_ALIGN(var) __attribute__((aligned(FSL_FEATURE_L2CACHE_LINESIZE_BYTE))) var
#endif
#elif defined(__GNUC__)
/*! Macro to define a variable with alignbytes alignment */
#define SDK_ALIGN(var, alignbytes) var __attribute__((aligned(alignbytes)))
/*! Macro to define a variable with L1 d-cache line size alignment */
#if defined(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE)
#define SDK_L1DCACHE_ALIGN(var) var __attribute__((aligned(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE)))
#endif
/*! Macro to define a variable with L2 cache line size alignment */
#if defined(FSL_FEATURE_L2CACHE_LINESIZE_BYTE)
#define SDK_L2CACHE_ALIGN(var) var __attribute__((aligned(FSL_FEATURE_L2CACHE_LINESIZE_BYTE)))
#endif
#else
#error Toolchain not supported
#define SDK_ALIGN(var, alignbytes) var
#if defined(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE)
#define SDK_L1DCACHE_ALIGN(var) var
#endif
#if defined(FSL_FEATURE_L2CACHE_LINESIZE_BYTE)
#define SDK_L2CACHE_ALIGN(var) var
#endif
#endif
/*! Macro to change a value to a given size aligned value */
#define SDK_SIZEALIGN(var, alignbytes) \
((unsigned int)((var) + ((alignbytes)-1U)) & (unsigned int)(~(unsigned int)((alignbytes)-1U)))
/* @} */
/*! @name Non-cacheable region definition macros */
/* For initialized non-zero non-cacheable variables, please using "AT_NONCACHEABLE_SECTION_INIT(var) ={xx};" or
* "AT_NONCACHEABLE_SECTION_ALIGN_INIT(var) ={xx};" in your projects to define them, for zero-inited non-cacheable variables,
* please using "AT_NONCACHEABLE_SECTION(var);" or "AT_NONCACHEABLE_SECTION_ALIGN(var);" to define them, these zero-inited variables
* will be initialized to zero in system startup.
*/
/* @{ */
#if (defined(__ICCARM__))
#if ((!(defined(FSL_FEATURE_HAS_NO_NONCACHEABLE_SECTION) && FSL_FEATURE_HAS_NO_NONCACHEABLE_SECTION)) && defined(FSL_FEATURE_L1ICACHE_LINESIZE_BYTE))
#define AT_NONCACHEABLE_SECTION(var) var @"NonCacheable"
#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) SDK_PRAGMA(data_alignment = alignbytes) var @"NonCacheable"
#define AT_NONCACHEABLE_SECTION_INIT(var) var @"NonCacheable.init"
#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) SDK_PRAGMA(data_alignment = alignbytes) var @"NonCacheable.init"
#else
#define AT_NONCACHEABLE_SECTION(var) var
#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) SDK_PRAGMA(data_alignment = alignbytes) var
#define AT_NONCACHEABLE_SECTION_INIT(var) var
#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) SDK_PRAGMA(data_alignment = alignbytes) var
#endif
#elif(defined(__CC_ARM) || defined(__ARMCC_VERSION))
#if ((!(defined(FSL_FEATURE_HAS_NO_NONCACHEABLE_SECTION) && FSL_FEATURE_HAS_NO_NONCACHEABLE_SECTION)) && defined(FSL_FEATURE_L1ICACHE_LINESIZE_BYTE))
#define AT_NONCACHEABLE_SECTION_INIT(var) __attribute__((section("NonCacheable.init"))) var
#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) \
__attribute__((section("NonCacheable.init"))) __attribute__((aligned(alignbytes))) var
#if(defined(__CC_ARM))
#define AT_NONCACHEABLE_SECTION(var) __attribute__((section("NonCacheable"), zero_init)) var
#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) \
__attribute__((section("NonCacheable"), zero_init)) __attribute__((aligned(alignbytes))) var
#else
#define AT_NONCACHEABLE_SECTION(var) __attribute__((section(".bss.NonCacheable"))) var
#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) \
__attribute__((section(".bss.NonCacheable"))) __attribute__((aligned(alignbytes))) var
#endif
#else
#define AT_NONCACHEABLE_SECTION(var) var
#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) __attribute__((aligned(alignbytes))) var
#define AT_NONCACHEABLE_SECTION_INIT(var) var
#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) __attribute__((aligned(alignbytes))) var
#endif
#elif(defined(__XCC__))
#define AT_NONCACHEABLE_SECTION_INIT(var) __attribute__((section("NonCacheable.init"))) var
#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) \
__attribute__((section("NonCacheable.init"))) var __attribute__((aligned(alignbytes)))
#define AT_NONCACHEABLE_SECTION(var) __attribute__((section("NonCacheable"))) var
#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) \
__attribute__((section("NonCacheable"))) var __attribute__((aligned(alignbytes)))
#elif(defined(__GNUC__))
/* For GCC, when the non-cacheable section is required, please define "__STARTUP_INITIALIZE_NONCACHEDATA"
* in your projects to make sure the non-cacheable section variables will be initialized in system startup.
*/
#if ((!(defined(FSL_FEATURE_HAS_NO_NONCACHEABLE_SECTION) && FSL_FEATURE_HAS_NO_NONCACHEABLE_SECTION)) && defined(FSL_FEATURE_L1ICACHE_LINESIZE_BYTE))
#define AT_NONCACHEABLE_SECTION_INIT(var) __attribute__((section("NonCacheable.init"))) var
#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) \
__attribute__((section("NonCacheable.init"))) var __attribute__((aligned(alignbytes)))
#define AT_NONCACHEABLE_SECTION(var) __attribute__((section("NonCacheable,\"aw\",%nobits @"))) var
#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) \
__attribute__((section("NonCacheable,\"aw\",%nobits @"))) var __attribute__((aligned(alignbytes)))
#else
#define AT_NONCACHEABLE_SECTION(var) var
#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) var __attribute__((aligned(alignbytes)))
#define AT_NONCACHEABLE_SECTION_INIT(var) var
#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) var __attribute__((aligned(alignbytes)))
#endif
#else
#error Toolchain not supported.
#define AT_NONCACHEABLE_SECTION(var) var
#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) var
#define AT_NONCACHEABLE_SECTION_INIT(var) var
#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) var
#endif
/* @} */
/*! @name Time sensitive region */
/* @{ */
#if defined(FSL_SDK_DRIVER_QUICK_ACCESS_ENABLE) && FSL_SDK_DRIVER_QUICK_ACCESS_ENABLE
#if (defined(__ICCARM__))
#define AT_QUICKACCESS_SECTION_CODE(func) func @"CodeQuickAccess"
#define AT_QUICKACCESS_SECTION_DATA(func) func @"DataQuickAccess"
#elif(defined(__CC_ARM) || defined(__ARMCC_VERSION))
#define AT_QUICKACCESS_SECTION_CODE(func) __attribute__((section("CodeQuickAccess"), __noinline__)) func
#define AT_QUICKACCESS_SECTION_DATA(func) __attribute__((section("DataQuickAccess"))) func
#elif(defined(__GNUC__))
#define AT_QUICKACCESS_SECTION_CODE(func) __attribute__((section("CodeQuickAccess"), __noinline__)) func
#define AT_QUICKACCESS_SECTION_DATA(func) __attribute__((section("DataQuickAccess"))) func
#else
#error Toolchain not supported.
#endif /* defined(__ICCARM__) */
#else
#if (defined(__ICCARM__))
#define AT_QUICKACCESS_SECTION_CODE(func) func
#define AT_QUICKACCESS_SECTION_DATA(func) func
#elif(defined(__CC_ARM) || defined(__ARMCC_VERSION))
#define AT_QUICKACCESS_SECTION_CODE(func) func
#define AT_QUICKACCESS_SECTION_DATA(func) func
#elif(defined(__GNUC__))
#define AT_QUICKACCESS_SECTION_CODE(func) func
#define AT_QUICKACCESS_SECTION_DATA(func) func
#else
#error Toolchain not supported.
#endif
#endif /* __FSL_SDK_DRIVER_QUICK_ACCESS_ENABLE */
/* @} */
/*! @name Ram Function */
#if (defined(__ICCARM__))
#define RAMFUNCTION_SECTION_CODE(func) func @"RamFunction"
#elif(defined(__CC_ARM) || defined(__ARMCC_VERSION))
#define RAMFUNCTION_SECTION_CODE(func) __attribute__((section("RamFunction"))) func
#elif(defined(__GNUC__))
#define RAMFUNCTION_SECTION_CODE(func) __attribute__((section("RamFunction"))) func
#else
#error Toolchain not supported.
#endif /* defined(__ICCARM__) */
/* @} */
/*! @name Suppress fallthrough warning macro */
/* For switch case code block, if case section ends without "break;" statement, there wil be
fallthrough warning with compiler flag -Wextra or -Wimplicit-fallthrough=n when using armgcc.
To suppress this warning, "SUPPRESS_FALL_THROUGH_WARNING();" need to be added at the end of each
case section which misses "break;"statement.
*/
/* @{ */
#if defined(__GNUC__) && !defined(__ARMCC_VERSION)
#define SUPPRESS_FALL_THROUGH_WARNING() __attribute__ ((fallthrough))
#else
#define SUPPRESS_FALL_THROUGH_WARNING()
#endif
/* @} */
/*! @name Atomic modification
*
* These macros are used for atomic access, such as read-modify-write
* to the peripheral registers.
*
* - SDK_ATOMIC_LOCAL_ADD
* - SDK_ATOMIC_LOCAL_SET
* - SDK_ATOMIC_LOCAL_CLEAR
* - SDK_ATOMIC_LOCAL_TOGGLE
* - SDK_ATOMIC_LOCAL_CLEAR_AND_SET
*
* Take SDK_ATOMIC_LOCAL_CLEAR_AND_SET as an example: the parameter @c addr
* means the address of the peripheral register or variable you want to modify
* atomically, the parameter @c clearBits is the bits to clear, the parameter
* @c setBits it the bits to set.
* For example, to set a 32-bit register bit1:bit0 to 0b10, use like this:
*
* @code
volatile uint32_t * reg = (volatile uint32_t *)REG_ADDR;
SDK_ATOMIC_LOCAL_CLEAR_AND_SET(reg, 0x03, 0x02);
@endcode
*
* In this example, the register bit1:bit0 are cleared and bit1 is set, as a result,
* register bit1:bit0 = 0b10.
*
* @note For the platforms don't support exclusive load and store, these macros
* disable the global interrupt to pretect the modification.
*
* @note These macros only guarantee the local processor atomic operations. For
* the multi-processor devices, use hardware semaphore such as SEMA42 to
* guarantee exclusive access if necessary.
*
* @{
*/
/* clang-format off */
#if ((defined(__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
(defined(__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
(defined(__ARM_ARCH_8M_MAIN__) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
(defined(__ARM_ARCH_8M_BASE__) && (__ARM_ARCH_8M_BASE__ == 1)))
/* clang-format on */
/* If the LDREX and STREX are supported, use them. */
#define _SDK_ATOMIC_LOCAL_OPS_1BYTE(addr, val, ops) \
do \
{ \
(val) = __LDREXB(addr); \
(ops); \
} while (0UL != __STREXB((val), (addr)))
#define _SDK_ATOMIC_LOCAL_OPS_2BYTE(addr, val, ops) \
do \
{ \
(val) = __LDREXH(addr); \
(ops); \
} while (0UL != __STREXH((val), (addr)))
#define _SDK_ATOMIC_LOCAL_OPS_4BYTE(addr, val, ops) \
do \
{ \
(val) = __LDREXW(addr); \
(ops); \
} while (0UL != __STREXW((val), (addr)))
static inline void _SDK_AtomicLocalAdd1Byte(volatile uint8_t *addr, uint8_t val)
{
uint8_t s_val;
_SDK_ATOMIC_LOCAL_OPS_1BYTE(addr, s_val, s_val += val);
}
static inline void _SDK_AtomicLocalAdd2Byte(volatile uint16_t *addr, uint16_t val)
{
uint16_t s_val;
_SDK_ATOMIC_LOCAL_OPS_2BYTE(addr, s_val, s_val += val);
}
static inline void _SDK_AtomicLocalAdd4Byte(volatile uint32_t *addr, uint32_t val)
{
uint32_t s_val;
_SDK_ATOMIC_LOCAL_OPS_4BYTE(addr, s_val, s_val += val);
}
static inline void _SDK_AtomicLocalSub1Byte(volatile uint8_t *addr, uint8_t val)
{
uint8_t s_val;
_SDK_ATOMIC_LOCAL_OPS_1BYTE(addr, s_val, s_val -= val);
}
static inline void _SDK_AtomicLocalSub2Byte(volatile uint16_t *addr, uint16_t val)
{
uint16_t s_val;
_SDK_ATOMIC_LOCAL_OPS_2BYTE(addr, s_val, s_val -= val);
}
static inline void _SDK_AtomicLocalSub4Byte(volatile uint32_t *addr, uint32_t val)
{
uint32_t s_val;
_SDK_ATOMIC_LOCAL_OPS_4BYTE(addr, s_val, s_val -= val);
}
static inline void _SDK_AtomicLocalSet1Byte(volatile uint8_t *addr, uint8_t bits)
{
uint8_t s_val;
_SDK_ATOMIC_LOCAL_OPS_1BYTE(addr, s_val, s_val |= bits);
}
static inline void _SDK_AtomicLocalSet2Byte(volatile uint16_t *addr, uint16_t bits)
{
uint16_t s_val;
_SDK_ATOMIC_LOCAL_OPS_2BYTE(addr, s_val, s_val |= bits);
}
static inline void _SDK_AtomicLocalSet4Byte(volatile uint32_t *addr, uint32_t bits)
{
uint32_t s_val;
_SDK_ATOMIC_LOCAL_OPS_4BYTE(addr, s_val, s_val |= bits);
}
static inline void _SDK_AtomicLocalClear1Byte(volatile uint8_t *addr, uint8_t bits)
{
uint8_t s_val;
_SDK_ATOMIC_LOCAL_OPS_1BYTE(addr, s_val, s_val &= ~bits);
}
static inline void _SDK_AtomicLocalClear2Byte(volatile uint16_t *addr, uint16_t bits)
{
uint16_t s_val;
_SDK_ATOMIC_LOCAL_OPS_2BYTE(addr, s_val, s_val &= ~bits);
}
static inline void _SDK_AtomicLocalClear4Byte(volatile uint32_t *addr, uint32_t bits)
{
uint32_t s_val;
_SDK_ATOMIC_LOCAL_OPS_4BYTE(addr, s_val, s_val &= ~bits);
}
static inline void _SDK_AtomicLocalToggle1Byte(volatile uint8_t *addr, uint8_t bits)
{
uint8_t s_val;
_SDK_ATOMIC_LOCAL_OPS_1BYTE(addr, s_val, s_val ^= bits);
}
static inline void _SDK_AtomicLocalToggle2Byte(volatile uint16_t *addr, uint16_t bits)
{
uint16_t s_val;
_SDK_ATOMIC_LOCAL_OPS_2BYTE(addr, s_val, s_val ^= bits);
}
static inline void _SDK_AtomicLocalToggle4Byte(volatile uint32_t *addr, uint32_t bits)
{
uint32_t s_val;
_SDK_ATOMIC_LOCAL_OPS_4BYTE(addr, s_val, s_val ^= bits);
}
static inline void _SDK_AtomicLocalClearAndSet1Byte(volatile uint8_t *addr, uint8_t clearBits, uint8_t setBits)
{
uint8_t s_val;
_SDK_ATOMIC_LOCAL_OPS_1BYTE(addr, s_val, s_val = (s_val & ~clearBits) | setBits);
}
static inline void _SDK_AtomicLocalClearAndSet2Byte(volatile uint16_t *addr, uint16_t clearBits, uint16_t setBits)
{
uint16_t s_val;
_SDK_ATOMIC_LOCAL_OPS_2BYTE(addr, s_val, s_val = (s_val & ~clearBits) | setBits);
}
static inline void _SDK_AtomicLocalClearAndSet4Byte(volatile uint32_t *addr, uint32_t clearBits, uint32_t setBits)
{
uint32_t s_val;
_SDK_ATOMIC_LOCAL_OPS_4BYTE(addr, s_val, s_val = (s_val & ~clearBits) | setBits);
}
#define SDK_ATOMIC_LOCAL_ADD(addr, val) \
((1UL == sizeof(*(addr))) ? _SDK_AtomicLocalAdd1Byte((volatile void*)(addr), (val)) : \
((2UL == sizeof(*(addr))) ? _SDK_AtomicLocalAdd2Byte((volatile void*)(addr), (val)) : \
_SDK_AtomicLocalAdd4Byte((volatile void*)(addr), (val))))
#define SDK_ATOMIC_LOCAL_SET(addr, bits) \
((1UL == sizeof(*(addr))) ? _SDK_AtomicLocalSet1Byte((volatile void*)(addr), (bits)) : \
((2UL == sizeof(*(addr))) ? _SDK_AtomicLocalSet2Byte((volatile void*)(addr), (bits)) : \
_SDK_AtomicLocalSet4Byte((volatile void*)(addr), (bits))))
#define SDK_ATOMIC_LOCAL_CLEAR(addr, bits) \
((1UL == sizeof(*(addr))) ? _SDK_AtomicLocalClear1Byte((volatile void*)(addr), (bits)) : \
((2UL == sizeof(*(addr))) ? _SDK_AtomicLocalClear2Byte((volatile void*)(addr), (bits)) : \
_SDK_AtomicLocalClear4Byte((volatile void*)(addr), (bits))))
#define SDK_ATOMIC_LOCAL_TOGGLE(addr, bits) \
((1UL == sizeof(*(addr))) ? _SDK_AtomicLocalToggle1Byte((volatile void*)(addr), (bits)) : \
((2UL == sizeof(*(addr))) ? _SDK_AtomicLocalToggle2Byte((volatile void*)(addr), (bits)) : \
_SDK_AtomicLocalToggle4Byte((volatile void*)(addr), (bits))))
#define SDK_ATOMIC_LOCAL_CLEAR_AND_SET(addr, clearBits, setBits) \
((1UL == sizeof(*(addr))) ? _SDK_AtomicLocalClearAndSet1Byte((volatile void*)(addr), (clearBits), (setBits)) : \
((2UL == sizeof(*(addr))) ? _SDK_AtomicLocalClearAndSet2Byte((volatile void*)(addr), (clearBits), (setBits)) : \
_SDK_AtomicLocalClearAndSet4Byte((volatile void*)(addr), (clearBits), (setBits))))
#else
#define SDK_ATOMIC_LOCAL_ADD(addr, val) \
do { \
uint32_t s_atomicOldInt; \
s_atomicOldInt = DisableGlobalIRQ(); \
*(addr) += (val); \
EnableGlobalIRQ(s_atomicOldInt); \
} while (0)
#define SDK_ATOMIC_LOCAL_SET(addr, bits) \
do { \
uint32_t s_atomicOldInt; \
s_atomicOldInt = DisableGlobalIRQ(); \
*(addr) |= (bits); \
EnableGlobalIRQ(s_atomicOldInt); \
} while (0)
#define SDK_ATOMIC_LOCAL_CLEAR(addr, bits) \
do { \
uint32_t s_atomicOldInt; \
s_atomicOldInt = DisableGlobalIRQ(); \
*(addr) &= ~(bits); \
EnableGlobalIRQ(s_atomicOldInt); \
} while (0)
#define SDK_ATOMIC_LOCAL_TOGGLE(addr, bits) \
do { \
uint32_t s_atomicOldInt; \
s_atomicOldInt = DisableGlobalIRQ(); \
*(addr) ^= (bits); \
EnableGlobalIRQ(s_atomicOldInt); \
} while (0)
#define SDK_ATOMIC_LOCAL_CLEAR_AND_SET(addr, clearBits, setBits) \
do { \
uint32_t s_atomicOldInt; \
s_atomicOldInt = DisableGlobalIRQ(); \
*(addr) = (*(addr) & ~(clearBits)) | (setBits); \
EnableGlobalIRQ(s_atomicOldInt); \
} while (0)
#endif
/* @} */
#if defined ( __ARMCC_VERSION ) && ( __ARMCC_VERSION >= 6010050 )
void DefaultISR(void);
#endif
/*
* The fsl_clock.h is included here because it needs MAKE_VERSION/MAKE_STATUS/status_t
* defined in previous of this file.
*/
#include "fsl_clock.h"
/*
* Chip level peripheral reset API, for MCUs that implement peripheral reset control external to a peripheral
*/
#if ((defined(FSL_FEATURE_SOC_SYSCON_COUNT) && (FSL_FEATURE_SOC_SYSCON_COUNT > 0)) || \
(defined(FSL_FEATURE_SOC_ASYNC_SYSCON_COUNT) && (FSL_FEATURE_SOC_ASYNC_SYSCON_COUNT > 0)))
#include "fsl_reset.h"
#endif
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C"
{
#endif
/*!
* @brief Enable specific interrupt.
*
* Enable LEVEL1 interrupt. For some devices, there might be multiple interrupt
* levels. For example, there are NVIC and intmux. Here the interrupts connected
* to NVIC are the LEVEL1 interrupts, because they are routed to the core directly.
* The interrupts connected to intmux are the LEVEL2 interrupts, they are routed
* to NVIC first then routed to core.
*
* This function only enables the LEVEL1 interrupts. The number of LEVEL1 interrupts
* is indicated by the feature macro FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS.
*
* @param interrupt The IRQ number.
* @retval kStatus_Success Interrupt enabled successfully
* @retval kStatus_Fail Failed to enable the interrupt
*/
static inline status_t EnableIRQ(IRQn_Type interrupt)
{
status_t status = kStatus_Success;
if (NotAvail_IRQn == interrupt)
{
status = kStatus_Fail;
}
#if defined(FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS) && (FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS > 0)
else if ((int32_t)interrupt >= (int32_t)FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS)
{
status = kStatus_Fail;
}
#endif
else
{
#if defined(__GIC_PRIO_BITS)
GIC_EnableIRQ(interrupt);
#else
NVIC_EnableIRQ(interrupt);
#endif
}
return status;
}
/*!
* @brief Disable specific interrupt.
*
* Disable LEVEL1 interrupt. For some devices, there might be multiple interrupt
* levels. For example, there are NVIC and intmux. Here the interrupts connected
* to NVIC are the LEVEL1 interrupts, because they are routed to the core directly.
* The interrupts connected to intmux are the LEVEL2 interrupts, they are routed
* to NVIC first then routed to core.
*
* This function only disables the LEVEL1 interrupts. The number of LEVEL1 interrupts
* is indicated by the feature macro FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS.
*
* @param interrupt The IRQ number.
* @retval kStatus_Success Interrupt disabled successfully
* @retval kStatus_Fail Failed to disable the interrupt
*/
static inline status_t DisableIRQ(IRQn_Type interrupt)
{
status_t status = kStatus_Success;
if (NotAvail_IRQn == interrupt)
{
status = kStatus_Fail;
}
#if defined(FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS) && (FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS > 0)
else if ((int32_t)interrupt >= (int32_t)FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS)
{
status = kStatus_Fail;
}
#endif
else
{
#if defined(__GIC_PRIO_BITS)
GIC_DisableIRQ(interrupt);
#else
NVIC_DisableIRQ(interrupt);
#endif
}
return status;
}
/*!
* @brief Disable the global IRQ
*
* Disable the global interrupt and return the current primask register. User is required to provided the primask
* register for the EnableGlobalIRQ().
*
* @return Current primask value.
*/
static inline uint32_t DisableGlobalIRQ(void)
{
#if defined (__XCC__)
return 0;
#else
#if defined(CPSR_I_Msk)
uint32_t cpsr = __get_CPSR() & CPSR_I_Msk;
__disable_irq();
return cpsr;
#else
uint32_t regPrimask = __get_PRIMASK();
__disable_irq();
return regPrimask;
#endif
#endif
}
/*!
* @brief Enable the global IRQ
*
* Set the primask register with the provided primask value but not just enable the primask. The idea is for the
* convenience of integration of RTOS. some RTOS get its own management mechanism of primask. User is required to
* use the EnableGlobalIRQ() and DisableGlobalIRQ() in pair.
*
* @param primask value of primask register to be restored. The primask value is supposed to be provided by the
* DisableGlobalIRQ().
*/
static inline void EnableGlobalIRQ(uint32_t primask)
{
#if defined (__XCC__)
#else
#if defined(CPSR_I_Msk)
__set_CPSR((__get_CPSR() & ~CPSR_I_Msk) | primask);
#else
__set_PRIMASK(primask);
#endif
#endif
}
#if defined(ENABLE_RAM_VECTOR_TABLE)
/*!
* @brief install IRQ handler
*
* @param irq IRQ number
* @param irqHandler IRQ handler address
* @return The old IRQ handler address
*/
uint32_t InstallIRQHandler(IRQn_Type irq, uint32_t irqHandler);
#endif /* ENABLE_RAM_VECTOR_TABLE. */
#if (defined(FSL_FEATURE_SOC_SYSCON_COUNT) && (FSL_FEATURE_SOC_SYSCON_COUNT > 0))
/*
* When FSL_FEATURE_POWERLIB_EXTEND is defined to non-zero value,
* powerlib should be used instead of these functions.
*/
#if !(defined(FSL_FEATURE_POWERLIB_EXTEND) && (FSL_FEATURE_POWERLIB_EXTEND != 0))
/*!
* @brief Enable specific interrupt for wake-up from deep-sleep mode.
*
* Enable the interrupt for wake-up from deep sleep mode.
* Some interrupts are typically used in sleep mode only and will not occur during
* deep-sleep mode because relevant clocks are stopped. However, it is possible to enable
* those clocks (significantly increasing power consumption in the reduced power mode),
* making these wake-ups possible.
*
* @note This function also enables the interrupt in the NVIC (EnableIRQ() is called internaly).
*
* @param interrupt The IRQ number.
*/
void EnableDeepSleepIRQ(IRQn_Type interrupt);
/*!
* @brief Disable specific interrupt for wake-up from deep-sleep mode.
*
* Disable the interrupt for wake-up from deep sleep mode.
* Some interrupts are typically used in sleep mode only and will not occur during
* deep-sleep mode because relevant clocks are stopped. However, it is possible to enable
* those clocks (significantly increasing power consumption in the reduced power mode),
* making these wake-ups possible.
*
* @note This function also disables the interrupt in the NVIC (DisableIRQ() is called internaly).
*
* @param interrupt The IRQ number.
*/
void DisableDeepSleepIRQ(IRQn_Type interrupt);
#endif /* FSL_FEATURE_POWERLIB_EXTEND */
#endif /* FSL_FEATURE_SOC_SYSCON_COUNT */
/*!
* @brief Allocate memory with given alignment and aligned size.
*
* This is provided to support the dynamically allocated memory
* used in cache-able region.
* @param size The length required to malloc.
* @param alignbytes The alignment size.
* @retval The allocated memory.
*/
void *SDK_Malloc(size_t size, size_t alignbytes);
/*!
* @brief Free memory.
*
* @param ptr The memory to be release.
*/
void SDK_Free(void *ptr);
/*!
* @brief Delay at least for some time.
* Please note that, this API uses while loop for delay, different run-time environments make the time not precise,
* if precise delay count was needed, please implement a new delay function with hardware timer.
*
* @param delayTime_us Delay time in unit of microsecond.
* @param coreClock_Hz Core clock frequency with Hz.
*/
void SDK_DelayAtLeastUs(uint32_t delayTime_us, uint32_t coreClock_Hz);
#if defined(__cplusplus)
}
#endif
/*! @} */
#endif /* _FSL_COMMON_H_ */

View File

@ -0,0 +1,224 @@
/*
* Copyright 2017-2018, 2020 NXP
* All rights reserved.
*
*
* SPDX-License-Identifier: BSD-3-Clause
*
* Debug console shall provide input and output functions to scan and print formatted data.
* o Support a format specifier for PRINTF follows this prototype "%[flags][width][.precision][length]specifier"
* - [flags] :'-', '+', '#', ' ', '0'
* - [width]: number (0,1...)
* - [.precision]: number (0,1...)
* - [length]: do not support
* - [specifier]: 'd', 'i', 'f', 'F', 'x', 'X', 'o', 'p', 'u', 'c', 's', 'n'
* o Support a format specifier for SCANF follows this prototype " %[*][width][length]specifier"
* - [*]: is supported.
* - [width]: number (0,1...)
* - [length]: 'h', 'hh', 'l','ll','L'. ignore ('j','z','t')
* - [specifier]: 'd', 'i', 'u', 'f', 'F', 'e', 'E', 'g', 'G', 'a', 'A', 'o', 'c', 's'
*/
#ifndef _FSL_DEBUGCONSOLE_H_
#define _FSL_DEBUGCONSOLE_H_
#include "fsl_common.h"
/*
* @addtogroup debugconsole
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @brief Definition select redirect toolchain printf, scanf to uart or not. */
#define DEBUGCONSOLE_REDIRECT_TO_TOOLCHAIN 0U /*!< Select toolchain printf and scanf. */
#define DEBUGCONSOLE_REDIRECT_TO_SDK 1U /*!< Select SDK version printf, scanf. */
#define DEBUGCONSOLE_DISABLE 2U /*!< Disable debugconsole function. */
/*! @brief Definition to select sdk or toolchain printf, scanf. */
#ifndef SDK_DEBUGCONSOLE
#define SDK_DEBUGCONSOLE DEBUGCONSOLE_REDIRECT_TO_SDK
#endif
#if defined(SDK_DEBUGCONSOLE) && !(SDK_DEBUGCONSOLE)
#include <stdio.h>
#endif
/*! @brief Definition to printf the float number. */
#ifndef PRINTF_FLOAT_ENABLE
#define PRINTF_FLOAT_ENABLE 0U
#endif /* PRINTF_FLOAT_ENABLE */
/*! @brief Definition to scanf the float number. */
#ifndef SCANF_FLOAT_ENABLE
#define SCANF_FLOAT_ENABLE 0U
#endif /* SCANF_FLOAT_ENABLE */
/*! @brief Definition to support advanced format specifier for printf. */
#ifndef PRINTF_ADVANCED_ENABLE
#define PRINTF_ADVANCED_ENABLE 0U
#endif /* PRINTF_ADVANCED_ENABLE */
/*! @brief Definition to support advanced format specifier for scanf. */
#ifndef SCANF_ADVANCED_ENABLE
#define SCANF_ADVANCED_ENABLE 0U
#endif /* SCANF_ADVANCED_ENABLE */
/*! @brief Definition to select redirect toolchain printf, scanf to uart or not.
*
* if SDK_DEBUGCONSOLE defined to 0,it represents select toolchain printf, scanf.
* if SDK_DEBUGCONSOLE defined to 1,it represents select SDK version printf, scanf.
* if SDK_DEBUGCONSOLE defined to 2,it represents disable debugconsole function.
*/
#if SDK_DEBUGCONSOLE == DEBUGCONSOLE_DISABLE /* Disable debug console */
#define PRINTF
#define SCANF
#define PUTCHAR
#define GETCHAR
#elif SDK_DEBUGCONSOLE == DEBUGCONSOLE_REDIRECT_TO_SDK /* Select printf, scanf, putchar, getchar of SDK version. */
#define PRINTF DbgConsole_Printf
#define SCANF DbgConsole_Scanf
#define PUTCHAR DbgConsole_Putchar
#define GETCHAR DbgConsole_Getchar
#elif SDK_DEBUGCONSOLE == \
DEBUGCONSOLE_REDIRECT_TO_TOOLCHAIN /* Select printf, scanf, putchar, getchar of toolchain. \ */
#define PRINTF printf
#define SCANF scanf
#define PUTCHAR putchar
#define GETCHAR getchar
#endif /* SDK_DEBUGCONSOLE */
typedef enum _serial_port_type
{
kSerialPort_None = 0U, /*!< Serial port is none */
kSerialPort_Uart = 1U, /*!< Serial port UART */
} serial_port_type_t;
/*******************************************************************************
* Prototypes
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif /* __cplusplus */
/*! @name Initialization*/
/* @{ */
#if ((SDK_DEBUGCONSOLE == DEBUGCONSOLE_REDIRECT_TO_SDK) || defined(SDK_DEBUGCONSOLE_UART))
/*!
* @brief Initializes the peripheral used for debug messages.
*
* Call this function to enable debug log messages to be output via the specified peripheral,
* frequency of peripheral source clock, and base address at the specified baud rate.
* After this function has returned, stdout and stdin are connected to the selected peripheral.
*
* @param instance The instance of the module.If the device is kSerialPort_Uart,
* the instance is UART peripheral instance. The UART hardware peripheral
* type is determined by UART adapter. For example, if the instance is 1,
* if the lpuart_adapter.c is added to the current project, the UART periheral
* is LPUART1.
* If the uart_adapter.c is added to the current project, the UART periheral
* is UART1.
* @param baudRate The desired baud rate in bits per second.
* @param device Low level device type for the debug console, can be one of the following.
* @arg kSerialPort_Uart.
* @param clkSrcFreq Frequency of peripheral source clock.
*
* @return Indicates whether initialization was successful or not.
* @retval kStatus_Success Execution successfully
* @retval kStatus_Fail Execution failure
*/
status_t DbgConsole_Init(uint8_t instance, uint32_t baudRate, serial_port_type_t device, uint32_t clkSrcFreq);
/*!
* @brief De-initializes the peripheral used for debug messages.
*
* Call this function to disable debug log messages to be output via the specified peripheral
* base address and at the specified baud rate.
*
* @return Indicates whether de-initialization was successful or not.
*/
status_t DbgConsole_Deinit(void);
#else
/*!
* Use an error to replace the DbgConsole_Init when SDK_DEBUGCONSOLE is not DEBUGCONSOLE_REDIRECT_TO_SDK and
* SDK_DEBUGCONSOLE_UART is not defined.
*/
static inline status_t DbgConsole_Init(uint8_t instance,
uint32_t baudRate,
serial_port_type_t device,
uint32_t clkSrcFreq)
{
(void)instance;
(void)baudRate;
(void)device;
(void)clkSrcFreq;
return (status_t)kStatus_Fail;
}
/*!
* Use an error to replace the DbgConsole_Deinit when SDK_DEBUGCONSOLE is not DEBUGCONSOLE_REDIRECT_TO_SDK and
* SDK_DEBUGCONSOLE_UART is not defined.
*/
static inline status_t DbgConsole_Deinit(void)
{
return (status_t)kStatus_Fail;
}
#endif /* ((SDK_DEBUGCONSOLE == DEBUGCONSOLE_REDIRECT_TO_SDK) || defined(SDK_DEBUGCONSOLE_UART)) */
#if SDK_DEBUGCONSOLE
/*!
* @brief Writes formatted output to the standard output stream.
*
* Call this function to write a formatted output to the standard output stream.
*
* @param fmt_s Format control string.
* @return Returns the number of characters printed or a negative value if an error occurs.
*/
int DbgConsole_Printf(const char *fmt_s, ...);
/*!
* @brief Writes a character to stdout.
*
* Call this function to write a character to stdout.
*
* @param ch Character to be written.
* @return Returns the character written.
*/
int DbgConsole_Putchar(int ch);
/*!
* @brief Reads formatted data from the standard input stream.
*
* Call this function to read formatted data from the standard input stream.
*
* @param fmt_ptr Format control string.
* @return Returns the number of fields successfully converted and assigned.
*/
int DbgConsole_Scanf(char *fmt_ptr, ...);
/*!
* @brief Reads a character from standard input.
*
* Call this function to read a character from standard input.
*
* @return Returns the character read.
*/
int DbgConsole_Getchar(void);
#endif /* SDK_DEBUGCONSOLE */
/*! @} */
#if defined(__cplusplus)
}
#endif /* __cplusplus */
/*! @} */
#endif /* _FSL_DEBUGCONSOLE_H_ */

View File

@ -0,0 +1,35 @@
/*
* Copyright 2014-2016 Freescale Semiconductor, Inc.
* Copyright 2016-2020 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#ifndef __FSL_DEVICE_REGISTERS_H__
#define __FSL_DEVICE_REGISTERS_H__
/*
* Include the cpu specific register header files.
*
* The CPU macro should be declared in the project or makefile.
*/
#if (defined(CPU_MIMX8ML8CVNKZ) || defined(CPU_MIMX8ML8DVNLZ))
#define MIMX8ML8_cm7_SERIES
/* CMSIS-style register definitions */
#include "MIMX8ML8_cm7.h"
/* CPU specific feature definitions */
#include "MIMX8ML8_cm7_features.h"
#else
#error "No valid CPU defined!"
#endif
#endif /* __FSL_DEVICE_REGISTERS_H__ */
/*******************************************************************************
* EOF
******************************************************************************/

View File

@ -0,0 +1,741 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016-2020 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_MU_H_
#define _FSL_MU_H_
#include "fsl_common.h"
/*!
* @addtogroup mu
* @{
*/
/******************************************************************************
* Definitions
*****************************************************************************/
/* Compatibility Macros */
#ifndef MU_CR_NMI_MASK
#define MU_CR_NMI_MASK 0U
#endif
#if (defined(FSL_FEATURE_MU_HAS_RESET_INT) && FSL_FEATURE_MU_HAS_RESET_INT)
#ifndef FSL_FEATURE_MU_HAS_RESET_ASSERT_INT
#define FSL_FEATURE_MU_HAS_RESET_ASSERT_INT 1
#endif
#ifndef FSL_FEATURE_MU_HAS_RESET_DEASSERT_INT
#define FSL_FEATURE_MU_HAS_RESET_DEASSERT_INT 1
#endif
#endif /* FSL_FEATURE_MU_HAS_RESET_INT */
/*! @name Driver version */
/*@{*/
/*! @brief MU driver version. */
#define FSL_MU_DRIVER_VERSION (MAKE_VERSION(2, 0, 6))
/*@}*/
/*!
* @brief MU status flags.
*/
enum _mu_status_flags
{
kMU_Tx0EmptyFlag = (1U << (MU_SR_TEn_SHIFT + 3U)), /*!< TX0 empty. */
kMU_Tx1EmptyFlag = (1U << (MU_SR_TEn_SHIFT + 2U)), /*!< TX1 empty. */
kMU_Tx2EmptyFlag = (1U << (MU_SR_TEn_SHIFT + 1U)), /*!< TX2 empty. */
kMU_Tx3EmptyFlag = (1U << (MU_SR_TEn_SHIFT + 0U)), /*!< TX3 empty. */
kMU_Rx0FullFlag = (1U << (MU_SR_RFn_SHIFT + 3U)), /*!< RX0 full. */
kMU_Rx1FullFlag = (1U << (MU_SR_RFn_SHIFT + 2U)), /*!< RX1 full. */
kMU_Rx2FullFlag = (1U << (MU_SR_RFn_SHIFT + 1U)), /*!< RX2 full. */
kMU_Rx3FullFlag = (1U << (MU_SR_RFn_SHIFT + 0U)), /*!< RX3 full. */
kMU_GenInt0Flag = (1U << (MU_SR_GIPn_SHIFT + 3U)), /*!< General purpose interrupt 0 pending. */
kMU_GenInt1Flag = (1U << (MU_SR_GIPn_SHIFT + 2U)), /*!< General purpose interrupt 0 pending. */
kMU_GenInt2Flag = (1U << (MU_SR_GIPn_SHIFT + 1U)), /*!< General purpose interrupt 0 pending. */
kMU_GenInt3Flag = (1U << (MU_SR_GIPn_SHIFT + 0U)), /*!< General purpose interrupt 0 pending. */
kMU_EventPendingFlag = MU_SR_EP_MASK, /*!< MU event pending. */
kMU_FlagsUpdatingFlag = MU_SR_FUP_MASK, /*!< MU flags update is on-going. */
#if (defined(FSL_FEATURE_MU_HAS_RESET_ASSERT_INT) && FSL_FEATURE_MU_HAS_RESET_ASSERT_INT)
kMU_ResetAssertInterruptFlag = MU_SR_RAIP_MASK, /*!< The other core reset assert interrupt pending. */
#endif
#if (defined(FSL_FEATURE_MU_HAS_RESET_DEASSERT_INT) && FSL_FEATURE_MU_HAS_RESET_DEASSERT_INT)
kMU_ResetDeassertInterruptFlag = MU_SR_RDIP_MASK, /*!< The other core reset de-assert interrupt pending. */
#endif
#if (defined(FSL_FEATURE_MU_HAS_SR_RS) && FSL_FEATURE_MU_HAS_SR_RS)
kMU_OtherSideInResetFlag = MU_SR_RS_MASK /*!< The other side is in reset. */
#endif
#if (defined(FSL_FEATURE_MU_HAS_SR_MURIP) && FSL_FEATURE_MU_HAS_SR_MURIP)
kMU_MuResetInterruptFlag = MU_SR_MURIP_MASK, /*!< The other side initializes MU reset. */
#endif
#if (defined(FSL_FEATURE_MU_HAS_SR_HRIP) && FSL_FEATURE_MU_HAS_SR_HRIP)
kMU_HardwareResetInterruptFlag = MU_SR_HRIP_MASK, /*!< Current side has been hardware reset by the other side. */
#endif
};
/*!
* @brief MU interrupt source to enable.
*/
enum _mu_interrupt_enable
{
kMU_Tx0EmptyInterruptEnable = (1U << (MU_CR_TIEn_SHIFT + 3U)), /*!< TX0 empty. */
kMU_Tx1EmptyInterruptEnable = (1U << (MU_CR_TIEn_SHIFT + 2U)), /*!< TX1 empty. */
kMU_Tx2EmptyInterruptEnable = (1U << (MU_CR_TIEn_SHIFT + 1U)), /*!< TX2 empty. */
kMU_Tx3EmptyInterruptEnable = (1U << (MU_CR_TIEn_SHIFT + 0U)), /*!< TX3 empty. */
kMU_Rx0FullInterruptEnable = (1U << (MU_CR_RIEn_SHIFT + 3U)), /*!< RX0 full. */
kMU_Rx1FullInterruptEnable = (1U << (MU_CR_RIEn_SHIFT + 2U)), /*!< RX1 full. */
kMU_Rx2FullInterruptEnable = (1U << (MU_CR_RIEn_SHIFT + 1U)), /*!< RX2 full. */
kMU_Rx3FullInterruptEnable = (1U << (MU_CR_RIEn_SHIFT + 0U)), /*!< RX3 full. */
kMU_GenInt0InterruptEnable = (int)(1U << (MU_CR_GIEn_SHIFT + 3U)), /*!< General purpose interrupt 0. */
kMU_GenInt1InterruptEnable = (1U << (MU_CR_GIEn_SHIFT + 2U)), /*!< General purpose interrupt 1. */
kMU_GenInt2InterruptEnable = (1U << (MU_CR_GIEn_SHIFT + 1U)), /*!< General purpose interrupt 2. */
kMU_GenInt3InterruptEnable = (1U << (MU_CR_GIEn_SHIFT + 0U)), /*!< General purpose interrupt 3. */
#if (defined(FSL_FEATURE_MU_HAS_RESET_ASSERT_INT) && FSL_FEATURE_MU_HAS_RESET_ASSERT_INT)
kMU_ResetAssertInterruptEnable = MU_CR_RAIE_MASK, /*!< The other core reset assert interrupt. */
#endif
#if (defined(FSL_FEATURE_MU_HAS_RESET_DEASSERT_INT) && FSL_FEATURE_MU_HAS_RESET_ASSERT_INT)
kMU_ResetDeassertInterruptEnable = MU_CR_RDIE_MASK, /*!< The other core reset de-assert interrupt. */
#endif
#if (defined(FSL_FEATURE_MU_HAS_SR_MURIP) && FSL_FEATURE_MU_HAS_SR_MURIP)
kMU_MuResetInterruptEnable = MU_CR_MURIE_MASK, /*!< The other side initializes MU reset. The interrupt
is ORed with the general purpose interrupt 3. The
general purpose interrupt 3 is issued when the other side
set the MU reset and this interrupt is enabled. */
#endif
#if (defined(FSL_FEATURE_MU_HAS_SR_HRIP) && FSL_FEATURE_MU_HAS_SR_HRIP)
kMU_HardwareResetInterruptEnable = MU_CR_HRIE_MASK, /*!< Current side has been hardware reset by the other side. */
#endif
};
/*!
* @brief MU interrupt that could be triggered to the other core.
*/
enum _mu_interrupt_trigger
{
#if !(defined(FSL_FEATURE_MU_NO_NMI) && FSL_FEATURE_MU_NO_NMI)
kMU_NmiInterruptTrigger = MU_CR_NMI_MASK, /*!< NMI interrupt. */
#endif
kMU_GenInt0InterruptTrigger = (1U << (MU_CR_GIRn_SHIFT + 3U)), /*!< General purpose interrupt 0. */
kMU_GenInt1InterruptTrigger = (1U << (MU_CR_GIRn_SHIFT + 2U)), /*!< General purpose interrupt 1. */
kMU_GenInt2InterruptTrigger = (1U << (MU_CR_GIRn_SHIFT + 1U)), /*!< General purpose interrupt 2. */
kMU_GenInt3InterruptTrigger = (1U << (MU_CR_GIRn_SHIFT + 0U)) /*!< General purpose interrupt 3. */
};
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @name MU initialization.
* @{
*/
/*!
* @brief Initializes the MU module.
*
* This function enables the MU clock only.
*
* @param base MU peripheral base address.
*/
void MU_Init(MU_Type *base);
/*!
* @brief De-initializes the MU module.
*
* This function disables the MU clock only.
*
* @param base MU peripheral base address.
*/
void MU_Deinit(MU_Type *base);
/* @} */
/*!
* @name MU Message
* @{
*/
/*!
* @brief Writes a message to the TX register.
*
* This function writes a message to the specific TX register. It does not check
* whether the TX register is empty or not. The upper layer should make sure the TX
* register is empty before calling this function. This function can be used
* in ISR for better performance.
*
* @code
* while (!(kMU_Tx0EmptyFlag & MU_GetStatusFlags(base))) { } Wait for TX0 register empty.
* MU_SendMsgNonBlocking(base, 0U, MSG_VAL); Write message to the TX0 register.
* @endcode
*
* @param base MU peripheral base address.
* @param regIndex TX register index.
* @param msg Message to send.
*/
static inline void MU_SendMsgNonBlocking(MU_Type *base, uint32_t regIndex, uint32_t msg)
{
assert(regIndex < MU_TR_COUNT);
base->TR[regIndex] = msg;
}
/*!
* @brief Blocks to send a message.
*
* This function waits until the TX register is empty and sends the message.
*
* @param base MU peripheral base address.
* @param regIndex TX register index.
* @param msg Message to send.
*/
void MU_SendMsg(MU_Type *base, uint32_t regIndex, uint32_t msg);
/*!
* @brief Reads a message from the RX register.
*
* This function reads a message from the specific RX register. It does not check
* whether the RX register is full or not. The upper layer should make sure the RX
* register is full before calling this function. This function can be used
* in ISR for better performance.
*
* @code
* uint32_t msg;
* while (!(kMU_Rx0FullFlag & MU_GetStatusFlags(base)))
* {
* } Wait for the RX0 register full.
*
* msg = MU_ReceiveMsgNonBlocking(base, 0U); Read message from RX0 register.
* @endcode
*
* @param base MU peripheral base address.
* @param regIndex TX register index.
* @return The received message.
*/
static inline uint32_t MU_ReceiveMsgNonBlocking(MU_Type *base, uint32_t regIndex)
{
assert(regIndex < MU_TR_COUNT);
return base->RR[regIndex];
}
/*!
* @brief Blocks to receive a message.
*
* This function waits until the RX register is full and receives the message.
*
* @param base MU peripheral base address.
* @param regIndex RX register index.
* @return The received message.
*/
uint32_t MU_ReceiveMsg(MU_Type *base, uint32_t regIndex);
/* @} */
/*!
* @name MU Flags
* @{
*/
/*!
* @brief Sets the 3-bit MU flags reflect on the other MU side.
*
* This function sets the 3-bit MU flags directly. Every time the 3-bit MU flags are changed,
* the status flag \c kMU_FlagsUpdatingFlag asserts indicating the 3-bit MU flags are
* updating to the other side. After the 3-bit MU flags are updated, the status flag
* \c kMU_FlagsUpdatingFlag is cleared by hardware. During the flags updating period,
* the flags cannot be changed. The upper layer should make sure the status flag
* \c kMU_FlagsUpdatingFlag is cleared before calling this function.
*
* @code
* while (kMU_FlagsUpdatingFlag & MU_GetStatusFlags(base))
* {
* } Wait for previous MU flags updating.
*
* MU_SetFlagsNonBlocking(base, 0U); Set the mU flags.
* @endcode
*
* @param base MU peripheral base address.
* @param flags The 3-bit MU flags to set.
*/
static inline void MU_SetFlagsNonBlocking(MU_Type *base, uint32_t flags)
{
uint32_t reg = base->CR;
reg = (reg & ~((MU_CR_GIRn_MASK | MU_CR_NMI_MASK) | MU_CR_Fn_MASK)) | MU_CR_Fn(flags);
base->CR = reg;
}
/*!
* @brief Blocks setting the 3-bit MU flags reflect on the other MU side.
*
* This function blocks setting the 3-bit MU flags. Every time the 3-bit MU flags are changed,
* the status flag \c kMU_FlagsUpdatingFlag asserts indicating the 3-bit MU flags are
* updating to the other side. After the 3-bit MU flags are updated, the status flag
* \c kMU_FlagsUpdatingFlag is cleared by hardware. During the flags updating period,
* the flags cannot be changed. This function waits for the MU status flag
* \c kMU_FlagsUpdatingFlag cleared and sets the 3-bit MU flags.
*
* @param base MU peripheral base address.
* @param flags The 3-bit MU flags to set.
*/
void MU_SetFlags(MU_Type *base, uint32_t flags);
/*!
* @brief Gets the current value of the 3-bit MU flags set by the other side.
*
* This function gets the current 3-bit MU flags on the current side.
*
* @param base MU peripheral base address.
* @return flags Current value of the 3-bit flags.
*/
static inline uint32_t MU_GetFlags(MU_Type *base)
{
return (base->SR & MU_SR_Fn_MASK) >> MU_SR_Fn_SHIFT;
}
/* @} */
/*!
* @name Status and Interrupt.
* @{
*/
/*!
* @brief Gets the MU status flags.
*
* This function returns the bit mask of the MU status flags. See _mu_status_flags.
*
* @code
* uint32_t flags;
* flags = MU_GetStatusFlags(base); Get all status flags.
* if (kMU_Tx0EmptyFlag & flags)
* {
* The TX0 register is empty. Message can be sent.
* MU_SendMsgNonBlocking(base, 0U, MSG0_VAL);
* }
* if (kMU_Tx1EmptyFlag & flags)
* {
* The TX1 register is empty. Message can be sent.
* MU_SendMsgNonBlocking(base, 1U, MSG1_VAL);
* }
* @endcode
*
* @param base MU peripheral base address.
* @return Bit mask of the MU status flags, see _mu_status_flags.
*/
static inline uint32_t MU_GetStatusFlags(MU_Type *base)
{
return (base->SR & (MU_SR_TEn_MASK | MU_SR_RFn_MASK | MU_SR_GIPn_MASK | MU_SR_EP_MASK | MU_SR_FUP_MASK
#if (defined(FSL_FEATURE_MU_HAS_SR_RS) && FSL_FEATURE_MU_HAS_SR_RS)
| MU_SR_RS_MASK
#endif
#if (defined(FSL_FEATURE_MU_HAS_RESET_ASSERT_INT) && FSL_FEATURE_MU_HAS_RESET_ASSERT_INT)
| MU_SR_RAIP_MASK
#endif
#if (defined(FSL_FEATURE_MU_HAS_RESET_DEASSERT_INT) && FSL_FEATURE_MU_HAS_RESET_ASSERT_INT)
| MU_SR_RDIP_MASK
#endif
#if (defined(FSL_FEATURE_MU_HAS_SR_MURIP) && FSL_FEATURE_MU_HAS_SR_MURIP)
| MU_SR_MURIP_MASK
#endif
#if (defined(FSL_FEATURE_MU_HAS_SR_HRIP) && FSL_FEATURE_MU_HAS_SR_HRIP)
| MU_SR_HRIP_MASK
#endif
));
}
/*!
* @brief Gets the MU IRQ pending status.
*
* This function returns the bit mask of the pending MU IRQs.
*
* @param base MU peripheral base address.
* @return Bit mask of the MU IRQs pending.
*/
static inline uint32_t MU_GetInterruptsPending(MU_Type *base)
{
uint32_t irqMask = base->CR & (MU_CR_GIRn_MASK | MU_CR_TIEn_MASK | MU_CR_RIEn_MASK);
return (base->SR & irqMask);
}
/*!
* @brief Clears the specific MU status flags.
*
* This function clears the specific MU status flags. The flags to clear should
* be passed in as bit mask. See _mu_status_flags.
*
* @code
* Clear general interrupt 0 and general interrupt 1 pending flags.
* MU_ClearStatusFlags(base, kMU_GenInt0Flag | kMU_GenInt1Flag);
* @endcode
*
* @param base MU peripheral base address.
* @param mask Bit mask of the MU status flags. See _mu_status_flags. The following
* flags are cleared by hardware, this function could not clear them.
* - kMU_Tx0EmptyFlag
* - kMU_Tx1EmptyFlag
* - kMU_Tx2EmptyFlag
* - kMU_Tx3EmptyFlag
* - kMU_Rx0FullFlag
* - kMU_Rx1FullFlag
* - kMU_Rx2FullFlag
* - kMU_Rx3FullFlag
* - kMU_EventPendingFlag
* - kMU_FlagsUpdatingFlag
* - kMU_OtherSideInResetFlag
*/
static inline void MU_ClearStatusFlags(MU_Type *base, uint32_t mask)
{
/* regMask is the mask of w1c status bits. */
uint32_t regMask = MU_SR_GIPn_MASK;
#if (defined(FSL_FEATURE_MU_HAS_RESET_ASSERT_INT) && FSL_FEATURE_MU_HAS_RESET_ASSERT_INT)
regMask |= MU_SR_RAIP_MASK;
#endif
#if (defined(FSL_FEATURE_MU_HAS_RESET_DEASSERT_INT) && FSL_FEATURE_MU_HAS_RESET_ASSERT_INT)
regMask |= MU_SR_RDIP_MASK;
#endif
#if (defined(FSL_FEATURE_MU_HAS_SR_MURIP) && FSL_FEATURE_MU_HAS_SR_MURIP)
regMask |= MU_SR_MURIP_MASK;
#endif
#if (defined(FSL_FEATURE_MU_HAS_SR_HRIP) && FSL_FEATURE_MU_HAS_SR_HRIP)
regMask |= MU_SR_HRIP_MASK;
#endif
base->SR = (mask & regMask);
}
/*!
* @brief Enables the specific MU interrupts.
*
* This function enables the specific MU interrupts. The interrupts to enable
* should be passed in as bit mask. See _mu_interrupt_enable.
*
* @code
* Enable general interrupt 0 and TX0 empty interrupt.
* MU_EnableInterrupts(base, kMU_GenInt0InterruptEnable | kMU_Tx0EmptyInterruptEnable);
* @endcode
*
* @param base MU peripheral base address.
* @param mask Bit mask of the MU interrupts. See _mu_interrupt_enable.
*/
static inline void MU_EnableInterrupts(MU_Type *base, uint32_t mask)
{
uint32_t reg = base->CR;
reg = (reg & ~(MU_CR_GIRn_MASK | MU_CR_NMI_MASK)) | mask;
base->CR = reg;
}
/*!
* @brief Disables the specific MU interrupts.
*
* This function disables the specific MU interrupts. The interrupts to disable
* should be passed in as bit mask. See _mu_interrupt_enable.
*
* @code
* Disable general interrupt 0 and TX0 empty interrupt.
* MU_DisableInterrupts(base, kMU_GenInt0InterruptEnable | kMU_Tx0EmptyInterruptEnable);
* @endcode
*
* @param base MU peripheral base address.
* @param mask Bit mask of the MU interrupts. See _mu_interrupt_enable.
*/
static inline void MU_DisableInterrupts(MU_Type *base, uint32_t mask)
{
uint32_t reg = base->CR;
reg &= ~((MU_CR_GIRn_MASK | MU_CR_NMI_MASK) | mask);
base->CR = reg;
}
/*!
* @brief Triggers interrupts to the other core.
*
* This function triggers the specific interrupts to the other core. The interrupts
* to trigger are passed in as bit mask. See \ref _mu_interrupt_trigger.
* The MU should not trigger an interrupt to the other core when the previous interrupt
* has not been processed by the other core. This function checks whether the
* previous interrupts have been processed. If not, it returns an error.
*
* @code
* if (kStatus_Success != MU_TriggerInterrupts(base, kMU_GenInt0InterruptTrigger | kMU_GenInt2InterruptTrigger))
* {
* Previous general purpose interrupt 0 or general purpose interrupt 2
* has not been processed by the other core.
* }
* @endcode
*
* @param base MU peripheral base address.
* @param mask Bit mask of the interrupts to trigger. See _mu_interrupt_trigger.
* @retval kStatus_Success Interrupts have been triggered successfully.
* @retval kStatus_Fail Previous interrupts have not been accepted.
*/
status_t MU_TriggerInterrupts(MU_Type *base, uint32_t mask);
#if !(defined(FSL_FEATURE_MU_NO_NMI) && FSL_FEATURE_MU_NO_NMI)
/*!
* @brief Clear non-maskable interrupt (NMI) sent by the other core.
*
* This function clears non-maskable interrupt (NMI) sent by the other core.
*
* @param base MU peripheral base address.
*/
static inline void MU_ClearNmi(MU_Type *base)
{
base->SR = MU_SR_NMIC_MASK;
}
#endif /* FSL_FEATURE_MU_NO_NMI */
/* @} */
/*!
* @name MU misc functions
* @{
*/
#if !(defined(FSL_FEATURE_MU_NO_RSTH) && FSL_FEATURE_MU_NO_RSTH)
/*!
* @brief Boots the core at B side.
*
* This function sets the B side core's boot configuration and releases the
* core from reset.
*
* @param base MU peripheral base address.
* @param mode Core B boot mode.
* @note Only MU side A can use this function.
*/
void MU_BootCoreB(MU_Type *base, mu_core_boot_mode_t mode);
/*!
* @brief Holds the core reset of B side.
*
* This function causes the core of B side to be held in reset following any reset event.
*
* @param base MU peripheral base address.
* @note Only A side could call this function.
*/
static inline void MU_HoldCoreBReset(MU_Type *base)
{
#if (defined(FSL_FEATURE_MU_HAS_CCR) && FSL_FEATURE_MU_HAS_CCR)
base->CCR |= MU_CCR_RSTH_MASK;
#else /* FSL_FEATURE_MU_HAS_CCR */
uint32_t reg = base->CR;
reg = (reg & ~(MU_CR_GIRn_MASK | MU_CR_NMI_MASK)) | MU_CR_RSTH_MASK;
base->CR = reg;
#endif /* FSL_FEATURE_MU_HAS_CCR */
}
/*!
* @brief Boots the other core.
*
* This function boots the other core with a boot configuration.
*
* @param base MU peripheral base address.
* @param mode The other core boot mode.
*/
void MU_BootOtherCore(MU_Type *base, mu_core_boot_mode_t mode);
/*!
* @brief Holds the other core reset.
*
* This function causes the other core to be held in reset following any reset event.
*
* @param base MU peripheral base address.
*/
static inline void MU_HoldOtherCoreReset(MU_Type *base)
{
/*
* MU_HoldOtherCoreReset and MU_HoldCoreBReset are the same, MU_HoldCoreBReset
* is kept for compatible with older platforms.
*/
MU_HoldCoreBReset(base);
}
#endif /* FSL_FEATURE_MU_NO_RSTH */
#if !(defined(FSL_FEATURE_MU_NO_MUR) && FSL_FEATURE_MU_NO_MUR)
/*!
* @brief Resets the MU for both A side and B side.
*
* This function resets the MU for both A side and B side. Before reset, it is
* recommended to interrupt processor B, because this function may affect the
* ongoing processor B programs.
*
* @param base MU peripheral base address.
* @note For some platforms, only MU side A could use this function, check
* reference manual for details.
*/
static inline void MU_ResetBothSides(MU_Type *base)
{
uint32_t reg = base->CR;
reg = (reg & ~(MU_CR_GIRn_MASK | MU_CR_NMI_MASK)) | MU_CR_MUR_MASK;
base->CR = reg;
#if (defined(FSL_FEATURE_MU_HAS_SR_RS) && FSL_FEATURE_MU_HAS_SR_RS)
/* Wait for the other side out of reset. */
while (0U != (base->SR & MU_SR_RS_MASK))
{
}
#endif /* FSL_FEATURE_MU_HAS_SR_RS */
}
#endif /* FSL_FEATURE_MU_NO_MUR */
#if (defined(FSL_FEATURE_MU_HAS_HRM) && FSL_FEATURE_MU_HAS_HRM)
/*!
* @brief Mask hardware reset by the other core.
*
* The other core could call MU_HardwareResetOtherCore() to reset current core.
* To mask the reset, call this function and pass in true.
*
* @param base MU peripheral base address.
* @param mask Pass true to mask the hardware reset, pass false to unmask it.
*/
static inline void MU_MaskHardwareReset(MU_Type *base, bool mask)
{
#if (defined(FSL_FEATURE_MU_HAS_CCR) && FSL_FEATURE_MU_HAS_CCR)
if (mask)
{
base->CCR |= MU_CCR_HRM_MASK;
}
else
{
base->CCR &= ~MU_CCR_HRM_MASK;
}
#else /* FSL_FEATURE_MU_HAS_CCR */
if (mask)
{
base->CR |= MU_CR_HRM_MASK;
}
else
{
base->CR &= ~MU_CR_HRM_MASK;
}
#endif /* FSL_FEATURE_MU_HAS_CCR */
}
#endif /* FSL_FEATURE_MU_HAS_HRM */
#if !(defined(FSL_FEATURE_MU_NO_HR) && FSL_FEATURE_MU_NO_HR)
/*!
* @brief Hardware reset the other core.
*
* This function resets the other core, the other core could mask the
* hardware reset by calling MU_MaskHardwareReset. The hardware reset
* mask feature is only available for some platforms.
* This function could be used together with MU_BootOtherCore to control the
* other core reset workflow.
*
* Example 1: Reset the other core, and no hold reset
* @code
* MU_HardwareResetOtherCore(MU_A, true, false, bootMode);
* @endcode
* In this example, the core at MU side B will reset with the specified boot mode.
*
* Example 2: Reset the other core and hold it, then boot the other core later.
* @code
* Here the other core enters reset, and the reset is hold
* MU_HardwareResetOtherCore(MU_A, true, true, modeDontCare);
* Current core boot the other core when necessary.
* MU_BootOtherCore(MU_A, bootMode);
* @endcode
*
* @param base MU peripheral base address.
* @param waitReset Wait the other core enters reset.
* - true: Wait until the other core enters reset, if the other
* core has masked the hardware reset, then this function will
* be blocked.
* - false: Don't wait the reset.
* @param holdReset Hold the other core reset or not.
* - true: Hold the other core in reset, this function returns
* directly when the other core enters reset.
* - false: Don't hold the other core in reset, this function
* waits until the other core out of reset.
* @param bootMode Boot mode of the other core, if @p holdReset is true, this
* parameter is useless.
*/
void MU_HardwareResetOtherCore(MU_Type *base, bool waitReset, bool holdReset, mu_core_boot_mode_t bootMode);
#endif /* FSL_FEATURE_MU_NO_HR */
#if !(defined(FSL_FEATURE_MU_NO_CLKE) && FSL_FEATURE_MU_NO_CLKE)
/*!
* @brief Enables or disables the clock on the other core.
*
* This function enables or disables the platform clock on the other core when
* that core enters a stop mode. If disabled, the platform clock for the other
* core is disabled when it enters stop mode. If enabled, the platform clock
* keeps running on the other core in stop mode, until this core also enters
* stop mode.
*
* @param base MU peripheral base address.
* @param enable Enable or disable the clock on the other core.
*/
static inline void MU_SetClockOnOtherCoreEnable(MU_Type *base, bool enable)
{
#if (defined(FSL_FEATURE_MU_HAS_CCR) && FSL_FEATURE_MU_HAS_CCR)
if (enable)
{
base->CCR |= MU_CCR_CLKE_MASK;
}
else
{
base->CCR &= ~MU_CCR_CLKE_MASK;
}
#else /* FSL_FEATURE_MU_HAS_CCR */
uint32_t reg = base->CR;
reg &= ~(MU_CR_GIRn_MASK | MU_CR_NMI_MASK);
if (enable)
{
reg |= MU_CR_CLKE_MASK;
}
else
{
reg &= ~MU_CR_CLKE_MASK;
}
base->CR = reg;
#endif /* FSL_FEATURE_MU_HAS_CCR */
}
#endif /* FSL_FEATURE_MU_NO_CLKE */
#if !(defined(FSL_FEATURE_MU_NO_PM) && FSL_FEATURE_MU_NO_PM)
/*!
* @brief Gets the power mode of the other core.
*
* This function gets the power mode of the other core.
*
* @param base MU peripheral base address.
* @return Power mode of the other core.
*/
static inline mu_power_mode_t MU_GetOtherCorePowerMode(MU_Type *base)
{
uint32_t ret = (base->SR & MU_SR_PM_MASK) >> MU_SR_PM_SHIFT;
return (mu_power_mode_t)ret;
}
#endif /* FSL_FEATURE_MU_NO_PM */
/* @} */
#if defined(__cplusplus)
}
#endif /*_cplusplus*/
/*@}*/
#endif /* _FSL_MU_H_*/

View File

@ -0,0 +1,417 @@
/*
* Copyright 2017-2020 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_RDC_H_
#define _FSL_RDC_H_
#include "fsl_common.h"
/*!
* @addtogroup rdc
* @{
*/
/******************************************************************************
* Definitions
*****************************************************************************/
#define FSL_RDC_DRIVER_VERSION (MAKE_VERSION(2, 1, 1))
#define RDC_ACCESS_POLICY(domainID, policy) (uint16_t)((uint16_t)(policy) << ((domainID)*2U))
/*!
* @brief RDC hardware configuration.
*/
typedef struct _rdc_hardware_config
{
uint32_t domainNumber : 4; /*!< Number of domains. */
uint32_t masterNumber : 8; /*!< Number of bus masters. */
uint32_t periphNumber : 8; /*!< Number of peripherals. */
uint32_t memNumber : 8; /*!< Number of memory regions. */
uint32_t : 4;
} rdc_hardware_config_t;
/*!
* @brief RDC interrupts
*/
enum _rdc_interrupts
{
kRDC_RestoreCompleteInterrupt = RDC_INTCTRL_RCI_EN_MASK,
/*!< Interrupt generated when the RDC has completed restoring state to a recently re-powered memory regions. */
};
/*!
* @brief RDC status
*/
enum _rdc_flags
{
kRDC_PowerDownDomainOn = RDC_STAT_PDS_MASK, /*!< Power down domain is ON. */
};
/*!
* @brief Master domain assignment.
*/
typedef struct _rdc_domain_assignment
{
uint32_t domainId : 2U; /*!< Domain ID. */
uint32_t : 29U; /*!< Reserved. */
uint32_t lock : 1U; /*!< Lock the domain assignment. */
} rdc_domain_assignment_t;
/*!
* @brief Access permission policy.
*/
enum _rdc_access_policy
{
kRDC_NoAccess = 0, /*!< Could not read or write. */
kRDC_WriteOnly = 1, /*!< Write only. */
kRDC_ReadOnly = 2, /*!< Read only. */
kRDC_ReadWrite = 3, /*!< Read and write. */
};
/*!
* @brief Peripheral domain access permission configuration.
*/
typedef struct _rdc_periph_access_config
{
rdc_periph_t periph; /*!< Peripheral name. */
bool lock; /*!< Lock the permission until reset. */
bool enableSema; /*!< Enable semaphore or not, when enabled, master should
call @ref RDC_SEMA42_Lock to lock the semaphore gate
accordingly before access the peripheral. */
uint16_t policy; /*!< Access policy. */
} rdc_periph_access_config_t;
/*!
* @brief Memory region domain access control configuration.
*
* Note that when setting the @ref baseAddress and @ref endAddress,
* should be aligned to the region resolution, see rdc_mem_t
* definitions.
*/
typedef struct _rdc_mem_access_config
{
rdc_mem_t mem; /*!< Memory region descriptor name. */
bool lock; /*!< Lock the configuration. */
uint64_t baseAddress; /*!< Start address of the memory region. */
uint64_t endAddress; /*!< End address of the memory region. */
uint16_t policy; /*!< Access policy. */
} rdc_mem_access_config_t;
/*!
* @brief Memory region access violation status.
*/
typedef struct _rdc_mem_status
{
bool hasViolation; /*!< Violating happens or not. */
uint8_t domainID; /*!< Violating Domain ID. */
uint64_t address; /*!< Violating Address. */
} rdc_mem_status_t;
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @brief Initializes the RDC module.
*
* This function enables the RDC clock.
*
* @param base RDC peripheral base address.
*/
void RDC_Init(RDC_Type *base);
/*!
* @brief De-initializes the RDC module.
*
* This function disables the RDC clock.
*
* @param base RDC peripheral base address.
*/
void RDC_Deinit(RDC_Type *base);
/*!
* @brief Gets the RDC hardware configuration.
*
* This function gets the RDC hardware configurations, including number of bus
* masters, number of domains, number of memory regions and number of peripherals.
*
* @param base RDC peripheral base address.
* @param config Pointer to the structure to get the configuration.
*/
void RDC_GetHardwareConfig(RDC_Type *base, rdc_hardware_config_t *config);
/*!
* @brief Enable interrupts.
*
* @param base RDC peripheral base address.
* @param mask Interrupts to enable, it is OR'ed value of enum @ref _rdc_interrupts.
*/
static inline void RDC_EnableInterrupts(RDC_Type *base, uint32_t mask)
{
base->INTCTRL |= mask;
}
/*!
* @brief Disable interrupts.
*
* @param base RDC peripheral base address.
* @param mask Interrupts to disable, it is OR'ed value of enum @ref _rdc_interrupts.
*/
static inline void RDC_DisableInterrupts(RDC_Type *base, uint32_t mask)
{
base->INTCTRL &= ~mask;
}
/*!
* @brief Get the interrupt pending status.
*
* @param base RDC peripheral base address.
* @return Interrupts pending status, it is OR'ed value of enum @ref _rdc_interrupts.
*/
static inline uint32_t RDC_GetInterruptStatus(RDC_Type *base)
{
return base->INTSTAT;
}
/*!
* @brief Clear interrupt pending status.
*
* @param base RDC peripheral base address.
* @param mask Status to clear, it is OR'ed value of enum @ref _rdc_interrupts.
*/
static inline void RDC_ClearInterruptStatus(RDC_Type *base, uint32_t mask)
{
base->INTSTAT = mask;
}
/*!
* @brief Get RDC status.
*
* @param base RDC peripheral base address.
* @return mask RDC status, it is OR'ed value of enum @ref _rdc_flags.
*/
static inline uint32_t RDC_GetStatus(RDC_Type *base)
{
return base->STAT;
}
/*!
* @brief Clear RDC status.
*
* @param base RDC peripheral base address.
* @param mask RDC status to clear, it is OR'ed value of enum @ref _rdc_flags.
*/
static inline void RDC_ClearStatus(RDC_Type *base, uint32_t mask)
{
base->STAT = mask;
}
/*!
* @brief Set master domain assignment
*
* @param base RDC peripheral base address.
* @param master Which master to set.
* @param domainAssignment Pointer to the assignment.
*/
void RDC_SetMasterDomainAssignment(RDC_Type *base,
rdc_master_t master,
const rdc_domain_assignment_t *domainAssignment);
/*!
* @brief Get default master domain assignment
*
* The default configuration is:
* @code
assignment->domainId = 0U;
assignment->lock = 0U;
@endcode
*
* @param domainAssignment Pointer to the assignment.
*/
void RDC_GetDefaultMasterDomainAssignment(rdc_domain_assignment_t *domainAssignment);
/*!
* @brief Lock master domain assignment
*
* Once locked, it could not be unlocked until next reset.
*
* @param base RDC peripheral base address.
* @param master Which master to lock.
*/
static inline void RDC_LockMasterDomainAssignment(RDC_Type *base, rdc_master_t master)
{
assert((uint32_t)master < RDC_MDA_COUNT);
base->MDA[master] |= RDC_MDA_LCK_MASK;
__DSB();
}
/*!
* @brief Set peripheral access policy.
*
* @param base RDC peripheral base address.
* @param config Pointer to the policy configuration.
*/
void RDC_SetPeriphAccessConfig(RDC_Type *base, const rdc_periph_access_config_t *config);
/*!
* @brief Get default peripheral access policy.
*
* The default configuration is:
* @code
config->lock = false;
config->enableSema = false;
config->policy = RDC_ACCESS_POLICY(0, kRDC_ReadWrite) |
RDC_ACCESS_POLICY(1, kRDC_ReadWrite) |
RDC_ACCESS_POLICY(2, kRDC_ReadWrite) |
RDC_ACCESS_POLICY(3, kRDC_ReadWrite);
@endcode
*
* @param config Pointer to the policy configuration.
*/
void RDC_GetDefaultPeriphAccessConfig(rdc_periph_access_config_t *config);
/*!
* @brief Lock peripheral access policy configuration.
*
* Once locked, it could not be unlocked until reset.
*
* @param base RDC peripheral base address.
* @param periph Which peripheral to lock.
*/
static inline void RDC_LockPeriphAccessConfig(RDC_Type *base, rdc_periph_t periph)
{
assert((uint32_t)periph < RDC_PDAP_COUNT);
base->PDAP[periph] |= RDC_PDAP_LCK_MASK;
__DSB();
}
/*!
* @brief Set memory region access policy.
*
* Note that when setting the baseAddress and endAddress in @p config,
* should be aligned to the region resolution, see rdc_mem_t
* definitions.
*
* @param base RDC peripheral base address.
* @param config Pointer to the policy configuration.
*/
void RDC_SetMemAccessConfig(RDC_Type *base, const rdc_mem_access_config_t *config);
/*!
* @brief Get default memory region access policy.
*
* The default configuration is:
* @code
config->lock = false;
config->baseAddress = 0;
config->endAddress = 0;
config->policy = RDC_ACCESS_POLICY(0, kRDC_ReadWrite) |
RDC_ACCESS_POLICY(1, kRDC_ReadWrite) |
RDC_ACCESS_POLICY(2, kRDC_ReadWrite) |
RDC_ACCESS_POLICY(3, kRDC_ReadWrite);
@endcode
*
* @param config Pointer to the policy configuration.
*/
void RDC_GetDefaultMemAccessConfig(rdc_mem_access_config_t *config);
/*!
* @brief Lock memory access policy configuration.
*
* Once locked, it could not be unlocked until reset. After locked, you can
* only call @ref RDC_SetMemAccessValid to enable the configuration, but can not
* disable it or change other settings.
*
* @param base RDC peripheral base address.
* @param mem Which memory region to lock.
*/
static inline void RDC_LockMemAccessConfig(RDC_Type *base, rdc_mem_t mem)
{
assert((uint32_t)mem < RDC_MRC_COUNT);
base->MR[mem].MRC |= RDC_MRC_LCK_MASK;
__DSB();
}
/*!
* @brief Enable or disable memory access policy configuration.
*
* @param base RDC peripheral base address.
* @param mem Which memory region to operate.
* @param valid Pass in true to valid, false to invalid.
*/
static inline void RDC_SetMemAccessValid(RDC_Type *base, rdc_mem_t mem, bool valid)
{
assert((uint32_t)mem < RDC_MRC_COUNT);
if (valid)
{
base->MR[mem].MRC |= RDC_MRC_ENA_MASK;
}
else
{
base->MR[mem].MRC &= ~RDC_MRC_ENA_MASK;
}
__DSB();
}
/*!
* @brief Get the memory region violation status.
*
* The first access violation is captured. Subsequent violations are ignored
* until the status register is cleared. Contents are cleared upon reading the
* register. Clearing of contents occurs only when the status is read by the
* memory region's associated domain ID(s).
*
* @param base RDC peripheral base address.
* @param mem Which memory region to get.
* @param status The returned status.
*/
void RDC_GetMemViolationStatus(RDC_Type *base, rdc_mem_t mem, rdc_mem_status_t *status);
/*!
* @brief Clear the memory region violation flag.
*
* @param base RDC peripheral base address.
* @param mem Which memory region to clear.
*/
static inline void RDC_ClearMemViolationFlag(RDC_Type *base, rdc_mem_t mem)
{
assert((uint32_t)mem < RDC_MRC_COUNT);
base->MR[mem].MRVS = RDC_MRVS_AD_MASK;
}
/*!
* @brief Gets the domain ID of the current bus master.
*
* This function returns the domain ID of the current bus master.
*
* @param base RDC peripheral base address.
* @return Domain ID of current bus master.
*/
static inline uint8_t RDC_GetCurrentMasterDomainId(RDC_Type *base)
{
return (uint8_t)((base->STAT & RDC_STAT_DID_MASK) >> RDC_STAT_DID_SHIFT);
}
#if defined(__cplusplus)
}
#endif
/*!
* @}
*/
#endif /* _FSL_RDC_H_ */

View File

@ -0,0 +1,902 @@
/*
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016-2020 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_UART_H_
#define _FSL_UART_H_
#include "fsl_common.h"
/*!
* @addtogroup uart_driver
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @name Driver version */
/*@{*/
/*! @brief UART driver version. */
#define FSL_UART_DRIVER_VERSION (MAKE_VERSION(2, 2, 0))
/*@}*/
/*! @brief Retry times for waiting flag. */
#ifndef UART_RETRY_TIMES
#define UART_RETRY_TIMES 0U /* Defining to zero means to keep waiting for the flag until it is assert/deassert. */
#endif
/*! @brief Error codes for the UART driver. */
enum
{
kStatus_UART_TxBusy = MAKE_STATUS(kStatusGroup_IUART, 0), /*!< Transmitter is busy. */
kStatus_UART_RxBusy = MAKE_STATUS(kStatusGroup_IUART, 1), /*!< Receiver is busy. */
kStatus_UART_TxIdle = MAKE_STATUS(kStatusGroup_IUART, 2), /*!< UART transmitter is idle. */
kStatus_UART_RxIdle = MAKE_STATUS(kStatusGroup_IUART, 3), /*!< UART receiver is idle. */
kStatus_UART_TxWatermarkTooLarge = MAKE_STATUS(kStatusGroup_IUART, 4), /*!< TX FIFO watermark too large */
kStatus_UART_RxWatermarkTooLarge = MAKE_STATUS(kStatusGroup_IUART, 5), /*!< RX FIFO watermark too large */
kStatus_UART_FlagCannotClearManually =
MAKE_STATUS(kStatusGroup_IUART, 6), /*!< UART flag can't be manually cleared. */
kStatus_UART_Error = MAKE_STATUS(kStatusGroup_IUART, 7), /*!< Error happens on UART. */
kStatus_UART_RxRingBufferOverrun = MAKE_STATUS(kStatusGroup_IUART, 8), /*!< UART RX software ring buffer overrun. */
kStatus_UART_RxHardwareOverrun = MAKE_STATUS(kStatusGroup_IUART, 9), /*!< UART RX receiver overrun. */
kStatus_UART_NoiseError = MAKE_STATUS(kStatusGroup_IUART, 10), /*!< UART noise error. */
kStatus_UART_FramingError = MAKE_STATUS(kStatusGroup_IUART, 11), /*!< UART framing error. */
kStatus_UART_ParityError = MAKE_STATUS(kStatusGroup_IUART, 12), /*!< UART parity error. */
kStatus_UART_BaudrateNotSupport =
MAKE_STATUS(kStatusGroup_IUART, 13), /*!< Baudrate is not support in current clock source */
kStatus_UART_BreakDetect = MAKE_STATUS(kStatusGroup_IUART, 14), /*!< Receiver detect BREAK signal */
kStatus_UART_Timeout = MAKE_STATUS(kStatusGroup_IUART, 15), /*!< UART times out. */
};
/*! @brief UART data bits count. */
typedef enum _uart_data_bits
{
kUART_SevenDataBits = 0x0U, /*!< Seven data bit */
kUART_EightDataBits = 0x1U, /*!< Eight data bit */
} uart_data_bits_t;
/*! @brief UART parity mode. */
typedef enum _uart_parity_mode
{
kUART_ParityDisabled = 0x0U, /*!< Parity disabled */
kUART_ParityEven = 0x2U, /*!< Even error check is selected */
kUART_ParityOdd = 0x3U, /*!< Odd error check is selected */
} uart_parity_mode_t;
/*! @brief UART stop bit count. */
typedef enum _uart_stop_bit_count
{
kUART_OneStopBit = 0x0U, /*!< One stop bit */
kUART_TwoStopBit = 0x1U, /*!< Two stop bits */
} uart_stop_bit_count_t;
/*! @brief UART idle condition detect. */
typedef enum _uart_idle_condition
{
kUART_IdleFor4Frames = 0x0U, /*!< Idle for more than 4 frames */
kUART_IdleFor8Frames = 0x1U, /*!< Idle for more than 8 frames */
kUART_IdleFor16Frames = 0x2U, /*!< Idle for more than 16 frames */
kUART_IdleFor32Frames = 0x3U, /*!< Idle for more than 32 frames */
} uart_idle_condition_t;
/*! @brief This structure contains the settings for all of the UART interrupt configurations. */
enum _uart_interrupt_enable
{
kUART_AutoBaudEnable = 0x1U, /* !< Automatic baud rate detection Interrupt Enable. */
kUART_TxReadyEnable = (0X1U << 1), /* !< transmitter ready Interrupt Enable. */
kUART_IdleEnable = (0x1U << 2), /* !< IDLE Interrupt Enable. */
kUART_RxReadyEnable = (0x1U << 3), /* !< Receiver Ready Interrupt Enable. */
kUART_TxEmptyEnable = (0x1U << 4), /* !< Transmitter Empty Interrupt Enable. */
kUART_RtsDeltaEnable = (0x1U << 5), /* !< RTS Delta Interrupt Enable. */
kUART_EscapeEnable = (0x1U << 8), /* !< Escape Sequence Interrupt Enable. */
kUART_RtsEnable = (0x1U << 9), /* !< Request to Send Interrupt Enable. */
kUART_AgingTimerEnable = (0x1U << 10), /* !< Aging Timer Interrupt Enable. */
kUART_DtrEnable = (0x1U << 12), /* !< Data Terminal Ready Interrupt Enable. */
kUART_ParityErrorEnable = (0x1U << 13), /* !< Parity Error Interrupt Enable. */
kUART_FrameErrorEnable = (0x1U << 14), /* !< Frame Error Interrupt Enable. */
kUART_DcdEnable = (0x1U << 15), /* !< Data Carrier Detect Interrupt Enable. */
kUART_RiEnable = (0x1U << 16), /* !< Ring Indicator Interrupt Enable. */
kUART_RxDsEnable = (0x1U << 17), /* !< Receive Status Interrupt Enable. */
kUART_tAirWakeEnable = (0x1U << 18), /* !< Asynchronous IR WAKE Interrupt Enable. */
kUART_AwakeEnable = (0x1U << 19), /* !< Asynchronous WAKE Interrupt Enable. */
kUART_DtrDeltaEnable = (0x1U << 20), /* !< Data Terminal Ready Delta Interrupt Enable. */
kUART_AutoBaudCntEnable = (0x1U << 21), /* !< Auto-baud Counter Interrupt Enable. */
kUART_IrEnable = (0X1U << 24), /* !< Serial Infrared Interrupt Enable. */
kUART_WakeEnable = (0X1U << 25), /* !< WAKE Interrupt Enable. */
kUART_TxCompleteEnable = (0X1U << 26), /* !< TransmitComplete Interrupt Enable. */
kUART_BreakDetectEnable = (0X1U << 27), /* !< BREAK Condition Detected Interrupt Enable. */
kUART_RxOverrunEnable = (0X1U << 28), /* !< Receiver Overrun Interrupt Enable. */
kUART_RxDataReadyEnable = (0X1U << 29), /* !< Receive Data Ready Interrupt Enable. */
kUART_RxDmaIdleEnable = (0X1U << 30), /* !< Receive DMA IDLE detect Interrupt Enable. */
kUART_AllInterruptsEnable =
kUART_AutoBaudEnable | kUART_TxReadyEnable | kUART_IdleEnable | kUART_RxReadyEnable | kUART_TxEmptyEnable |
kUART_RtsDeltaEnable | kUART_EscapeEnable | kUART_RtsEnable | kUART_AgingTimerEnable | kUART_DtrEnable |
kUART_ParityErrorEnable | kUART_FrameErrorEnable | kUART_DcdEnable | kUART_RiEnable | kUART_RxDsEnable |
kUART_tAirWakeEnable | kUART_AwakeEnable | kUART_DtrDeltaEnable | kUART_AutoBaudCntEnable | kUART_IrEnable |
kUART_WakeEnable | kUART_TxCompleteEnable | kUART_BreakDetectEnable | kUART_RxOverrunEnable |
kUART_RxDataReadyEnable | kUART_RxDmaIdleEnable,
};
/*!
* @brief UART status flags.
*
* This provides constants for the UART status flags for use in the UART functions.
*/
enum
{
kUART_RxCharReadyFlag = 0x0000000FU, /*!< Rx Character Ready Flag. */
kUART_RxErrorFlag = 0x0000000EU, /*!< Rx Error Detect Flag. */
kUART_RxOverrunErrorFlag = 0x0000000DU, /*!< Rx Overrun Flag. */
kUART_RxFrameErrorFlag = 0x0000000CU, /*!< Rx Frame Error Flag. */
kUART_RxBreakDetectFlag = 0x0000000BU, /*!< Rx Break Detect Flag. */
kUART_RxParityErrorFlag = 0x0000000AU, /*!< Rx Parity Error Flag. */
kUART_ParityErrorFlag = 0x0094000FU, /*!< Parity Error Interrupt Flag. */
kUART_RtsStatusFlag = 0x0094000EU, /*!< RTS_B Pin Status Flag. */
kUART_TxReadyFlag = 0x0094000DU, /*!< Transmitter Ready Interrupt/DMA Flag. */
kUART_RtsDeltaFlag = 0x0094000CU, /*!< RTS Delta Flag. */
kUART_EscapeFlag = 0x0094000BU, /*!< Escape Sequence Interrupt Flag. */
kUART_FrameErrorFlag = 0x0094000AU, /*!< Frame Error Interrupt Flag. */
kUART_RxReadyFlag = 0x00940009U, /*!< Receiver Ready Interrupt/DMA Flag. */
kUART_AgingTimerFlag = 0x00940008U, /*!< Aging Timer Interrupt Flag. */
kUART_DtrDeltaFlag = 0x00940007U, /*!< DTR Delta Flag. */
kUART_RxDsFlag = 0x00940006U, /*!< Receiver IDLE Interrupt Flag. */
kUART_tAirWakeFlag = 0x00940005U, /*!< Asynchronous IR WAKE Interrupt Flag. */
kUART_AwakeFlag = 0x00940004U, /*!< Asynchronous WAKE Interrupt Flag. */
kUART_Rs485SlaveAddrMatchFlag = 0x00940003U, /*!< RS-485 Slave Address Detected Interrupt Flag. */
kUART_AutoBaudFlag = 0x0098000FU, /*!< Automatic Baud Rate Detect Complete Flag. */
kUART_TxEmptyFlag = 0x0098000EU, /*!< Transmit Buffer FIFO Empty. */
kUART_DtrFlag = 0x0098000DU, /*!< DTR edge triggered interrupt flag. */
kUART_IdleFlag = 0x0098000CU, /*!< Idle Condition Flag. */
kUART_AutoBaudCntStopFlag = 0x0098000BU, /*!< Auto-baud Counter Stopped Flag. */
kUART_RiDeltaFlag = 0x0098000AU, /*!< Ring Indicator Delta Flag. */
kUART_RiFlag = 0x00980009U, /*!< Ring Indicator Input Flag. */
kUART_IrFlag = 0x00980008U, /*!< Serial Infrared Interrupt Flag. */
kUART_WakeFlag = 0x00980007U, /*!< Wake Flag. */
kUART_DcdDeltaFlag = 0x00980006U, /*!< Data Carrier Detect Delta Flag. */
kUART_DcdFlag = 0x00980005U, /*!< Data Carrier Detect Input Flag. */
kUART_RtsFlag = 0x00980004U, /*!< RTS Edge Triggered Interrupt Flag. */
kUART_TxCompleteFlag = 0x00980003U, /*!< Transmitter Complete Flag. */
kUART_BreakDetectFlag = 0x00980002U, /*!< BREAK Condition Detected Flag. */
kUART_RxOverrunFlag = 0x00980001U, /*!< Overrun Error Flag. */
kUART_RxDataReadyFlag = 0x00980000U, /*!< Receive Data Ready Flag. */
};
/*! @brief UART configuration structure. */
typedef struct _uart_config
{
uint32_t baudRate_Bps; /*!< UART baud rate. */
uart_parity_mode_t parityMode; /*!< Parity error check mode of this module. */
uart_data_bits_t dataBitsCount; /*!< Data bits count, eight (default), seven */
uart_stop_bit_count_t stopBitCount; /*!< Number of stop bits in one frame. */
uint8_t txFifoWatermark; /*!< TX FIFO watermark */
uint8_t rxFifoWatermark; /*!< RX FIFO watermark */
uint8_t rxRTSWatermark; /*!< RX RTS watermark, RX FIFO data count being larger than this triggers RTS deassertion */
bool enableAutoBaudRate; /*!< Enable automatic baud rate detection */
bool enableTx; /*!< Enable TX */
bool enableRx; /*!< Enable RX */
bool enableRxRTS; /*!< RX RTS enable */
bool enableTxCTS; /*!< TX CTS enable */
} uart_config_t;
/*! @brief UART transfer structure. */
typedef struct _uart_transfer
{
uint8_t *data; /*!< The buffer of data to be transfer.*/
size_t dataSize; /*!< The byte count to be transfer. */
} uart_transfer_t;
/*! @brief Forward declaration of the handle typedef. */
typedef struct _uart_handle uart_handle_t;
/*! @brief UART transfer callback function. */
typedef void (*uart_transfer_callback_t)(UART_Type *base, uart_handle_t *handle, status_t status, void *userData);
/*! @brief UART handle structure. */
struct _uart_handle
{
uint8_t *volatile txData; /*!< Address of remaining data to send. */
volatile size_t txDataSize; /*!< Size of the remaining data to send. */
size_t txDataSizeAll; /*!< Size of the data to send out. */
uint8_t *volatile rxData; /*!< Address of remaining data to receive. */
volatile size_t rxDataSize; /*!< Size of the remaining data to receive. */
size_t rxDataSizeAll; /*!< Size of the data to receive. */
uint8_t *rxRingBuffer; /*!< Start address of the receiver ring buffer. */
size_t rxRingBufferSize; /*!< Size of the ring buffer. */
volatile uint16_t rxRingBufferHead; /*!< Index for the driver to store received data into ring buffer. */
volatile uint16_t rxRingBufferTail; /*!< Index for the user to get data from the ring buffer. */
uart_transfer_callback_t callback; /*!< Callback function. */
void *userData; /*!< UART callback function parameter.*/
volatile uint8_t txState; /*!< TX transfer state. */
volatile uint8_t rxState; /*!< RX transfer state */
};
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @brief Get the UART instance from peripheral base address.
*
* @param base UART peripheral base address.
* @return UART instance.
*/
uint32_t UART_GetInstance(UART_Type *base);
/*!
* @name Software Reset
* @{
*/
/*!
* @brief Resets the UART using software.
*
* This function resets the transmit and receive state machines, all FIFOs and register
* USR1, USR2, UBIR, UBMR, UBRC , URXD, UTXD and UTS[6-3]
*
* @param base UART peripheral base address.
*/
static inline void UART_SoftwareReset(UART_Type *base)
{
base->UCR2 &= ~UART_UCR2_SRST_MASK;
while ((base->UCR2 & UART_UCR2_SRST_MASK) == 0U)
{
}
}
/* @} */
/*!
* @name Initialization and deinitialization
* @{
*/
/*!
* @brief Initializes an UART instance with the user configuration structure and the peripheral clock.
*
* This function configures the UART module with user-defined settings. Call the UART_GetDefaultConfig() function
* to configure the configuration structure and get the default configuration.
* The example below shows how to use this API to configure the UART.
* @code
* uart_config_t uartConfig;
* uartConfig.baudRate_Bps = 115200U;
* uartConfig.parityMode = kUART_ParityDisabled;
* uartConfig.dataBitsCount = kUART_EightDataBits;
* uartConfig.stopBitCount = kUART_OneStopBit;
* uartConfig.txFifoWatermark = 2;
* uartConfig.rxFifoWatermark = 1;
* uartConfig.enableAutoBaudrate = false;
* uartConfig.enableTx = true;
* uartConfig.enableRx = true;
* UART_Init(UART1, &uartConfig, 24000000U);
* @endcode
*
* @param base UART peripheral base address.
* @param config Pointer to a user-defined configuration structure.
* @param srcClock_Hz UART clock source frequency in HZ.
* @retval kStatus_Success UART initialize succeed
*/
status_t UART_Init(UART_Type *base, const uart_config_t *config, uint32_t srcClock_Hz);
/*!
* @brief Deinitializes a UART instance.
*
* This function waits for transmit to complete, disables TX and RX, and disables the UART clock.
*
* @param base UART peripheral base address.
*/
void UART_Deinit(UART_Type *base);
/*!l
* @brief Gets the default configuration structure.
*
* This function initializes the UART configuration structure to a default value. The default
* values are:
* uartConfig->baudRate_Bps = 115200U;
* uartConfig->parityMode = kUART_ParityDisabled;
* uartConfig->dataBitsCount = kUART_EightDataBits;
* uartConfig->stopBitCount = kUART_OneStopBit;
* uartConfig->txFifoWatermark = 2;
* uartConfig->rxFifoWatermark = 1;
* uartConfig->enableAutoBaudrate = flase;
* uartConfig->enableTx = false;
* uartConfig->enableRx = false;
*
* @param config Pointer to a configuration structure.
*/
void UART_GetDefaultConfig(uart_config_t *config);
/*!
* @brief Sets the UART instance baud rate.
*
* This function configures the UART module baud rate. This function is used to update
* the UART module baud rate after the UART module is initialized by the UART_Init.
* @code
* UART_SetBaudRate(UART1, 115200U, 20000000U);
* @endcode
*
* @param base UART peripheral base address.
* @param baudRate_Bps UART baudrate to be set.
* @param srcClock_Hz UART clock source frequency in Hz.
* @retval kStatus_UART_BaudrateNotSupport Baudrate is not support in the current clock source.
* @retval kStatus_Success Set baudrate succeeded.
*/
status_t UART_SetBaudRate(UART_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz);
/*!
* @brief This function is used to Enable the UART Module.
*
* @param base UART base pointer.
*/
static inline void UART_Enable(UART_Type *base)
{
base->UCR1 |= UART_UCR1_UARTEN_MASK;
}
/*!
* @brief This function is used to configure the IDLE line condition.
*
* @param base UART base pointer.
* @param condition IDLE line detect condition of the enumerators in @ref uart_idle_condition_t.
*/
static inline void UART_SetIdleCondition(UART_Type *base, uart_idle_condition_t condition)
{
base->UCR1 = (base->UCR1 & ~UART_UCR1_ICD_MASK) | UART_UCR1_ICD(condition);
}
/*!
* @brief This function is used to Disable the UART Module.
*
* @param base UART base pointer.
*/
static inline void UART_Disable(UART_Type *base)
{
base->UCR1 &= ~UART_UCR1_UARTEN_MASK;
}
/* @} */
/*!
* @name Status
* @{
*/
/*!
* @brief This function is used to get the current status of specific
* UART status flag(including interrupt flag). The available
* status flag can be select from uart_status_flag_t enumeration.
*
* @param base UART base pointer.
* @param flag Status flag to check.
* @retval current state of corresponding status flag.
*/
bool UART_GetStatusFlag(UART_Type *base, uint32_t flag);
/*!
* @brief This function is used to clear the current status
* of specific UART status flag. The available status
* flag can be select from uart_status_flag_t enumeration.
*
* @param base UART base pointer.
* @param flag Status flag to clear.
*/
void UART_ClearStatusFlag(UART_Type *base, uint32_t flag);
/*@}*/
/*!
* @name Interrupts
* @{
*/
/*!
* @brief Enables UART interrupts according to the provided mask.
*
* This function enables the UART interrupts according to the provided mask. The mask
* is a logical OR of enumeration members. See @ref _uart_interrupt_enable.
* For example, to enable TX empty interrupt and RX data ready interrupt, do the following.
* @code
* UART_EnableInterrupts(UART1,kUART_TxEmptyEnable | kUART_RxDataReadyEnable);
* @endcode
*
* @param base UART peripheral base address.
* @param mask The interrupts to enable. Logical OR of @ref _uart_interrupt_enable.
*/
void UART_EnableInterrupts(UART_Type *base, uint32_t mask);
/*!
* @brief Disables the UART interrupts according to the provided mask.
*
* This function disables the UART interrupts according to the provided mask. The mask
* is a logical OR of enumeration members. See @ref _uart_interrupt_enable.
* For example, to disable TX empty interrupt and RX data ready interrupt do the following.
* @code
* UART_EnableInterrupts(UART1,kUART_TxEmptyEnable | kUART_RxDataReadyEnable);
* @endcode
*
* @param base UART peripheral base address.
* @param mask The interrupts to disable. Logical OR of @ref _uart_interrupt_enable.
*/
void UART_DisableInterrupts(UART_Type *base, uint32_t mask);
/*!
* @brief Gets enabled UART interrupts.
*
* This function gets the enabled UART interrupts. The enabled interrupts are returned
* as the logical OR value of the enumerators @ref _uart_interrupt_enable. To check
* a specific interrupt enable status, compare the return value with enumerators
* in @ref _uart_interrupt_enable.
* For example, to check whether the TX empty interrupt is enabled:
* @code
* uint32_t enabledInterrupts = UART_GetEnabledInterrupts(UART1);
*
* if (kUART_TxEmptyEnable & enabledInterrupts)
* {
* ...
* }
* @endcode
*
* @param base UART peripheral base address.
* @return UART interrupt flags which are logical OR of the enumerators in @ref _uart_interrupt_enable.
*/
uint32_t UART_GetEnabledInterrupts(UART_Type *base);
/* @} */
/*!
* @name Bus Operations
* @{
*/
/*!
* @brief Enables or disables the UART transmitter.
*
* This function enables or disables the UART transmitter.
*
* @param base UART peripheral base address.
* @param enable True to enable, false to disable.
*/
static inline void UART_EnableTx(UART_Type *base, bool enable)
{
if (enable)
{
base->UCR2 |= UART_UCR2_TXEN_MASK;
}
else
{
base->UCR2 &= ~UART_UCR2_TXEN_MASK;
}
}
/*!
* @brief Enables or disables the UART receiver.
*
* This function enables or disables the UART receiver.
*
* @param base UART peripheral base address.
* @param enable True to enable, false to disable.
*/
static inline void UART_EnableRx(UART_Type *base, bool enable)
{
if (enable)
{
base->UCR2 |= UART_UCR2_RXEN_MASK;
}
else
{
base->UCR2 &= ~UART_UCR2_RXEN_MASK;
}
}
/*!
* @brief Writes to the transmitter register.
*
* This function is used to write data to transmitter register.
* The upper layer must ensure that the TX register is empty or that
* the TX FIFO has room before calling this function.
*
* @param base UART peripheral base address.
* @param data Data write to the TX register.
*/
static inline void UART_WriteByte(UART_Type *base, uint8_t data)
{
base->UTXD = (uint32_t)data & UART_UTXD_TX_DATA_MASK;
}
/*!
* @brief Reads the receiver register.
*
* This function is used to read data from receiver register.
* The upper layer must ensure that the receiver register is full or that
* the RX FIFO has data before calling this function.
*
* @param base UART peripheral base address.
* @return Data read from data register.
*/
static inline uint8_t UART_ReadByte(UART_Type *base)
{
return (uint8_t)((base->URXD & UART_URXD_RX_DATA_MASK) >> UART_URXD_RX_DATA_SHIFT);
}
/*!
* @brief Writes to the TX register using a blocking method.
*
* This function polls the TX register, waits for the TX register to be empty or for the TX FIFO
* to have room and writes data to the TX buffer.
*
* @param base UART peripheral base address.
* @param data Start address of the data to write.
* @param length Size of the data to write.
* @retval kStatus_UART_Timeout Transmission timed out and was aborted.
* @retval kStatus_Success Successfully wrote all data.
*/
status_t UART_WriteBlocking(UART_Type *base, const uint8_t *data, size_t length);
/*!
* @brief Read RX data register using a blocking method.
*
* This function polls the RX register, waits for the RX register to be full or for RX FIFO to
* have data, and reads data from the TX register.
*
* @param base UART peripheral base address.
* @param data Start address of the buffer to store the received data.
* @param length Size of the buffer.
* @retval kStatus_UART_RxHardwareOverrun Receiver overrun occurred while receiving data.
* @retval kStatus_UART_NoiseError A noise error occurred while receiving data.
* @retval kStatus_UART_FramingError A framing error occurred while receiving data.
* @retval kStatus_UART_ParityError A parity error occurred while receiving data.
* @retval kStatus_UART_Timeout Transmission timed out and was aborted.
* @retval kStatus_Success Successfully received all data.
*/
status_t UART_ReadBlocking(UART_Type *base, uint8_t *data, size_t length);
/* @} */
/*!
* @name Transactional
* @{
*/
/*!
* @brief Initializes the UART handle.
*
* This function initializes the UART handle which can be used for other UART
* transactional APIs. Usually, for a specified UART instance,
* call this API once to get the initialized handle.
*
* @param base UART peripheral base address.
* @param handle UART handle pointer.
* @param callback The callback function.
* @param userData The parameter of the callback function.
*/
void UART_TransferCreateHandle(UART_Type *base,
uart_handle_t *handle,
uart_transfer_callback_t callback,
void *userData);
/*!
* @brief Sets up the RX ring buffer.
*
* This function sets up the RX ring buffer to a specific UART handle.
*
* When the RX ring buffer is used, data received are stored into the ring buffer even when the
* user doesn't call the UART_TransferReceiveNonBlocking() API. If data is already received
* in the ring buffer, the user can get the received data from the ring buffer directly.
*
* @note When using the RX ring buffer, one byte is reserved for internal use. In other
* words, if @p ringBufferSize is 32, only 31 bytes are used for saving data.
*
* @param base UART peripheral base address.
* @param handle UART handle pointer.
* @param ringBuffer Start address of the ring buffer for background receiving. Pass NULL to disable the ring buffer.
* @param ringBufferSize Size of the ring buffer.
*/
void UART_TransferStartRingBuffer(UART_Type *base, uart_handle_t *handle, uint8_t *ringBuffer, size_t ringBufferSize);
/*!
* @brief Aborts the background transfer and uninstalls the ring buffer.
*
* This function aborts the background transfer and uninstalls the ring buffer.
*
* @param base UART peripheral base address.
* @param handle UART handle pointer.
*/
void UART_TransferStopRingBuffer(UART_Type *base, uart_handle_t *handle);
/*!
* @brief Get the length of received data in RX ring buffer.
*
* @param handle UART handle pointer.
* @return Length of received data in RX ring buffer.
*/
size_t UART_TransferGetRxRingBufferLength(uart_handle_t *handle);
/*!
* @brief Transmits a buffer of data using the interrupt method.
*
* This function sends data using an interrupt method. This is a non-blocking function, which
* returns directly without waiting for all data to be written to the TX register. When
* all data is written to the TX register in the ISR, the UART driver calls the callback
* function and passes the @ref kStatus_UART_TxIdle as status parameter.
*
* @note The kStatus_UART_TxIdle is passed to the upper layer when all data is written
* to the TX register. However, it does not ensure that all data is sent out. Before disabling the TX,
* check the kUART_TransmissionCompleteFlag to ensure that the TX is finished.
*
* @param base UART peripheral base address.
* @param handle UART handle pointer.
* @param xfer UART transfer structure. See #uart_transfer_t.
* @retval kStatus_Success Successfully start the data transmission.
* @retval kStatus_UART_TxBusy Previous transmission still not finished; data not all written to TX register yet.
* @retval kStatus_InvalidArgument Invalid argument.
*/
status_t UART_TransferSendNonBlocking(UART_Type *base, uart_handle_t *handle, uart_transfer_t *xfer);
/*!
* @brief Aborts the interrupt-driven data transmit.
*
* This function aborts the interrupt-driven data sending. The user can get the remainBytes to find out
* how many bytes are not sent out.
*
* @param base UART peripheral base address.
* @param handle UART handle pointer.
*/
void UART_TransferAbortSend(UART_Type *base, uart_handle_t *handle);
/*!
* @brief Gets the number of bytes written to the UART TX register.
*
* This function gets the number of bytes written to the UART TX
* register by using the interrupt method.
*
* @param base UART peripheral base address.
* @param handle UART handle pointer.
* @param count Send bytes count.
* @retval kStatus_NoTransferInProgress No send in progress.
* @retval kStatus_InvalidArgument The parameter is invalid.
* @retval kStatus_Success Get successfully through the parameter \p count;
*/
status_t UART_TransferGetSendCount(UART_Type *base, uart_handle_t *handle, uint32_t *count);
/*!
* @brief Receives a buffer of data using an interrupt method.
*
* This function receives data using an interrupt method. This is a non-blocking function, which
* returns without waiting for all data to be received.
* If the RX ring buffer is used and not empty, the data in the ring buffer is copied and
* the parameter @p receivedBytes shows how many bytes are copied from the ring buffer.
* After copying, if the data in the ring buffer is not enough to read, the receive
* request is saved by the UART driver. When the new data arrives, the receive request
* is serviced first. When all data is received, the UART driver notifies the upper layer
* through a callback function and passes the status parameter @ref kStatus_UART_RxIdle.
* For example, the upper layer needs 10 bytes but there are only 5 bytes in the ring buffer.
* The 5 bytes are copied to the xfer->data and this function returns with the
* parameter @p receivedBytes set to 5. For the left 5 bytes, newly arrived data is
* saved from the xfer->data[5]. When 5 bytes are received, the UART driver notifies the upper layer.
* If the RX ring buffer is not enabled, this function enables the RX and RX interrupt
* to receive data to the xfer->data. When all data is received, the upper layer is notified.
*
* @param base UART peripheral base address.
* @param handle UART handle pointer.
* @param xfer UART transfer structure, see #uart_transfer_t.
* @param receivedBytes Bytes received from the ring buffer directly.
* @retval kStatus_Success Successfully queue the transfer into transmit queue.
* @retval kStatus_UART_RxBusy Previous receive request is not finished.
* @retval kStatus_InvalidArgument Invalid argument.
*/
status_t UART_TransferReceiveNonBlocking(UART_Type *base,
uart_handle_t *handle,
uart_transfer_t *xfer,
size_t *receivedBytes);
/*!
* @brief Aborts the interrupt-driven data receiving.
*
* This function aborts the interrupt-driven data receiving. The user can get the remainBytes to know
* how many bytes are not received yet.
*
* @param base UART peripheral base address.
* @param handle UART handle pointer.
*/
void UART_TransferAbortReceive(UART_Type *base, uart_handle_t *handle);
/*!
* @brief Gets the number of bytes that have been received.
*
* This function gets the number of bytes that have been received.
*
* @param base UART peripheral base address.
* @param handle UART handle pointer.
* @param count Receive bytes count.
* @retval kStatus_NoTransferInProgress No receive in progress.
* @retval kStatus_InvalidArgument Parameter is invalid.
* @retval kStatus_Success Get successfully through the parameter \p count;
*/
status_t UART_TransferGetReceiveCount(UART_Type *base, uart_handle_t *handle, uint32_t *count);
/*!
* @brief UART IRQ handle function.
*
* This function handles the UART transmit and receive IRQ request.
*
* @param base UART peripheral base address.
* @param handle UART handle pointer.
*/
void UART_TransferHandleIRQ(UART_Type *base, uart_handle_t *handle);
/*@}*/
/*!
* @name DMA control functions.
* @{
*/
/*!
* @brief Enables or disables the UART transmitter DMA request.
*
* This function enables or disables the transmit request when the transmitter
* has one or more slots available in the TxFIFO. The fill level in the TxFIFO
* that generates the DMA request is controlled by the TXTL bits.
*
* @param base UART peripheral base address.
* @param enable True to enable, false to disable.
*/
static inline void UART_EnableTxDMA(UART_Type *base, bool enable)
{
assert(base != NULL);
if (enable)
{
base->UCR1 |= UART_UCR1_TXDMAEN_MASK;
}
else
{
base->UCR1 &= ~UART_UCR1_TXDMAEN_MASK;
}
}
/*!
* @brief Enables or disables the UART receiver DMA request.
*
* This function enables or disables the receive request when the receiver
* has data in the RxFIFO. The fill level in the RxFIFO at which a DMA request
* is generated is controlled by the RXTL bits .
*
* @param base UART peripheral base address.
* @param enable True to enable, false to disable.
*/
static inline void UART_EnableRxDMA(UART_Type *base, bool enable)
{
assert(base != NULL);
if (enable)
{
base->UCR1 |= UART_UCR1_RXDMAEN_MASK;
}
else
{
base->UCR1 &= ~UART_UCR1_RXDMAEN_MASK;
}
}
/*@}*/
/*!
* @name FIFO control functions.
* @{
*/
/*!
* @brief This function is used to set the watermark of UART Tx FIFO.
* A maskable interrupt is generated whenever the data level in
* the TxFIFO falls below the Tx FIFO watermark.
*
* @param base UART base pointer.
* @param watermark The Tx FIFO watermark.
*/
static inline void UART_SetTxFifoWatermark(UART_Type *base, uint8_t watermark)
{
assert((watermark >= 2U) && ((int32_t)watermark <= (int32_t)FSL_FEATURE_IUART_FIFO_SIZEn(base)));
base->UFCR = (base->UFCR & ~UART_UFCR_TXTL_MASK) | UART_UFCR_TXTL(watermark);
}
/*!
* @brief This function is used to set the watermark of UART RTS deassertion.
*
* The RTS signal deasserts whenever the data count in RxFIFO reaches the Rx
* RTS watermark.
*
* @param base UART base pointer.
* @param watermark The Rx RTS watermark.
*/
static inline void UART_SetRxRTSWatermark(UART_Type *base, uint8_t watermark)
{
assert((int32_t)watermark <= (int32_t)FSL_FEATURE_IUART_FIFO_SIZEn(base));
base->UCR4 = (base->UCR4 & ~UART_UCR4_CTSTL_MASK) | UART_UCR4_CTSTL(watermark);
}
/*!
* @brief This function is used to set the watermark of UART Rx FIFO.
* A maskable interrupt is generated whenever the data level in
* the RxFIFO reaches the Rx FIFO watermark.
*
* @param base UART base pointer.
* @param watermark The Rx FIFO watermark.
*/
static inline void UART_SetRxFifoWatermark(UART_Type *base, uint8_t watermark)
{
assert((int32_t)watermark <= (int32_t)FSL_FEATURE_IUART_FIFO_SIZEn(base));
base->UFCR = (base->UFCR & ~UART_UFCR_RXTL_MASK) | UART_UFCR_RXTL(watermark);
}
/*@}*/
/*!
* @name Auto baud rate detection.
* @{
*/
/*!
* @brief This function is used to set the enable condition of
* Automatic Baud Rate Detection feature.
*
* @param base UART base pointer.
* @param enable Enable/Disable Automatic Baud Rate Detection feature.
* - true: Enable Automatic Baud Rate Detection feature.
* - false: Disable Automatic Baud Rate Detection feature.
*/
static inline void UART_EnableAutoBaudRate(UART_Type *base, bool enable)
{
if (enable)
{
/* When ADET=0 and ADBR=1, automatic baud rate detection starts */
/* Enable automatic baud rate detection */
base->UCR1 |= UART_UCR1_ADBR_MASK;
/* Clear ADET brfore start automatic baud rate detection*/
base->USR2 |= UART_USR2_ADET_MASK;
}
else
{
/* Disable automatic baud rate detection */
base->UCR1 &= ~UART_UCR1_ADBR_MASK;
}
}
/*!
* @brief This function is used to read if the automatic baud rate detection
* has finished.
*
* @param base UART base pointer.
* @return - true: Automatic baud rate detection has finished.
* - false: Automatic baud rate detection has not finished.
*/
static inline bool UART_IsAutoBaudRateComplete(UART_Type *base)
{
if ((UART_USR2_ACST_MASK & base->USR2) != 0U)
{
base->USR2 |= UART_USR2_ACST_MASK;
return true;
}
else
{
return false;
}
}
#ifdef __cplusplus
}
#endif
/*@}*/
/*! @}*/
#endif /* _FSL_UART_H_ */

View File

@ -0,0 +1,272 @@
/******************************************************************************
* @file mpu_armv7.h
* @brief CMSIS MPU API for Armv7-M MPU
* @version V5.1.0
* @date 08. March 2019
******************************************************************************/
/*
* Copyright (c) 2017-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 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) & 2U), ((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)
{
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;
}
/** 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 rsar Value for RSAR 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 rsar Value for RSAR 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;
}
/** Memcopy with strictly ordered memory access, e.g. for register targets.
* \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

View File

@ -0,0 +1,56 @@
/*
* Copyright 2019-2020 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#ifndef _PIN_MUX_H_
#define _PIN_MUX_H_
#include "board.h"
/***********************************************************************************************************************
* Definitions
**********************************************************************************************************************/
/*!
* @addtogroup pin_mux
* @{
*/
/***********************************************************************************************************************
* API
**********************************************************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @brief Calls initialization functions.
*
*/
void BOARD_InitBootPins(void);
/*!
* @brief Configures pin routing and optionally pin electrical features.
*
*/
void BOARD_InitPins(void); /*!< Function assigned for the core: Cortex-M7F[m7] */
#if defined(__cplusplus)
}
#endif
/*!
* @}
*/
#endif /* _PIN_MUX_H_ */
/***********************************************************************************************************************
* EOF
**********************************************************************************************************************/

View File

@ -0,0 +1,115 @@
/*
** ###################################################################
** Processors: MIMX8ML8CVNKZ
** MIMX8ML8DVNLZ
**
** Compilers: GNU C Compiler
** IAR ANSI C/C++ Compiler for ARM
** Keil ARM C/C++ Compiler
**
** Reference manual: IMX8MPRM, Rev.D, 10/2020
** Version: rev. 4.0, 2020-11-16
** Build: b201104
**
** Abstract:
** Provides a system configuration function and a global variable that
** contains the system frequency. It configures the device and initializes
** the oscillator (PLL) that is part of the microcontroller device.
**
** Copyright 2016 Freescale Semiconductor, Inc.
** Copyright 2016-2020 NXP
** All rights reserved.
**
** SPDX-License-Identifier: BSD-3-Clause
**
** http: www.nxp.com
** mail: support@nxp.com
**
** Revisions:
** - rev. 1.0 (2019-10-11)
** Initial version.
** - rev. 2.0 (2020-02-21)
** Rev.B Header.
** - rev. 3.0 (2020-06-22)
** Rev.C Header.
** - rev. 4.0 (2020-11-16)
** Rev.D Header.
**
** ###################################################################
*/
/*!
* @file MIMX8ML8_cm7
* @version 4.0
* @date 2020-11-16
* @brief Device specific configuration file for MIMX8ML8_cm7 (header file)
*
* Provides a system configuration function and a global variable that contains
* the system frequency. It configures the device and initializes the oscillator
* (PLL) that is part of the microcontroller device.
*/
#ifndef _SYSTEM_MIMX8ML8_cm7_H_
#define _SYSTEM_MIMX8ML8_cm7_H_ /**< Symbol preventing repeated inclusion */
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/* i.MX8ML Definitions */
#ifndef DISABLE_WDOG
#define DISABLE_WDOG 1
#endif
/* Define clock source values */
#define CPU_XTAL_SOSC_CLK_24MHZ 24000000U /* Value of the external System Oscillator Clock(SOSC) frequency in Hz */
#define CLK_PAD_CLK 0U /* The value could be changed according to the actual usage */
#define DEFAULT_SYSTEM_CLOCK 800000000U /* Default System clock value */
/**
* @brief System clock frequency (core clock)
*
* The system clock frequency supplied to the SysTick timer and the processor
* core clock. This variable can be used by the user application to setup the
* SysTick timer or configure other parameters. It may also be used by debugger to
* query the frequency of the debug timer or configure the trace clock speed
* SystemCoreClock is initialized with a correct predefined value.
*/
extern uint32_t SystemCoreClock;
/**
* @brief Setup the microcontroller system.
*
* Typically this function configures the oscillator (PLL) that is part of the
* microcontroller device. For systems with variable clock speed it also updates
* the variable SystemCoreClock. SystemInit is called from startup_device file.
*/
void SystemInit(void);
/**
* @brief Updates the SystemCoreClock variable.
*
* It must be called whenever the core clock is changed during program
* execution. SystemCoreClockUpdate() evaluates the clock register settings and calculates
* the current core clock.
*/
void SystemCoreClockUpdate(void);
/**
* @brief SystemInit function hook.
*
* This weak function allows to call specific initialization code during the
* SystemInit() execution.This can be used when an application specific code needs
* to be called as close to the reset entry as possible (for example the Multicore
* Manager MCMGR_EarlyInit() function call).
* NOTE: No global r/w variables can be used in this hook function because the
* initialization of these variables happens after this function.
*/
void SystemInitHook(void);
#ifdef __cplusplus
}
#endif
#endif /* _SYSTEM_MIMX8ML8_cm7_H_ */

View File

@ -0,0 +1,69 @@
/*
* Copyright 2019-2020 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
/***********************************************************************************************************************
* This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file
* will be overwritten if the respective MCUXpresso Config Tools is used to update this file.
**********************************************************************************************************************/
/*
* TEXT BELOW IS USED AS SETTING FOR TOOLS *************************************
!!GlobalInfo
product: Pins v8.0
processor: MIMX8ML8xxxLZ
package_id: MIMX8ML8DVNLZ
mcu_data: ksdk2_0
processor_version: 0.8.3
* BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS ***********
*/
#include "fsl_common.h"
#include "fsl_iomuxc.h"
#include "pin_mux.h"
/* FUNCTION ************************************************************************************************************
*
* Function Name : BOARD_InitBootPins
* Description : Calls initialization functions.
*
* END ****************************************************************************************************************/
void BOARD_InitBootPins(void)
{
}
/*
* TEXT BELOW IS USED AS SETTING FOR TOOLS *************************************
BOARD_InitPins:
- options: {callFromInitBoot: 'false', coreID: m7}
- pin_list:
- {pin_num: AJ5, peripheral: UART4, signal: uart_rx, pin_signal: UART4_RXD, PE: Enabled, HYS: CMOS, PUE: Weak_Pull_Up, FSEL: Slow, DSE: X1}
- {pin_num: AH5, peripheral: UART4, signal: uart_tx, pin_signal: UART4_TXD, PE: Enabled, HYS: CMOS, PUE: Weak_Pull_Up, FSEL: Slow, DSE: X1}
* BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS ***********
*/
/* FUNCTION ************************************************************************************************************
*
* Function Name : BOARD_InitPins
* Description : Configures pin routing and optionally pin electrical features.
*
* END ****************************************************************************************************************/
void BOARD_InitPins(void) { /*!< Function assigned for the core: Cortex-M7F[m7] */
IOMUXC_SetPinMux(IOMUXC_UART4_RXD_UART4_RX, 0U);
IOMUXC_SetPinConfig(IOMUXC_UART4_RXD_UART4_RX,
IOMUXC_SW_PAD_CTL_PAD_PUE_MASK |
IOMUXC_SW_PAD_CTL_PAD_PE_MASK);
IOMUXC_SetPinMux(IOMUXC_UART4_TXD_UART4_TX, 0U);
IOMUXC_SetPinConfig(IOMUXC_UART4_TXD_UART4_TX,
IOMUXC_SW_PAD_CTL_PAD_PUE_MASK |
IOMUXC_SW_PAD_CTL_PAD_PE_MASK);
}
/***********************************************************************************************************************
* EOF
**********************************************************************************************************************/

View File

@ -0,0 +1,219 @@
/*
** ###################################################################
** Processors: MIMX8ML8CVNKZ
** MIMX8ML8DVNLZ
**
** Compilers: GNU C Compiler
** IAR ANSI C/C++ Compiler for ARM
** Keil ARM C/C++ Compiler
**
** Reference manual: IMX8MPRM, Rev.D, 10/2020
** Version: rev. 4.0, 2020-11-16
** Build: b201104
**
** Abstract:
** Provides a system configuration function and a global variable that
** contains the system frequency. It configures the device and initializes
** the oscillator (PLL) that is part of the microcontroller device.
**
** Copyright 2016 Freescale Semiconductor, Inc.
** Copyright 2016-2020 NXP
** All rights reserved.
**
** SPDX-License-Identifier: BSD-3-Clause
**
** http: www.nxp.com
** mail: support@nxp.com
**
** Revisions:
** - rev. 1.0 (2019-10-11)
** Initial version.
** - rev. 2.0 (2020-02-21)
** Rev.B Header.
** - rev. 3.0 (2020-06-22)
** Rev.C Header.
** - rev. 4.0 (2020-11-16)
** Rev.D Header.
**
** ###################################################################
*/
/*!
* @file MIMX8ML8_cm7
* @version 4.0
* @date 2020-11-16
* @brief Device specific configuration file for MIMX8ML8_cm7 (implementation
* file)
*
* Provides a system configuration function and a global variable that contains
* the system frequency. It configures the device and initializes the oscillator
* (PLL) that is part of the microcontroller device.
*/
#include <stdint.h>
#include "fsl_device_registers.h"
/*!
* @brief CCM reg macros to extract corresponding registers bit field.
*/
#define CCM_BIT_FIELD_VAL(val, mask, shift) (((val)&mask) >> shift)
/*!
* @brief CCM reg macros to get corresponding registers values.
*/
#define CCM_ANALOG_REG_VAL(base, off) (*((volatile uint32_t *)((uint32_t)(base) + (off))))
/*******************************************************************************
* Prototypes
******************************************************************************/
uint32_t GetFracPllFreq(const volatile uint32_t *base);
uint32_t GetIntegerPllFreq(const volatile uint32_t *base);
uint32_t GetFracPllFreq(const volatile uint32_t *base)
{
uint32_t fracCfg0 = CCM_ANALOG_REG_VAL(base, 0U);
uint32_t fracCfg1 = CCM_ANALOG_REG_VAL(base, 4U);
uint32_t fracCfg2 = CCM_ANALOG_REG_VAL(base, 8U);
uint32_t refClkFreq = 0U;
uint64_t fracClk = 0U;
uint8_t refSel = (uint8_t)CCM_BIT_FIELD_VAL(fracCfg0, CCM_ANALOG_AUDIO_PLL1_GEN_CTRL_PLL_REF_CLK_SEL_MASK,
CCM_ANALOG_AUDIO_PLL1_GEN_CTRL_PLL_REF_CLK_SEL_SHIFT);
uint32_t mainDiv = CCM_BIT_FIELD_VAL(fracCfg1, CCM_ANALOG_AUDIO_PLL1_FDIV_CTL0_PLL_MAIN_DIV_MASK,
CCM_ANALOG_AUDIO_PLL1_FDIV_CTL0_PLL_MAIN_DIV_SHIFT);
uint8_t preDiv = (uint8_t)CCM_BIT_FIELD_VAL(fracCfg1, CCM_ANALOG_AUDIO_PLL1_FDIV_CTL0_PLL_PRE_DIV_MASK,
CCM_ANALOG_AUDIO_PLL1_FDIV_CTL0_PLL_PRE_DIV_SHIFT);
uint8_t postDiv = (uint8_t)CCM_BIT_FIELD_VAL(fracCfg1, CCM_ANALOG_AUDIO_PLL1_FDIV_CTL0_PLL_POST_DIV_MASK,
CCM_ANALOG_AUDIO_PLL1_FDIV_CTL0_PLL_POST_DIV_SHIFT);
uint32_t dsm = CCM_BIT_FIELD_VAL(fracCfg2, CCM_ANALOG_AUDIO_PLL1_FDIV_CTL1_PLL_DSM_MASK,
CCM_ANALOG_AUDIO_PLL1_FDIV_CTL1_PLL_DSM_SHIFT);
if (refSel == 0U) /* OSC 24M Clock */
{
refClkFreq = CPU_XTAL_SOSC_CLK_24MHZ;
}
else
{
refClkFreq = CLK_PAD_CLK; /* CLK_PAD_CLK Clock, please note that the value is 0hz by default, it could be set at
system_MIMX8MLx_cm7.h :65 */
}
fracClk = (uint64_t)refClkFreq * ((uint64_t)mainDiv * 65536UL + (uint64_t)dsm) /
((uint64_t)65536UL * preDiv * (1UL << postDiv));
return (uint32_t)fracClk;
}
uint32_t GetIntegerPllFreq(const volatile uint32_t *base)
{
uint32_t integerCfg0 = CCM_ANALOG_REG_VAL(base, 0U);
uint32_t integerCfg1 = CCM_ANALOG_REG_VAL(base, 4U);
uint32_t refClkFreq = 0U;
uint64_t pllOutClock = 0U;
uint8_t pllBypass = (uint8_t)CCM_BIT_FIELD_VAL(integerCfg0, CCM_ANALOG_SYS_PLL1_GEN_CTRL_PLL_BYPASS_MASK,
CCM_ANALOG_SYS_PLL1_GEN_CTRL_PLL_BYPASS_SHIFT);
uint8_t refSel = (uint8_t)CCM_BIT_FIELD_VAL(integerCfg0, CCM_ANALOG_SYS_PLL1_GEN_CTRL_PLL_REF_CLK_SEL_MASK,
CCM_ANALOG_SYS_PLL1_GEN_CTRL_PLL_REF_CLK_SEL_SHIFT);
uint32_t mainDiv = CCM_BIT_FIELD_VAL(integerCfg1, CCM_ANALOG_SYS_PLL1_FDIV_CTL0_PLL_MAIN_DIV_MASK,
CCM_ANALOG_SYS_PLL1_FDIV_CTL0_PLL_MAIN_DIV_SHIFT);
uint8_t preDiv = (uint8_t)CCM_BIT_FIELD_VAL(integerCfg1, CCM_ANALOG_SYS_PLL1_FDIV_CTL0_PLL_PRE_DIV_MASK,
CCM_ANALOG_SYS_PLL1_FDIV_CTL0_PLL_PRE_DIV_SHIFT);
uint8_t postDiv = (uint8_t)CCM_BIT_FIELD_VAL(integerCfg1, CCM_ANALOG_SYS_PLL1_FDIV_CTL0_PLL_POST_DIV_MASK,
CCM_ANALOG_SYS_PLL1_FDIV_CTL0_PLL_POST_DIV_SHIFT);
if (refSel == 0U) /* OSC 24M Clock */
{
refClkFreq = CPU_XTAL_SOSC_CLK_24MHZ;
}
else
{
refClkFreq = CLK_PAD_CLK; /* CLK_PAD_CLK Clock, please note that the value is 0hz by default, it could be set at
system_MIMX8MLx_cm7.h :65 */
}
if (pllBypass != 0U)
{
pllOutClock = refClkFreq;
}
else
{
pllOutClock = (uint64_t)refClkFreq * mainDiv / (((uint64_t)(1U) << postDiv) * preDiv);
}
return (uint32_t)pllOutClock;
}
/* ----------------------------------------------------------------------------
-- Core clock
---------------------------------------------------------------------------- */
uint32_t SystemCoreClock = DEFAULT_SYSTEM_CLOCK;
/* ----------------------------------------------------------------------------
-- SystemInit()
---------------------------------------------------------------------------- */
void SystemInit(void)
{
#if ((__FPU_PRESENT == 1) && (__FPU_USED == 1))
SCB->CPACR |= ((3UL << 10 * 2) | (3UL << 11 * 2)); /* set CP10, CP11 Full Access */
#endif /* ((__FPU_PRESENT == 1) && (__FPU_USED == 1)) */
SystemInitHook();
}
/* ----------------------------------------------------------------------------
-- SystemCoreClockUpdate()
---------------------------------------------------------------------------- */
void SystemCoreClockUpdate(void)
{
volatile uint32_t *M7_ClockRoot = (volatile uint32_t *)(&(CCM)->ROOT[1].TARGET_ROOT);
uint32_t pre = ((*M7_ClockRoot & CCM_TARGET_ROOT_PRE_PODF_MASK) >> CCM_TARGET_ROOT_PRE_PODF_SHIFT) + 1U;
uint32_t post = ((*M7_ClockRoot & CCM_TARGET_ROOT_POST_PODF_MASK) >> CCM_TARGET_ROOT_POST_PODF_SHIFT) + 1U;
uint32_t freq = 0U;
switch ((*M7_ClockRoot & CCM_TARGET_ROOT_MUX_MASK) >> CCM_TARGET_ROOT_MUX_SHIFT)
{
case 0U: /* OSC 24M Clock */
freq = CPU_XTAL_SOSC_CLK_24MHZ;
break;
case 1U: /* System PLL2 DIV5 */
freq = GetIntegerPllFreq(&(CCM_ANALOG->SYS_PLL2_GEN_CTRL)) / 5U; /* Get System PLL2 DIV5 freq */
break;
case 2U: /* System PLL2 DIV4 */
freq = GetIntegerPllFreq(&(CCM_ANALOG->SYS_PLL2_GEN_CTRL)) / 4U; /* Get System PLL2 DIV4 freq */
break;
case 3U: /* System PLL1 DIV3 */
freq = GetIntegerPllFreq(&(CCM_ANALOG->SYS_PLL1_GEN_CTRL)) / 3U; /* Get System PLL1 DIV3 freq */
break;
case 4U: /* System PLL1 */
freq = GetIntegerPllFreq(&(CCM_ANALOG->SYS_PLL1_GEN_CTRL)); /* Get System PLL1 freq */
break;
case 5U: /* AUDIO PLL1 */
freq = GetFracPllFreq(&(CCM_ANALOG->AUDIO_PLL1_GEN_CTRL)); /* Get AUDIO PLL1 freq */
break;
case 6U: /* VIDEO PLL1 */
freq = GetFracPllFreq(&(CCM_ANALOG->VIDEO_PLL1_GEN_CTRL)); /* Get VIDEO PLL1 freq */
break;
case 7U: /* System PLL3 */
freq = GetIntegerPllFreq(&(CCM_ANALOG->SYS_PLL3_GEN_CTRL)); /* Get System PLL3 freq */
break;
default:
freq = CPU_XTAL_SOSC_CLK_24MHZ;
break;
}
SystemCoreClock = freq / pre / post;
}
/* ----------------------------------------------------------------------------
-- SystemInitHook()
---------------------------------------------------------------------------- */
__attribute__((weak)) void SystemInitHook(void)
{
/* Void implementation of the weak function. */
}

View File

@ -526,6 +526,17 @@ KERNELPATHS += -I$(KERNEL_ROOT)/resources/include/netdev
endif endif
endif endif
ifeq ($(BSP_ROOT),$(KERNEL_ROOT)/board/imx8mp)
KERNELPATHS += \
-I$(KERNEL_ROOT)/arch/arm/cortex-m7 \
-I$(BSP_ROOT)/ \
-I$(BSP_ROOT)/include \
-I$(BSP_ROOT)/third_party_driver/include \
-I$(BSP_ROOT)/rpmsg_lite/lib/include \
-I$(BSP_ROOT)/rpmsg_lite/lib/include/platform/imx8mp_m7 \
-I$(KERNEL_ROOT)/include #
endif
ifeq ($(BSP_ROOT),$(KERNEL_ROOT)/board/xishutong-arm32) ifeq ($(BSP_ROOT),$(KERNEL_ROOT)/board/xishutong-arm32)
KERNELPATHS += \ KERNELPATHS += \
-I$(KERNEL_ROOT)/arch/arm/cortex-m4/hc32f4a0 \ -I$(KERNEL_ROOT)/arch/arm/cortex-m4/hc32f4a0 \

View File

@ -417,23 +417,12 @@ static inline int SerialDevPollingRead(struct SerialHardwareDevice *serial_dev,
uint8 get_char; uint8 get_char;
while (read_length) get_char = hwdev_done->get_char(serial_dev);
{
get_char = hwdev_done->get_char(serial_dev);
if (-ERROR == get_char)
{
break;
}
*read_data = get_char; *read_data = get_char;
read_data++; read_data++;
read_length--; read_length--;
read_param->read_length++;
if ('\n' == get_char)
{
break;
}
}
return EOK; return EOK;
} }