add xiwangtong-arm32 board on XiZi/board/
|
@ -18,7 +18,7 @@ static void event_handler(lv_event_t * e)
|
|||
void lv_demo_calendar(void)
|
||||
{
|
||||
lv_obj_t * calendar = lv_calendar_create(lv_scr_act());
|
||||
lv_obj_set_size(calendar, 480, 272);
|
||||
lv_obj_set_size(calendar, 800, 480);//lv_obj_set_size(calendar, 800, 480);
|
||||
lv_obj_align(calendar, LV_ALIGN_CENTER, 0, 0);
|
||||
lv_obj_add_event_cb(calendar, event_handler, LV_EVENT_ALL, NULL);
|
||||
|
||||
|
|
|
@ -43,6 +43,6 @@ if ADD_RTTHREAD_FETURES
|
|||
string "BC28 device pin driver path"
|
||||
default "/dev/pin"
|
||||
config ADAPTER_BC28_RESETPIN
|
||||
string "BC28 RESET pin number"
|
||||
int "BC28 RESET pin number"
|
||||
default "100"
|
||||
endif
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
#include "lv_port_indev_template.h"
|
||||
#include "../../lvgl.h"
|
||||
|
||||
static int touch_fd = 0;
|
||||
static int touch_fd = -1;
|
||||
static TouchDataParam touch_data;
|
||||
/*********************
|
||||
* DEFINES
|
||||
|
@ -230,8 +230,8 @@ static void touchpad_init(void)
|
|||
printf("touch fd = %d\n",touch_fd);
|
||||
} else {
|
||||
printf("open %s touch fd = %d failed.\n",PRIV_TOUCH_DEV,touch_fd);
|
||||
touch_fd = -1;
|
||||
}
|
||||
|
||||
/*Your code comes here*/
|
||||
}
|
||||
|
||||
|
@ -260,6 +260,11 @@ static bool touchpad_is_pressed(void)
|
|||
int ret;
|
||||
/*Your code comes here*/
|
||||
memset(&touch_data, 0 ,sizeof(TouchDataParam));
|
||||
|
||||
if (touch_fd < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ret = PrivRead(touch_fd, &touch_data, 1);
|
||||
if(ret && touch_data.x >= 0 && touch_data.x < MY_INDEV_X && touch_data.y >= 0 && touch_data.y < MY_INDEV_Y)
|
||||
{
|
||||
|
|
|
@ -6,7 +6,7 @@ MAKEFLAGS += --no-print-directory
|
|||
|
||||
|
||||
support :=kd233 stm32f407-st-discovery maix-go stm32f407zgt6 aiit-riscv64-board aiit-arm32-board hifive1-rev-B hifive1-emulator k210-emulator cortex-m3-emulator cortex-m4-emulator ok1052-c gapuino stm32f103-nano gd32vf103_rvstar cortex-m0-emulator rv32m1_vega nuvoton-m2354
|
||||
support += xidatong
|
||||
support += xidatong xiwangtong-arm32
|
||||
SRC_DIR :=
|
||||
|
||||
export BOARD ?=kd233
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
/**
|
||||
* @file connect_i2c.c
|
||||
* @brief support ok1052-c board i2c function and register to bus framework
|
||||
* @brief support imxrt1052 board i2c function and register to bus framework
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022-03-01
|
||||
|
|
|
@ -1,6 +1,18 @@
|
|||
/*
|
||||
* Copyright (c) 2022 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 connect_lcd.c
|
||||
* @brief support xidatong lcd function and register to bus framework
|
||||
* @brief support imxrt1052 lcd function and register to bus framework
|
||||
* @version 2.0
|
||||
* @author AIIT XiUOS Lab
|
||||
* @date 2022-04-25
|
||||
|
|
|
@ -1,3 +1,23 @@
|
|||
/*
|
||||
* 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 connect_touch.c
|
||||
* @brief support imxrt1052 semc function
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022-05-15
|
||||
*/
|
||||
|
||||
#include "fsl_semc.h"
|
||||
#include "clock_config.h"
|
||||
#include <xs_base.h>
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
/**
|
||||
* @file connect_touch.c
|
||||
* @brief support xidatong touch function and register to bus framework
|
||||
* @brief support imxrt1052 touch function and register to bus framework
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022-05-15
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
mainmenu "XiZi 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 "xiwangtong-arm32 feature"
|
||||
source "$BSP_DIR/third_party_driver/Kconfig"
|
||||
|
||||
menu "config default board resources"
|
||||
menu "config board app name"
|
||||
config BOARD_APP_NAME
|
||||
string "config board app name"
|
||||
default "/XiUOS_xiwangtong_arm32_app.bin"
|
||||
endmenu
|
||||
|
||||
menu "config board service table"
|
||||
config SERVICE_TABLE_ADDRESS
|
||||
hex "board service table address"
|
||||
default 0x2007F0000
|
||||
endmenu
|
||||
|
||||
endmenu
|
||||
|
||||
config __STACKSIZE__
|
||||
int "stack size for interrupt"
|
||||
default 4096
|
||||
|
||||
menu "config board peripheral"
|
||||
config MOUNT_SDCARD
|
||||
bool "mount sd card"
|
||||
default n
|
||||
endmenu
|
||||
|
||||
endmenu
|
||||
|
||||
|
||||
menu "Hardware feature"
|
||||
source "$KERNEL_DIR/resources/Kconfig"
|
||||
endmenu
|
||||
|
||||
source "$KERNEL_DIR/Kconfig"
|
||||
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
SRC_DIR := third_party_driver xip
|
||||
|
||||
SRC_FILES := board.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -0,0 +1,172 @@
|
|||
# 从零开始构建矽璓工业物联操作系统:使用ARM架构的矽望通
|
||||
|
||||
# xiwangtong-arm32
|
||||
|
||||
[XiUOS](http://xuos.io/) (X Industrial Ubiquitous Operating System) 矽璓XiUOS是一款面向智慧车间的工业物联网操作系统,主要由一个极简的微型实时操作系统内核和其上的工业物联框架构成,通过高效管理工业物联网设备、支撑工业物联应用,在生产车间内实现智能化的“感知环境、联网传输、知悉识别、控制调整”,促进以工业设备和工业控制系统为核心的人、机、物深度互联,帮助提升生产线的数字化和智能化水平。
|
||||
|
||||
## 1. 简介
|
||||
|
||||
| 硬件 | 描述 |
|
||||
| -- | -- |
|
||||
|芯片型号| MIMXRT1052DVL6A |
|
||||
|架构| cortex-m7 |
|
||||
|主频| 600MHz |
|
||||
|片内SRAM| 512KB shared with TCM |
|
||||
|外设支持| UART |
|
||||
|
||||
XiUOS板级当前支持使用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
|
||||
```
|
||||
|
||||
## 编译说明
|
||||
|
||||
### 编辑环境:`Ubuntu18.04`
|
||||
|
||||
### 编译工具链:`arm-none-eabi-gcc`
|
||||
使用`VScode`打开工程的方法有多种,本文介绍一种快捷键,在项目目录下将`code .`输入linux系统命令终端即可打开目标项目
|
||||
|
||||
|
||||
编译步骤:
|
||||
|
||||
1.在VScode命令终端中执行以下命令,生成配置文件
|
||||
|
||||
```c
|
||||
cd ./Ubiquitous/XiZi
|
||||
make BOARD=xiwangtong-arm32 distclean
|
||||
make BOARD=xiwangtong-arm32 menuconfig
|
||||
```
|
||||
|
||||
2.在menuconfig界面配置需要关闭和开启的功能,按回车键进入下级菜单,按Y键选中需要开启的功能,按N键选中需要关闭的功能,配置结束后保存并退出(本例旨在演示简单的输出例程,所以没有需要配置的选项,双击快捷键ESC退出配置)
|
||||
|
||||

|
||||
|
||||
退出时选择`yes`保存上面所配置的内容,如下图所示:
|
||||
|
||||

|
||||
|
||||
3.继续执行以下命令,进行编译
|
||||
|
||||
```
|
||||
make BOARD=xiwangtong-arm32
|
||||
```
|
||||
|
||||
4.如果编译正确无误,会产生XiZi-xiwangtong-arm32.elf、XiZi-xiwangtong-arm32.bin文件。
|
||||
|
||||
## 3. 烧写及运行
|
||||
|
||||
### 3.1 烧写
|
||||
1、烧写工具:NXP MCU Boot Utility,可参考[https://github.com/JayHeng/NXP-MCUBootUtility](https://github.com/JayHeng/NXP-MCUBootUtility)
|
||||
|
||||
2、xiwangtong开发板支持UART串口烧写程序,打开NXP MCU Boot Utility后,选择好芯片类型为i.MXRT105x,开发板上电,使用串口转USB线将开发板和PC连接,拨码开关设置为1 on 2 on 3 off 4 off,重新上电,选择对应的COM口和波特率(需关闭串口终端连接,确保该COM口空闲,否则会导致Utility工具连接失败),连接成功后,点击reconnect,等待NXP MCU Boot Utility中红色显示变成蓝色显示,则表示已正确识别并连接到了开发板。如下图所示:
|
||||

|
||||
|
||||
3、同时需要匹配xiwangtong开发板所使用的Flash型号,点击Boot Device Configuration,在Use Typical Device中选择Winbond_W25QxxxJV,然后点击ok。如下图所示:
|
||||

|
||||
|
||||
4、选择编译生成的XiZi-xiwangtong-arm32.elf或bin文件路径,按照图示步骤,将文件烧写至Flash中(link.lds中已构造Flash Bootable image,如有修改Flash相关配置需求,可修改/xip目录内相关文件,无需NXPBootUtility再次构造),若烧写无误,则下列绿色进度条会执行到底。如下图所示:
|
||||

|
||||
### 3.2 运行结果
|
||||
|
||||
按照3.1烧写步骤执行后,将拨码开关设置为1 off 2 off 3 off 4 off,重新上电后,重新打开该COM口串口终端,若程序正常,则串口终端上会显示启动信息打印输出。如下图所示:
|
||||

|
|
@ -0,0 +1,376 @@
|
|||
/*
|
||||
* Copyright 2017 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file board.c
|
||||
* @brief relative configure for xidatong
|
||||
* @version 2.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022.03.15
|
||||
*/
|
||||
|
||||
/*************************************************
|
||||
File name: board.c
|
||||
Description: support imxrt1052-board init function
|
||||
Others: take SDK_2.6.1_MIMXRT1052xxxxB for references
|
||||
History:
|
||||
1. Date: 2022-03-15
|
||||
Author: AIIT XUOS Lab
|
||||
Modification:
|
||||
1. support imxrt1052-board MPU、clock、memory init
|
||||
2. support imxrt1052-board uart、sdio driver init
|
||||
*************************************************/
|
||||
|
||||
#include "fsl_common.h"
|
||||
#include "board.h"
|
||||
#include "pin_mux.h"
|
||||
|
||||
#if defined(SDK_I2C_BASED_COMPONENT_USED) && SDK_I2C_BASED_COMPONENT_USED
|
||||
#include "fsl_lpi2c.h"
|
||||
#endif /* SDK_I2C_BASED_COMPONENT_USED */
|
||||
#include "fsl_iomuxc.h"
|
||||
#include "fsl_gpio.h"
|
||||
#include "fsl_lpuart.h"
|
||||
|
||||
#ifdef BSP_USING_GPIO
|
||||
#include <connect_gpio.h>
|
||||
#endif
|
||||
|
||||
#ifdef BSP_USING_LPUART
|
||||
#include <connect_uart.h>
|
||||
#endif
|
||||
|
||||
#ifdef BSP_USING_I2C
|
||||
#include <connect_i2c.h>
|
||||
#endif
|
||||
|
||||
#ifdef BSP_USING_CH438
|
||||
#include <connect_ch438.h>
|
||||
#endif
|
||||
|
||||
#ifdef BSP_USING_SDIO
|
||||
#include <connect_sdio.h>
|
||||
#endif
|
||||
|
||||
#ifdef BSP_USING_WDT
|
||||
#include <connect_wdt.h>
|
||||
#endif
|
||||
|
||||
#ifdef BSP_USING_SEMC
|
||||
extern status_t BOARD_InitSEMC(void);
|
||||
#ifdef BSP_USING_EXTSRAM
|
||||
extern int ExtSramInit(void);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef BSP_USING_LWIP
|
||||
extern int ETH_BSP_Config();
|
||||
#endif
|
||||
|
||||
#ifdef BSP_USING_LCD
|
||||
extern int Imxrt1052HwLcdInit(void);
|
||||
#endif
|
||||
|
||||
#ifdef BSP_USING_TOUCH
|
||||
extern int HwTouchInit();
|
||||
#endif
|
||||
|
||||
void BOARD_SD_Pin_Config(uint32_t speed, uint32_t strength)
|
||||
{
|
||||
IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B0_00_USDHC1_CMD,
|
||||
IOMUXC_SW_PAD_CTL_PAD_SPEED(speed) | IOMUXC_SW_PAD_CTL_PAD_SRE_MASK |
|
||||
IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | IOMUXC_SW_PAD_CTL_PAD_PUE_MASK |
|
||||
IOMUXC_SW_PAD_CTL_PAD_HYS_MASK | IOMUXC_SW_PAD_CTL_PAD_PUS(1) |
|
||||
IOMUXC_SW_PAD_CTL_PAD_DSE(strength));
|
||||
IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B0_01_USDHC1_CLK,
|
||||
IOMUXC_SW_PAD_CTL_PAD_SPEED(speed) | IOMUXC_SW_PAD_CTL_PAD_SRE_MASK |
|
||||
IOMUXC_SW_PAD_CTL_PAD_HYS_MASK | IOMUXC_SW_PAD_CTL_PAD_PUS(0) |
|
||||
IOMUXC_SW_PAD_CTL_PAD_DSE(strength));
|
||||
IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B0_02_USDHC1_DATA0,
|
||||
IOMUXC_SW_PAD_CTL_PAD_SPEED(speed) | IOMUXC_SW_PAD_CTL_PAD_SRE_MASK |
|
||||
IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | IOMUXC_SW_PAD_CTL_PAD_PUE_MASK |
|
||||
IOMUXC_SW_PAD_CTL_PAD_HYS_MASK | IOMUXC_SW_PAD_CTL_PAD_PUS(1) |
|
||||
IOMUXC_SW_PAD_CTL_PAD_DSE(strength));
|
||||
IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B0_03_USDHC1_DATA1,
|
||||
IOMUXC_SW_PAD_CTL_PAD_SPEED(speed) | IOMUXC_SW_PAD_CTL_PAD_SRE_MASK |
|
||||
IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | IOMUXC_SW_PAD_CTL_PAD_PUE_MASK |
|
||||
IOMUXC_SW_PAD_CTL_PAD_HYS_MASK | IOMUXC_SW_PAD_CTL_PAD_PUS(1) |
|
||||
IOMUXC_SW_PAD_CTL_PAD_DSE(strength));
|
||||
IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B0_04_USDHC1_DATA2,
|
||||
IOMUXC_SW_PAD_CTL_PAD_SPEED(speed) | IOMUXC_SW_PAD_CTL_PAD_SRE_MASK |
|
||||
IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | IOMUXC_SW_PAD_CTL_PAD_PUE_MASK |
|
||||
IOMUXC_SW_PAD_CTL_PAD_HYS_MASK | IOMUXC_SW_PAD_CTL_PAD_PUS(1) |
|
||||
IOMUXC_SW_PAD_CTL_PAD_DSE(strength));
|
||||
IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B0_05_USDHC1_DATA3,
|
||||
IOMUXC_SW_PAD_CTL_PAD_SPEED(speed) | IOMUXC_SW_PAD_CTL_PAD_SRE_MASK |
|
||||
IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | IOMUXC_SW_PAD_CTL_PAD_PUE_MASK |
|
||||
IOMUXC_SW_PAD_CTL_PAD_HYS_MASK | IOMUXC_SW_PAD_CTL_PAD_PUS(1) |
|
||||
IOMUXC_SW_PAD_CTL_PAD_DSE(strength));
|
||||
}
|
||||
|
||||
void BOARD_MMC_Pin_Config(uint32_t speed, uint32_t strength)
|
||||
{
|
||||
IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B1_05_USDHC2_CMD,
|
||||
IOMUXC_SW_PAD_CTL_PAD_SPEED(speed) | IOMUXC_SW_PAD_CTL_PAD_SRE_MASK |
|
||||
IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | IOMUXC_SW_PAD_CTL_PAD_PUE_MASK |
|
||||
IOMUXC_SW_PAD_CTL_PAD_HYS_MASK | IOMUXC_SW_PAD_CTL_PAD_PUS(1) |
|
||||
IOMUXC_SW_PAD_CTL_PAD_DSE(strength));
|
||||
IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B1_04_USDHC2_CLK,
|
||||
IOMUXC_SW_PAD_CTL_PAD_SPEED(speed) | IOMUXC_SW_PAD_CTL_PAD_SRE_MASK |
|
||||
IOMUXC_SW_PAD_CTL_PAD_HYS_MASK | IOMUXC_SW_PAD_CTL_PAD_PUS(0) |
|
||||
IOMUXC_SW_PAD_CTL_PAD_DSE(strength));
|
||||
IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B1_03_USDHC2_DATA0,
|
||||
IOMUXC_SW_PAD_CTL_PAD_SPEED(speed) | IOMUXC_SW_PAD_CTL_PAD_SRE_MASK |
|
||||
IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | IOMUXC_SW_PAD_CTL_PAD_PUE_MASK |
|
||||
IOMUXC_SW_PAD_CTL_PAD_HYS_MASK | IOMUXC_SW_PAD_CTL_PAD_PUS(1) |
|
||||
IOMUXC_SW_PAD_CTL_PAD_DSE(strength));
|
||||
IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B1_02_USDHC2_DATA1,
|
||||
IOMUXC_SW_PAD_CTL_PAD_SPEED(speed) | IOMUXC_SW_PAD_CTL_PAD_SRE_MASK |
|
||||
IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | IOMUXC_SW_PAD_CTL_PAD_PUE_MASK |
|
||||
IOMUXC_SW_PAD_CTL_PAD_HYS_MASK | IOMUXC_SW_PAD_CTL_PAD_PUS(1) |
|
||||
IOMUXC_SW_PAD_CTL_PAD_DSE(strength));
|
||||
IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B1_01_USDHC2_DATA2,
|
||||
IOMUXC_SW_PAD_CTL_PAD_SPEED(speed) | IOMUXC_SW_PAD_CTL_PAD_SRE_MASK |
|
||||
IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | IOMUXC_SW_PAD_CTL_PAD_PUE_MASK |
|
||||
IOMUXC_SW_PAD_CTL_PAD_HYS_MASK | IOMUXC_SW_PAD_CTL_PAD_PUS(1) |
|
||||
IOMUXC_SW_PAD_CTL_PAD_DSE(strength));
|
||||
IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B1_00_USDHC2_DATA3,
|
||||
IOMUXC_SW_PAD_CTL_PAD_SPEED(speed) | IOMUXC_SW_PAD_CTL_PAD_SRE_MASK |
|
||||
IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | IOMUXC_SW_PAD_CTL_PAD_PUE_MASK |
|
||||
IOMUXC_SW_PAD_CTL_PAD_HYS_MASK | IOMUXC_SW_PAD_CTL_PAD_PUS(1) |
|
||||
IOMUXC_SW_PAD_CTL_PAD_DSE(strength));
|
||||
IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B1_08_USDHC2_DATA4,
|
||||
IOMUXC_SW_PAD_CTL_PAD_SPEED(speed) | IOMUXC_SW_PAD_CTL_PAD_SRE_MASK |
|
||||
IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | IOMUXC_SW_PAD_CTL_PAD_PUE_MASK |
|
||||
IOMUXC_SW_PAD_CTL_PAD_HYS_MASK | IOMUXC_SW_PAD_CTL_PAD_PUS(1) |
|
||||
IOMUXC_SW_PAD_CTL_PAD_DSE(strength));
|
||||
IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B1_09_USDHC2_DATA5,
|
||||
IOMUXC_SW_PAD_CTL_PAD_SPEED(speed) | IOMUXC_SW_PAD_CTL_PAD_SRE_MASK |
|
||||
IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | IOMUXC_SW_PAD_CTL_PAD_PUE_MASK |
|
||||
IOMUXC_SW_PAD_CTL_PAD_HYS_MASK | IOMUXC_SW_PAD_CTL_PAD_PUS(1) |
|
||||
IOMUXC_SW_PAD_CTL_PAD_DSE(strength));
|
||||
IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B1_10_USDHC2_DATA6,
|
||||
IOMUXC_SW_PAD_CTL_PAD_SPEED(speed) | IOMUXC_SW_PAD_CTL_PAD_SRE_MASK |
|
||||
IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | IOMUXC_SW_PAD_CTL_PAD_PUE_MASK |
|
||||
IOMUXC_SW_PAD_CTL_PAD_HYS_MASK | IOMUXC_SW_PAD_CTL_PAD_PUS(1) |
|
||||
IOMUXC_SW_PAD_CTL_PAD_DSE(strength));
|
||||
IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B1_11_USDHC2_DATA7,
|
||||
IOMUXC_SW_PAD_CTL_PAD_SPEED(speed) | IOMUXC_SW_PAD_CTL_PAD_SRE_MASK |
|
||||
IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | IOMUXC_SW_PAD_CTL_PAD_PUE_MASK |
|
||||
IOMUXC_SW_PAD_CTL_PAD_HYS_MASK | IOMUXC_SW_PAD_CTL_PAD_PUS(1) |
|
||||
IOMUXC_SW_PAD_CTL_PAD_DSE(strength));
|
||||
}
|
||||
|
||||
/* MPU configuration. */
|
||||
void BOARD_ConfigMPU(void)
|
||||
{
|
||||
/* 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 setting: Memory with Device type, not shareable, non-cacheable. */
|
||||
MPU->RBAR = ARM_MPU_RBAR(0, 0xC0000000U);
|
||||
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 2, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_512MB);
|
||||
|
||||
/* Region 1 setting: Memory with Device type, not shareable, non-cacheable. */
|
||||
MPU->RBAR = ARM_MPU_RBAR(1, 0x80000000U);
|
||||
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 2, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_1GB);
|
||||
|
||||
/* Region 2 setting */
|
||||
#if defined(XIP_EXTERNAL_FLASH) && (XIP_EXTERNAL_FLASH == 1)
|
||||
/* Setting Memory with Normal type, not shareable, outer/inner write back. */
|
||||
MPU->RBAR = ARM_MPU_RBAR(2, 0x60000000U);
|
||||
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_RO, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_64MB);
|
||||
#else
|
||||
/* Setting Memory with Device type, not shareable, non-cacheable. */
|
||||
MPU->RBAR = ARM_MPU_RBAR(2, 0x60000000U);
|
||||
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_RO, 2, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_64MB);
|
||||
#endif
|
||||
|
||||
/* Region 3 setting: Memory with Device type, not shareable, non-cacheable. */
|
||||
MPU->RBAR = ARM_MPU_RBAR(3, 0x00000000U);
|
||||
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 2, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_1GB);
|
||||
|
||||
/* Region 4 setting: Memory with Normal type, not shareable, outer/inner write back */
|
||||
MPU->RBAR = ARM_MPU_RBAR(4, 0x00000000U);
|
||||
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_128KB);
|
||||
|
||||
/* Region 5 setting: Memory with Normal type, not shareable, outer/inner write back */
|
||||
MPU->RBAR = ARM_MPU_RBAR(5, 0x20000000U);
|
||||
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_128KB);
|
||||
|
||||
/* Region 6 setting: Memory with Normal type, not shareable, outer/inner write back */
|
||||
MPU->RBAR = ARM_MPU_RBAR(6, 0x20200000U);
|
||||
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_256KB);
|
||||
|
||||
/* The define sets the cacheable memory to shareable,
|
||||
* this suggestion is referred from chapter 2.2.1 Memory regions,
|
||||
* types and attributes in Cortex-M7 Devices, Generic User Guide */
|
||||
#if defined(SDRAM_IS_SHAREABLE)
|
||||
/* Region 7 setting: Memory with Normal type, shareable, outer/inner write back */
|
||||
MPU->RBAR = ARM_MPU_RBAR(7, 0x80000000U);
|
||||
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 1, 1, 1, 0, ARM_MPU_REGION_SIZE_32MB);
|
||||
#else
|
||||
/* Region 7 setting: Memory with Normal type, not shareable, outer/inner write back */
|
||||
MPU->RBAR = ARM_MPU_RBAR(7, 0x80000000U);
|
||||
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_32MB);
|
||||
#endif
|
||||
|
||||
/* Region 8 setting, set last 2MB of SDRAM can't be accessed by cache, glocal variables which are not expected to be
|
||||
* accessed by cache can be put here */
|
||||
/* Memory with Normal type, not shareable, non-cacheable */
|
||||
MPU->RBAR = ARM_MPU_RBAR(8, 0x81E00000U);
|
||||
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 1, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_2MB);
|
||||
|
||||
/* Enable MPU */
|
||||
ARM_MPU_Enable(MPU_CTRL_PRIVDEFENA_Msk);
|
||||
|
||||
/* Enable I cache and D cache */
|
||||
SCB_EnableDCache();
|
||||
SCB_EnableICache();
|
||||
}
|
||||
|
||||
/* This is the timer interrupt service routine. */
|
||||
void SysTick_Handler(int irqn, void *arg)
|
||||
{
|
||||
TickAndTaskTimesliceUpdate();
|
||||
}
|
||||
DECLARE_HW_IRQ(SYSTICK_IRQN, SysTick_Handler, NONE);
|
||||
|
||||
struct InitSequenceDesc _board_init[] =
|
||||
{
|
||||
#ifdef BSP_USING_GPIO
|
||||
{ "hw_pin", Imxrt1052HwGpioInit },
|
||||
#endif
|
||||
|
||||
#ifdef BSP_USING_CH438
|
||||
{"ch438", Imxrt1052HwCh438Init()},
|
||||
#endif
|
||||
|
||||
#ifdef BSP_USING_SDIO
|
||||
{ "sdio", Imxrt1052HwSdioInit },
|
||||
#endif
|
||||
|
||||
#ifdef BSP_USING_I2C
|
||||
{ "hw_i2c", Imxrt1052HwI2cInit },
|
||||
#endif
|
||||
|
||||
#ifdef BSP_USING_LCD
|
||||
{ "hw_lcd", Imxrt1052HwLcdInit },
|
||||
#endif
|
||||
|
||||
#ifdef BSP_USING_TOUCH
|
||||
{"touch", HwTouchInit },
|
||||
#endif
|
||||
|
||||
#ifdef BSP_USING_LWIP
|
||||
{"ETH_BSP", ETH_BSP_Config},
|
||||
#endif
|
||||
|
||||
#ifdef BSP_USING_WDT
|
||||
{ "hw_wdt", Imxrt1052HwWdgInit },
|
||||
#endif
|
||||
{ " NONE ",NONE },
|
||||
};
|
||||
|
||||
/**
|
||||
* This function will initial imxrt1050 board.
|
||||
*/
|
||||
void InitBoardHardware()
|
||||
{
|
||||
int i = 0;
|
||||
int ret = 0;
|
||||
|
||||
BOARD_ConfigMPU();
|
||||
BOARD_InitPins();
|
||||
BOARD_BootClockRUN();
|
||||
|
||||
NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
|
||||
SysTick_Config(SystemCoreClock / TICK_PER_SECOND);
|
||||
|
||||
InitBoardMemory((void *)HEAP_BEGIN, (void *)HEAP_END);
|
||||
|
||||
#ifdef BSP_USING_SEMC
|
||||
CLOCK_InitSysPfd(kCLOCK_Pfd2, 29);
|
||||
/* Set semc clock to 163.86 MHz */
|
||||
CLOCK_SetMux(kCLOCK_SemcMux, 1);
|
||||
CLOCK_SetDiv(kCLOCK_SemcDiv, 1);
|
||||
|
||||
if (BOARD_InitSEMC() != kStatus_Success) {
|
||||
KPrintf("\r\n SEMC Init Failed\r\n");
|
||||
}
|
||||
#ifdef MEM_EXTERN_SRAM
|
||||
else {
|
||||
ExtSramInit();
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef BSP_USING_LPUART
|
||||
Imxrt1052HwUartInit();
|
||||
#endif
|
||||
|
||||
InstallConsole(KERNEL_CONSOLE_BUS_NAME, KERNEL_CONSOLE_DRV_NAME, KERNEL_CONSOLE_DEVICE_NAME);
|
||||
KPrintf("\nconsole init completed.\n");
|
||||
KPrintf("board initialization......\n");
|
||||
|
||||
for(i = 0; _board_init[i].fn != NONE; i++) {
|
||||
ret = _board_init[i].fn();
|
||||
KPrintf("initialize %s %s\n",_board_init[i].fn_name, ret == 0 ? "success" : "failed");
|
||||
}
|
||||
KPrintf("board init done.\n");
|
||||
KPrintf("start kernel...\n");
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
export CROSS_COMPILE ?=/usr/bin/arm-none-eabi-
|
||||
|
||||
export CFLAGS := -mcpu=cortex-m7 -mthumb -ffunction-sections -fdata-sections -Dgcc -O0 -gdwarf-2 -g -fgnu89-inline -Wa,-mimplicit-it=thumb
|
||||
export AFLAGS := -c -mcpu=cortex-m7 -mthumb -ffunction-sections -fdata-sections -x assembler-with-cpp -Wa,-mimplicit-it=thumb -gdwarf-2
|
||||
|
||||
### if use USB function, use special lds file because USB uses ITCM
|
||||
|
||||
ifeq ($(CONFIG_BSP_USING_USB),y)
|
||||
export LFLAGS := -mcpu=cortex-m7 -mthumb -ffunction-sections -fdata-sections -Wl,--gc-sections,-Map=XiZi_xidatong.map,-cref,-u,Reset_Handler -T $(BSP_ROOT)/link-usb.lds
|
||||
else
|
||||
export LFLAGS := -mcpu=cortex-m7 -mthumb -ffunction-sections -fdata-sections -Wl,--gc-sections,-Map=XiZi_xidatong.map,-cref,-u,Reset_Handler -T $(BSP_ROOT)/link.lds
|
||||
endif
|
||||
|
||||
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_userspace.lds
|
||||
|
||||
|
||||
export DEFINES := -DHAVE_CCONFIG_H -DCPU_MIMXRT1052CVL5B -DSKIP_SYSCLK_INIT -DEVK_MCIMXRM -DFSL_SDK_ENABLE_DRIVER_CACHE_CONTROL=1 -DXIP_EXTERNAL_FLASH=1 -D__STARTUP_INITIALIZE_NONCACHEDATA -D__STARTUP_CLEAR_BSS
|
||||
|
||||
export ARCH = arm
|
||||
export MCU = cortex-m7
|
After Width: | Height: | Size: 63 KiB |
After Width: | Height: | Size: 51 KiB |
After Width: | Height: | Size: 70 KiB |
After Width: | Height: | Size: 36 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 39 KiB |
After Width: | Height: | Size: 56 KiB |
|
@ -0,0 +1,177 @@
|
|||
/*
|
||||
* Copyright 2017-2018 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file board.h
|
||||
* @brief define imxrt1052-board init configure and start-up function
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021-05-28
|
||||
*/
|
||||
|
||||
/*************************************************
|
||||
File name: board.h
|
||||
Description: define imxrt1052-board board init function and struct
|
||||
Others:
|
||||
History:
|
||||
1. Date: 2021-05-28
|
||||
Author: AIIT XUOS Lab
|
||||
Modification:
|
||||
1. define imxrt-board InitBoardHardware
|
||||
2. define imxrt-board heap struct
|
||||
*************************************************/
|
||||
|
||||
#ifndef __BOARD_H__
|
||||
#define __BOARD_H__
|
||||
|
||||
#include "fsl_common.h"
|
||||
#include "fsl_gpio.h"
|
||||
#include "fsl_clock.h"
|
||||
#include "fsl_enet.h"
|
||||
#include "clock_config.h"
|
||||
#include <xizi.h>
|
||||
#include <arch_interrupt.h>
|
||||
|
||||
extern int heap_start;
|
||||
extern int heap_end;
|
||||
#define HEAP_BEGIN (&heap_start)
|
||||
#define HEAP_END (&heap_end)
|
||||
|
||||
#define HEAP_SIZE ((uint32_t)HEAP_END - (uint32_t)HEAP_BEGIN)
|
||||
|
||||
void InitBoardHardware(void);
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
/*! @brief The board name */
|
||||
#define BOARD_NAME "IMXRT1050"
|
||||
|
||||
#define NVIC_PRIORITYGROUP_0 0x00000007U /*!< 0 bits for pre-emption priority
|
||||
4 bits for subpriority */
|
||||
#define NVIC_PRIORITYGROUP_1 0x00000006U /*!< 1 bits for pre-emption priority
|
||||
3 bits for subpriority */
|
||||
#define NVIC_PRIORITYGROUP_2 0x00000005U /*!< 2 bits for pre-emption priority
|
||||
2 bits for subpriority */
|
||||
#define NVIC_PRIORITYGROUP_3 0x00000004U /*!< 3 bits for pre-emption priority
|
||||
1 bits for subpriority */
|
||||
#define NVIC_PRIORITYGROUP_4 0x00000003U /*!< 4 bits for pre-emption priority*/
|
||||
|
||||
/*! @brief The ENET PHY address. */
|
||||
#define BOARD_ENET0_PHY_ADDRESS (0x0U) /* Phy address of enet port 0. */
|
||||
|
||||
/* USB PHY condfiguration */
|
||||
#define BOARD_USB_PHY_D_CAL (0x0CU)
|
||||
#define BOARD_USB_PHY_TXCAL45DP (0x06U)
|
||||
#define BOARD_USB_PHY_TXCAL45DM (0x06U)
|
||||
|
||||
#define BOARD_ARDUINO_INT_IRQ (GPIO1_INT3_IRQn)
|
||||
#define BOARD_ARDUINO_I2C_IRQ (LPI2C1_IRQn)
|
||||
#define BOARD_ARDUINO_I2C_INDEX (1)
|
||||
#define BOARD_USDHC1_BASEADDR USDHC1
|
||||
#define BOARD_USDHC2_BASEADDR USDHC2
|
||||
#define BOARD_USDHC_CD_GPIO_BASE GPIO2
|
||||
#define BOARD_USDHC_CD_GPIO_PIN 28
|
||||
#define BOARD_USDHC_CD_PORT_IRQ GPIO2_Combined_16_31_IRQn
|
||||
#define BOARD_USDHC_CD_PORT_IRQ_HANDLER GPIO2_Combined_16_31_IRQHandler
|
||||
|
||||
#define BOARD_USDHC_CD_STATUS() (GPIO_PinRead(BOARD_USDHC_CD_GPIO_BASE, BOARD_USDHC_CD_GPIO_PIN))
|
||||
|
||||
#define BOARD_USDHC_CD_INTERRUPT_STATUS() (GPIO_PortGetInterruptFlags(BOARD_USDHC_CD_GPIO_BASE))
|
||||
#define BOARD_USDHC_CD_CLEAR_INTERRUPT(flag) (GPIO_PortClearInterruptFlags(BOARD_USDHC_CD_GPIO_BASE, flag))
|
||||
|
||||
#define BOARD_USDHC_CD_GPIO_INIT() \
|
||||
{ \
|
||||
gpio_pin_config_t sw_config = { \
|
||||
kGPIO_DigitalInput, \
|
||||
0, \
|
||||
kGPIO_IntRisingOrFallingEdge, \
|
||||
}; \
|
||||
GPIO_PinInit(BOARD_USDHC_CD_GPIO_BASE, BOARD_USDHC_CD_GPIO_PIN, &sw_config); \
|
||||
GPIO_PortEnableInterrupts(BOARD_USDHC_CD_GPIO_BASE, 1U << BOARD_USDHC_CD_GPIO_PIN); \
|
||||
GPIO_PortClearInterruptFlags(BOARD_USDHC_CD_GPIO_BASE, ~0); \
|
||||
}
|
||||
#define BOARD_HAS_SDCARD (1U)
|
||||
#define BOARD_SD_POWER_RESET_GPIO (GPIO1)
|
||||
#define BOARD_SD_POWER_RESET_GPIO_PIN (5U)
|
||||
|
||||
#define BOARD_USDHC_CARD_INSERT_CD_LEVEL (0U)
|
||||
|
||||
#define BOARD_USDHC_MMCCARD_POWER_CONTROL(state)
|
||||
|
||||
#define BOARD_USDHC_MMCCARD_POWER_CONTROL_INIT() \
|
||||
{ \
|
||||
gpio_pin_config_t sw_config = { \
|
||||
kGPIO_DigitalOutput, \
|
||||
0, \
|
||||
kGPIO_NoIntmode, \
|
||||
}; \
|
||||
GPIO_PinInit(BOARD_SD_POWER_RESET_GPIO, BOARD_SD_POWER_RESET_GPIO_PIN, &sw_config); \
|
||||
GPIO_PinWrite(BOARD_SD_POWER_RESET_GPIO, BOARD_SD_POWER_RESET_GPIO_PIN, true); \
|
||||
}
|
||||
|
||||
#define BOARD_USDHC_SDCARD_POWER_CONTROL_INIT() \
|
||||
{ \
|
||||
gpio_pin_config_t sw_config = { \
|
||||
kGPIO_DigitalOutput, \
|
||||
0, \
|
||||
kGPIO_NoIntmode, \
|
||||
}; \
|
||||
GPIO_PinInit(BOARD_SD_POWER_RESET_GPIO, BOARD_SD_POWER_RESET_GPIO_PIN, &sw_config); \
|
||||
}
|
||||
|
||||
#define BOARD_USDHC_SDCARD_POWER_CONTROL(state) \
|
||||
(GPIO_PinWrite(BOARD_SD_POWER_RESET_GPIO, BOARD_SD_POWER_RESET_GPIO_PIN, state))
|
||||
|
||||
#define BOARD_USDHC1_CLK_FREQ (CLOCK_GetSysPfdFreq(kCLOCK_Pfd0) / (CLOCK_GetDiv(kCLOCK_Usdhc1Div) + 1U))
|
||||
#define BOARD_USDHC2_CLK_FREQ (CLOCK_GetSysPfdFreq(kCLOCK_Pfd0) / (CLOCK_GetDiv(kCLOCK_Usdhc2Div) + 1U))
|
||||
|
||||
#define BOARD_SD_HOST_BASEADDR BOARD_USDHC1_BASEADDR
|
||||
#define BOARD_SD_HOST_CLK_FREQ BOARD_USDHC1_CLK_FREQ
|
||||
#define BOARD_SD_HOST_IRQ USDHC1_IRQn
|
||||
|
||||
#define BOARD_MMC_HOST_BASEADDR BOARD_USDHC2_BASEADDR
|
||||
#define BOARD_MMC_HOST_CLK_FREQ BOARD_USDHC2_CLK_FREQ
|
||||
#define BOARD_MMC_HOST_IRQ USDHC2_IRQn
|
||||
#define BOARD_MMC_VCCQ_SUPPLY kMMC_VoltageWindow170to195
|
||||
#define BOARD_MMC_VCC_SUPPLY kMMC_VoltageWindows270to360
|
||||
/* we are using the BB SD socket to DEMO the MMC example,but the
|
||||
* SD socket provide 4bit bus only, so we define this macro to avoid
|
||||
* 8bit data bus test
|
||||
*/
|
||||
#define BOARD_MMC_SUPPORT_8BIT_BUS (1U)
|
||||
|
||||
#define BOARD_SD_HOST_SUPPORT_SDR104_FREQ (200000000U)
|
||||
#define BOARD_SD_HOST_SUPPORT_HS200_FREQ (180000000U)
|
||||
|
||||
/* @Brief Board accelerator sensor configuration */
|
||||
#define BOARD_ACCEL_I2C_BASEADDR LPI2C1
|
||||
/* Select USB1 PLL (480 MHz) as LPI2C's clock source */
|
||||
#define BOARD_ACCEL_I2C_CLOCK_SOURCE_SELECT (0U)
|
||||
/* Clock divider for LPI2C clock source */
|
||||
#define BOARD_ACCEL_I2C_CLOCK_SOURCE_DIVIDER (5U)
|
||||
#define BOARD_ACCEL_I2C_CLOCK_FREQ (CLOCK_GetFreq(kCLOCK_Usb1PllClk) / 8 / (BOARD_ACCEL_I2C_CLOCK_SOURCE_DIVIDER + 1U))
|
||||
|
||||
#define BOARD_CODEC_I2C_BASEADDR LPI2C1
|
||||
#define BOARD_CODEC_I2C_INSTANCE 1U
|
||||
#define BOARD_CODEC_I2C_CLOCK_SOURCE_SELECT (0U)
|
||||
#define BOARD_CODEC_I2C_CLOCK_SOURCE_DIVIDER (5U)
|
||||
#define BOARD_CODEC_I2C_CLOCK_FREQ (10000000U)
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
void BOARD_ConfigMPU(void);
|
||||
void BOARD_SD_Pin_Config(uint32_t speed, uint32_t strength);
|
||||
void BOARD_MMC_Pin_Config(uint32_t speed, uint32_t strength);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _BOARD_H_ */
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* Copyright 2017-2019 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file clock_config.h
|
||||
* @brief define imxrt1052-board clock configure
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021-05-29
|
||||
*/
|
||||
|
||||
#ifndef _CLOCK_CONFIG_H_
|
||||
#define _CLOCK_CONFIG_H_
|
||||
|
||||
#include "fsl_common.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
#define BOARD_XTAL0_CLK_HZ 24000000U /*!< Board xtal0 frequency in Hz */
|
||||
|
||||
#define BOARD_XTAL32K_CLK_HZ 32768U /*!< Board xtal32k frequency in Hz */
|
||||
/*******************************************************************************
|
||||
************************ BOARD_InitBootClocks function ************************
|
||||
******************************************************************************/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif /* __cplusplus*/
|
||||
|
||||
/*!
|
||||
* @brief This function executes default configuration of clocks.
|
||||
*
|
||||
*/
|
||||
void BOARD_InitBootClocks(void);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif /* __cplusplus*/
|
||||
|
||||
/*******************************************************************************
|
||||
********************** Configuration BOARD_BootClockRUN ***********************
|
||||
******************************************************************************/
|
||||
/*******************************************************************************
|
||||
* Definitions for BOARD_BootClockRUN configuration
|
||||
******************************************************************************/
|
||||
#define BOARD_BOOTCLOCKRUN_CORE_CLOCK 600000000U /*!< Core clock frequency: 600000000Hz */
|
||||
|
||||
/*! @brief Arm PLL set for BOARD_BootClockRUN configuration.
|
||||
*/
|
||||
extern const clock_arm_pll_config_t armPllConfig_BOARD_BootClockRUN;
|
||||
/*! @brief Usb1 PLL set for BOARD_BootClockRUN configuration.
|
||||
*/
|
||||
extern const clock_usb_pll_config_t usb1PllConfig_BOARD_BootClockRUN;
|
||||
/*! @brief Sys PLL for BOARD_BootClockRUN configuration.
|
||||
*/
|
||||
extern const clock_sys_pll_config_t sysPllConfig_BOARD_BootClockRUN;
|
||||
|
||||
/*******************************************************************************
|
||||
* API for BOARD_BootClockRUN configuration
|
||||
******************************************************************************/
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif /* __cplusplus*/
|
||||
|
||||
/*!
|
||||
* @brief This function executes configuration of clocks.
|
||||
*
|
||||
*/
|
||||
void BOARD_BootClockRUN(void);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif /* __cplusplus*/
|
||||
|
||||
#endif /* _CLOCK_CONFIG_H_ */
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* Copyright 2017-2019 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file pin_mux.h
|
||||
* @brief define imxrt1052-board pin configure
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021-05-29
|
||||
*/
|
||||
|
||||
/***********************************************************************************************************************
|
||||
* 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.
|
||||
**********************************************************************************************************************/
|
||||
|
||||
#ifndef _PIN_MUX_H_
|
||||
#define _PIN_MUX_H_
|
||||
|
||||
/***********************************************************************************************************************
|
||||
* Definitions
|
||||
**********************************************************************************************************************/
|
||||
|
||||
/*! @brief Direction type */
|
||||
typedef enum _pin_mux_direction
|
||||
{
|
||||
kPIN_MUX_DirectionInput = 0U, /* Input direction */
|
||||
kPIN_MUX_DirectionOutput = 1U, /* Output direction */
|
||||
kPIN_MUX_DirectionInputOrOutput = 2U /* Input or output direction */
|
||||
} pin_mux_direction_t;
|
||||
|
||||
/*!
|
||||
* @addtogroup pin_mux
|
||||
* @{
|
||||
*/
|
||||
|
||||
/***********************************************************************************************************************
|
||||
* API
|
||||
**********************************************************************************************************************/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @brief Calls initialization functions.
|
||||
*
|
||||
*/
|
||||
void BOARD_InitBootPins(void);
|
||||
|
||||
/* GPIO_AD_B0_13 (coord L14), UART1_RXD */
|
||||
#define BOARD_INITPINS_UART1_RXD_PERIPHERAL LPUART1 /*!< Device name: LPUART1 */
|
||||
#define BOARD_INITPINS_UART1_RXD_SIGNAL RX /*!< LPUART1 signal: RX */
|
||||
|
||||
/* GPIO_AD_B0_12 (coord K14), UART1_TXD */
|
||||
#define BOARD_INITPINS_UART1_TXD_PERIPHERAL LPUART1 /*!< Device name: LPUART1 */
|
||||
#define BOARD_INITPINS_UART1_TXD_SIGNAL TX /*!< LPUART1 signal: TX */
|
||||
|
||||
/* GPIO_AD_B0_09 (coord F14), BSP_LED */
|
||||
#define BOARD_INITPINS_BSP_LED_GPIO GPIO1 /*!< GPIO device name: GPIO1 */
|
||||
#define BOARD_INITPINS_BSP_LED_PORT GPIO1 /*!< PORT device name: GPIO1 */
|
||||
#define BOARD_INITPINS_BSP_LED_PIN 9U /*!< GPIO1 pin index: 9 */
|
||||
|
||||
|
||||
/*!
|
||||
* @brief Configures pin routing and optionally pin electrical features.
|
||||
*
|
||||
*/
|
||||
void BOARD_InitPins(void);
|
||||
void BOARD_InitI2C1Pins(void);
|
||||
void BOARD_InitSPIPins(void);
|
||||
void BOARD_InitUartPins(void);
|
||||
void BOARD_InitCh438Pins(void);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @}
|
||||
*/
|
||||
#endif /* _PIN_MUX_H_ */
|
||||
|
||||
/***********************************************************************************************************************
|
||||
* EOF
|
||||
**********************************************************************************************************************/
|
|
@ -0,0 +1,262 @@
|
|||
/*
|
||||
** ###################################################################
|
||||
** Processors: MIMXRT1052CVJ5B
|
||||
** MIMXRT1052CVL5B
|
||||
** MIMXRT1052DVJ6B
|
||||
** MIMXRT1052DVL6B
|
||||
**
|
||||
** Compiler: GNU C Compiler
|
||||
** Reference manual: IMXRT1050RM Rev.1, 03/2018
|
||||
** Version: rev. 1.0, 2018-09-21
|
||||
** Build: b180921
|
||||
**
|
||||
** Abstract:
|
||||
** Linker file for the GNU C Compiler
|
||||
**
|
||||
** Copyright 2016 Freescale Semiconductor, Inc.
|
||||
** Copyright 2016-2018 NXP
|
||||
** All rights reserved.
|
||||
**
|
||||
** SPDX-License-Identifier: BSD-3-Clause
|
||||
**
|
||||
** http: www.nxp.com
|
||||
** mail: support@nxp.com
|
||||
**
|
||||
** ###################################################################
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @file link.lds
|
||||
* @brief xidatong Linker script
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021-05-28
|
||||
*/
|
||||
|
||||
/*************************************************
|
||||
File name: link.lds
|
||||
Description: xidatong Linker script
|
||||
Others: take MIMXRT1052xxxxx_flexspi_nor.ld for references
|
||||
History:
|
||||
1. Date: 2021-05-28
|
||||
Author: AIIT XUOS Lab
|
||||
Modification:
|
||||
1. add shell cmd table and g_service_table
|
||||
*************************************************/
|
||||
|
||||
/* Entry Point */
|
||||
ENTRY(Reset_Handler)
|
||||
|
||||
HEAP_SIZE = DEFINED(__heap_size__) ? __heap_size__ : 0x0400;
|
||||
STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x1000;
|
||||
|
||||
/* Specify the memory areas */
|
||||
MEMORY
|
||||
{
|
||||
m_boot_data (RX) : ORIGIN = 0x60000000, LENGTH = 0x00001000
|
||||
m_image_vertor_table (RX) : ORIGIN = 0x60001000, LENGTH = 0x00001000
|
||||
|
||||
m_interrupts (RX) : ORIGIN = 0x60002000, LENGTH = 0x00000400
|
||||
m_text (RX) : ORIGIN = 0x60002400, LENGTH = 0x03FFDC00
|
||||
m_data (RW) : ORIGIN = 0x20000000, LENGTH = 0x00020000
|
||||
m_data2 (RW) : ORIGIN = 0x20200000, LENGTH = 0x00060000
|
||||
}
|
||||
|
||||
/* Define output sections */
|
||||
SECTIONS
|
||||
{
|
||||
.boot_data :
|
||||
{
|
||||
KEEP(*(.boot_hdr.conf))
|
||||
} > m_boot_data
|
||||
|
||||
.image_vertor_table :
|
||||
{
|
||||
KEEP(*(.boot_hdr.ivt))
|
||||
KEEP(*(.boot_hdr.boot_data))
|
||||
KEEP(*(.boot_hdr.dcd_data))
|
||||
} > m_image_vertor_table
|
||||
|
||||
/* The startup code goes first into internal RAM */
|
||||
.interrupts :
|
||||
{
|
||||
__VECTOR_TABLE = .;
|
||||
. = ALIGN(4);
|
||||
KEEP(*(.isr_vector)) /* Startup code */
|
||||
. = ALIGN(4);
|
||||
} > m_interrupts
|
||||
|
||||
__VECTOR_RAM = __VECTOR_TABLE;
|
||||
__RAM_VECTOR_TABLE_SIZE_BYTES = 0x0;
|
||||
|
||||
/* 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
|
||||
|
||||
__NDATA_ROM = __DATA_ROM + (__data_end__ - __data_start__);
|
||||
.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_data
|
||||
. = __noncachedata_init_end__;
|
||||
.ncache :
|
||||
{
|
||||
*(NonCacheable)
|
||||
. = ALIGN(4);
|
||||
__noncachedata_end__ = .; /* define a global symbol at ncache data end */
|
||||
} > m_data
|
||||
|
||||
__DATA_END = __NDATA_ROM + (__noncachedata_init_end__ - __noncachedata_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
|
||||
|
||||
.stack :
|
||||
{
|
||||
. = ALIGN(8);
|
||||
stack_start = .;
|
||||
. += STACK_SIZE;
|
||||
stack_end = .;
|
||||
__StackTop = .;
|
||||
heap_start = .;
|
||||
} > m_data
|
||||
|
||||
PROVIDE(heap_end = ORIGIN(m_data) + LENGTH(m_data));
|
||||
|
||||
.ARM.attributes 0 : { *(.ARM.attributes) }
|
||||
}
|
||||
|
|
@ -0,0 +1,265 @@
|
|||
/*
|
||||
** ###################################################################
|
||||
** Processors: MIMXRT1052CVJ5B
|
||||
** MIMXRT1052CVL5B
|
||||
** MIMXRT1052DVJ6B
|
||||
** MIMXRT1052DVL6B
|
||||
**
|
||||
** Compiler: GNU C Compiler
|
||||
** Reference manual: IMXRT1050RM Rev.1, 03/2018
|
||||
** Version: rev. 1.0, 2018-09-21
|
||||
** Build: b180921
|
||||
**
|
||||
** Abstract:
|
||||
** Linker file for the GNU C Compiler
|
||||
**
|
||||
** Copyright 2016 Freescale Semiconductor, Inc.
|
||||
** Copyright 2016-2018 NXP
|
||||
** All rights reserved.
|
||||
**
|
||||
** SPDX-License-Identifier: BSD-3-Clause
|
||||
**
|
||||
** http: www.nxp.com
|
||||
** mail: support@nxp.com
|
||||
**
|
||||
** ###################################################################
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @file link.lds
|
||||
* @brief xidatong Linker script
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021-05-28
|
||||
*/
|
||||
|
||||
/*************************************************
|
||||
File name: link.lds
|
||||
Description: xidatong Linker script
|
||||
Others: take MIMXRT1052xxxxx_flexspi_nor.ld for references
|
||||
History:
|
||||
1. Date: 2021-05-28
|
||||
Author: AIIT XUOS Lab
|
||||
Modification:
|
||||
1. add shell cmd table and g_service_table
|
||||
*************************************************/
|
||||
|
||||
/* Entry Point */
|
||||
ENTRY(Reset_Handler)
|
||||
|
||||
HEAP_SIZE = DEFINED(__heap_size__) ? __heap_size__ : 0x0400;
|
||||
STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x1000;
|
||||
|
||||
/* Specify the memory areas */
|
||||
MEMORY
|
||||
{
|
||||
m_boot_data (RX) : ORIGIN = 0x60000000, LENGTH = 0x00001000
|
||||
m_image_vertor_table (RX) : ORIGIN = 0x60001000, LENGTH = 0x00001000
|
||||
|
||||
m_interrupts (RX) : ORIGIN = 0x60002000, LENGTH = 0x00000400
|
||||
m_text (RX) : ORIGIN = 0x60002400, LENGTH = 0x03FFDC00
|
||||
m_data (RW) : ORIGIN = 0x20000000, LENGTH = 0x00020000
|
||||
m_data2 (RW) : ORIGIN = 0x20200000, LENGTH = 0x00060000
|
||||
|
||||
m_sdram (RW) : ORIGIN = 0x80000000, LENGTH = 0x01E00000
|
||||
m_nocache (RW) : ORIGIN = 0x81E00000, LENGTH = 0x00200000
|
||||
}
|
||||
|
||||
/* Define output sections */
|
||||
SECTIONS
|
||||
{
|
||||
.boot_data :
|
||||
{
|
||||
KEEP(*(.boot_hdr.conf))
|
||||
} > m_boot_data
|
||||
|
||||
.image_vertor_table :
|
||||
{
|
||||
KEEP(*(.boot_hdr.ivt))
|
||||
KEEP(*(.boot_hdr.boot_data))
|
||||
KEEP(*(.boot_hdr.dcd_data))
|
||||
} > m_image_vertor_table
|
||||
|
||||
/* The startup code goes first into internal RAM */
|
||||
.interrupts :
|
||||
{
|
||||
__VECTOR_TABLE = .;
|
||||
. = ALIGN(4);
|
||||
KEEP(*(.isr_vector)) /* Startup code */
|
||||
. = ALIGN(4);
|
||||
} > m_interrupts
|
||||
|
||||
__VECTOR_RAM = __VECTOR_TABLE;
|
||||
__RAM_VECTOR_TABLE_SIZE_BYTES = 0x0;
|
||||
|
||||
/* 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
|
||||
|
||||
__NDATA_ROM = __DATA_ROM + (__data_end__ - __data_start__);
|
||||
.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_nocache
|
||||
. = __noncachedata_init_end__;
|
||||
.ncache :
|
||||
{
|
||||
*(NonCacheable)
|
||||
. = ALIGN(4);
|
||||
__noncachedata_end__ = .; /* define a global symbol at ncache data end */
|
||||
} > m_nocache
|
||||
|
||||
__DATA_END = __NDATA_ROM + (__noncachedata_init_end__ - __noncachedata_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
|
||||
|
||||
.stack :
|
||||
{
|
||||
. = ALIGN(8);
|
||||
stack_start = .;
|
||||
. += STACK_SIZE;
|
||||
stack_end = .;
|
||||
__StackTop = .;
|
||||
heap_start = .;
|
||||
} > m_data2
|
||||
|
||||
PROVIDE(heap_end = ORIGIN(m_data2) + LENGTH(m_data2));
|
||||
|
||||
.ARM.attributes 0 : { *(.ARM.attributes) }
|
||||
}
|
||||
|
|
@ -0,0 +1,266 @@
|
|||
/**************************************************************************//**
|
||||
* @file cmsis_compiler.h
|
||||
* @brief CMSIS compiler generic header file
|
||||
* @version V5.0.4
|
||||
* @date 10. January 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 (armclang)
|
||||
*/
|
||||
#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
|
||||
#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
|
||||
#warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored.
|
||||
#define __RESTRICT
|
||||
#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
|
||||
|
||||
|
||||
/*
|
||||
* 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
|
||||
|
||||
|
||||
#else
|
||||
#error Unknown compiler.
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* __CMSIS_COMPILER_H */
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
/**************************************************************************//**
|
||||
* @file cmsis_version.h
|
||||
* @brief CMSIS Core(M) Version definitions
|
||||
* @version V5.0.2
|
||||
* @date 19. April 2017
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2009-2017 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 ( 1U) /*!< [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
|
|
@ -0,0 +1,197 @@
|
|||
/******************************************************************************
|
||||
* @file mpu_armv7.h
|
||||
* @brief CMSIS MPU API for Armv7-M MPU
|
||||
* @version V5.0.4
|
||||
* @date 10. January 2018
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2017-2018 Arm Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#if defined ( __ICCARM__ )
|
||||
#pragma system_include /* treat file as system include file for MISRA check */
|
||||
#elif defined (__clang__)
|
||||
#pragma clang system_header /* treat file as system include file */
|
||||
#endif
|
||||
|
||||
#ifndef ARM_MPU_ARMV7_H
|
||||
#define ARM_MPU_ARMV7_H
|
||||
|
||||
#define ARM_MPU_REGION_SIZE_32B ((uint8_t)0x04U)
|
||||
#define ARM_MPU_REGION_SIZE_64B ((uint8_t)0x05U)
|
||||
#define ARM_MPU_REGION_SIZE_128B ((uint8_t)0x06U)
|
||||
#define ARM_MPU_REGION_SIZE_256B ((uint8_t)0x07U)
|
||||
#define ARM_MPU_REGION_SIZE_512B ((uint8_t)0x08U)
|
||||
#define ARM_MPU_REGION_SIZE_1KB ((uint8_t)0x09U)
|
||||
#define ARM_MPU_REGION_SIZE_2KB ((uint8_t)0x0AU)
|
||||
#define ARM_MPU_REGION_SIZE_4KB ((uint8_t)0x0BU)
|
||||
#define ARM_MPU_REGION_SIZE_8KB ((uint8_t)0x0CU)
|
||||
#define ARM_MPU_REGION_SIZE_16KB ((uint8_t)0x0DU)
|
||||
#define ARM_MPU_REGION_SIZE_32KB ((uint8_t)0x0EU)
|
||||
#define ARM_MPU_REGION_SIZE_64KB ((uint8_t)0x0FU)
|
||||
#define ARM_MPU_REGION_SIZE_128KB ((uint8_t)0x10U)
|
||||
#define ARM_MPU_REGION_SIZE_256KB ((uint8_t)0x11U)
|
||||
#define ARM_MPU_REGION_SIZE_512KB ((uint8_t)0x12U)
|
||||
#define ARM_MPU_REGION_SIZE_1MB ((uint8_t)0x13U)
|
||||
#define ARM_MPU_REGION_SIZE_2MB ((uint8_t)0x14U)
|
||||
#define ARM_MPU_REGION_SIZE_4MB ((uint8_t)0x15U)
|
||||
#define ARM_MPU_REGION_SIZE_8MB ((uint8_t)0x16U)
|
||||
#define ARM_MPU_REGION_SIZE_16MB ((uint8_t)0x17U)
|
||||
#define ARM_MPU_REGION_SIZE_32MB ((uint8_t)0x18U)
|
||||
#define ARM_MPU_REGION_SIZE_64MB ((uint8_t)0x19U)
|
||||
#define ARM_MPU_REGION_SIZE_128MB ((uint8_t)0x1AU)
|
||||
#define ARM_MPU_REGION_SIZE_256MB ((uint8_t)0x1BU)
|
||||
#define ARM_MPU_REGION_SIZE_512MB ((uint8_t)0x1CU)
|
||||
#define ARM_MPU_REGION_SIZE_1GB ((uint8_t)0x1DU)
|
||||
#define ARM_MPU_REGION_SIZE_2GB ((uint8_t)0x1EU)
|
||||
#define ARM_MPU_REGION_SIZE_4GB ((uint8_t)0x1FU)
|
||||
|
||||
#define ARM_MPU_AP_NONE 0U
|
||||
#define ARM_MPU_AP_PRIV 1U
|
||||
#define ARM_MPU_AP_URO 2U
|
||||
#define ARM_MPU_AP_FULL 3U
|
||||
#define ARM_MPU_AP_PRO 5U
|
||||
#define ARM_MPU_AP_RO 6U
|
||||
|
||||
/** 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 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) \
|
||||
((((DisableExec ) << MPU_RASR_XN_Pos) & MPU_RASR_XN_Msk) | \
|
||||
(((AccessPermission) << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk) | \
|
||||
(((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) | \
|
||||
(((SubRegionDisable) << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk) | \
|
||||
(((Size ) << MPU_RASR_SIZE_Pos) & MPU_RASR_SIZE_Msk) | \
|
||||
(MPU_RASR_ENABLE_Msk))
|
||||
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
__DSB();
|
||||
__ISB();
|
||||
MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk;
|
||||
#ifdef SCB_SHCSR_MEMFAULTENA_Msk
|
||||
SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk;
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Disable the MPU.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_Disable(void)
|
||||
{
|
||||
__DSB();
|
||||
__ISB();
|
||||
#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 orderedCpy(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) {
|
||||
orderedCpy(&(MPU->RBAR), &(table->RBAR), MPU_TYPE_RALIASES*rowWordSize);
|
||||
table += MPU_TYPE_RALIASES;
|
||||
cnt -= MPU_TYPE_RALIASES;
|
||||
}
|
||||
orderedCpy(&(MPU->RBAR), &(table->RBAR), cnt*rowWordSize);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,201 @@
|
|||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright {yyyy} {name of copyright owner}
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
|
@ -0,0 +1,83 @@
|
|||
menuconfig BSP_USING_LPUART
|
||||
bool "Using UART device"
|
||||
default y
|
||||
select RESOURCES_SERIAL
|
||||
if BSP_USING_LPUART
|
||||
source "$BSP_DIR/third_party_driver/uart/Kconfig"
|
||||
endif
|
||||
|
||||
menuconfig BSP_USING_CH438
|
||||
bool "Using CH438 device"
|
||||
default n
|
||||
if BSP_USING_CH438
|
||||
source "$BSP_DIR/third_party_driver/ch438/Kconfig"
|
||||
endif
|
||||
|
||||
menuconfig BSP_USING_GPIO
|
||||
bool "Using GPIO device "
|
||||
default y
|
||||
select RESOURCES_PIN
|
||||
if BSP_USING_GPIO
|
||||
source "$BSP_DIR/third_party_driver/gpio/Kconfig"
|
||||
endif
|
||||
|
||||
menuconfig BSP_USING_I2C
|
||||
bool "Using I2C device"
|
||||
default n
|
||||
select RESOURCES_I2C
|
||||
|
||||
if BSP_USING_I2C
|
||||
source "$BSP_DIR/third_party_driver/i2c/Kconfig"
|
||||
endif
|
||||
|
||||
menuconfig BSP_USING_LWIP
|
||||
bool "Using LwIP device"
|
||||
default n
|
||||
select RESOURCES_LWIP
|
||||
|
||||
menuconfig BSP_USING_SEMC
|
||||
bool "Using SEMC device"
|
||||
default n
|
||||
if BSP_USING_SEMC
|
||||
source "$BSP_DIR/third_party_driver/semc/Kconfig"
|
||||
endif
|
||||
|
||||
menuconfig BSP_USING_SDIO
|
||||
bool "Using SD card device"
|
||||
default n
|
||||
select RESOURCES_SDIO
|
||||
if BSP_USING_SDIO
|
||||
source "$BSP_DIR/third_party_driver/sdio/Kconfig"
|
||||
endif
|
||||
menuconfig BSP_USING_LCD
|
||||
bool "Using LCD device"
|
||||
default n
|
||||
select RESOURCES_LCD
|
||||
if BSP_USING_LCD
|
||||
source "$BSP_DIR/third_party_driver/lcd/Kconfig"
|
||||
endif
|
||||
menuconfig BSP_USING_TOUCH
|
||||
bool "Using TOUCH device"
|
||||
default n
|
||||
select RESOURCES_TOUCH
|
||||
select BSP_USING_I2C
|
||||
select BSP_USING_LCD
|
||||
if BSP_USING_TOUCH
|
||||
source "$BSP_DIR/third_party_driver/touch/Kconfig"
|
||||
endif
|
||||
|
||||
menuconfig BSP_USING_USB
|
||||
bool "Using USB device"
|
||||
default n
|
||||
select RESOURCES_USB
|
||||
if BSP_USING_USB
|
||||
source "$BSP_DIR/third_party_driver/usb/Kconfig"
|
||||
endif
|
||||
|
||||
menuconfig BSP_USING_WDT
|
||||
bool "Using WATCHDOG TIMER device"
|
||||
default n
|
||||
select RESOURCES_WDT
|
||||
if BSP_USING_WDT
|
||||
source "$BSP_DIR/third_party_driver/wdt/Kconfig"
|
||||
endif
|
|
@ -0,0 +1,43 @@
|
|||
SRC_DIR := common gpio
|
||||
|
||||
ifeq ($(CONFIG_BSP_USING_LWIP),y)
|
||||
SRC_DIR += ethernet
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_BSP_USING_SEMC),y)
|
||||
SRC_DIR += semc
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_BSP_USING_I2C),y)
|
||||
SRC_DIR += i2c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_BSP_USING_LPUART),y)
|
||||
SRC_DIR += uart
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_BSP_USING_CH438),y)
|
||||
SRC_DIR += ch438
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_BSP_USING_SDIO),y)
|
||||
SRC_DIR += sdio
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_BSP_USING_USB),y)
|
||||
SRC_DIR += usb
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_BSP_USING_LCD),y)
|
||||
SRC_DIR += lcd
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_BSP_USING_TOUCH),y)
|
||||
SRC_DIR += touch
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_BSP_USING_WDT),y)
|
||||
SRC_DIR += wdt
|
||||
endif
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -0,0 +1,39 @@
|
|||
config CH438_BUS_NAME
|
||||
string
|
||||
default "extuart"
|
||||
|
||||
config CH438_DRIVER_NAME
|
||||
string
|
||||
default "extuart_drv"
|
||||
|
||||
config CH438_DEVICE_NAME_0
|
||||
string
|
||||
default "extuart_dev0"
|
||||
|
||||
config CH438_DEVICE_NAME_1
|
||||
string
|
||||
default "extuart_dev1"
|
||||
|
||||
config CH438_DEVICE_NAME_2
|
||||
string
|
||||
default "extuart_dev2"
|
||||
|
||||
config CH438_DEVICE_NAME_3
|
||||
string
|
||||
default "extuart_dev3"
|
||||
|
||||
config CH438_DEVICE_NAME_4
|
||||
string
|
||||
default "extuart_dev4"
|
||||
|
||||
config CH438_DEVICE_NAME_5
|
||||
string
|
||||
default "extuart_dev5"
|
||||
|
||||
config CH438_DEVICE_NAME_6
|
||||
string
|
||||
default "extuart_dev6"
|
||||
|
||||
config CH438_DEVICE_NAME_7
|
||||
string
|
||||
default "extuart_dev7"
|
|
@ -0,0 +1,4 @@
|
|||
SRC_FILES := connect_ch438.c
|
||||
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -0,0 +1,7 @@
|
|||
SRC_FILES := system_MIMXRT1052.c fsl_cache.c fsl_clock.c fsl_common.c pin_mux.c clock_config.c
|
||||
|
||||
ifeq ($(CONFIG_BSP_USING_SDIO),y)
|
||||
SRC_FILES += fsl_usdhc.c
|
||||
endif
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -0,0 +1,479 @@
|
|||
/*
|
||||
* Copyright 2017-2019 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file clock_config.c
|
||||
* @brief support imxrt1052-board clock configure
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021-05-29
|
||||
*/
|
||||
|
||||
/*
|
||||
* How to setup clock using clock driver functions:
|
||||
*
|
||||
* 1. Call CLOCK_InitXXXPLL() to configure corresponding PLL clock.
|
||||
*
|
||||
* 2. Call CLOCK_InitXXXpfd() to configure corresponding PLL pfd clock.
|
||||
*
|
||||
* 3. Call CLOCK_SetMux() to configure corresponding clock source for target clock out.
|
||||
*
|
||||
* 4. Call CLOCK_SetDiv() to configure corresponding clock divider for target clock out.
|
||||
*
|
||||
* 5. Call CLOCK_SetXtalFreq() to set XTAL frequency based on board settings.
|
||||
*
|
||||
*/
|
||||
|
||||
/* TEXT BELOW IS USED AS SETTING FOR TOOLS *************************************
|
||||
!!GlobalInfo
|
||||
product: Clocks v5.0
|
||||
processor: MIMXRT1052xxxxB
|
||||
package_id: MIMXRT1052DVL6B
|
||||
mcu_data: ksdk2_0
|
||||
processor_version: 5.0.2
|
||||
board: IMXRT1050-EVKB
|
||||
* BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/
|
||||
|
||||
#include "clock_config.h"
|
||||
#include "fsl_iomuxc.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
* Variables
|
||||
******************************************************************************/
|
||||
/* System clock frequency. */
|
||||
extern uint32_t SystemCoreClock;
|
||||
|
||||
/*******************************************************************************
|
||||
************************ BOARD_InitBootClocks function ************************
|
||||
******************************************************************************/
|
||||
void BOARD_InitBootClocks(void)
|
||||
{
|
||||
BOARD_BootClockRUN();
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
********************** Configuration BOARD_BootClockRUN ***********************
|
||||
******************************************************************************/
|
||||
/* TEXT BELOW IS USED AS SETTING FOR TOOLS *************************************
|
||||
!!Configuration
|
||||
name: BOARD_BootClockRUN
|
||||
called_from_default_init: true
|
||||
outputs:
|
||||
- {id: AHB_CLK_ROOT.outFreq, value: 600 MHz}
|
||||
- {id: CAN_CLK_ROOT.outFreq, value: 40 MHz}
|
||||
- {id: CKIL_SYNC_CLK_ROOT.outFreq, value: 32.768 kHz}
|
||||
- {id: CLK_1M.outFreq, value: 1 MHz}
|
||||
- {id: CLK_24M.outFreq, value: 24 MHz}
|
||||
- {id: CSI_CLK_ROOT.outFreq, value: 12 MHz}
|
||||
- {id: ENET1_TX_CLK.outFreq, value: 2.4 MHz}
|
||||
- {id: ENET_125M_CLK.outFreq, value: 2.4 MHz}
|
||||
- {id: ENET_25M_REF_CLK.outFreq, value: 1.2 MHz}
|
||||
- {id: FLEXIO1_CLK_ROOT.outFreq, value: 30 MHz}
|
||||
- {id: FLEXIO2_CLK_ROOT.outFreq, value: 30 MHz}
|
||||
- {id: FLEXSPI_CLK_ROOT.outFreq, value: 2880/11 MHz}
|
||||
- {id: GPT1_ipg_clk_highfreq.outFreq, value: 75 MHz}
|
||||
- {id: GPT2_ipg_clk_highfreq.outFreq, value: 75 MHz}
|
||||
- {id: IPG_CLK_ROOT.outFreq, value: 150 MHz}
|
||||
- {id: LCDIF_CLK_ROOT.outFreq, value: 67.5/7 MHz}
|
||||
- {id: LPI2C_CLK_ROOT.outFreq, value: 60 MHz}
|
||||
- {id: LPSPI_CLK_ROOT.outFreq, value: 105.6 MHz}
|
||||
- {id: LVDS1_CLK.outFreq, value: 1.2 GHz}
|
||||
- {id: MQS_MCLK.outFreq, value: 1080/17 MHz}
|
||||
- {id: PERCLK_CLK_ROOT.outFreq, value: 75 MHz}
|
||||
- {id: PLL7_MAIN_CLK.outFreq, value: 24 MHz}
|
||||
- {id: SAI1_CLK_ROOT.outFreq, value: 1080/17 MHz}
|
||||
- {id: SAI1_MCLK1.outFreq, value: 1080/17 MHz}
|
||||
- {id: SAI1_MCLK2.outFreq, value: 1080/17 MHz}
|
||||
- {id: SAI1_MCLK3.outFreq, value: 30 MHz}
|
||||
- {id: SAI2_CLK_ROOT.outFreq, value: 1080/17 MHz}
|
||||
- {id: SAI2_MCLK1.outFreq, value: 1080/17 MHz}
|
||||
- {id: SAI2_MCLK3.outFreq, value: 30 MHz}
|
||||
- {id: SAI3_CLK_ROOT.outFreq, value: 1080/17 MHz}
|
||||
- {id: SAI3_MCLK1.outFreq, value: 1080/17 MHz}
|
||||
- {id: SAI3_MCLK3.outFreq, value: 30 MHz}
|
||||
- {id: SEMC_CLK_ROOT.outFreq, value: 75 MHz}
|
||||
- {id: SPDIF0_CLK_ROOT.outFreq, value: 30 MHz}
|
||||
- {id: TRACE_CLK_ROOT.outFreq, value: 352/3 MHz}
|
||||
- {id: UART_CLK_ROOT.outFreq, value: 80 MHz}
|
||||
- {id: USDHC1_CLK_ROOT.outFreq, value: 198 MHz}
|
||||
- {id: USDHC2_CLK_ROOT.outFreq, value: 198 MHz}
|
||||
settings:
|
||||
- {id: CCM.AHB_PODF.scale, value: '1', locked: true}
|
||||
- {id: CCM.ARM_PODF.scale, value: '2', locked: true}
|
||||
- {id: CCM.FLEXSPI_PODF.scale, value: '1', locked: true}
|
||||
- {id: CCM.FLEXSPI_SEL.sel, value: CCM_ANALOG.PLL3_PFD0_CLK}
|
||||
- {id: CCM.LCDIF_PODF.scale, value: '8', locked: true}
|
||||
- {id: CCM.LCDIF_PRED.scale, value: '7', locked: true}
|
||||
- {id: CCM.LPSPI_PODF.scale, value: '5', locked: true}
|
||||
- {id: CCM.PERCLK_PODF.scale, value: '2', locked: true}
|
||||
- {id: CCM.SEMC_PODF.scale, value: '8'}
|
||||
- {id: CCM.TRACE_PODF.scale, value: '3', locked: true}
|
||||
- {id: CCM_ANALOG.PLL1_BYPASS.sel, value: CCM_ANALOG.PLL1}
|
||||
- {id: CCM_ANALOG.PLL1_PREDIV.scale, value: '1', locked: true}
|
||||
- {id: CCM_ANALOG.PLL1_VDIV.scale, value: '50', locked: true}
|
||||
- {id: CCM_ANALOG.PLL2.denom, value: '1', locked: true}
|
||||
- {id: CCM_ANALOG.PLL2.num, value: '0', locked: true}
|
||||
- {id: CCM_ANALOG.PLL2_BYPASS.sel, value: CCM_ANALOG.PLL2_OUT_CLK}
|
||||
- {id: CCM_ANALOG.PLL2_PFD0_BYPASS.sel, value: CCM_ANALOG.PLL2_PFD0}
|
||||
- {id: CCM_ANALOG.PLL2_PFD1_BYPASS.sel, value: CCM_ANALOG.PLL2_PFD1}
|
||||
- {id: CCM_ANALOG.PLL2_PFD2_BYPASS.sel, value: CCM_ANALOG.PLL2_PFD2}
|
||||
- {id: CCM_ANALOG.PLL2_PFD3_BYPASS.sel, value: CCM_ANALOG.PLL2_PFD3}
|
||||
- {id: CCM_ANALOG.PLL3_BYPASS.sel, value: CCM_ANALOG.PLL3}
|
||||
- {id: CCM_ANALOG.PLL3_PFD0_BYPASS.sel, value: CCM_ANALOG.PLL3_PFD0}
|
||||
- {id: CCM_ANALOG.PLL3_PFD0_DIV.scale, value: '33', locked: true}
|
||||
- {id: CCM_ANALOG.PLL3_PFD0_MUL.scale, value: '18', locked: true}
|
||||
- {id: CCM_ANALOG.PLL3_PFD1_BYPASS.sel, value: CCM_ANALOG.PLL3_PFD1}
|
||||
- {id: CCM_ANALOG.PLL3_PFD2_BYPASS.sel, value: CCM_ANALOG.PLL3_PFD2}
|
||||
- {id: CCM_ANALOG.PLL3_PFD3_BYPASS.sel, value: CCM_ANALOG.PLL3_PFD3}
|
||||
- {id: CCM_ANALOG.PLL4.denom, value: '50'}
|
||||
- {id: CCM_ANALOG.PLL4.div, value: '47'}
|
||||
- {id: CCM_ANALOG.PLL5.denom, value: '1'}
|
||||
- {id: CCM_ANALOG.PLL5.div, value: '40'}
|
||||
- {id: CCM_ANALOG.PLL5.num, value: '0'}
|
||||
- {id: CCM_ANALOG_PLL_ENET_POWERDOWN_CFG, value: 'Yes'}
|
||||
- {id: CCM_ANALOG_PLL_USB1_POWER_CFG, value: 'Yes'}
|
||||
sources:
|
||||
- {id: XTALOSC24M.OSC.outFreq, value: 24 MHz, enabled: true}
|
||||
- {id: XTALOSC24M.RTC_OSC.outFreq, value: 32.768 kHz, enabled: true}
|
||||
* BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/
|
||||
|
||||
/*******************************************************************************
|
||||
* Variables for BOARD_BootClockRUN configuration
|
||||
******************************************************************************/
|
||||
const clock_arm_pll_config_t armPllConfig_BOARD_BootClockRUN =
|
||||
{
|
||||
.loopDivider = 100, /* PLL loop divider, Fout = Fin * 50 */
|
||||
.src = 0, /* Bypass clock source, 0 - OSC 24M, 1 - CLK1_P and CLK1_N */
|
||||
};
|
||||
const clock_sys_pll_config_t sysPllConfig_BOARD_BootClockRUN =
|
||||
{
|
||||
.loopDivider = 1, /* PLL loop divider, Fout = Fin * ( 20 + loopDivider*2 + numerator / denominator ) */
|
||||
.numerator = 0, /* 30 bit numerator of fractional loop divider */
|
||||
.denominator = 1, /* 30 bit denominator of fractional loop divider */
|
||||
.src = 0, /* Bypass clock source, 0 - OSC 24M, 1 - CLK1_P and CLK1_N */
|
||||
};
|
||||
const clock_usb_pll_config_t usb1PllConfig_BOARD_BootClockRUN =
|
||||
{
|
||||
.loopDivider = 0, /* PLL loop divider, Fout = Fin * 20 */
|
||||
.src = 0, /* Bypass clock source, 0 - OSC 24M, 1 - CLK1_P and CLK1_N */
|
||||
};
|
||||
/*******************************************************************************
|
||||
* Code for BOARD_BootClockRUN configuration
|
||||
******************************************************************************/
|
||||
void BOARD_BootClockRUN(void)
|
||||
{
|
||||
/* Init RTC OSC clock frequency. */
|
||||
CLOCK_SetRtcXtalFreq(32768U);
|
||||
/* Enable 1MHz clock output. */
|
||||
XTALOSC24M->OSC_CONFIG2 |= XTALOSC24M_OSC_CONFIG2_ENABLE_1M_MASK;
|
||||
/* Use free 1MHz clock output. */
|
||||
XTALOSC24M->OSC_CONFIG2 &= ~XTALOSC24M_OSC_CONFIG2_MUX_1M_MASK;
|
||||
/* Set XTAL 24MHz clock frequency. */
|
||||
CLOCK_SetXtalFreq(24000000U);
|
||||
/* Enable XTAL 24MHz clock source. */
|
||||
CLOCK_InitExternalClk(0);
|
||||
/* Enable internal RC. */
|
||||
CLOCK_InitRcOsc24M();
|
||||
/* Switch clock source to external OSC. */
|
||||
CLOCK_SwitchOsc(kCLOCK_XtalOsc);
|
||||
/* Set Oscillator ready counter value. */
|
||||
CCM->CCR = (CCM->CCR & (~CCM_CCR_OSCNT_MASK)) | CCM_CCR_OSCNT(127);
|
||||
/* Setting PeriphClk2Mux and PeriphMux to provide stable clock before PLLs are initialed */
|
||||
CLOCK_SetMux(kCLOCK_PeriphClk2Mux, 1); /* Set PERIPH_CLK2 MUX to OSC */
|
||||
CLOCK_SetMux(kCLOCK_PeriphMux, 1); /* Set PERIPH_CLK MUX to PERIPH_CLK2 */
|
||||
/* Setting the VDD_SOC to 1.275V. It is necessary to config AHB to 600Mhz. */
|
||||
DCDC->REG3 = (DCDC->REG3 & (~DCDC_REG3_TRG_MASK)) | DCDC_REG3_TRG(0x13);
|
||||
/* Waiting for DCDC_STS_DC_OK bit is asserted */
|
||||
while (DCDC_REG0_STS_DC_OK_MASK != (DCDC_REG0_STS_DC_OK_MASK & DCDC->REG0))
|
||||
{
|
||||
}
|
||||
/* Set AHB_PODF. */
|
||||
CLOCK_SetDiv(kCLOCK_AhbDiv, 0);
|
||||
/* Disable IPG clock gate. */
|
||||
CLOCK_DisableClock(kCLOCK_Adc1);
|
||||
CLOCK_DisableClock(kCLOCK_Adc2);
|
||||
CLOCK_DisableClock(kCLOCK_Xbar1);
|
||||
CLOCK_DisableClock(kCLOCK_Xbar2);
|
||||
CLOCK_DisableClock(kCLOCK_Xbar3);
|
||||
/* Set IPG_PODF. */
|
||||
CLOCK_SetDiv(kCLOCK_IpgDiv, 3);
|
||||
/* Set ARM_PODF. */
|
||||
CLOCK_SetDiv(kCLOCK_ArmDiv, 1);
|
||||
/* Set PERIPH_CLK2_PODF. */
|
||||
CLOCK_SetDiv(kCLOCK_PeriphClk2Div, 0);
|
||||
/* Disable PERCLK clock gate. */
|
||||
CLOCK_DisableClock(kCLOCK_Gpt1);
|
||||
CLOCK_DisableClock(kCLOCK_Gpt1S);
|
||||
CLOCK_DisableClock(kCLOCK_Gpt2);
|
||||
CLOCK_DisableClock(kCLOCK_Gpt2S);
|
||||
CLOCK_DisableClock(kCLOCK_Pit);
|
||||
/* Set PERCLK_PODF. */
|
||||
CLOCK_SetDiv(kCLOCK_PerclkDiv, 1);
|
||||
/* Disable USDHC1 clock gate. */
|
||||
CLOCK_DisableClock(kCLOCK_Usdhc1);
|
||||
/* Set USDHC1_PODF. */
|
||||
CLOCK_SetDiv(kCLOCK_Usdhc1Div, 1);
|
||||
/* Set Usdhc1 clock source. */
|
||||
CLOCK_SetMux(kCLOCK_Usdhc1Mux, 0);
|
||||
/* Disable USDHC2 clock gate. */
|
||||
CLOCK_DisableClock(kCLOCK_Usdhc2);
|
||||
/* Set USDHC2_PODF. */
|
||||
CLOCK_SetDiv(kCLOCK_Usdhc2Div, 1);
|
||||
/* Set Usdhc2 clock source. */
|
||||
CLOCK_SetMux(kCLOCK_Usdhc2Mux, 0);
|
||||
/* In SDK projects, SDRAM (configured by SEMC) will be initialized in either debug script or dcd.
|
||||
* With this macro SKIP_SYSCLK_INIT, system pll (selected to be SEMC source clock in SDK projects) will be left unchanged.
|
||||
* Note: If another clock source is selected for SEMC, user may want to avoid changing that clock as well.*/
|
||||
#ifndef SKIP_SYSCLK_INIT
|
||||
/* Disable Semc clock gate. */
|
||||
CLOCK_DisableClock(kCLOCK_Semc);
|
||||
/* Set SEMC_PODF. */
|
||||
CLOCK_SetDiv(kCLOCK_SemcDiv, 7);
|
||||
/* Set Semc alt clock source. */
|
||||
CLOCK_SetMux(kCLOCK_SemcAltMux, 0);
|
||||
/* Set Semc clock source. */
|
||||
CLOCK_SetMux(kCLOCK_SemcMux, 0);
|
||||
#endif
|
||||
/* In SDK projects, external flash (configured by FLEXSPI) will be initialized by dcd.
|
||||
* With this macro XIP_EXTERNAL_FLASH, usb1 pll (selected to be FLEXSPI clock source in SDK projects) will be left unchanged.
|
||||
* Note: If another clock source is selected for FLEXSPI, user may want to avoid changing that clock as well.*/
|
||||
#if !(defined(XIP_EXTERNAL_FLASH) && (XIP_EXTERNAL_FLASH == 1))
|
||||
/* Disable Flexspi clock gate. */
|
||||
CLOCK_DisableClock(kCLOCK_FlexSpi);
|
||||
/* Set FLEXSPI_PODF. */
|
||||
CLOCK_SetDiv(kCLOCK_FlexspiDiv, 0);
|
||||
/* Set Flexspi clock source. */
|
||||
CLOCK_SetMux(kCLOCK_FlexspiMux, 3);
|
||||
#endif
|
||||
/* Disable CSI clock gate. */
|
||||
CLOCK_DisableClock(kCLOCK_Csi);
|
||||
/* Set CSI_PODF. */
|
||||
CLOCK_SetDiv(kCLOCK_CsiDiv, 1);
|
||||
/* Set Csi clock source. */
|
||||
CLOCK_SetMux(kCLOCK_CsiMux, 0);
|
||||
/* Disable LPSPI clock gate. */
|
||||
CLOCK_DisableClock(kCLOCK_Lpspi1);
|
||||
CLOCK_DisableClock(kCLOCK_Lpspi2);
|
||||
CLOCK_DisableClock(kCLOCK_Lpspi3);
|
||||
CLOCK_DisableClock(kCLOCK_Lpspi4);
|
||||
/* Set LPSPI_PODF. */
|
||||
CLOCK_SetDiv(kCLOCK_LpspiDiv, 4);
|
||||
/* Set Lpspi clock source. */
|
||||
CLOCK_SetMux(kCLOCK_LpspiMux, 2);
|
||||
/* Disable TRACE clock gate. */
|
||||
CLOCK_DisableClock(kCLOCK_Trace);
|
||||
/* Set TRACE_PODF. */
|
||||
CLOCK_SetDiv(kCLOCK_TraceDiv, 2);
|
||||
/* Set Trace clock source. */
|
||||
CLOCK_SetMux(kCLOCK_TraceMux, 2);
|
||||
/* Disable SAI1 clock gate. */
|
||||
CLOCK_DisableClock(kCLOCK_Sai1);
|
||||
/* Set SAI1_CLK_PRED. */
|
||||
CLOCK_SetDiv(kCLOCK_Sai1PreDiv, 3);
|
||||
/* Set SAI1_CLK_PODF. */
|
||||
CLOCK_SetDiv(kCLOCK_Sai1Div, 1);
|
||||
/* Set Sai1 clock source. */
|
||||
CLOCK_SetMux(kCLOCK_Sai1Mux, 0);
|
||||
/* Disable SAI2 clock gate. */
|
||||
CLOCK_DisableClock(kCLOCK_Sai2);
|
||||
/* Set SAI2_CLK_PRED. */
|
||||
CLOCK_SetDiv(kCLOCK_Sai2PreDiv, 3);
|
||||
/* Set SAI2_CLK_PODF. */
|
||||
CLOCK_SetDiv(kCLOCK_Sai2Div, 1);
|
||||
/* Set Sai2 clock source. */
|
||||
CLOCK_SetMux(kCLOCK_Sai2Mux, 0);
|
||||
/* Disable SAI3 clock gate. */
|
||||
CLOCK_DisableClock(kCLOCK_Sai3);
|
||||
/* Set SAI3_CLK_PRED. */
|
||||
CLOCK_SetDiv(kCLOCK_Sai3PreDiv, 3);
|
||||
/* Set SAI3_CLK_PODF. */
|
||||
CLOCK_SetDiv(kCLOCK_Sai3Div, 1);
|
||||
/* Set Sai3 clock source. */
|
||||
CLOCK_SetMux(kCLOCK_Sai3Mux, 0);
|
||||
/* Disable Lpi2c clock gate. */
|
||||
CLOCK_DisableClock(kCLOCK_Lpi2c1);
|
||||
CLOCK_DisableClock(kCLOCK_Lpi2c2);
|
||||
CLOCK_DisableClock(kCLOCK_Lpi2c3);
|
||||
/* Set LPI2C_CLK_PODF. */
|
||||
CLOCK_SetDiv(kCLOCK_Lpi2cDiv, 0);
|
||||
/* Set Lpi2c clock source. */
|
||||
CLOCK_SetMux(kCLOCK_Lpi2cMux, 0);
|
||||
/* Disable CAN clock gate. */
|
||||
CLOCK_DisableClock(kCLOCK_Can1);
|
||||
CLOCK_DisableClock(kCLOCK_Can2);
|
||||
CLOCK_DisableClock(kCLOCK_Can1S);
|
||||
CLOCK_DisableClock(kCLOCK_Can2S);
|
||||
/* Set CAN_CLK_PODF. */
|
||||
CLOCK_SetDiv(kCLOCK_CanDiv, 1);
|
||||
/* Set Can clock source. */
|
||||
CLOCK_SetMux(kCLOCK_CanMux, 2);
|
||||
/* Disable UART clock gate. */
|
||||
CLOCK_DisableClock(kCLOCK_Lpuart1);
|
||||
CLOCK_DisableClock(kCLOCK_Lpuart2);
|
||||
CLOCK_DisableClock(kCLOCK_Lpuart3);
|
||||
CLOCK_DisableClock(kCLOCK_Lpuart4);
|
||||
CLOCK_DisableClock(kCLOCK_Lpuart5);
|
||||
CLOCK_DisableClock(kCLOCK_Lpuart6);
|
||||
CLOCK_DisableClock(kCLOCK_Lpuart7);
|
||||
CLOCK_DisableClock(kCLOCK_Lpuart8);
|
||||
/* Set UART_CLK_PODF. */
|
||||
CLOCK_SetDiv(kCLOCK_UartDiv, 0);
|
||||
/* Set Uart clock source. */
|
||||
CLOCK_SetMux(kCLOCK_UartMux, 0);
|
||||
/* Disable LCDIF clock gate. */
|
||||
CLOCK_DisableClock(kCLOCK_LcdPixel);
|
||||
/* Set LCDIF_PRED. */
|
||||
CLOCK_SetDiv(kCLOCK_LcdifPreDiv, 6);
|
||||
/* Set LCDIF_CLK_PODF. */
|
||||
CLOCK_SetDiv(kCLOCK_LcdifDiv, 7);
|
||||
/* Set Lcdif pre clock source. */
|
||||
CLOCK_SetMux(kCLOCK_LcdifPreMux, 5);
|
||||
/* Disable SPDIF clock gate. */
|
||||
CLOCK_DisableClock(kCLOCK_Spdif);
|
||||
/* Set SPDIF0_CLK_PRED. */
|
||||
CLOCK_SetDiv(kCLOCK_Spdif0PreDiv, 1);
|
||||
/* Set SPDIF0_CLK_PODF. */
|
||||
CLOCK_SetDiv(kCLOCK_Spdif0Div, 7);
|
||||
/* Set Spdif clock source. */
|
||||
CLOCK_SetMux(kCLOCK_SpdifMux, 3);
|
||||
/* Disable Flexio1 clock gate. */
|
||||
CLOCK_DisableClock(kCLOCK_Flexio1);
|
||||
/* Set FLEXIO1_CLK_PRED. */
|
||||
CLOCK_SetDiv(kCLOCK_Flexio1PreDiv, 1);
|
||||
/* Set FLEXIO1_CLK_PODF. */
|
||||
CLOCK_SetDiv(kCLOCK_Flexio1Div, 7);
|
||||
/* Set Flexio1 clock source. */
|
||||
CLOCK_SetMux(kCLOCK_Flexio1Mux, 3);
|
||||
/* Disable Flexio2 clock gate. */
|
||||
CLOCK_DisableClock(kCLOCK_Flexio2);
|
||||
/* Set FLEXIO2_CLK_PRED. */
|
||||
CLOCK_SetDiv(kCLOCK_Flexio2PreDiv, 1);
|
||||
/* Set FLEXIO2_CLK_PODF. */
|
||||
CLOCK_SetDiv(kCLOCK_Flexio2Div, 7);
|
||||
/* Set Flexio2 clock source. */
|
||||
CLOCK_SetMux(kCLOCK_Flexio2Mux, 3);
|
||||
/* Set Pll3 sw clock source. */
|
||||
CLOCK_SetMux(kCLOCK_Pll3SwMux, 0);
|
||||
/* Init ARM PLL. */
|
||||
CLOCK_InitArmPll(&armPllConfig_BOARD_BootClockRUN);
|
||||
/* In SDK projects, SDRAM (configured by SEMC) will be initialized in either debug script or dcd.
|
||||
* With this macro SKIP_SYSCLK_INIT, system pll (selected to be SEMC source clock in SDK projects) will be left unchanged.
|
||||
* Note: If another clock source is selected for SEMC, user may want to avoid changing that clock as well.*/
|
||||
#ifndef SKIP_SYSCLK_INIT
|
||||
/* Init System PLL. */
|
||||
CLOCK_InitSysPll(&sysPllConfig_BOARD_BootClockRUN);
|
||||
/* Init System pfd0. */
|
||||
CLOCK_InitSysPfd(kCLOCK_Pfd0, 27);
|
||||
/* Init System pfd1. */
|
||||
CLOCK_InitSysPfd(kCLOCK_Pfd1, 16);
|
||||
/* Init System pfd2. */
|
||||
CLOCK_InitSysPfd(kCLOCK_Pfd2, 24);
|
||||
/* Init System pfd3. */
|
||||
CLOCK_InitSysPfd(kCLOCK_Pfd3, 16);
|
||||
/* Disable pfd offset. */
|
||||
CCM_ANALOG->PLL_SYS &= ~CCM_ANALOG_PLL_SYS_PFD_OFFSET_EN_MASK;
|
||||
#endif
|
||||
/* In SDK projects, external flash (configured by FLEXSPI) will be initialized by dcd.
|
||||
* With this macro XIP_EXTERNAL_FLASH, usb1 pll (selected to be FLEXSPI clock source in SDK projects) will be left unchanged.
|
||||
* Note: If another clock source is selected for FLEXSPI, user may want to avoid changing that clock as well.*/
|
||||
#if !(defined(XIP_EXTERNAL_FLASH) && (XIP_EXTERNAL_FLASH == 1))
|
||||
/* Init Usb1 PLL. */
|
||||
CLOCK_InitUsb1Pll(&usb1PllConfig_BOARD_BootClockRUN);
|
||||
/* Init Usb1 pfd0. */
|
||||
CLOCK_InitUsb1Pfd(kCLOCK_Pfd0, 33);
|
||||
/* Init Usb1 pfd1. */
|
||||
CLOCK_InitUsb1Pfd(kCLOCK_Pfd1, 16);
|
||||
/* Init Usb1 pfd2. */
|
||||
CLOCK_InitUsb1Pfd(kCLOCK_Pfd2, 17);
|
||||
/* Init Usb1 pfd3. */
|
||||
CLOCK_InitUsb1Pfd(kCLOCK_Pfd3, 19);
|
||||
/* Disable Usb1 PLL output for USBPHY1. */
|
||||
CCM_ANALOG->PLL_USB1 &= ~CCM_ANALOG_PLL_USB1_EN_USB_CLKS_MASK;
|
||||
#endif
|
||||
/* DeInit Audio PLL. */
|
||||
CLOCK_DeinitAudioPll();
|
||||
/* Bypass Audio PLL. */
|
||||
CLOCK_SetPllBypass(CCM_ANALOG, kCLOCK_PllAudio, 1);
|
||||
/* Set divider for Audio PLL. */
|
||||
CCM_ANALOG->MISC2 &= ~CCM_ANALOG_MISC2_AUDIO_DIV_LSB_MASK;
|
||||
CCM_ANALOG->MISC2 &= ~CCM_ANALOG_MISC2_AUDIO_DIV_MSB_MASK;
|
||||
/* Enable Audio PLL output. */
|
||||
CCM_ANALOG->PLL_AUDIO |= CCM_ANALOG_PLL_AUDIO_ENABLE_MASK;
|
||||
/* DeInit Video PLL. */
|
||||
CLOCK_DeinitVideoPll();
|
||||
/* Bypass Video PLL. */
|
||||
CCM_ANALOG->PLL_VIDEO |= CCM_ANALOG_PLL_VIDEO_BYPASS_MASK;
|
||||
/* Set divider for Video PLL. */
|
||||
CCM_ANALOG->MISC2 = (CCM_ANALOG->MISC2 & (~CCM_ANALOG_MISC2_VIDEO_DIV_MASK)) | CCM_ANALOG_MISC2_VIDEO_DIV(0);
|
||||
/* Enable Video PLL output. */
|
||||
CCM_ANALOG->PLL_VIDEO |= CCM_ANALOG_PLL_VIDEO_ENABLE_MASK;
|
||||
/* DeInit Enet PLL. */
|
||||
CLOCK_DeinitEnetPll();
|
||||
/* Bypass Enet PLL. */
|
||||
CLOCK_SetPllBypass(CCM_ANALOG, kCLOCK_PllEnet, 1);
|
||||
/* Set Enet output divider. */
|
||||
CCM_ANALOG->PLL_ENET = (CCM_ANALOG->PLL_ENET & (~CCM_ANALOG_PLL_ENET_DIV_SELECT_MASK)) | CCM_ANALOG_PLL_ENET_DIV_SELECT(1);
|
||||
/* Enable Enet output. */
|
||||
CCM_ANALOG->PLL_ENET |= CCM_ANALOG_PLL_ENET_ENABLE_MASK;
|
||||
/* Enable Enet25M output. */
|
||||
CCM_ANALOG->PLL_ENET |= CCM_ANALOG_PLL_ENET_ENET_25M_REF_EN_MASK;
|
||||
/* DeInit Usb2 PLL. */
|
||||
CLOCK_DeinitUsb2Pll();
|
||||
/* Bypass Usb2 PLL. */
|
||||
CLOCK_SetPllBypass(CCM_ANALOG, kCLOCK_PllUsb2, 1);
|
||||
/* Enable Usb2 PLL output. */
|
||||
CCM_ANALOG->PLL_USB2 |= CCM_ANALOG_PLL_USB2_ENABLE_MASK;
|
||||
/* Set preperiph clock source. */
|
||||
CLOCK_SetMux(kCLOCK_PrePeriphMux, 3);
|
||||
/* Set periph clock source. */
|
||||
CLOCK_SetMux(kCLOCK_PeriphMux, 0);
|
||||
/* Set periph clock2 clock source. */
|
||||
CLOCK_SetMux(kCLOCK_PeriphClk2Mux, 0);
|
||||
/* Set per clock source. */
|
||||
CLOCK_SetMux(kCLOCK_PerclkMux, 0);
|
||||
/* Set lvds1 clock source. */
|
||||
CCM_ANALOG->MISC1 = (CCM_ANALOG->MISC1 & (~CCM_ANALOG_MISC1_LVDS1_CLK_SEL_MASK)) | CCM_ANALOG_MISC1_LVDS1_CLK_SEL(0);
|
||||
/* Set clock out1 divider. */
|
||||
CCM->CCOSR = (CCM->CCOSR & (~CCM_CCOSR_CLKO1_DIV_MASK)) | CCM_CCOSR_CLKO1_DIV(0);
|
||||
/* Set clock out1 source. */
|
||||
CCM->CCOSR = (CCM->CCOSR & (~CCM_CCOSR_CLKO1_SEL_MASK)) | CCM_CCOSR_CLKO1_SEL(1);
|
||||
/* Set clock out2 divider. */
|
||||
CCM->CCOSR = (CCM->CCOSR & (~CCM_CCOSR_CLKO2_DIV_MASK)) | CCM_CCOSR_CLKO2_DIV(0);
|
||||
/* Set clock out2 source. */
|
||||
CCM->CCOSR = (CCM->CCOSR & (~CCM_CCOSR_CLKO2_SEL_MASK)) | CCM_CCOSR_CLKO2_SEL(18);
|
||||
/* Set clock out1 drives clock out1. */
|
||||
CCM->CCOSR &= ~CCM_CCOSR_CLK_OUT_SEL_MASK;
|
||||
/* Disable clock out1. */
|
||||
CCM->CCOSR &= ~CCM_CCOSR_CLKO1_EN_MASK;
|
||||
/* Disable clock out2. */
|
||||
CCM->CCOSR &= ~CCM_CCOSR_CLKO2_EN_MASK;
|
||||
/* Set SAI1 MCLK1 clock source. */
|
||||
IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI1MClk1Sel, 0);
|
||||
/* Set SAI1 MCLK2 clock source. */
|
||||
IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI1MClk2Sel, 0);
|
||||
/* Set SAI1 MCLK3 clock source. */
|
||||
IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI1MClk3Sel, 0);
|
||||
/* Set SAI2 MCLK3 clock source. */
|
||||
IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI2MClk3Sel, 0);
|
||||
/* Set SAI3 MCLK3 clock source. */
|
||||
IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI3MClk3Sel, 0);
|
||||
/* Set MQS configuration. */
|
||||
IOMUXC_MQSConfig(IOMUXC_GPR,kIOMUXC_MqsPwmOverSampleRate32, 0);
|
||||
/* Set ENET Tx clock source. */
|
||||
IOMUXC_EnableMode(IOMUXC_GPR, kIOMUXC_GPR_ENET1RefClkMode, false);
|
||||
/* Set GPT1 High frequency reference clock source. */
|
||||
IOMUXC_GPR->GPR5 &= ~IOMUXC_GPR_GPR5_VREF_1M_CLK_GPT1_MASK;
|
||||
/* Set GPT2 High frequency reference clock source. */
|
||||
IOMUXC_GPR->GPR5 &= ~IOMUXC_GPR_GPR5_VREF_1M_CLK_GPT2_MASK;
|
||||
/* Set SystemCoreClock variable. */
|
||||
SystemCoreClock = BOARD_BOOTCLOCKRUN_CORE_CLOCK;
|
||||
}
|
||||
|
|
@ -0,0 +1,611 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2017 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file fsl_cache.c
|
||||
* @brief cache drivers
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021.11.11
|
||||
*/
|
||||
|
||||
#include "fsl_cache.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/* Component ID definition, used by tools. */
|
||||
#ifndef FSL_COMPONENT_ID
|
||||
#define FSL_COMPONENT_ID "platform.drivers.cache_armv7_m7"
|
||||
#endif
|
||||
|
||||
#if defined(FSL_FEATURE_SOC_L2CACHEC_COUNT) && FSL_FEATURE_SOC_L2CACHEC_COUNT
|
||||
#define L2CACHE_OPERATION_TIMEOUT 0xFFFFFU
|
||||
#define L2CACHE_8WAYS_MASK 0xFFU
|
||||
#define L2CACHE_16WAYS_MASK 0xFFFFU
|
||||
#define L2CACHE_SMALLWAYS_NUM 8U
|
||||
#define L2CACHE_1KBCOVERTOB 1024U
|
||||
#define L2CACHE_SAMLLWAYS_SIZE 16U
|
||||
#define L2CACHE_LOCKDOWN_REGNUM 8 /*!< Lock down register numbers.*/
|
||||
/*******************************************************************************
|
||||
* Prototypes
|
||||
******************************************************************************/
|
||||
/*!
|
||||
* @brief Set for all ways and waiting for the operation finished.
|
||||
* This is provided for all the background operations.
|
||||
*
|
||||
* @param auxCtlReg The auxiliary control register.
|
||||
* @param regAddr The register address to be operated.
|
||||
*/
|
||||
static void L2CACHE_SetAndWaitBackGroundOperate(uint32_t auxCtlReg, uint32_t regAddr);
|
||||
|
||||
/*!
|
||||
* @brief Invalidates the Level 2 cache line by physical address.
|
||||
* This function invalidates a cache line by physcial address.
|
||||
*
|
||||
* @param address The physical addderss of the cache.
|
||||
* The format of the address shall be :
|
||||
* bit 31 ~ bit n+1 | bitn ~ bit5 | bit4 ~ bit0
|
||||
* Tag | index | 0
|
||||
* Note: the physical address shall be aligned to the line size - 32B (256 bit).
|
||||
* so keep the last 5 bits (bit 4 ~ bit 0) of the physical address always be zero.
|
||||
* If the input address is not aligned, it will be changed to 32-byte aligned address.
|
||||
* The n is varies according to the index width.
|
||||
* @return The actual 32-byte aligned physical address be operated.
|
||||
*/
|
||||
static uint32_t L2CACHE_InvalidateLineByAddr(uint32_t address);
|
||||
|
||||
/*!
|
||||
* @brief Cleans the Level 2 cache line based on the physical address.
|
||||
* This function cleans a cache line based on a physcial address.
|
||||
*
|
||||
* @param address The physical addderss of the cache.
|
||||
* The format of the address shall be :
|
||||
* bit 31 ~ bit n+1 | bitn ~ bit5 | bit4 ~ bit0
|
||||
* Tag | index | 0
|
||||
* Note: the physical address shall be aligned to the line size - 32B (256 bit).
|
||||
* so keep the last 5 bits (bit 4 ~ bit 0) of the physical address always be zero.
|
||||
* If the input address is not aligned, it will be changed to 32-byte aligned address.
|
||||
* The n is varies according to the index width.
|
||||
* @return The actual 32-byte aligned physical address be operated.
|
||||
*/
|
||||
static uint32_t L2CACHE_CleanLineByAddr(uint32_t address);
|
||||
|
||||
/*!
|
||||
* @brief Cleans and invalidates the Level 2 cache line based on the physical address.
|
||||
* This function cleans and invalidates a cache line based on a physcial address.
|
||||
*
|
||||
* @param address The physical addderss of the cache.
|
||||
* The format of the address shall be :
|
||||
* bit 31 ~ bit n+1 | bitn ~ bit5 | bit4 ~ bit0
|
||||
* Tag | index | 0
|
||||
* Note: the physical address shall be aligned to the line size - 32B (256 bit).
|
||||
* so keep the last 5 bits (bit 4 ~ bit 0) of the physical address always be zero.
|
||||
* If the input address is not aligned, it will be changed to 32-byte aligned address.
|
||||
* The n is varies according to the index width.
|
||||
* @return The actual 32-byte aligned physical address be operated.
|
||||
*/
|
||||
static uint32_t L2CACHE_CleanInvalidateLineByAddr(uint32_t address);
|
||||
|
||||
/*!
|
||||
* @brief Gets the number of the Level 2 cache and the way size.
|
||||
* This function cleans and invalidates a cache line based on a physcial address.
|
||||
*
|
||||
* @param num_ways The number of the cache way.
|
||||
* @param size_way The way size.
|
||||
*/
|
||||
static void L2CACHE_GetWayNumSize(uint32_t *num_ways, uint32_t *size_way);
|
||||
/*******************************************************************************
|
||||
* Code
|
||||
******************************************************************************/
|
||||
static void L2CACHE_SetAndWaitBackGroundOperate(uint32_t auxCtlReg, uint32_t regAddr)
|
||||
{
|
||||
uint16_t mask = L2CACHE_8WAYS_MASK;
|
||||
uint32_t timeout = L2CACHE_OPERATION_TIMEOUT;
|
||||
|
||||
/* Check the ways used at first. */
|
||||
if (auxCtlReg & L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY_MASK)
|
||||
{
|
||||
mask = L2CACHE_16WAYS_MASK;
|
||||
}
|
||||
|
||||
/* Set the opeartion for all ways/entries of the cache. */
|
||||
*(uint32_t *)regAddr = mask;
|
||||
/* Waiting for until the operation is complete. */
|
||||
while ((*(volatile uint32_t *)regAddr & mask) && timeout)
|
||||
{
|
||||
__ASM("nop");
|
||||
timeout--;
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t L2CACHE_InvalidateLineByAddr(uint32_t address)
|
||||
{
|
||||
/* Align the address first. */
|
||||
address &= ~(uint32_t)(FSL_FEATURE_L2CACHE_LINESIZE_BYTE - 1);
|
||||
/* Invalidate the cache line by physical address. */
|
||||
L2CACHEC->REG7_INV_PA = address;
|
||||
|
||||
return address;
|
||||
}
|
||||
|
||||
static uint32_t L2CACHE_CleanLineByAddr(uint32_t address)
|
||||
{
|
||||
/* Align the address first. */
|
||||
address &= ~(uint32_t)(FSL_FEATURE_L2CACHE_LINESIZE_BYTE - 1);
|
||||
/* Invalidate the cache line by physical address. */
|
||||
L2CACHEC->REG7_CLEAN_PA = address;
|
||||
|
||||
return address;
|
||||
}
|
||||
|
||||
static uint32_t L2CACHE_CleanInvalidateLineByAddr(uint32_t address)
|
||||
{
|
||||
/* Align the address first. */
|
||||
address &= ~(uint32_t)(FSL_FEATURE_L2CACHE_LINESIZE_BYTE - 1);
|
||||
/* Clean and invalidate the cache line by physical address. */
|
||||
L2CACHEC->REG7_CLEAN_INV_PA = address;
|
||||
|
||||
return address;
|
||||
}
|
||||
|
||||
static void L2CACHE_GetWayNumSize(uint32_t *num_ways, uint32_t *size_way)
|
||||
{
|
||||
assert(num_ways);
|
||||
assert(size_way);
|
||||
|
||||
uint32_t number = (L2CACHEC->REG1_AUX_CONTROL & L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY_MASK) >>
|
||||
L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY_SHIFT;
|
||||
uint32_t size = (L2CACHEC->REG1_AUX_CONTROL & L2CACHEC_REG1_AUX_CONTROL_WAYSIZE_MASK) >>
|
||||
L2CACHEC_REG1_AUX_CONTROL_WAYSIZE_SHIFT;
|
||||
|
||||
*num_ways = (number + 1) * L2CACHE_SMALLWAYS_NUM;
|
||||
if (!size)
|
||||
{
|
||||
/* 0 internally mapped to the same size as 1 - 16KB.*/
|
||||
size += 1;
|
||||
}
|
||||
*size_way = (1 << (size - 1)) * L2CACHE_SAMLLWAYS_SIZE * L2CACHE_1KBCOVERTOB;
|
||||
}
|
||||
|
||||
/*!
|
||||
* brief Initializes the level 2 cache controller module.
|
||||
*
|
||||
* param config Pointer to configuration structure. See "l2cache_config_t".
|
||||
*/
|
||||
void L2CACHE_Init(l2cache_config_t *config)
|
||||
{
|
||||
assert(config);
|
||||
|
||||
uint16_t waysNum = 0xFFU; /* Default use the 8-way mask. */
|
||||
uint8_t count;
|
||||
uint32_t auxReg = 0;
|
||||
|
||||
/*The aux register must be configured when the cachec is disabled
|
||||
* So disable first if the cache controller is enabled.
|
||||
*/
|
||||
if (L2CACHEC->REG1_CONTROL & L2CACHEC_REG1_CONTROL_CE_MASK)
|
||||
{
|
||||
L2CACHE_Disable();
|
||||
}
|
||||
|
||||
/* Unlock all entries. */
|
||||
if (L2CACHEC->REG1_AUX_CONTROL & L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY_MASK)
|
||||
{
|
||||
waysNum = 0xFFFFU;
|
||||
}
|
||||
|
||||
for (count = 0; count < L2CACHE_LOCKDOWN_REGNUM; count++)
|
||||
{
|
||||
L2CACHE_LockdownByWayEnable(count, waysNum, false);
|
||||
}
|
||||
|
||||
/* Set the ways and way-size etc. */
|
||||
auxReg = L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY(config->wayNum) |
|
||||
L2CACHEC_REG1_AUX_CONTROL_WAYSIZE(config->waySize) | L2CACHEC_REG1_AUX_CONTROL_CRP(config->repacePolicy) |
|
||||
L2CACHEC_REG1_AUX_CONTROL_IPE(config->istrPrefetchEnable) |
|
||||
L2CACHEC_REG1_AUX_CONTROL_DPE(config->dataPrefetchEnable) |
|
||||
L2CACHEC_REG1_AUX_CONTROL_NLE(config->nsLockdownEnable) |
|
||||
L2CACHEC_REG1_AUX_CONTROL_FWA(config->writeAlloc) | L2CACHEC_REG1_AUX_CONTROL_HPSDRE(config->writeAlloc);
|
||||
L2CACHEC->REG1_AUX_CONTROL = auxReg;
|
||||
|
||||
/* Set the tag/data ram latency. */
|
||||
if (config->lateConfig)
|
||||
{
|
||||
uint32_t data = 0;
|
||||
/* Tag latency. */
|
||||
data = L2CACHEC_REG1_TAG_RAM_CONTROL_SL(config->lateConfig->tagSetupLate) |
|
||||
L2CACHEC_REG1_TAG_RAM_CONTROL_SL(config->lateConfig->tagSetupLate) |
|
||||
L2CACHEC_REG1_TAG_RAM_CONTROL_RAL(config->lateConfig->tagReadLate) |
|
||||
L2CACHEC_REG1_TAG_RAM_CONTROL_WAL(config->lateConfig->dataWriteLate);
|
||||
L2CACHEC->REG1_TAG_RAM_CONTROL = data;
|
||||
/* Data latency. */
|
||||
data = L2CACHEC_REG1_DATA_RAM_CONTROL_SL(config->lateConfig->dataSetupLate) |
|
||||
L2CACHEC_REG1_DATA_RAM_CONTROL_SL(config->lateConfig->dataSetupLate) |
|
||||
L2CACHEC_REG1_DATA_RAM_CONTROL_RAL(config->lateConfig->dataReadLate) |
|
||||
L2CACHEC_REG1_DATA_RAM_CONTROL_WAL(config->lateConfig->dataWriteLate);
|
||||
L2CACHEC->REG1_DATA_RAM_CONTROL = data;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* brief Gets an available default settings for the cache controller.
|
||||
*
|
||||
* This function initializes the cache controller configuration structure with default settings.
|
||||
* The default values are:
|
||||
* code
|
||||
* config->waysNum = kL2CACHE_8ways;
|
||||
* config->waySize = kL2CACHE_32KbSize;
|
||||
* config->repacePolicy = kL2CACHE_Roundrobin;
|
||||
* config->lateConfig = NULL;
|
||||
* config->istrPrefetchEnable = false;
|
||||
* config->dataPrefetchEnable = false;
|
||||
* config->nsLockdownEnable = false;
|
||||
* config->writeAlloc = kL2CACHE_UseAwcache;
|
||||
* endcode
|
||||
* param config Pointer to the configuration structure.
|
||||
*/
|
||||
void L2CACHE_GetDefaultConfig(l2cache_config_t *config)
|
||||
{
|
||||
assert(config);
|
||||
|
||||
/* Initializes the configure structure to zero. */
|
||||
memset(config, 0, sizeof(*config));
|
||||
|
||||
uint32_t number = (L2CACHEC->REG1_AUX_CONTROL & L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY_MASK) >>
|
||||
L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY_SHIFT;
|
||||
uint32_t size = (L2CACHEC->REG1_AUX_CONTROL & L2CACHEC_REG1_AUX_CONTROL_WAYSIZE_MASK) >>
|
||||
L2CACHEC_REG1_AUX_CONTROL_WAYSIZE_SHIFT;
|
||||
|
||||
/* Get the default value */
|
||||
config->wayNum = (l2cache_way_num_t)number;
|
||||
config->waySize = (l2cache_way_size)size;
|
||||
config->repacePolicy = kL2CACHE_Roundrobin;
|
||||
config->lateConfig = NULL;
|
||||
config->istrPrefetchEnable = false;
|
||||
config->dataPrefetchEnable = false;
|
||||
config->nsLockdownEnable = false;
|
||||
config->writeAlloc = kL2CACHE_UseAwcache;
|
||||
}
|
||||
|
||||
/*!
|
||||
* brief Enables the level 2 cache controller.
|
||||
* This function enables the cache controller. Must be written using a secure access.
|
||||
* If write with a Non-secure access will cause a DECERR response.
|
||||
*
|
||||
*/
|
||||
void L2CACHE_Enable(void)
|
||||
{
|
||||
/* Invalidate first. */
|
||||
L2CACHE_Invalidate();
|
||||
/* Enable the level 2 cache controller. */
|
||||
L2CACHEC->REG1_CONTROL = L2CACHEC_REG1_CONTROL_CE_MASK;
|
||||
}
|
||||
|
||||
/*!
|
||||
* brief Disables the level 2 cache controller.
|
||||
* This function disables the cache controller. Must be written using a secure access.
|
||||
* If write with a Non-secure access will cause a DECERR response.
|
||||
*
|
||||
*/
|
||||
void L2CACHE_Disable(void)
|
||||
{
|
||||
/* First CleanInvalidate all enties in the cache. */
|
||||
L2CACHE_CleanInvalidate();
|
||||
/* Disable the level 2 cache controller. */
|
||||
L2CACHEC->REG1_CONTROL &= ~L2CACHEC_REG1_CONTROL_CE_MASK;
|
||||
/* DSB - data sync barrier.*/
|
||||
__DSB();
|
||||
}
|
||||
|
||||
/*!
|
||||
* brief Invalidates the Level 2 cache.
|
||||
* This function invalidates all entries in cache.
|
||||
*
|
||||
*/
|
||||
void L2CACHE_Invalidate(void)
|
||||
{
|
||||
/* Invalidate all entries in cache. */
|
||||
L2CACHE_SetAndWaitBackGroundOperate(L2CACHEC->REG1_AUX_CONTROL, (uint32_t)&L2CACHEC->REG7_INV_WAY);
|
||||
/* Cache sync. */
|
||||
L2CACHEC->REG7_CACHE_SYNC = 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
* brief Cleans the level 2 cache controller.
|
||||
* This function cleans all entries in the level 2 cache controller.
|
||||
*
|
||||
*/
|
||||
void L2CACHE_Clean(void)
|
||||
{
|
||||
/* Clean all entries of the cache. */
|
||||
L2CACHE_SetAndWaitBackGroundOperate(L2CACHEC->REG1_AUX_CONTROL, (uint32_t)&L2CACHEC->REG7_CLEAN_WAY);
|
||||
/* Cache sync. */
|
||||
L2CACHEC->REG7_CACHE_SYNC = 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
* brief Cleans and invalidates the level 2 cache controller.
|
||||
* This function cleans and invalidates all entries in the level 2 cache controller.
|
||||
*
|
||||
*/
|
||||
void L2CACHE_CleanInvalidate(void)
|
||||
{
|
||||
/* Clean all entries of the cache. */
|
||||
L2CACHE_SetAndWaitBackGroundOperate(L2CACHEC->REG1_AUX_CONTROL, (uint32_t)&L2CACHEC->REG7_CLEAN_INV_WAY);
|
||||
/* Cache sync. */
|
||||
L2CACHEC->REG7_CACHE_SYNC = 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
* brief Invalidates the Level 2 cache lines in the range of two physical addresses.
|
||||
* This function invalidates all cache lines between two physical addresses.
|
||||
*
|
||||
* param address The start address of the memory to be invalidated.
|
||||
* param size_byte The memory size.
|
||||
* note The start address and size_byte should be 32-byte(FSL_FEATURE_L2CACHE_LINESIZE_BYTE) aligned.
|
||||
* The startAddr here will be forced to align to L2 line size if startAddr
|
||||
* is not aligned. For the size_byte, application should make sure the
|
||||
* alignment or make sure the right operation order if the size_byte is not aligned.
|
||||
*/
|
||||
void L2CACHE_InvalidateByRange(uint32_t address, uint32_t size_byte)
|
||||
{
|
||||
uint32_t endAddr = address + size_byte;
|
||||
|
||||
/* Invalidate addresses in the range. */
|
||||
while (address < endAddr)
|
||||
{
|
||||
address = L2CACHE_InvalidateLineByAddr(address);
|
||||
/* Update the size. */
|
||||
address += FSL_FEATURE_L2CACHE_LINESIZE_BYTE;
|
||||
}
|
||||
|
||||
/* Cache sync. */
|
||||
L2CACHEC->REG7_CACHE_SYNC = 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
* brief Cleans the Level 2 cache lines in the range of two physical addresses.
|
||||
* This function cleans all cache lines between two physical addresses.
|
||||
*
|
||||
* param address The start address of the memory to be cleaned.
|
||||
* param size_byte The memory size.
|
||||
* note The start address and size_byte should be 32-byte(FSL_FEATURE_L2CACHE_LINESIZE_BYTE) aligned.
|
||||
* The startAddr here will be forced to align to L2 line size if startAddr
|
||||
* is not aligned. For the size_byte, application should make sure the
|
||||
* alignment or make sure the right operation order if the size_byte is not aligned.
|
||||
*/
|
||||
void L2CACHE_CleanByRange(uint32_t address, uint32_t size_byte)
|
||||
{
|
||||
uint32_t num_ways = 0;
|
||||
uint32_t size_way = 0;
|
||||
uint32_t endAddr = address + size_byte;
|
||||
|
||||
/* Get the number and size of the cache way. */
|
||||
L2CACHE_GetWayNumSize(&num_ways, &size_way);
|
||||
|
||||
/* Check if the clean size is over the cache size. */
|
||||
if ((endAddr - address) > num_ways * size_way)
|
||||
{
|
||||
L2CACHE_Clean();
|
||||
return;
|
||||
}
|
||||
|
||||
/* Clean addresses in the range. */
|
||||
while ((address & ~(uint32_t)(FSL_FEATURE_L2CACHE_LINESIZE_BYTE - 1)) < endAddr)
|
||||
{
|
||||
/* Clean the address in the range. */
|
||||
address = L2CACHE_CleanLineByAddr(address);
|
||||
address += FSL_FEATURE_L2CACHE_LINESIZE_BYTE;
|
||||
}
|
||||
|
||||
L2CACHEC->REG7_CACHE_SYNC = 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
* brief Cleans and invalidates the Level 2 cache lines in the range of two physical addresses.
|
||||
* This function cleans and invalidates all cache lines between two physical addresses.
|
||||
*
|
||||
* param address The start address of the memory to be cleaned and invalidated.
|
||||
* param size_byte The memory size.
|
||||
* note The start address and size_byte should be 32-byte(FSL_FEATURE_L2CACHE_LINESIZE_BYTE) aligned.
|
||||
* The startAddr here will be forced to align to L2 line size if startAddr
|
||||
* is not aligned. For the size_byte, application should make sure the
|
||||
* alignment or make sure the right operation order if the size_byte is not aligned.
|
||||
*/
|
||||
void L2CACHE_CleanInvalidateByRange(uint32_t address, uint32_t size_byte)
|
||||
{
|
||||
uint32_t num_ways = 0;
|
||||
uint32_t size_way = 0;
|
||||
uint32_t endAddr = address + size_byte;
|
||||
|
||||
/* Get the number and size of the cache way. */
|
||||
L2CACHE_GetWayNumSize(&num_ways, &size_way);
|
||||
|
||||
/* Check if the clean size is over the cache size. */
|
||||
if ((endAddr - address) > num_ways * size_way)
|
||||
{
|
||||
L2CACHE_CleanInvalidate();
|
||||
return;
|
||||
}
|
||||
|
||||
/* Clean addresses in the range. */
|
||||
while ((address & ~(uint32_t)(FSL_FEATURE_L2CACHE_LINESIZE_BYTE - 1)) < endAddr)
|
||||
{
|
||||
/* Clean the address in the range. */
|
||||
address = L2CACHE_CleanInvalidateLineByAddr(address);
|
||||
address += FSL_FEATURE_L2CACHE_LINESIZE_BYTE;
|
||||
}
|
||||
|
||||
L2CACHEC->REG7_CACHE_SYNC = 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
* brief Enables or disables to lock down the data and instruction by way.
|
||||
* This function locks down the cached instruction/data by way and prevent the adresses from
|
||||
* being allocated and prevent dara from being evicted out of the level 2 cache.
|
||||
* But the normal cache maintenance operations that invalidate, clean or clean
|
||||
* and validate cache contents affect the locked-down cache lines as normal.
|
||||
*
|
||||
* param masterId The master id, range from 0 ~ 7.
|
||||
* param mask The ways to be enabled or disabled to lockdown.
|
||||
* each bit in value is related to each way of the cache. for example:
|
||||
* value: bit 0 ------ way 0.
|
||||
* value: bit 1 ------ way 1.
|
||||
* --------------------------
|
||||
* value: bit 15 ------ way 15.
|
||||
* Note: please make sure the value setting is align with your supported ways.
|
||||
* param enable True enable the lockdown, false to disable the lockdown.
|
||||
*/
|
||||
void L2CACHE_LockdownByWayEnable(uint32_t masterId, uint32_t mask, bool enable)
|
||||
{
|
||||
uint8_t num_ways = (L2CACHEC->REG1_AUX_CONTROL & L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY_MASK) >>
|
||||
L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY_SHIFT;
|
||||
num_ways = (num_ways + 1) * L2CACHE_SMALLWAYS_NUM;
|
||||
|
||||
assert(mask < (1U << num_ways));
|
||||
assert(masterId < L2CACHE_LOCKDOWN_REGNUM);
|
||||
|
||||
uint32_t dataReg = L2CACHEC->LOCKDOWN[masterId].REG9_D_LOCKDOWN;
|
||||
uint32_t istrReg = L2CACHEC->LOCKDOWN[masterId].REG9_I_LOCKDOWN;
|
||||
|
||||
if (enable)
|
||||
{
|
||||
/* Data lockdown. */
|
||||
L2CACHEC->LOCKDOWN[masterId].REG9_D_LOCKDOWN = dataReg | mask;
|
||||
/* Instruction lockdown. */
|
||||
L2CACHEC->LOCKDOWN[masterId].REG9_I_LOCKDOWN = istrReg | mask;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Data lockdown. */
|
||||
L2CACHEC->LOCKDOWN[masterId].REG9_D_LOCKDOWN = dataReg & ~mask;
|
||||
/* Instruction lockdown. */
|
||||
L2CACHEC->LOCKDOWN[masterId].REG9_I_LOCKDOWN = istrReg & ~mask;
|
||||
}
|
||||
}
|
||||
#endif /* FSL_FEATURE_SOC_L2CACHEC_COUNT */
|
||||
|
||||
/*!
|
||||
* brief Invalidate cortex-m7 L1 instruction cache by range.
|
||||
*
|
||||
* param address The start address of the memory to be invalidated.
|
||||
* param size_byte The memory size.
|
||||
* note The start address and size_byte should be 32-byte(FSL_FEATURE_L1ICACHE_LINESIZE_BYTE) aligned.
|
||||
* The startAddr here will be forced to align to L1 I-cache line size if
|
||||
* startAddr is not aligned. For the size_byte, application should make sure the
|
||||
* alignment or make sure the right operation order if the size_byte is not aligned.
|
||||
*/
|
||||
void L1CACHE_InvalidateICacheByRange(uint32_t address, uint32_t size_byte)
|
||||
{
|
||||
#if (__DCACHE_PRESENT == 1U)
|
||||
uint32_t addr = address & (uint32_t) ~(FSL_FEATURE_L1ICACHE_LINESIZE_BYTE - 1);
|
||||
int32_t size = size_byte + address - addr;
|
||||
uint32_t linesize = 32U;
|
||||
|
||||
__DSB();
|
||||
while (size > 0)
|
||||
{
|
||||
SCB->ICIMVAU = addr;
|
||||
addr += linesize;
|
||||
size -= linesize;
|
||||
}
|
||||
__DSB();
|
||||
__ISB();
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
* brief Invalidates all instruction caches by range.
|
||||
*
|
||||
* Both cortex-m7 L1 cache line and L2 PL310 cache line length is 32-byte.
|
||||
*
|
||||
* param address The physical address.
|
||||
* param size_byte size of the memory to be invalidated.
|
||||
* note address and size should be aligned to cache line size
|
||||
* 32-Byte due to the cache operation unit is one cache line. The startAddr here will be forced
|
||||
* to align to the cache line size if startAddr is not aligned. For the size_byte, application should
|
||||
* make sure the alignment or make sure the right operation order if the size_byte is not aligned.
|
||||
*/
|
||||
void ICACHE_InvalidateByRange(uint32_t address, uint32_t size_byte)
|
||||
{
|
||||
#if defined(FSL_FEATURE_SOC_L2CACHEC_COUNT) && FSL_FEATURE_SOC_L2CACHEC_COUNT
|
||||
#if defined(FSL_SDK_DISBLE_L2CACHE_PRESENT) && !FSL_SDK_DISBLE_L2CACHE_PRESENT
|
||||
L2CACHE_InvalidateByRange(address, size_byte);
|
||||
#endif /* !FSL_SDK_DISBLE_L2CACHE_PRESENT */
|
||||
#endif /* FSL_FEATURE_SOC_L2CACHEC_COUNT */
|
||||
|
||||
L1CACHE_InvalidateICacheByRange(address, size_byte);
|
||||
}
|
||||
|
||||
/*!
|
||||
* brief Invalidates all data caches by range.
|
||||
*
|
||||
* Both cortex-m7 L1 cache line and L2 PL310 cache line length is 32-byte.
|
||||
*
|
||||
* param address The physical address.
|
||||
* param size_byte size of the memory to be invalidated.
|
||||
* note address and size should be aligned to cache line size
|
||||
* 32-Byte due to the cache operation unit is one cache line. The startAddr here will be forced
|
||||
* to align to the cache line size if startAddr is not aligned. For the size_byte, application should
|
||||
* make sure the alignment or make sure the right operation order if the size_byte is not aligned.
|
||||
*/
|
||||
void DCACHE_InvalidateByRange(uint32_t address, uint32_t size_byte)
|
||||
{
|
||||
#if defined(FSL_FEATURE_SOC_L2CACHEC_COUNT) && FSL_FEATURE_SOC_L2CACHEC_COUNT
|
||||
#if defined(FSL_SDK_DISBLE_L2CACHE_PRESENT) && !FSL_SDK_DISBLE_L2CACHE_PRESENT
|
||||
L2CACHE_InvalidateByRange(address, size_byte);
|
||||
#endif /* !FSL_SDK_DISBLE_L2CACHE_PRESENT */
|
||||
#endif /* FSL_FEATURE_SOC_L2CACHEC_COUNT */
|
||||
L1CACHE_InvalidateDCacheByRange(address, size_byte);
|
||||
}
|
||||
|
||||
/*!
|
||||
* brief Cleans all data caches by range.
|
||||
*
|
||||
* Both cortex-m7 L1 cache line and L2 PL310 cache line length is 32-byte.
|
||||
*
|
||||
* param address The physical address.
|
||||
* param size_byte size of the memory to be cleaned.
|
||||
* note address and size should be aligned to cache line size
|
||||
* 32-Byte due to the cache operation unit is one cache line. The startAddr here will be forced
|
||||
* to align to the cache line size if startAddr is not aligned. For the size_byte, application should
|
||||
* make sure the alignment or make sure the right operation order if the size_byte is not aligned.
|
||||
*/
|
||||
void DCACHE_CleanByRange(uint32_t address, uint32_t size_byte)
|
||||
{
|
||||
L1CACHE_CleanDCacheByRange(address, size_byte);
|
||||
#if defined(FSL_FEATURE_SOC_L2CACHEC_COUNT) && FSL_FEATURE_SOC_L2CACHEC_COUNT
|
||||
#if defined(FSL_SDK_DISBLE_L2CACHE_PRESENT) && !FSL_SDK_DISBLE_L2CACHE_PRESENT
|
||||
L2CACHE_CleanByRange(address, size_byte);
|
||||
#endif /* !FSL_SDK_DISBLE_L2CACHE_PRESENT */
|
||||
#endif /* FSL_FEATURE_SOC_L2CACHEC_COUNT */
|
||||
}
|
||||
|
||||
/*!
|
||||
* brief Cleans and Invalidates all data caches by range.
|
||||
*
|
||||
* Both cortex-m7 L1 cache line and L2 PL310 cache line length is 32-byte.
|
||||
*
|
||||
* param address The physical address.
|
||||
* param size_byte size of the memory to be cleaned and invalidated.
|
||||
* note address and size should be aligned to cache line size
|
||||
* 32-Byte due to the cache operation unit is one cache line. The startAddr here will be forced
|
||||
* to align to the cache line size if startAddr is not aligned. For the size_byte, application should
|
||||
* make sure the alignment or make sure the right operation order if the size_byte is not aligned.
|
||||
*/
|
||||
void DCACHE_CleanInvalidateByRange(uint32_t address, uint32_t size_byte)
|
||||
{
|
||||
L1CACHE_CleanInvalidateDCacheByRange(address, size_byte);
|
||||
#if defined(FSL_FEATURE_SOC_L2CACHEC_COUNT) && FSL_FEATURE_SOC_L2CACHEC_COUNT
|
||||
#if defined(FSL_SDK_DISBLE_L2CACHE_PRESENT) && !FSL_SDK_DISBLE_L2CACHE_PRESENT
|
||||
L2CACHE_CleanInvalidateByRange(address, size_byte);
|
||||
#endif /* !FSL_SDK_DISBLE_L2CACHE_PRESENT */
|
||||
#endif /* FSL_FEATURE_SOC_L2CACHEC_COUNT */
|
||||
}
|
|
@ -0,0 +1,155 @@
|
|||
/*
|
||||
* Copyright (c) 2015-2016, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2018 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file fsl_common.c
|
||||
* @brief common drivers
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021.11.11
|
||||
*/
|
||||
|
||||
#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)
|
||||
{
|
||||
/* 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[irq + 16];
|
||||
/* make sure the __VECTOR_RAM is noncachable */
|
||||
__VECTOR_RAM[irq + 16] = irqHandler;
|
||||
|
||||
EnableGlobalIRQ(irqMaskValue);
|
||||
|
||||
/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
|
||||
exception return operation might vector to incorrect interrupt */
|
||||
#if defined __CORTEX_M && (__CORTEX_M == 4U)
|
||||
__DSB();
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* ENABLE_RAM_VECTOR_TABLE. */
|
||||
#endif /* __GIC_PRIO_BITS. */
|
||||
|
||||
#if (defined(FSL_FEATURE_SOC_SYSCON_COUNT) && (FSL_FEATURE_SOC_SYSCON_COUNT > 0))
|
||||
#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] = 1u << intNumber;
|
||||
EnableIRQ(interrupt); /* also enable interrupt at NVIC */
|
||||
}
|
||||
|
||||
void DisableDeepSleepIRQ(IRQn_Type interrupt)
|
||||
{
|
||||
uint32_t intNumber = (uint32_t)interrupt;
|
||||
|
||||
DisableIRQ(interrupt); /* also disable interrupt at NVIC */
|
||||
uint32_t index = 0;
|
||||
|
||||
while (intNumber >= 32u)
|
||||
{
|
||||
index++;
|
||||
intNumber -= 32u;
|
||||
}
|
||||
|
||||
SYSCON->STARTERCLR[index] = 1u << intNumber;
|
||||
}
|
||||
#endif /* FSL_FEATURE_SYSCON_STARTER_DISCONTINUOUS */
|
||||
#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);
|
||||
void *p_align_addr, *p_addr = malloc(alignedsize);
|
||||
|
||||
if (!p_addr)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
p_align_addr = (void *)SDK_SIZEALIGN((uint32_t)p_addr + sizeof(mem_align_cb_t), alignbytes);
|
||||
|
||||
p_cb = (mem_align_cb_t *)((uint32_t)p_align_addr - 4);
|
||||
p_cb->identifier = SDK_MEM_MAGIC_NUMBER;
|
||||
p_cb->offset = (uint32_t)p_align_addr - (uint32_t)p_addr;
|
||||
|
||||
return (void *)p_align_addr;
|
||||
}
|
||||
|
||||
void SDK_Free(void *ptr)
|
||||
{
|
||||
mem_align_cb_t *p_cb = (mem_align_cb_t *)((uint32_t)ptr - 4);
|
||||
|
||||
if (p_cb->identifier != SDK_MEM_MAGIC_NUMBER)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
free((void *)((uint32_t)ptr - p_cb->offset));
|
||||
}
|
|
@ -0,0 +1,236 @@
|
|||
/*
|
||||
** ###################################################################
|
||||
** Processors: MIMXRT1052CVJ5B
|
||||
** MIMXRT1052CVL5B
|
||||
** MIMXRT1052DVJ6B
|
||||
** MIMXRT1052DVL6B
|
||||
**
|
||||
** Compilers: Freescale C/C++ for Embedded ARM
|
||||
** GNU C Compiler
|
||||
** IAR ANSI C/C++ Compiler for ARM
|
||||
** Keil ARM C/C++ Compiler
|
||||
** MCUXpresso Compiler
|
||||
**
|
||||
** Reference manual: IMXRT1050RM Rev.2.1, 12/2018
|
||||
** Version: rev. 1.2, 2018-11-27
|
||||
** Build: b181205
|
||||
**
|
||||
** 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-2018 NXP
|
||||
** All rights reserved.
|
||||
**
|
||||
** SPDX-License-Identifier: BSD-3-Clause
|
||||
**
|
||||
** http: www.nxp.com
|
||||
** mail: support@nxp.com
|
||||
**
|
||||
** Revisions:
|
||||
** - rev. 0.1 (2017-01-10)
|
||||
** Initial version.
|
||||
** - rev. 1.0 (2018-09-21)
|
||||
** Update interrupt vector table and dma request source.
|
||||
** Update register BEE_ADDR_OFFSET1's bitfield name to ADDR_OFFSET1.
|
||||
** Split GPIO_COMBINED_IRQS to GPIO_COMBINED_LOW_IRQS and GPIO_COMBINED_HIGH_IRQS.
|
||||
** - rev. 1.1 (2018-11-16)
|
||||
** Update header files to align with IMXRT1050RM Rev.1.
|
||||
** - rev. 1.2 (2018-11-27)
|
||||
** Update header files to align with IMXRT1050RM Rev.2.1.
|
||||
**
|
||||
** ###################################################################
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @file MIMXRT1052
|
||||
* @version 1.2
|
||||
* @date 2018-11-27
|
||||
* @brief Device specific configuration file for MIMXRT1052 (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"
|
||||
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
-- 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)) */
|
||||
|
||||
#if defined(__MCUXPRESSO)
|
||||
extern uint32_t g_pfnVectors[]; // Vector table defined in startup code
|
||||
SCB->VTOR = (uint32_t)g_pfnVectors;
|
||||
#endif
|
||||
|
||||
/* Disable Watchdog Power Down Counter */
|
||||
WDOG1->WMCR &= ~WDOG_WMCR_PDE_MASK;
|
||||
WDOG2->WMCR &= ~WDOG_WMCR_PDE_MASK;
|
||||
|
||||
/* Watchdog disable */
|
||||
|
||||
#if (DISABLE_WDOG)
|
||||
if (WDOG1->WCR & WDOG_WCR_WDE_MASK)
|
||||
{
|
||||
WDOG1->WCR &= ~WDOG_WCR_WDE_MASK;
|
||||
}
|
||||
if (WDOG2->WCR & WDOG_WCR_WDE_MASK)
|
||||
{
|
||||
WDOG2->WCR &= ~WDOG_WCR_WDE_MASK;
|
||||
}
|
||||
RTWDOG->CNT = 0xD928C520U; /* 0xD928C520U is the update key */
|
||||
RTWDOG->TOVAL = 0xFFFF;
|
||||
RTWDOG->CS = (uint32_t) ((RTWDOG->CS) & ~RTWDOG_CS_EN_MASK) | RTWDOG_CS_UPDATE_MASK;
|
||||
#endif /* (DISABLE_WDOG) */
|
||||
|
||||
/* Disable Systick which might be enabled by bootrom */
|
||||
if (SysTick->CTRL & SysTick_CTRL_ENABLE_Msk)
|
||||
{
|
||||
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
|
||||
}
|
||||
|
||||
/* Enable instruction and data caches */
|
||||
#if defined(__ICACHE_PRESENT) && __ICACHE_PRESENT
|
||||
if (SCB_CCR_IC_Msk != (SCB_CCR_IC_Msk & SCB->CCR)) {
|
||||
SCB_EnableICache();
|
||||
}
|
||||
#endif
|
||||
#if defined(__DCACHE_PRESENT) && __DCACHE_PRESENT
|
||||
if (SCB_CCR_DC_Msk != (SCB_CCR_DC_Msk & SCB->CCR)) {
|
||||
SCB_EnableDCache();
|
||||
}
|
||||
#endif
|
||||
|
||||
SystemInitHook();
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
-- SystemCoreClockUpdate()
|
||||
---------------------------------------------------------------------------- */
|
||||
|
||||
void SystemCoreClockUpdate (void) {
|
||||
|
||||
uint32_t freq;
|
||||
uint32_t PLL1MainClock;
|
||||
uint32_t PLL2MainClock;
|
||||
|
||||
/* Periph_clk2_clk ---> Periph_clk */
|
||||
if (CCM->CBCDR & CCM_CBCDR_PERIPH_CLK_SEL_MASK)
|
||||
{
|
||||
switch (CCM->CBCMR & CCM_CBCMR_PERIPH_CLK2_SEL_MASK)
|
||||
{
|
||||
/* Pll3_sw_clk ---> Periph_clk2_clk ---> Periph_clk */
|
||||
case CCM_CBCMR_PERIPH_CLK2_SEL(0U):
|
||||
if(CCM_ANALOG->PLL_USB1 & CCM_ANALOG_PLL_USB1_BYPASS_MASK)
|
||||
{
|
||||
freq = (((CCM_ANALOG->PLL_USB1 & CCM_ANALOG_PLL_USB1_BYPASS_CLK_SRC_MASK) >> CCM_ANALOG_PLL_USB1_BYPASS_CLK_SRC_SHIFT) == 0U) ?
|
||||
CPU_XTAL_CLK_HZ : CPU_CLK1_HZ;
|
||||
}
|
||||
else
|
||||
{
|
||||
freq = (CPU_XTAL_CLK_HZ * ((CCM_ANALOG->PLL_USB1 & CCM_ANALOG_PLL_USB1_DIV_SELECT_MASK) ? 22U : 20U));
|
||||
}
|
||||
break;
|
||||
|
||||
/* Osc_clk ---> Periph_clk2_clk ---> Periph_clk */
|
||||
case CCM_CBCMR_PERIPH_CLK2_SEL(1U):
|
||||
freq = CPU_XTAL_CLK_HZ;
|
||||
break;
|
||||
|
||||
case CCM_CBCMR_PERIPH_CLK2_SEL(2U):
|
||||
freq = (((CCM_ANALOG->PLL_SYS & CCM_ANALOG_PLL_SYS_BYPASS_CLK_SRC_MASK) >> CCM_ANALOG_PLL_SYS_BYPASS_CLK_SRC_SHIFT) == 0U) ?
|
||||
CPU_XTAL_CLK_HZ : CPU_CLK1_HZ;
|
||||
break;
|
||||
|
||||
case CCM_CBCMR_PERIPH_CLK2_SEL(3U):
|
||||
default:
|
||||
freq = 0U;
|
||||
break;
|
||||
}
|
||||
|
||||
freq /= (((CCM->CBCDR & CCM_CBCDR_PERIPH_CLK2_PODF_MASK) >> CCM_CBCDR_PERIPH_CLK2_PODF_SHIFT) + 1U);
|
||||
}
|
||||
/* Pre_Periph_clk ---> Periph_clk */
|
||||
else
|
||||
{
|
||||
/* check if pll is bypassed */
|
||||
if(CCM_ANALOG->PLL_ARM & CCM_ANALOG_PLL_ARM_BYPASS_MASK)
|
||||
{
|
||||
PLL1MainClock = (((CCM_ANALOG->PLL_ARM & CCM_ANALOG_PLL_ARM_BYPASS_CLK_SRC_MASK) >> CCM_ANALOG_PLL_ARM_BYPASS_CLK_SRC_SHIFT) == 0U) ?
|
||||
CPU_XTAL_CLK_HZ : CPU_CLK1_HZ;
|
||||
}
|
||||
else
|
||||
{
|
||||
PLL1MainClock = ((CPU_XTAL_CLK_HZ * ((CCM_ANALOG->PLL_ARM & CCM_ANALOG_PLL_ARM_DIV_SELECT_MASK) >>
|
||||
CCM_ANALOG_PLL_ARM_DIV_SELECT_SHIFT)) >> 1U);
|
||||
}
|
||||
|
||||
/* check if pll is bypassed */
|
||||
if(CCM_ANALOG->PLL_SYS & CCM_ANALOG_PLL_SYS_BYPASS_MASK)
|
||||
{
|
||||
PLL2MainClock = (((CCM_ANALOG->PLL_SYS & CCM_ANALOG_PLL_SYS_BYPASS_CLK_SRC_MASK) >> CCM_ANALOG_PLL_SYS_BYPASS_CLK_SRC_SHIFT) == 0U) ?
|
||||
CPU_XTAL_CLK_HZ : CPU_CLK1_HZ;
|
||||
}
|
||||
else
|
||||
{
|
||||
PLL2MainClock = (CPU_XTAL_CLK_HZ * ((CCM_ANALOG->PLL_SYS & CCM_ANALOG_PLL_SYS_DIV_SELECT_MASK) ? 22U : 20U));
|
||||
}
|
||||
PLL2MainClock += ((uint64_t)CPU_XTAL_CLK_HZ * ((uint64_t)(CCM_ANALOG->PLL_SYS_NUM))) / ((uint64_t)(CCM_ANALOG->PLL_SYS_DENOM));
|
||||
|
||||
|
||||
switch (CCM->CBCMR & CCM_CBCMR_PRE_PERIPH_CLK_SEL_MASK)
|
||||
{
|
||||
/* PLL2 ---> Pre_Periph_clk ---> Periph_clk */
|
||||
case CCM_CBCMR_PRE_PERIPH_CLK_SEL(0U):
|
||||
freq = PLL2MainClock;
|
||||
break;
|
||||
|
||||
/* PLL2 PFD2 ---> Pre_Periph_clk ---> Periph_clk */
|
||||
case CCM_CBCMR_PRE_PERIPH_CLK_SEL(1U):
|
||||
freq = PLL2MainClock / ((CCM_ANALOG->PFD_528 & CCM_ANALOG_PFD_528_PFD2_FRAC_MASK) >> CCM_ANALOG_PFD_528_PFD2_FRAC_SHIFT) * 18U;
|
||||
break;
|
||||
|
||||
/* PLL2 PFD0 ---> Pre_Periph_clk ---> Periph_clk */
|
||||
case CCM_CBCMR_PRE_PERIPH_CLK_SEL(2U):
|
||||
freq = PLL2MainClock / ((CCM_ANALOG->PFD_528 & CCM_ANALOG_PFD_528_PFD0_FRAC_MASK) >> CCM_ANALOG_PFD_528_PFD0_FRAC_SHIFT) * 18U;
|
||||
break;
|
||||
|
||||
/* PLL1 divided(/2) ---> Pre_Periph_clk ---> Periph_clk */
|
||||
case CCM_CBCMR_PRE_PERIPH_CLK_SEL(3U):
|
||||
freq = PLL1MainClock / (((CCM->CACRR & CCM_CACRR_ARM_PODF_MASK) >> CCM_CACRR_ARM_PODF_SHIFT) + 1U);
|
||||
break;
|
||||
|
||||
default:
|
||||
freq = 0U;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
SystemCoreClock = (freq / (((CCM->CBCDR & CCM_CBCDR_AHB_PODF_MASK) >> CCM_CBCDR_AHB_PODF_SHIFT) + 1U));
|
||||
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
-- SystemInitHook()
|
||||
---------------------------------------------------------------------------- */
|
||||
|
||||
__attribute__ ((weak)) void SystemInitHook (void) {
|
||||
/* Void implementation of the weak function. */
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
SRC_FILES := enet_ethernetif.c enet_ethernetif_kinetis.c fsl_enet.c
|
||||
SRC_DIR := lan8720
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -0,0 +1,312 @@
|
|||
/*
|
||||
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||
* 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. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Adam Dunkels <adam@sics.se>
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2013-2016, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2019 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file enet_ethernetif.c
|
||||
* @brief ethernet drivers
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021.11.11
|
||||
*/
|
||||
|
||||
#include "lwip/opt.h"
|
||||
#include "lwip/def.h"
|
||||
#include "lwip/mem.h"
|
||||
#include "lwip/pbuf.h"
|
||||
#include "lwip/stats.h"
|
||||
#include "lwip/snmp.h"
|
||||
#include "lwip/ethip6.h"
|
||||
#include "netif/etharp.h"
|
||||
#include "netif/ppp/pppoe.h"
|
||||
#include "lwip/igmp.h"
|
||||
#include "lwip/mld6.h"
|
||||
|
||||
#if USE_RTOS && defined(FSL_RTOS_FREE_RTOS)
|
||||
//#include "FreeRTOS.h"
|
||||
//#include "event_groups.h"
|
||||
#endif
|
||||
|
||||
#include "netif/ethernet.h"
|
||||
#include "enet_ethernetif.h"
|
||||
#include "enet_ethernetif_priv.h"
|
||||
|
||||
#include "fsl_enet.h"
|
||||
#include "fsl_phy.h"
|
||||
#include "fsl_gpio.h"
|
||||
#include "fsl_iomuxc.h"
|
||||
|
||||
#include "sys_arch.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
* Code
|
||||
******************************************************************************/
|
||||
|
||||
void enet_delay(void)
|
||||
{
|
||||
volatile uint32_t i = 0;
|
||||
for (i = 0; i < 1000000; ++i)
|
||||
{
|
||||
__asm("NOP"); /* delay */
|
||||
}
|
||||
}
|
||||
|
||||
void Time_Update_LwIP(void)
|
||||
{
|
||||
}
|
||||
|
||||
void ethernetif_clk_init(void)
|
||||
{
|
||||
const clock_enet_pll_config_t config = {.enableClkOutput = true, .enableClkOutput25M = false, .loopDivider = 1};
|
||||
CLOCK_InitEnetPll(&config);
|
||||
}
|
||||
|
||||
void ethernetif_gpio_init(void)
|
||||
{
|
||||
gpio_pin_config_t gpio_config = {kGPIO_DigitalOutput, 0, kGPIO_NoIntmode};
|
||||
|
||||
IOMUXC_EnableMode(IOMUXC_GPR, kIOMUXC_GPR_ENET1TxClkOutputDir, true);
|
||||
|
||||
GPIO_PinInit(GPIO1, 3, &gpio_config);
|
||||
GPIO_PinInit(GPIO1, 10, &gpio_config);
|
||||
/* pull up the ENET_INT before RESET. */
|
||||
GPIO_WritePinOutput(GPIO1, 10, 1);
|
||||
GPIO_WritePinOutput(GPIO1, 3, 0);
|
||||
enet_delay();
|
||||
GPIO_WritePinOutput(GPIO1, 3, 1);
|
||||
}
|
||||
|
||||
void ETH_BSP_Config(void)
|
||||
{
|
||||
static int flag = 0;
|
||||
if(flag == 0)
|
||||
{
|
||||
ethernetif_clk_init();
|
||||
ethernetif_gpio_init();
|
||||
flag = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void ethernetif_phy_init(struct ethernetif *ethernetif,
|
||||
const ethernetif_config_t *ethernetifConfig,
|
||||
enet_config_t *config)
|
||||
{
|
||||
uint32_t sysClock;
|
||||
status_t status;
|
||||
bool link = false;
|
||||
uint32_t count = 0;
|
||||
phy_speed_t speed;
|
||||
phy_duplex_t duplex;
|
||||
|
||||
sysClock = CLOCK_GetFreq(ethernetifConfig->clockName);
|
||||
|
||||
LWIP_PLATFORM_DIAG(("Initializing PHY...\r\n"));
|
||||
|
||||
while ((count < ENET_ATONEGOTIATION_TIMEOUT) && (!link))
|
||||
{
|
||||
status = PHY_Init(*ethernetif_enet_ptr(ethernetif), ethernetifConfig->phyAddress, sysClock);
|
||||
|
||||
if (kStatus_Success == status)
|
||||
{
|
||||
PHY_GetLinkStatus(*ethernetif_enet_ptr(ethernetif), ethernetifConfig->phyAddress, &link);
|
||||
}
|
||||
else if (kStatus_PHY_AutoNegotiateFail == status)
|
||||
{
|
||||
LWIP_PLATFORM_DIAG(("PHY Auto-negotiation failed. Please check the ENET cable connection and link partner setting."));
|
||||
}
|
||||
else
|
||||
{
|
||||
LWIP_ASSERT("\r\nCannot initialize PHY.\r\n", 0);
|
||||
}
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
if (link)
|
||||
{
|
||||
/* Get the actual PHY link speed. */
|
||||
PHY_GetLinkSpeedDuplex(*ethernetif_enet_ptr(ethernetif), ethernetifConfig->phyAddress, &speed, &duplex);
|
||||
/* Change the MII speed and duplex for actual link status. */
|
||||
config->miiSpeed = (enet_mii_speed_t)speed;
|
||||
config->miiDuplex = (enet_mii_duplex_t)duplex;
|
||||
}
|
||||
#if 0 /* Disable assert. If initial auto-negation is timeout, \ \
|
||||
the ENET is set to default (100Mbs and full-duplex). */
|
||||
else
|
||||
{
|
||||
LWIP_ASSERT("\r\nGiving up PHY initialization. Please check the ENET cable connection and link partner setting and reset the board.\r\n", 0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* This function should be called when a packet is ready to be read
|
||||
* from the interface. It uses the function ethernetif_linkinput() that
|
||||
* should handle the actual reception of bytes from the network
|
||||
* interface. Then the type of the received packet is determined and
|
||||
* the appropriate input function is called.
|
||||
*
|
||||
* @param netif the lwip network interface structure for this ethernetif
|
||||
*/
|
||||
|
||||
void ethernetif_input(struct netif *netif)
|
||||
{
|
||||
struct pbuf *p;
|
||||
err_t ret = 0;
|
||||
|
||||
LWIP_ASSERT("netif != NULL", (netif != NULL));
|
||||
|
||||
/* move received packet into a new pbuf */
|
||||
while ((p = ethernetif_linkinput(netif)) != NULL)
|
||||
{
|
||||
/* pass all packets to ethernet_input, which decides what packets it supports */
|
||||
if ((ret = netif->input(p, netif)) != ERR_OK)
|
||||
{
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n"));
|
||||
lw_print("lw: [%s] ret %d p %p\n", __func__, ret, p);
|
||||
pbuf_free(p);
|
||||
p = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static ENET_Type *ethernetif_get_enet_base(const uint8_t enetIdx)
|
||||
{
|
||||
ENET_Type* enets[] = ENET_BASE_PTRS;
|
||||
int arrayIdx;
|
||||
int enetCount;
|
||||
|
||||
for (arrayIdx = 0, enetCount = 0; arrayIdx < ARRAY_SIZE(enets); arrayIdx++)
|
||||
{
|
||||
if (enets[arrayIdx] != 0U) /* process only defined positions */
|
||||
{ /* (some SOC headers count ENETs from 1 instead of 0) */
|
||||
if (enetCount == enetIdx)
|
||||
{
|
||||
return enets[arrayIdx];
|
||||
}
|
||||
enetCount++;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
err_t ethernetif_init(struct netif *netif, struct ethernetif *ethernetif,
|
||||
const uint8_t enetIdx,
|
||||
const ethernetif_config_t *ethernetifConfig)
|
||||
{
|
||||
LWIP_ASSERT("netif != NULL", (netif != NULL));
|
||||
LWIP_ASSERT("ethernetifConfig != NULL", (ethernetifConfig != NULL));
|
||||
|
||||
#if LWIP_NETIF_HOSTNAME
|
||||
/* Initialize interface hostname */
|
||||
netif->hostname = "lwip";
|
||||
#endif /* LWIP_NETIF_HOSTNAME */
|
||||
|
||||
/*
|
||||
* Initialize the snmp variables and counters inside the struct netif.
|
||||
* The last argument should be replaced with your link speed, in units
|
||||
* of bits per second.
|
||||
*/
|
||||
MIB2_INIT_NETIF(netif, snmp_ifType_ethernet_csmacd, LINK_SPEED_OF_YOUR_NETIF_IN_BPS);
|
||||
|
||||
netif->state = ethernetif;
|
||||
netif->name[0] = IFNAME0;
|
||||
netif->name[1] = IFNAME1;
|
||||
/* We directly use etharp_output() here to save a function call.
|
||||
* You can instead declare your own function an call etharp_output()
|
||||
* from it if you have to do some checks before sending (e.g. if link
|
||||
* is available...) */
|
||||
#if LWIP_IPV4
|
||||
netif->output = etharp_output;
|
||||
#endif
|
||||
#if LWIP_IPV6
|
||||
netif->output_ip6 = ethip6_output;
|
||||
#endif /* LWIP_IPV6 */
|
||||
netif->linkoutput = ethernetif_linkoutput;
|
||||
|
||||
#if LWIP_IPV4 && LWIP_IGMP
|
||||
netif_set_igmp_mac_filter(netif, ethernetif_igmp_mac_filter);
|
||||
netif->flags |= NETIF_FLAG_IGMP;
|
||||
#endif
|
||||
#if LWIP_IPV6 && LWIP_IPV6_MLD
|
||||
netif_set_mld_mac_filter(netif, ethernetif_mld_mac_filter);
|
||||
netif->flags |= NETIF_FLAG_MLD6;
|
||||
#endif
|
||||
|
||||
/* Init ethernetif parameters.*/
|
||||
*ethernetif_enet_ptr(ethernetif) = ethernetif_get_enet_base(enetIdx);
|
||||
LWIP_ASSERT("*ethernetif_enet_ptr(ethernetif) != NULL", (*ethernetif_enet_ptr(ethernetif) != NULL));
|
||||
|
||||
/* set MAC hardware address length */
|
||||
netif->hwaddr_len = ETH_HWADDR_LEN;
|
||||
|
||||
/* set MAC hardware address */
|
||||
memcpy(netif->hwaddr, ethernetifConfig->macAddress, NETIF_MAX_HWADDR_LEN);
|
||||
|
||||
/* maximum transfer unit */
|
||||
netif->mtu = 1500; /* TODO: define a config */
|
||||
|
||||
/* device capabilities */
|
||||
/* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */
|
||||
netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP;
|
||||
|
||||
/* ENET driver initialization.*/
|
||||
ethernetif_enet_init(netif, ethernetif, ethernetifConfig);
|
||||
|
||||
#if LWIP_IPV6 && LWIP_IPV6_MLD
|
||||
/*
|
||||
* For hardware/netifs that implement MAC filtering.
|
||||
* All-nodes link-local is handled by default, so we must let the hardware know
|
||||
* to allow multicast packets in.
|
||||
* Should set mld_mac_filter previously. */
|
||||
if (netif->mld_mac_filter != NULL)
|
||||
{
|
||||
ip6_addr_t ip6_allnodes_ll;
|
||||
ip6_addr_set_allnodes_linklocal(&ip6_allnodes_ll);
|
||||
netif->mld_mac_filter(netif, &ip6_allnodes_ll, NETIF_ADD_MAC_FILTER);
|
||||
}
|
||||
#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
|
|
@ -0,0 +1,674 @@
|
|||
/*
|
||||
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||
* 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. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Adam Dunkels <adam@sics.se>
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2013-2016, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2019 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file enet_ethernetif_kinetis.c
|
||||
* @brief ethernet drivers
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021.11.11
|
||||
*/
|
||||
|
||||
#include "sys_arch.h"
|
||||
#include "lwip/opt.h"
|
||||
#include "lwip/def.h"
|
||||
#include "lwip/mem.h"
|
||||
#include "lwip/pbuf.h"
|
||||
#include "lwip/stats.h"
|
||||
#include "lwip/snmp.h"
|
||||
#include "lwip/ethip6.h"
|
||||
#include "netif/etharp.h"
|
||||
#include "netif/ppp/pppoe.h"
|
||||
#include "lwip/igmp.h"
|
||||
#include "lwip/mld6.h"
|
||||
|
||||
#ifdef FSL_RTOS_XIUOS
|
||||
#define USE_RTOS 1
|
||||
#define FSL_RTOS_FREE_RTOS
|
||||
#endif
|
||||
|
||||
#if USE_RTOS && defined(FSL_RTOS_FREE_RTOS)
|
||||
|
||||
#ifdef FSL_RTOS_XIUOS
|
||||
#include "xs_sem.h"
|
||||
|
||||
#else
|
||||
#include "FreeRTOS.h"
|
||||
#include "event_groups.h"
|
||||
#include "list.h"
|
||||
#endif
|
||||
|
||||
typedef uint32_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||
|
||||
typedef TickType_t EventBits_t;
|
||||
|
||||
typedef long BaseType_t;
|
||||
typedef unsigned long UBaseType_t;
|
||||
|
||||
#define portBASE_TYPE long
|
||||
|
||||
#define pdFALSE ( ( BaseType_t ) 0 )
|
||||
#define pdTRUE ( ( BaseType_t ) 1 )
|
||||
|
||||
#define pdPASS ( pdTRUE )
|
||||
#define pdFAIL ( pdFALSE )
|
||||
|
||||
#ifndef FSL_RTOS_XIUOS
|
||||
typedef struct EventGroupDef_t
|
||||
{
|
||||
EventBits_t uxEventBits;
|
||||
List_t xTasksWaitingForBits; /*< List of tasks waiting for a bit to be set. */
|
||||
|
||||
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||
UBaseType_t uxEventGroupNumber;
|
||||
#endif
|
||||
|
||||
#if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) )
|
||||
uint8_t ucStaticallyAllocated; /*< Set to pdTRUE if the event group is statically allocated to ensure no attempt is made to free the memory. */
|
||||
#endif
|
||||
} EventGroup_t;
|
||||
|
||||
struct EventGroupDef_t;
|
||||
typedef struct EventGroupDef_t * EventGroupHandle_t;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#include "enet_ethernetif.h"
|
||||
#include "enet_ethernetif_priv.h"
|
||||
|
||||
#include "fsl_enet.h"
|
||||
#include "fsl_phy.h"
|
||||
|
||||
#include "sys_arch.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/**
|
||||
* Helper struct to hold private data used to operate your ethernet interface.
|
||||
*/
|
||||
struct ethernetif
|
||||
{
|
||||
ENET_Type *base;
|
||||
#if (defined(FSL_FEATURE_SOC_ENET_COUNT) && (FSL_FEATURE_SOC_ENET_COUNT > 0)) || \
|
||||
(USE_RTOS && defined(FSL_RTOS_FREE_RTOS))
|
||||
enet_handle_t handle;
|
||||
#endif
|
||||
#if USE_RTOS && defined(FSL_RTOS_FREE_RTOS)
|
||||
|
||||
#ifdef FSL_RTOS_XIUOS
|
||||
int enetSemaphore;
|
||||
#else
|
||||
EventGroupHandle_t enetTransmitAccessEvent;
|
||||
#endif
|
||||
EventBits_t txFlag;
|
||||
#endif
|
||||
enet_rx_bd_struct_t *RxBuffDescrip;
|
||||
enet_tx_bd_struct_t *TxBuffDescrip;
|
||||
rx_buffer_t *RxDataBuff;
|
||||
tx_buffer_t *TxDataBuff;
|
||||
};
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Code
|
||||
******************************************************************************/
|
||||
#if USE_RTOS && defined(FSL_RTOS_FREE_RTOS)
|
||||
|
||||
int32 lwip_obtain_semaphore(struct netif *netif)
|
||||
{
|
||||
struct ethernetif *ethernetif = netif->state;
|
||||
return (KSemaphoreObtain(ethernetif->enetSemaphore, WAITING_FOREVER) == EOK);
|
||||
}
|
||||
|
||||
#if FSL_FEATURE_ENET_QUEUE > 1
|
||||
static void ethernet_callback(ENET_Type *base, enet_handle_t *handle, uint32_t ringId, enet_event_t event, void *param)
|
||||
#else
|
||||
static void ethernet_callback(ENET_Type *base, enet_handle_t *handle, enet_event_t event, void *param)
|
||||
#endif /* FSL_FEATURE_ENET_QUEUE */
|
||||
{
|
||||
struct netif *netif = (struct netif *)param;
|
||||
struct ethernetif *ethernetif = netif->state;
|
||||
BaseType_t xResult;
|
||||
|
||||
switch (event)
|
||||
{
|
||||
case kENET_RxEvent:
|
||||
ethernetif_input(netif);
|
||||
break;
|
||||
case kENET_TxEvent:
|
||||
#ifndef FSL_RTOS_XIUOS
|
||||
{
|
||||
portBASE_TYPE taskToWake = pdFALSE;
|
||||
|
||||
#ifdef __CA7_REV
|
||||
if (SystemGetIRQNestingLevel())
|
||||
#else
|
||||
if (__get_IPSR())
|
||||
#endif
|
||||
{
|
||||
xResult = xEventGroupSetBitsFromISR(ethernetif->enetTransmitAccessEvent, ethernetif->txFlag, &taskToWake);
|
||||
if ((pdPASS == xResult) && (pdTRUE == taskToWake))
|
||||
{
|
||||
portYIELD_FROM_ISR(taskToWake);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
xEventGroupSetBits(ethernetif->enetTransmitAccessEvent, ethernetif->txFlag);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
KSemaphoreAbandon(ethernetif->enetSemaphore);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if LWIP_IPV4 && LWIP_IGMP
|
||||
err_t ethernetif_igmp_mac_filter(struct netif *netif, const ip4_addr_t *group,
|
||||
enum netif_mac_filter_action action)
|
||||
{
|
||||
struct ethernetif *ethernetif = netif->state;
|
||||
uint8_t multicastMacAddr[6];
|
||||
err_t result;
|
||||
|
||||
multicastMacAddr[0] = 0x01U;
|
||||
multicastMacAddr[1] = 0x00U;
|
||||
multicastMacAddr[2] = 0x5EU;
|
||||
multicastMacAddr[3] = (group->addr >> 8) & 0x7FU;
|
||||
multicastMacAddr[4] = (group->addr >> 16) & 0xFFU;
|
||||
multicastMacAddr[5] = (group->addr >> 24) & 0xFFU;
|
||||
|
||||
switch (action)
|
||||
{
|
||||
case IGMP_ADD_MAC_FILTER:
|
||||
/* Adds the ENET device to a multicast group.*/
|
||||
ENET_AddMulticastGroup(ethernetif->base, multicastMacAddr);
|
||||
result = ERR_OK;
|
||||
break;
|
||||
case IGMP_DEL_MAC_FILTER:
|
||||
/*
|
||||
* Moves the ENET device from a multicast group.
|
||||
* Since the ENET_LeaveMulticastGroup() could filter out also other
|
||||
* group addresses having the same hash, the call is commented out.
|
||||
*/
|
||||
/* ENET_LeaveMulticastGroup(ethernetif->base, multicastMacAddr); */
|
||||
result = ERR_OK;
|
||||
break;
|
||||
default:
|
||||
result = ERR_IF;
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if LWIP_IPV6 && LWIP_IPV6_MLD
|
||||
err_t ethernetif_mld_mac_filter(struct netif *netif, const ip6_addr_t *group,
|
||||
enum netif_mac_filter_action action)
|
||||
{
|
||||
struct ethernetif *ethernetif = netif->state;
|
||||
uint8_t multicastMacAddr[6];
|
||||
err_t result;
|
||||
|
||||
multicastMacAddr[0] = 0x33U;
|
||||
multicastMacAddr[1] = 0x33U;
|
||||
multicastMacAddr[2] = (group->addr[3]) & 0xFFU;
|
||||
multicastMacAddr[3] = (group->addr[3] >> 8) & 0xFFU;
|
||||
multicastMacAddr[4] = (group->addr[3] >> 16) & 0xFFU;
|
||||
multicastMacAddr[5] = (group->addr[3] >> 24) & 0xFFU;
|
||||
|
||||
switch (action)
|
||||
{
|
||||
case NETIF_ADD_MAC_FILTER:
|
||||
/* Adds the ENET device to a multicast group.*/
|
||||
ENET_AddMulticastGroup(ethernetif->base, multicastMacAddr);
|
||||
result = ERR_OK;
|
||||
break;
|
||||
case NETIF_DEL_MAC_FILTER:
|
||||
/*
|
||||
* Moves the ENET device from a multicast group.
|
||||
* Since the ENET_LeaveMulticastGroup() could filter out also other
|
||||
* group addresses having the same hash, the call is commented out.
|
||||
*/
|
||||
/* ENET_LeaveMulticastGroup(ethernetif->base, multicastMacAddr); */
|
||||
result = ERR_OK;
|
||||
break;
|
||||
default:
|
||||
result = ERR_IF;
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Initializes ENET driver.
|
||||
*/
|
||||
void ethernetif_enet_init(struct netif *netif, struct ethernetif *ethernetif,
|
||||
const ethernetif_config_t *ethernetifConfig)
|
||||
{
|
||||
enet_config_t config;
|
||||
uint32_t sysClock;
|
||||
enet_buffer_config_t buffCfg[ENET_RING_NUM];
|
||||
|
||||
/* prepare the buffer configuration. */
|
||||
buffCfg[0].rxBdNumber = ENET_RXBD_NUM; /* Receive buffer descriptor number. */
|
||||
buffCfg[0].txBdNumber = ENET_TXBD_NUM; /* Transmit buffer descriptor number. */
|
||||
buffCfg[0].rxBuffSizeAlign = sizeof(rx_buffer_t); /* Aligned receive data buffer size. */
|
||||
buffCfg[0].txBuffSizeAlign = sizeof(tx_buffer_t); /* Aligned transmit data buffer size. */
|
||||
buffCfg[0].rxBdStartAddrAlign = &(ethernetif->RxBuffDescrip[0]); /* Aligned receive buffer descriptor start address. */
|
||||
buffCfg[0].txBdStartAddrAlign = &(ethernetif->TxBuffDescrip[0]); /* Aligned transmit buffer descriptor start address. */
|
||||
buffCfg[0].rxBufferAlign = &(ethernetif->RxDataBuff[0][0]); /* Receive data buffer start address. */
|
||||
buffCfg[0].txBufferAlign = &(ethernetif->TxDataBuff[0][0]); /* Transmit data buffer start address. */
|
||||
|
||||
sysClock = CLOCK_GetFreq(ethernetifConfig->clockName);
|
||||
|
||||
ENET_GetDefaultConfig(&config);
|
||||
config.ringNum = ENET_RING_NUM;
|
||||
|
||||
ethernetif_phy_init(ethernetif, ethernetifConfig, &config);
|
||||
|
||||
#if USE_RTOS && defined(FSL_RTOS_FREE_RTOS)
|
||||
uint32_t instance;
|
||||
static ENET_Type *const enetBases[] = ENET_BASE_PTRS;
|
||||
static const IRQn_Type enetTxIrqId[] = ENET_Transmit_IRQS;
|
||||
/*! @brief Pointers to enet receive IRQ number for each instance. */
|
||||
static const IRQn_Type enetRxIrqId[] = ENET_Receive_IRQS;
|
||||
#if defined(ENET_ENHANCEDBUFFERDESCRIPTOR_MODE) && ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
|
||||
/*! @brief Pointers to enet timestamp IRQ number for each instance. */
|
||||
static const IRQn_Type enetTsIrqId[] = ENET_1588_Timer_IRQS;
|
||||
#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
|
||||
|
||||
/* Create the Event for transmit busy release trigger. */
|
||||
#ifdef FSL_RTOS_XIUOS
|
||||
if(ethernetif->enetSemaphore < 0)
|
||||
{
|
||||
ethernetif->enetSemaphore = KSemaphoreCreate(0);
|
||||
}
|
||||
#else
|
||||
ethernetif->enetTransmitAccessEvent = xEventGroupCreate();
|
||||
#endif
|
||||
ethernetif->txFlag = 0x1;
|
||||
|
||||
config.interrupt |= kENET_RxFrameInterrupt | kENET_TxFrameInterrupt | kENET_TxBufferInterrupt;
|
||||
|
||||
for (instance = 0; instance < ARRAY_SIZE(enetBases); instance++)
|
||||
{
|
||||
if (enetBases[instance] == ethernetif->base)
|
||||
{
|
||||
#ifdef __CA7_REV
|
||||
GIC_SetPriority(enetRxIrqId[instance], ENET_PRIORITY);
|
||||
GIC_SetPriority(enetTxIrqId[instance], ENET_PRIORITY);
|
||||
#if defined(ENET_ENHANCEDBUFFERDESCRIPTOR_MODE) && ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
|
||||
GIC_SetPriority(enetTsIrqId[instance], ENET_1588_PRIORITY);
|
||||
#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
|
||||
#else
|
||||
NVIC_SetPriority(enetRxIrqId[instance], ENET_PRIORITY);
|
||||
NVIC_SetPriority(enetTxIrqId[instance], ENET_PRIORITY);
|
||||
#if defined(ENET_ENHANCEDBUFFERDESCRIPTOR_MODE) && ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
|
||||
NVIC_SetPriority(enetTsIrqId[instance], ENET_1588_PRIORITY);
|
||||
#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
|
||||
#endif /* __CA7_REV */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
LWIP_ASSERT("Input Ethernet base error!", (instance != ARRAY_SIZE(enetBases)));
|
||||
#endif /* USE_RTOS */
|
||||
|
||||
/* Initialize the ENET module.*/
|
||||
ENET_Init(ethernetif->base, ðernetif->handle, &config, &buffCfg[0], netif->hwaddr, sysClock);
|
||||
|
||||
#if USE_RTOS && defined(FSL_RTOS_FREE_RTOS)
|
||||
ENET_SetCallback(ðernetif->handle, ethernet_callback, netif);
|
||||
#endif
|
||||
|
||||
ENET_ActiveRead(ethernetif->base);
|
||||
// low_level_init();
|
||||
}
|
||||
|
||||
ENET_Type **ethernetif_enet_ptr(struct ethernetif *ethernetif)
|
||||
{
|
||||
return &(ethernetif->base);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns next buffer for TX.
|
||||
* Can wait if no buffer available.
|
||||
*/
|
||||
static unsigned char *enet_get_tx_buffer(struct ethernetif *ethernetif)
|
||||
{
|
||||
static unsigned char ucBuffer[ENET_FRAME_MAX_FRAMELEN];
|
||||
return ucBuffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends frame via ENET.
|
||||
*/
|
||||
static err_t enet_send_frame(struct ethernetif *ethernetif, unsigned char *data, const uint32_t length)
|
||||
{
|
||||
#if USE_RTOS && defined(FSL_RTOS_FREE_RTOS)
|
||||
{
|
||||
status_t result;
|
||||
|
||||
lw_print("lw: [%s] len %d\n", __func__, length);
|
||||
|
||||
do
|
||||
{
|
||||
result = ENET_SendFrame(ethernetif->base, ðernetif->handle, data, length);
|
||||
|
||||
if (result == kStatus_ENET_TxFrameBusy)
|
||||
{
|
||||
#ifdef FSL_RTOS_XIUOS
|
||||
KSemaphoreObtain(ethernetif->enetSemaphore, portMAX_DELAY);
|
||||
#else
|
||||
xEventGroupWaitBits(ethernetif->enetTransmitAccessEvent, ethernetif->txFlag, pdTRUE, (BaseType_t) false,
|
||||
portMAX_DELAY);
|
||||
#endif
|
||||
}
|
||||
|
||||
} while (result == kStatus_ENET_TxFrameBusy);
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
#else
|
||||
{
|
||||
uint32_t counter;
|
||||
|
||||
for (counter = ENET_TIMEOUT; counter != 0U; counter--)
|
||||
{
|
||||
if (ENET_SendFrame(ethernetif->base, ðernetif->handle, data, length) != kStatus_ENET_TxFrameBusy)
|
||||
{
|
||||
return ERR_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return ERR_TIMEOUT;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
struct pbuf *ethernetif_linkinput(struct netif *netif)
|
||||
{
|
||||
struct ethernetif *ethernetif = netif->state;
|
||||
struct pbuf *p = NULL;
|
||||
struct pbuf *q;
|
||||
uint32_t len;
|
||||
status_t status;
|
||||
|
||||
/* Obtain the size of the packet and put it into the "len"
|
||||
variable. */
|
||||
status = ENET_GetRxFrameSize(ðernetif->handle, &len);
|
||||
|
||||
if (kStatus_ENET_RxFrameEmpty != status)
|
||||
{
|
||||
/* Call ENET_ReadFrame when there is a received frame. */
|
||||
if (len != 0)
|
||||
{
|
||||
#if ETH_PAD_SIZE
|
||||
len += ETH_PAD_SIZE; /* allow room for Ethernet padding */
|
||||
#endif
|
||||
|
||||
/* We allocate a pbuf chain of pbufs from the pool. */
|
||||
p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
|
||||
|
||||
if (p != NULL)
|
||||
{
|
||||
#if ETH_PAD_SIZE
|
||||
pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
|
||||
#endif
|
||||
if (p->next == 0) /* One-chain buffer.*/
|
||||
{
|
||||
ENET_ReadFrame(ethernetif->base, ðernetif->handle, p->payload, p->len);
|
||||
}
|
||||
else /* Multi-chain buffer.*/
|
||||
{
|
||||
uint8_t data_tmp[ENET_FRAME_MAX_FRAMELEN];
|
||||
uint32_t data_tmp_len = 0;
|
||||
|
||||
ENET_ReadFrame(ethernetif->base, ðernetif->handle, data_tmp, p->tot_len);
|
||||
|
||||
/* We iterate over the pbuf chain until we have read the entire
|
||||
* packet into the pbuf. */
|
||||
for (q = p; (q != NULL) && ((data_tmp_len + q->len) <= sizeof(data_tmp)); q = q->next)
|
||||
{
|
||||
/* Read enough bytes to fill this pbuf in the chain. The
|
||||
* available data in the pbuf is given by the q->len
|
||||
* variable. */
|
||||
memcpy(q->payload, &data_tmp[data_tmp_len], q->len);
|
||||
data_tmp_len += q->len;
|
||||
}
|
||||
}
|
||||
|
||||
MIB2_STATS_NETIF_ADD(netif, ifinoctets, p->tot_len);
|
||||
if (((u8_t *)p->payload)[0] & 1)
|
||||
{
|
||||
/* broadcast or multicast packet*/
|
||||
MIB2_STATS_NETIF_INC(netif, ifinnucastpkts);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* unicast packet*/
|
||||
MIB2_STATS_NETIF_INC(netif, ifinucastpkts);
|
||||
}
|
||||
#if ETH_PAD_SIZE
|
||||
pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
|
||||
#endif
|
||||
|
||||
LINK_STATS_INC(link.recv);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* drop packet*/
|
||||
ENET_ReadFrame(ethernetif->base, ðernetif->handle, NULL, 0U);
|
||||
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_linkinput: Fail to allocate new memory space\n"));
|
||||
|
||||
LINK_STATS_INC(link.memerr);
|
||||
LINK_STATS_INC(link.drop);
|
||||
MIB2_STATS_NETIF_INC(netif, ifindiscards);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Update the received buffer when error happened. */
|
||||
if (status == kStatus_ENET_RxFrameError)
|
||||
{
|
||||
#if 0 && defined(FSL_FEATURE_SOC_ENET_COUNT) && (FSL_FEATURE_SOC_ENET_COUNT > 0) /* Error statisctics */
|
||||
enet_data_error_stats_t eErrStatic;
|
||||
/* Get the error information of the received g_frame. */
|
||||
ENET_GetRxErrBeforeReadFrame(ðernetif->handle, &eErrStatic);
|
||||
#endif
|
||||
/* Update the receive buffer. */
|
||||
ENET_ReadFrame(ethernetif->base, ðernetif->handle, NULL, 0U);
|
||||
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_linkinput: RxFrameError\n"));
|
||||
|
||||
LINK_STATS_INC(link.drop);
|
||||
MIB2_STATS_NETIF_INC(netif, ifindiscards);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
err_t ethernetif_linkoutput(struct netif *netif, struct pbuf *p)
|
||||
{
|
||||
err_t result;
|
||||
struct ethernetif *ethernetif = netif->state;
|
||||
struct pbuf *q;
|
||||
unsigned char *pucBuffer;
|
||||
unsigned char *pucChar;
|
||||
|
||||
LWIP_ASSERT("Output packet buffer empty", p);
|
||||
|
||||
pucBuffer = enet_get_tx_buffer(ethernetif);
|
||||
if (pucBuffer == NULL)
|
||||
{
|
||||
return ERR_BUF;
|
||||
}
|
||||
|
||||
/* Initiate transfer. */
|
||||
|
||||
#if ETH_PAD_SIZE
|
||||
pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
|
||||
#endif
|
||||
|
||||
if (p->len == p->tot_len)
|
||||
{
|
||||
/* No pbuf chain, don't have to copy -> faster. */
|
||||
pucBuffer = (unsigned char *)p->payload;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* pbuf chain, copy into contiguous ucBuffer. */
|
||||
if (p->tot_len > ENET_FRAME_MAX_FRAMELEN)
|
||||
{
|
||||
return ERR_BUF;
|
||||
}
|
||||
else
|
||||
{
|
||||
pucChar = pucBuffer;
|
||||
|
||||
for (q = p; q != NULL; q = q->next)
|
||||
{
|
||||
/* Send the data from the pbuf to the interface, one pbuf at a
|
||||
time. The size of the data in each pbuf is kept in the ->len
|
||||
variable. */
|
||||
/* send data from(q->payload, q->len); */
|
||||
memcpy(pucChar, q->payload, q->len);
|
||||
pucChar += q->len;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Send frame. */
|
||||
result = enet_send_frame(ethernetif, pucBuffer, p->tot_len);
|
||||
|
||||
MIB2_STATS_NETIF_ADD(netif, ifoutoctets, p->tot_len);
|
||||
if (((u8_t *)p->payload)[0] & 1)
|
||||
{
|
||||
/* broadcast or multicast packet*/
|
||||
MIB2_STATS_NETIF_INC(netif, ifoutnucastpkts);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* unicast packet */
|
||||
MIB2_STATS_NETIF_INC(netif, ifoutucastpkts);
|
||||
}
|
||||
/* increase ifoutdiscards or ifouterrors on error */
|
||||
|
||||
#if ETH_PAD_SIZE
|
||||
pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
|
||||
#endif
|
||||
|
||||
LINK_STATS_INC(link.xmit);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should be called at the beginning of the program to set up the
|
||||
* first network interface. It calls the function ethernetif_init() to do the
|
||||
* actual setup of the hardware.
|
||||
*
|
||||
* This function should be passed as a parameter to netif_add().
|
||||
*
|
||||
* @param netif the lwip network interface structure for this ethernetif
|
||||
* @return ERR_OK if the loopif is initialized
|
||||
* ERR_MEM if private data couldn't be allocated
|
||||
* any other err_t on error
|
||||
*/
|
||||
err_t ethernetif0_init(struct netif *netif)
|
||||
{
|
||||
static struct ethernetif ethernetif_0;
|
||||
AT_NONCACHEABLE_SECTION_ALIGN(static enet_rx_bd_struct_t rxBuffDescrip_0[ENET_RXBD_NUM], FSL_ENET_BUFF_ALIGNMENT);
|
||||
AT_NONCACHEABLE_SECTION_ALIGN(static enet_tx_bd_struct_t txBuffDescrip_0[ENET_TXBD_NUM], FSL_ENET_BUFF_ALIGNMENT);
|
||||
SDK_ALIGN(static rx_buffer_t rxDataBuff_0[ENET_RXBD_NUM], FSL_ENET_BUFF_ALIGNMENT);
|
||||
SDK_ALIGN(static tx_buffer_t txDataBuff_0[ENET_TXBD_NUM], FSL_ENET_BUFF_ALIGNMENT);
|
||||
|
||||
ethernetif_0.RxBuffDescrip = &(rxBuffDescrip_0[0]);
|
||||
ethernetif_0.TxBuffDescrip = &(txBuffDescrip_0[0]);
|
||||
ethernetif_0.RxDataBuff = &(rxDataBuff_0[0]);
|
||||
ethernetif_0.TxDataBuff = &(txDataBuff_0[0]);
|
||||
|
||||
return ethernetif_init(netif, ðernetif_0, 0U, (ethernetif_config_t *)netif->state);
|
||||
}
|
||||
|
||||
#if defined(FSL_FEATURE_SOC_ENET_COUNT) && (FSL_FEATURE_SOC_ENET_COUNT > 1)
|
||||
/**
|
||||
* Should be called at the beginning of the program to set up the
|
||||
* second network interface. It calls the function ethernetif_init() to do the
|
||||
* actual setup of the hardware.
|
||||
*
|
||||
* This function should be passed as a parameter to netif_add().
|
||||
*
|
||||
* @param netif the lwip network interface structure for this ethernetif
|
||||
* @return ERR_OK if the loopif is initialized
|
||||
* ERR_MEM if private data couldn't be allocated
|
||||
* any other err_t on error
|
||||
*/
|
||||
err_t ethernetif1_init(struct netif *netif)
|
||||
{
|
||||
static struct ethernetif ethernetif_1;
|
||||
AT_NONCACHEABLE_SECTION_ALIGN(static enet_rx_bd_struct_t rxBuffDescrip_1[ENET_RXBD_NUM], FSL_ENET_BUFF_ALIGNMENT);
|
||||
AT_NONCACHEABLE_SECTION_ALIGN(static enet_tx_bd_struct_t txBuffDescrip_1[ENET_TXBD_NUM], FSL_ENET_BUFF_ALIGNMENT);
|
||||
SDK_ALIGN(static rx_buffer_t rxDataBuff_1[ENET_RXBD_NUM], FSL_ENET_BUFF_ALIGNMENT);
|
||||
SDK_ALIGN(static tx_buffer_t txDataBuff_1[ENET_TXBD_NUM], FSL_ENET_BUFF_ALIGNMENT);
|
||||
|
||||
ethernetif_1.RxBuffDescrip = &(rxBuffDescrip_1[0]);
|
||||
ethernetif_1.TxBuffDescrip = &(txBuffDescrip_1[0]);
|
||||
ethernetif_1.RxDataBuff = &(rxDataBuff_1[0]);
|
||||
ethernetif_1.TxDataBuff = &(txDataBuff_1[0]);
|
||||
|
||||
return ethernetif_init(netif, ðernetif_1, 1U, (ethernetif_config_t *)netif->state);
|
||||
}
|
||||
#endif /* FSL_FEATURE_SOC_*_ENET_COUNT */
|
|
@ -0,0 +1,960 @@
|
|||
/*
|
||||
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||
* 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. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Adam Dunkels <adam@sics.se>
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2013-2016, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2019 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file enet_ethernetif_lpc.c
|
||||
* @brief ethernet drivers
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021.11.11
|
||||
*/
|
||||
|
||||
|
||||
#include "lwip/opt.h"
|
||||
#include "lwip/def.h"
|
||||
#include "lwip/mem.h"
|
||||
#include "lwip/pbuf.h"
|
||||
#include "lwip/stats.h"
|
||||
#include "lwip/snmp.h"
|
||||
#include "lwip/sys.h"
|
||||
#include "lwip/ethip6.h"
|
||||
#include "netif/etharp.h"
|
||||
#include "netif/ppp/pppoe.h"
|
||||
#include "lwip/igmp.h"
|
||||
#include "lwip/mld6.h"
|
||||
|
||||
//#if !NO_SYS
|
||||
//#include "FreeRTOS.h"
|
||||
//#include "event_groups.h"
|
||||
//#include "lwip/tcpip.h"
|
||||
//#endif /* !NO_SYS */
|
||||
|
||||
#include "enet_ethernetif.h"
|
||||
#include "enet_ethernetif_priv.h"
|
||||
|
||||
#include "fsl_enet.h"
|
||||
#include "fsl_phy.h"
|
||||
|
||||
//#if MEM_ALIGNMENT != FSL_ENET_BUFF_ALIGNMENT
|
||||
///* These two has to match for zero-copy functionality */
|
||||
//#error "MEM_ALIGNMENT != FSL_ENET_BUFF_ALIGNMENT"
|
||||
//#endif /* MEM_ALIGNMENT != FSL_ENET_BUFF_ALIGNMENT */
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*!
|
||||
* @brief Used to wrap received data in a pbuf to be passed into lwIP
|
||||
* without copying.
|
||||
* Once last reference is released, RX descriptor will be returned to DMA.
|
||||
*/
|
||||
typedef struct rx_pbuf_wrapper
|
||||
{
|
||||
struct pbuf_custom p; /*!< Pbuf wrapper. Has to be first. */
|
||||
enet_rx_bd_struct_t* rxDesc; /*!< Descriptor holding the data. */
|
||||
struct ethernetif *ethernetif; /*!< Ethernet interface context data. */
|
||||
volatile bool ownedByLwip; /*!< If true, descriptor cannot be reused by DMA yet. */
|
||||
} rx_pbuf_wrapper_t;
|
||||
|
||||
/*!
|
||||
* @brief Helper struct to hold private data used to operate
|
||||
* your ethernet interface.
|
||||
*/
|
||||
struct ethernetif
|
||||
{
|
||||
ENET_Type *base;
|
||||
enet_handle_t handle;
|
||||
#if !NO_SYS
|
||||
EventGroupHandle_t enetTransmitAccessEvent;
|
||||
EventBits_t txFlag;
|
||||
#endif /* !NO_SYS */
|
||||
enet_rx_bd_struct_t *RxBuffDescrip;
|
||||
enet_tx_bd_struct_t *TxBuffDescrip;
|
||||
rx_buffer_t *RxDataBuff;
|
||||
volatile struct pbuf *txPbufs[ENET_TXBD_NUM];
|
||||
volatile uint8_t txIdx;
|
||||
volatile uint8_t txReleaseIdx;
|
||||
rx_pbuf_wrapper_t rxPbufs[ENET_RXBD_NUM];
|
||||
uint8_t rxIdx;
|
||||
const mem_range_t *non_dma_memory;
|
||||
};
|
||||
|
||||
static void ethernetif_tx_release(struct ethernetif *ethernetif);
|
||||
static void ethernetif_rx_release(struct pbuf *p);
|
||||
|
||||
/*******************************************************************************
|
||||
* Code
|
||||
******************************************************************************/
|
||||
|
||||
/**
|
||||
* Called from ENET ISR.
|
||||
*/
|
||||
static void ethernet_callback(ENET_Type *base, enet_handle_t *handle,
|
||||
enet_event_t event, uint8_t channel, void *param)
|
||||
#if NO_SYS
|
||||
{
|
||||
struct netif *netif = (struct netif *)param;
|
||||
struct ethernetif *ethernetif = netif->state;
|
||||
|
||||
if (event == kENET_TxIntEvent)
|
||||
{
|
||||
ethernetif_tx_release(ethernetif);
|
||||
}
|
||||
}
|
||||
#else
|
||||
{
|
||||
struct netif *netif = (struct netif *)param;
|
||||
struct ethernetif *ethernetif = netif->state;
|
||||
BaseType_t xResult;
|
||||
|
||||
switch (event)
|
||||
{
|
||||
case kENET_RxIntEvent:
|
||||
ethernetif_input(netif);
|
||||
break;
|
||||
case kENET_TxIntEvent:
|
||||
{
|
||||
portBASE_TYPE taskToWake = pdFALSE;
|
||||
|
||||
ethernetif_tx_release(ethernetif);
|
||||
|
||||
#ifdef __CA7_REV
|
||||
if (SystemGetIRQNestingLevel())
|
||||
#else
|
||||
if (__get_IPSR())
|
||||
#endif
|
||||
{
|
||||
xResult = xEventGroupSetBitsFromISR(
|
||||
ethernetif->enetTransmitAccessEvent,
|
||||
ethernetif->txFlag, &taskToWake);
|
||||
if ((pdPASS == xResult) && (pdTRUE == taskToWake))
|
||||
{
|
||||
portYIELD_FROM_ISR(taskToWake);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
xEventGroupSetBits(ethernetif->enetTransmitAccessEvent,
|
||||
ethernetif->txFlag);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif /* NO_SYS */
|
||||
|
||||
#if LWIP_IPV4 && LWIP_IGMP
|
||||
err_t ethernetif_igmp_mac_filter(struct netif *netif, const ip4_addr_t *group,
|
||||
enum netif_mac_filter_action action)
|
||||
{
|
||||
struct ethernetif *ethernetif = netif->state;
|
||||
err_t result;
|
||||
|
||||
switch (action)
|
||||
{
|
||||
case IGMP_ADD_MAC_FILTER:
|
||||
/* LPC ENET does not accept multicast selectively,
|
||||
* so all multicast has to be passed through. */
|
||||
ENET_AcceptAllMulticast(ethernetif->base);
|
||||
result = ERR_OK;
|
||||
break;
|
||||
case IGMP_DEL_MAC_FILTER:
|
||||
/*
|
||||
* Moves the ENET device from a multicast group.
|
||||
* Since we don't keep track of which multicast groups
|
||||
* are still to enabled, the call is commented out.
|
||||
*/
|
||||
/* ENET_RejectAllMulticast(ethernetif->base); */
|
||||
result = ERR_OK;
|
||||
break;
|
||||
default:
|
||||
result = ERR_IF;
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if LWIP_IPV6 && LWIP_IPV6_MLD
|
||||
err_t ethernetif_mld_mac_filter(struct netif *netif, const ip6_addr_t *group,
|
||||
enum netif_mac_filter_action action)
|
||||
{
|
||||
struct ethernetif *ethernetif = netif->state;
|
||||
err_t result;
|
||||
|
||||
switch (action)
|
||||
{
|
||||
case NETIF_ADD_MAC_FILTER:
|
||||
/* LPC ENET does not accept multicast selectively,
|
||||
* so all multicast has to be passed through. */
|
||||
ENET_AcceptAllMulticast(ethernetif->base);
|
||||
result = ERR_OK;
|
||||
break;
|
||||
case NETIF_DEL_MAC_FILTER:
|
||||
/*
|
||||
* Moves the ENET device from a multicast group.
|
||||
* Since we don't keep track of which multicast groups
|
||||
* are still to enabled, the call is commented out.
|
||||
*/
|
||||
/* ENET_RejectAllMulticast(ethernetif->base); */
|
||||
result = ERR_OK;
|
||||
break;
|
||||
default:
|
||||
result = ERR_IF;
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Gets the RX descriptor by its index.
|
||||
*/
|
||||
static inline enet_rx_bd_struct_t *ethernetif_get_rx_desc(
|
||||
struct ethernetif *ethernetif,
|
||||
uint32_t index)
|
||||
{
|
||||
return &(ethernetif->RxBuffDescrip[index]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the TX descriptor by its index.
|
||||
*/
|
||||
static inline enet_tx_bd_struct_t *ethernetif_get_tx_desc(
|
||||
struct ethernetif *ethernetif,
|
||||
uint32_t index)
|
||||
{
|
||||
return &(ethernetif->TxBuffDescrip[index]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes ENET driver.
|
||||
*/
|
||||
void ethernetif_enet_init(struct netif *netif, struct ethernetif *ethernetif,
|
||||
const ethernetif_config_t *ethernetifConfig)
|
||||
{
|
||||
enet_config_t config;
|
||||
uint32_t sysClock;
|
||||
enet_buffer_config_t buffCfg[ENET_RING_NUM];
|
||||
uint32_t rxBufferStartAddr[ENET_RXBD_NUM];
|
||||
uint32_t i;
|
||||
|
||||
/* calculate start addresses of all rx buffers */
|
||||
for (i = 0; i < ENET_RXBD_NUM; i++)
|
||||
{
|
||||
rxBufferStartAddr[i] = (uint32_t)&(ethernetif->RxDataBuff[i][ETH_PAD_SIZE]);
|
||||
}
|
||||
|
||||
/* prepare the buffer configuration. */
|
||||
buffCfg[0].rxRingLen = ENET_RXBD_NUM; /* The length of receive buffer descriptor ring. */
|
||||
buffCfg[0].txRingLen = ENET_TXBD_NUM; /* The length of transmit buffer descriptor ring. */
|
||||
buffCfg[0].txDescStartAddrAlign = ethernetif_get_tx_desc(ethernetif, 0U); /* Aligned transmit descriptor start address. */
|
||||
buffCfg[0].txDescTailAddrAlign = ethernetif_get_tx_desc(ethernetif, 0U); /* Aligned transmit descriptor tail address. */
|
||||
buffCfg[0].rxDescStartAddrAlign = ethernetif_get_rx_desc(ethernetif, 0U); /* Aligned receive descriptor start address. */
|
||||
buffCfg[0].rxDescTailAddrAlign = ethernetif_get_rx_desc(ethernetif, ENET_RXBD_NUM); /* Aligned receive descriptor tail address. */
|
||||
buffCfg[0].rxBufferStartAddr = rxBufferStartAddr; /* Start addresses of the rx buffers. */
|
||||
buffCfg[0].rxBuffSizeAlign = sizeof(rx_buffer_t); /* Aligned receive data buffer size. */
|
||||
|
||||
sysClock = CLOCK_GetFreq(ethernetifConfig->clockName);
|
||||
|
||||
LWIP_ASSERT("ethernetifConfig->non_dma_memory == NULL", (ethernetifConfig->non_dma_memory != NULL));
|
||||
ethernetif->non_dma_memory = ethernetifConfig->non_dma_memory;
|
||||
|
||||
ENET_GetDefaultConfig(&config);
|
||||
config.multiqueueCfg = NULL;
|
||||
|
||||
ethernetif_phy_init(ethernetif, ethernetifConfig, &config);
|
||||
|
||||
#if !NO_SYS
|
||||
/* Create the Event for transmit busy release trigger. */
|
||||
ethernetif->enetTransmitAccessEvent = xEventGroupCreate();
|
||||
ethernetif->txFlag = 0x1;
|
||||
#endif /* !NO_SYS */
|
||||
NVIC_SetPriority(ETHERNET_IRQn, ENET_PRIORITY);
|
||||
|
||||
ethernetif->txIdx = 0U;
|
||||
ethernetif->rxIdx = 0U;
|
||||
ethernetif->txReleaseIdx = 0U;
|
||||
|
||||
for (i = 0; i < ENET_RXBD_NUM; i++)
|
||||
{
|
||||
ethernetif->rxPbufs[i].p.custom_free_function = ethernetif_rx_release;
|
||||
ethernetif->rxPbufs[i].rxDesc = ðernetif->RxBuffDescrip[i];
|
||||
ethernetif->rxPbufs[i].ethernetif = ethernetif;
|
||||
ethernetif->rxPbufs[i].ownedByLwip = false;
|
||||
}
|
||||
|
||||
ENET_Init(ethernetif->base, &config, netif->hwaddr, sysClock);
|
||||
|
||||
#if defined(LPC54018_SERIES)
|
||||
/* Workaround for receive issue on lpc54018 */
|
||||
ethernetif->base->MAC_FRAME_FILTER |= ENET_MAC_FRAME_FILTER_RA_MASK;
|
||||
#endif
|
||||
|
||||
/* Create the handler. */
|
||||
#if NO_SYS
|
||||
ENET_EnableInterrupts(ethernetif->base, kENET_DmaTx);
|
||||
#else
|
||||
ENET_EnableInterrupts(ethernetif->base, kENET_DmaTx | kENET_DmaRx);
|
||||
#endif /* NO_SYS */
|
||||
ENET_CreateHandler(ethernetif->base, ðernetif->handle, &config,
|
||||
&buffCfg[0], ethernet_callback, netif);
|
||||
|
||||
ENET_DescriptorInit(ethernetif->base, &config, &buffCfg[0]);
|
||||
|
||||
/* Active TX/RX. */
|
||||
ENET_StartRxTx(ethernetif->base, 1, 1);
|
||||
}
|
||||
|
||||
ENET_Type **ethernetif_enet_ptr(struct ethernetif *ethernetif)
|
||||
{
|
||||
return &(ethernetif->base);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the ENET instance index from its base address.
|
||||
*/
|
||||
static uint32_t ethernetif_get_enet_idx(ENET_Type *base)
|
||||
{
|
||||
static ENET_Type *const s_enetBases[] = ENET_BASE_PTRS;
|
||||
uint32_t instance;
|
||||
|
||||
for (instance = 0; instance < FSL_FEATURE_SOC_LPC_ENET_COUNT; instance++)
|
||||
{
|
||||
if (s_enetBases[instance] == base)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
LWIP_ASSERT("Cannot find ENET instance index from its base address.",
|
||||
instance < FSL_FEATURE_SOC_LPC_ENET_COUNT);
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends (part of) a frame via ENET.
|
||||
* TODO: Since ENET_SendFrame() could not be used, some functionality it does
|
||||
* is missing here for now (channel selection depending on AVB content,
|
||||
* timestamping.
|
||||
*/
|
||||
static void ethernetif_send_buffer(struct ethernetif *ethernetif,
|
||||
unsigned char *data,
|
||||
const uint32_t length,
|
||||
struct pbuf *p_to_release,
|
||||
enet_desc_flag flag)
|
||||
{
|
||||
static const IRQn_Type s_enetIrqId[] = ENET_IRQS;
|
||||
enet_tx_bd_struct_t *txDesc = ethernetif_get_tx_desc(ethernetif,
|
||||
ethernetif->txIdx);
|
||||
ethernetif->txPbufs[ethernetif->txIdx] = p_to_release;
|
||||
ethernetif->txIdx = (ethernetif->txIdx + 1) % ENET_TXBD_NUM;
|
||||
|
||||
/* Prepare the descriptor for transmit. */
|
||||
txDesc->buff1Addr = (uint32_t)data;
|
||||
txDesc->buff2Addr = (uint32_t)NULL;
|
||||
txDesc->buffLen =
|
||||
ENET_TXDESCRIP_RD_BL1(length) | ENET_TXDESCRIP_RD_IOC_MASK;
|
||||
|
||||
txDesc->controlStat =
|
||||
ENET_TXDESCRIP_RD_FL(length) | ENET_TXDESCRIP_RD_LDFD(flag);
|
||||
if ((flag & kENET_FirstFlagOnly) == 0)
|
||||
{
|
||||
/*
|
||||
* Submit to DMA if not the first descriptor in chain.
|
||||
* All the descriptors have to be prepared before the first one
|
||||
* is flagged for DMA and transfer starts. ENET could output invalid
|
||||
* frames otherwise (the exception is Store and Forward mode, where
|
||||
* delays between preparing of descriptors does not matter).
|
||||
*/
|
||||
txDesc->controlStat |= ENET_TXDESCRIP_RD_OWN_MASK;
|
||||
}
|
||||
|
||||
enet_tx_bd_ring_t *txBdRing = (enet_tx_bd_ring_t *)
|
||||
ðernetif->handle.txBdRing[0];
|
||||
|
||||
/*
|
||||
* Increment txDescUsed.
|
||||
* Without this, callback would not fire from ENET ISR on finished TX.
|
||||
* This is kind of a hack. Alternative could be to define
|
||||
* void ETHERNET_DriverIRQHandler(void) and handle IRQs completely
|
||||
* in this file.
|
||||
*/
|
||||
DisableIRQ(s_enetIrqId[ethernetif_get_enet_idx(ethernetif->base)]);
|
||||
txBdRing->txDescUsed++;
|
||||
EnableIRQ(s_enetIrqId[ethernetif_get_enet_idx(ethernetif->base)]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reclaims exactly one TX descriptor after its data has been sent out.
|
||||
* Then the descriptor can be used by application to prepare next data to send.
|
||||
*/
|
||||
static void ethernetif_tx_release(struct ethernetif *ethernetif)
|
||||
{
|
||||
LWIP_ASSERT("Attempt to release more TX buffers than acquired.",
|
||||
ethernetif->txIdx != ethernetif->txReleaseIdx);
|
||||
enet_tx_bd_struct_t *txDesc
|
||||
= ðernetif->TxBuffDescrip[ethernetif->txReleaseIdx];
|
||||
LWIP_ASSERT("TX buffer still owned by DMA.",
|
||||
!ENET_IsTxDescriptorDmaOwn(txDesc));
|
||||
|
||||
struct pbuf *p = (struct pbuf *)
|
||||
ethernetif->txPbufs[ethernetif->txReleaseIdx];
|
||||
if (p != NULL)
|
||||
{
|
||||
#if ETH_PAD_SIZE
|
||||
/* Reclaim the padding, force because it may be REF pbuf. */
|
||||
pbuf_header_force(p, ETH_PAD_SIZE);
|
||||
#endif
|
||||
|
||||
#if NO_SYS
|
||||
#if defined(LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT) && LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT
|
||||
pbuf_free(p);
|
||||
#else
|
||||
#error "Bare metal requires LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT=1 because pbuf_free() is being called from an ISR"
|
||||
#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */
|
||||
#else
|
||||
if (pbuf_free_callback(p) != ERR_OK)
|
||||
{
|
||||
#if defined(LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT) && LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT
|
||||
pbuf_free(p);
|
||||
#else
|
||||
LWIP_ASSERT("Failed to enqueue pbuf deallocation on tcpip_thread",
|
||||
0);
|
||||
#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */
|
||||
}
|
||||
#endif /* NO_SYS */
|
||||
|
||||
ethernetif->txPbufs[ethernetif->txReleaseIdx] = NULL;
|
||||
}
|
||||
|
||||
ethernetif->txReleaseIdx = (ethernetif->txReleaseIdx + 1) % ENET_TXBD_NUM;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reclaims RX descriptor which holds the p's buffer after p is no longer used
|
||||
* by the application / lwIP. The DMA can receive new data into
|
||||
* the descriptor's buffer then.
|
||||
* Note that RX buffers may be freed by lwIP out of the order in which they were
|
||||
* passed to lwIP. Therefore there may be spaces between the RX descriptors
|
||||
* flagged as owned by DMA and DMA could still wait until it's actual position
|
||||
* is released.
|
||||
*/
|
||||
static void ethernetif_rx_release(struct pbuf *p)
|
||||
{
|
||||
SYS_ARCH_DECL_PROTECT(old_level);
|
||||
rx_pbuf_wrapper_t *wrapper = (rx_pbuf_wrapper_t *)p;
|
||||
#if NO_SYS
|
||||
bool intEnable = false;
|
||||
#else
|
||||
bool intEnable = true;
|
||||
#endif /* NO_SYS */
|
||||
|
||||
SYS_ARCH_PROTECT(old_level);
|
||||
|
||||
wrapper->ownedByLwip = false;
|
||||
|
||||
/* Update the receive buffer descriptor. */
|
||||
ENET_UpdateRxDescriptor(wrapper->rxDesc, NULL, NULL, intEnable, false);
|
||||
ENET_UpdateRxDescriptorTail(wrapper->ethernetif->base, 0U,
|
||||
(uint32_t)ethernetif_get_rx_desc(wrapper->ethernetif, ENET_RXBD_NUM));
|
||||
|
||||
SYS_ARCH_UNPROTECT(old_level);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the length of a received frame (if there is some).
|
||||
*/
|
||||
static status_t ethernetif_get_rx_frame_size(struct ethernetif *ethernetif,
|
||||
uint32_t *length)
|
||||
{
|
||||
uint8_t index = ethernetif->rxIdx;
|
||||
enet_rx_bd_struct_t *rxDesc;
|
||||
uint32_t rxControl;
|
||||
|
||||
/* Reset the length to zero. */
|
||||
*length = 0;
|
||||
|
||||
do
|
||||
{
|
||||
rxDesc = ethernetif_get_rx_desc(ethernetif, index);
|
||||
rxControl = ENET_GetRxDescriptor(rxDesc);
|
||||
|
||||
if ((rxControl & ENET_RXDESCRIP_WR_OWN_MASK)
|
||||
|| (ethernetif->rxPbufs[index].ownedByLwip))
|
||||
{
|
||||
/*
|
||||
* Buffer descriptor is owned by DMA or lwIP.
|
||||
* We haven't received any complete frame yet.
|
||||
*/
|
||||
return kStatus_ENET_RxFrameEmpty;
|
||||
}
|
||||
|
||||
/* Application owns the buffer descriptor. */
|
||||
if (rxControl & ENET_RXDESCRIP_WR_LD_MASK)
|
||||
{
|
||||
/* It's last descriptor of a frame, get its status or length. */
|
||||
if (rxControl & ENET_RXDESCRIP_WR_ERRSUM_MASK)
|
||||
{
|
||||
return kStatus_ENET_RxFrameError;
|
||||
}
|
||||
else
|
||||
{
|
||||
*length = rxControl & ENET_RXDESCRIP_WR_PACKETLEN_MASK;
|
||||
return kStatus_Success;
|
||||
}
|
||||
}
|
||||
|
||||
index = (index + 1U) % ENET_RXBD_NUM;
|
||||
} while (index != ethernetif->rxIdx);
|
||||
|
||||
/*
|
||||
* All descriptors have data but the end of the frame not detected.
|
||||
*/
|
||||
return kStatus_ENET_RxFrameError;
|
||||
}
|
||||
|
||||
/**
|
||||
* Drops (releases) receive descriptors until the last one of a frame is reached
|
||||
* or drops entire descriptor ring when all descriptors have data but end
|
||||
* of the frame not detected among them.
|
||||
* Function can be called only after ethernetif_get_rx_frame_size() indicates
|
||||
* that there actually is a frame error or a received frame.
|
||||
*/
|
||||
static void ethernetif_drop_frame(struct ethernetif *ethernetif)
|
||||
{
|
||||
#if NO_SYS
|
||||
bool intEnable = false;
|
||||
#else
|
||||
bool intEnable = true;
|
||||
#endif /* NO_SYS */
|
||||
|
||||
enet_rx_bd_struct_t *rxDesc;
|
||||
uint8_t index = ethernetif->rxIdx;
|
||||
uint32_t rxControl;
|
||||
|
||||
do
|
||||
{
|
||||
rxDesc = ethernetif_get_rx_desc(ethernetif, ethernetif->rxIdx);
|
||||
ethernetif->rxIdx = (ethernetif->rxIdx + 1U) % ENET_RXBD_NUM;
|
||||
rxControl = ENET_GetRxDescriptor(rxDesc);
|
||||
|
||||
/* Update the receive buffer descriptor. */
|
||||
ENET_UpdateRxDescriptor(rxDesc, NULL, NULL, intEnable, false);
|
||||
|
||||
/* Find the last buffer descriptor for the frame. */
|
||||
if (rxControl & ENET_RXDESCRIP_WR_LD_MASK)
|
||||
{
|
||||
break;
|
||||
}
|
||||
} while (ethernetif->rxIdx != index);
|
||||
|
||||
ENET_UpdateRxDescriptorTail(ethernetif->base, 0U,
|
||||
(uint32_t)ethernetif_get_rx_desc(ethernetif, ENET_RXBD_NUM));
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a received frame - wraps its descriptor buffer(s) into a pbuf
|
||||
* or a pbuf chain, flag descriptors as owned by lwIP and returns the pbuf.
|
||||
* The descriptors are returned to DMA only after the returned pbuf is released.
|
||||
* Function can be called only after ethernetif_get_rx_frame_size() indicates
|
||||
* that there actually is a received frame.
|
||||
*/
|
||||
static struct pbuf *ethernetif_read_frame(struct ethernetif *ethernetif,
|
||||
uint32_t length)
|
||||
{
|
||||
rx_pbuf_wrapper_t *wrapper;
|
||||
enet_rx_bd_struct_t *rxDesc;
|
||||
uint32_t rxControl;
|
||||
uint32_t len = 0;
|
||||
struct pbuf *p = NULL;
|
||||
struct pbuf *q = NULL;
|
||||
|
||||
do
|
||||
{
|
||||
wrapper = ðernetif->rxPbufs[ethernetif->rxIdx];
|
||||
wrapper->ownedByLwip = true;
|
||||
ethernetif->rxIdx = (ethernetif->rxIdx + 1U) % ENET_RXBD_NUM;
|
||||
|
||||
rxDesc = wrapper->rxDesc;
|
||||
rxControl = ENET_GetRxDescriptor(rxDesc);
|
||||
|
||||
len = (rxControl & ENET_RXDESCRIP_WR_PACKETLEN_MASK);
|
||||
|
||||
/* Wrap the receive buffer in pbuf. */
|
||||
if (p == NULL)
|
||||
{
|
||||
p = pbuf_alloced_custom(PBUF_RAW, len, PBUF_REF, &wrapper->p,
|
||||
(void *)rxDesc->buff1Addr, len);
|
||||
LWIP_ASSERT("pbuf_alloced_custom() failed", p);
|
||||
|
||||
#if ETH_PAD_SIZE
|
||||
/* Add the padding header, force because it is a REF type buffer. */
|
||||
pbuf_header_force(p, ETH_PAD_SIZE);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
q = pbuf_alloced_custom(PBUF_RAW, len, PBUF_REF, &wrapper->p,
|
||||
(void *)rxDesc->buff1Addr, len);
|
||||
LWIP_ASSERT("pbuf_alloced_custom() failed", q);
|
||||
|
||||
pbuf_cat(p, q);
|
||||
}
|
||||
} while (((rxControl & ENET_RXDESCRIP_WR_LD_MASK) == 0U)
|
||||
&& (p->tot_len < length));
|
||||
|
||||
MIB2_STATS_NETIF_ADD(netif, ifinoctets, p->tot_len);
|
||||
if (((u8_t *)p->payload)[0] & 1)
|
||||
{
|
||||
/* broadcast or multicast packet */
|
||||
MIB2_STATS_NETIF_INC(netif, ifinnucastpkts);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* unicast packet */
|
||||
MIB2_STATS_NETIF_INC(netif, ifinucastpkts);
|
||||
}
|
||||
|
||||
LINK_STATS_INC(link.recv);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to read a frame from ENET and returns it wrapped in a pbuf
|
||||
* or returns NULL when no frame is received. Discards invalid frames.
|
||||
*/
|
||||
struct pbuf *ethernetif_linkinput(struct netif *netif)
|
||||
{
|
||||
struct ethernetif *ethernetif = netif->state;
|
||||
struct pbuf *p = NULL;
|
||||
uint32_t len;
|
||||
status_t status;
|
||||
|
||||
/* Obtain the size of the packet and put it into the "len" variable. */
|
||||
status = ethernetif_get_rx_frame_size(ethernetif, &len);
|
||||
|
||||
if (status == kStatus_Success)
|
||||
{
|
||||
p = ethernetif_read_frame(ethernetif, len);
|
||||
|
||||
if (p == NULL)
|
||||
{
|
||||
/* Could not initialise wrapper pbuf(s) - drop the frame. */
|
||||
ethernetif_drop_frame(ethernetif);
|
||||
|
||||
LWIP_DEBUGF(NETIF_DEBUG,
|
||||
("ethernetif_linkinput: Fail to allocate new memory space\n"));
|
||||
|
||||
LINK_STATS_INC(link.memerr);
|
||||
LINK_STATS_INC(link.drop);
|
||||
MIB2_STATS_NETIF_INC(netif, ifindiscards);
|
||||
}
|
||||
}
|
||||
else if (status == kStatus_ENET_RxFrameError)
|
||||
{
|
||||
/* Update the received buffer when error happened. */
|
||||
ethernetif_drop_frame(ethernetif);
|
||||
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_linkinput: RxFrameError\n"));
|
||||
|
||||
LINK_STATS_INC(link.drop);
|
||||
MIB2_STATS_NETIF_INC(netif, ifindiscards);
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of TX descriptors which could be used by lwIP/application
|
||||
* to put new TX data into.
|
||||
*
|
||||
* The max number of free descriptors is (ENET_TXBD_NUM - 1), that is when
|
||||
* ethernetif->txReleaseIdx == ethernetif->txIdx. Having the capacity decreased
|
||||
* by one allows to avoid locking: txReleaseIdx is advanced only from ISR
|
||||
* and txIdx from tcpip_thread/main loop. Should we use full capacity and have
|
||||
* some variable to indicate between the "all buffers are free" vs. "all buffers
|
||||
* are used" situation, it would be manipulated from two contexts hence locking
|
||||
* would be needed.
|
||||
*/
|
||||
static inline int ethernetif_avail_tx_descs(struct ethernetif *ethernetif)
|
||||
{
|
||||
return (ethernetif->txReleaseIdx + ENET_TXBD_NUM - 1 - ethernetif->txIdx)
|
||||
% ENET_TXBD_NUM;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to output a frame from ENET. The function avoids copying of
|
||||
* p's payload when possible. In such situation it increases p's reference count
|
||||
* and decreases it (and possibly releases p) after the payload is sent.
|
||||
*/
|
||||
err_t ethernetif_linkoutput(struct netif *netif, struct pbuf *p)
|
||||
{
|
||||
struct ethernetif *ethernetif = netif->state;
|
||||
struct pbuf *q;
|
||||
struct pbuf *pbuf_to_free = NULL;
|
||||
struct pbuf *p_copy;
|
||||
uint16_t clen;
|
||||
bool copy = false;
|
||||
const mem_range_t *non_dma_memory;
|
||||
uint8_t *dst;
|
||||
uint32_t cnt = 0;
|
||||
uint8_t first_idx;
|
||||
uint32_t tail_address;
|
||||
|
||||
LWIP_ASSERT("Output packet buffer empty", p);
|
||||
|
||||
if ((p->tot_len - ETH_PAD_SIZE) > ENET_FRAME_MAX_FRAMELEN)
|
||||
{
|
||||
return ERR_BUF;
|
||||
}
|
||||
|
||||
clen = pbuf_clen(p);
|
||||
|
||||
/* Check if relocation is needed */
|
||||
|
||||
if (clen > (ENET_TXBD_NUM - 1))
|
||||
{
|
||||
/* Pbuf chain is too long to be prepared for DMA at once. */
|
||||
copy = true;
|
||||
}
|
||||
|
||||
for (q = p; (q != NULL) && !copy; q = q->next)
|
||||
{
|
||||
/*
|
||||
* Check if payload is aligned is not desired: lwIP creates RAM pbufs
|
||||
* in a way that the data coming after the headers are aligned, but not
|
||||
* the beginning of the ethernet header. LPC ENET DMA will read from
|
||||
* the aligned address, which is ok, because there is additional space
|
||||
* before the headers to make up for alignment - so DMA will not read
|
||||
* from invalid address or unrelated data.
|
||||
*/
|
||||
|
||||
/* Check payload address is usable by ENET DMA */
|
||||
for (non_dma_memory = ethernetif->non_dma_memory;
|
||||
(non_dma_memory->start != 0U)
|
||||
|| (non_dma_memory->end != 0U); non_dma_memory++)
|
||||
{
|
||||
if ((q->payload >= (void *) non_dma_memory->start)
|
||||
&& (q->payload < (void *) non_dma_memory->end))
|
||||
{
|
||||
copy = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (copy)
|
||||
{
|
||||
/* Pbuf needs to be copied. */
|
||||
|
||||
p_copy = pbuf_alloc(PBUF_RAW, (uint16_t) p->tot_len, PBUF_POOL);
|
||||
if (p_copy == NULL)
|
||||
{
|
||||
return ERR_MEM;
|
||||
}
|
||||
|
||||
dst = (uint8_t *) p_copy->payload;
|
||||
for (q = p; q != NULL; q = q->next)
|
||||
{
|
||||
LWIP_ASSERT("Copied bytes would exceed p->tot_len",
|
||||
(q->len + dst - (uint8_t *) p_copy->payload) <= p->tot_len);
|
||||
memcpy(dst, (uint8_t *)q->payload, q->len);
|
||||
dst += q->len;
|
||||
}
|
||||
LWIP_ASSERT("Copied bytes != p->tot_len",
|
||||
(dst - (uint8_t *) p_copy->payload) == p->tot_len);
|
||||
p_copy->len = p_copy->tot_len = p->tot_len;
|
||||
|
||||
p = p_copy;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Increase reference count so p is released only after it is sent.
|
||||
* For copied pbuf, ref is already 1 after pbuf_alloc().
|
||||
*/
|
||||
pbuf_ref(p);
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait until the sufficient number of descriptors are available,
|
||||
* as we have to start the transfer of the first buffer only
|
||||
* after all buffers in chain are prepared.
|
||||
*/
|
||||
while (ethernetif_avail_tx_descs(ethernetif) < clen)
|
||||
{
|
||||
#if !NO_SYS
|
||||
xEventGroupWaitBits(ethernetif->enetTransmitAccessEvent,
|
||||
ethernetif->txFlag, pdTRUE, (BaseType_t) false,
|
||||
portMAX_DELAY);
|
||||
#endif /* !NO_SYS */
|
||||
cnt++;
|
||||
if (cnt >= ENET_TIMEOUT)
|
||||
{
|
||||
return ERR_TIMEOUT;
|
||||
}
|
||||
}
|
||||
|
||||
#if ETH_PAD_SIZE
|
||||
/* Drop the padding. */
|
||||
pbuf_header(p, -ETH_PAD_SIZE);
|
||||
#endif
|
||||
|
||||
/* Initiate transfer. */
|
||||
|
||||
first_idx = ethernetif->txIdx;
|
||||
|
||||
for (q = p; q != NULL; q = q->next)
|
||||
{
|
||||
enet_desc_flag flag = kENET_MiddleFlag;
|
||||
pbuf_to_free = NULL;
|
||||
|
||||
if (q == p)
|
||||
{
|
||||
flag |= kENET_FirstFlagOnly;
|
||||
}
|
||||
|
||||
if (q->next == NULL)
|
||||
{
|
||||
flag |= kENET_LastFlagOnly;
|
||||
|
||||
/* On last TX interrupt, free pbuf chain. */
|
||||
pbuf_to_free = p;
|
||||
}
|
||||
|
||||
ethernetif_send_buffer(ethernetif, q->payload, q->len, pbuf_to_free,
|
||||
flag);
|
||||
}
|
||||
|
||||
/* All pbufs from chain are prepared, allow DMA to access the first one. */
|
||||
ethernetif_get_tx_desc(ethernetif, first_idx)->controlStat |=
|
||||
ENET_TXDESCRIP_RD_OWN_MASK;
|
||||
|
||||
/* Update the transmit tail address. */
|
||||
if (ethernetif->txIdx == 0U)
|
||||
{
|
||||
tail_address = (uint32_t)ethernetif_get_tx_desc(ethernetif,
|
||||
ENET_TXBD_NUM);
|
||||
}
|
||||
else
|
||||
{
|
||||
tail_address = (uint32_t)ethernetif_get_tx_desc(ethernetif,
|
||||
ethernetif->txIdx);
|
||||
}
|
||||
ENET_UpdateTxDescriptorTail(ethernetif->base, 0, tail_address);
|
||||
|
||||
MIB2_STATS_NETIF_ADD(netif, ifoutoctets, p->tot_len);
|
||||
if (((uint8_t *)p->payload)[0] & 1)
|
||||
{
|
||||
/* broadcast or multicast packet */
|
||||
MIB2_STATS_NETIF_INC(netif, ifoutnucastpkts);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* unicast packet */
|
||||
MIB2_STATS_NETIF_INC(netif, ifoutucastpkts);
|
||||
}
|
||||
LINK_STATS_INC(link.xmit);
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should be called at the beginning of the program to set up the
|
||||
* first network interface. It calls the function ethernetif_init() to do the
|
||||
* actual setup of the hardware.
|
||||
*
|
||||
* This function should be passed as a parameter to netif_add().
|
||||
*
|
||||
* @param netif the lwip network interface structure for this ethernetif
|
||||
* @return ERR_OK if the loopif is initialized
|
||||
* ERR_MEM if private data couldn't be allocated
|
||||
* any other err_t on error
|
||||
*/
|
||||
err_t ethernetif0_init(struct netif *netif)
|
||||
{
|
||||
static struct ethernetif ethernetif_0;
|
||||
AT_NONCACHEABLE_SECTION_ALIGN(static enet_rx_bd_struct_t rxBuffDescrip_0[ENET_RXBD_NUM], FSL_ENET_BUFF_ALIGNMENT);
|
||||
AT_NONCACHEABLE_SECTION_ALIGN(static enet_tx_bd_struct_t txBuffDescrip_0[ENET_TXBD_NUM], FSL_ENET_BUFF_ALIGNMENT);
|
||||
SDK_ALIGN(static rx_buffer_t rxDataBuff_0[ENET_RXBD_NUM], FSL_ENET_BUFF_ALIGNMENT);
|
||||
|
||||
ethernetif_0.RxBuffDescrip = &(rxBuffDescrip_0[0]);
|
||||
ethernetif_0.TxBuffDescrip = &(txBuffDescrip_0[0]);
|
||||
ethernetif_0.RxDataBuff = &(rxDataBuff_0[0]);
|
||||
|
||||
return ethernetif_init(netif, ðernetif_0, 0U, (ethernetif_config_t *)netif->state);
|
||||
}
|
||||
|
||||
#if defined(FSL_FEATURE_SOC_LPC_ENET_COUNT) && (FSL_FEATURE_SOC_LPC_ENET_COUNT > 1)
|
||||
/**
|
||||
* Should be called at the beginning of the program to set up the
|
||||
* second network interface. It calls the function ethernetif_init() to do the
|
||||
* actual setup of the hardware.
|
||||
*
|
||||
* This function should be passed as a parameter to netif_add().
|
||||
*
|
||||
* @param netif the lwip network interface structure for this ethernetif
|
||||
* @return ERR_OK if the loopif is initialized
|
||||
* ERR_MEM if private data couldn't be allocated
|
||||
* any other err_t on error
|
||||
*/
|
||||
err_t ethernetif1_init(struct netif *netif)
|
||||
{
|
||||
static struct ethernetif ethernetif_1;
|
||||
AT_NONCACHEABLE_SECTION_ALIGN(static enet_rx_bd_struct_t rxBuffDescrip_1[ENET_RXBD_NUM], FSL_ENET_BUFF_ALIGNMENT);
|
||||
AT_NONCACHEABLE_SECTION_ALIGN(static enet_tx_bd_struct_t txBuffDescrip_1[ENET_TXBD_NUM], FSL_ENET_BUFF_ALIGNMENT);
|
||||
SDK_ALIGN(static rx_buffer_t rxDataBuff_1[ENET_RXBD_NUM], FSL_ENET_BUFF_ALIGNMENT);
|
||||
|
||||
ethernetif_1.RxBuffDescrip = &(rxBuffDescrip_1[0]);
|
||||
ethernetif_1.TxBuffDescrip = &(txBuffDescrip_1[0]);
|
||||
ethernetif_1.RxDataBuff = &(rxDataBuff_1[0]);
|
||||
|
||||
return ethernetif_init(netif, ðernetif_1, 1U, (ethernetif_config_t *)netif->state);
|
||||
}
|
||||
#endif /* FSL_FEATURE_SOC_*_ENET_COUNT */
|
|
@ -0,0 +1,2 @@
|
|||
SRC_FILES := fsl_phy.c
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -0,0 +1,324 @@
|
|||
/*
|
||||
* The Clear BSD License
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2017 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted (subject to the limitations in the disclaimer below) provided
|
||||
* that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o 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.
|
||||
*
|
||||
* o 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.
|
||||
*
|
||||
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
|
||||
* 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 "fsl_phy.h"
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*! @brief Defines the timeout macro. */
|
||||
#define PHY_TIMEOUT_COUNT 0x3FFFFFFU
|
||||
|
||||
/*******************************************************************************
|
||||
* Prototypes
|
||||
******************************************************************************/
|
||||
|
||||
/*!
|
||||
* @brief Get the ENET instance from peripheral base address.
|
||||
*
|
||||
* @param base ENET peripheral base address.
|
||||
* @return ENET instance.
|
||||
*/
|
||||
extern uint32_t ENET_GetInstance(ENET_Type *base);
|
||||
|
||||
/*******************************************************************************
|
||||
* Variables
|
||||
******************************************************************************/
|
||||
|
||||
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
|
||||
/*! @brief Pointers to enet clocks for each instance. */
|
||||
extern clock_ip_name_t s_enetClock[FSL_FEATURE_SOC_ENET_COUNT];
|
||||
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
|
||||
|
||||
/*******************************************************************************
|
||||
* Code
|
||||
******************************************************************************/
|
||||
|
||||
status_t PHY_Init(ENET_Type *base, uint32_t phyAddr, uint32_t srcClock_Hz)
|
||||
{
|
||||
uint32_t bssReg;
|
||||
uint32_t counter = PHY_TIMEOUT_COUNT;
|
||||
uint32_t idReg = 0;
|
||||
status_t result = kStatus_Success;
|
||||
uint32_t instance = ENET_GetInstance(base);
|
||||
uint32_t timeDelay;
|
||||
|
||||
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
|
||||
/* Set SMI first. */
|
||||
CLOCK_EnableClock(s_enetClock[instance]);
|
||||
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
|
||||
ENET_SetSMI(base, srcClock_Hz, false);
|
||||
|
||||
/* Initialization after PHY stars to work. */
|
||||
while ((idReg != PHY_CONTROL_ID1) && (counter != 0))
|
||||
{
|
||||
PHY_Read(base, phyAddr, PHY_ID1_REG, &idReg);
|
||||
counter --;
|
||||
}
|
||||
|
||||
if (!counter)
|
||||
{
|
||||
return kStatus_Fail;
|
||||
}
|
||||
|
||||
/* Reset PHY. */
|
||||
counter = PHY_TIMEOUT_COUNT;
|
||||
result = PHY_Write(base, phyAddr, PHY_BASICCONTROL_REG, PHY_BCTL_RESET_MASK);
|
||||
if (result == kStatus_Success)
|
||||
{
|
||||
|
||||
/* Set the negotiation. */
|
||||
result = PHY_Write(base, phyAddr, PHY_AUTONEG_ADVERTISE_REG,
|
||||
(PHY_100BASETX_FULLDUPLEX_MASK | PHY_100BASETX_HALFDUPLEX_MASK |
|
||||
PHY_10BASETX_FULLDUPLEX_MASK | PHY_10BASETX_HALFDUPLEX_MASK | 0x1U));
|
||||
if (result == kStatus_Success)
|
||||
{
|
||||
result = PHY_Write(base, phyAddr, PHY_BASICCONTROL_REG,
|
||||
(PHY_BCTL_AUTONEG_MASK | PHY_BCTL_RESTART_AUTONEG_MASK));
|
||||
if (result == kStatus_Success)
|
||||
{
|
||||
/* Check auto negotiation complete. */
|
||||
while (counter --)
|
||||
{
|
||||
result = PHY_Read(base, phyAddr, PHY_BASICSTATUS_REG, &bssReg);
|
||||
if ( result == kStatus_Success)
|
||||
{
|
||||
if ((bssReg & PHY_BSTATUS_AUTONEGCOMP_MASK) != 0)
|
||||
{
|
||||
/* Wait a moment for Phy status stable. */
|
||||
for (timeDelay = 0; timeDelay < PHY_TIMEOUT_COUNT; timeDelay ++)
|
||||
{
|
||||
__ASM("nop");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!counter)
|
||||
{
|
||||
return kStatus_PHY_AutoNegotiateFail;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
status_t PHY_Write(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg, uint32_t data)
|
||||
{
|
||||
uint32_t counter;
|
||||
|
||||
/* Clear the SMI interrupt event. */
|
||||
ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK);
|
||||
|
||||
/* Starts a SMI write command. */
|
||||
ENET_StartSMIWrite(base, phyAddr, phyReg, kENET_MiiWriteValidFrame, data);
|
||||
|
||||
/* Wait for SMI complete. */
|
||||
for (counter = PHY_TIMEOUT_COUNT; counter > 0; counter--)
|
||||
{
|
||||
if (ENET_GetInterruptStatus(base) & ENET_EIR_MII_MASK)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for timeout. */
|
||||
if (!counter)
|
||||
{
|
||||
return kStatus_PHY_SMIVisitTimeout;
|
||||
}
|
||||
|
||||
/* Clear MII interrupt event. */
|
||||
ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK);
|
||||
|
||||
return kStatus_Success;
|
||||
}
|
||||
|
||||
status_t PHY_Read(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg, uint32_t *dataPtr)
|
||||
{
|
||||
assert(dataPtr);
|
||||
|
||||
uint32_t counter;
|
||||
|
||||
/* Clear the MII interrupt event. */
|
||||
ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK);
|
||||
|
||||
/* Starts a SMI read command operation. */
|
||||
ENET_StartSMIRead(base, phyAddr, phyReg, kENET_MiiReadValidFrame);
|
||||
|
||||
/* Wait for MII complete. */
|
||||
for (counter = PHY_TIMEOUT_COUNT; counter > 0; counter--)
|
||||
{
|
||||
if (ENET_GetInterruptStatus(base) & ENET_EIR_MII_MASK)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for timeout. */
|
||||
if (!counter)
|
||||
{
|
||||
return kStatus_PHY_SMIVisitTimeout;
|
||||
}
|
||||
|
||||
/* Get data from MII register. */
|
||||
*dataPtr = ENET_ReadSMIData(base);
|
||||
|
||||
/* Clear MII interrupt event. */
|
||||
ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK);
|
||||
|
||||
return kStatus_Success;
|
||||
}
|
||||
|
||||
status_t PHY_EnableLoopback(ENET_Type *base, uint32_t phyAddr, phy_loop_t mode, phy_speed_t speed, bool enable)
|
||||
{
|
||||
status_t result;
|
||||
uint32_t data = 0;
|
||||
|
||||
/* Set the loop mode. */
|
||||
if (enable)
|
||||
{
|
||||
if (mode == kPHY_LocalLoop)
|
||||
{
|
||||
if (speed == kPHY_Speed100M)
|
||||
{
|
||||
data = PHY_BCTL_SPEED_100M_MASK | PHY_BCTL_DUPLEX_MASK | PHY_BCTL_LOOP_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
data = PHY_BCTL_DUPLEX_MASK | PHY_BCTL_LOOP_MASK;
|
||||
}
|
||||
return PHY_Write(base, phyAddr, PHY_BASICCONTROL_REG, data);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* First read the current status in control register. */
|
||||
result = PHY_Read(base, phyAddr, PHY_CONTROL1_REG, &data);
|
||||
if (result == kStatus_Success)
|
||||
{
|
||||
return PHY_Write(base, phyAddr, PHY_CONTROL1_REG, (data | PHY_CTL1_REMOTELOOP_MASK));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Disable the loop mode. */
|
||||
if (mode == kPHY_LocalLoop)
|
||||
{
|
||||
/* First read the current status in control register. */
|
||||
result = PHY_Read(base, phyAddr, PHY_BASICCONTROL_REG, &data);
|
||||
if (result == kStatus_Success)
|
||||
{
|
||||
data &= ~PHY_BCTL_LOOP_MASK;
|
||||
return PHY_Write(base, phyAddr, PHY_BASICCONTROL_REG, (data | PHY_BCTL_RESTART_AUTONEG_MASK));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* First read the current status in control one register. */
|
||||
result = PHY_Read(base, phyAddr, PHY_CONTROL1_REG, &data);
|
||||
if (result == kStatus_Success)
|
||||
{
|
||||
return PHY_Write(base, phyAddr, PHY_CONTROL1_REG, (data & ~PHY_CTL1_REMOTELOOP_MASK));
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
status_t PHY_GetLinkStatus(ENET_Type *base, uint32_t phyAddr, bool *status)
|
||||
{
|
||||
assert(status);
|
||||
|
||||
status_t result = kStatus_Success;
|
||||
uint32_t data;
|
||||
|
||||
/* Read the basic status register. */
|
||||
result = PHY_Read(base, phyAddr, PHY_BASICSTATUS_REG, &data);
|
||||
if (result == kStatus_Success)
|
||||
{
|
||||
if (!(PHY_BSTATUS_LINKSTATUS_MASK & data))
|
||||
{
|
||||
/* link down. */
|
||||
*status = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* link up. */
|
||||
*status = true;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
status_t PHY_GetLinkSpeedDuplex(ENET_Type *base, uint32_t phyAddr, phy_speed_t *speed, phy_duplex_t *duplex)
|
||||
{
|
||||
assert(duplex);
|
||||
|
||||
status_t result = kStatus_Success;
|
||||
uint32_t data, ctlReg;
|
||||
|
||||
/* Read the control two register. */
|
||||
result = PHY_Read(base, phyAddr, PHY_CONTROL1_REG, &ctlReg);
|
||||
if (result == kStatus_Success)
|
||||
{
|
||||
data = ctlReg & PHY_CTL1_SPEEDUPLX_MASK;
|
||||
if ((PHY_CTL1_10FULLDUPLEX_MASK == data) || (PHY_CTL1_100FULLDUPLEX_MASK == data))
|
||||
{
|
||||
/* Full duplex. */
|
||||
*duplex = kPHY_FullDuplex;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Half duplex. */
|
||||
*duplex = kPHY_HalfDuplex;
|
||||
}
|
||||
|
||||
data = ctlReg & PHY_CTL1_SPEEDUPLX_MASK;
|
||||
if ((PHY_CTL1_100HALFDUPLEX_MASK == data) || (PHY_CTL1_100FULLDUPLEX_MASK == data))
|
||||
{
|
||||
/* 100M speed. */
|
||||
*speed = kPHY_Speed100M;
|
||||
}
|
||||
else
|
||||
{ /* 10M speed. */
|
||||
*speed = kPHY_Speed10M;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
|
@ -0,0 +1,225 @@
|
|||
/*
|
||||
* The Clear BSD License
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2017 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted (subject to the limitations in the disclaimer below) provided
|
||||
* that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o 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.
|
||||
*
|
||||
* o 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.
|
||||
*
|
||||
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
|
||||
* 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 _FSL_PHY_H_
|
||||
#define _FSL_PHY_H_
|
||||
|
||||
#include "fsl_enet.h"
|
||||
|
||||
/*!
|
||||
* @addtogroup phy_driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*! @brief PHY driver version */
|
||||
#define FSL_PHY_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*!< Version 2.0.0. */
|
||||
|
||||
/*! @brief Defines the PHY registers. */
|
||||
#define PHY_BASICCONTROL_REG 0x00U /*!< The PHY basic control register. */
|
||||
#define PHY_BASICSTATUS_REG 0x01U /*!< The PHY basic status register. */
|
||||
#define PHY_ID1_REG 0x02U /*!< The PHY ID one register. */
|
||||
#define PHY_ID2_REG 0x03U /*!< The PHY ID two register. */
|
||||
#define PHY_AUTONEG_ADVERTISE_REG 0x04U /*!< The PHY auto-negotiate advertise register. */
|
||||
#define PHY_CONTROL1_REG 0x1FU /*!< The PHY control one register. */
|
||||
|
||||
#define PHY_CONTROL_ID1 0x07U /*!< The PHY ID1*/
|
||||
|
||||
/*! @brief Defines the mask flag in basic control register. */
|
||||
#define PHY_BCTL_DUPLEX_MASK 0x0100U /*!< The PHY duplex bit mask. */
|
||||
#define PHY_BCTL_RESTART_AUTONEG_MASK 0x0200U /*!< The PHY restart auto negotiation mask. */
|
||||
#define PHY_BCTL_AUTONEG_MASK 0x1000U /*!< The PHY auto negotiation bit mask. */
|
||||
#define PHY_BCTL_SPEED_MASK 0x2000U /*!< The PHY speed bit mask. */
|
||||
#define PHY_BCTL_LOOP_MASK 0x4000U /*!< The PHY loop bit mask. */
|
||||
#define PHY_BCTL_RESET_MASK 0x8000U /*!< The PHY reset bit mask. */
|
||||
#define PHY_BCTL_SPEED_100M_MASK 0x2000U /*!< The PHY 100M speed mask. */
|
||||
|
||||
/*!@brief Defines the mask flag of operation mode in control two register*/
|
||||
#define PHY_CTL1_REMOTELOOP_MASK 0x0004U /*!< The PHY remote loopback mask. */
|
||||
//#define PHY_CTL2_REFCLK_SELECT_MASK 0x0080U /*!< The PHY RMII reference clock select. */
|
||||
#define PHY_CTL1_10HALFDUPLEX_MASK 0x0004U /*!< The PHY 10M half duplex mask. */
|
||||
#define PHY_CTL1_100HALFDUPLEX_MASK 0x0008U /*!< The PHY 100M half duplex mask. */
|
||||
#define PHY_CTL1_10FULLDUPLEX_MASK 0x0014U /*!< The PHY 10M full duplex mask. */
|
||||
#define PHY_CTL1_100FULLDUPLEX_MASK 0x0018U /*!< The PHY 100M full duplex mask. */
|
||||
#define PHY_CTL1_SPEEDUPLX_MASK 0x001CU /*!< The PHY speed and duplex mask. */
|
||||
#define PHY_CTL1_ENERGYDETECT_MASK 0x10U /*!< The PHY signal present on rx differential pair. */
|
||||
#define PHY_CTL1_LINKUP_MASK 0x100U /*!< The PHY link up. */
|
||||
#define PHY_LINK_READY_MASK (PHY_CTL1_ENERGYDETECT_MASK | PHY_CTL1_LINKUP_MASK)
|
||||
|
||||
/*! @brief Defines the mask flag in basic status register. */
|
||||
#define PHY_BSTATUS_LINKSTATUS_MASK 0x0004U /*!< The PHY link status mask. */
|
||||
#define PHY_BSTATUS_AUTONEGABLE_MASK 0x0008U /*!< The PHY auto-negotiation ability mask. */
|
||||
#define PHY_BSTATUS_AUTONEGCOMP_MASK 0x0020U /*!< The PHY auto-negotiation complete mask. */
|
||||
|
||||
/*! @brief Defines the mask flag in PHY auto-negotiation advertise register. */
|
||||
#define PHY_100BaseT4_ABILITY_MASK 0x200U /*!< The PHY have the T4 ability. */
|
||||
#define PHY_100BASETX_FULLDUPLEX_MASK 0x100U /*!< The PHY has the 100M full duplex ability.*/
|
||||
#define PHY_100BASETX_HALFDUPLEX_MASK 0x080U /*!< The PHY has the 100M full duplex ability.*/
|
||||
#define PHY_10BASETX_FULLDUPLEX_MASK 0x040U /*!< The PHY has the 10M full duplex ability.*/
|
||||
#define PHY_10BASETX_HALFDUPLEX_MASK 0x020U /*!< The PHY has the 10M full duplex ability.*/
|
||||
|
||||
/*! @brief Defines the PHY status. */
|
||||
enum _phy_status
|
||||
{
|
||||
kStatus_PHY_SMIVisitTimeout = MAKE_STATUS(kStatusGroup_PHY, 1), /*!< ENET PHY SMI visit timeout. */
|
||||
kStatus_PHY_AutoNegotiateFail = MAKE_STATUS(kStatusGroup_PHY, 2) /*!< ENET PHY AutoNegotiate Fail. */
|
||||
};
|
||||
|
||||
/*! @brief Defines the PHY link speed. This is align with the speed for ENET MAC. */
|
||||
typedef enum _phy_speed
|
||||
{
|
||||
kPHY_Speed10M = 0U, /*!< ENET PHY 10M speed. */
|
||||
kPHY_Speed100M /*!< ENET PHY 100M speed. */
|
||||
} phy_speed_t;
|
||||
|
||||
/*! @brief Defines the PHY link duplex. */
|
||||
typedef enum _phy_duplex
|
||||
{
|
||||
kPHY_HalfDuplex = 0U, /*!< ENET PHY half duplex. */
|
||||
kPHY_FullDuplex /*!< ENET PHY full duplex. */
|
||||
} phy_duplex_t;
|
||||
|
||||
/*! @brief Defines the PHY loopback mode. */
|
||||
typedef enum _phy_loop
|
||||
{
|
||||
kPHY_LocalLoop = 0U, /*!< ENET PHY local loopback. */
|
||||
kPHY_RemoteLoop /*!< ENET PHY remote loopback. */
|
||||
} phy_loop_t;
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @name PHY Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Initializes PHY.
|
||||
*
|
||||
* This function initialize the SMI interface and initialize PHY.
|
||||
* The SMI is the MII management interface between PHY and MAC, which should be
|
||||
* firstly initialized before any other operation for PHY. The PHY initialize with auto-negotiation.
|
||||
*
|
||||
* @param base ENET peripheral base address.
|
||||
* @param phyAddr The PHY address.
|
||||
* @param srcClock_Hz The module clock frequency - system clock for MII management interface - SMI.
|
||||
* @retval kStatus_Success PHY initialize success
|
||||
* @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out
|
||||
* @retval kStatus_PHY_AutoNegotiateFail PHY auto negotiate fail
|
||||
*/
|
||||
status_t PHY_Init(ENET_Type *base, uint32_t phyAddr, uint32_t srcClock_Hz);
|
||||
|
||||
/*!
|
||||
* @brief PHY Write function. This function write data over the SMI to
|
||||
* the specified PHY register. This function is called by all PHY interfaces.
|
||||
*
|
||||
* @param base ENET peripheral base address.
|
||||
* @param phyAddr The PHY address.
|
||||
* @param phyReg The PHY register.
|
||||
* @param data The data written to the PHY register.
|
||||
* @retval kStatus_Success PHY write success
|
||||
* @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out
|
||||
*/
|
||||
status_t PHY_Write(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg, uint32_t data);
|
||||
|
||||
/*!
|
||||
* @brief PHY Read function. This interface read data over the SMI from the
|
||||
* specified PHY register. This function is called by all PHY interfaces.
|
||||
*
|
||||
* @param base ENET peripheral base address.
|
||||
* @param phyAddr The PHY address.
|
||||
* @param phyReg The PHY register.
|
||||
* @param dataPtr The address to store the data read from the PHY register.
|
||||
* @retval kStatus_Success PHY read success
|
||||
* @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out
|
||||
*/
|
||||
status_t PHY_Read(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg, uint32_t *dataPtr);
|
||||
|
||||
/*!
|
||||
* @brief Enables/disables PHY loopback.
|
||||
*
|
||||
* @param base ENET peripheral base address.
|
||||
* @param phyAddr The PHY address.
|
||||
* @param mode The loopback mode to be enabled, please see "phy_loop_t".
|
||||
* the two loopback mode should not be both set. when one loopback mode is set
|
||||
* the other one should be disabled.
|
||||
* @param speed PHY speed for loopback mode.
|
||||
* @param enable True to enable, false to disable.
|
||||
* @retval kStatus_Success PHY loopback success
|
||||
* @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out
|
||||
*/
|
||||
status_t PHY_EnableLoopback(ENET_Type *base, uint32_t phyAddr, phy_loop_t mode, phy_speed_t speed, bool enable);
|
||||
|
||||
/*!
|
||||
* @brief Gets the PHY link status.
|
||||
*
|
||||
* @param base ENET peripheral base address.
|
||||
* @param phyAddr The PHY address.
|
||||
* @param status The link up or down status of the PHY.
|
||||
* - true the link is up.
|
||||
* - false the link is down.
|
||||
* @retval kStatus_Success PHY get link status success
|
||||
* @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out
|
||||
*/
|
||||
status_t PHY_GetLinkStatus(ENET_Type *base, uint32_t phyAddr, bool *status);
|
||||
|
||||
/*!
|
||||
* @brief Gets the PHY link speed and duplex.
|
||||
*
|
||||
* @param base ENET peripheral base address.
|
||||
* @param phyAddr The PHY address.
|
||||
* @param speed The address of PHY link speed.
|
||||
* @param duplex The link duplex of PHY.
|
||||
* @retval kStatus_Success PHY get link speed and duplex success
|
||||
* @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out
|
||||
*/
|
||||
status_t PHY_GetLinkSpeedDuplex(ENET_Type *base, uint32_t phyAddr, phy_speed_t *speed, phy_duplex_t *duplex);
|
||||
|
||||
/* @} */
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
/*! @}*/
|
||||
|
||||
#endif /* _FSL_PHY_H_ */
|
|
@ -0,0 +1,12 @@
|
|||
|
||||
config PIN_BUS_NAME
|
||||
string "pin bus name"
|
||||
default "pin"
|
||||
|
||||
config PIN_DRIVER_NAME
|
||||
string "pin driver name"
|
||||
default "pin_drv"
|
||||
|
||||
config PIN_DEVICE_NAME
|
||||
string "pin device name"
|
||||
default "pin_dev"
|
|
@ -0,0 +1,3 @@
|
|||
SRC_FILES := connect_gpio.c fsl_gpio.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -0,0 +1,779 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2018-4-30 misonyo the first version.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file connect_gpio.c
|
||||
* @brief support gpio function using bus driver framework
|
||||
* @version 2.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022-03-16
|
||||
*/
|
||||
|
||||
/*************************************************
|
||||
File name: connect_gpio.c
|
||||
Description: support gpio configure and register to bus framework
|
||||
Others: take RT-Thread v4.0.2/bsp/imxrt/libraries/drivers/drv_gpio.c for references
|
||||
https://github.com/RT-Thread/rt-thread/tree/v4.0.2
|
||||
History:
|
||||
1. Date: 2022-03-16
|
||||
Author: AIIT XUOS Lab
|
||||
Modification: add bus driver framework support for gpio
|
||||
*************************************************/
|
||||
|
||||
#include <connect_gpio.h>
|
||||
#include <fsl_gpio.h>
|
||||
#include <fsl_iomuxc.h>
|
||||
|
||||
struct PinIndex
|
||||
{
|
||||
int index;
|
||||
GPIO_Type *gpio;
|
||||
uint32_t pin;
|
||||
};
|
||||
|
||||
struct PinIrq
|
||||
{
|
||||
uint8 port_source;
|
||||
uint8 pin_source;
|
||||
enum IRQn irq_exti_channel;
|
||||
uint32 exti_line;
|
||||
};
|
||||
|
||||
struct PinMask
|
||||
{
|
||||
GPIO_Type *gpio;
|
||||
uint32 valid_mask;
|
||||
};
|
||||
|
||||
static const IRQn_Type irq_tab[10] =
|
||||
{
|
||||
GPIO1_Combined_0_15_IRQn,
|
||||
GPIO1_Combined_16_31_IRQn,
|
||||
GPIO2_Combined_0_15_IRQn,
|
||||
GPIO2_Combined_16_31_IRQn,
|
||||
GPIO3_Combined_0_15_IRQn,
|
||||
GPIO3_Combined_16_31_IRQn,
|
||||
GPIO4_Combined_0_15_IRQn,
|
||||
GPIO4_Combined_16_31_IRQn,
|
||||
GPIO5_Combined_0_15_IRQn,
|
||||
GPIO5_Combined_16_31_IRQn
|
||||
};
|
||||
|
||||
const struct PinMask pin_mask[] =
|
||||
{
|
||||
{GPIO1, 0xFFFFFFFF}, /* GPIO1 */
|
||||
{GPIO2, 0xFFFFFFFF}, /* GPIO2 */
|
||||
{GPIO3, 0x0FFFFFFF}, /* GPIO3,28~31 not supported */
|
||||
{GPIO4, 0xFFFFFFFF}, /* GPIO4 */
|
||||
{GPIO5, 0x00000007} /* GPIO5,3~31 not supported */
|
||||
};
|
||||
|
||||
struct PinIrqHdr pin_irq_hdr_tab[] =
|
||||
{
|
||||
/* GPIO1 */
|
||||
{-1, 0, NONE, NONE},//1
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},//32
|
||||
/* GPIO2 */
|
||||
{-1, 0, NONE, NONE},//33
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},//64
|
||||
/* GPIO3 */
|
||||
{-1, 0, NONE, NONE},//65
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},//96
|
||||
/* GPIO4 */
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},//128
|
||||
/* GPIO5 */
|
||||
{-1, 0, NONE, NONE},//129
|
||||
{-1, 0, NONE, NONE},
|
||||
{-1, 0, NONE, NONE},
|
||||
};
|
||||
|
||||
#define MUX_BASE 0x401f8014
|
||||
#define CONFIG_BASE 0x401f8204
|
||||
|
||||
#define GPIO5_MUX_BASE 0x400A8000
|
||||
#define GPIO5_CONFIG_BASE 0x400A8018
|
||||
|
||||
const uint8_t reg_offset[] =
|
||||
{
|
||||
42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73,
|
||||
74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,100,101,102,103,104,105,
|
||||
112,113,114,115,116,117,118,119,120,121,122,123,106,107,108,109,110,111, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, -1, -1, -1, -1,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
||||
};
|
||||
|
||||
static int GetPin(struct PinIndex *pin_index, uint8_t pin)
|
||||
{
|
||||
pin_index->index = pin >> 5;//0:GPIO1 1:GPIO2 2:GPIO3 3:GPIO4 4:GPIO5
|
||||
pin_index->pin = pin & 31;//each GPIOx support 32 io
|
||||
|
||||
if ((pin_index->index > 4) || ((pin_mask[pin_index->index].valid_mask & (1 << pin_index->pin)) == 0)) {
|
||||
KPrintf("GetPin unsupport pin index %u pin %u\n", pin_index->index, pin_index->pin);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pin_index->gpio = pin_mask[pin_index->index].gpio;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32 GpioConfigMode(int mode, struct PinIndex *pin_index, int32 pin)
|
||||
{
|
||||
gpio_pin_config_t gpio_config;
|
||||
uint32_t config_value = 0;
|
||||
NULL_PARAM_CHECK(pin_index);
|
||||
|
||||
gpio_config.outputLogic = 0;
|
||||
gpio_config.interruptMode = kGPIO_NoIntmode;
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case GPIO_CFG_OUTPUT:
|
||||
gpio_config.direction = kGPIO_DigitalOutput;
|
||||
config_value = 0x0030U; /* Drive Strength R0/6 */
|
||||
break;
|
||||
case GPIO_CFG_INPUT:
|
||||
gpio_config.direction = kGPIO_DigitalInput;
|
||||
config_value = 0x0830U; /* Open Drain Enable */
|
||||
break;
|
||||
case GPIO_CFG_INPUT_PULLUP:
|
||||
gpio_config.direction = kGPIO_DigitalInput;
|
||||
config_value = 0xB030U; /* 100K Ohm Pull Up */
|
||||
break;
|
||||
case GPIO_CFG_INPUT_PULLDOWN:
|
||||
gpio_config.direction = kGPIO_DigitalInput;
|
||||
config_value = 0x3030U; /* 100K Ohm Pull Down */
|
||||
break;
|
||||
case GPIO_CFG_OUTPUT_OD:
|
||||
gpio_config.direction = kGPIO_DigitalOutput;
|
||||
config_value = 0x0830U; /* Open Drain Enable */
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (pin_mask[pin_index->index].gpio != GPIO5) {
|
||||
CLOCK_EnableClock(kCLOCK_Iomuxc);
|
||||
IOMUXC_SetPinMux(MUX_BASE + reg_offset[pin] * 4, 0x5U, 0, 0, CONFIG_BASE + reg_offset[pin] * 4, 1);
|
||||
IOMUXC_SetPinConfig(MUX_BASE + reg_offset[pin] * 4, 0x5U, 0, 0, CONFIG_BASE + reg_offset[pin] * 4, config_value);
|
||||
} else {
|
||||
CLOCK_EnableClock(kCLOCK_IomuxcSnvs);
|
||||
IOMUXC_SetPinMux(GPIO5_MUX_BASE + pin_index->pin * 4, 0x5U, 0, 0, GPIO5_CONFIG_BASE + pin_index->pin * 4, 1);
|
||||
IOMUXC_SetPinConfig(GPIO5_MUX_BASE + pin_index->pin * 4, 0x5U, 0, 0, GPIO5_CONFIG_BASE + pin_index->pin * 4, config_value);
|
||||
}
|
||||
|
||||
GPIO_PinInit(pin_index->gpio, pin_index->pin, &gpio_config);
|
||||
return EOK;
|
||||
}
|
||||
|
||||
static int32 GpioIrqRegister(int32 pin, int32 mode, void (*hdr)(void *args), void *args)
|
||||
{
|
||||
struct PinIndex pin_index;
|
||||
|
||||
if (GetPin(&pin_index, pin) < 0) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
x_base level = CriticalAreaLock();
|
||||
if (pin_irq_hdr_tab[pin].pin == pin &&
|
||||
pin_irq_hdr_tab[pin].hdr == hdr &&
|
||||
pin_irq_hdr_tab[pin].mode == mode &&
|
||||
pin_irq_hdr_tab[pin].args == args
|
||||
)
|
||||
{
|
||||
CriticalAreaUnLock(level);
|
||||
return EOK;
|
||||
}
|
||||
|
||||
if (pin_irq_hdr_tab[pin].pin != -1) {
|
||||
CriticalAreaUnLock(level);
|
||||
return -EDEV_BUSY;
|
||||
}
|
||||
pin_irq_hdr_tab[pin].pin = pin;
|
||||
pin_irq_hdr_tab[pin].hdr = hdr;
|
||||
pin_irq_hdr_tab[pin].mode = mode;
|
||||
pin_irq_hdr_tab[pin].args = args;
|
||||
CriticalAreaUnLock(level);
|
||||
|
||||
return EOK;
|
||||
}
|
||||
|
||||
static uint32 GpioIrqFree(int32 pin)
|
||||
{
|
||||
struct PinIndex pin_index;
|
||||
|
||||
if (GetPin(&pin_index, pin) < 0) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
x_base level = CriticalAreaLock();
|
||||
if (pin_irq_hdr_tab[pin].pin == -1){
|
||||
CriticalAreaUnLock(level);
|
||||
return EOK;
|
||||
}
|
||||
pin_irq_hdr_tab[pin].pin = -1;
|
||||
pin_irq_hdr_tab[pin].hdr = NONE;
|
||||
pin_irq_hdr_tab[pin].mode = 0;
|
||||
pin_irq_hdr_tab[pin].args = NONE;
|
||||
CriticalAreaUnLock(level);
|
||||
|
||||
return EOK;
|
||||
}
|
||||
|
||||
static int32 GpioIrqEnable(x_base pin)
|
||||
{
|
||||
uint8_t irq_index;
|
||||
gpio_interrupt_mode_t gpio_int_mode;
|
||||
struct PinIndex pin_index;
|
||||
|
||||
if (GetPin(&pin_index, pin) < 0) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
x_base level = CriticalAreaLock();
|
||||
if (pin_irq_hdr_tab[pin].pin == -1) {
|
||||
CriticalAreaUnLock(level);
|
||||
return -ENONESYS;
|
||||
}
|
||||
|
||||
switch (pin_irq_hdr_tab[pin].mode)
|
||||
{
|
||||
case GPIO_IRQ_EDGE_RISING:
|
||||
gpio_int_mode = kGPIO_IntRisingEdge;
|
||||
break;
|
||||
case GPIO_IRQ_EDGE_FALLING:
|
||||
gpio_int_mode = kGPIO_IntFallingEdge;
|
||||
break;
|
||||
case GPIO_IRQ_EDGE_BOTH:
|
||||
gpio_int_mode = kGPIO_IntRisingOrFallingEdge;
|
||||
break;
|
||||
case GPIO_IRQ_LEVEL_HIGH:
|
||||
gpio_int_mode = kGPIO_IntHighLevel;
|
||||
break;
|
||||
case GPIO_IRQ_LEVEL_LOW:
|
||||
gpio_int_mode = kGPIO_IntLowLevel;
|
||||
break;
|
||||
default:
|
||||
gpio_int_mode = kGPIO_IntRisingEdge;
|
||||
break;
|
||||
}
|
||||
|
||||
irq_index = (pin_index.index << 1) + (pin_index.pin >> 4);
|
||||
GPIO_PinSetInterruptConfig(pin_index.gpio, pin_index.pin, gpio_int_mode);
|
||||
GPIO_PortEnableInterrupts(pin_index.gpio, 1U << pin_index.pin);
|
||||
NVIC_SetPriority(irq_tab[irq_index], NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0));
|
||||
EnableIRQ(irq_tab[irq_index]);
|
||||
CriticalAreaUnLock(level);
|
||||
return EOK;
|
||||
}
|
||||
|
||||
static int32 GpioIrqDisable(x_base pin)
|
||||
{
|
||||
struct PinIndex pin_index;
|
||||
|
||||
if (GetPin(&pin_index, pin) < 0) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
GPIO_PortDisableInterrupts(pin_index.gpio, 1U << pin_index.pin);
|
||||
return EOK;
|
||||
}
|
||||
|
||||
static uint32 Imxrt1052PinConfigure(struct PinParam *param)
|
||||
{
|
||||
NULL_PARAM_CHECK(param);
|
||||
int ret = EOK;
|
||||
|
||||
struct PinIndex pin_index;
|
||||
|
||||
if (GetPin(&pin_index, param->pin) < 0) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
switch(param->cmd)
|
||||
{
|
||||
case GPIO_CONFIG_MODE:
|
||||
GpioConfigMode(param->mode, &pin_index, param->pin);
|
||||
break;
|
||||
case GPIO_IRQ_REGISTER:
|
||||
ret = GpioIrqRegister(param->pin, param->irq_set.irq_mode, param->irq_set.hdr, param->irq_set.args);
|
||||
break;
|
||||
case GPIO_IRQ_FREE:
|
||||
ret = GpioIrqFree(param->pin);
|
||||
break;
|
||||
case GPIO_IRQ_ENABLE:
|
||||
ret = GpioIrqEnable(param->pin);
|
||||
break;
|
||||
case GPIO_IRQ_DISABLE:
|
||||
ret = GpioIrqDisable(param->pin);
|
||||
break;
|
||||
default:
|
||||
ret = -EINVALED;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static uint32 Imxrt1052PinInit(void)
|
||||
{
|
||||
static x_bool pin_init_flag = RET_FALSE;
|
||||
|
||||
if (!pin_init_flag) {
|
||||
pin_init_flag = RET_TRUE;
|
||||
}
|
||||
|
||||
return EOK;
|
||||
}
|
||||
|
||||
static uint32 Imxrt1052GpioDrvConfigure(void *drv, struct BusConfigureInfo *configure_info)
|
||||
{
|
||||
NULL_PARAM_CHECK(drv);
|
||||
NULL_PARAM_CHECK(configure_info);
|
||||
|
||||
x_err_t ret = EOK;
|
||||
struct PinParam *param;
|
||||
|
||||
switch (configure_info->configure_cmd)
|
||||
{
|
||||
case OPE_INT:
|
||||
ret = Imxrt1052PinInit();
|
||||
break;
|
||||
case OPE_CFG:
|
||||
param = (struct PinParam *)configure_info->private_data;
|
||||
ret = Imxrt1052PinConfigure(param);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint32 Imxrt1052PinWrite(void *dev, struct BusBlockWriteParam *write_param)
|
||||
{
|
||||
NULL_PARAM_CHECK(dev);
|
||||
NULL_PARAM_CHECK(write_param);
|
||||
struct PinStat *pin_stat = (struct PinStat *)write_param->buffer;
|
||||
struct PinIndex pin_index;
|
||||
|
||||
if (GetPin(&pin_index, pin_stat->pin) < 0) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
if (GPIO_LOW == pin_stat->val) {
|
||||
GPIO_PinWrite(pin_index.gpio, pin_index.pin, 0);
|
||||
} else {
|
||||
GPIO_PinWrite(pin_index.gpio, pin_index.pin, 1);
|
||||
}
|
||||
return EOK;
|
||||
}
|
||||
|
||||
uint32 Imxrt1052PinRead(void *dev, struct BusBlockReadParam *read_param)
|
||||
{
|
||||
NULL_PARAM_CHECK(dev);
|
||||
NULL_PARAM_CHECK(read_param);
|
||||
struct PinStat *pin_stat = (struct PinStat *)read_param->buffer;
|
||||
struct PinIndex pin_index;
|
||||
|
||||
if (GetPin(&pin_index, pin_stat->pin) < 0) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
if(GPIO_LOW == GPIO_PinRead(pin_index.gpio, pin_index.pin)) {
|
||||
pin_stat->val = GPIO_LOW;
|
||||
} else {
|
||||
pin_stat->val = GPIO_HIGH;
|
||||
}
|
||||
return pin_stat->val;
|
||||
}
|
||||
|
||||
static const struct PinDevDone dev_done =
|
||||
{
|
||||
.open = NONE,
|
||||
.close = NONE,
|
||||
.write = Imxrt1052PinWrite,
|
||||
.read = Imxrt1052PinRead,
|
||||
};
|
||||
|
||||
int Imxrt1052HwGpioInit(void)
|
||||
{
|
||||
x_err_t ret = EOK;
|
||||
|
||||
static struct PinBus pin;
|
||||
|
||||
ret = PinBusInit(&pin, PIN_BUS_NAME);
|
||||
if (ret != EOK) {
|
||||
KPrintf("gpio bus init error %d\n", ret);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
static struct PinDriver drv;
|
||||
drv.configure = Imxrt1052GpioDrvConfigure;
|
||||
|
||||
ret = PinDriverInit(&drv, PIN_DRIVER_NAME, NONE);
|
||||
if (ret != EOK) {
|
||||
KPrintf("pin driver init error %d\n", ret);
|
||||
return ERROR;
|
||||
}
|
||||
ret = PinDriverAttachToBus(PIN_DRIVER_NAME, PIN_BUS_NAME);
|
||||
if (ret != EOK) {
|
||||
KPrintf("pin driver attach error %d\n", ret);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
static struct PinHardwareDevice dev;
|
||||
dev.dev_done = &dev_done;
|
||||
|
||||
ret = PinDeviceRegister(&dev, NONE, PIN_DEVICE_NAME);
|
||||
if (ret != EOK) {
|
||||
KPrintf("pin device register error %d\n", ret);
|
||||
return ERROR;
|
||||
}
|
||||
ret = PinDeviceAttachToBus(PIN_DEVICE_NAME, PIN_BUS_NAME);
|
||||
if (ret != EOK) {
|
||||
KPrintf("pin device register error %d\n", ret);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static __inline void PinIrqHdr(uint32_t index_offset, uint8_t pin_start, GPIO_Type *gpio)
|
||||
{
|
||||
int i;
|
||||
uint32_t isr_status, pin;
|
||||
struct PinIndex pin_index;
|
||||
|
||||
isr_status = GPIO_PortGetInterruptFlags(gpio) & gpio->IMR;
|
||||
|
||||
for (i = pin_start; i <= pin_start + 15 ; i ++) {
|
||||
|
||||
if (GetPin(&pin_index, i + index_offset) < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isr_status & (1 << i)) {
|
||||
GPIO_PortClearInterruptFlags(gpio, (1 << i));
|
||||
|
||||
__DSB();
|
||||
|
||||
pin = index_offset + i;
|
||||
if (pin_irq_hdr_tab[pin].hdr) {
|
||||
pin_irq_hdr_tab[pin].hdr(pin_irq_hdr_tab[pin].args);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GPIO1_0_15_IRQHandler(int irq_num, void *arg)
|
||||
{
|
||||
x_base lock = 0;
|
||||
lock = DISABLE_INTERRUPT();
|
||||
|
||||
PinIrqHdr(0, 0, GPIO1);
|
||||
|
||||
ENABLE_INTERRUPT(lock);
|
||||
}
|
||||
DECLARE_HW_IRQ(GPIO1_Combined_0_15_IRQn, GPIO1_0_15_IRQHandler, NONE);
|
||||
|
||||
void GPIO1_16_31_IRQHandler(int irq_num, void *arg)
|
||||
{
|
||||
x_base lock = 0;
|
||||
lock = DISABLE_INTERRUPT();
|
||||
|
||||
PinIrqHdr(0, 15, GPIO1);
|
||||
|
||||
ENABLE_INTERRUPT(lock);
|
||||
}
|
||||
DECLARE_HW_IRQ(GPIO1_Combined_16_31_IRQn, GPIO1_16_31_IRQHandler, NONE);
|
||||
|
||||
void GPIO2_0_15_IRQHandler(int irq_num, void *arg)
|
||||
{
|
||||
x_base lock = 0;
|
||||
lock = DISABLE_INTERRUPT();
|
||||
|
||||
PinIrqHdr(32, 0, GPIO2);
|
||||
|
||||
ENABLE_INTERRUPT(lock);
|
||||
}
|
||||
DECLARE_HW_IRQ(GPIO2_Combined_0_15_IRQn, GPIO2_0_15_IRQHandler, NONE);
|
||||
|
||||
void GPIO2_16_31_IRQHandler(int irq_num, void *arg)
|
||||
{
|
||||
x_base lock = 0;
|
||||
lock = DISABLE_INTERRUPT();
|
||||
|
||||
PinIrqHdr(32, 15, GPIO2);
|
||||
|
||||
ENABLE_INTERRUPT(lock);
|
||||
}
|
||||
DECLARE_HW_IRQ(GPIO2_Combined_16_31_IRQn, GPIO2_16_31_IRQHandler, NONE);
|
||||
|
||||
void GPIO3_0_15_IRQHandler(int irq_num, void *arg)
|
||||
{
|
||||
x_base lock = 0;
|
||||
lock = DISABLE_INTERRUPT();
|
||||
|
||||
PinIrqHdr(64, 0, GPIO3);
|
||||
|
||||
ENABLE_INTERRUPT(lock);
|
||||
}
|
||||
DECLARE_HW_IRQ(GPIO3_Combined_0_15_IRQn, GPIO3_0_15_IRQHandler, NONE);
|
||||
|
||||
void GPIO3_16_31_IRQHandler(int irq_num, void *arg)
|
||||
{
|
||||
x_base lock = 0;
|
||||
lock = DISABLE_INTERRUPT();
|
||||
|
||||
PinIrqHdr(64, 15, GPIO3);
|
||||
|
||||
ENABLE_INTERRUPT(lock);
|
||||
}
|
||||
DECLARE_HW_IRQ(GPIO3_Combined_16_31_IRQn, GPIO3_16_31_IRQHandler, NONE);
|
||||
|
||||
void GPIO4_0_15_IRQHandler(int irq_num, void *arg)
|
||||
{
|
||||
x_base lock = 0;
|
||||
lock = DISABLE_INTERRUPT();
|
||||
|
||||
PinIrqHdr(96, 0, GPIO4);
|
||||
|
||||
ENABLE_INTERRUPT(lock);
|
||||
}
|
||||
DECLARE_HW_IRQ(GPIO4_Combined_0_15_IRQn, GPIO4_0_15_IRQHandler, NONE);
|
||||
|
||||
void GPIO4_16_31_IRQHandler(int irq_num, void *arg)
|
||||
{
|
||||
x_base lock = 0;
|
||||
lock = DISABLE_INTERRUPT();
|
||||
|
||||
PinIrqHdr(96, 15, GPIO4);
|
||||
|
||||
ENABLE_INTERRUPT(lock);
|
||||
}
|
||||
DECLARE_HW_IRQ(GPIO4_Combined_16_31_IRQn, GPIO4_16_31_IRQHandler, NONE);
|
||||
|
||||
void GPIO5_0_15_IRQHandler(int irq_num, void *arg)
|
||||
{
|
||||
x_base lock = 0;
|
||||
lock = DISABLE_INTERRUPT();
|
||||
|
||||
PinIrqHdr(128, 0, GPIO5);
|
||||
|
||||
ENABLE_INTERRUPT(lock);
|
||||
}
|
||||
DECLARE_HW_IRQ(GPIO5_Combined_0_15_IRQn, GPIO5_0_15_IRQHandler, NONE);
|
||||
|
||||
void GPIO5_16_31_IRQHandler(int irq_num, void *arg)
|
||||
{
|
||||
x_base lock = 0;
|
||||
lock = DISABLE_INTERRUPT();
|
||||
|
||||
PinIrqHdr(128, 15, GPIO5);
|
||||
|
||||
ENABLE_INTERRUPT(lock);
|
||||
}
|
||||
DECLARE_HW_IRQ(GPIO5_Combined_16_31_IRQn, GPIO5_16_31_IRQHandler, NONE);
|
||||
|
||||
#ifdef GPIO_LED_TEST
|
||||
static void GpioLedDelay(void)
|
||||
{
|
||||
volatile uint32_t i = 0;
|
||||
for (i = 0; i < 8000000; ++i)
|
||||
{
|
||||
__asm("NOP"); /* delay */
|
||||
}
|
||||
}
|
||||
|
||||
void GpioLedTest(void)
|
||||
{
|
||||
BusType pin;
|
||||
struct BusConfigureInfo configure_info;
|
||||
struct BusBlockWriteParam write_param;
|
||||
|
||||
int ret = 0;
|
||||
bool pinSet = 1;
|
||||
|
||||
pin = BusFind(PIN_BUS_NAME);
|
||||
if (!pin) {
|
||||
KPrintf("find %s failed!\n", PIN_BUS_NAME);
|
||||
return;
|
||||
}
|
||||
pin->owner_driver = BusFindDriver(pin, PIN_DRIVER_NAME);
|
||||
pin->owner_haldev = BusFindDevice(pin, PIN_DEVICE_NAME);
|
||||
|
||||
configure_info.configure_cmd = OPE_INT;
|
||||
ret = BusDrvConfigure(pin->owner_driver, &configure_info);
|
||||
if (ret != EOK) {
|
||||
KPrintf("initialize %s failed!\n", PIN_BUS_NAME);
|
||||
return;
|
||||
}
|
||||
|
||||
struct PinParam led_gpio_param;
|
||||
struct PinStat led_gpio_stat;
|
||||
|
||||
/* config led pin as output*/
|
||||
led_gpio_param.cmd = GPIO_CONFIG_MODE;
|
||||
led_gpio_param.pin = IMXRT_GET_PIN(1, 9);
|
||||
led_gpio_param.mode = GPIO_CFG_OUTPUT_OD;
|
||||
|
||||
configure_info.configure_cmd = OPE_CFG;
|
||||
configure_info.private_data = (void *)&led_gpio_param;
|
||||
ret = BusDrvConfigure(pin->owner_driver, &configure_info);
|
||||
if (ret != EOK) {
|
||||
KPrintf("config pin %d failed!\n", IMXRT_GET_PIN(1, 9));
|
||||
return;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
|
||||
GpioLedDelay();
|
||||
|
||||
if (pinSet) {
|
||||
/* set led pin as high*/
|
||||
led_gpio_stat.pin = IMXRT_GET_PIN(1, 9);
|
||||
led_gpio_stat.val = GPIO_HIGH;
|
||||
write_param.buffer = (void *)&led_gpio_stat;
|
||||
BusDevWriteData(pin->owner_haldev, &write_param);
|
||||
pinSet = 0;
|
||||
} else {
|
||||
/* set led pin as low*/
|
||||
led_gpio_stat.pin = IMXRT_GET_PIN(1, 9);
|
||||
led_gpio_stat.val = GPIO_LOW;
|
||||
write_param.buffer = (void *)&led_gpio_stat;
|
||||
BusDevWriteData(pin->owner_haldev, &write_param);
|
||||
pinSet = 1;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN),
|
||||
GpioLedTest, GpioLedTest, GpioLedTest GPIO1 IO09 LED);
|
||||
#endif
|
|
@ -0,0 +1,171 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2017 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "fsl_gpio.h"
|
||||
|
||||
/* Component ID definition, used by tools. */
|
||||
#ifndef FSL_COMPONENT_ID
|
||||
#define FSL_COMPONENT_ID "platform.drivers.igpio"
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
* Variables
|
||||
******************************************************************************/
|
||||
|
||||
/* Array of GPIO peripheral base address. */
|
||||
static GPIO_Type *const s_gpioBases[] = GPIO_BASE_PTRS;
|
||||
|
||||
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
|
||||
/* Array of GPIO clock name. */
|
||||
static const clock_ip_name_t s_gpioClock[] = GPIO_CLOCKS;
|
||||
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
|
||||
|
||||
/*******************************************************************************
|
||||
* Prototypes
|
||||
******************************************************************************/
|
||||
|
||||
/*!
|
||||
* @brief Gets the GPIO instance according to the GPIO base
|
||||
*
|
||||
* @param base GPIO peripheral base pointer(PTA, PTB, PTC, etc.)
|
||||
* @retval GPIO instance
|
||||
*/
|
||||
static uint32_t GPIO_GetInstance(GPIO_Type *base);
|
||||
|
||||
/*******************************************************************************
|
||||
* Code
|
||||
******************************************************************************/
|
||||
|
||||
static uint32_t GPIO_GetInstance(GPIO_Type *base)
|
||||
{
|
||||
uint32_t instance;
|
||||
|
||||
/* Find the instance index from base address mappings. */
|
||||
for (instance = 0; instance < ARRAY_SIZE(s_gpioBases); instance++)
|
||||
{
|
||||
if (s_gpioBases[instance] == base)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assert(instance < ARRAY_SIZE(s_gpioBases));
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
/*!
|
||||
* brief Initializes the GPIO peripheral according to the specified
|
||||
* parameters in the initConfig.
|
||||
*
|
||||
* param base GPIO base pointer.
|
||||
* param pin Specifies the pin number
|
||||
* param initConfig pointer to a ref gpio_pin_config_t structure that
|
||||
* contains the configuration information.
|
||||
*/
|
||||
void GPIO_PinInit(GPIO_Type *base, uint32_t pin, const gpio_pin_config_t *Config)
|
||||
{
|
||||
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
|
||||
/* Enable GPIO clock. */
|
||||
uint32_t instance = GPIO_GetInstance(base);
|
||||
|
||||
/* If The clock IP is valid, enable the clock gate. */
|
||||
if ((instance < ARRAY_SIZE(s_gpioClock)) && (kCLOCK_IpInvalid != s_gpioClock[instance]))
|
||||
{
|
||||
CLOCK_EnableClock(s_gpioClock[instance]);
|
||||
}
|
||||
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
|
||||
|
||||
/* Register reset to default value */
|
||||
base->IMR &= ~(1U << pin);
|
||||
|
||||
/* Configure GPIO pin direction */
|
||||
if (Config->direction == kGPIO_DigitalInput)
|
||||
{
|
||||
base->GDIR &= ~(1U << pin);
|
||||
}
|
||||
else
|
||||
{
|
||||
GPIO_PinWrite(base, pin, Config->outputLogic);
|
||||
base->GDIR |= (1U << pin);
|
||||
}
|
||||
|
||||
/* Configure GPIO pin interrupt mode */
|
||||
GPIO_SetPinInterruptConfig(base, pin, Config->interruptMode);
|
||||
}
|
||||
|
||||
/*!
|
||||
* brief Sets the output level of the individual GPIO pin to logic 1 or 0.
|
||||
*
|
||||
* param base GPIO base pointer.
|
||||
* param pin GPIO port pin number.
|
||||
* param output GPIOpin output logic level.
|
||||
* - 0: corresponding pin output low-logic level.
|
||||
* - 1: corresponding pin output high-logic level.
|
||||
*/
|
||||
void GPIO_PinWrite(GPIO_Type *base, uint32_t pin, uint8_t output)
|
||||
{
|
||||
assert(pin < 32);
|
||||
if (output == 0U)
|
||||
{
|
||||
base->DR &= ~(1U << pin); /* Set pin output to low level.*/
|
||||
}
|
||||
else
|
||||
{
|
||||
base->DR |= (1U << pin); /* Set pin output to high level.*/
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* brief Sets the current pin interrupt mode.
|
||||
*
|
||||
* param base GPIO base pointer.
|
||||
* param pin GPIO port pin number.
|
||||
* param pininterruptMode pointer to a ref gpio_interrupt_mode_t structure
|
||||
* that contains the interrupt mode information.
|
||||
*/
|
||||
void GPIO_PinSetInterruptConfig(GPIO_Type *base, uint32_t pin, gpio_interrupt_mode_t pinInterruptMode)
|
||||
{
|
||||
volatile uint32_t *icr;
|
||||
uint32_t icrShift;
|
||||
|
||||
icrShift = pin;
|
||||
|
||||
/* Register reset to default value */
|
||||
base->EDGE_SEL &= ~(1U << pin);
|
||||
|
||||
if (pin < 16)
|
||||
{
|
||||
icr = &(base->ICR1);
|
||||
}
|
||||
else
|
||||
{
|
||||
icr = &(base->ICR2);
|
||||
icrShift -= 16;
|
||||
}
|
||||
switch (pinInterruptMode)
|
||||
{
|
||||
case (kGPIO_IntLowLevel):
|
||||
*icr &= ~(3U << (2 * icrShift));
|
||||
break;
|
||||
case (kGPIO_IntHighLevel):
|
||||
*icr = (*icr & (~(3U << (2 * icrShift)))) | (1U << (2 * icrShift));
|
||||
break;
|
||||
case (kGPIO_IntRisingEdge):
|
||||
*icr = (*icr & (~(3U << (2 * icrShift)))) | (2U << (2 * icrShift));
|
||||
break;
|
||||
case (kGPIO_IntFallingEdge):
|
||||
*icr |= (3U << (2 * icrShift));
|
||||
break;
|
||||
case (kGPIO_IntRisingOrFallingEdge):
|
||||
base->EDGE_SEL |= (1U << pin);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
if BSP_USING_I2C
|
||||
config I2C_BUS_NAME_1
|
||||
string "i2c bus 1 name"
|
||||
default "i2c1"
|
||||
config I2C_DRV_NAME_1
|
||||
string "i2c bus 1 driver name"
|
||||
default "i2c1_drv"
|
||||
config I2C_1_DEVICE_NAME_0
|
||||
string "i2c bus 1 device 0 name"
|
||||
default "i2c1_dev0"
|
||||
endif
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
SRC_FILES := connect_i2c.c hardware_i2c.c fsl_lpi2c.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -0,0 +1,179 @@
|
|||
/*
|
||||
* Copyright (c) 2022 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 connect_i2c.c
|
||||
* @brief support imxrt1052 board i2c function and register to bus framework
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022-03-01
|
||||
*/
|
||||
|
||||
#include <board.h>
|
||||
#include "bus_serial.h"
|
||||
#include "connect_i2c.h"
|
||||
#include "fsl_lpi2c.h"
|
||||
|
||||
static uint32 I2cWriteData(struct I2cHardwareDevice *i2c_dev, struct I2cDataStandard *msg)
|
||||
{
|
||||
status_t ret;
|
||||
Stm32I2cType *param = (Stm32I2cType *)i2c_dev->haldev.private_data;
|
||||
ret = I2cHardwareWrite(param->base, param->slave_addr, param->sub_addr, msg->buf, msg->len);
|
||||
if(kStatus_Success == ret)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint32 I2cReadData(struct I2cHardwareDevice *i2c_dev, struct I2cDataStandard *msg)
|
||||
{
|
||||
status_t ret;
|
||||
Stm32I2cType *param = (Stm32I2cType *)i2c_dev->haldev.private_data;
|
||||
ret = I2cHardwareRead(param->base, i2c_dev->i2c_dev_addr, param->sub_addr, msg->buf, msg->len);
|
||||
if(kStatus_Success == ret)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint32 I2cInit(struct I2cDriver *i2c_drv, struct BusConfigureInfo *configure_info)
|
||||
{
|
||||
NULL_PARAM_CHECK(i2c_drv);
|
||||
|
||||
struct I2cHardwareDevice *i2c_dev = (struct I2cHardwareDevice *)i2c_drv->driver.owner_bus->owner_haldev;
|
||||
|
||||
if (configure_info->private_data) {
|
||||
i2c_dev->i2c_dev_addr = *((uint16 *)configure_info->private_data);
|
||||
return EOK;
|
||||
}
|
||||
|
||||
i2c_print("I2cInit need set i2c dev addr\n");
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
static uint32 I2cDrvConfigure(void *drv, struct BusConfigureInfo *configure_info)
|
||||
{
|
||||
NULL_PARAM_CHECK(drv);
|
||||
NULL_PARAM_CHECK(configure_info);
|
||||
|
||||
x_err_t ret = EOK;
|
||||
struct I2cDriver *i2c_drv = (struct I2cDriver *)drv;
|
||||
|
||||
switch (configure_info->configure_cmd)
|
||||
{
|
||||
case OPE_INT:
|
||||
ret = I2cInit(i2c_drv, configure_info);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*manage the i2c device operations*/
|
||||
static const struct I2cDevDone i2c_dev_done =
|
||||
{
|
||||
.dev_open = NONE,
|
||||
.dev_close = NONE,
|
||||
.dev_write = I2cWriteData,
|
||||
.dev_read = I2cReadData,
|
||||
};
|
||||
|
||||
/*Init i2c bus*/
|
||||
static int BoardI2cBusInit(struct I2cBus *i2c_bus, struct I2cDriver *i2c_driver)
|
||||
{
|
||||
x_err_t ret = EOK;
|
||||
|
||||
/*Init the i2c bus */
|
||||
i2c_bus->private_data = (void *)NULL;
|
||||
ret = I2cBusInit(i2c_bus, I2C_BUS_NAME_1);
|
||||
if (EOK != ret) {
|
||||
i2c_print("BoardI2cBusInit I2cBusInit error %d\n", ret);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/*Init the i2c driver*/
|
||||
i2c_driver->private_data = (void *)NULL;
|
||||
ret = I2cDriverInit(i2c_driver, I2C_DRV_NAME_1);
|
||||
if (EOK != ret) {
|
||||
i2c_print("BoardI2cBusInit I2cDriverInit error %d\n", ret);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/*Attach the i2c driver to the i2c bus*/
|
||||
ret = I2cDriverAttachToBus(I2C_DRV_NAME_1, I2C_BUS_NAME_1);
|
||||
if (EOK != ret) {
|
||||
i2c_print("BoardI2cBusInit I2cDriverAttachToBus error %d\n", ret);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*Attach the i2c device to the i2c bus*/
|
||||
static int BoardI2cDevBend(void)
|
||||
{
|
||||
x_err_t ret = EOK;
|
||||
static struct I2cHardwareDevice i2c_device0;
|
||||
memset(&i2c_device0, 0, sizeof(struct I2cHardwareDevice));
|
||||
|
||||
i2c_device0.i2c_dev_done = &i2c_dev_done;
|
||||
|
||||
ret = I2cDeviceRegister(&i2c_device0, NONE, I2C_1_DEVICE_NAME_0);
|
||||
if (EOK != ret) {
|
||||
i2c_print("BoardI2cDevBend I2cDeviceInit device %s error %d\n", I2C_1_DEVICE_NAME_0, ret);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
ret = I2cDeviceAttachToBus(I2C_1_DEVICE_NAME_0, I2C_BUS_NAME_1);
|
||||
if (EOK != ret) {
|
||||
i2c_print("BoardI2cDevBend I2cDeviceAttachToBus device %s error %d\n", I2C_1_DEVICE_NAME_0, ret);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*BOARD I2C INIT*/
|
||||
int Imxrt1052HwI2cInit(void)
|
||||
{
|
||||
static int init_flag = 0;
|
||||
x_err_t ret = EOK;
|
||||
|
||||
if(init_flag)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
init_flag = 1;
|
||||
|
||||
static struct I2cBus i2c_bus;
|
||||
memset(&i2c_bus, 0, sizeof(struct I2cBus));
|
||||
static struct I2cDriver i2c_driver;
|
||||
memset(&i2c_driver, 0, sizeof(struct I2cDriver));
|
||||
|
||||
#ifdef BSP_USING_I2C
|
||||
i2c_driver.configure = I2cDrvConfigure;
|
||||
|
||||
ret = BoardI2cBusInit(&i2c_bus, &i2c_driver);
|
||||
if (EOK != ret) {
|
||||
i2c_print("board_i2c_Init error ret %u\n", ret);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
ret = BoardI2cDevBend();
|
||||
if (EOK != ret) {
|
||||
i2c_print("board_i2c_Init error ret %u\n", ret);
|
||||
return ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* Copyright (c) 2022 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 connect_i2c_eeprom.h
|
||||
* @brief ok1052-c board eeprom relative codes
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022-03-01
|
||||
*/
|
||||
|
||||
#include "board.h"
|
||||
#include "connect_i2c.h"
|
||||
#include "fsl_lpi2c.h"
|
||||
#include "pin_mux.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
#define I2C_EEPROM_BASE LPI2C1
|
||||
#define I2C_EEPROM_ADDR (0xA0 >> 1)
|
||||
|
||||
/*******************************************************************************
|
||||
* Code
|
||||
******************************************************************************/
|
||||
|
||||
void I2cEEpromTestWrite(void)
|
||||
{
|
||||
uint8_t dat[8] = {0};
|
||||
|
||||
if(I2cHardwareRead(I2C_EEPROM_BASE, I2C_EEPROM_ADDR, 0, dat, 8) == kStatus_Success)
|
||||
{
|
||||
i2c_print("Read from EEPROM %d %d %d %d %d %d %d %d\r\n",
|
||||
dat[0], dat[1], dat[2], dat[3], dat[4], dat[5], dat[6], dat[7]);
|
||||
}
|
||||
|
||||
for(uint8_t i = 0; i < 8; i++)
|
||||
{
|
||||
dat[i] ++;
|
||||
}
|
||||
|
||||
if(I2cHardwareWrite(I2C_EEPROM_BASE, I2C_EEPROM_ADDR, 0, dat, 8) == kStatus_Success)
|
||||
{
|
||||
i2c_print("Write to EEPROM %d %d %d %d %d %d %d %d\r\n",
|
||||
dat[0], dat[1], dat[2], dat[3], dat[4], dat[5], dat[6], dat[7]);
|
||||
}
|
||||
|
||||
memset(dat, 0, 8);
|
||||
if(I2cHardwareRead(I2C_EEPROM_BASE, I2C_EEPROM_ADDR, 0, dat, 8) == kStatus_Success)
|
||||
{
|
||||
i2c_print("Read from EEPROM %d %d %d %d %d %d %d %d\r\n",
|
||||
dat[0], dat[1], dat[2], dat[3], dat[4], dat[5], dat[6], dat[7]);
|
||||
}
|
||||
}
|
||||
|
||||
int I2cEEpromTest(void)
|
||||
{
|
||||
BOARD_InitI2C1Pins();
|
||||
I2cHardwareInit();
|
||||
I2cEEpromTestWrite();
|
||||
return 0;
|
||||
}
|
||||
|
||||
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)| SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN)| SHELL_CMD_PARAM_NUM(0),
|
||||
eeprom, I2cEEpromTest, test i2c eeprom);
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* The Clear BSD License
|
||||
* Copyright (c) 2016, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2017 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted (subject to the limitations in the disclaimer below) provided
|
||||
* that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o 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.
|
||||
*
|
||||
* o 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.
|
||||
*
|
||||
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
|
||||
* 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 hardware_i2c.c
|
||||
* @brief ok1052-c i2c board relative codes
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022-03-01
|
||||
*/
|
||||
|
||||
#include "fsl_common.h"
|
||||
#include "fsl_lpi2c.h"
|
||||
|
||||
#define I2C_BASE LPI2C1
|
||||
|
||||
/* Select USB1 PLL (480 MHz) as master lpi2c clock source */
|
||||
#define LPI2C_CLOCK_SOURCE_SELECT (0U)
|
||||
/* Clock divider for master lpi2c clock source */
|
||||
#define LPI2C_CLOCK_SOURCE_DIVIDER (5U)
|
||||
|
||||
#define I2C_CLOCK_FREQ ((CLOCK_GetFreq(kCLOCK_Usb1PllClk) / 8) / (LPI2C_CLOCK_SOURCE_DIVIDER + 1U))
|
||||
#define I2C_BAUDRATE 100000U
|
||||
|
||||
void I2cHardwareInit(void)
|
||||
{
|
||||
lpi2c_master_config_t masterConfig = {0};
|
||||
|
||||
LPI2C_MasterGetDefaultConfig(&masterConfig);
|
||||
|
||||
/* Change the default baudrate configuration */
|
||||
masterConfig.baudRate_Hz = I2C_BAUDRATE;
|
||||
|
||||
/* Initialize the LPI2C master peripheral */
|
||||
LPI2C_MasterInit(I2C_BASE, &masterConfig, I2C_CLOCK_FREQ);
|
||||
}
|
||||
|
||||
status_t I2cHardwareWrite(LPI2C_Type* base, uint16_t slave_addr, uint32_t subAdd, uint8_t* dataBuff, uint16_t dataLen)
|
||||
{
|
||||
lpi2c_master_transfer_t xfer;
|
||||
xfer.slaveAddress = slave_addr;
|
||||
xfer.direction = kLPI2C_Write;
|
||||
xfer.subaddress = subAdd;
|
||||
xfer.subaddressSize = 0x01;
|
||||
xfer.data = dataBuff;
|
||||
xfer.dataSize = dataLen;
|
||||
xfer.flags = kLPI2C_TransferDefaultFlag;
|
||||
return LPI2C_MasterTransferBlocking(base, &xfer);
|
||||
}
|
||||
|
||||
status_t I2cHardwareRead(LPI2C_Type* base, uint16_t slave_addr, uint32_t subAdd, uint8_t* dataBuffer, uint16_t dataLen)
|
||||
{
|
||||
lpi2c_master_transfer_t masterXfer = {0};
|
||||
masterXfer.slaveAddress = slave_addr;
|
||||
masterXfer.direction = kLPI2C_Read;
|
||||
masterXfer.subaddress = subAdd;
|
||||
masterXfer.subaddressSize = 0x01;
|
||||
masterXfer.data = dataBuffer;
|
||||
masterXfer.dataSize = dataLen;
|
||||
masterXfer.flags = kLPI2C_TransferDefaultFlag;
|
||||
return LPI2C_MasterTransferBlocking(base, &masterXfer);
|
||||
}
|
||||
|
42538
Ubiquitous/XiZi/board/xiwangtong-arm32/third_party_driver/include/MIMXRT1052.h
Executable file
|
@ -0,0 +1,627 @@
|
|||
/*
|
||||
** ###################################################################
|
||||
** Version: rev. 1.1, 2018-11-16
|
||||
** Build: b181120
|
||||
**
|
||||
** Abstract:
|
||||
** Chip specific module features.
|
||||
**
|
||||
** Copyright 2016 Freescale Semiconductor, Inc.
|
||||
** Copyright 2016-2018 NXP
|
||||
** All rights reserved.
|
||||
**
|
||||
** SPDX-License-Identifier: BSD-3-Clause
|
||||
**
|
||||
** http: www.nxp.com
|
||||
** mail: support@nxp.com
|
||||
**
|
||||
** Revisions:
|
||||
** - rev. 0.1 (2017-01-10)
|
||||
** Initial version.
|
||||
** - rev. 1.0 (2018-09-21)
|
||||
** Update interrupt vector table and dma request source.
|
||||
** Update register BEE_ADDR_OFFSET1's bitfield name to ADDR_OFFSET1.
|
||||
** Split GPIO_COMBINED_IRQS to GPIO_COMBINED_LOW_IRQS and GPIO_COMBINED_HIGH_IRQS.
|
||||
** - rev. 1.1 (2018-11-16)
|
||||
** Update feature files to align with IMXRT1050RM Rev.1.
|
||||
**
|
||||
** ###################################################################
|
||||
*/
|
||||
|
||||
#ifndef _MIMXRT1052_FEATURES_H_
|
||||
#define _MIMXRT1052_FEATURES_H_
|
||||
|
||||
/* SOC module features */
|
||||
|
||||
/* @brief ADC availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_ADC_COUNT (2)
|
||||
/* @brief AIPSTZ availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_AIPSTZ_COUNT (4)
|
||||
/* @brief AOI availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_AOI_COUNT (2)
|
||||
/* @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 CMP availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_CMP_COUNT (4)
|
||||
/* @brief CSI availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_CSI_COUNT (1)
|
||||
/* @brief DCDC availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_DCDC_COUNT (1)
|
||||
/* @brief DCP availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_DCP_COUNT (1)
|
||||
/* @brief DMAMUX availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_DMAMUX_COUNT (1)
|
||||
/* @brief EDMA availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_EDMA_COUNT (1)
|
||||
/* @brief ENC availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_ENC_COUNT (4)
|
||||
/* @brief ENET availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_ENET_COUNT (1)
|
||||
/* @brief EWM availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_EWM_COUNT (1)
|
||||
/* @brief FLEXCAN availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_FLEXCAN_COUNT (2)
|
||||
/* @brief FLEXIO availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_FLEXIO_COUNT (2)
|
||||
/* @brief FLEXRAM availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_FLEXRAM_COUNT (1)
|
||||
/* @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 GPT availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_GPT_COUNT (2)
|
||||
/* @brief I2S availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_I2S_COUNT (3)
|
||||
/* @brief IGPIO availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_IGPIO_COUNT (5)
|
||||
/* @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 IOMUXC_SNVS availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_IOMUXC_SNVS_COUNT (1)
|
||||
/* @brief KPP availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_KPP_COUNT (1)
|
||||
/* @brief LCDIF availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_LCDIF_COUNT (1)
|
||||
/* @brief LPI2C availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_LPI2C_COUNT (4)
|
||||
/* @brief LPSPI availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_LPSPI_COUNT (4)
|
||||
/* @brief LPUART availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_LPUART_COUNT (8)
|
||||
/* @brief OCOTP availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_OCOTP_COUNT (1)
|
||||
/* @brief PIT availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_PIT_COUNT (1)
|
||||
/* @brief PMU availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_PMU_COUNT (1)
|
||||
/* @brief PWM availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_PWM_COUNT (4)
|
||||
/* @brief PXP availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_PXP_COUNT (1)
|
||||
/* @brief ROMC availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_ROMC_COUNT (1)
|
||||
/* @brief SEMC availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_SEMC_COUNT (1)
|
||||
/* @brief SNVS availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_SNVS_COUNT (1)
|
||||
/* @brief SPDIF availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_SPDIF_COUNT (1)
|
||||
/* @brief SRC availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_SRC_COUNT (1)
|
||||
/* @brief TEMPMON availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_TEMPMON_COUNT (1)
|
||||
/* @brief TMR availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_TMR_COUNT (4)
|
||||
/* @brief TRNG availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_TRNG_COUNT (1)
|
||||
/* @brief TSC availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_TSC_COUNT (1)
|
||||
/* @brief USBHS availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_USBHS_COUNT (2)
|
||||
/* @brief USBNC availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_USBNC_COUNT (2)
|
||||
/* @brief USBPHY availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_USBPHY_COUNT (2)
|
||||
/* @brief USDHC availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_USDHC_COUNT (2)
|
||||
/* @brief WDOG availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_WDOG_COUNT (2)
|
||||
/* @brief XBARA availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_XBARA_COUNT (1)
|
||||
/* @brief XBARB availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_XBARB_COUNT (2)
|
||||
/* @brief XTALOSC24M availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_XTALOSC24M_COUNT (1)
|
||||
|
||||
/* ADC module features */
|
||||
|
||||
/* @brief Remove Hardware Trigger feature. */
|
||||
#define FSL_FEATURE_ADC_SUPPORT_HARDWARE_TRIGGER_REMOVE (0)
|
||||
/* @brief Remove ALT Clock selection feature. */
|
||||
#define FSL_FEATURE_ADC_SUPPORT_ALTCLK_REMOVE (1)
|
||||
/* @brief Conversion control count (related to number of registers HCn and Rn). */
|
||||
#define FSL_FEATURE_ADC_CONVERSION_CONTROL_COUNT (8)
|
||||
|
||||
/* ADC_ETC module features */
|
||||
|
||||
/* @brief Has DMA model control(bit field CTRL[DMA_MODE_SEL]). */
|
||||
#define FSL_FEATURE_ADC_ETC_HAS_CTRL_DMA_MODE_SEL (1)
|
||||
|
||||
/* AOI module features */
|
||||
|
||||
/* @brief Maximum value of input mux. */
|
||||
#define FSL_FEATURE_AOI_MODULE_INPUTS (4)
|
||||
/* @brief Number of events related to number of registers AOIx_BFCRT01n/AOIx_BFCRT23n. */
|
||||
#define FSL_FEATURE_AOI_EVENT_COUNT (4)
|
||||
|
||||
/* 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 (0)
|
||||
/* @brief Insatnce has doze mode support (register bit field MCR[DOZE]). */
|
||||
#define FSL_FEATURE_FLEXCAN_INSTANCE_HAS_DOZE_MODE_SUPPORTn(x) (0)
|
||||
/* @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) (0)
|
||||
/* @brief Has a receive FIFO DMA feature (register bit field MCR[DMA]). */
|
||||
#define FSL_FEATURE_FLEXCAN_HAS_RX_FIFO_DMA (0)
|
||||
/* @brief Instance has a receive FIFO DMA feature (register bit field MCR[DMA]). */
|
||||
#define FSL_FEATURE_FLEXCAN_INSTANCE_HAS_RX_FIFO_DMAn(x) (0)
|
||||
/* @brief Remove CAN Engine Clock Source Selection from unsupported part. */
|
||||
#define FSL_FEATURE_FLEXCAN_SUPPORT_ENGINE_CLK_SEL_REMOVE (1)
|
||||
/* @brief Instance remove CAN Engine Clock Source Selection from unsupported part. */
|
||||
#define FSL_FEATURE_FLEXCAN_INSTANCE_SUPPORT_ENGINE_CLK_SEL_REMOVEn(x) (1)
|
||||
/* @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 (1)
|
||||
/* @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 (1)
|
||||
/* @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 (1)
|
||||
/* @brief Has CAN with Flexible Data rate (CAN FD) protocol. */
|
||||
#define FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE (0)
|
||||
/* @brief CAN instance support Flexible Data rate (CAN FD) protocol. */
|
||||
#define FSL_FEATURE_FLEXCAN_INSTANCE_HAS_FLEXIBLE_DATA_RATEn(x) (0)
|
||||
/* @brief Has extra MB interrupt or common one. */
|
||||
#define FSL_FEATURE_FLEXCAN_HAS_EXTRA_MB_INT (1)
|
||||
|
||||
/* CMP module features */
|
||||
|
||||
/* @brief Has Trigger mode in CMP (register bit field CR1[TRIGM]). */
|
||||
#define FSL_FEATURE_CMP_HAS_TRIGGER_MODE (0)
|
||||
/* @brief Has Window mode in CMP (register bit field CR1[WE]). */
|
||||
#define FSL_FEATURE_CMP_HAS_WINDOW_MODE (1)
|
||||
/* @brief Has External sample supported in CMP (register bit field CR1[SE]). */
|
||||
#define FSL_FEATURE_CMP_HAS_EXTERNAL_SAMPLE_SUPPORT (1)
|
||||
/* @brief Has DMA support in CMP (register bit field SCR[DMAEN]). */
|
||||
#define FSL_FEATURE_CMP_HAS_DMA (1)
|
||||
/* @brief Has Pass Through mode in CMP (register bit field MUXCR[PSTM]). */
|
||||
#define FSL_FEATURE_CMP_HAS_PASS_THROUGH_MODE (0)
|
||||
/* @brief Has DAC Test function in CMP (register DACTEST). */
|
||||
#define FSL_FEATURE_CMP_HAS_DAC_TEST (0)
|
||||
|
||||
/* 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)
|
||||
|
||||
/* DMAMUX module features */
|
||||
|
||||
/* @brief Number of DMA channels (related to number of register CHCFGn). */
|
||||
#define FSL_FEATURE_DMAMUX_MODULE_CHANNEL (32)
|
||||
/* @brief Total number of DMA channels on all modules. */
|
||||
#define FSL_FEATURE_DMAMUX_DMAMUX_CHANNELS (FSL_FEATURE_SOC_DMAMUX_COUNT * 32)
|
||||
/* @brief Has the periodic trigger capability for the triggered DMA channel (register bit CHCFG0[TRIG]). */
|
||||
#define FSL_FEATURE_DMAMUX_HAS_TRIG (1)
|
||||
/* @brief Has DMA Channel Always ON function (register bit CHCFG0[A_ON]). */
|
||||
#define FSL_FEATURE_DMAMUX_HAS_A_ON (1)
|
||||
|
||||
/* ENET module features */
|
||||
|
||||
/* @brief Support Interrupt Coalesce */
|
||||
#define FSL_FEATURE_ENET_HAS_INTERRUPT_COALESCE (1)
|
||||
/* @brief Queue Size. */
|
||||
#define FSL_FEATURE_ENET_QUEUE (1)
|
||||
/* @brief Has AVB Support. */
|
||||
#define FSL_FEATURE_ENET_HAS_AVB (0)
|
||||
/* @brief Has Timer Pulse Width control. */
|
||||
#define FSL_FEATURE_ENET_HAS_TIMER_PWCONTROL (1)
|
||||
/* @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 (0)
|
||||
|
||||
/* EWM module features */
|
||||
|
||||
/* @brief Has clock select (register CLKCTRL). */
|
||||
#define FSL_FEATURE_EWM_HAS_CLOCK_SELECT (1)
|
||||
/* @brief Has clock prescaler (register CLKPRESCALER). */
|
||||
#define FSL_FEATURE_EWM_HAS_PRESCALER (1)
|
||||
|
||||
/* FLEXIO module features */
|
||||
|
||||
/* @brief Has Shifter Status Register (FLEXIO_SHIFTSTAT) */
|
||||
#define FSL_FEATURE_FLEXIO_HAS_SHIFTER_STATUS (1)
|
||||
/* @brief Has Pin Data Input Register (FLEXIO_PIN) */
|
||||
#define FSL_FEATURE_FLEXIO_HAS_PIN_STATUS (1)
|
||||
/* @brief Has Shifter Buffer N Nibble Byte Swapped Register (FLEXIO_SHIFTBUFNBSn) */
|
||||
#define FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_BYTE_SWAP (1)
|
||||
/* @brief Has Shifter Buffer N Half Word Swapped Register (FLEXIO_SHIFTBUFHWSn) */
|
||||
#define FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_HALF_WORD_SWAP (1)
|
||||
/* @brief Has Shifter Buffer N Nibble Swapped Register (FLEXIO_SHIFTBUFNISn) */
|
||||
#define FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_SWAP (1)
|
||||
/* @brief Supports Shifter State Mode (FLEXIO_SHIFTCTLn[SMOD]) */
|
||||
#define FSL_FEATURE_FLEXIO_HAS_STATE_MODE (1)
|
||||
/* @brief Supports Shifter Logic Mode (FLEXIO_SHIFTCTLn[SMOD]) */
|
||||
#define FSL_FEATURE_FLEXIO_HAS_LOGIC_MODE (1)
|
||||
/* @brief Supports paralle width (FLEXIO_SHIFTCFGn[PWIDTH]) */
|
||||
#define FSL_FEATURE_FLEXIO_HAS_PARALLEL_WIDTH (1)
|
||||
/* @brief Reset value of the FLEXIO_VERID register */
|
||||
#define FSL_FEATURE_FLEXIO_VERID_RESET_VALUE (0x1010001)
|
||||
/* @brief Reset value of the FLEXIO_PARAM register */
|
||||
#define FSL_FEATURE_FLEXIO_PARAM_RESET_VALUE (0x2200404)
|
||||
|
||||
/* FLEXRAM module features */
|
||||
|
||||
/* @brief Bank size */
|
||||
#define FSL_FEATURE_FLEXRAM_INTERNAL_RAM_BANK_SIZE (32768)
|
||||
/* @brief Total Bank numbers */
|
||||
#define FSL_FEATURE_FLEXRAM_INTERNAL_RAM_TOTAL_BANK_NUMBERS (16)
|
||||
|
||||
/* FLEXSPI module features */
|
||||
|
||||
/* @brief FlexSPI AHB buffer count */
|
||||
#define FSL_FEATURE_FLEXSPI_AHB_BUFFER_COUNTn(x) (4)
|
||||
/* @brief FlexSPI has no data learn. */
|
||||
#define FSL_FEATURE_FLEXSPI_HAS_NO_DATA_LEARN (1)
|
||||
|
||||
/* GPC module features */
|
||||
|
||||
/* @brief Has DVFS0 Change Request. */
|
||||
#define FSL_FEATURE_GPC_HAS_CNTR_DVFS0CR (0)
|
||||
/* @brief Has GPC interrupt/event masking. */
|
||||
#define FSL_FEATURE_GPC_HAS_CNTR_GPCIRQM (0)
|
||||
/* @brief Has L2 cache power control. */
|
||||
#define FSL_FEATURE_GPC_HAS_CNTR_L2PGE (0)
|
||||
/* @brief Has FLEXRAM PDRAM0(bank1-7) power control. */
|
||||
#define FSL_FEATURE_GPC_HAS_CNTR_PDRAM0PGE (1)
|
||||
/* @brief Has VADC power control. */
|
||||
#define FSL_FEATURE_GPC_HAS_CNTR_VADC (0)
|
||||
/* @brief Has Display power control. */
|
||||
#define FSL_FEATURE_GPC_HAS_CNTR_DISPLAY (0)
|
||||
/* @brief Supports IRQ 0-31. */
|
||||
#define FSL_FEATURE_GPC_HAS_IRQ_0_31 (1)
|
||||
|
||||
/* IGPIO module features */
|
||||
|
||||
/* @brief Has data register set DR_SET. */
|
||||
#define FSL_FEATURE_IGPIO_HAS_DR_SET (1)
|
||||
/* @brief Has data register clear DR_CLEAR. */
|
||||
#define FSL_FEATURE_IGPIO_HAS_DR_CLEAR (1)
|
||||
/* @brief Has data register toggle DR_TOGGLE. */
|
||||
#define FSL_FEATURE_IGPIO_HAS_DR_TOGGLE (1)
|
||||
|
||||
/* LCDIF module features */
|
||||
|
||||
/* @brief LCDIF does not support alpha support. */
|
||||
#define FSL_FEATURE_LCDIF_HAS_NO_AS (1)
|
||||
/* @brief LCDIF does not support output reset pin to LCD panel. */
|
||||
#define FSL_FEATURE_LCDIF_HAS_NO_RESET_PIN (1)
|
||||
/* @brief LCDIF supports LUT. */
|
||||
#define FSL_FEATURE_LCDIF_HAS_LUT (1)
|
||||
|
||||
/* LPI2C module features */
|
||||
|
||||
/* @brief Has separate DMA RX and TX requests. */
|
||||
#define FSL_FEATURE_LPI2C_HAS_SEPARATE_DMA_RX_TX_REQn(x) (0)
|
||||
/* @brief Capacity (number of entries) of the transmit/receive FIFO (or zero if no FIFO is available). */
|
||||
#define FSL_FEATURE_LPI2C_FIFO_SIZEn(x) (4)
|
||||
|
||||
/* LPSPI module features */
|
||||
|
||||
/* @brief Capacity (number of entries) of the transmit/receive FIFO (or zero if no FIFO is available). */
|
||||
#define FSL_FEATURE_LPSPI_FIFO_SIZEn(x) (16)
|
||||
/* @brief Has separate DMA RX and TX requests. */
|
||||
#define FSL_FEATURE_LPSPI_HAS_SEPARATE_DMA_RX_TX_REQn(x) (1)
|
||||
|
||||
/* LPUART module features */
|
||||
|
||||
/* @brief Has receive FIFO overflow detection (bit field CFIFO[RXOFE]). */
|
||||
#define FSL_FEATURE_LPUART_HAS_IRQ_EXTENDED_FUNCTIONS (0)
|
||||
/* @brief Has low power features (can be enabled in wait mode via register bit C1[DOZEEN] or CTRL[DOZEEN] if the registers are 32-bit wide). */
|
||||
#define FSL_FEATURE_LPUART_HAS_LOW_POWER_UART_SUPPORT (1)
|
||||
/* @brief Has extended data register ED (or extra flags in the DATA register if the registers are 32-bit wide). */
|
||||
#define FSL_FEATURE_LPUART_HAS_EXTENDED_DATA_REGISTER_FLAGS (1)
|
||||
/* @brief Capacity (number of entries) of the transmit/receive FIFO (or zero if no FIFO is available). */
|
||||
#define FSL_FEATURE_LPUART_HAS_FIFO (1)
|
||||
/* @brief Has 32-bit register MODIR */
|
||||
#define FSL_FEATURE_LPUART_HAS_MODIR (1)
|
||||
/* @brief Hardware flow control (RTS, CTS) is supported. */
|
||||
#define FSL_FEATURE_LPUART_HAS_MODEM_SUPPORT (1)
|
||||
/* @brief Infrared (modulation) is supported. */
|
||||
#define FSL_FEATURE_LPUART_HAS_IR_SUPPORT (1)
|
||||
/* @brief 2 bits long stop bit is available. */
|
||||
#define FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT (1)
|
||||
/* @brief If 10-bit mode is supported. */
|
||||
#define FSL_FEATURE_LPUART_HAS_10BIT_DATA_SUPPORT (1)
|
||||
/* @brief If 7-bit mode is supported. */
|
||||
#define FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT (1)
|
||||
/* @brief Baud rate fine adjustment is available. */
|
||||
#define FSL_FEATURE_LPUART_HAS_BAUD_RATE_FINE_ADJUST_SUPPORT (0)
|
||||
/* @brief Baud rate oversampling is available (has bit fields C4[OSR], C5[BOTHEDGE], C5[RESYNCDIS] or BAUD[OSR], BAUD[BOTHEDGE], BAUD[RESYNCDIS] if the registers are 32-bit wide). */
|
||||
#define FSL_FEATURE_LPUART_HAS_BAUD_RATE_OVER_SAMPLING_SUPPORT (1)
|
||||
/* @brief Baud rate oversampling is available. */
|
||||
#define FSL_FEATURE_LPUART_HAS_RX_RESYNC_SUPPORT (1)
|
||||
/* @brief Baud rate oversampling is available. */
|
||||
#define FSL_FEATURE_LPUART_HAS_BOTH_EDGE_SAMPLING_SUPPORT (1)
|
||||
/* @brief Peripheral type. */
|
||||
#define FSL_FEATURE_LPUART_IS_SCI (1)
|
||||
/* @brief Capacity (number of entries) of the transmit/receive FIFO (or zero if no FIFO is available). */
|
||||
#define FSL_FEATURE_LPUART_FIFO_SIZEn(x) (4)
|
||||
/* @brief Maximal data width without parity bit. */
|
||||
#define FSL_FEATURE_LPUART_MAX_DATA_WIDTH_WITH_NO_PARITY (10)
|
||||
/* @brief Maximal data width with parity bit. */
|
||||
#define FSL_FEATURE_LPUART_MAX_DATA_WIDTH_WITH_PARITY (9)
|
||||
/* @brief Supports two match addresses to filter incoming frames. */
|
||||
#define FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING (1)
|
||||
/* @brief Has transmitter/receiver DMA enable bits C5[TDMAE]/C5[RDMAE] (or BAUD[TDMAE]/BAUD[RDMAE] if the registers are 32-bit wide). */
|
||||
#define FSL_FEATURE_LPUART_HAS_DMA_ENABLE (1)
|
||||
/* @brief Has transmitter/receiver DMA select bits C4[TDMAS]/C4[RDMAS], resp. C5[TDMAS]/C5[RDMAS] if IS_SCI = 0. */
|
||||
#define FSL_FEATURE_LPUART_HAS_DMA_SELECT (0)
|
||||
/* @brief Data character bit order selection is supported (bit field S2[MSBF] or STAT[MSBF] if the registers are 32-bit wide). */
|
||||
#define FSL_FEATURE_LPUART_HAS_BIT_ORDER_SELECT (1)
|
||||
/* @brief Has smart card (ISO7816 protocol) support and no improved smart card support. */
|
||||
#define FSL_FEATURE_LPUART_HAS_SMART_CARD_SUPPORT (0)
|
||||
/* @brief Has improved smart card (ISO7816 protocol) support. */
|
||||
#define FSL_FEATURE_LPUART_HAS_IMPROVED_SMART_CARD_SUPPORT (0)
|
||||
/* @brief Has local operation network (CEA709.1-B protocol) support. */
|
||||
#define FSL_FEATURE_LPUART_HAS_LOCAL_OPERATION_NETWORK_SUPPORT (0)
|
||||
/* @brief Has 32-bit registers (BAUD, STAT, CTRL, DATA, MATCH, MODIR) instead of 8-bit (BDH, BDL, C1, S1, D, etc.). */
|
||||
#define FSL_FEATURE_LPUART_HAS_32BIT_REGISTERS (1)
|
||||
/* @brief Lin break detect available (has bit BAUD[LBKDIE]). */
|
||||
#define FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT (1)
|
||||
/* @brief UART stops in Wait mode available (has bit C1[UARTSWAI]). */
|
||||
#define FSL_FEATURE_LPUART_HAS_WAIT_MODE_OPERATION (0)
|
||||
/* @brief Has separate DMA RX and TX requests. */
|
||||
#define FSL_FEATURE_LPUART_HAS_SEPARATE_DMA_RX_TX_REQn(x) (1)
|
||||
/* @brief Has separate RX and TX interrupts. */
|
||||
#define FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ (0)
|
||||
/* @brief Has LPAURT_PARAM. */
|
||||
#define FSL_FEATURE_LPUART_HAS_PARAM (1)
|
||||
/* @brief Has LPUART_VERID. */
|
||||
#define FSL_FEATURE_LPUART_HAS_VERID (1)
|
||||
/* @brief Has LPUART_GLOBAL. */
|
||||
#define FSL_FEATURE_LPUART_HAS_GLOBAL (1)
|
||||
/* @brief Has LPUART_PINCFG. */
|
||||
#define FSL_FEATURE_LPUART_HAS_PINCFG (1)
|
||||
|
||||
/* 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 (151)
|
||||
|
||||
/* OCOTP module features */
|
||||
|
||||
/* No feature definitions */
|
||||
|
||||
/* PIT module features */
|
||||
|
||||
/* @brief Number of channels (related to number of registers LDVALn, CVALn, TCTRLn, TFLGn). */
|
||||
#define FSL_FEATURE_PIT_TIMER_COUNT (4)
|
||||
/* @brief Has lifetime timer (related to existence of registers LTMR64L and LTMR64H). */
|
||||
#define FSL_FEATURE_PIT_HAS_LIFETIME_TIMER (1)
|
||||
/* @brief Has chain mode (related to existence of register bit field TCTRLn[CHN]). */
|
||||
#define FSL_FEATURE_PIT_HAS_CHAIN_MODE (1)
|
||||
/* @brief Has shared interrupt handler (has not individual interrupt handler for each channel). */
|
||||
#define FSL_FEATURE_PIT_HAS_SHARED_IRQ_HANDLER (1)
|
||||
/* @brief Has timer enable control. */
|
||||
#define FSL_FEATURE_PIT_HAS_MDIS (1)
|
||||
|
||||
/* PMU module features */
|
||||
|
||||
/* @brief PMU supports lower power control. */
|
||||
#define FSL_FEATURE_PMU_HAS_LOWPWR_CTRL (0)
|
||||
|
||||
/* PWM module features */
|
||||
|
||||
/* @brief Number of each EflexPWM module channels (outputs). */
|
||||
#define FSL_FEATURE_PWM_CHANNEL_COUNT (12U)
|
||||
/* @brief Number of EflexPWM module A channels (outputs). */
|
||||
#define FSL_FEATURE_PWM_CHANNELA_COUNT (4U)
|
||||
/* @brief Number of EflexPWM module B channels (outputs). */
|
||||
#define FSL_FEATURE_PWM_CHANNELB_COUNT (4U)
|
||||
/* @brief Number of EflexPWM module X channels (outputs). */
|
||||
#define FSL_FEATURE_PWM_CHANNELX_COUNT (4U)
|
||||
/* @brief Number of each EflexPWM module compare channels interrupts. */
|
||||
#define FSL_FEATURE_PWM_CMP_INT_HANDLER_COUNT (4U)
|
||||
/* @brief Number of each EflexPWM module reload channels interrupts. */
|
||||
#define FSL_FEATURE_PWM_RELOAD_INT_HANDLER_COUNT (4U)
|
||||
/* @brief Number of each EflexPWM module capture channels interrupts. */
|
||||
#define FSL_FEATURE_PWM_CAP_INT_HANDLER_COUNT (1U)
|
||||
/* @brief Number of each EflexPWM module reload error channels interrupts. */
|
||||
#define FSL_FEATURE_PWM_RERR_INT_HANDLER_COUNT (1U)
|
||||
/* @brief Number of each EflexPWM module fault channels interrupts. */
|
||||
#define FSL_FEATURE_PWM_FAULT_INT_HANDLER_COUNT (1U)
|
||||
/* @brief Number of submodules in each EflexPWM module. */
|
||||
#define FSL_FEATURE_PWM_SUBMODULE_COUNT (4U)
|
||||
|
||||
/* PXP module features */
|
||||
|
||||
/* @brief PXP module has dither engine. */
|
||||
#define FSL_FEATURE_PXP_HAS_DITHER (0)
|
||||
/* @brief PXP module supports repeat run */
|
||||
#define FSL_FEATURE_PXP_HAS_EN_REPEAT (1)
|
||||
/* @brief PXP doesn't have CSC */
|
||||
#define FSL_FEATURE_PXP_HAS_NO_CSC2 (1)
|
||||
/* @brief PXP doesn't have LUT */
|
||||
#define FSL_FEATURE_PXP_HAS_NO_LUT (1)
|
||||
|
||||
/* RTWDOG module features */
|
||||
|
||||
/* @brief Watchdog is available. */
|
||||
#define FSL_FEATURE_RTWDOG_HAS_WATCHDOG (1)
|
||||
/* @brief RTWDOG_CNT can be 32-bit written. */
|
||||
#define FSL_FEATURE_RTWDOG_HAS_32BIT_ACCESS (1)
|
||||
|
||||
/* 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 (32)
|
||||
/* @brief Receive/transmit channel number (register bit fields TCR3[TCE], RCR3[RCE], registers TDRn and RDRn). */
|
||||
#define FSL_FEATURE_SAI_CHANNEL_COUNT (4)
|
||||
/* @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 (2)
|
||||
/* @brief Has register of MCR. */
|
||||
#define FSL_FEATURE_SAI_HAS_MCR (0)
|
||||
/* @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 (0)
|
||||
|
||||
/* SEMC module features */
|
||||
|
||||
/* @brief Has WDH time in NOR controller (register bit field NORCR2[WDH]). */
|
||||
#define FSL_FEATURE_SEMC_HAS_NOR_WDH_TIME (1)
|
||||
/* @brief Has WDS time in NOR controller (register bit field NORCR2[WDS]).) */
|
||||
#define FSL_FEATURE_SEMC_HAS_NOR_WDS_TIME (1)
|
||||
|
||||
/* SNVS module features */
|
||||
|
||||
/* @brief Has Secure Real Time Counter Enabled and Valid (bit field LPCR[SRTC_ENV]). */
|
||||
#define FSL_FEATURE_SNVS_HAS_SRTC (1)
|
||||
|
||||
/* SRC module features */
|
||||
|
||||
/* @brief There is MASK_WDOG3_RST bit in SCR register. */
|
||||
#define FSL_FEATURE_SRC_HAS_SCR_MASK_WDOG3_RST (1)
|
||||
/* @brief There is MIX_RST_STRCH bit in SCR register. */
|
||||
#define FSL_FEATURE_SRC_HAS_SCR_MIX_RST_STRCH (0)
|
||||
/* @brief There is DBG_RST_MSK_PG bit in SCR register. */
|
||||
#define FSL_FEATURE_SRC_HAS_SCR_DBG_RST_MSK_PG (1)
|
||||
/* @brief There is WDOG3_RST_OPTN bit in SCR register. */
|
||||
#define FSL_FEATURE_SRC_HAS_SCR_WDOG3_RST_OPTN (0)
|
||||
/* @brief There is CORES_DBG_RST bit in SCR register. */
|
||||
#define FSL_FEATURE_SRC_HAS_SCR_CORES_DBG_RST (0)
|
||||
/* @brief There is MTSR bit in SCR register. */
|
||||
#define FSL_FEATURE_SRC_HAS_SCR_MTSR (0)
|
||||
/* @brief There is CORE0_DBG_RST bit in SCR register. */
|
||||
#define FSL_FEATURE_SRC_HAS_SCR_CORE0_DBG_RST (1)
|
||||
/* @brief There is CORE0_RST bit in SCR register. */
|
||||
#define FSL_FEATURE_SRC_HAS_SCR_CORE0_RST (1)
|
||||
/* @brief There is LOCKUP_RST bit in SCR register. */
|
||||
#define FSL_FEATURE_SRC_HAS_SCR_LOCKUP_RST (0)
|
||||
/* @brief There is SWRC bit in SCR register. */
|
||||
#define FSL_FEATURE_SRC_HAS_SCR_SWRC (0)
|
||||
/* @brief There is EIM_RST bit in SCR register. */
|
||||
#define FSL_FEATURE_SRC_HAS_SCR_EIM_RST (0)
|
||||
/* @brief There is LUEN bit in SCR register. */
|
||||
#define FSL_FEATURE_SRC_HAS_SCR_LUEN (0)
|
||||
/* @brief There is no WRBC bit in SCR register. */
|
||||
#define FSL_FEATURE_SRC_HAS_NO_SCR_WRBC (1)
|
||||
/* @brief There is no WRE bit in SCR register. */
|
||||
#define FSL_FEATURE_SRC_HAS_NO_SCR_WRE (1)
|
||||
/* @brief There is SISR register. */
|
||||
#define FSL_FEATURE_SRC_HAS_SISR (0)
|
||||
/* @brief There is RESET_OUT bit in SRSR register. */
|
||||
#define FSL_FEATURE_SRC_HAS_SRSR_RESET_OUT (0)
|
||||
/* @brief There is WDOG3_RST_B bit in SRSR register. */
|
||||
#define FSL_FEATURE_SRC_HAS_SRSR_WDOG3_RST_B (1)
|
||||
/* @brief There is SW bit in SRSR register. */
|
||||
#define FSL_FEATURE_SRC_HAS_SRSR_SW (0)
|
||||
/* @brief There is IPP_USER_RESET_B bit in SRSR register. */
|
||||
#define FSL_FEATURE_SRC_HAS_SRSR_IPP_USER_RESET_B (1)
|
||||
/* @brief There is SNVS bit in SRSR register. */
|
||||
#define FSL_FEATURE_SRC_HAS_SRSR_SNVS (0)
|
||||
/* @brief There is CSU_RESET_B bit in SRSR register. */
|
||||
#define FSL_FEATURE_SRC_HAS_SRSR_CSU_RESET_B (1)
|
||||
/* @brief There is LOCKUP bit in SRSR register. */
|
||||
#define FSL_FEATURE_SRC_HAS_SRSR_LOCKUP (0)
|
||||
/* @brief There is LOCKUP_SYSRESETREQ bit in SRSR register. */
|
||||
#define FSL_FEATURE_SRC_HAS_SRSR_LOCKUP_SYSRESETREQ (1)
|
||||
/* @brief There is POR bit in SRSR register. */
|
||||
#define FSL_FEATURE_SRC_HAS_SRSR_POR (0)
|
||||
/* @brief There is IPP_RESET_B bit in SRSR register. */
|
||||
#define FSL_FEATURE_SRC_HAS_SRSR_IPP_RESET_B (1)
|
||||
/* @brief There is no WBI bit in SCR register. */
|
||||
#define FSL_FEATURE_SRC_HAS_NO_SRSR_WBI (1)
|
||||
|
||||
/* SCB 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)
|
||||
|
||||
/* TRNG module features */
|
||||
|
||||
/* @brief TRNG has no TRNG_ACC bitfield. */
|
||||
#define FSL_FEATURE_TRNG_HAS_NO_TRNG_ACC (1)
|
||||
|
||||
/* USBHS module features */
|
||||
|
||||
/* @brief EHCI module instance count */
|
||||
#define FSL_FEATURE_USBHS_EHCI_COUNT (2)
|
||||
/* @brief Number of endpoints supported */
|
||||
#define FSL_FEATURE_USBHS_ENDPT_COUNT (8)
|
||||
|
||||
/* USDHC module features */
|
||||
|
||||
/* @brief Has external DMA support (VEND_SPEC[EXT_DMA_EN]) */
|
||||
#define FSL_FEATURE_USDHC_HAS_EXT_DMA (0)
|
||||
/* @brief Has HS400 mode (MIX_CTRL[HS400_MODE]) */
|
||||
#define FSL_FEATURE_USDHC_HAS_HS400_MODE (0)
|
||||
/* @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)
|
||||
|
||||
/* XBARA module features */
|
||||
|
||||
/* @brief DMA_CH_MUX_REQ_30. */
|
||||
#define FSL_FEATURE_XBARA_OUTPUT_DMA_CH_MUX_REQ_30 (1)
|
||||
/* @brief DMA_CH_MUX_REQ_31. */
|
||||
#define FSL_FEATURE_XBARA_OUTPUT_DMA_CH_MUX_REQ_31 (1)
|
||||
/* @brief DMA_CH_MUX_REQ_94. */
|
||||
#define FSL_FEATURE_XBARA_OUTPUT_DMA_CH_MUX_REQ_94 (1)
|
||||
/* @brief DMA_CH_MUX_REQ_95. */
|
||||
#define FSL_FEATURE_XBARA_OUTPUT_DMA_CH_MUX_REQ_95 (1)
|
||||
|
||||
#endif /* _MIMXRT1052_FEATURES_H_ */
|
||||
|
|
@ -0,0 +1,273 @@
|
|||
/*
|
||||
* 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 connect_ch438.h
|
||||
* @brief define imxrt1052-board ch438 function and struct
|
||||
* @version 2.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022-03-15
|
||||
*/
|
||||
|
||||
#ifndef CONNECT_CH438_H
|
||||
#define CONNECT_CH438_H
|
||||
|
||||
#include <board.h>
|
||||
#include <device.h>
|
||||
#include <connect_gpio.h>
|
||||
|
||||
#define CH438_BUFFSIZE 255
|
||||
|
||||
/******************************************************************************************/
|
||||
|
||||
/* chip definition */
|
||||
/* CH438serial port0 register address */
|
||||
|
||||
#define REG_RBR0_ADDR 0x00 /* serial port0receive buffer register address */
|
||||
#define REG_THR0_ADDR 0x00 /* serial port0send hold register address */
|
||||
#define REG_IER0_ADDR 0x01 /* serial port0interrupt enable register address */
|
||||
#define REG_IIR0_ADDR 0x02 /* serial port0interrupt identifies register address */
|
||||
#define REG_FCR0_ADDR 0x02 /* serial port0FIFO controls register address */
|
||||
#define REG_LCR0_ADDR 0x03 /* serial port0circuit control register address */
|
||||
#define REG_MCR0_ADDR 0x04 /* serial port0MODEM controls register address */
|
||||
#define REG_LSR0_ADDR 0x05 /* serial port0line status register address */
|
||||
#define REG_MSR0_ADDR 0x06 /* serial port0address of MODEM status register */
|
||||
#define REG_SCR0_ADDR 0x07 /* serial port0the user can define the register address */
|
||||
#define REG_DLL0_ADDR 0x00 /* Baud rate divisor latch low 8-bit byte address */
|
||||
#define REG_DLM0_ADDR 0x01 /* Baud rate divisor latch high 8-bit byte address */
|
||||
|
||||
/* CH438serial port1 register address */
|
||||
|
||||
#define REG_RBR1_ADDR 0x10 /* serial port1receive buffer register address */
|
||||
#define REG_THR1_ADDR 0x10 /* serial port1send hold register address */
|
||||
#define REG_IER1_ADDR 0x11 /* serial port1interrupt enable register address */
|
||||
#define REG_IIR1_ADDR 0x12 /* serial port1interrupt identifies register address */
|
||||
#define REG_FCR1_ADDR 0x12 /* serial port1FIFO controls register address */
|
||||
#define REG_LCR1_ADDR 0x13 /* serial port1circuit control register address */
|
||||
#define REG_MCR1_ADDR 0x14 /* serial port1MODEM controls register address */
|
||||
#define REG_LSR1_ADDR 0x15 /* serial port1line status register address */
|
||||
#define REG_MSR1_ADDR 0x16 /* serial port1address of MODEM status register */
|
||||
#define REG_SCR1_ADDR 0x17 /* serial port1the user can define the register address */
|
||||
#define REG_DLL1_ADDR 0x10 /* Baud rate divisor latch low 8-bit byte address */
|
||||
#define REG_DLM1_ADDR 0x11 /* Baud rate divisor latch high 8-bit byte address */
|
||||
|
||||
|
||||
/* CH438serial port2 register address */
|
||||
|
||||
#define REG_RBR2_ADDR 0x20 /* serial port2receive buffer register address */
|
||||
#define REG_THR2_ADDR 0x20 /* serial port2send hold register address */
|
||||
#define REG_IER2_ADDR 0x21 /* serial port2interrupt enable register address */
|
||||
#define REG_IIR2_ADDR 0x22 /* serial port2interrupt identifies register address */
|
||||
#define REG_FCR2_ADDR 0x22 /* serial port2FIFO controls register address */
|
||||
#define REG_LCR2_ADDR 0x23 /* serial port2circuit control register address */
|
||||
#define REG_MCR2_ADDR 0x24 /* serial port2MODEM controls register address */
|
||||
#define REG_LSR2_ADDR 0x25 /* serial port2line status register address */
|
||||
#define REG_MSR2_ADDR 0x26 /* serial port2address of MODEM status register */
|
||||
#define REG_SCR2_ADDR 0x27 /* serial port2the user can define the register address */
|
||||
#define REG_DLL2_ADDR 0x20 /* Baud rate divisor latch low 8-bit byte address */
|
||||
#define REG_DLM2_ADDR 0x21 /* Baud rate divisor latch high 8-bit byte address */
|
||||
|
||||
|
||||
|
||||
/* CH438serial port3 register address */
|
||||
|
||||
#define REG_RBR3_ADDR 0x30 /* serial port3receive buffer register address */
|
||||
#define REG_THR3_ADDR 0x30 /* serial port3send hold register address */
|
||||
#define REG_IER3_ADDR 0x31 /* serial port3interrupt enable register address */
|
||||
#define REG_IIR3_ADDR 0x32 /* serial port3interrupt identifies register address */
|
||||
#define REG_FCR3_ADDR 0x32 /* serial port3FIFO controls register address */
|
||||
#define REG_LCR3_ADDR 0x33 /* serial port3circuit control register address */
|
||||
#define REG_MCR3_ADDR 0x34 /* serial port3MODEM controls register address */
|
||||
#define REG_LSR3_ADDR 0x35 /* serial port3line status register address */
|
||||
#define REG_MSR3_ADDR 0x36 /* serial port3address of MODEM status register */
|
||||
#define REG_SCR3_ADDR 0x37 /* serial port3the user can define the register address */
|
||||
#define REG_DLL3_ADDR 0x30 /* Baud rate divisor latch low 8-bit byte address */
|
||||
#define REG_DLM3_ADDR 0x31 /* Baud rate divisor latch high 8-bit byte address */
|
||||
|
||||
|
||||
/* CH438serial port4 register address */
|
||||
|
||||
#define REG_RBR4_ADDR 0x08 /* serial port4receive buffer register address */
|
||||
#define REG_THR4_ADDR 0x08 /* serial port4send hold register address */
|
||||
#define REG_IER4_ADDR 0x09 /* serial port4interrupt enable register address */
|
||||
#define REG_IIR4_ADDR 0x0A /* serial port4interrupt identifies register address */
|
||||
#define REG_FCR4_ADDR 0x0A /* serial port4FIFO controls register address */
|
||||
#define REG_LCR4_ADDR 0x0B /* serial port4circuit control register address */
|
||||
#define REG_MCR4_ADDR 0x0C /* serial port4MODEM controls register address */
|
||||
#define REG_LSR4_ADDR 0x0D /* serial port4line status register address */
|
||||
#define REG_MSR4_ADDR 0x0E /* serial port4address of MODEM status register */
|
||||
#define REG_SCR4_ADDR 0x0F /* serial port4the user can define the register address */
|
||||
#define REG_DLL4_ADDR 0x08 /* Baud rate divisor latch low 8-bit byte address */
|
||||
#define REG_DLM4_ADDR 0x09 /* Baud rate divisor latch high 8-bit byte address */
|
||||
|
||||
|
||||
|
||||
/* CH438serial port5 register address */
|
||||
|
||||
#define REG_RBR5_ADDR 0x18 /* serial port5receive buffer register address */
|
||||
#define REG_THR5_ADDR 0x18 /* serial port5send hold register address */
|
||||
#define REG_IER5_ADDR 0x19 /* serial port5interrupt enable register address */
|
||||
#define REG_IIR5_ADDR 0x1A /* serial port5interrupt identifies register address */
|
||||
#define REG_FCR5_ADDR 0x1A /* serial port5FIFO controls register address */
|
||||
#define REG_LCR5_ADDR 0x1B /* serial port5circuit control register address */
|
||||
#define REG_MCR5_ADDR 0x1C /* serial port5MODEM controls register address */
|
||||
#define REG_LSR5_ADDR 0x1D /* serial port5line status register address */
|
||||
#define REG_MSR5_ADDR 0x1E /* serial port5address of MODEM status register */
|
||||
#define REG_SCR5_ADDR 0x1F /* serial port5the user can define the register address */
|
||||
#define REG_DLL5_ADDR 0x18 /* Baud rate divisor latch low 8-bit byte address */
|
||||
#define REG_DLM5_ADDR 0x19 /* Baud rate divisor latch high 8-bit byte address */
|
||||
|
||||
|
||||
/* CH438serial port6 register address */
|
||||
|
||||
#define REG_RBR6_ADDR 0x28 /* serial port6receive buffer register address */
|
||||
#define REG_THR6_ADDR 0x28 /* serial port6send hold register address */
|
||||
#define REG_IER6_ADDR 0x29 /* serial port6interrupt enable register address */
|
||||
#define REG_IIR6_ADDR 0x2A /* serial port6interrupt identifies register address */
|
||||
#define REG_FCR6_ADDR 0x2A /* serial port6FIFO controls register address */
|
||||
#define REG_LCR6_ADDR 0x2B /* serial port6circuit control register address */
|
||||
#define REG_MCR6_ADDR 0x2C /* serial port6MODEM controls register address */
|
||||
#define REG_LSR6_ADDR 0x2D /* serial port6line status register address */
|
||||
#define REG_MSR6_ADDR 0x2E /* serial port6address of MODEM status register */
|
||||
#define REG_SCR6_ADDR 0x2F /* serial port6the user can define the register address */
|
||||
#define REG_DLL6_ADDR 0x28 /* Baud rate divisor latch low 8-bit byte address */
|
||||
#define REG_DLM6_ADDR 0x29 /* Baud rate divisor latch high 8-bit byte address */
|
||||
|
||||
|
||||
/* CH438serial port7 register address */
|
||||
|
||||
#define REG_RBR7_ADDR 0x38 /* serial port7receive buffer register address */
|
||||
#define REG_THR7_ADDR 0x38 /* serial port7send hold register address */
|
||||
#define REG_IER7_ADDR 0x39 /* serial port7interrupt enable register address */
|
||||
#define REG_IIR7_ADDR 0x3A /* serial port7interrupt identifies register address */
|
||||
#define REG_FCR7_ADDR 0x3A /* serial port7FIFO controls register address */
|
||||
#define REG_LCR7_ADDR 0x3B /* serial port7circuit control register address */
|
||||
#define REG_MCR7_ADDR 0x3C /* serial port7MODEM controls register address */
|
||||
#define REG_LSR7_ADDR 0x3D /* serial port7line status register address */
|
||||
#define REG_MSR7_ADDR 0x3E /* serial port7address of MODEM status register */
|
||||
#define REG_SCR7_ADDR 0x3F /* serial port7the user can define the register address */
|
||||
#define REG_DLL7_ADDR 0x38 /* Baud rate divisor latch low 8-bit byte address */
|
||||
#define REG_DLM7_ADDR 0x39 /* Baud rate divisor latch high 8-bit byte address */
|
||||
|
||||
|
||||
#define REG_SSR_ADDR 0x4F /* pecial status register address */
|
||||
|
||||
|
||||
/* IER register bit */
|
||||
|
||||
#define BIT_IER_RESET 0x80 /* The bit is 1 soft reset serial port */
|
||||
#define BIT_IER_LOWPOWER 0x40 /* The bit is 1 close serial port internal reference clock */
|
||||
#define BIT_IER_SLP 0x20 /* serial port0 is SLP, 1 close clock vibrator */
|
||||
#define BIT_IER1_CK2X 0x20 /* serial port1 is CK2X, 1 force the external clock signal after 2 times as internal reference clock */
|
||||
#define BIT_IER_IEMODEM 0x08 /* The bit is 1 allows MODEM input status to interrupt */
|
||||
#define BIT_IER_IELINES 0x04 /* The bit is 1 allow receiving line status to be interrupted */
|
||||
#define BIT_IER_IETHRE 0x02 /* The bit is 1 allows the send hold register to break in mid-air */
|
||||
#define BIT_IER_IERECV 0x01 /* The bit is 1 allows receiving data interrupts */
|
||||
|
||||
/* IIR register bit */
|
||||
|
||||
#define BIT_IIR_FIFOENS1 0x80
|
||||
#define BIT_IIR_FIFOENS0 0x40 /* The two is 1 said use FIFO */
|
||||
|
||||
/* Interrupt type: 0001 has no interrupt, 0110 receiving line status is interrupted, 0100 receiving data can be interrupted,
|
||||
1100 received data timeout interrupt, 0010THR register air interrupt, 0000MODEM input change interrupt */
|
||||
#define BIT_IIR_IID3 0x08
|
||||
#define BIT_IIR_IID2 0x04
|
||||
#define BIT_IIR_IID1 0x02
|
||||
#define BIT_IIR_NOINT 0x01
|
||||
|
||||
/* FCR register bit */
|
||||
|
||||
/* Trigger point: 00 corresponds to 1 byte, 01 corresponds to 16 bytes, 10 corresponds to 64 bytes, 11 corresponds to 112 bytes */
|
||||
#define BIT_FCR_RECVTG1 0x80 /* Set the trigger point for FIFO interruption and automatic hardware flow control */
|
||||
#define BIT_FCR_RECVTG0 0x40 /* Set the trigger point for FIFO interruption and automatic hardware flow control */
|
||||
|
||||
#define BIT_FCR_TFIFORST 0x04 /* The bit is 1 empty the data sent in FIFO */
|
||||
#define BIT_FCR_RFIFORST 0x02 /* The bit is 1 empty the data sent in FIFO */
|
||||
#define BIT_FCR_FIFOEN 0x01 /* The bit is 1 use FIFO, 0 disable FIFO */
|
||||
|
||||
/* LCR register bit */
|
||||
|
||||
#define BIT_LCR_DLAB 0x80 /* To access DLL, DLM, 0 to access RBR/THR/IER */
|
||||
#define BIT_LCR_BREAKEN 0x40 /* 1 forces a BREAK line interval*/
|
||||
|
||||
/* Set the check format: when PAREN is 1, 00 odd check, 01 even check, 10 MARK (set 1), 11 blank (SPACE, clear 0) */
|
||||
#define BIT_LCR_PARMODE1 0x20 /* Sets the parity bit format */
|
||||
#define BIT_LCR_PARMODE0 0x10 /* Sets the parity bit format */
|
||||
|
||||
#define BIT_LCR_PAREN 0x08 /* A value of 1 allows you to generate and receive parity bits when sending */
|
||||
#define BIT_LCR_STOPBIT 0x04 /* If is 1, then two stop bits, is 0, a stop bit */
|
||||
|
||||
/* Set word length: 00 for 5 data bits, 01 for 6 data bits, 10 for 7 data bits and 11 for 8 data bits */
|
||||
#define BIT_LCR_WORDSZ1 0x02 /* Set the word length length */
|
||||
#define BIT_LCR_WORDSZ0 0x01
|
||||
|
||||
/* MCR register bit */
|
||||
|
||||
#define BIT_MCR_AFE 0x20 /* For 1 allows automatic flow control of CTS and RTS hardware */
|
||||
#define BIT_MCR_LOOP 0x10 /* Is the test mode of 1 enabling internal loop */
|
||||
#define BIT_MCR_OUT2 0x08 /* 1 Allows an interrupt request for the serial port output */
|
||||
#define BIT_MCR_OUT1 0x04 /* The MODEM control bit defined for the user */
|
||||
#define BIT_MCR_RTS 0x02 /* The bit is 1 RTS pin output effective */
|
||||
#define BIT_MCR_DTR 0x01 /* The bit is 1 DTR pin output effective */
|
||||
|
||||
/* LSR register bit */
|
||||
|
||||
#define BIT_LSR_RFIFOERR 0x80 /* 1 said There is at least one error in receiving FIFO */
|
||||
#define BIT_LSR_TEMT 0x40 /* 1 said THR and TSR are empty */
|
||||
#define BIT_LSR_THRE 0x20 /* 1 said THR is empty*/
|
||||
#define BIT_LSR_BREAKINT 0x10 /* The bit is 1 said the BREAK line interval was detected*/
|
||||
#define BIT_LSR_FRAMEERR 0x08 /* The bit is 1 said error reading data frame */
|
||||
#define BIT_LSR_PARERR 0x04 /* The bit is 1 said parity error */
|
||||
#define BIT_LSR_OVERR 0x02 /* 1 said receive FIFO buffer overflow */
|
||||
#define BIT_LSR_DATARDY 0x01 /* The bit is 1 said receive data received in FIFO */
|
||||
|
||||
/* MSR register bit */
|
||||
|
||||
#define BIT_MSR_DCD 0x80 /* The bit is 1 said DCD pin effective */
|
||||
#define BIT_MSR_RI 0x40 /* The bit is 1 said RI pin effective */
|
||||
#define BIT_MSR_DSR 0x20 /* The bit is 1 said DSR pin effective */
|
||||
#define BIT_MSR_CTS 0x10 /* The bit is 1 said CTS pin effective */
|
||||
#define BIT_MSR_DDCD 0x08 /* The bit is 1 said DCD pin The input state has changed */
|
||||
#define BIT_MSR_TERI 0x04 /* The bit is 1 said RI pin The input state has changed */
|
||||
#define BIT_MSR_DDSR 0x02 /* The bit is 1 said DSR pin The input state has changed */
|
||||
#define BIT_MSR_DCTS 0x01 /* The bit is 1 said CTS pin The input state has changed */
|
||||
|
||||
/* Interrupt status code */
|
||||
|
||||
#define INT_NOINT 0x01 /* There is no interruption */
|
||||
#define INT_THR_EMPTY 0x02 /* THR empty interruption */
|
||||
#define INT_RCV_OVERTIME 0x0C /* Receive timeout interrupt */
|
||||
#define INT_RCV_SUCCESS 0x04 /* Interrupts are available to receive data */
|
||||
#define INT_RCV_LINES 0x06 /* Receiving line status interrupted */
|
||||
#define INT_MODEM_CHANGE 0x00 /* MODEM input changes interrupt */
|
||||
|
||||
#define CH438_IIR_FIFOS_ENABLED 0xC0 /* use FIFO */
|
||||
|
||||
#define Fpclk 1843200 /* Define the internal clock frequency */
|
||||
|
||||
#define CH438_D0_PIN IMXRT_GET_PIN(1, 25)
|
||||
#define CH438_D1_PIN IMXRT_GET_PIN(1, 24)
|
||||
#define CH438_D2_PIN IMXRT_GET_PIN(1, 20)
|
||||
#define CH438_D3_PIN IMXRT_GET_PIN(1, 21)
|
||||
#define CH438_D4_PIN IMXRT_GET_PIN(1, 31)
|
||||
#define CH438_D5_PIN IMXRT_GET_PIN(1, 28)
|
||||
#define CH438_D6_PIN IMXRT_GET_PIN(1, 30)
|
||||
#define CH438_D7_PIN IMXRT_GET_PIN(1, 29)
|
||||
#define CH438_NWR_PIN IMXRT_GET_PIN(3, 4)
|
||||
#define CH438_NRD_PIN IMXRT_GET_PIN(3, 5)
|
||||
#define CH438_ALE_PIN IMXRT_GET_PIN(3, 2)
|
||||
#define CH438_INT_PIN IMXRT_GET_PIN(3, 3)
|
||||
|
||||
int Imxrt1052HwCh438Init(void);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright (c) 2021 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 connect_ethernet.h
|
||||
* @brief Adapted network software protocol stack and hardware operation functions
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021-12-7
|
||||
*/
|
||||
|
||||
#ifndef __CONNECT_ETHERNET_H_
|
||||
#define __CONNECT_ETHERNET_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef sourceClock
|
||||
#define sourceClock CLOCK_GetFreq(kCLOCK_CoreSysClk)
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright (c) 2022 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 connect_gpio.h
|
||||
* @brief define imxrt1052-board gpio function and struct
|
||||
* @version 2.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022-03-15
|
||||
*/
|
||||
|
||||
#ifndef __CONNECT_GPIO_H_
|
||||
#define __CONNECT_GPIO_H_
|
||||
|
||||
#include <device.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define IMXRT_GET_PIN(PORTx, PIN) (32 * (PORTx - 1) + (PIN & 31)) /* PORTx:1,2,3,4,5 */
|
||||
|
||||
int Imxrt1052HwGpioInit(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright (c) 2021 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 connect_i2c.h
|
||||
* @brief define ok1052-c board i2c function and struct
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021-04-25
|
||||
*/
|
||||
|
||||
#ifndef CONNECT_I2C_H
|
||||
#define CONNECT_I2C_H
|
||||
|
||||
#include <device.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct Stm32I2c
|
||||
{
|
||||
LPI2C_Type* base;
|
||||
uint16_t slave_addr;
|
||||
uint32_t sub_addr;
|
||||
}Stm32I2cType;
|
||||
|
||||
#define i2c_print KPrintf
|
||||
|
||||
int Imxrt1052HwI2cInit(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,20 @@
|
|||
/**
|
||||
* @file connect_lcd.h
|
||||
* @brief define xidatong lcd function
|
||||
* @version 1.0
|
||||
* @author AIIT XiUOS Lab
|
||||
* @date 2022-04-25
|
||||
*/
|
||||
|
||||
#ifndef CONNECT_LCD_H
|
||||
#define CONNECT_LCD_H
|
||||
|
||||
#include <device.h>
|
||||
|
||||
#ifdef BSP_USING_TOUCH
|
||||
#include "connect_touch.h"
|
||||
#endif
|
||||
|
||||
|
||||
int Imxrt1052HwLcdInit(void);
|
||||
#endif
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* 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 connect_sdio.h
|
||||
* @brief define imxrt1052-board sdio function and struct
|
||||
* @version 2.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022-03-15
|
||||
*/
|
||||
|
||||
#ifndef CONNECT_SDIO_H
|
||||
#define CONNECT_SDIO_H
|
||||
|
||||
#include <device.h>
|
||||
#include <fsl_sd.h>
|
||||
#include <pin_mux.h>
|
||||
#include <clock_config.h>
|
||||
#include <fsl_gpio.h>
|
||||
#include <fsl_common.h>
|
||||
#include <connect_gpio.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define SD_CARD_STACK_SIZE 2048
|
||||
|
||||
int Imxrt1052HwSdioInit(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,61 @@
|
|||
|
||||
/**
|
||||
* @file connect_touch.c
|
||||
* @brief support xidatong touch function and register to bus framework
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022-04-25
|
||||
*/
|
||||
|
||||
#ifndef CONNECT_TOUCH_H
|
||||
#define CONNECT_TOUCH_H
|
||||
|
||||
#include <device.h>
|
||||
|
||||
/* 表示读数据 */
|
||||
#define I2C_M_RD 0x0001
|
||||
|
||||
struct i2c_msg {
|
||||
uint8_t addr; /*从设备的I2C设备地址 */
|
||||
uint16_t flags; /*控制标志 */
|
||||
uint16_t len; /*读写数据的长度 */
|
||||
uint8_t *buf; /*存储读写数据的指针 */
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int X;
|
||||
int Y;
|
||||
}POINT;
|
||||
|
||||
typedef enum _touch_event
|
||||
{
|
||||
kTouch_Down = 0, /*!< The state changed to touched. */
|
||||
kTouch_Up = 1, /*!< The state changed to not touched. */
|
||||
kTouch_Contact = 2, /*!< There is a continuous touch being detected. */
|
||||
kTouch_Reserved = 3 /*!< No touch information available. */
|
||||
} touch_event_t;
|
||||
|
||||
/*设定使用的电容屏IIC设备地址*/
|
||||
#define GTP_ADDRESS 0xBA
|
||||
|
||||
#define GTP_MAX_HEIGHT 272
|
||||
#define GTP_MAX_WIDTH 480
|
||||
#define GTP_INT_TRIGGER 0
|
||||
#define GTP_MAX_TOUCH 5
|
||||
|
||||
#define GTP_CONFIG_MAX_LENGTH 240
|
||||
#define GTP_ADDR_LENGTH 2
|
||||
|
||||
// Registers define
|
||||
#define GTP_READ_COOR_ADDR 0x814E
|
||||
#define GTP_REG_SLEEP 0x8040
|
||||
#define GTP_REG_SENSOR_ID 0x814A
|
||||
#define GTP_REG_CONFIG_DATA 0x8047
|
||||
#define GTP_REG_VERSION 0x8140
|
||||
|
||||
#define CFG_GROUP_LEN(p_cfg_grp) (sizeof(p_cfg_grp) / sizeof(p_cfg_grp[0]))
|
||||
|
||||
int HwTouchInit(void);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* 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 connect_uart.h
|
||||
* @brief define imxrt1052-board usart function and struct
|
||||
* @version 2.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022-03-15
|
||||
*/
|
||||
|
||||
#ifndef CONNECT_UART_H
|
||||
#define CONNECT_UART_H
|
||||
|
||||
#include <device.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#define KERNEL_CONSOLE_BUS_NAME SERIAL_BUS_NAME_1
|
||||
#define KERNEL_CONSOLE_DRV_NAME SERIAL_DRV_NAME_1
|
||||
#define KERNEL_CONSOLE_DEVICE_NAME SERIAL_1_DEVICE_NAME_0
|
||||
|
||||
int Imxrt1052HwUartInit(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* 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 connect_usb.h
|
||||
* @brief define imxrt1052-board usb function and struct
|
||||
* @version 2.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022-03-15
|
||||
*/
|
||||
|
||||
#ifndef CONNECT_USB_H
|
||||
#define CONNECT_USB_H
|
||||
|
||||
#include <device.h>
|
||||
#include <fsl_common.h>
|
||||
#include <usb_host_config.h>
|
||||
#include <usb_host.h>
|
||||
#include <usb_host_msd.h>
|
||||
#include <host_msd_command.h>
|
||||
#include <usb_phy.h>
|
||||
|
||||
#if defined(FS_VFS)
|
||||
#include <iot-vfs.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define CONTROLLER_ID kUSB_ControllerEhci1
|
||||
#define USB_HOST_INTERRUPT_PRIORITY (3U)
|
||||
|
||||
#define USB_HOST_STACK_SIZE 4096
|
||||
|
||||
#define USB_SINGLE_BLOCK_SIZE 512
|
||||
|
||||
int Imxrt1052HwUsbHostInit(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* 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 connect_wdt.h
|
||||
* @brief define imxrt1052-board watchdog function and struct
|
||||
* @version 2.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022-05-06
|
||||
*/
|
||||
|
||||
#ifndef CONNECT_WDT_H
|
||||
#define CONNECT_WDT_H
|
||||
|
||||
#include <device.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int Imxrt1052HwWdgInit(void);
|
||||
|
||||
int StartWatchdog(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,192 @@
|
|||
/*
|
||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
||||
* 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. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Adam Dunkels <adam@sics.se>
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2013-2016, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2019 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file enet_ethernetif.h
|
||||
* @brief ethernet drivers
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021.11.11
|
||||
*/
|
||||
|
||||
|
||||
#ifndef ENET_ETHERNETIF_H
|
||||
#define ENET_ETHERNETIF_H
|
||||
|
||||
#include "lwip/err.h"
|
||||
#include "lwip/netif.h"
|
||||
#include "fsl_enet.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
#ifndef ENET_RXBD_NUM
|
||||
#define ENET_RXBD_NUM (5)
|
||||
#endif
|
||||
#ifndef ENET_TXBD_NUM
|
||||
#if defined(FSL_FEATURE_SOC_LPC_ENET_COUNT) && (FSL_FEATURE_SOC_LPC_ENET_COUNT > 0)
|
||||
#define ENET_TXBD_NUM (5)
|
||||
#else
|
||||
#define ENET_TXBD_NUM (3)
|
||||
#endif
|
||||
#endif
|
||||
#ifndef ENET_RXBUFF_SIZE
|
||||
#if defined(FSL_FEATURE_SOC_LPC_ENET_COUNT) && (FSL_FEATURE_SOC_LPC_ENET_COUNT > 0)
|
||||
#define ENET_RXBUFF_SIZE (ENET_FRAME_MAX_FRAMELEN + ETH_PAD_SIZE)
|
||||
#else
|
||||
#define ENET_RXBUFF_SIZE ENET_FRAME_MAX_FRAMELEN
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ENET_TXBUFF_SIZE
|
||||
#define ENET_TXBUFF_SIZE (ENET_FRAME_MAX_FRAMELEN)
|
||||
#endif
|
||||
|
||||
#define ENET_TIMEOUT (0xFFFU)
|
||||
|
||||
/* ENET IRQ priority. Used in FreeRTOS. */
|
||||
/* Interrupt priorities. */
|
||||
#ifdef __CA7_REV
|
||||
#ifndef ENET_PRIORITY
|
||||
#define ENET_PRIORITY (21U)
|
||||
#endif
|
||||
#ifndef ENET_1588_PRIORITY
|
||||
#define ENET_1588_PRIORITY (20U)
|
||||
#endif
|
||||
#else
|
||||
#ifndef ENET_PRIORITY
|
||||
#define ENET_PRIORITY (15U)//(6U)
|
||||
#endif
|
||||
#ifndef ENET_1588_PRIORITY
|
||||
#define ENET_1588_PRIORITY (5U)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Defines Ethernet Autonegotiation Timeout during initialization.
|
||||
* Set it to 0 to disable the waiting. */
|
||||
#ifndef ENET_ATONEGOTIATION_TIMEOUT
|
||||
#define ENET_ATONEGOTIATION_TIMEOUT (0xFFFU)
|
||||
#endif
|
||||
|
||||
/* Define those to better describe your network interface. */
|
||||
#define IFNAME0 'e'
|
||||
#define IFNAME1 'n'
|
||||
|
||||
#if defined(FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL) && FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL
|
||||
#if defined(FSL_FEATURE_L2CACHE_LINESIZE_BYTE) \
|
||||
&& ((!defined(FSL_SDK_DISBLE_L2CACHE_PRESENT)) || (FSL_SDK_DISBLE_L2CACHE_PRESENT == 0))
|
||||
#if defined(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE)
|
||||
#define FSL_CACHE_LINESIZE_MAX MAX(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE, FSL_FEATURE_L2CACHE_LINESIZE_BYTE)
|
||||
#define FSL_ENET_BUFF_ALIGNMENT MAX(ENET_BUFF_ALIGNMENT, FSL_CACHE_LINESIZE_MAX)
|
||||
#else
|
||||
#define FSL_ENET_BUFF_ALIGNMENT MAX(ENET_BUFF_ALIGNMENT, FSL_FEATURE_L2CACHE_LINESIZE_BYTE)
|
||||
#endif
|
||||
#elif defined(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE)
|
||||
#define FSL_ENET_BUFF_ALIGNMENT MAX(ENET_BUFF_ALIGNMENT, FSL_FEATURE_L1DCACHE_LINESIZE_BYTE)
|
||||
#else
|
||||
#define FSL_ENET_BUFF_ALIGNMENT ENET_BUFF_ALIGNMENT
|
||||
#endif
|
||||
#else
|
||||
#define FSL_ENET_BUFF_ALIGNMENT ENET_BUFF_ALIGNMENT
|
||||
#endif
|
||||
|
||||
#define ENET_RING_NUM 1U
|
||||
|
||||
typedef uint8_t rx_buffer_t[SDK_SIZEALIGN(ENET_RXBUFF_SIZE, FSL_ENET_BUFF_ALIGNMENT)];
|
||||
typedef uint8_t tx_buffer_t[SDK_SIZEALIGN(ENET_TXBUFF_SIZE, FSL_ENET_BUFF_ALIGNMENT)];
|
||||
|
||||
#if (defined(FSL_FEATURE_SOC_LPC_ENET_COUNT) && (FSL_FEATURE_SOC_LPC_ENET_COUNT > 0))
|
||||
typedef struct mem_range
|
||||
{
|
||||
uint32_t start;
|
||||
uint32_t end;
|
||||
} mem_range_t;
|
||||
#endif /* FSL_FEATURE_SOC_LPC_ENET_COUNT */
|
||||
|
||||
/**
|
||||
* Helper struct to hold data for configuration of ethernet interface.
|
||||
*/
|
||||
typedef struct ethernetif_config
|
||||
{
|
||||
uint32_t phyAddress;
|
||||
clock_name_t clockName;
|
||||
uint8_t macAddress[NETIF_MAX_HWADDR_LEN];
|
||||
#if (defined(FSL_FEATURE_SOC_LPC_ENET_COUNT) && (FSL_FEATURE_SOC_LPC_ENET_COUNT > 0))
|
||||
const mem_range_t *non_dma_memory;
|
||||
#endif /* FSL_FEATURE_SOC_LPC_ENET_COUNT */
|
||||
} ethernetif_config_t;
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/**
|
||||
* This function should be passed as a parameter to netif_add()
|
||||
* if you initialize the first ENET interface.
|
||||
*/
|
||||
err_t ethernetif0_init(struct netif *netif);
|
||||
|
||||
#if (defined(FSL_FEATURE_SOC_ENET_COUNT) && (FSL_FEATURE_SOC_ENET_COUNT > 1)) \
|
||||
|| (defined(FSL_FEATURE_SOC_LPC_ENET_COUNT) && (FSL_FEATURE_SOC_LPC_ENET_COUNT > 1))
|
||||
/**
|
||||
* This function should be passed as a parameter to netif_add()
|
||||
* if you initialize the second ENET interface.
|
||||
*/
|
||||
err_t ethernetif1_init(struct netif *netif);
|
||||
#endif /* FSL_FEATURE_SOC_*_ENET_COUNT */
|
||||
|
||||
/**
|
||||
* This function should be called when a packet is ready to be read
|
||||
* from the interface.
|
||||
* It is used by bare-metal applications.
|
||||
*
|
||||
* @param netif the lwip network interface structure for this ethernetif
|
||||
*/
|
||||
void ethernetif_input( struct netif *netif);
|
||||
|
||||
void ETH_BSP_Config(void);
|
||||
|
||||
int32 lwip_obtain_semaphore(struct netif *netif);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* ENET_ETHERNETIF_H */
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* Copyright 2019 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file enet_ethernetif_priv.h
|
||||
* @brief ethernet drivers
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021.11.11
|
||||
*/
|
||||
|
||||
|
||||
#ifndef ENET_ETHERNETIF_PRIV_H
|
||||
#define ENET_ETHERNETIF_PRIV_H
|
||||
|
||||
#include "lwip/err.h"
|
||||
|
||||
struct ethernetif;
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
err_t ethernetif_init(struct netif *netif, struct ethernetif *ethernetif,
|
||||
const uint8_t enetIdx,
|
||||
const ethernetif_config_t *ethernetifConfig);
|
||||
|
||||
void ethernetif_enet_init(struct netif *netif, struct ethernetif *ethernetif,
|
||||
const ethernetif_config_t *ethernetifConfig);
|
||||
|
||||
void ethernetif_phy_init(struct ethernetif *ethernetif,
|
||||
const ethernetif_config_t *ethernetifConfig,
|
||||
enet_config_t *config);
|
||||
|
||||
ENET_Type **ethernetif_enet_ptr(struct ethernetif *ethernetif);
|
||||
|
||||
#if LWIP_IPV4 && LWIP_IGMP
|
||||
err_t ethernetif_igmp_mac_filter(struct netif *netif, const ip4_addr_t *group,
|
||||
enum netif_mac_filter_action action);
|
||||
#endif
|
||||
|
||||
#if LWIP_IPV6 && LWIP_IPV6_MLD
|
||||
err_t ethernetif_mld_mac_filter(struct netif *netif, const ip6_addr_t *group,
|
||||
enum netif_mac_filter_action action);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Should allocate a pbuf and transfer the bytes of the incoming
|
||||
* packet from the interface into the pbuf.
|
||||
*
|
||||
* @param netif the lwip network interface structure for this ethernetif
|
||||
* @return a pbuf filled with the received packet (including MAC header)
|
||||
* NULL on memory error
|
||||
*/
|
||||
struct pbuf *ethernetif_linkinput(struct netif *netif);
|
||||
|
||||
/**
|
||||
* This function should do the actual transmission of the packet. The packet is
|
||||
* contained in the pbuf that is passed to the function. This pbuf
|
||||
* might be chained.
|
||||
*
|
||||
* @param netif the lwip network interface structure for this ethernetif
|
||||
* @param p the MAC packet to send (e.g. IP packet including MAC addresses and type)
|
||||
* @return ERR_OK if the packet could be sent
|
||||
* an err_t value if the packet couldn't be sent
|
||||
*
|
||||
* @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to
|
||||
* strange results. You might consider waiting for space in the DMA queue
|
||||
* to become available since the stack doesn't retry to send a packet
|
||||
* dropped because of memory failure (except for the TCP timers).
|
||||
*/
|
||||
err_t ethernetif_linkoutput(struct netif *netif, struct pbuf *p);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* ENET_ETHERNETIF_PRIV_H */
|
|
@ -0,0 +1,476 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2017 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file fsl_cache.h
|
||||
* @brief cache drivers
|
||||
* @version 2.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022-03-15
|
||||
*/
|
||||
|
||||
#ifndef _FSL_CACHE_H_
|
||||
#define _FSL_CACHE_H_
|
||||
|
||||
#include "fsl_common.h"
|
||||
|
||||
/*!
|
||||
* @addtogroup cache
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*! @name Driver version */
|
||||
/*@{*/
|
||||
/*! @brief cache driver version 2.0.1. */
|
||||
#define FSL_CACHE_DRIVER_VERSION (MAKE_VERSION(2, 0, 1))
|
||||
/*@}*/
|
||||
|
||||
#if defined(FSL_FEATURE_SOC_L2CACHEC_COUNT) && FSL_FEATURE_SOC_L2CACHEC_COUNT
|
||||
#ifndef FSL_SDK_DISBLE_L2CACHE_PRESENT
|
||||
#define FSL_SDK_DISBLE_L2CACHE_PRESENT 0
|
||||
#endif
|
||||
#endif /* FSL_FEATURE_SOC_L2CACHEC_COUNT */
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
#if defined(FSL_FEATURE_SOC_L2CACHEC_COUNT) && FSL_FEATURE_SOC_L2CACHEC_COUNT
|
||||
|
||||
/*! @brief Number of level 2 cache controller ways. */
|
||||
typedef enum _l2cache_way_num
|
||||
{
|
||||
kL2CACHE_8ways = 0, /*!< 8 ways. */
|
||||
#if defined(FSL_FEATURE_L2CACHE_SUPPORT_16_WAY_ASSOCIATIVITY) && FSL_FEATURE_L2CACHE_SUPPORT_16_WAY_ASSOCIATIVITY
|
||||
kL2CACHE_16ways /*!< 16 ways. */
|
||||
#endif /* FSL_FEATURE_L2CACHE_SUPPORT_16_WAY_ASSOCIATIVITY */
|
||||
} l2cache_way_num_t;
|
||||
|
||||
/*! @brief Level 2 cache controller way size. */
|
||||
typedef enum _l2cache_way_size
|
||||
{
|
||||
kL2CACHE_16KBSize = 1, /*!< 16 KB way size. */
|
||||
kL2CACHE_32KBSize = 2, /*!< 32 KB way size. */
|
||||
kL2CACHE_64KBSize = 3, /*!< 64 KB way size. */
|
||||
kL2CACHE_128KBSize = 4, /*!< 128 KB way size. */
|
||||
kL2CACHE_256KBSize = 5, /*!< 256 KB way size. */
|
||||
kL2CACHE_512KBSize = 6 /*!< 512 KB way size. */
|
||||
} l2cache_way_size;
|
||||
|
||||
/*! @brief Level 2 cache controller replacement policy. */
|
||||
typedef enum _l2cache_replacement
|
||||
{
|
||||
kL2CACHE_Pseudorandom = 0U, /*!< Peseudo-random replacement policy using an lfsr. */
|
||||
kL2CACHE_Roundrobin /*!< Round-robin replacemnt policy. */
|
||||
} l2cache_replacement_t;
|
||||
|
||||
/*! @brief Level 2 cache controller force write allocate options. */
|
||||
typedef enum _l2cache_writealloc
|
||||
{
|
||||
kL2CACHE_UseAwcache = 0, /*!< Use AWCAHE attribute for the write allocate. */
|
||||
kL2CACHE_NoWriteallocate, /*!< Force no write allocate. */
|
||||
kL2CACHE_forceWriteallocate /*!< Force write allocate when write misses. */
|
||||
} l2cache_writealloc_t;
|
||||
|
||||
/*! @brief Level 2 cache controller tag/data ram latency. */
|
||||
typedef enum _l2cache_latency
|
||||
{
|
||||
kL2CACHE_1CycleLate = 0, /*!< 1 cycle of latency. */
|
||||
kL2CACHE_2CycleLate, /*!< 2 cycle of latency. */
|
||||
kL2CACHE_3CycleLate, /*!< 3 cycle of latency. */
|
||||
kL2CACHE_4CycleLate, /*!< 4 cycle of latency. */
|
||||
kL2CACHE_5CycleLate, /*!< 5 cycle of latency. */
|
||||
kL2CACHE_6CycleLate, /*!< 6 cycle of latency. */
|
||||
kL2CACHE_7CycleLate, /*!< 7 cycle of latency. */
|
||||
kL2CACHE_8CycleLate /*!< 8 cycle of latency. */
|
||||
} l2cache_latency_t;
|
||||
|
||||
/*! @brief Level 2 cache controller tag/data ram latency configure structure. */
|
||||
typedef struct _l2cache_latency_config
|
||||
{
|
||||
l2cache_latency_t tagWriteLate; /*!< Tag write latency. */
|
||||
l2cache_latency_t tagReadLate; /*!< Tag Read latency. */
|
||||
l2cache_latency_t tagSetupLate; /*!< Tag setup latency. */
|
||||
l2cache_latency_t dataWriteLate; /*!< Data write latency. */
|
||||
l2cache_latency_t dataReadLate; /*!< Data Read latency. */
|
||||
l2cache_latency_t dataSetupLate; /*!< Data setup latency. */
|
||||
} L2cache_latency_config_t;
|
||||
|
||||
/*! @brief Level 2 cache controller configure structure. */
|
||||
typedef struct _l2cache_config
|
||||
{
|
||||
/* ------------------------ l2 cachec basic settings ---------------------------- */
|
||||
l2cache_way_num_t wayNum; /*!< The number of ways. */
|
||||
l2cache_way_size waySize; /*!< The way size = Cache Ram size / wayNum. */
|
||||
l2cache_replacement_t repacePolicy; /*!< Replacemnet policy. */
|
||||
/* ------------------------ tag/data ram latency settings ----------------------- */
|
||||
L2cache_latency_config_t *lateConfig; /*!< Tag/data latency configure. Set NUll if not required. */
|
||||
/* ------------------------ Prefetch enable settings ---------------------------- */
|
||||
bool istrPrefetchEnable; /*!< Instruction prefetch enable. */
|
||||
bool dataPrefetchEnable; /*!< Data prefetch enable. */
|
||||
/* ------------------------ Non-secure access settings -------------------------- */
|
||||
bool nsLockdownEnable; /*!< None-secure lockdown enable. */
|
||||
/* ------------------------ other settings -------------------------------------- */
|
||||
l2cache_writealloc_t writeAlloc; /*!< Write allcoate force option. */
|
||||
} l2cache_config_t;
|
||||
#endif /* FSL_FEATURE_SOC_L2CACHEC_COUNT */
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @name Control for cortex-m7 L1 cache
|
||||
*@{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Enables cortex-m7 L1 instruction cache.
|
||||
*
|
||||
*/
|
||||
static inline void L1CACHE_EnableICache(void)
|
||||
{
|
||||
SCB_EnableICache();
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Disables cortex-m7 L1 instruction cache.
|
||||
*
|
||||
*/
|
||||
static inline void L1CACHE_DisableICache(void)
|
||||
{
|
||||
SCB_DisableICache();
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Invalidate cortex-m7 L1 instruction cache.
|
||||
*
|
||||
*/
|
||||
static inline void L1CACHE_InvalidateICache(void)
|
||||
{
|
||||
SCB_InvalidateICache();
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Invalidate cortex-m7 L1 instruction cache by range.
|
||||
*
|
||||
* @param address The start address of the memory to be invalidated.
|
||||
* @param size_byte The memory size.
|
||||
* @note The start address and size_byte should be 32-byte(FSL_FEATURE_L1ICACHE_LINESIZE_BYTE) aligned.
|
||||
* The startAddr here will be forced to align to L1 I-cache line size if
|
||||
* startAddr is not aligned. For the size_byte, application should make sure the
|
||||
* alignment or make sure the right operation order if the size_byte is not aligned.
|
||||
*/
|
||||
void L1CACHE_InvalidateICacheByRange(uint32_t address, uint32_t size_byte);
|
||||
|
||||
/*!
|
||||
* @brief Enables cortex-m7 L1 data cache.
|
||||
*
|
||||
*/
|
||||
static inline void L1CACHE_EnableDCache(void)
|
||||
{
|
||||
SCB_EnableDCache();
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Disables cortex-m7 L1 data cache.
|
||||
*
|
||||
*/
|
||||
static inline void L1CACHE_DisableDCache(void)
|
||||
{
|
||||
SCB_DisableDCache();
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Invalidates cortex-m7 L1 data cache.
|
||||
*
|
||||
*/
|
||||
static inline void L1CACHE_InvalidateDCache(void)
|
||||
{
|
||||
SCB_InvalidateDCache();
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Cleans cortex-m7 L1 data cache.
|
||||
*
|
||||
*/
|
||||
static inline void L1CACHE_CleanDCache(void)
|
||||
{
|
||||
SCB_CleanDCache();
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Cleans and Invalidates cortex-m7 L1 data cache.
|
||||
*
|
||||
*/
|
||||
static inline void L1CACHE_CleanInvalidateDCache(void)
|
||||
{
|
||||
SCB_CleanInvalidateDCache();
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Invalidates cortex-m7 L1 data cache by range.
|
||||
*
|
||||
* @param address The start address of the memory to be invalidated.
|
||||
* @param size_byte The memory size.
|
||||
* @note The start address and size_byte should be 32-byte(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE) aligned.
|
||||
* The startAddr here will be forced to align to L1 D-cache line size if
|
||||
* startAddr is not aligned. For the size_byte, application should make sure the
|
||||
* alignment or make sure the right operation order if the size_byte is not aligned.
|
||||
*/
|
||||
static inline void L1CACHE_InvalidateDCacheByRange(uint32_t address, uint32_t size_byte)
|
||||
{
|
||||
uint32_t startAddr = address & (uint32_t) ~(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE - 1);
|
||||
uint32_t size = size_byte + address - startAddr;
|
||||
|
||||
SCB_InvalidateDCache_by_Addr((uint32_t *)startAddr, size);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Cleans cortex-m7 L1 data cache by range.
|
||||
*
|
||||
* @param address The start address of the memory to be cleaned.
|
||||
* @param size_byte The memory size.
|
||||
* @note The start address and size_byte should be 32-byte(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE) aligned.
|
||||
* The startAddr here will be forced to align to L1 D-cache line size if
|
||||
* startAddr is not aligned. For the size_byte, application should make sure the
|
||||
* alignment or make sure the right operation order if the size_byte is not aligned.
|
||||
*/
|
||||
static inline void L1CACHE_CleanDCacheByRange(uint32_t address, uint32_t size_byte)
|
||||
{
|
||||
uint32_t startAddr = address & (uint32_t) ~(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE - 1);
|
||||
uint32_t size = size_byte + address - startAddr;
|
||||
|
||||
SCB_CleanDCache_by_Addr((uint32_t *)startAddr, size);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Cleans and Invalidates cortex-m7 L1 data cache by range.
|
||||
*
|
||||
* @param address The start address of the memory to be clean and invalidated.
|
||||
* @param size_byte The memory size.
|
||||
* @note The start address and size_byte should be 32-byte(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE) aligned.
|
||||
* The startAddr here will be forced to align to L1 D-cache line size if
|
||||
* startAddr is not aligned. For the size_byte, application should make sure the
|
||||
* alignment or make sure the right operation order if the size_byte is not aligned.
|
||||
*/
|
||||
static inline void L1CACHE_CleanInvalidateDCacheByRange(uint32_t address, uint32_t size_byte)
|
||||
{
|
||||
uint32_t startAddr = address & (uint32_t) ~(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE - 1);
|
||||
uint32_t size = size_byte + address - startAddr;
|
||||
|
||||
SCB_CleanInvalidateDCache_by_Addr((uint32_t *)startAddr, size);
|
||||
}
|
||||
/*@}*/
|
||||
|
||||
#if defined(FSL_FEATURE_SOC_L2CACHEC_COUNT) && FSL_FEATURE_SOC_L2CACHEC_COUNT
|
||||
/*!
|
||||
* @name Control for L2 pl310 cache
|
||||
*@{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Initializes the level 2 cache controller module.
|
||||
*
|
||||
* @param config Pointer to configuration structure. See "l2cache_config_t".
|
||||
*/
|
||||
void L2CACHE_Init(l2cache_config_t *config);
|
||||
|
||||
/*!
|
||||
* @brief Gets an available default settings for the cache controller.
|
||||
*
|
||||
* This function initializes the cache controller configuration structure with default settings.
|
||||
* The default values are:
|
||||
* @code
|
||||
* config->waysNum = kL2CACHE_8ways;
|
||||
* config->waySize = kL2CACHE_32KbSize;
|
||||
* config->repacePolicy = kL2CACHE_Roundrobin;
|
||||
* config->lateConfig = NULL;
|
||||
* config->istrPrefetchEnable = false;
|
||||
* config->dataPrefetchEnable = false;
|
||||
* config->nsLockdownEnable = false;
|
||||
* config->writeAlloc = kL2CACHE_UseAwcache;
|
||||
* @endcode
|
||||
* @param config Pointer to the configuration structure.
|
||||
*/
|
||||
void L2CACHE_GetDefaultConfig(l2cache_config_t *config);
|
||||
|
||||
/*!
|
||||
* @brief Enables the level 2 cache controller.
|
||||
* This function enables the cache controller. Must be written using a secure access.
|
||||
* If write with a Non-secure access will cause a DECERR response.
|
||||
*
|
||||
*/
|
||||
void L2CACHE_Enable(void);
|
||||
|
||||
/*!
|
||||
* @brief Disables the level 2 cache controller.
|
||||
* This function disables the cache controller. Must be written using a secure access.
|
||||
* If write with a Non-secure access will cause a DECERR response.
|
||||
*
|
||||
*/
|
||||
void L2CACHE_Disable(void);
|
||||
|
||||
/*!
|
||||
* @brief Invalidates the Level 2 cache.
|
||||
* This function invalidates all entries in cache.
|
||||
*
|
||||
*/
|
||||
void L2CACHE_Invalidate(void);
|
||||
|
||||
/*!
|
||||
* @brief Invalidates the Level 2 cache lines in the range of two physical addresses.
|
||||
* This function invalidates all cache lines between two physical addresses.
|
||||
*
|
||||
* @param address The start address of the memory to be invalidated.
|
||||
* @param size_byte The memory size.
|
||||
* @note The start address and size_byte should be 32-byte(FSL_FEATURE_L2CACHE_LINESIZE_BYTE) aligned.
|
||||
* The startAddr here will be forced to align to L2 line size if startAddr
|
||||
* is not aligned. For the size_byte, application should make sure the
|
||||
* alignment or make sure the right operation order if the size_byte is not aligned.
|
||||
*/
|
||||
void L2CACHE_InvalidateByRange(uint32_t address, uint32_t size_byte);
|
||||
|
||||
/*!
|
||||
* @brief Cleans the level 2 cache controller.
|
||||
* This function cleans all entries in the level 2 cache controller.
|
||||
*
|
||||
*/
|
||||
void L2CACHE_Clean(void);
|
||||
|
||||
/*!
|
||||
* @brief Cleans the Level 2 cache lines in the range of two physical addresses.
|
||||
* This function cleans all cache lines between two physical addresses.
|
||||
*
|
||||
* @param address The start address of the memory to be cleaned.
|
||||
* @param size_byte The memory size.
|
||||
* @note The start address and size_byte should be 32-byte(FSL_FEATURE_L2CACHE_LINESIZE_BYTE) aligned.
|
||||
* The startAddr here will be forced to align to L2 line size if startAddr
|
||||
* is not aligned. For the size_byte, application should make sure the
|
||||
* alignment or make sure the right operation order if the size_byte is not aligned.
|
||||
*/
|
||||
void L2CACHE_CleanByRange(uint32_t address, uint32_t size_byte);
|
||||
|
||||
/*!
|
||||
* @brief Cleans and invalidates the level 2 cache controller.
|
||||
* This function cleans and invalidates all entries in the level 2 cache controller.
|
||||
*
|
||||
*/
|
||||
void L2CACHE_CleanInvalidate(void);
|
||||
|
||||
/*!
|
||||
* @brief Cleans and invalidates the Level 2 cache lines in the range of two physical addresses.
|
||||
* This function cleans and invalidates all cache lines between two physical addresses.
|
||||
*
|
||||
* @param address The start address of the memory to be cleaned and invalidated.
|
||||
* @param size_byte The memory size.
|
||||
* @note The start address and size_byte should be 32-byte(FSL_FEATURE_L2CACHE_LINESIZE_BYTE) aligned.
|
||||
* The startAddr here will be forced to align to L2 line size if startAddr
|
||||
* is not aligned. For the size_byte, application should make sure the
|
||||
* alignment or make sure the right operation order if the size_byte is not aligned.
|
||||
*/
|
||||
void L2CACHE_CleanInvalidateByRange(uint32_t address, uint32_t size_byte);
|
||||
|
||||
/*!
|
||||
* @brief Enables or disables to lock down the data and instruction by way.
|
||||
* This function locks down the cached instruction/data by way and prevent the adresses from
|
||||
* being allocated and prevent dara from being evicted out of the level 2 cache.
|
||||
* But the normal cache maintenance operations that invalidate, clean or clean
|
||||
* and validate cache contents affect the locked-down cache lines as normal.
|
||||
*
|
||||
* @param masterId The master id, range from 0 ~ 7.
|
||||
* @param mask The ways to be enabled or disabled to lockdown.
|
||||
* each bit in value is related to each way of the cache. for example:
|
||||
* value: bit 0 ------ way 0.
|
||||
* value: bit 1 ------ way 1.
|
||||
* --------------------------
|
||||
* value: bit 15 ------ way 15.
|
||||
* Note: please make sure the value setting is align with your supported ways.
|
||||
* @param enable True enable the lockdown, false to disable the lockdown.
|
||||
*/
|
||||
void L2CACHE_LockdownByWayEnable(uint32_t masterId, uint32_t mask, bool enable);
|
||||
|
||||
/*@}*/
|
||||
#endif /* FSL_FEATURE_SOC_L2CACHEC_COUNT */
|
||||
|
||||
/*!
|
||||
* @name Unified Cache Control for all caches (cortex-m7 L1 cache + l2 pl310)
|
||||
* Mainly used for many drivers for easy cache operation.
|
||||
*@{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Invalidates all instruction caches by range.
|
||||
*
|
||||
* Both cortex-m7 L1 cache line and L2 PL310 cache line length is 32-byte.
|
||||
*
|
||||
* @param address The physical address.
|
||||
* @param size_byte size of the memory to be invalidated.
|
||||
* @note address and size should be aligned to cache line size
|
||||
* 32-Byte due to the cache operation unit is one cache line. The startAddr here will be forced
|
||||
* to align to the cache line size if startAddr is not aligned. For the size_byte, application should
|
||||
* make sure the alignment or make sure the right operation order if the size_byte is not aligned.
|
||||
*/
|
||||
void ICACHE_InvalidateByRange(uint32_t address, uint32_t size_byte);
|
||||
|
||||
/*!
|
||||
* @brief Invalidates all data caches by range.
|
||||
*
|
||||
* Both cortex-m7 L1 cache line and L2 PL310 cache line length is 32-byte.
|
||||
*
|
||||
* @param address The physical address.
|
||||
* @param size_byte size of the memory to be invalidated.
|
||||
* @note address and size should be aligned to cache line size
|
||||
* 32-Byte due to the cache operation unit is one cache line. The startAddr here will be forced
|
||||
* to align to the cache line size if startAddr is not aligned. For the size_byte, application should
|
||||
* make sure the alignment or make sure the right operation order if the size_byte is not aligned.
|
||||
*/
|
||||
void DCACHE_InvalidateByRange(uint32_t address, uint32_t size_byte);
|
||||
|
||||
/*!
|
||||
* @brief Cleans all data caches by range.
|
||||
*
|
||||
* Both cortex-m7 L1 cache line and L2 PL310 cache line length is 32-byte.
|
||||
*
|
||||
* @param address The physical address.
|
||||
* @param size_byte size of the memory to be cleaned.
|
||||
* @note address and size should be aligned to cache line size
|
||||
* 32-Byte due to the cache operation unit is one cache line. The startAddr here will be forced
|
||||
* to align to the cache line size if startAddr is not aligned. For the size_byte, application should
|
||||
* make sure the alignment or make sure the right operation order if the size_byte is not aligned.
|
||||
*/
|
||||
void DCACHE_CleanByRange(uint32_t address, uint32_t size_byte);
|
||||
|
||||
/*!
|
||||
* @brief Cleans and Invalidates all data caches by range.
|
||||
*
|
||||
* Both cortex-m7 L1 cache line and L2 PL310 cache line length is 32-byte.
|
||||
*
|
||||
* @param address The physical address.
|
||||
* @param size_byte size of the memory to be cleaned and invalidated.
|
||||
* @note address and size should be aligned to cache line size
|
||||
* 32-Byte due to the cache operation unit is one cache line. The startAddr here will be forced
|
||||
* to align to the cache line size if startAddr is not aligned. For the size_byte, application should
|
||||
* make sure the alignment or make sure the right operation order if the size_byte is not aligned.
|
||||
*/
|
||||
void DCACHE_CleanInvalidateByRange(uint32_t address, uint32_t size_byte);
|
||||
|
||||
/*@}*/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
/*! @}*/
|
||||
|
||||
#endif /* _FSL_CACHE_H_*/
|
|
@ -0,0 +1,593 @@
|
|||
/*
|
||||
* Copyright (c) 2015-2016, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2018 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file fsl_common.h
|
||||
* @brief common drivers header
|
||||
* @version 2.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022-03-15
|
||||
*/
|
||||
|
||||
#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__)
|
||||
#include <stddef.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 2.0.1. */
|
||||
#define FSL_COMMON_DRIVER_VERSION (MAKE_VERSION(2, 0, 1))
|
||||
/*@}*/
|
||||
|
||||
/* 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_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_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. */
|
||||
};
|
||||
|
||||
/*! @brief Generic status return codes. */
|
||||
enum _generic_status
|
||||
{
|
||||
kStatus_Success = MAKE_STATUS(kStatusGroup_Generic, 0),
|
||||
kStatus_Fail = MAKE_STATUS(kStatusGroup_Generic, 1),
|
||||
kStatus_ReadOnly = MAKE_STATUS(kStatusGroup_Generic, 2),
|
||||
kStatus_OutOfRange = MAKE_STATUS(kStatusGroup_Generic, 3),
|
||||
kStatus_InvalidArgument = MAKE_STATUS(kStatusGroup_Generic, 4),
|
||||
kStatus_Timeout = MAKE_STATUS(kStatusGroup_Generic, 5),
|
||||
kStatus_NoTransferInProgress = MAKE_STATUS(kStatusGroup_Generic, 6),
|
||||
};
|
||||
|
||||
/*! @brief Type used for all status and error return values. */
|
||||
typedef int32_t status_t;
|
||||
|
||||
/*
|
||||
* 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
|
||||
|
||||
/*
|
||||
* 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 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)-1)) & (unsigned int)(~(unsigned int)((alignbytes)-1)))
|
||||
/* @} */
|
||||
|
||||
/*! @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(var) __attribute__((section("NonCacheable"), zero_init)) var
|
||||
#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) \
|
||||
__attribute__((section("NonCacheable"), zero_init)) __attribute__((aligned(alignbytes))) var
|
||||
#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
|
||||
#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(__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"))) func
|
||||
#define AT_QUICKACCESS_SECTION_DATA(func) __attribute__((section("DataQuickAccess"))) func
|
||||
#elif(defined(__GNUC__))
|
||||
#define AT_QUICKACCESS_SECTION_CODE(func) __attribute__((section("CodeQuickAccess"))) 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__) */
|
||||
/* @} */
|
||||
/*******************************************************************************
|
||||
* 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)
|
||||
{
|
||||
if (NotAvail_IRQn == interrupt)
|
||||
{
|
||||
return kStatus_Fail;
|
||||
}
|
||||
|
||||
#if defined(FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS) && (FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS > 0)
|
||||
if (interrupt >= FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS)
|
||||
{
|
||||
return kStatus_Fail;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(__GIC_PRIO_BITS)
|
||||
GIC_EnableIRQ(interrupt);
|
||||
#else
|
||||
NVIC_EnableIRQ(interrupt);
|
||||
#endif
|
||||
return kStatus_Success;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @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)
|
||||
{
|
||||
if (NotAvail_IRQn == interrupt)
|
||||
{
|
||||
return kStatus_Fail;
|
||||
}
|
||||
|
||||
#if defined(FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS) && (FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS > 0)
|
||||
if (interrupt >= FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS)
|
||||
{
|
||||
return kStatus_Fail;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(__GIC_PRIO_BITS)
|
||||
GIC_DisableIRQ(interrupt);
|
||||
#else
|
||||
NVIC_DisableIRQ(interrupt);
|
||||
#endif
|
||||
return kStatus_Success;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @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(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
|
||||
}
|
||||
|
||||
/*!
|
||||
* @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(CPSR_I_Msk)
|
||||
__set_CPSR((__get_CPSR() & ~CPSR_I_Msk) | primask);
|
||||
#else
|
||||
__set_PRIMASK(primask);
|
||||
#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))
|
||||
/*!
|
||||
* @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_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);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
/*! @} */
|
||||
|
||||
#endif /* _FSL_COMMON_H_ */
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright 2014-2016 Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2018 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file fsl_device_registers.h
|
||||
* @brief device register function
|
||||
* @version 2.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022-03-15
|
||||
*/
|
||||
|
||||
#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_MIMXRT1052CVJ5B) || defined(CPU_MIMXRT1052CVL5B) || defined(CPU_MIMXRT1052DVJ6B) || \
|
||||
defined(CPU_MIMXRT1052DVL6B))
|
||||
|
||||
#define MIMXRT1052_SERIES
|
||||
|
||||
/* CMSIS-style register definitions */
|
||||
#include "MIMXRT1052.h"
|
||||
/* CPU specific feature definitions */
|
||||
#include "MIMXRT1052_features.h"
|
||||
|
||||
#else
|
||||
#error "No valid CPU defined!"
|
||||
#endif
|
||||
|
||||
#endif /* __FSL_DEVICE_REGISTERS_H__ */
|
||||
|
||||
/*******************************************************************************
|
||||
* EOF
|
||||
******************************************************************************/
|
|
@ -0,0 +1,750 @@
|
|||
/*
|
||||
* Copyright 2017 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _FSL_ELCDIF_H_
|
||||
#define _FSL_ELCDIF_H_
|
||||
|
||||
#include "fsl_common.h"
|
||||
|
||||
/*!
|
||||
* @addtogroup elcdif
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*! @name Driver version */
|
||||
/*@{*/
|
||||
/*! @brief eLCDIF driver version */
|
||||
#define FSL_ELCDIF_DRIVER_VERSION (MAKE_VERSION(2, 0, 1)) /*!< Version 2.0.1. */
|
||||
/*@}*/
|
||||
|
||||
/* All IRQ flags in CTRL1 register. */
|
||||
#define ELCDIF_CTRL1_IRQ_MASK \
|
||||
(LCDIF_CTRL1_BM_ERROR_IRQ_MASK | LCDIF_CTRL1_OVERFLOW_IRQ_MASK | LCDIF_CTRL1_UNDERFLOW_IRQ_MASK | \
|
||||
LCDIF_CTRL1_CUR_FRAME_DONE_IRQ_MASK | LCDIF_CTRL1_VSYNC_EDGE_IRQ_MASK)
|
||||
|
||||
/* All IRQ enable control bits in CTRL1 register. */
|
||||
#define ELCDIF_CTRL1_IRQ_EN_MASK \
|
||||
(LCDIF_CTRL1_BM_ERROR_IRQ_EN_MASK | LCDIF_CTRL1_OVERFLOW_IRQ_EN_MASK | LCDIF_CTRL1_UNDERFLOW_IRQ_EN_MASK | \
|
||||
LCDIF_CTRL1_CUR_FRAME_DONE_IRQ_EN_MASK | LCDIF_CTRL1_VSYNC_EDGE_IRQ_EN_MASK)
|
||||
|
||||
/* All IRQ flags in AS_CTRL register. */
|
||||
#if defined(LCDIF_AS_CTRL_CSI_SYNC_ON_IRQ_MASK)
|
||||
#define ELCDIF_AS_CTRL_IRQ_MASK (LCDIF_AS_CTRL_CSI_SYNC_ON_IRQ_MASK)
|
||||
#else
|
||||
#define ELCDIF_AS_CTRL_IRQ_MASK 0U
|
||||
#endif
|
||||
|
||||
/* All IRQ enable control bits in AS_CTRL register. */
|
||||
#if defined(LCDIF_AS_CTRL_CSI_SYNC_ON_IRQ_EN_MASK)
|
||||
#define ELCDIF_AS_CTRL_IRQ_EN_MASK (LCDIF_AS_CTRL_CSI_SYNC_ON_IRQ_EN_MASK)
|
||||
#else
|
||||
#define ELCDIF_AS_CTRL_IRQ_EN_MASK 0U
|
||||
#endif
|
||||
|
||||
#if ((ELCDIF_CTRL1_IRQ_MASK & ELCDIF_AS_CTRL_IRQ_MASK) || (ELCDIF_AS_CTRL_IRQ_MASK & ELCDIF_AS_CTRL_IRQ_EN_MASK))
|
||||
#error Interrupt bits overlap, need to update the interrupt functions.
|
||||
#endif
|
||||
|
||||
/* LUT memory entery number. */
|
||||
#define ELCDIF_LUT_ENTRY_NUM 256
|
||||
|
||||
/*!
|
||||
* @brief eLCDIF signal polarity flags
|
||||
*/
|
||||
enum _elcdif_polarity_flags
|
||||
{
|
||||
kELCDIF_VsyncActiveLow = 0U, /*!< VSYNC active low. */
|
||||
kELCDIF_VsyncActiveHigh = LCDIF_VDCTRL0_VSYNC_POL_MASK, /*!< VSYNC active high. */
|
||||
kELCDIF_HsyncActiveLow = 0U, /*!< HSYNC active low. */
|
||||
kELCDIF_HsyncActiveHigh = LCDIF_VDCTRL0_HSYNC_POL_MASK, /*!< HSYNC active high. */
|
||||
kELCDIF_DataEnableActiveLow = 0U, /*!< Data enable line active low. */
|
||||
kELCDIF_DataEnableActiveHigh = LCDIF_VDCTRL0_ENABLE_POL_MASK, /*!< Data enable line active high. */
|
||||
kELCDIF_DriveDataOnFallingClkEdge = 0U, /*!< Drive data on falling clock edge, capture data
|
||||
on rising clock edge. */
|
||||
kELCDIF_DriveDataOnRisingClkEdge = LCDIF_VDCTRL0_DOTCLK_POL_MASK, /*!< Drive data on falling
|
||||
clock edge, capture data
|
||||
on rising clock edge. */
|
||||
};
|
||||
|
||||
/*!
|
||||
* @brief The eLCDIF interrupts to enable.
|
||||
*/
|
||||
enum _elcdif_interrupt_enable
|
||||
{
|
||||
kELCDIF_BusMasterErrorInterruptEnable = LCDIF_CTRL1_BM_ERROR_IRQ_EN_MASK, /*!< Bus master error interrupt. */
|
||||
kELCDIF_TxFifoOverflowInterruptEnable = LCDIF_CTRL1_OVERFLOW_IRQ_EN_MASK, /*!< TXFIFO overflow interrupt. */
|
||||
kELCDIF_TxFifoUnderflowInterruptEnable = LCDIF_CTRL1_UNDERFLOW_IRQ_EN_MASK, /*!< TXFIFO underflow interrupt. */
|
||||
kELCDIF_CurFrameDoneInterruptEnable =
|
||||
LCDIF_CTRL1_CUR_FRAME_DONE_IRQ_EN_MASK, /*!< Interrupt when hardware enters vertical blanking state. */
|
||||
kELCDIF_VsyncEdgeInterruptEnable =
|
||||
LCDIF_CTRL1_VSYNC_EDGE_IRQ_EN_MASK, /*!< Interrupt when hardware encounters VSYNC edge. */
|
||||
#if defined(LCDIF_AS_CTRL_CSI_SYNC_ON_IRQ_EN_MASK)
|
||||
kELCDIF_SciSyncOnInterruptEnable =
|
||||
LCDIF_AS_CTRL_CSI_SYNC_ON_IRQ_EN_MASK, /*!< Interrupt when eLCDIF lock with CSI input. */
|
||||
#endif
|
||||
};
|
||||
|
||||
/*!
|
||||
* @brief The eLCDIF interrupt status flags.
|
||||
*/
|
||||
enum _elcdif_interrupt_flags
|
||||
{
|
||||
kELCDIF_BusMasterError = LCDIF_CTRL1_BM_ERROR_IRQ_MASK, /*!< Bus master error interrupt. */
|
||||
kELCDIF_TxFifoOverflow = LCDIF_CTRL1_OVERFLOW_IRQ_MASK, /*!< TXFIFO overflow interrupt. */
|
||||
kELCDIF_TxFifoUnderflow = LCDIF_CTRL1_UNDERFLOW_IRQ_MASK, /*!< TXFIFO underflow interrupt. */
|
||||
kELCDIF_CurFrameDone =
|
||||
LCDIF_CTRL1_CUR_FRAME_DONE_IRQ_MASK, /*!< Interrupt when hardware enters vertical blanking state. */
|
||||
kELCDIF_VsyncEdge = LCDIF_CTRL1_VSYNC_EDGE_IRQ_MASK, /*!< Interrupt when hardware encounters VSYNC edge. */
|
||||
#if defined(LCDIF_AS_CTRL_CSI_SYNC_ON_IRQ_MASK)
|
||||
kELCDIF_SciSyncOn = LCDIF_AS_CTRL_CSI_SYNC_ON_IRQ_MASK, /*!< Interrupt when eLCDIF lock with CSI input. */
|
||||
#endif
|
||||
};
|
||||
|
||||
/*!
|
||||
* @brief eLCDIF status flags
|
||||
*/
|
||||
enum _elcdif_status_flags
|
||||
{
|
||||
kELCDIF_LFifoFull = LCDIF_STAT_LFIFO_FULL_MASK, /*!< LFIFO full. */
|
||||
kELCDIF_LFifoEmpty = LCDIF_STAT_LFIFO_EMPTY_MASK, /*!< LFIFO empty. */
|
||||
kELCDIF_TxFifoFull = LCDIF_STAT_TXFIFO_FULL_MASK, /*!< TXFIFO full. */
|
||||
kELCDIF_TxFifoEmpty = LCDIF_STAT_TXFIFO_EMPTY_MASK, /*!< TXFIFO empty. */
|
||||
#if defined(LCDIF_STAT_BUSY_MASK)
|
||||
kELCDIF_LcdControllerBusy = LCDIF_STAT_BUSY_MASK, /*!< The external LCD controller busy signal. */
|
||||
#endif
|
||||
#if defined(LCDIF_STAT_DVI_CURRENT_FIELD_MASK)
|
||||
kELCDIF_CurDviField2 = LCDIF_STAT_DVI_CURRENT_FIELD_MASK, /*!< Current DVI filed, if set, then current filed is 2,
|
||||
otherwise current filed is 1. */
|
||||
#endif
|
||||
};
|
||||
|
||||
/*!
|
||||
* @brief The pixel format.
|
||||
*
|
||||
* This enumerator should be defined together with the array s_pixelFormatReg.
|
||||
* To support new pixel format, enhance this enumerator and s_pixelFormatReg.
|
||||
*/
|
||||
typedef enum _elcdif_pixel_format
|
||||
{
|
||||
kELCDIF_PixelFormatRAW8 = 0, /*!< RAW 8 bit, four data use 32 bits. */
|
||||
kELCDIF_PixelFormatRGB565 = 1, /*!< RGB565, two pixel use 32 bits. */
|
||||
kELCDIF_PixelFormatRGB666 = 2, /*!< RGB666 unpacked, one pixel uses 32 bits, high byte unused,
|
||||
upper 2 bits of other bytes unused. */
|
||||
kELCDIF_PixelFormatXRGB8888 = 3, /*!< XRGB8888 unpacked, one pixel uses 32 bits, high byte unused. */
|
||||
kELCDIF_PixelFormatRGB888 = 4, /*!< RGB888 packed, one pixel uses 24 bits. */
|
||||
} elcdif_pixel_format_t;
|
||||
|
||||
/*! @brief The LCD data bus type. */
|
||||
typedef enum _elcdif_lcd_data_bus
|
||||
{
|
||||
kELCDIF_DataBus8Bit = LCDIF_CTRL_LCD_DATABUS_WIDTH(1), /*!< 8-bit data bus. */
|
||||
kELCDIF_DataBus16Bit = LCDIF_CTRL_LCD_DATABUS_WIDTH(0), /*!< 16-bit data bus, support RGB565. */
|
||||
kELCDIF_DataBus18Bit = LCDIF_CTRL_LCD_DATABUS_WIDTH(2), /*!< 18-bit data bus, support RGB666. */
|
||||
kELCDIF_DataBus24Bit = LCDIF_CTRL_LCD_DATABUS_WIDTH(3), /*!< 24-bit data bus, support RGB888. */
|
||||
} elcdif_lcd_data_bus_t;
|
||||
|
||||
/*!
|
||||
* @brief The register value when using different pixel format.
|
||||
*
|
||||
* These register bits control the pixel format:
|
||||
* - CTRL[DATA_FORMAT_24_BIT]
|
||||
* - CTRL[DATA_FORMAT_18_BIT]
|
||||
* - CTRL[DATA_FORMAT_16_BIT]
|
||||
* - CTRL[WORD_LENGTH]
|
||||
* - CTRL1[BYTE_PACKING_FORMAT]
|
||||
*/
|
||||
typedef struct _elcdif_pixel_format_reg
|
||||
{
|
||||
uint32_t regCtrl; /*!< Value of register CTRL. */
|
||||
uint32_t regCtrl1; /*!< Value of register CTRL1. */
|
||||
} elcdif_pixel_format_reg_t;
|
||||
|
||||
/*!
|
||||
* @brief eLCDIF configure structure for RGB mode (DOTCLK mode).
|
||||
*/
|
||||
typedef struct _elcdif_rgb_mode_config
|
||||
{
|
||||
uint16_t panelWidth; /*!< Display panel width, pixels per line. */
|
||||
uint16_t panelHeight; /*!< Display panel height, how many lines per panel. */
|
||||
uint8_t hsw; /*!< HSYNC pulse width. */
|
||||
uint8_t hfp; /*!< Horizontal front porch. */
|
||||
uint8_t hbp; /*!< Horizontal back porch. */
|
||||
uint8_t vsw; /*!< VSYNC pulse width. */
|
||||
uint8_t vfp; /*!< Vrtical front porch. */
|
||||
uint8_t vbp; /*!< Vertical back porch. */
|
||||
uint32_t polarityFlags; /*!< OR'ed value of @ref _elcdif_polarity_flags, used to contol the signal polarity. */
|
||||
uint32_t bufferAddr; /*!< Frame buffer address. */
|
||||
elcdif_pixel_format_t pixelFormat; /*!< Pixel format. */
|
||||
elcdif_lcd_data_bus_t dataBus; /*!< LCD data bus. */
|
||||
} elcdif_rgb_mode_config_t;
|
||||
|
||||
/*!
|
||||
* @brief eLCDIF alpha surface pixel format.
|
||||
*/
|
||||
typedef enum _elcdif_as_pixel_format
|
||||
{
|
||||
kELCDIF_AsPixelFormatARGB8888 = 0x0, /*!< 32-bit pixels with alpha. */
|
||||
kELCDIF_AsPixelFormatRGB888 = 0x4, /*!< 32-bit pixels without alpha (unpacked 24-bit format) */
|
||||
kELCDIF_AsPixelFormatARGB1555 = 0x8, /*!< 16-bit pixels with alpha. */
|
||||
kELCDIF_AsPixelFormatARGB4444 = 0x9, /*!< 16-bit pixels with alpha. */
|
||||
kELCDIF_AsPixelFormatRGB555 = 0xC, /*!< 16-bit pixels without alpha. */
|
||||
kELCDIF_AsPixelFormatRGB444 = 0xD, /*!< 16-bit pixels without alpha. */
|
||||
kELCDIF_AsPixelFormatRGB565 = 0xE, /*!< 16-bit pixels without alpha. */
|
||||
} elcdif_as_pixel_format_t;
|
||||
|
||||
/*!
|
||||
* @brief eLCDIF alpha surface buffer configuration.
|
||||
*/
|
||||
typedef struct _elcdif_as_buffer_config
|
||||
{
|
||||
uint32_t bufferAddr; /*!< Buffer address. */
|
||||
elcdif_as_pixel_format_t pixelFormat; /*!< Pixel format. */
|
||||
} elcdif_as_buffer_config_t;
|
||||
|
||||
/*!
|
||||
* @brief eLCDIF alpha mode during blending.
|
||||
*/
|
||||
typedef enum _elcdif_alpha_mode
|
||||
{
|
||||
kELCDIF_AlphaEmbedded, /*!< The alpha surface pixel alpha value will be used for blend. */
|
||||
kELCDIF_AlphaOverride, /*!< The user defined alpha value will be used for blend directly. */
|
||||
kELCDIF_AlphaMultiply, /*!< The alpha surface pixel alpha value scaled the user defined
|
||||
alpha value will be used for blend, for example, pixel alpha set
|
||||
set to 200, user defined alpha set to 100, then the reault alpha
|
||||
is 200 * 100 / 255. */
|
||||
kELCDIF_AlphaRop /*!< Raster operation. */
|
||||
} elcdif_alpha_mode_t;
|
||||
|
||||
/*!
|
||||
* @brief eLCDIF ROP mode during blending.
|
||||
*
|
||||
* Explanation:
|
||||
* - AS: Alpha surface
|
||||
* - PS: Process surface
|
||||
* - nAS: Alpha surface NOT value
|
||||
* - nPS: Process surface NOT value
|
||||
*/
|
||||
typedef enum _elcdif_rop_mode
|
||||
{
|
||||
kELCDIF_RopMaskAs = 0x0, /*!< AS AND PS. */
|
||||
kELCDIF_RopMaskNotAs = 0x1, /*!< nAS AND PS. */
|
||||
kELCDIF_RopMaskAsNot = 0x2, /*!< AS AND nPS. */
|
||||
kELCDIF_RopMergeAs = 0x3, /*!< AS OR PS. */
|
||||
kELCDIF_RopMergeNotAs = 0x4, /*!< nAS OR PS. */
|
||||
kELCDIF_RopMergeAsNot = 0x5, /*!< AS OR nPS. */
|
||||
kELCDIF_RopNotCopyAs = 0x6, /*!< nAS. */
|
||||
kELCDIF_RopNot = 0x7, /*!< nPS. */
|
||||
kELCDIF_RopNotMaskAs = 0x8, /*!< AS NAND PS. */
|
||||
kELCDIF_RopNotMergeAs = 0x9, /*!< AS NOR PS. */
|
||||
kELCDIF_RopXorAs = 0xA, /*!< AS XOR PS. */
|
||||
kELCDIF_RopNotXorAs = 0xB /*!< AS XNOR PS. */
|
||||
} elcdif_rop_mode_t;
|
||||
|
||||
/*!
|
||||
* @brief eLCDIF alpha surface blending configuration.
|
||||
*/
|
||||
typedef struct _elcdif_as_blend_config
|
||||
{
|
||||
uint8_t alpha; /*!< User defined alpha value, only used when @ref alphaMode is @ref kELCDIF_AlphaOverride or @ref
|
||||
kELCDIF_AlphaRop. */
|
||||
bool invertAlpha; /*!< Set true to invert the alpha. */
|
||||
elcdif_alpha_mode_t alphaMode; /*!< Alpha mode. */
|
||||
elcdif_rop_mode_t ropMode; /*!< ROP mode, only valid when @ref alphaMode is @ref kELCDIF_AlphaRop. */
|
||||
} elcdif_as_blend_config_t;
|
||||
|
||||
/*!
|
||||
* @brief eLCDIF LUT
|
||||
*
|
||||
* The Lookup Table (LUT) is used to expand the 8 bits pixel to 24 bits pixel
|
||||
* before output to external displayer.
|
||||
*
|
||||
* There are two 256x24 bits LUT memory in LCDIF, the LSB of frame buffer address
|
||||
* determins which memory to use.
|
||||
*/
|
||||
typedef enum _elcdif_lut
|
||||
{
|
||||
kELCDIF_Lut0 = 0, /*!< LUT 0. */
|
||||
kELCDIF_Lut1, /*!< LUT 1. */
|
||||
} elcdif_lut_t;
|
||||
|
||||
/*******************************************************************************
|
||||
* APIs
|
||||
******************************************************************************/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/*!
|
||||
* @name eLCDIF initialization and de-initialization
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Initializes the eLCDIF to work in RGB mode (DOTCLK mode).
|
||||
*
|
||||
* This function ungates the eLCDIF clock and configures the eLCDIF peripheral according
|
||||
* to the configuration structure.
|
||||
*
|
||||
* @param base eLCDIF peripheral base address.
|
||||
* @param config Pointer to the configuration structure.
|
||||
*/
|
||||
void ELCDIF_RgbModeInit(LCDIF_Type *base, const elcdif_rgb_mode_config_t *config);
|
||||
|
||||
/*!
|
||||
* @brief Gets the eLCDIF default configuration structure for RGB (DOTCLK) mode.
|
||||
*
|
||||
* This function sets the configuration structure to default values.
|
||||
* The default configuration is set to the following values.
|
||||
* @code
|
||||
config->panelWidth = 480U;
|
||||
config->panelHeight = 272U;
|
||||
config->hsw = 41;
|
||||
config->hfp = 4;
|
||||
config->hbp = 8;
|
||||
config->vsw = 10;
|
||||
config->vfp = 4;
|
||||
config->vbp = 2;
|
||||
config->polarityFlags = kELCDIF_VsyncActiveLow |
|
||||
kELCDIF_HsyncActiveLow |
|
||||
kELCDIF_DataEnableActiveLow |
|
||||
kELCDIF_DriveDataOnFallingClkEdge;
|
||||
config->bufferAddr = 0U;
|
||||
config->pixelFormat = kELCDIF_PixelFormatRGB888;
|
||||
config->dataBus = kELCDIF_DataBus24Bit;
|
||||
@code
|
||||
*
|
||||
* @param config Pointer to the eLCDIF configuration structure.
|
||||
*/
|
||||
void ELCDIF_RgbModeGetDefaultConfig(elcdif_rgb_mode_config_t *config);
|
||||
|
||||
/*!
|
||||
* @brief Deinitializes the eLCDIF peripheral.
|
||||
*
|
||||
* @param base eLCDIF peripheral base address.
|
||||
*/
|
||||
void ELCDIF_Deinit(LCDIF_Type *base);
|
||||
|
||||
/* @} */
|
||||
|
||||
/*!
|
||||
* @name Module operation
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Set the pixel format in RGB (DOTCLK) mode.
|
||||
*
|
||||
* @param base eLCDIF peripheral base address.
|
||||
* @param pixelFormat The pixel format.
|
||||
*/
|
||||
void ELCDIF_RgbModeSetPixelFormat(LCDIF_Type *base, elcdif_pixel_format_t pixelFormat);
|
||||
|
||||
/*!
|
||||
* @brief Start to display in RGB (DOTCLK) mode.
|
||||
*
|
||||
* @param base eLCDIF peripheral base address.
|
||||
*/
|
||||
static inline void ELCDIF_RgbModeStart(LCDIF_Type *base)
|
||||
{
|
||||
base->CTRL_SET = LCDIF_CTRL_RUN_MASK | LCDIF_CTRL_DOTCLK_MODE_MASK;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Stop display in RGB (DOTCLK) mode and wait until finished.
|
||||
*
|
||||
* @param base eLCDIF peripheral base address.
|
||||
*/
|
||||
void ELCDIF_RgbModeStop(LCDIF_Type *base);
|
||||
|
||||
/*!
|
||||
* @brief Set the next frame buffer address to display.
|
||||
*
|
||||
* @param base eLCDIF peripheral base address.
|
||||
* @param bufferAddr The frame buffer address to set.
|
||||
*/
|
||||
static inline void ELCDIF_SetNextBufferAddr(LCDIF_Type *base, uint32_t bufferAddr)
|
||||
{
|
||||
base->NEXT_BUF = bufferAddr;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Reset the eLCDIF peripheral.
|
||||
*
|
||||
* @param base eLCDIF peripheral base address.
|
||||
*/
|
||||
void ELCDIF_Reset(LCDIF_Type *base);
|
||||
|
||||
#if !(defined(FSL_FEATURE_LCDIF_HAS_NO_RESET_PIN) && FSL_FEATURE_LCDIF_HAS_NO_RESET_PIN)
|
||||
/*!
|
||||
* @brief Pull up or down the reset pin for the externel LCD controller.
|
||||
*
|
||||
* @param base eLCDIF peripheral base address.
|
||||
* @param pullUp True to pull up reset pin, false to pull down.
|
||||
*/
|
||||
static inline void ELCDIF_PullUpResetPin(LCDIF_Type *base, bool pullUp)
|
||||
{
|
||||
if (pullUp)
|
||||
{
|
||||
base->CTRL1_SET = LCDIF_CTRL1_RESET_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
base->CTRL1_CLR = LCDIF_CTRL1_RESET_MASK;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @brief Enable or disable the hand shake with PXP.
|
||||
*
|
||||
* @param base eLCDIF peripheral base address.
|
||||
* @param enable True to enable, false to disable.
|
||||
*/
|
||||
static inline void ELCDIF_EnablePxpHandShake(LCDIF_Type *base, bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
base->CTRL_SET = LCDIF_CTRL_ENABLE_PXP_HANDSHAKE_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
base->CTRL_CLR = LCDIF_CTRL_ENABLE_PXP_HANDSHAKE_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
/* @} */
|
||||
|
||||
/*!
|
||||
* @name Status
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Get the CRC value of the frame sent out.
|
||||
*
|
||||
* When a frame is sent complete (the interrupt @ref kELCDIF_CurFrameDone assert), this function
|
||||
* can be used to get the CRC value of the frame sent.
|
||||
*
|
||||
* @param base eLCDIF peripheral base address.
|
||||
* @return The CRC value.
|
||||
*
|
||||
* @note The CRC value is dependent on the LCD_DATABUS_WIDTH.
|
||||
*/
|
||||
static inline uint32_t ELCDIF_GetCrcValue(LCDIF_Type *base)
|
||||
{
|
||||
return base->CRC_STAT;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Get the bus master error virtual address.
|
||||
*
|
||||
* When bus master error occurs (the interrupt kELCDIF_BusMasterError assert), this function
|
||||
* can get the virtual address at which the AXI master received an error
|
||||
* response from the slave.
|
||||
*
|
||||
* @param base eLCDIF peripheral base address.
|
||||
* @return The error virtual address.
|
||||
*/
|
||||
static inline uint32_t ELCDIF_GetBusMasterErrorAddr(LCDIF_Type *base)
|
||||
{
|
||||
return base->BM_ERROR_STAT;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Get the eLCDIF status.
|
||||
*
|
||||
* The status flags are returned as a mask value, application could check the
|
||||
* corresponding bit. Example:
|
||||
*
|
||||
* @code
|
||||
uint32_t statusFlags;
|
||||
statusFlags = ELCDIF_GetStatus(LCDIF);
|
||||
|
||||
// If LFIFO is full.
|
||||
if (kELCDIF_LFifoFull & statusFlags)
|
||||
{
|
||||
// ...;
|
||||
}
|
||||
// If TXFIFO is empty.
|
||||
if (kELCDIF_TxFifoEmpty & statusFlags)
|
||||
{
|
||||
// ...;
|
||||
}
|
||||
@endcode
|
||||
*
|
||||
* @param base eLCDIF peripheral base address.
|
||||
* @return The mask value of status flags, it is OR'ed value of @ref _elcdif_status_flags.
|
||||
*/
|
||||
static inline uint32_t ELCDIF_GetStatus(LCDIF_Type *base)
|
||||
{
|
||||
return base->STAT & (LCDIF_STAT_LFIFO_FULL_MASK | LCDIF_STAT_LFIFO_EMPTY_MASK | LCDIF_STAT_TXFIFO_FULL_MASK |
|
||||
LCDIF_STAT_TXFIFO_EMPTY_MASK
|
||||
#if defined(LCDIF_STAT_BUSY_MASK)
|
||||
| LCDIF_STAT_BUSY_MASK
|
||||
#endif
|
||||
#if defined(LCDIF_STAT_DVI_CURRENT_FIELD_MASK)
|
||||
| LCDIF_STAT_DVI_CURRENT_FIELD_MASK
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Get current count in Latency buffer (LFIFO).
|
||||
*
|
||||
* @param base eLCDIF peripheral base address.
|
||||
* @return The LFIFO current count
|
||||
*/
|
||||
static inline uint32_t ELCDIF_GetLFifoCount(LCDIF_Type *base)
|
||||
{
|
||||
return (base->STAT & LCDIF_STAT_LFIFO_COUNT_MASK) >> LCDIF_STAT_LFIFO_COUNT_SHIFT;
|
||||
}
|
||||
|
||||
/* @} */
|
||||
|
||||
/*!
|
||||
* @name Interrupts
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Enables eLCDIF interrupt requests.
|
||||
*
|
||||
* @param base eLCDIF peripheral base address.
|
||||
* @param mask interrupt source, OR'ed value of _elcdif_interrupt_enable.
|
||||
*/
|
||||
static inline void ELCDIF_EnableInterrupts(LCDIF_Type *base, uint32_t mask)
|
||||
{
|
||||
base->CTRL1_SET = (mask & ELCDIF_CTRL1_IRQ_EN_MASK);
|
||||
#if !(defined(FSL_FEATURE_LCDIF_HAS_NO_AS) && FSL_FEATURE_LCDIF_HAS_NO_AS)
|
||||
base->AS_CTRL |= (mask & ELCDIF_AS_CTRL_IRQ_EN_MASK);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Disables eLCDIF interrupt requests.
|
||||
*
|
||||
* @param base eLCDIF peripheral base address.
|
||||
* @param mask interrupt source, OR'ed value of _elcdif_interrupt_enable.
|
||||
*/
|
||||
static inline void ELCDIF_DisableInterrupts(LCDIF_Type *base, uint32_t mask)
|
||||
{
|
||||
base->CTRL1_CLR = (mask & ELCDIF_CTRL1_IRQ_EN_MASK);
|
||||
#if !(defined(FSL_FEATURE_LCDIF_HAS_NO_AS) && FSL_FEATURE_LCDIF_HAS_NO_AS)
|
||||
base->AS_CTRL &= ~(mask & ELCDIF_AS_CTRL_IRQ_EN_MASK);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Get eLCDIF interrupt peding status.
|
||||
*
|
||||
* @param base eLCDIF peripheral base address.
|
||||
* @return Interrupt pending status, OR'ed value of _elcdif_interrupt_flags.
|
||||
*/
|
||||
static inline uint32_t ELCDIF_GetInterruptStatus(LCDIF_Type *base)
|
||||
{
|
||||
uint32_t flags;
|
||||
|
||||
flags = (base->CTRL1 & ELCDIF_CTRL1_IRQ_MASK);
|
||||
#if !(defined(FSL_FEATURE_LCDIF_HAS_NO_AS) && FSL_FEATURE_LCDIF_HAS_NO_AS)
|
||||
flags |= (base->AS_CTRL & ELCDIF_AS_CTRL_IRQ_MASK);
|
||||
#endif
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Clear eLCDIF interrupt peding status.
|
||||
*
|
||||
* @param base eLCDIF peripheral base address.
|
||||
* @param mask of the flags to clear, OR'ed value of _elcdif_interrupt_flags.
|
||||
*/
|
||||
static inline void ELCDIF_ClearInterruptStatus(LCDIF_Type *base, uint32_t mask)
|
||||
{
|
||||
base->CTRL1_CLR = (mask & ELCDIF_CTRL1_IRQ_MASK);
|
||||
#if !(defined(FSL_FEATURE_LCDIF_HAS_NO_AS) && FSL_FEATURE_LCDIF_HAS_NO_AS)
|
||||
base->AS_CTRL &= ~(mask & ELCDIF_AS_CTRL_IRQ_MASK);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* @} */
|
||||
|
||||
#if !(defined(FSL_FEATURE_LCDIF_HAS_NO_AS) && FSL_FEATURE_LCDIF_HAS_NO_AS)
|
||||
/*!
|
||||
* @name Alpha surface
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Set the configuration for alpha surface buffer.
|
||||
*
|
||||
* @param base eLCDIF peripheral base address.
|
||||
* @param config Pointer to the configuration structure.
|
||||
*/
|
||||
void ELCDIF_SetAlphaSurfaceBufferConfig(LCDIF_Type *base, const elcdif_as_buffer_config_t *config);
|
||||
|
||||
/*!
|
||||
* @brief Set the alpha surface blending configuration.
|
||||
*
|
||||
* @param base eLCDIF peripheral base address.
|
||||
* @param config Pointer to the configuration structure.
|
||||
*/
|
||||
void ELCDIF_SetAlphaSurfaceBlendConfig(LCDIF_Type *base, const elcdif_as_blend_config_t *config);
|
||||
|
||||
/*!
|
||||
* @brief Set the next alpha surface buffer address.
|
||||
*
|
||||
* @param base eLCDIF peripheral base address.
|
||||
* @param bufferAddr Alpha surface buffer address.
|
||||
*/
|
||||
static inline void ELCDIF_SetNextAlphaSurfaceBufferAddr(LCDIF_Type *base, uint32_t bufferAddr)
|
||||
{
|
||||
base->AS_NEXT_BUF = bufferAddr;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Set the overlay color key.
|
||||
*
|
||||
* If a pixel in the current overlay image with a color that falls in the range
|
||||
* from the @p colorKeyLow to @p colorKeyHigh range, it will use the process surface
|
||||
* pixel value for that location.
|
||||
*
|
||||
* @param base eLCDIF peripheral base address.
|
||||
* @param colorKeyLow Color key low range.
|
||||
* @param colorKeyHigh Color key high range.
|
||||
*
|
||||
* @note Colorkey operations are higher priority than alpha or ROP operations
|
||||
*/
|
||||
static inline void ELCDIF_SetOverlayColorKey(LCDIF_Type *base, uint32_t colorKeyLow, uint32_t colorKeyHigh)
|
||||
{
|
||||
base->AS_CLRKEYLOW = colorKeyLow;
|
||||
base->AS_CLRKEYHIGH = colorKeyHigh;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Enable or disable the color key.
|
||||
*
|
||||
* @param base eLCDIF peripheral base address.
|
||||
* @param enable True to enable, false to disable.
|
||||
*/
|
||||
static inline void ELCDIF_EnableOverlayColorKey(LCDIF_Type *base, bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
base->AS_CTRL |= LCDIF_AS_CTRL_ENABLE_COLORKEY_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
base->AS_CTRL &= ~LCDIF_AS_CTRL_ENABLE_COLORKEY_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Enable or disable the alpha surface.
|
||||
*
|
||||
* @param base eLCDIF peripheral base address.
|
||||
* @param enable True to enable, false to disable.
|
||||
*/
|
||||
static inline void ELCDIF_EnableAlphaSurface(LCDIF_Type *base, bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
base->AS_CTRL |= LCDIF_AS_CTRL_AS_ENABLE_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
base->AS_CTRL &= ~LCDIF_AS_CTRL_AS_ENABLE_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Enable or disable the process surface.
|
||||
*
|
||||
* Process surface is the normal frame buffer. The process surface content
|
||||
* is controlled by @ref ELCDIF_SetNextBufferAddr.
|
||||
*
|
||||
* @param base eLCDIF peripheral base address.
|
||||
* @param enable True to enable, false to disable.
|
||||
*/
|
||||
static inline void ELCDIF_EnableProcessSurface(LCDIF_Type *base, bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
base->AS_CTRL &= ~LCDIF_AS_CTRL_PS_DISABLE_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
base->AS_CTRL |= LCDIF_AS_CTRL_PS_DISABLE_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
/* @} */
|
||||
#endif /* FSL_FEATURE_LCDIF_HAS_NO_AS */
|
||||
|
||||
#if (defined(FSL_FEATURE_LCDIF_HAS_LUT) && FSL_FEATURE_LCDIF_HAS_LUT)
|
||||
/*!
|
||||
* @name LUT
|
||||
*
|
||||
* The Lookup Table (LUT) is used to expand the 8 bits pixel to 24 bits pixel
|
||||
* before output to external displayer.
|
||||
*
|
||||
* There are two 256x24 bits LUT memory in LCDIF, the LSB of frame buffer address
|
||||
* determins which memory to use.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Enable or disable the LUT.
|
||||
*
|
||||
* @param base eLCDIF peripheral base address.
|
||||
* @param enable True to enable, false to disable.
|
||||
*/
|
||||
static inline void ELCDIF_EnableLut(LCDIF_Type *base, bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
base->LUT_CTRL &= ~LCDIF_LUT_CTRL_LUT_BYPASS_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
base->LUT_CTRL |= LCDIF_LUT_CTRL_LUT_BYPASS_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Load the LUT value.
|
||||
*
|
||||
* This function loads the LUT value to the specific LUT memory, user can
|
||||
* specify the start entry index.
|
||||
*
|
||||
* @param base eLCDIF peripheral base address.
|
||||
* @param lut Which LUT to load.
|
||||
* @param startIndex The start index of the LUT entry to update.
|
||||
* @param lutData The LUT data to load.
|
||||
* @param count Count of @p lutData.
|
||||
* @retval kStatus_Success Initialization success.
|
||||
* @retval kStatus_InvalidArgument Wrong argument.
|
||||
*/
|
||||
status_t ELCDIF_UpdateLut(
|
||||
LCDIF_Type *base, elcdif_lut_t lut, uint16_t startIndex, const uint32_t *lutData, uint16_t count);
|
||||
|
||||
/* @} */
|
||||
#endif /* FSL_FEATURE_LCDIF_HAS_LUT */
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/* @} */
|
||||
|
||||
#endif /*_FSL_ELCDIF_H_*/
|
|
@ -0,0 +1,350 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2017 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file fsl_gpio.h
|
||||
* @brief gpio drivers
|
||||
* @version 2.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022-03-15
|
||||
*/
|
||||
|
||||
#ifndef _FSL_GPIO_H_
|
||||
#define _FSL_GPIO_H_
|
||||
|
||||
#include "fsl_common.h"
|
||||
|
||||
/*!
|
||||
* @addtogroup gpio_driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*! @name Driver version */
|
||||
/*@{*/
|
||||
/*! @brief GPIO driver version 2.0.1. */
|
||||
#define FSL_GPIO_DRIVER_VERSION (MAKE_VERSION(2, 0, 1))
|
||||
/*@}*/
|
||||
|
||||
/*! @brief GPIO direction definition. */
|
||||
typedef enum _gpio_pin_direction
|
||||
{
|
||||
kGPIO_DigitalInput = 0U, /*!< Set current pin as digital input.*/
|
||||
kGPIO_DigitalOutput = 1U, /*!< Set current pin as digital output.*/
|
||||
} gpio_pin_direction_t;
|
||||
|
||||
/*! @brief GPIO interrupt mode definition. */
|
||||
typedef enum _gpio_interrupt_mode
|
||||
{
|
||||
kGPIO_NoIntmode = 0U, /*!< Set current pin general IO functionality.*/
|
||||
kGPIO_IntLowLevel = 1U, /*!< Set current pin interrupt is low-level sensitive.*/
|
||||
kGPIO_IntHighLevel = 2U, /*!< Set current pin interrupt is high-level sensitive.*/
|
||||
kGPIO_IntRisingEdge = 3U, /*!< Set current pin interrupt is rising-edge sensitive.*/
|
||||
kGPIO_IntFallingEdge = 4U, /*!< Set current pin interrupt is falling-edge sensitive.*/
|
||||
kGPIO_IntRisingOrFallingEdge = 5U, /*!< Enable the edge select bit to override the ICR register's configuration.*/
|
||||
} gpio_interrupt_mode_t;
|
||||
|
||||
/*! @brief GPIO Init structure definition. */
|
||||
typedef struct _gpio_pin_config
|
||||
{
|
||||
gpio_pin_direction_t direction; /*!< Specifies the pin direction. */
|
||||
uint8_t outputLogic; /*!< Set a default output logic, which has no use in input */
|
||||
gpio_interrupt_mode_t
|
||||
interruptMode; /*!< Specifies the pin interrupt mode, a value of @ref gpio_interrupt_mode_t. */
|
||||
} gpio_pin_config_t;
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @name GPIO Initialization and Configuration functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Initializes the GPIO peripheral according to the specified
|
||||
* parameters in the initConfig.
|
||||
*
|
||||
* @param base GPIO base pointer.
|
||||
* @param pin Specifies the pin number
|
||||
* @param initConfig pointer to a @ref gpio_pin_config_t structure that
|
||||
* contains the configuration information.
|
||||
*/
|
||||
void GPIO_PinInit(GPIO_Type *base, uint32_t pin, const gpio_pin_config_t *Config);
|
||||
/*@}*/
|
||||
|
||||
/*!
|
||||
* @name GPIO Reads and Write Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Sets the output level of the individual GPIO pin to logic 1 or 0.
|
||||
*
|
||||
* @param base GPIO base pointer.
|
||||
* @param pin GPIO port pin number.
|
||||
* @param output GPIOpin output logic level.
|
||||
* - 0: corresponding pin output low-logic level.
|
||||
* - 1: corresponding pin output high-logic level.
|
||||
*/
|
||||
void GPIO_PinWrite(GPIO_Type *base, uint32_t pin, uint8_t output);
|
||||
|
||||
/*!
|
||||
* @brief Sets the output level of the individual GPIO pin to logic 1 or 0.
|
||||
* @deprecated Do not use this function. It has been superceded by @ref GPIO_PinWrite.
|
||||
*/
|
||||
static inline void GPIO_WritePinOutput(GPIO_Type *base, uint32_t pin, uint8_t output)
|
||||
{
|
||||
GPIO_PinWrite(base, pin, output);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Sets the output level of the multiple GPIO pins to the logic 1.
|
||||
*
|
||||
* @param base GPIO peripheral base pointer (GPIO1, GPIO2, GPIO3, and so on.)
|
||||
* @param mask GPIO pin number macro
|
||||
*/
|
||||
static inline void GPIO_PortSet(GPIO_Type *base, uint32_t mask)
|
||||
{
|
||||
#if (defined(FSL_FEATURE_IGPIO_HAS_DR_SET) && (FSL_FEATURE_IGPIO_HAS_DR_SET == 1))
|
||||
base->DR_SET = mask;
|
||||
#else
|
||||
base->DR |= mask;
|
||||
#endif /* FSL_FEATURE_IGPIO_HAS_DR_SET */
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Sets the output level of the multiple GPIO pins to the logic 1.
|
||||
* @deprecated Do not use this function. It has been superceded by @ref GPIO_PortSet.
|
||||
*/
|
||||
static inline void GPIO_SetPinsOutput(GPIO_Type *base, uint32_t mask)
|
||||
{
|
||||
GPIO_PortSet(base, mask);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Sets the output level of the multiple GPIO pins to the logic 0.
|
||||
*
|
||||
* @param base GPIO peripheral base pointer (GPIO1, GPIO2, GPIO3, and so on.)
|
||||
* @param mask GPIO pin number macro
|
||||
*/
|
||||
static inline void GPIO_PortClear(GPIO_Type *base, uint32_t mask)
|
||||
{
|
||||
#if (defined(FSL_FEATURE_IGPIO_HAS_DR_CLEAR) && (FSL_FEATURE_IGPIO_HAS_DR_CLEAR == 1))
|
||||
base->DR_CLEAR = mask;
|
||||
#else
|
||||
base->DR &= ~mask;
|
||||
#endif /* FSL_FEATURE_IGPIO_HAS_DR_CLEAR */
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Sets the output level of the multiple GPIO pins to the logic 0.
|
||||
* @deprecated Do not use this function. It has been superceded by @ref GPIO_PortClear.
|
||||
*/
|
||||
static inline void GPIO_ClearPinsOutput(GPIO_Type *base, uint32_t mask)
|
||||
{
|
||||
GPIO_PortClear(base, mask);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Reverses the current output logic of the multiple GPIO pins.
|
||||
*
|
||||
* @param base GPIO peripheral base pointer (GPIO1, GPIO2, GPIO3, and so on.)
|
||||
* @param mask GPIO pin number macro
|
||||
*/
|
||||
static inline void GPIO_PortToggle(GPIO_Type *base, uint32_t mask)
|
||||
{
|
||||
#if (defined(FSL_FEATURE_IGPIO_HAS_DR_TOGGLE) && (FSL_FEATURE_IGPIO_HAS_DR_TOGGLE == 1))
|
||||
base->DR_TOGGLE = mask;
|
||||
#endif /* FSL_FEATURE_IGPIO_HAS_DR_TOGGLE */
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Reads the current input value of the GPIO port.
|
||||
*
|
||||
* @param base GPIO base pointer.
|
||||
* @param pin GPIO port pin number.
|
||||
* @retval GPIO port input value.
|
||||
*/
|
||||
static inline uint32_t GPIO_PinRead(GPIO_Type *base, uint32_t pin)
|
||||
{
|
||||
assert(pin < 32);
|
||||
|
||||
return (((base->DR) >> pin) & 0x1U);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Reads the current input value of the GPIO port.
|
||||
* @deprecated Do not use this function. It has been superceded by @ref GPIO_PinRead.
|
||||
*/
|
||||
static inline uint32_t GPIO_ReadPinInput(GPIO_Type *base, uint32_t pin)
|
||||
{
|
||||
return GPIO_PinRead(base, pin);
|
||||
}
|
||||
/*@}*/
|
||||
|
||||
/*!
|
||||
* @name GPIO Reads Pad Status Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Reads the current GPIO pin pad status.
|
||||
*
|
||||
* @param base GPIO base pointer.
|
||||
* @param pin GPIO port pin number.
|
||||
* @retval GPIO pin pad status value.
|
||||
*/
|
||||
static inline uint8_t GPIO_PinReadPadStatus(GPIO_Type *base, uint32_t pin)
|
||||
{
|
||||
assert(pin < 32);
|
||||
|
||||
return (uint8_t)(((base->PSR) >> pin) & 0x1U);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Reads the current GPIO pin pad status.
|
||||
* @deprecated Do not use this function. It has been superceded by @ref GPIO_PinReadPadStatus.
|
||||
*/
|
||||
static inline uint8_t GPIO_ReadPadStatus(GPIO_Type *base, uint32_t pin)
|
||||
{
|
||||
return GPIO_PinReadPadStatus(base, pin);
|
||||
}
|
||||
|
||||
/*@}*/
|
||||
|
||||
/*!
|
||||
* @name Interrupts and flags management functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Sets the current pin interrupt mode.
|
||||
*
|
||||
* @param base GPIO base pointer.
|
||||
* @param pin GPIO port pin number.
|
||||
* @param pininterruptMode pointer to a @ref gpio_interrupt_mode_t structure
|
||||
* that contains the interrupt mode information.
|
||||
*/
|
||||
void GPIO_PinSetInterruptConfig(GPIO_Type *base, uint32_t pin, gpio_interrupt_mode_t pinInterruptMode);
|
||||
|
||||
/*!
|
||||
* @brief Sets the current pin interrupt mode.
|
||||
* @deprecated Do not use this function. It has been superceded by @ref GPIO_PinSetInterruptConfig.
|
||||
*/
|
||||
static inline void GPIO_SetPinInterruptConfig(GPIO_Type *base, uint32_t pin, gpio_interrupt_mode_t pinInterruptMode)
|
||||
{
|
||||
GPIO_PinSetInterruptConfig(base, pin, pinInterruptMode);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Enables the specific pin interrupt.
|
||||
*
|
||||
* @param base GPIO base pointer.
|
||||
* @param mask GPIO pin number macro.
|
||||
*/
|
||||
static inline void GPIO_PortEnableInterrupts(GPIO_Type *base, uint32_t mask)
|
||||
{
|
||||
base->IMR |= mask;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Enables the specific pin interrupt.
|
||||
*
|
||||
* @param base GPIO base pointer.
|
||||
* @param mask GPIO pin number macro.
|
||||
*/
|
||||
static inline void GPIO_EnableInterrupts(GPIO_Type *base, uint32_t mask)
|
||||
{
|
||||
GPIO_PortEnableInterrupts(base, mask);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Disables the specific pin interrupt.
|
||||
*
|
||||
* @param base GPIO base pointer.
|
||||
* @param mask GPIO pin number macro.
|
||||
*/
|
||||
static inline void GPIO_PortDisableInterrupts(GPIO_Type *base, uint32_t mask)
|
||||
{
|
||||
base->IMR &= ~mask;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Disables the specific pin interrupt.
|
||||
* @deprecated Do not use this function. It has been superceded by @ref GPIO_PortDisableInterrupts.
|
||||
*/
|
||||
static inline void GPIO_DisableInterrupts(GPIO_Type *base, uint32_t mask)
|
||||
{
|
||||
GPIO_PortDisableInterrupts(base, mask);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Reads individual pin interrupt status.
|
||||
*
|
||||
* @param base GPIO base pointer.
|
||||
* @retval current pin interrupt status flag.
|
||||
*/
|
||||
static inline uint32_t GPIO_PortGetInterruptFlags(GPIO_Type *base)
|
||||
{
|
||||
return base->ISR;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Reads individual pin interrupt status.
|
||||
*
|
||||
* @param base GPIO base pointer.
|
||||
* @retval current pin interrupt status flag.
|
||||
*/
|
||||
static inline uint32_t GPIO_GetPinsInterruptFlags(GPIO_Type *base)
|
||||
{
|
||||
return GPIO_PortGetInterruptFlags(base);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Clears pin interrupt flag. Status flags are cleared by
|
||||
* writing a 1 to the corresponding bit position.
|
||||
*
|
||||
* @param base GPIO base pointer.
|
||||
* @param mask GPIO pin number macro.
|
||||
*/
|
||||
static inline void GPIO_PortClearInterruptFlags(GPIO_Type *base, uint32_t mask)
|
||||
{
|
||||
base->ISR = mask;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Clears pin interrupt flag. Status flags are cleared by
|
||||
* writing a 1 to the corresponding bit position.
|
||||
*
|
||||
* @param base GPIO base pointer.
|
||||
* @param mask GPIO pin number macro.
|
||||
*/
|
||||
static inline void GPIO_ClearPinsInterruptFlags(GPIO_Type *base, uint32_t mask)
|
||||
{
|
||||
GPIO_PortClearInterruptFlags(base, mask);
|
||||
}
|
||||
/*@}*/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* _FSL_GPIO_H_*/
|
|
@ -0,0 +1,864 @@
|
|||
/*
|
||||
* Copyright (c) 2015-2016, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2017 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file fsl_lpuart.h
|
||||
* @brief fsl uart drivers
|
||||
* @version 2.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022-03-15
|
||||
*/
|
||||
|
||||
#ifndef _FSL_LPUART_H_
|
||||
#define _FSL_LPUART_H_
|
||||
|
||||
#include "fsl_common.h"
|
||||
|
||||
/*!
|
||||
* @addtogroup lpuart_driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*! @name Driver version */
|
||||
/*@{*/
|
||||
/*! @brief LPUART driver version 2.2.6. */
|
||||
#define FSL_LPUART_DRIVER_VERSION (MAKE_VERSION(2, 2, 6))
|
||||
/*@}*/
|
||||
|
||||
/*! @brief Error codes for the LPUART driver. */
|
||||
enum _lpuart_status
|
||||
{
|
||||
kStatus_LPUART_TxBusy = MAKE_STATUS(kStatusGroup_LPUART, 0), /*!< TX busy */
|
||||
kStatus_LPUART_RxBusy = MAKE_STATUS(kStatusGroup_LPUART, 1), /*!< RX busy */
|
||||
kStatus_LPUART_TxIdle = MAKE_STATUS(kStatusGroup_LPUART, 2), /*!< LPUART transmitter is idle. */
|
||||
kStatus_LPUART_RxIdle = MAKE_STATUS(kStatusGroup_LPUART, 3), /*!< LPUART receiver is idle. */
|
||||
kStatus_LPUART_TxWatermarkTooLarge = MAKE_STATUS(kStatusGroup_LPUART, 4), /*!< TX FIFO watermark too large */
|
||||
kStatus_LPUART_RxWatermarkTooLarge = MAKE_STATUS(kStatusGroup_LPUART, 5), /*!< RX FIFO watermark too large */
|
||||
kStatus_LPUART_FlagCannotClearManually = MAKE_STATUS(kStatusGroup_LPUART, 6), /*!< Some flag can't manually clear */
|
||||
kStatus_LPUART_Error = MAKE_STATUS(kStatusGroup_LPUART, 7), /*!< Error happens on LPUART. */
|
||||
kStatus_LPUART_RxRingBufferOverrun =
|
||||
MAKE_STATUS(kStatusGroup_LPUART, 8), /*!< LPUART RX software ring buffer overrun. */
|
||||
kStatus_LPUART_RxHardwareOverrun = MAKE_STATUS(kStatusGroup_LPUART, 9), /*!< LPUART RX receiver overrun. */
|
||||
kStatus_LPUART_NoiseError = MAKE_STATUS(kStatusGroup_LPUART, 10), /*!< LPUART noise error. */
|
||||
kStatus_LPUART_FramingError = MAKE_STATUS(kStatusGroup_LPUART, 11), /*!< LPUART framing error. */
|
||||
kStatus_LPUART_ParityError = MAKE_STATUS(kStatusGroup_LPUART, 12), /*!< LPUART parity error. */
|
||||
kStatus_LPUART_BaudrateNotSupport =
|
||||
MAKE_STATUS(kStatusGroup_LPUART, 13), /*!< Baudrate is not support in current clock source */
|
||||
kStatus_LPUART_IdleLineDetected = MAKE_STATUS(kStatusGroup_LPUART, 14), /*!< IDLE flag. */
|
||||
};
|
||||
|
||||
/*! @brief LPUART parity mode. */
|
||||
typedef enum _lpuart_parity_mode
|
||||
{
|
||||
kLPUART_ParityDisabled = 0x0U, /*!< Parity disabled */
|
||||
kLPUART_ParityEven = 0x2U, /*!< Parity enabled, type even, bit setting: PE|PT = 10 */
|
||||
kLPUART_ParityOdd = 0x3U, /*!< Parity enabled, type odd, bit setting: PE|PT = 11 */
|
||||
} lpuart_parity_mode_t;
|
||||
|
||||
/*! @brief LPUART data bits count. */
|
||||
typedef enum _lpuart_data_bits
|
||||
{
|
||||
kLPUART_EightDataBits = 0x0U, /*!< Eight data bit */
|
||||
#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT
|
||||
kLPUART_SevenDataBits = 0x1U, /*!< Seven data bit */
|
||||
#endif
|
||||
} lpuart_data_bits_t;
|
||||
|
||||
/*! @brief LPUART stop bit count. */
|
||||
typedef enum _lpuart_stop_bit_count
|
||||
{
|
||||
kLPUART_OneStopBit = 0U, /*!< One stop bit */
|
||||
kLPUART_TwoStopBit = 1U, /*!< Two stop bits */
|
||||
} lpuart_stop_bit_count_t;
|
||||
|
||||
#if defined(FSL_FEATURE_LPUART_HAS_MODEM_SUPPORT) && FSL_FEATURE_LPUART_HAS_MODEM_SUPPORT
|
||||
/*! @brief LPUART transmit CTS source. */
|
||||
typedef enum _lpuart_transmit_cts_source
|
||||
{
|
||||
kLPUART_CtsSourcePin = 0U, /*!< CTS resource is the LPUART_CTS pin. */
|
||||
kLPUART_CtsSourceMatchResult = 1U, /*!< CTS resource is the match result. */
|
||||
} lpuart_transmit_cts_source_t;
|
||||
|
||||
/*! @brief LPUART transmit CTS configure. */
|
||||
typedef enum _lpuart_transmit_cts_config
|
||||
{
|
||||
kLPUART_CtsSampleAtStart = 0U, /*!< CTS input is sampled at the start of each character. */
|
||||
kLPUART_CtsSampleAtIdle = 1U, /*!< CTS input is sampled when the transmitter is idle */
|
||||
} lpuart_transmit_cts_config_t;
|
||||
#endif
|
||||
|
||||
/*! @brief LPUART idle flag type defines when the receiver starts counting. */
|
||||
typedef enum _lpuart_idle_type_select
|
||||
{
|
||||
kLPUART_IdleTypeStartBit = 0U, /*!< Start counting after a valid start bit. */
|
||||
kLPUART_IdleTypeStopBit = 1U, /*!< Start counting after a stop bit. */
|
||||
} lpuart_idle_type_select_t;
|
||||
|
||||
/*! @brief LPUART idle detected configuration.
|
||||
* This structure defines the number of idle characters that must be received before
|
||||
* the IDLE flag is set.
|
||||
*/
|
||||
typedef enum _lpuart_idle_config
|
||||
{
|
||||
kLPUART_IdleCharacter1 = 0U, /*!< the number of idle characters. */
|
||||
kLPUART_IdleCharacter2 = 1U, /*!< the number of idle characters. */
|
||||
kLPUART_IdleCharacter4 = 2U, /*!< the number of idle characters. */
|
||||
kLPUART_IdleCharacter8 = 3U, /*!< the number of idle characters. */
|
||||
kLPUART_IdleCharacter16 = 4U, /*!< the number of idle characters. */
|
||||
kLPUART_IdleCharacter32 = 5U, /*!< the number of idle characters. */
|
||||
kLPUART_IdleCharacter64 = 6U, /*!< the number of idle characters. */
|
||||
kLPUART_IdleCharacter128 = 7U, /*!< the number of idle characters. */
|
||||
} lpuart_idle_config_t;
|
||||
|
||||
/*!
|
||||
* @brief LPUART interrupt configuration structure, default settings all disabled.
|
||||
*
|
||||
* This structure contains the settings for all LPUART interrupt configurations.
|
||||
*/
|
||||
enum _lpuart_interrupt_enable
|
||||
{
|
||||
#if defined(FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT) && FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT
|
||||
kLPUART_LinBreakInterruptEnable = (LPUART_BAUD_LBKDIE_MASK >> 8), /*!< LIN break detect. */
|
||||
#endif
|
||||
kLPUART_RxActiveEdgeInterruptEnable = (LPUART_BAUD_RXEDGIE_MASK >> 8), /*!< Receive Active Edge. */
|
||||
kLPUART_TxDataRegEmptyInterruptEnable = (LPUART_CTRL_TIE_MASK), /*!< Transmit data register empty. */
|
||||
kLPUART_TransmissionCompleteInterruptEnable = (LPUART_CTRL_TCIE_MASK), /*!< Transmission complete. */
|
||||
kLPUART_RxDataRegFullInterruptEnable = (LPUART_CTRL_RIE_MASK), /*!< Receiver data register full. */
|
||||
kLPUART_IdleLineInterruptEnable = (LPUART_CTRL_ILIE_MASK), /*!< Idle line. */
|
||||
kLPUART_RxOverrunInterruptEnable = (LPUART_CTRL_ORIE_MASK), /*!< Receiver Overrun. */
|
||||
kLPUART_NoiseErrorInterruptEnable = (LPUART_CTRL_NEIE_MASK), /*!< Noise error flag. */
|
||||
kLPUART_FramingErrorInterruptEnable = (LPUART_CTRL_FEIE_MASK), /*!< Framing error flag. */
|
||||
kLPUART_ParityErrorInterruptEnable = (LPUART_CTRL_PEIE_MASK), /*!< Parity error flag. */
|
||||
#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
|
||||
kLPUART_TxFifoOverflowInterruptEnable = (LPUART_FIFO_TXOFE_MASK >> 8), /*!< Transmit FIFO Overflow. */
|
||||
kLPUART_RxFifoUnderflowInterruptEnable = (LPUART_FIFO_RXUFE_MASK >> 8), /*!< Receive FIFO Underflow. */
|
||||
#endif
|
||||
};
|
||||
|
||||
/*!
|
||||
* @brief LPUART status flags.
|
||||
*
|
||||
* This provides constants for the LPUART status flags for use in the LPUART functions.
|
||||
*/
|
||||
enum _lpuart_flags
|
||||
{
|
||||
kLPUART_TxDataRegEmptyFlag =
|
||||
(LPUART_STAT_TDRE_MASK), /*!< Transmit data register empty flag, sets when transmit buffer is empty */
|
||||
kLPUART_TransmissionCompleteFlag =
|
||||
(LPUART_STAT_TC_MASK), /*!< Transmission complete flag, sets when transmission activity complete */
|
||||
kLPUART_RxDataRegFullFlag =
|
||||
(LPUART_STAT_RDRF_MASK), /*!< Receive data register full flag, sets when the receive data buffer is full */
|
||||
kLPUART_IdleLineFlag = (LPUART_STAT_IDLE_MASK), /*!< Idle line detect flag, sets when idle line detected */
|
||||
kLPUART_RxOverrunFlag = (LPUART_STAT_OR_MASK), /*!< Receive Overrun, sets when new data is received before data is
|
||||
read from receive register */
|
||||
kLPUART_NoiseErrorFlag = (LPUART_STAT_NF_MASK), /*!< Receive takes 3 samples of each received bit. If any of these
|
||||
samples differ, noise flag sets */
|
||||
kLPUART_FramingErrorFlag =
|
||||
(LPUART_STAT_FE_MASK), /*!< Frame error flag, sets if logic 0 was detected where stop bit expected */
|
||||
kLPUART_ParityErrorFlag = (LPUART_STAT_PF_MASK), /*!< If parity enabled, sets upon parity error detection */
|
||||
#if defined(FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT) && FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT
|
||||
kLPUART_LinBreakFlag =
|
||||
(int)(LPUART_STAT_LBKDIF_MASK), /*!< LIN break detect interrupt flag, sets when LIN break char
|
||||
detected and LIN circuit enabled */
|
||||
#endif
|
||||
kLPUART_RxActiveEdgeFlag =
|
||||
(LPUART_STAT_RXEDGIF_MASK), /*!< Receive pin active edge interrupt flag, sets when active edge detected */
|
||||
kLPUART_RxActiveFlag =
|
||||
(LPUART_STAT_RAF_MASK), /*!< Receiver Active Flag (RAF), sets at beginning of valid start bit */
|
||||
#if defined(FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING) && FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING
|
||||
kLPUART_DataMatch1Flag = LPUART_STAT_MA1F_MASK, /*!< The next character to be read from LPUART_DATA matches MA1*/
|
||||
kLPUART_DataMatch2Flag = LPUART_STAT_MA2F_MASK, /*!< The next character to be read from LPUART_DATA matches MA2*/
|
||||
#endif
|
||||
#if defined(FSL_FEATURE_LPUART_HAS_EXTENDED_DATA_REGISTER_FLAGS) && FSL_FEATURE_LPUART_HAS_EXTENDED_DATA_REGISTER_FLAGS
|
||||
kLPUART_NoiseErrorInRxDataRegFlag =
|
||||
(LPUART_DATA_NOISY_MASK >> 10), /*!< NOISY bit, sets if noise detected in current data word */
|
||||
kLPUART_ParityErrorInRxDataRegFlag =
|
||||
(LPUART_DATA_PARITYE_MASK >> 10), /*!< PARITYE bit, sets if noise detected in current data word */
|
||||
#endif
|
||||
#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
|
||||
kLPUART_TxFifoEmptyFlag = (LPUART_FIFO_TXEMPT_MASK >> 16), /*!< TXEMPT bit, sets if transmit buffer is empty */
|
||||
kLPUART_RxFifoEmptyFlag = (LPUART_FIFO_RXEMPT_MASK >> 16), /*!< RXEMPT bit, sets if receive buffer is empty */
|
||||
kLPUART_TxFifoOverflowFlag =
|
||||
(LPUART_FIFO_TXOF_MASK >> 16), /*!< TXOF bit, sets if transmit buffer overflow occurred */
|
||||
kLPUART_RxFifoUnderflowFlag =
|
||||
(LPUART_FIFO_RXUF_MASK >> 16), /*!< RXUF bit, sets if receive buffer underflow occurred */
|
||||
#endif
|
||||
};
|
||||
|
||||
/*! @brief LPUART configuration structure. */
|
||||
typedef struct _lpuart_config
|
||||
{
|
||||
uint32_t baudRate_Bps; /*!< LPUART baud rate */
|
||||
lpuart_parity_mode_t parityMode; /*!< Parity mode, disabled (default), even, odd */
|
||||
lpuart_data_bits_t dataBitsCount; /*!< Data bits count, eight (default), seven */
|
||||
bool isMsb; /*!< Data bits order, LSB (default), MSB */
|
||||
#if defined(FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT) && FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT
|
||||
lpuart_stop_bit_count_t stopBitCount; /*!< Number of stop bits, 1 stop bit (default) or 2 stop bits */
|
||||
#endif
|
||||
#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
|
||||
uint8_t txFifoWatermark; /*!< TX FIFO watermark */
|
||||
uint8_t rxFifoWatermark; /*!< RX FIFO watermark */
|
||||
#endif
|
||||
#if defined(FSL_FEATURE_LPUART_HAS_MODEM_SUPPORT) && FSL_FEATURE_LPUART_HAS_MODEM_SUPPORT
|
||||
bool enableRxRTS; /*!< RX RTS enable */
|
||||
bool enableTxCTS; /*!< TX CTS enable */
|
||||
lpuart_transmit_cts_source_t txCtsSource; /*!< TX CTS source */
|
||||
lpuart_transmit_cts_config_t txCtsConfig; /*!< TX CTS configure */
|
||||
#endif
|
||||
lpuart_idle_type_select_t rxIdleType; /*!< RX IDLE type. */
|
||||
lpuart_idle_config_t rxIdleConfig; /*!< RX IDLE configuration. */
|
||||
bool enableTx; /*!< Enable TX */
|
||||
bool enableRx; /*!< Enable RX */
|
||||
} lpuart_config_t;
|
||||
|
||||
/*! @brief LPUART transfer structure. */
|
||||
typedef struct _lpuart_transfer
|
||||
{
|
||||
uint8_t *data; /*!< The buffer of data to be transfer.*/
|
||||
size_t dataSize; /*!< The byte count to be transfer. */
|
||||
} lpuart_transfer_t;
|
||||
|
||||
/* Forward declaration of the handle typedef. */
|
||||
typedef struct _lpuart_handle lpuart_handle_t;
|
||||
|
||||
/*! @brief LPUART transfer callback function. */
|
||||
typedef void (*lpuart_transfer_callback_t)(LPUART_Type *base, lpuart_handle_t *handle, status_t status, void *userData);
|
||||
|
||||
/*! @brief LPUART handle structure. */
|
||||
struct _lpuart_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. */
|
||||
|
||||
lpuart_transfer_callback_t callback; /*!< Callback function. */
|
||||
void *userData; /*!< LPUART callback function parameter.*/
|
||||
|
||||
volatile uint8_t txState; /*!< TX transfer state. */
|
||||
volatile uint8_t rxState; /*!< RX transfer state. */
|
||||
|
||||
#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT
|
||||
bool isSevenDataBits; /*!< Seven data bits flag. */
|
||||
#endif
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif /* _cplusplus */
|
||||
|
||||
#if defined(FSL_FEATURE_LPUART_HAS_GLOBAL) && FSL_FEATURE_LPUART_HAS_GLOBAL
|
||||
|
||||
/*!
|
||||
* @name Software Reset
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Resets the LPUART using software.
|
||||
*
|
||||
* This function resets all internal logic and registers except the Global Register.
|
||||
* Remains set until cleared by software.
|
||||
*
|
||||
* @param base LPUART peripheral base address.
|
||||
*/
|
||||
static inline void LPUART_SoftwareReset(LPUART_Type *base)
|
||||
{
|
||||
base->GLOBAL |= LPUART_GLOBAL_RST_MASK;
|
||||
base->GLOBAL &= ~LPUART_GLOBAL_RST_MASK;
|
||||
}
|
||||
/* @} */
|
||||
#endif /*FSL_FEATURE_LPUART_HAS_GLOBAL*/
|
||||
|
||||
/*!
|
||||
* @name Initialization and deinitialization
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Initializes an LPUART instance with the user configuration structure and the peripheral clock.
|
||||
*
|
||||
* This function configures the LPUART module with user-defined settings. Call the LPUART_GetDefaultConfig() function
|
||||
* to configure the configuration structure and get the default configuration.
|
||||
* The example below shows how to use this API to configure the LPUART.
|
||||
* @code
|
||||
* lpuart_config_t lpuartConfig;
|
||||
* lpuartConfig.baudRate_Bps = 115200U;
|
||||
* lpuartConfig.parityMode = kLPUART_ParityDisabled;
|
||||
* lpuartConfig.dataBitsCount = kLPUART_EightDataBits;
|
||||
* lpuartConfig.isMsb = false;
|
||||
* lpuartConfig.stopBitCount = kLPUART_OneStopBit;
|
||||
* lpuartConfig.txFifoWatermark = 0;
|
||||
* lpuartConfig.rxFifoWatermark = 1;
|
||||
* LPUART_Init(LPUART1, &lpuartConfig, 20000000U);
|
||||
* @endcode
|
||||
*
|
||||
* @param base LPUART peripheral base address.
|
||||
* @param config Pointer to a user-defined configuration structure.
|
||||
* @param srcClock_Hz LPUART clock source frequency in HZ.
|
||||
* @retval kStatus_LPUART_BaudrateNotSupport Baudrate is not support in current clock source.
|
||||
* @retval kStatus_Success LPUART initialize succeed
|
||||
*/
|
||||
status_t LPUART_Init(LPUART_Type *base, const lpuart_config_t *config, uint32_t srcClock_Hz);
|
||||
|
||||
/*!
|
||||
* @brief Deinitializes a LPUART instance.
|
||||
*
|
||||
* This function waits for transmit to complete, disables TX and RX, and disables the LPUART clock.
|
||||
*
|
||||
* @param base LPUART peripheral base address.
|
||||
*/
|
||||
void LPUART_Deinit(LPUART_Type *base);
|
||||
|
||||
/*!
|
||||
* @brief Gets the default configuration structure.
|
||||
*
|
||||
* This function initializes the LPUART configuration structure to a default value. The default
|
||||
* values are:
|
||||
* lpuartConfig->baudRate_Bps = 115200U;
|
||||
* lpuartConfig->parityMode = kLPUART_ParityDisabled;
|
||||
* lpuartConfig->dataBitsCount = kLPUART_EightDataBits;
|
||||
* lpuartConfig->isMsb = false;
|
||||
* lpuartConfig->stopBitCount = kLPUART_OneStopBit;
|
||||
* lpuartConfig->txFifoWatermark = 0;
|
||||
* lpuartConfig->rxFifoWatermark = 1;
|
||||
* lpuartConfig->rxIdleType = kLPUART_IdleTypeStartBit;
|
||||
* lpuartConfig->rxIdleConfig = kLPUART_IdleCharacter1;
|
||||
* lpuartConfig->enableTx = false;
|
||||
* lpuartConfig->enableRx = false;
|
||||
*
|
||||
* @param config Pointer to a configuration structure.
|
||||
*/
|
||||
void LPUART_GetDefaultConfig(lpuart_config_t *config);
|
||||
|
||||
/*!
|
||||
* @brief Sets the LPUART instance baudrate.
|
||||
*
|
||||
* This function configures the LPUART module baudrate. This function is used to update
|
||||
* the LPUART module baudrate after the LPUART module is initialized by the LPUART_Init.
|
||||
* @code
|
||||
* LPUART_SetBaudRate(LPUART1, 115200U, 20000000U);
|
||||
* @endcode
|
||||
*
|
||||
* @param base LPUART peripheral base address.
|
||||
* @param baudRate_Bps LPUART baudrate to be set.
|
||||
* @param srcClock_Hz LPUART clock source frequency in HZ.
|
||||
* @retval kStatus_LPUART_BaudrateNotSupport Baudrate is not supported in the current clock source.
|
||||
* @retval kStatus_Success Set baudrate succeeded.
|
||||
*/
|
||||
status_t LPUART_SetBaudRate(LPUART_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz);
|
||||
|
||||
/* @} */
|
||||
|
||||
/*!
|
||||
* @name Status
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Gets LPUART status flags.
|
||||
*
|
||||
* This function gets all LPUART status flags. The flags are returned as the logical
|
||||
* OR value of the enumerators @ref _lpuart_flags. To check for a specific status,
|
||||
* compare the return value with enumerators in the @ref _lpuart_flags.
|
||||
* For example, to check whether the TX is empty:
|
||||
* @code
|
||||
* if (kLPUART_TxDataRegEmptyFlag & LPUART_GetStatusFlags(LPUART1))
|
||||
* {
|
||||
* ...
|
||||
* }
|
||||
* @endcode
|
||||
*
|
||||
* @param base LPUART peripheral base address.
|
||||
* @return LPUART status flags which are ORed by the enumerators in the _lpuart_flags.
|
||||
*/
|
||||
uint32_t LPUART_GetStatusFlags(LPUART_Type *base);
|
||||
|
||||
/*!
|
||||
* @brief Clears status flags with a provided mask.
|
||||
*
|
||||
* This function clears LPUART status flags with a provided mask. Automatically cleared flags
|
||||
* can't be cleared by this function.
|
||||
* Flags that can only cleared or set by hardware are:
|
||||
* kLPUART_TxDataRegEmptyFlag, kLPUART_TransmissionCompleteFlag, kLPUART_RxDataRegFullFlag,
|
||||
* kLPUART_RxActiveFlag, kLPUART_NoiseErrorInRxDataRegFlag, kLPUART_ParityErrorInRxDataRegFlag,
|
||||
* kLPUART_TxFifoEmptyFlag,kLPUART_RxFifoEmptyFlag
|
||||
* Note: This API should be called when the Tx/Rx is idle, otherwise it takes no effects.
|
||||
*
|
||||
* @param base LPUART peripheral base address.
|
||||
* @param mask the status flags to be cleared. The user can use the enumerators in the
|
||||
* _lpuart_status_flag_t to do the OR operation and get the mask.
|
||||
* @return 0 succeed, others failed.
|
||||
* @retval kStatus_LPUART_FlagCannotClearManually The flag can't be cleared by this function but
|
||||
* it is cleared automatically by hardware.
|
||||
* @retval kStatus_Success Status in the mask are cleared.
|
||||
*/
|
||||
status_t LPUART_ClearStatusFlags(LPUART_Type *base, uint32_t mask);
|
||||
|
||||
/* @} */
|
||||
|
||||
/*!
|
||||
* @name Interrupts
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Enables LPUART interrupts according to a provided mask.
|
||||
*
|
||||
* This function enables the LPUART interrupts according to a provided mask. The mask
|
||||
* is a logical OR of enumeration members. See the @ref _lpuart_interrupt_enable.
|
||||
* This examples shows how to enable TX empty interrupt and RX full interrupt:
|
||||
* @code
|
||||
* LPUART_EnableInterrupts(LPUART1,kLPUART_TxDataRegEmptyInterruptEnable | kLPUART_RxDataRegFullInterruptEnable);
|
||||
* @endcode
|
||||
*
|
||||
* @param base LPUART peripheral base address.
|
||||
* @param mask The interrupts to enable. Logical OR of @ref _uart_interrupt_enable.
|
||||
*/
|
||||
void LPUART_EnableInterrupts(LPUART_Type *base, uint32_t mask);
|
||||
|
||||
/*!
|
||||
* @brief Disables LPUART interrupts according to a provided mask.
|
||||
*
|
||||
* This function disables the LPUART interrupts according to a provided mask. The mask
|
||||
* is a logical OR of enumeration members. See @ref _lpuart_interrupt_enable.
|
||||
* This example shows how to disable the TX empty interrupt and RX full interrupt:
|
||||
* @code
|
||||
* LPUART_DisableInterrupts(LPUART1,kLPUART_TxDataRegEmptyInterruptEnable | kLPUART_RxDataRegFullInterruptEnable);
|
||||
* @endcode
|
||||
*
|
||||
* @param base LPUART peripheral base address.
|
||||
* @param mask The interrupts to disable. Logical OR of @ref _lpuart_interrupt_enable.
|
||||
*/
|
||||
void LPUART_DisableInterrupts(LPUART_Type *base, uint32_t mask);
|
||||
|
||||
/*!
|
||||
* @brief Gets enabled LPUART interrupts.
|
||||
*
|
||||
* This function gets the enabled LPUART interrupts. The enabled interrupts are returned
|
||||
* as the logical OR value of the enumerators @ref _lpuart_interrupt_enable. To check
|
||||
* a specific interrupt enable status, compare the return value with enumerators
|
||||
* in @ref _lpuart_interrupt_enable.
|
||||
* For example, to check whether the TX empty interrupt is enabled:
|
||||
* @code
|
||||
* uint32_t enabledInterrupts = LPUART_GetEnabledInterrupts(LPUART1);
|
||||
*
|
||||
* if (kLPUART_TxDataRegEmptyInterruptEnable & enabledInterrupts)
|
||||
* {
|
||||
* ...
|
||||
* }
|
||||
* @endcode
|
||||
*
|
||||
* @param base LPUART peripheral base address.
|
||||
* @return LPUART interrupt flags which are logical OR of the enumerators in @ref _lpuart_interrupt_enable.
|
||||
*/
|
||||
uint32_t LPUART_GetEnabledInterrupts(LPUART_Type *base);
|
||||
|
||||
#if defined(FSL_FEATURE_LPUART_HAS_DMA_ENABLE) && FSL_FEATURE_LPUART_HAS_DMA_ENABLE
|
||||
/*!
|
||||
* @brief Gets the LPUART data register address.
|
||||
*
|
||||
* This function returns the LPUART data register address, which is mainly used by the DMA/eDMA.
|
||||
*
|
||||
* @param base LPUART peripheral base address.
|
||||
* @return LPUART data register addresses which are used both by the transmitter and receiver.
|
||||
*/
|
||||
static inline uint32_t LPUART_GetDataRegisterAddress(LPUART_Type *base)
|
||||
{
|
||||
return (uint32_t) & (base->DATA);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Enables or disables the LPUART transmitter DMA request.
|
||||
*
|
||||
* This function enables or disables the transmit data register empty flag, STAT[TDRE], to generate DMA requests.
|
||||
*
|
||||
* @param base LPUART peripheral base address.
|
||||
* @param enable True to enable, false to disable.
|
||||
*/
|
||||
static inline void LPUART_EnableTxDMA(LPUART_Type *base, bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
base->BAUD |= LPUART_BAUD_TDMAE_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
base->BAUD &= ~LPUART_BAUD_TDMAE_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Enables or disables the LPUART receiver DMA.
|
||||
*
|
||||
* This function enables or disables the receiver data register full flag, STAT[RDRF], to generate DMA requests.
|
||||
*
|
||||
* @param base LPUART peripheral base address.
|
||||
* @param enable True to enable, false to disable.
|
||||
*/
|
||||
static inline void LPUART_EnableRxDMA(LPUART_Type *base, bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
base->BAUD |= LPUART_BAUD_RDMAE_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
base->BAUD &= ~LPUART_BAUD_RDMAE_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
/* @} */
|
||||
#endif /* FSL_FEATURE_LPUART_HAS_DMA_ENABLE */
|
||||
|
||||
/*!
|
||||
* @name Bus Operations
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Get the LPUART instance from peripheral base address.
|
||||
*
|
||||
* @param base LPUART peripheral base address.
|
||||
* @return LPUART instance.
|
||||
*/
|
||||
uint32_t LPUART_GetInstance(LPUART_Type *base);
|
||||
|
||||
/*!
|
||||
* @brief Enables or disables the LPUART transmitter.
|
||||
*
|
||||
* This function enables or disables the LPUART transmitter.
|
||||
*
|
||||
* @param base LPUART peripheral base address.
|
||||
* @param enable True to enable, false to disable.
|
||||
*/
|
||||
static inline void LPUART_EnableTx(LPUART_Type *base, bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
base->CTRL |= LPUART_CTRL_TE_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
base->CTRL &= ~LPUART_CTRL_TE_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Enables or disables the LPUART receiver.
|
||||
*
|
||||
* This function enables or disables the LPUART receiver.
|
||||
*
|
||||
* @param base LPUART peripheral base address.
|
||||
* @param enable True to enable, false to disable.
|
||||
*/
|
||||
static inline void LPUART_EnableRx(LPUART_Type *base, bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
base->CTRL |= LPUART_CTRL_RE_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
base->CTRL &= ~LPUART_CTRL_RE_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Writes to the transmitter register.
|
||||
*
|
||||
* This function writes data to the transmitter register directly. The upper layer must
|
||||
* ensure that the TX register is empty or that the TX FIFO has room before calling this function.
|
||||
*
|
||||
* @param base LPUART peripheral base address.
|
||||
* @param data Data write to the TX register.
|
||||
*/
|
||||
static inline void LPUART_WriteByte(LPUART_Type *base, uint8_t data)
|
||||
{
|
||||
base->DATA = data;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Reads the receiver register.
|
||||
*
|
||||
* This function reads data from the receiver register directly. The upper layer must
|
||||
* ensure that the receiver register is full or that the RX FIFO has data before calling this function.
|
||||
*
|
||||
* @param base LPUART peripheral base address.
|
||||
* @return Data read from data register.
|
||||
*/
|
||||
static inline uint8_t LPUART_ReadByte(LPUART_Type *base)
|
||||
{
|
||||
#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT
|
||||
uint32_t ctrl = base->CTRL;
|
||||
bool isSevenDataBits =
|
||||
((ctrl & LPUART_CTRL_M7_MASK) ||
|
||||
((!(ctrl & LPUART_CTRL_M7_MASK)) && (!(ctrl & LPUART_CTRL_M_MASK)) && (ctrl & LPUART_CTRL_PE_MASK)));
|
||||
|
||||
if (isSevenDataBits)
|
||||
{
|
||||
return (base->DATA & 0x7F);
|
||||
}
|
||||
else
|
||||
{
|
||||
return base->DATA;
|
||||
}
|
||||
#else
|
||||
return base->DATA;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Writes to the transmitter register using a blocking method.
|
||||
*
|
||||
* This function polls the transmitter register, waits for the register to be empty or for TX FIFO to have
|
||||
* room, and writes data to the transmitter buffer.
|
||||
*
|
||||
* @note This function does not check whether all data has been sent out to the bus.
|
||||
* Before disabling the transmitter, check the kLPUART_TransmissionCompleteFlag to ensure that the transmit is
|
||||
* finished.
|
||||
*
|
||||
* @param base LPUART peripheral base address.
|
||||
* @param data Start address of the data to write.
|
||||
* @param length Size of the data to write.
|
||||
*/
|
||||
void LPUART_WriteBlocking(LPUART_Type *base, const uint8_t *data, size_t length);
|
||||
|
||||
/*!
|
||||
* @brief Reads the receiver data register using a blocking method.
|
||||
*
|
||||
* This function polls the receiver register, waits for the receiver register full or receiver FIFO
|
||||
* has data, and reads data from the TX register.
|
||||
*
|
||||
* @param base LPUART peripheral base address.
|
||||
* @param data Start address of the buffer to store the received data.
|
||||
* @param length Size of the buffer.
|
||||
* @retval kStatus_LPUART_RxHardwareOverrun Receiver overrun happened while receiving data.
|
||||
* @retval kStatus_LPUART_NoiseError Noise error happened while receiving data.
|
||||
* @retval kStatus_LPUART_FramingError Framing error happened while receiving data.
|
||||
* @retval kStatus_LPUART_ParityError Parity error happened while receiving data.
|
||||
* @retval kStatus_Success Successfully received all data.
|
||||
*/
|
||||
status_t LPUART_ReadBlocking(LPUART_Type *base, uint8_t *data, size_t length);
|
||||
|
||||
/* @} */
|
||||
|
||||
/*!
|
||||
* @name Transactional
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Initializes the LPUART handle.
|
||||
*
|
||||
* This function initializes the LPUART handle, which can be used for other LPUART
|
||||
* transactional APIs. Usually, for a specified LPUART instance,
|
||||
* call this API once to get the initialized handle.
|
||||
*
|
||||
* The LPUART driver supports the "background" receiving, which means that user can set up
|
||||
* an RX ring buffer optionally. Data received is stored into the ring buffer even when the
|
||||
* user doesn't call the LPUART_TransferReceiveNonBlocking() API. If there is already data received
|
||||
* in the ring buffer, the user can get the received data from the ring buffer directly.
|
||||
* The ring buffer is disabled if passing NULL as @p ringBuffer.
|
||||
*
|
||||
* @param base LPUART peripheral base address.
|
||||
* @param handle LPUART handle pointer.
|
||||
* @param callback Callback function.
|
||||
* @param userData User data.
|
||||
*/
|
||||
void LPUART_TransferCreateHandle(LPUART_Type *base,
|
||||
lpuart_handle_t *handle,
|
||||
lpuart_transfer_callback_t callback,
|
||||
void *userData);
|
||||
/*!
|
||||
* @brief Transmits a buffer of data using the interrupt method.
|
||||
*
|
||||
* This function send data using an interrupt method. This is a non-blocking function, which
|
||||
* returns directly without waiting for all data written to the transmitter register. When
|
||||
* all data is written to the TX register in the ISR, the LPUART driver calls the callback
|
||||
* function and passes the @ref kStatus_LPUART_TxIdle as status parameter.
|
||||
*
|
||||
* @note The kStatus_LPUART_TxIdle is passed to the upper layer when all data are written
|
||||
* to the TX register. However, there is no check to ensure that all the data sent out. Before disabling the TX,
|
||||
* check the kLPUART_TransmissionCompleteFlag to ensure that the transmit is finished.
|
||||
*
|
||||
* @param base LPUART peripheral base address.
|
||||
* @param handle LPUART handle pointer.
|
||||
* @param xfer LPUART transfer structure, see #lpuart_transfer_t.
|
||||
* @retval kStatus_Success Successfully start the data transmission.
|
||||
* @retval kStatus_LPUART_TxBusy Previous transmission still not finished, data not all written to the TX register.
|
||||
* @retval kStatus_InvalidArgument Invalid argument.
|
||||
*/
|
||||
status_t LPUART_TransferSendNonBlocking(LPUART_Type *base, lpuart_handle_t *handle, lpuart_transfer_t *xfer);
|
||||
|
||||
/*!
|
||||
* @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 is stored into the ring buffer even when
|
||||
* the user doesn't call the UART_TransferReceiveNonBlocking() API. If there is already data received
|
||||
* in the ring buffer, the user can get the received data from the ring buffer directly.
|
||||
*
|
||||
* @note When using RX ring buffer, one byte is reserved for internal use. In other
|
||||
* words, if @p ringBufferSize is 32, then only 31 bytes are used for saving data.
|
||||
*
|
||||
* @param base LPUART peripheral base address.
|
||||
* @param handle LPUART handle pointer.
|
||||
* @param ringBuffer Start address of ring buffer for background receiving. Pass NULL to disable the ring buffer.
|
||||
* @param ringBufferSize size of the ring buffer.
|
||||
*/
|
||||
void LPUART_TransferStartRingBuffer(LPUART_Type *base,
|
||||
lpuart_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 LPUART peripheral base address.
|
||||
* @param handle LPUART handle pointer.
|
||||
*/
|
||||
void LPUART_TransferStopRingBuffer(LPUART_Type *base, lpuart_handle_t *handle);
|
||||
|
||||
/*!
|
||||
* @brief Get the length of received data in RX ring buffer.
|
||||
*
|
||||
* @param handle LPUART handle pointer.
|
||||
* @return Length of received data in RX ring buffer.
|
||||
*/
|
||||
size_t LPUART_TransferGetRxRingBufferLength(LPUART_Type *base, lpuart_handle_t *handle);
|
||||
|
||||
/*!
|
||||
* @brief Aborts the interrupt-driven data transmit.
|
||||
*
|
||||
* This function aborts the interrupt driven data sending. The user can get the remainBtyes to find out
|
||||
* how many bytes are not sent out.
|
||||
*
|
||||
* @param base LPUART peripheral base address.
|
||||
* @param handle LPUART handle pointer.
|
||||
*/
|
||||
void LPUART_TransferAbortSend(LPUART_Type *base, lpuart_handle_t *handle);
|
||||
|
||||
/*!
|
||||
* @brief Gets the number of bytes that have been written to the LPUART transmitter register.
|
||||
*
|
||||
* This function gets the number of bytes that have been written to LPUART TX
|
||||
* register by an interrupt method.
|
||||
*
|
||||
* @param base LPUART peripheral base address.
|
||||
* @param handle LPUART handle pointer.
|
||||
* @param count Send bytes count.
|
||||
* @retval kStatus_NoTransferInProgress No send in progress.
|
||||
* @retval kStatus_InvalidArgument Parameter is invalid.
|
||||
* @retval kStatus_Success Get successfully through the parameter \p count;
|
||||
*/
|
||||
status_t LPUART_TransferGetSendCount(LPUART_Type *base, lpuart_handle_t *handle, uint32_t *count);
|
||||
|
||||
/*!
|
||||
* @brief Receives a buffer of data using the interrupt method.
|
||||
*
|
||||
* This function receives data using an interrupt method. This is a non-blocking function
|
||||
* which returns without waiting to ensure that all data are 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 for read, the receive
|
||||
* request is saved by the LPUART driver. When the new data arrives, the receive request
|
||||
* is serviced first. When all data is received, the LPUART driver notifies the upper layer
|
||||
* through a callback function and passes a status parameter @ref kStatus_UART_RxIdle.
|
||||
* For example, the upper layer needs 10 bytes but there are only 5 bytes in ring buffer.
|
||||
* The 5 bytes are copied to xfer->data, which returns with the
|
||||
* parameter @p receivedBytes set to 5. For the remaining 5 bytes, the newly arrived data is
|
||||
* saved from xfer->data[5]. When 5 bytes are received, the LPUART 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 xfer->data. When all data is received, the upper layer is notified.
|
||||
*
|
||||
* @param base LPUART peripheral base address.
|
||||
* @param handle LPUART handle pointer.
|
||||
* @param xfer LPUART transfer structure, see #uart_transfer_t.
|
||||
* @param receivedBytes Bytes received from the ring buffer directly.
|
||||
* @retval kStatus_Success Successfully queue the transfer into the transmit queue.
|
||||
* @retval kStatus_LPUART_RxBusy Previous receive request is not finished.
|
||||
* @retval kStatus_InvalidArgument Invalid argument.
|
||||
*/
|
||||
status_t LPUART_TransferReceiveNonBlocking(LPUART_Type *base,
|
||||
lpuart_handle_t *handle,
|
||||
lpuart_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 find out
|
||||
* how many bytes not received yet.
|
||||
*
|
||||
* @param base LPUART peripheral base address.
|
||||
* @param handle LPUART handle pointer.
|
||||
*/
|
||||
void LPUART_TransferAbortReceive(LPUART_Type *base, lpuart_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 LPUART peripheral base address.
|
||||
* @param handle LPUART 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 LPUART_TransferGetReceiveCount(LPUART_Type *base, lpuart_handle_t *handle, uint32_t *count);
|
||||
|
||||
/*!
|
||||
* @brief LPUART IRQ handle function.
|
||||
*
|
||||
* This function handles the LPUART transmit and receive IRQ request.
|
||||
*
|
||||
* @param base LPUART peripheral base address.
|
||||
* @param handle LPUART handle pointer.
|
||||
*/
|
||||
void LPUART_TransferHandleIRQ(LPUART_Type *base, lpuart_handle_t *handle);
|
||||
|
||||
/*!
|
||||
* @brief LPUART Error IRQ handle function.
|
||||
*
|
||||
* This function handles the LPUART error IRQ request.
|
||||
*
|
||||
* @param base LPUART peripheral base address.
|
||||
* @param handle LPUART handle pointer.
|
||||
*/
|
||||
void LPUART_TransferHandleErrorIRQ(LPUART_Type *base, lpuart_handle_t *handle);
|
||||
|
||||
/* @} */
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
/*! @}*/
|
||||
|
||||
#endif /* _FSL_LPUART_H_ */
|
|
@ -0,0 +1,830 @@
|
|||
/*
|
||||
* Copyright 2017-2018 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
#ifndef _FSL_SEMC_H_
|
||||
#define _FSL_SEMC_H_
|
||||
|
||||
#include "fsl_common.h"
|
||||
|
||||
/*!
|
||||
* @addtogroup semc
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*! @name Driver version */
|
||||
/*@{*/
|
||||
/*! @brief SEMC driver version 2.0.4. */
|
||||
#define FSL_SEMC_DRIVER_VERSION (MAKE_VERSION(2, 0, 4))
|
||||
/*@}*/
|
||||
|
||||
/*! @brief SEMC status. */
|
||||
enum _semc_status
|
||||
{
|
||||
kStatus_SEMC_InvalidDeviceType = MAKE_STATUS(kStatusGroup_SEMC, 0),
|
||||
kStatus_SEMC_IpCommandExecutionError = MAKE_STATUS(kStatusGroup_SEMC, 1),
|
||||
kStatus_SEMC_AxiCommandExecutionError = MAKE_STATUS(kStatusGroup_SEMC, 2),
|
||||
kStatus_SEMC_InvalidMemorySize = MAKE_STATUS(kStatusGroup_SEMC, 3),
|
||||
kStatus_SEMC_InvalidIpcmdDataSize = MAKE_STATUS(kStatusGroup_SEMC, 4),
|
||||
kStatus_SEMC_InvalidAddressPortWidth = MAKE_STATUS(kStatusGroup_SEMC, 5),
|
||||
kStatus_SEMC_InvalidDataPortWidth = MAKE_STATUS(kStatusGroup_SEMC, 6),
|
||||
kStatus_SEMC_InvalidSwPinmuxSelection = MAKE_STATUS(kStatusGroup_SEMC, 7),
|
||||
kStatus_SEMC_InvalidBurstLength = MAKE_STATUS(kStatusGroup_SEMC, 8),
|
||||
kStatus_SEMC_InvalidColumnAddressBitWidth = MAKE_STATUS(kStatusGroup_SEMC, 9),
|
||||
kStatus_SEMC_InvalidBaseAddress = MAKE_STATUS(kStatusGroup_SEMC, 10),
|
||||
kStatus_SEMC_InvalidTimerSetting = MAKE_STATUS(kStatusGroup_SEMC, 11),
|
||||
};
|
||||
|
||||
/*! @brief SEMC memory device type. */
|
||||
typedef enum _semc_mem_type
|
||||
{
|
||||
kSEMC_MemType_SDRAM = 0, /*!< SDRAM */
|
||||
kSEMC_MemType_SRAM, /*!< SRAM */
|
||||
kSEMC_MemType_NOR, /*!< NOR */
|
||||
kSEMC_MemType_NAND, /*!< NAND */
|
||||
kSEMC_MemType_8080 /*!< 8080. */
|
||||
} semc_mem_type_t;
|
||||
|
||||
/*! @brief SEMC WAIT/RDY polarity. */
|
||||
typedef enum _semc_waitready_polarity
|
||||
{
|
||||
kSEMC_LowActive = 0, /*!< Low active. */
|
||||
kSEMC_HighActive, /*!< High active. */
|
||||
} semc_waitready_polarity_t;
|
||||
|
||||
/*! @brief SEMC SDRAM Chip selection . */
|
||||
typedef enum _semc_sdram_cs
|
||||
{
|
||||
kSEMC_SDRAM_CS0 = 0, /*!< SEMC SDRAM CS0. */
|
||||
kSEMC_SDRAM_CS1, /*!< SEMC SDRAM CS1. */
|
||||
kSEMC_SDRAM_CS2, /*!< SEMC SDRAM CS2. */
|
||||
kSEMC_SDRAM_CS3 /*!< SEMC SDRAM CS3. */
|
||||
} semc_sdram_cs_t;
|
||||
|
||||
/*! @brief SEMC NAND device type. */
|
||||
typedef enum _semc_nand_access_type
|
||||
{
|
||||
kSEMC_NAND_ACCESS_BY_AXI = 0,
|
||||
kSEMC_NAND_ACCESS_BY_IPCMD,
|
||||
} semc_nand_access_type_t;
|
||||
|
||||
/*! @brief SEMC interrupts . */
|
||||
typedef enum _semc_interrupt_enable
|
||||
{
|
||||
kSEMC_IPCmdDoneInterrupt = SEMC_INTEN_IPCMDDONEEN_MASK, /*!< Ip command done interrupt. */
|
||||
kSEMC_IPCmdErrInterrupt = SEMC_INTEN_IPCMDERREN_MASK, /*!< Ip command error interrupt. */
|
||||
kSEMC_AXICmdErrInterrupt = SEMC_INTEN_AXICMDERREN_MASK, /*!< AXI command error interrupt. */
|
||||
kSEMC_AXIBusErrInterrupt = SEMC_INTEN_AXIBUSERREN_MASK /*!< AXI bus error interrupt. */
|
||||
} semc_interrupt_enable_t;
|
||||
|
||||
/*! @brief SEMC IP command data size in bytes. */
|
||||
typedef enum _semc_ipcmd_datasize
|
||||
{
|
||||
kSEMC_IPcmdDataSize_1bytes = 1, /*!< The IP command data size 1 byte. */
|
||||
kSEMC_IPcmdDataSize_2bytes, /*!< The IP command data size 2 byte. */
|
||||
kSEMC_IPcmdDataSize_3bytes, /*!< The IP command data size 3 byte. */
|
||||
kSEMC_IPcmdDataSize_4bytes /*!< The IP command data size 4 byte. */
|
||||
} semc_ipcmd_datasize_t;
|
||||
|
||||
/*! @brief SEMC auto-refresh timing. */
|
||||
typedef enum _semc_refresh_time
|
||||
{
|
||||
kSEMC_RefreshThreeClocks = 0x0U, /*!< The refresh timing with three bus clocks. */
|
||||
kSEMC_RefreshSixClocks, /*!< The refresh timing with six bus clocks. */
|
||||
kSEMC_RefreshNineClocks /*!< The refresh timing with nine bus clocks. */
|
||||
} semc_refresh_time_t;
|
||||
|
||||
/*! @brief CAS latency */
|
||||
typedef enum _semc_caslatency
|
||||
{
|
||||
kSEMC_LatencyOne = 1, /*!< Latency 1. */
|
||||
kSEMC_LatencyTwo, /*!< Latency 2. */
|
||||
kSEMC_LatencyThree, /*!< Latency 3. */
|
||||
} semc_caslatency_t;
|
||||
|
||||
/*! @brief SEMC sdram column address bit number. */
|
||||
typedef enum _semc_sdram_column_bit_num
|
||||
{
|
||||
kSEMC_SdramColunm_12bit = 0x0U, /*!< 12 bit. */
|
||||
kSEMC_SdramColunm_11bit, /*!< 11 bit. */
|
||||
kSEMC_SdramColunm_10bit, /*!< 10 bit. */
|
||||
kSEMC_SdramColunm_9bit, /*!< 9 bit. */
|
||||
} semc_sdram_column_bit_num_t;
|
||||
|
||||
/*! @brief SEMC sdram burst length. */
|
||||
typedef enum _semc_sdram_burst_len
|
||||
{
|
||||
kSEMC_Sdram_BurstLen1 = 0, /*!< Burst length 1*/
|
||||
kSEMC_Sdram_BurstLen2, /*!< Burst length 2*/
|
||||
kSEMC_Sdram_BurstLen4, /*!< Burst length 4*/
|
||||
kSEMC_Sdram_BurstLen8 /*!< Burst length 8*/
|
||||
} sem_sdram_burst_len_t;
|
||||
|
||||
/*! @brief SEMC nand column address bit number. */
|
||||
typedef enum _semc_nand_column_bit_num
|
||||
{
|
||||
kSEMC_NandColum_16bit = 0x0U, /*!< 16 bit. */
|
||||
kSEMC_NandColum_15bit, /*!< 15 bit. */
|
||||
kSEMC_NandColum_14bit, /*!< 14 bit. */
|
||||
kSEMC_NandColum_13bit, /*!< 13 bit. */
|
||||
kSEMC_NandColum_12bit, /*!< 12 bit. */
|
||||
kSEMC_NandColum_11bit, /*!< 11 bit. */
|
||||
kSEMC_NandColum_10bit, /*!< 10 bit. */
|
||||
kSEMC_NandColum_9bit, /*!< 9 bit. */
|
||||
} semc_nand_column_bit_num_t;
|
||||
|
||||
/*! @brief SEMC nand burst length. */
|
||||
typedef enum _semc_nand_burst_len
|
||||
{
|
||||
kSEMC_Nand_BurstLen1 = 0, /*!< Burst length 1*/
|
||||
kSEMC_Nand_BurstLen2, /*!< Burst length 2*/
|
||||
kSEMC_Nand_BurstLen4, /*!< Burst length 4*/
|
||||
kSEMC_Nand_BurstLen8, /*!< Burst length 8*/
|
||||
kSEMC_Nand_BurstLen16, /*!< Burst length 16*/
|
||||
kSEMC_Nand_BurstLen32, /*!< Burst length 32*/
|
||||
kSEMC_Nand_BurstLen64 /*!< Burst length 64*/
|
||||
} sem_nand_burst_len_t;
|
||||
|
||||
/*! @brief SEMC nor/sram column address bit number. */
|
||||
typedef enum _semc_norsram_column_bit_num
|
||||
{
|
||||
kSEMC_NorColum_12bit = 0x0U, /*!< 12 bit. */
|
||||
kSEMC_NorColum_11bit, /*!< 11 bit. */
|
||||
kSEMC_NorColum_10bit, /*!< 10 bit. */
|
||||
kSEMC_NorColum_9bit, /*!< 9 bit. */
|
||||
kSEMC_NorColum_8bit, /*!< 8 bit. */
|
||||
kSEMC_NorColum_7bit, /*!< 7 bit. */
|
||||
kSEMC_NorColum_6bit, /*!< 6 bit. */
|
||||
kSEMC_NorColum_5bit, /*!< 5 bit. */
|
||||
kSEMC_NorColum_4bit, /*!< 4 bit. */
|
||||
kSEMC_NorColum_3bit, /*!< 3 bit. */
|
||||
kSEMC_NorColum_2bit /*!< 2 bit. */
|
||||
} semc_norsram_column_bit_num_t;
|
||||
|
||||
/*! @brief SEMC nor/sram burst length. */
|
||||
typedef enum _semc_norsram_burst_len
|
||||
{
|
||||
kSEMC_Nor_BurstLen1 = 0, /*!< Burst length 1*/
|
||||
kSEMC_Nor_BurstLen2, /*!< Burst length 2*/
|
||||
kSEMC_Nor_BurstLen4, /*!< Burst length 4*/
|
||||
kSEMC_Nor_BurstLen8, /*!< Burst length 8*/
|
||||
kSEMC_Nor_BurstLen16, /*!< Burst length 16*/
|
||||
kSEMC_Nor_BurstLen32, /*!< Burst length 32*/
|
||||
kSEMC_Nor_BurstLen64 /*!< Burst length 64*/
|
||||
} sem_norsram_burst_len_t;
|
||||
|
||||
/*! @brief SEMC dbi column address bit number. */
|
||||
typedef enum _semc_dbi_column_bit_num
|
||||
{
|
||||
kSEMC_Dbi_Colum_12bit = 0x0U, /*!< 12 bit. */
|
||||
kSEMC_Dbi_Colum_11bit, /*!< 11 bit. */
|
||||
kSEMC_Dbi_Colum_10bit, /*!< 10 bit. */
|
||||
kSEMC_Dbi_Colum_9bit, /*!< 9 bit. */
|
||||
kSEMC_Dbi_Colum_8bit, /*!< 8 bit. */
|
||||
kSEMC_Dbi_Colum_7bit, /*!< 7 bit. */
|
||||
kSEMC_Dbi_Colum_6bit, /*!< 6 bit. */
|
||||
kSEMC_Dbi_Colum_5bit, /*!< 5 bit. */
|
||||
kSEMC_Dbi_Colum_4bit, /*!< 4 bit. */
|
||||
kSEMC_Dbi_Colum_3bit, /*!< 3 bit. */
|
||||
kSEMC_Dbi_Colum_2bit /*!< 2 bit. */
|
||||
} semc_dbi_column_bit_num_t;
|
||||
|
||||
/*! @brief SEMC dbi burst length. */
|
||||
typedef enum _semc_dbi_burst_len
|
||||
{
|
||||
kSEMC_Dbi_BurstLen1 = 0, /*!< Burst length 1*/
|
||||
kSEMC_Dbi_BurstLen2, /*!< Burst length 2*/
|
||||
kSEMC_Dbi_Dbi_BurstLen4, /*!< Burst length 4*/
|
||||
kSEMC_Dbi_BurstLen8, /*!< Burst length 8*/
|
||||
kSEMC_Dbi_BurstLen16, /*!< Burst length 16*/
|
||||
kSEMC_Dbi_BurstLen32, /*!< Burst length 32*/
|
||||
kSEMC_Dbi_BurstLen64 /*!< Burst length 64*/
|
||||
} sem_dbi_burst_len_t;
|
||||
|
||||
/*! @brief SEMC IOMUXC. */
|
||||
typedef enum _semc_iomux_pin
|
||||
{
|
||||
kSEMC_MUXA8 = SEMC_IOCR_MUX_A8_SHIFT, /*!< MUX A8 pin. */
|
||||
kSEMC_MUXCSX0 = SEMC_IOCR_MUX_CSX0_SHIFT, /*!< MUX CSX0 pin */
|
||||
kSEMC_MUXCSX1 = SEMC_IOCR_MUX_CSX1_SHIFT, /*!< MUX CSX1 Pin.*/
|
||||
kSEMC_MUXCSX2 = SEMC_IOCR_MUX_CSX2_SHIFT, /*!< MUX CSX2 Pin. */
|
||||
kSEMC_MUXCSX3 = SEMC_IOCR_MUX_CSX3_SHIFT, /*!< MUX CSX3 Pin. */
|
||||
kSEMC_MUXRDY = SEMC_IOCR_MUX_RDY_SHIFT /*!< MUX RDY pin. */
|
||||
} semc_iomux_pin;
|
||||
|
||||
/*! @brief SEMC NOR/PSRAM Address bit 27 A27. */
|
||||
typedef enum _semc_iomux_nora27_pin
|
||||
{
|
||||
kSEMC_MORA27_NONE = 0, /*!< No NOR/SRAM A27 pin. */
|
||||
kSEMC_NORA27_MUXCSX3 = SEMC_IOCR_MUX_CSX3_SHIFT, /*!< MUX CSX3 Pin. */
|
||||
kSEMC_NORA27_MUXRDY = SEMC_IOCR_MUX_RDY_SHIFT /*!< MUX RDY pin. */
|
||||
} semc_iomux_nora27_pin;
|
||||
|
||||
/*! @brief SEMC port size. */
|
||||
typedef enum _semc_port_size
|
||||
{
|
||||
kSEMC_PortSize8Bit = 0, /*!< 8-Bit port size. */
|
||||
kSEMC_PortSize16Bit /*!< 16-Bit port size. */
|
||||
} smec_port_size_t;
|
||||
|
||||
/*! @brief SEMC address mode. */
|
||||
typedef enum _semc_addr_mode
|
||||
{
|
||||
kSEMC_AddrDataMux = 0, /*!< SEMC address/data mux mode. */
|
||||
kSEMC_AdvAddrdataMux, /*!< Advanced address/data mux mode. */
|
||||
kSEMC_AddrDataNonMux /*!< Address/data non-mux mode. */
|
||||
} semc_addr_mode_t;
|
||||
|
||||
/*! @brief SEMC DQS read strobe mode. */
|
||||
typedef enum _semc_dqs_mode
|
||||
{
|
||||
kSEMC_Loopbackinternal = 0, /*!< Dummy read strobe loopbacked internally. */
|
||||
kSEMC_Loopbackdqspad, /*!< Dummy read strobe loopbacked from DQS pad. */
|
||||
} semc_dqs_mode_t;
|
||||
|
||||
/*! @brief SEMC ADV signal active polarity. */
|
||||
typedef enum _semc_adv_polarity
|
||||
{
|
||||
kSEMC_AdvActiveLow = 0, /*!< Adv active low. */
|
||||
kSEMC_AdvActivehigh, /*!< Adv active low. */
|
||||
} semc_adv_polarity_t;
|
||||
|
||||
/*! @brief SEMC RDY signal active polarity. */
|
||||
typedef enum _semc_rdy_polarity
|
||||
{
|
||||
kSEMC_RdyActiveLow = 0, /*!< Adv active low. */
|
||||
kSEMC_RdyActivehigh, /*!< Adv active low. */
|
||||
} semc_rdy_polarity_t;
|
||||
|
||||
/*! @brief SEMC IP command for NAND: address mode. */
|
||||
typedef enum _semc_ipcmd_nand_addrmode
|
||||
{
|
||||
kSEMC_NANDAM_ColumnRow = 0x0U, /*!< Address mode: column and row address(5Byte-CA0/CA1/RA0/RA1/RA2). */
|
||||
kSEMC_NANDAM_ColumnCA0, /*!< Address mode: column address only(1 Byte-CA0). */
|
||||
kSEMC_NANDAM_ColumnCA0CA1, /*!< Address mode: column address only(2 Byte-CA0/CA1). */
|
||||
kSEMC_NANDAM_RawRA0, /*!< Address mode: row address only(1 Byte-RA0). */
|
||||
kSEMC_NANDAM_RawRA0RA1, /*!< Address mode: row address only(2 Byte-RA0/RA1). */
|
||||
kSEMC_NANDAM_RawRA0RA1RA2 /*!< Address mode: row address only(3 Byte-RA0). */
|
||||
} semc_ipcmd_nand_addrmode_t;
|
||||
|
||||
/*! @brief SEMC IP command for NAND: command mode. */
|
||||
typedef enum _semc_ipcmd_nand_cmdmode
|
||||
{
|
||||
kSEMC_NANDCM_Command = 0x2U, /*!< command. */
|
||||
kSEMC_NANDCM_CommandHold, /*!< Command hold. */
|
||||
kSEMC_NANDCM_CommandAddress, /*!< Command address. */
|
||||
kSEMC_NANDCM_CommandAddressHold, /*!< Command address hold. */
|
||||
kSEMC_NANDCM_CommandAddressRead, /*!< Command address read. */
|
||||
kSEMC_NANDCM_CommandAddressWrite, /*!< Command address write. */
|
||||
kSEMC_NANDCM_CommandRead, /*!< Command read. */
|
||||
kSEMC_NANDCM_CommandWrite, /*!< Command write. */
|
||||
kSEMC_NANDCM_Read, /*!< Read. */
|
||||
kSEMC_NANDCM_Write /*!< Write. */
|
||||
} semc_ipcmd_nand_cmdmode_t;
|
||||
|
||||
/*! @brief SEMC NAND address option. */
|
||||
typedef enum _semc_nand_address_option
|
||||
{
|
||||
kSEMC_NandAddrOption_5byte_CA2RA3 = 0U, /*!< CA0+CA1+RA0+RA1+RA2 */
|
||||
kSEMC_NandAddrOption_4byte_CA2RA2 = 2U, /*!< CA0+CA1+RA0+RA1 */
|
||||
kSEMC_NandAddrOption_3byte_CA2RA1 = 4U, /*!< CA0+CA1+RA0 */
|
||||
kSEMC_NandAddrOption_4byte_CA1RA3 = 1U, /*!< CA0+RA0+RA1+RA2 */
|
||||
kSEMC_NandAddrOption_3byte_CA1RA2 = 3U, /*!< CA0+RA0+RA1 */
|
||||
kSEMC_NandAddrOption_2byte_CA1RA1 = 7U, /*!< CA0+RA0 */
|
||||
} semc_nand_address_option_t;
|
||||
|
||||
/*! @brief SEMC IP command for NOR. */
|
||||
typedef enum _semc_ipcmd_nor_dbi
|
||||
{
|
||||
kSEMC_NORDBICM_Read = 0x2U, /*!< NOR read. */
|
||||
kSEMC_NORDBICM_Write /*!< NOR write. */
|
||||
} semc_ipcmd_nor_dbi_t;
|
||||
|
||||
/*! @brief SEMC IP command for SRAM. */
|
||||
typedef enum _semc_ipcmd_sram
|
||||
{
|
||||
kSEMC_SRAMCM_ArrayRead = 0x2U, /*!< SRAM memory array read. */
|
||||
kSEMC_SRAMCM_ArrayWrite, /*!< SRAM memory array write. */
|
||||
kSEMC_SRAMCM_RegRead, /*!< SRAM memory register read. */
|
||||
kSEMC_SRAMCM_RegWrite /*!< SRAM memory register write. */
|
||||
} semc_ipcmd_sram_t;
|
||||
|
||||
/*! @brief SEMC IP command for SDARM. */
|
||||
typedef enum _semc_ipcmd_sdram
|
||||
{
|
||||
kSEMC_SDRAMCM_Read = 0x8U, /*!< SDRAM memory read. */
|
||||
kSEMC_SDRAMCM_Write, /*!< SDRAM memory write. */
|
||||
kSEMC_SDRAMCM_Modeset, /*!< SDRAM MODE SET. */
|
||||
kSEMC_SDRAMCM_Active, /*!< SDRAM active. */
|
||||
kSEMC_SDRAMCM_AutoRefresh, /*!< SDRAM auto-refresh. */
|
||||
kSEMC_SDRAMCM_SelfRefresh, /*!< SDRAM self-refresh. */
|
||||
kSEMC_SDRAMCM_Precharge, /*!< SDRAM precharge. */
|
||||
kSEMC_SDRAMCM_Prechargeall /*!< SDRAM precharge all. */
|
||||
} semc_ipcmd_sdram_t;
|
||||
|
||||
/*! @brief SEMC SDRAM configuration structure.
|
||||
*
|
||||
* 1. The memory size in the configuration is in the unit of KB. So memsize_kbytes
|
||||
* should be set as 2^2, 2^3, 2^4 .etc which is base 2KB exponential function.
|
||||
* Take refer to BR0~BR3 register in RM for details.
|
||||
* 2. The prescalePeriod_N16Cycle is in unit of 16 clock cycle. It is a exception for prescaleTimer_n16cycle = 0,
|
||||
* it means the prescaler timer period is 256 * 16 clock cycles. For precalerIf precalerTimer_n16cycle not equal to 0,
|
||||
* The prescaler timer period is prescalePeriod_N16Cycle * 16 clock cycles.
|
||||
* idleTimeout_NprescalePeriod, refreshUrgThreshold_NprescalePeriod, refreshPeriod_NprescalePeriod are
|
||||
* similar to prescalePeriod_N16Cycle.
|
||||
*
|
||||
*/
|
||||
typedef struct _semc_sdram_config
|
||||
{
|
||||
semc_iomux_pin csxPinMux; /*!< CS pin mux. The kSEMC_MUXA8 is not valid in sdram pin mux setting. */
|
||||
uint32_t address; /*!< The base address. */
|
||||
uint32_t memsize_kbytes; /*!< The memory size in unit of kbytes. */
|
||||
smec_port_size_t portSize; /*!< Port size. */
|
||||
sem_sdram_burst_len_t burstLen; /*!< Burst length. */
|
||||
semc_sdram_column_bit_num_t columnAddrBitNum; /*!< Column address bit number. */
|
||||
semc_caslatency_t casLatency; /*!< CAS latency. */
|
||||
uint8_t tPrecharge2Act_Ns; /*!< Precharge to active wait time in unit of nanosecond. */
|
||||
uint8_t tAct2ReadWrite_Ns; /*!< Act to read/write wait time in unit of nanosecond. */
|
||||
uint8_t tRefreshRecovery_Ns; /*!< Refresh recovery time in unit of nanosecond. */
|
||||
uint8_t tWriteRecovery_Ns; /*!< write recovery time in unit of nanosecond. */
|
||||
uint8_t tCkeOff_Ns; /*!< CKE off minimum time in unit of nanosecond. */
|
||||
uint8_t tAct2Prechage_Ns; /*!< Active to precharge in unit of nanosecond. */
|
||||
uint8_t tSelfRefRecovery_Ns; /*!< Self refresh recovery time in unit of nanosecond. */
|
||||
uint8_t tRefresh2Refresh_Ns; /*!< Refresh to refresh wait time in unit of nanosecond. */
|
||||
uint8_t tAct2Act_Ns; /*!< Active to active wait time in unit of nanosecond. */
|
||||
uint32_t tPrescalePeriod_Ns; /*!< Prescaler timer period should not be larger than 256 * 16 * clock cycle. */
|
||||
uint32_t tIdleTimeout_Ns; /*!< Idle timeout in unit of prescale time period. */
|
||||
uint32_t refreshPeriod_nsPerRow; /*!< Refresh timer period like 64ms * 1000000/8192 . */
|
||||
uint32_t refreshUrgThreshold; /*!< Refresh urgent threshold. */
|
||||
uint8_t refreshBurstLen; /*!< Refresh burst length. */
|
||||
} semc_sdram_config_t;
|
||||
|
||||
/*! @brief SEMC NAND device timing configuration structure. */
|
||||
typedef struct _semc_nand_timing_config
|
||||
{
|
||||
uint8_t tCeSetup_Ns; /*!< CE setup time: tCS. */
|
||||
uint8_t tCeHold_Ns; /*!< CE hold time: tCH. */
|
||||
uint8_t tCeInterval_Ns; /*!< CE interval time:tCEITV. */
|
||||
uint8_t tWeLow_Ns; /*!< WE low time: tWP. */
|
||||
uint8_t tWeHigh_Ns; /*!< WE high time: tWH. */
|
||||
uint8_t tReLow_Ns; /*!< RE low time: tRP. */
|
||||
uint8_t tReHigh_Ns; /*!< RE high time: tREH. */
|
||||
uint8_t tTurnAround_Ns; /*!< Turnaround time for async mode: tTA. */
|
||||
uint8_t tWehigh2Relow_Ns; /*!< WE# high to RE# wait time: tWHR. */
|
||||
uint8_t tRehigh2Welow_Ns; /*!< RE# high to WE# low wait time: tRHW. */
|
||||
uint8_t tAle2WriteStart_Ns; /*!< ALE to write start wait time: tADL. */
|
||||
uint8_t tReady2Relow_Ns; /*!< Ready to RE# low min wait time: tRR. */
|
||||
uint8_t tWehigh2Busy_Ns; /*!< WE# high to busy wait time: tWB. */
|
||||
} semc_nand_timing_config_t;
|
||||
|
||||
/*! @brief SEMC NAND configuration structure. */
|
||||
typedef struct _semc_nand_config
|
||||
{
|
||||
semc_iomux_pin cePinMux; /*!< The CE pin mux setting. The kSEMC_MUXRDY is not valid for CE pin setting. */
|
||||
uint32_t axiAddress; /*!< The base address for AXI nand. */
|
||||
uint32_t axiMemsize_kbytes; /*!< The memory size in unit of kbytes for AXI nand. */
|
||||
uint32_t ipgAddress; /*!< The base address for IPG nand . */
|
||||
uint32_t ipgMemsize_kbytes; /*!< The memory size in unit of kbytes for IPG nand. */
|
||||
semc_rdy_polarity_t rdyactivePolarity; /*!< Wait ready polarity. */
|
||||
bool edoModeEnabled; /*!< EDO mode enabled. */
|
||||
semc_nand_column_bit_num_t columnAddrBitNum; /*!< Column address bit number. */
|
||||
semc_nand_address_option_t arrayAddrOption; /*!< Address option. */
|
||||
sem_nand_burst_len_t burstLen; /*!< Burst length. */
|
||||
smec_port_size_t portSize; /*!< Port size. */
|
||||
semc_nand_timing_config_t *timingConfig; /*!< SEMC nand timing configuration. */
|
||||
} semc_nand_config_t;
|
||||
|
||||
/*! @brief SEMC NOR configuration structure. */
|
||||
typedef struct _semc_nor_config
|
||||
{
|
||||
semc_iomux_pin cePinMux; /*!< The CE# pin mux setting. */
|
||||
semc_iomux_nora27_pin addr27; /*!< The Addr bit 27 pin mux setting. */
|
||||
uint32_t address; /*!< The base address. */
|
||||
uint32_t memsize_kbytes; /*!< The memory size in unit of kbytes. */
|
||||
uint8_t addrPortWidth; /*!< The address port width. */
|
||||
semc_rdy_polarity_t rdyactivePolarity; /*!< Wait ready polarity. */
|
||||
semc_adv_polarity_t advActivePolarity; /*!< ADV# polarity. */
|
||||
semc_norsram_column_bit_num_t columnAddrBitNum; /*!< Column address bit number. */
|
||||
semc_addr_mode_t addrMode; /*!< Address mode. */
|
||||
sem_norsram_burst_len_t burstLen; /*!< Burst length. */
|
||||
smec_port_size_t portSize; /*!< Port size. */
|
||||
uint8_t tCeSetup_Ns; /*!< The CE setup time. */
|
||||
uint8_t tCeHold_Ns; /*!< The CE hold time. */
|
||||
uint8_t tCeInterval_Ns; /*!< CE interval minimum time. */
|
||||
uint8_t tAddrSetup_Ns; /*!< The address setup time. */
|
||||
uint8_t tAddrHold_Ns; /*!< The address hold time. */
|
||||
uint8_t tWeLow_Ns; /*!< WE low time for async mode. */
|
||||
uint8_t tWeHigh_Ns; /*!< WE high time for async mode. */
|
||||
uint8_t tReLow_Ns; /*!< RE low time for async mode. */
|
||||
uint8_t tReHigh_Ns; /*!< RE high time for async mode. */
|
||||
uint8_t tTurnAround_Ns; /*!< Turnaround time for async mode. */
|
||||
uint8_t tAddr2WriteHold_Ns; /*!< Address to write data hold time for async mode. */
|
||||
#if defined(FSL_FEATURE_SEMC_HAS_NOR_WDS_TIME) && (FSL_FEATURE_SEMC_HAS_NOR_WDS_TIME)
|
||||
uint8_t tWriteSetup_Ns; /*!< Write data setup time for sync mode.*/
|
||||
#endif
|
||||
#if defined(FSL_FEATURE_SEMC_HAS_NOR_WDH_TIME) && (FSL_FEATURE_SEMC_HAS_NOR_WDH_TIME)
|
||||
uint8_t tWriteHold_Ns; /*!< Write hold time for sync mode. */
|
||||
#endif
|
||||
uint8_t latencyCount; /*!< Latency count for sync mode. */
|
||||
uint8_t readCycle; /*!< Read cycle time for sync mode. */
|
||||
} semc_nor_config_t;
|
||||
|
||||
/*! @brief SEMC SRAM configuration structure. */
|
||||
typedef struct _semc_sram_config
|
||||
{
|
||||
semc_iomux_pin cePinMux; /*!< The CE# pin mux setting. */
|
||||
semc_iomux_nora27_pin addr27; /*!< The Addr bit 27 pin mux setting. */
|
||||
uint32_t address; /*!< The base address. */
|
||||
uint32_t memsize_kbytes; /*!< The memory size in unit of kbytes. */
|
||||
uint8_t addrPortWidth; /*!< The address port width. */
|
||||
semc_adv_polarity_t advActivePolarity; /*!< ADV# polarity 1: active high, 0: active low. */
|
||||
semc_addr_mode_t addrMode; /*!< Address mode. */
|
||||
sem_norsram_burst_len_t burstLen; /*!< Burst length. */
|
||||
smec_port_size_t portSize; /*!< Port size. */
|
||||
uint8_t tCeSetup_Ns; /*!< The CE setup time. */
|
||||
uint8_t tCeHold_Ns; /*!< The CE hold time. */
|
||||
uint8_t tCeInterval_Ns; /*!< CE interval minimum time. */
|
||||
uint8_t tAddrSetup_Ns; /*!< The address setup time. */
|
||||
uint8_t tAddrHold_Ns; /*!< The address hold time. */
|
||||
uint8_t tWeLow_Ns; /*!< WE low time for async mode. */
|
||||
uint8_t tWeHigh_Ns; /*!< WE high time for async mode. */
|
||||
uint8_t tReLow_Ns; /*!< RE low time for async mode. */
|
||||
uint8_t tReHigh_Ns; /*!< RE high time for async mode. */
|
||||
uint8_t tTurnAround_Ns; /*!< Turnaround time for async mode. */
|
||||
uint8_t tAddr2WriteHold_Ns; /*!< Address to write data hold time for async mode. */
|
||||
uint8_t tWriteSetup_Ns; /*!< Write data setup time for sync mode.*/
|
||||
uint8_t tWriteHold_Ns; /*!< Write hold time for sync mode. */
|
||||
uint8_t latencyCount; /*!< Latency count for sync mode. */
|
||||
uint8_t readCycle; /*!< Read cycle time for sync mode. */
|
||||
} semc_sram_config_t;
|
||||
|
||||
/*! @brief SEMC DBI configuration structure. */
|
||||
typedef struct _semc_dbi_config
|
||||
{
|
||||
semc_iomux_pin csxPinMux; /*!< The CE# pin mux. */
|
||||
uint32_t address; /*!< The base address. */
|
||||
uint32_t memsize_kbytes; /*!< The memory size in unit of 4kbytes. */
|
||||
semc_dbi_column_bit_num_t columnAddrBitNum; /*!< Column address bit number. */
|
||||
sem_dbi_burst_len_t burstLen; /*!< Burst length. */
|
||||
smec_port_size_t portSize; /*!< Port size. */
|
||||
uint8_t tCsxSetup_Ns; /*!< The CSX setup time. */
|
||||
uint8_t tCsxHold_Ns; /*!< The CSX hold time. */
|
||||
uint8_t tWexLow_Ns; /*!< WEX low time. */
|
||||
uint8_t tWexHigh_Ns; /*!< WEX high time. */
|
||||
uint8_t tRdxLow_Ns; /*!< RDX low time. */
|
||||
uint8_t tRdxHigh_Ns; /*!< RDX high time. */
|
||||
uint8_t tCsxInterval_Ns; /*!< Write data setup time.*/
|
||||
} semc_dbi_config_t;
|
||||
|
||||
/*! @brief SEMC AXI queue a weight setting structure. */
|
||||
typedef struct _semc_queuea_weight_struct
|
||||
{
|
||||
uint32_t qos : 4; /*!< weight of qos for queue 0 . */
|
||||
uint32_t aging : 4; /*!< weight of aging for queue 0.*/
|
||||
uint32_t slaveHitSwith : 8; /*!< weight of read/write switch for queue 0.*/
|
||||
uint32_t slaveHitNoswitch : 8; /*!< weight of read/write no switch for queue 0 .*/
|
||||
} semc_queuea_weight_struct_t;
|
||||
|
||||
/*! @brief SEMC AXI queue a weight setting union. */
|
||||
typedef union _semc_queuea_weight
|
||||
{
|
||||
semc_queuea_weight_struct_t queueaConfig; /*!< Structure configuration for queueA. */
|
||||
uint32_t queueaValue; /*!< Configuration value for queueA which could directly write to the reg. */
|
||||
} semc_queuea_weight_t;
|
||||
|
||||
/*! @brief SEMC AXI queue b weight setting structure. */
|
||||
typedef struct _semc_queueb_weight_struct
|
||||
{
|
||||
uint32_t qos : 4; /*!< weight of qos for queue 1. */
|
||||
uint32_t aging : 4; /*!< weight of aging for queue 1.*/
|
||||
uint32_t slaveHitSwith : 8; /*!< weight of read/write switch for queue 1.*/
|
||||
uint32_t weightPagehit : 8; /*!< weight of page hit for queue 1 only .*/
|
||||
uint32_t bankRotation : 8; /*!< weight of bank rotation for queue 1 only .*/
|
||||
} semc_queueb_weight_struct_t;
|
||||
|
||||
/*! @brief SEMC AXI queue b weight setting union. */
|
||||
typedef union _semc_queueb_weight
|
||||
{
|
||||
semc_queueb_weight_struct_t queuebConfig; /*!< Structure configuration for queueB. */
|
||||
uint32_t queuebValue; /*!< Configuration value for queueB which could directly write to the reg. */
|
||||
} semc_queueb_weight_t;
|
||||
|
||||
/*! @brief SEMC AXI queue weight setting. */
|
||||
typedef struct _semc_axi_queueweight
|
||||
{
|
||||
semc_queuea_weight_t queueaWeight; /*!< Weight settings for queue a. */
|
||||
semc_queueb_weight_t queuebWeight; /*!< Weight settings for queue b. */
|
||||
} semc_axi_queueweight_t;
|
||||
|
||||
/*!
|
||||
* @brief SEMC configuration structure.
|
||||
*
|
||||
* busTimeoutCycles: when busTimeoutCycles is zero, the bus timeout cycle is
|
||||
* 255*1024. otherwise the bus timeout cycles is busTimeoutCycles*1024.
|
||||
* cmdTimeoutCycles: is used for command execution timeout cycles. it's
|
||||
* similar to the busTimeoutCycles.
|
||||
*/
|
||||
typedef struct _semc_config_t
|
||||
{
|
||||
semc_dqs_mode_t dqsMode; /*!< Dummy read strobe mode: use enum in "semc_dqs_mode_t". */
|
||||
uint8_t cmdTimeoutCycles; /*!< Command execution timeout cycles. */
|
||||
uint8_t busTimeoutCycles; /*!< Bus timeout cycles. */
|
||||
semc_axi_queueweight_t queueWeight; /*!< AXI queue weight. */
|
||||
} semc_config_t;
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @name SEMC Initialization and De-initialization
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Gets the SEMC default basic configuration structure.
|
||||
*
|
||||
* The purpose of this API is to get the default SEMC
|
||||
* configure structure for SEMC_Init(). User may use the initialized
|
||||
* structure unchanged in SEMC_Init(), or modify some fields of the
|
||||
* structure before calling SEMC_Init().
|
||||
* Example:
|
||||
@code
|
||||
semc_config_t config;
|
||||
SEMC_GetDefaultConfig(&config);
|
||||
@endcode
|
||||
* @param config The SEMC configuration structure pointer.
|
||||
*/
|
||||
void SEMC_GetDefaultConfig(semc_config_t *config);
|
||||
|
||||
/*!
|
||||
* @brief Initializes SEMC.
|
||||
* This function ungates the SEMC clock and initializes SEMC.
|
||||
* This function must be called before calling any other SEMC driver functions.
|
||||
*
|
||||
* @param base SEMC peripheral base address.
|
||||
* @param configure The SEMC configuration structure pointer.
|
||||
*/
|
||||
void SEMC_Init(SEMC_Type *base, semc_config_t *configure);
|
||||
|
||||
/*!
|
||||
* @brief Deinitializes the SEMC module and gates the clock.
|
||||
*
|
||||
* This function gates the SEMC clock. As a result, the SEMC module doesn't work after
|
||||
* calling this function, for some IDE, calling this API may cause the next downloading
|
||||
* operation failed. so, please call this API cautiously. Additional, users can
|
||||
* using "#define FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL (1)" to disable the clock control
|
||||
* operation in drivers.
|
||||
*
|
||||
* @param base SEMC peripheral base address.
|
||||
*/
|
||||
void SEMC_Deinit(SEMC_Type *base);
|
||||
|
||||
/* @} */
|
||||
|
||||
/*!
|
||||
* @name SEMC Configuration Operation For Each Memory Type
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Configures SDRAM controller in SEMC.
|
||||
*
|
||||
* @param base SEMC peripheral base address.
|
||||
* @param cs The chip selection.
|
||||
* @param config The sdram configuration.
|
||||
* @param clkSrc_Hz The SEMC clock frequency.
|
||||
*/
|
||||
status_t SEMC_ConfigureSDRAM(SEMC_Type *base, semc_sdram_cs_t cs, semc_sdram_config_t *config, uint32_t clkSrc_Hz);
|
||||
|
||||
/*!
|
||||
* @brief Configures NAND controller in SEMC.
|
||||
*
|
||||
* @param base SEMC peripheral base address.
|
||||
* @param config The nand configuration.
|
||||
* @param clkSrc_Hz The SEMC clock frequency.
|
||||
*/
|
||||
status_t SEMC_ConfigureNAND(SEMC_Type *base, semc_nand_config_t *config, uint32_t clkSrc_Hz);
|
||||
|
||||
/*!
|
||||
* @brief Configures NOR controller in SEMC.
|
||||
*
|
||||
* @param base SEMC peripheral base address.
|
||||
* @param config The nor configuration.
|
||||
* @param clkSrc_Hz The SEMC clock frequency.
|
||||
*/
|
||||
status_t SEMC_ConfigureNOR(SEMC_Type *base, semc_nor_config_t *config, uint32_t clkSrc_Hz);
|
||||
|
||||
/*!
|
||||
* @brief Configures SRAM controller in SEMC.
|
||||
*
|
||||
* @param base SEMC peripheral base address.
|
||||
* @param config The sram configuration.
|
||||
* @param clkSrc_Hz The SEMC clock frequency.
|
||||
*/
|
||||
status_t SEMC_ConfigureSRAM(SEMC_Type *base, semc_sram_config_t *config, uint32_t clkSrc_Hz);
|
||||
|
||||
/*!
|
||||
* @brief Configures DBI controller in SEMC.
|
||||
*
|
||||
* @param base SEMC peripheral base address.
|
||||
* @param config The dbi configuration.
|
||||
* @param clkSrc_Hz The SEMC clock frequency.
|
||||
*/
|
||||
status_t SEMC_ConfigureDBI(SEMC_Type *base, semc_dbi_config_t *config, uint32_t clkSrc_Hz);
|
||||
|
||||
/* @} */
|
||||
|
||||
/*!
|
||||
* @name SEMC Interrupt Operation
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Enables the SEMC interrupt.
|
||||
*
|
||||
* This function enables the SEMC interrupts according to the provided mask. The mask
|
||||
* is a logical OR of enumeration members. See @ref semc_interrupt_enable_t.
|
||||
* For example, to enable the IP command done and error interrupt, do the following.
|
||||
* @code
|
||||
* SEMC_EnableInterrupts(ENET, kSEMC_IPCmdDoneInterrupt | kSEMC_IPCmdErrInterrupt);
|
||||
* @endcode
|
||||
*
|
||||
* @param base SEMC peripheral base address.
|
||||
* @param mask SEMC interrupts to enable. This is a logical OR of the
|
||||
* enumeration :: semc_interrupt_enable_t.
|
||||
*/
|
||||
static inline void SEMC_EnableInterrupts(SEMC_Type *base, uint32_t mask)
|
||||
{
|
||||
base->INTEN |= mask;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Disables the SEMC interrupt.
|
||||
*
|
||||
* This function disables the SEMC interrupts according to the provided mask. The mask
|
||||
* is a logical OR of enumeration members. See @ref semc_interrupt_enable_t.
|
||||
* For example, to disable the IP command done and error interrupt, do the following.
|
||||
* @code
|
||||
* SEMC_DisableInterrupts(ENET, kSEMC_IPCmdDoneInterrupt | kSEMC_IPCmdErrInterrupt);
|
||||
* @endcode
|
||||
*
|
||||
* @param base SEMC peripheral base address.
|
||||
* @param mask SEMC interrupts to disable. This is a logical OR of the
|
||||
* enumeration :: semc_interrupt_enable_t.
|
||||
*/
|
||||
static inline void SEMC_DisableInterrupts(SEMC_Type *base, uint32_t mask)
|
||||
{
|
||||
base->INTEN &= ~mask;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Gets the SEMC status.
|
||||
*
|
||||
* This function gets the SEMC interrupts event status.
|
||||
* User can use the a logical OR of enumeration member as a mask.
|
||||
* See @ref semc_interrupt_enable_t.
|
||||
*
|
||||
* @param base SEMC peripheral base address.
|
||||
* @return status flag, use status flag in semc_interrupt_enable_t to get the related status.
|
||||
*/
|
||||
static inline bool SEMC_GetStatusFlag(SEMC_Type *base)
|
||||
{
|
||||
return base->INTR;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Clears the SEMC status flag state.
|
||||
*
|
||||
* The following status register flags can be cleared SEMC interrupt status.
|
||||
*
|
||||
* @param base SEMC base pointer
|
||||
* @param mask The status flag mask, a logical OR of enumeration member @ref semc_interrupt_enable_t.
|
||||
*/
|
||||
static inline void SEMC_ClearStatusFlags(SEMC_Type *base, uint32_t mask)
|
||||
{
|
||||
base->INTR |= mask;
|
||||
}
|
||||
|
||||
/* @} */
|
||||
|
||||
/*!
|
||||
* @name SEMC Memory Access Operation
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Check if SEMC is in idle.
|
||||
*
|
||||
* @param base SEMC peripheral base address.
|
||||
* @return True SEMC is in idle, false is not in idle.
|
||||
*/
|
||||
static inline bool SEMC_IsInIdle(SEMC_Type *base)
|
||||
{
|
||||
return (base->STS0 & SEMC_STS0_IDLE_MASK) ? true : false;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief SEMC IP command access.
|
||||
*
|
||||
* @param base SEMC peripheral base address.
|
||||
* @param type SEMC memory type. refer to "semc_mem_type_t"
|
||||
* @param address SEMC device address.
|
||||
* @param command SEMC IP command.
|
||||
* For NAND device, we should use the SEMC_BuildNandIPCommand to get the right nand command.
|
||||
* For NOR/DBI device, take refer to "semc_ipcmd_nor_dbi_t".
|
||||
* For SRAM device, take refer to "semc_ipcmd_sram_t".
|
||||
* For SDRAM device, take refer to "semc_ipcmd_sdram_t".
|
||||
* @param write Data for write access.
|
||||
* @param read Data pointer for read data out.
|
||||
*/
|
||||
status_t SEMC_SendIPCommand(
|
||||
SEMC_Type *base, semc_mem_type_t type, uint32_t address, uint16_t command, uint32_t write, uint32_t *read);
|
||||
|
||||
/*!
|
||||
* @brief Build SEMC IP command for NAND.
|
||||
*
|
||||
* This function build SEMC NAND IP command. The command is build of user command code,
|
||||
* SEMC address mode and SEMC command mode.
|
||||
*
|
||||
* @param userCommand NAND device normal command.
|
||||
* @param addrMode NAND address mode. Refer to "semc_ipcmd_nand_addrmode_t".
|
||||
* @param cmdMode NAND command mode. Refer to "semc_ipcmd_nand_cmdmode_t".
|
||||
*/
|
||||
static inline uint16_t SEMC_BuildNandIPCommand(uint8_t userCommand,
|
||||
semc_ipcmd_nand_addrmode_t addrMode,
|
||||
semc_ipcmd_nand_cmdmode_t cmdMode)
|
||||
{
|
||||
return (uint16_t)((uint16_t)userCommand << 8) | (uint16_t)(addrMode << 4) | ((uint8_t)cmdMode & 0x0Fu);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Check if the NAND device is ready.
|
||||
*
|
||||
* @param base SEMC peripheral base address.
|
||||
* @return True NAND is ready, false NAND is not ready.
|
||||
*/
|
||||
static inline bool SEMC_IsNandReady(SEMC_Type *base)
|
||||
{
|
||||
return (base->STS0 & SEMC_STS0_NARDY_MASK) ? true : false;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief SEMC NAND device memory write through IP command.
|
||||
*
|
||||
* @param base SEMC peripheral base address.
|
||||
* @param address SEMC NAND device address.
|
||||
* @param data Data for write access.
|
||||
* @param size_bytes Data length.
|
||||
*/
|
||||
status_t SEMC_IPCommandNandWrite(SEMC_Type *base, uint32_t address, uint8_t *data, uint32_t size_bytes);
|
||||
|
||||
/*!
|
||||
* @brief SEMC NAND device memory read through IP command.
|
||||
*
|
||||
* @param base SEMC peripheral base address.
|
||||
* @param address SEMC NAND device address.
|
||||
* @param data Data pointer for data read out.
|
||||
* @param size_bytes Data length.
|
||||
*/
|
||||
status_t SEMC_IPCommandNandRead(SEMC_Type *base, uint32_t address, uint8_t *data, uint32_t size_bytes);
|
||||
|
||||
/*!
|
||||
* @brief SEMC NOR device memory write through IP command.
|
||||
*
|
||||
* @param base SEMC peripheral base address.
|
||||
* @param address SEMC NOR device address.
|
||||
* @param data Data for write access.
|
||||
* @param size_bytes Data length.
|
||||
*/
|
||||
status_t SEMC_IPCommandNorWrite(SEMC_Type *base, uint32_t address, uint8_t *data, uint32_t size_bytes);
|
||||
|
||||
/*!
|
||||
* @brief SEMC NOR device memory read through IP command.
|
||||
*
|
||||
* @param base SEMC peripheral base address.
|
||||
* @param address SEMC NOR device address.
|
||||
* @param data Data pointer for data read out.
|
||||
* @param size_bytes Data length.
|
||||
*/
|
||||
status_t SEMC_IPCommandNorRead(SEMC_Type *base, uint32_t address, uint8_t *data, uint32_t size_bytes);
|
||||
|
||||
/* @} */
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
/*! @}*/
|
||||
|
||||
#endif /* _FSL_SEMC_H_*/
|
|
@ -0,0 +1,312 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2018 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
#ifndef _FSL_WDOG_H_
|
||||
#define _FSL_WDOG_H_
|
||||
|
||||
#include "fsl_common.h"
|
||||
|
||||
/*!
|
||||
* @addtogroup wdog
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
*******************************************************************************/
|
||||
/*! @name Driver version */
|
||||
/*@{*/
|
||||
/*! @brief Defines WDOG driver version */
|
||||
#define FSL_WDOG_DRIVER_VERSION (MAKE_VERSION(2, 1, 0))
|
||||
/*@}*/
|
||||
/*! @name Refresh sequence */
|
||||
/*@{*/
|
||||
#define WDOG_REFRESH_KEY (0xAAAA5555U)
|
||||
/*@}*/
|
||||
|
||||
/*! @brief Defines WDOG work mode. */
|
||||
typedef struct _wdog_work_mode
|
||||
{
|
||||
bool enableWait; /*!< continue or suspend WDOG in wait mode */
|
||||
bool enableStop; /*!< continue or suspend WDOG in stop mode */
|
||||
bool enableDebug; /*!< continue or suspend WDOG in debug mode */
|
||||
} wdog_work_mode_t;
|
||||
|
||||
/*! @brief Describes WDOG configuration structure. */
|
||||
typedef struct _wdog_config
|
||||
{
|
||||
bool enableWdog; /*!< Enables or disables WDOG */
|
||||
wdog_work_mode_t workMode; /*!< Configures WDOG work mode in debug stop and wait mode */
|
||||
bool enableInterrupt; /*!< Enables or disables WDOG interrupt */
|
||||
uint16_t timeoutValue; /*!< Timeout value */
|
||||
uint16_t interruptTimeValue; /*!< Interrupt count timeout value */
|
||||
bool softwareResetExtension; /*!< software reset extension */
|
||||
bool enablePowerDown; /*!< power down enable bit */
|
||||
bool enableTimeOutAssert; /*!< Enable WDOG_B timeout assertion. */
|
||||
} wdog_config_t;
|
||||
|
||||
/*!
|
||||
* @brief WDOG interrupt configuration structure, default settings all disabled.
|
||||
*
|
||||
* This structure contains the settings for all of the WDOG interrupt configurations.
|
||||
*/
|
||||
enum _wdog_interrupt_enable
|
||||
{
|
||||
kWDOG_InterruptEnable = WDOG_WICR_WIE_MASK /*!< WDOG timeout generates an interrupt before reset*/
|
||||
};
|
||||
|
||||
/*!
|
||||
* @brief WDOG status flags.
|
||||
*
|
||||
* This structure contains the WDOG status flags for use in the WDOG functions.
|
||||
*/
|
||||
enum _wdog_status_flags
|
||||
{
|
||||
kWDOG_RunningFlag = WDOG_WCR_WDE_MASK, /*!< Running flag, set when WDOG is enabled*/
|
||||
kWDOG_PowerOnResetFlag = WDOG_WRSR_POR_MASK, /*!< Power On flag, set when reset is the result of a powerOnReset*/
|
||||
kWDOG_TimeoutResetFlag = WDOG_WRSR_TOUT_MASK, /*!< Timeout flag, set when reset is the result of a timeout*/
|
||||
kWDOG_SoftwareResetFlag = WDOG_WRSR_SFTW_MASK, /*!< Software flag, set when reset is the result of a software*/
|
||||
kWDOG_InterruptFlag = WDOG_WICR_WTIS_MASK /*!< interrupt flag,whether interrupt has occurred or not*/
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
*******************************************************************************/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/*!
|
||||
* @name WDOG Initialization and De-initialization.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Initializes the WDOG configuration structure.
|
||||
*
|
||||
* This function initializes the WDOG configuration structure to default values. The default
|
||||
* values are as follows.
|
||||
* @code
|
||||
* wdogConfig->enableWdog = true;
|
||||
* wdogConfig->workMode.enableWait = true;
|
||||
* wdogConfig->workMode.enableStop = false;
|
||||
* wdogConfig->workMode.enableDebug = false;
|
||||
* wdogConfig->enableInterrupt = false;
|
||||
* wdogConfig->enablePowerdown = false;
|
||||
* wdogConfig->resetExtension = flase;
|
||||
* wdogConfig->timeoutValue = 0xFFU;
|
||||
* wdogConfig->interruptTimeValue = 0x04u;
|
||||
* @endcode
|
||||
*
|
||||
* @param config Pointer to the WDOG configuration structure.
|
||||
* @see wdog_config_t
|
||||
*/
|
||||
void WDOG_GetDefaultConfig(wdog_config_t *config);
|
||||
|
||||
/*!
|
||||
* @brief Initializes the WDOG.
|
||||
*
|
||||
* This function initializes the WDOG. When called, the WDOG runs according to the configuration.
|
||||
*
|
||||
* This is an example.
|
||||
* @code
|
||||
* wdog_config_t config;
|
||||
* WDOG_GetDefaultConfig(&config);
|
||||
* config.timeoutValue = 0xffU;
|
||||
* config->interruptTimeValue = 0x04u;
|
||||
* WDOG_Init(wdog_base,&config);
|
||||
* @endcode
|
||||
*
|
||||
* @param base WDOG peripheral base address
|
||||
* @param config The configuration of WDOG
|
||||
*/
|
||||
void WDOG_Init(WDOG_Type *base, const wdog_config_t *config);
|
||||
|
||||
/*!
|
||||
* @brief Shuts down the WDOG.
|
||||
*
|
||||
* This function shuts down the WDOG.
|
||||
* Watchdog Enable bit is a write one once only bit. It is not
|
||||
* possible to clear this bit by a software write, once the bit is set.
|
||||
* This bit(WDE) can be set/reset only in debug mode(exception).
|
||||
*/
|
||||
void WDOG_Deinit(WDOG_Type *base);
|
||||
|
||||
/*!
|
||||
* @brief Enables the WDOG module.
|
||||
*
|
||||
* This function writes a value into the WDOG_WCR register to enable the WDOG.
|
||||
* This is a write one once only bit. It is not possible to clear this bit by a software write,
|
||||
* once the bit is set. only debug mode exception.
|
||||
* @param base WDOG peripheral base address
|
||||
*/
|
||||
static inline void WDOG_Enable(WDOG_Type *base)
|
||||
{
|
||||
base->WCR |= WDOG_WCR_WDE_MASK;
|
||||
}
|
||||
|
||||
|
||||
static inline void SET_WDOG_WDT(WDOG_Type *base)
|
||||
{
|
||||
base->WCR |= WDOG_WCR_WDT_MASK;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
* @brief Disables the WDOG module.
|
||||
*
|
||||
* This function writes a value into the WDOG_WCR register to disable the WDOG.
|
||||
* This is a write one once only bit. It is not possible to clear this bit by a software write,once the bit is set.
|
||||
* only debug mode exception
|
||||
* @param base WDOG peripheral base address
|
||||
*/
|
||||
static inline void WDOG_Disable(WDOG_Type *base)
|
||||
{
|
||||
base->WCR &= ~WDOG_WCR_WDE_MASK;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Trigger the system software reset.
|
||||
*
|
||||
* This function will write to the WCR[SRS] bit to trigger a software system reset.
|
||||
* This bit will automatically resets to "1" after it has been asserted to "0".
|
||||
* Note: Calling this API will reset the system right now, please using it with more attention.
|
||||
*
|
||||
* @param base WDOG peripheral base address
|
||||
*/
|
||||
static inline void WDOG_TriggerSystemSoftwareReset(WDOG_Type *base)
|
||||
{
|
||||
base->WCR &= ~WDOG_WCR_SRS_MASK;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Trigger an output assertion.
|
||||
*
|
||||
* This function will write to the WCR[WDA] bit to trigger WDOG_B signal assertion.
|
||||
* The WDOG_B signal can be routed to external pin of the chip, the output pin will turn to
|
||||
* assertion along with WDOG_B signal.
|
||||
* Note: The WDOG_B signal will remain assert until a power on reset occurred, so, please
|
||||
* take more attention while calling it.
|
||||
*
|
||||
* @param base WDOG peripheral base address
|
||||
*/
|
||||
static inline void WDOG_TriggerSoftwareSignal(WDOG_Type *base)
|
||||
{
|
||||
base->WCR &= ~WDOG_WCR_WDA_MASK;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Enables the WDOG interrupt.
|
||||
*
|
||||
*This bit is a write once only bit. Once the software does a write access to this bit, it will get
|
||||
*locked and cannot be reprogrammed until the next system reset assertion
|
||||
*
|
||||
* @param base WDOG peripheral base address
|
||||
* @param mask The interrupts to enable
|
||||
* The parameter can be combination of the following source if defined.
|
||||
* @arg kWDOG_InterruptEnable
|
||||
*/
|
||||
static inline void WDOG_EnableInterrupts(WDOG_Type *base, uint16_t mask)
|
||||
{
|
||||
base->WICR |= mask;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Gets the WDOG all reset status flags.
|
||||
*
|
||||
* This function gets all reset status flags.
|
||||
*
|
||||
* @code
|
||||
* uint16_t status;
|
||||
* status = WDOG_GetStatusFlags (wdog_base);
|
||||
* @endcode
|
||||
* @param base WDOG peripheral base address
|
||||
* @return State of the status flag: asserted (true) or not-asserted (false).@see _wdog_status_flags
|
||||
* - true: a related status flag has been set.
|
||||
* - false: a related status flag is not set.
|
||||
*/
|
||||
uint16_t WDOG_GetStatusFlags(WDOG_Type *base);
|
||||
|
||||
/*!
|
||||
* @brief Clears the WDOG flag.
|
||||
*
|
||||
* This function clears the WDOG status flag.
|
||||
*
|
||||
* This is an example for clearing the interrupt flag.
|
||||
* @code
|
||||
* WDOG_ClearStatusFlags(wdog_base,KWDOG_InterruptFlag);
|
||||
* @endcode
|
||||
* @param base WDOG peripheral base address
|
||||
* @param mask The status flags to clear.
|
||||
* The parameter could be any combination of the following values.
|
||||
* kWDOG_TimeoutFlag
|
||||
*/
|
||||
void WDOG_ClearInterruptStatus(WDOG_Type *base, uint16_t mask);
|
||||
|
||||
/*!
|
||||
* @brief Sets the WDOG timeout value.
|
||||
*
|
||||
* This function sets the timeout value.
|
||||
* This function writes a value into WCR registers.
|
||||
* The time-out value can be written at any point of time but it is loaded to the counter at the time
|
||||
* when WDOG is enabled or after the service routine has been performed.
|
||||
*
|
||||
* @param base WDOG peripheral base address
|
||||
* @param timeoutCount WDOG timeout value; count of WDOG clock tick.
|
||||
*/
|
||||
static inline void WDOG_SetTimeoutValue(WDOG_Type *base, uint16_t timeoutCount)
|
||||
{
|
||||
base->WCR = (base->WCR & ~WDOG_WCR_WT_MASK) | WDOG_WCR_WT(timeoutCount);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Sets the WDOG interrupt count timeout value.
|
||||
*
|
||||
* This function sets the interrupt count timeout value.
|
||||
* This function writes a value into WIC registers which are wirte-once.
|
||||
* This field is write once only. Once the software does a write access to this field, it will get locked
|
||||
* and cannot be reprogrammed until the next system reset assertion.
|
||||
* @param base WDOG peripheral base address
|
||||
* @param timeoutCount WDOG timeout value; count of WDOG clock tick.
|
||||
*/
|
||||
static inline void WDOG_SetInterrputTimeoutValue(WDOG_Type *base, uint16_t timeoutCount)
|
||||
{
|
||||
base->WICR = (base->WICR & ~WDOG_WICR_WICT_MASK) | WDOG_WICR_WICT(timeoutCount);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Disable the WDOG power down enable bit.
|
||||
*
|
||||
* This function disable the WDOG power down enable(PDE).
|
||||
* This function writes a value into WMCR registers which are wirte-once.
|
||||
* This field is write once only. Once software sets this bit it cannot be reset until the next system reset.
|
||||
* @param base WDOG peripheral base address
|
||||
*/
|
||||
static inline void WDOG_DisablePowerDownEnable(WDOG_Type *base)
|
||||
{
|
||||
base->WMCR &= ~WDOG_WMCR_PDE_MASK;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Refreshes the WDOG timer.
|
||||
*
|
||||
* This function feeds the WDOG.
|
||||
* This function should be called before the WDOG timer is in timeout. Otherwise, a reset is asserted.
|
||||
*
|
||||
* @param base WDOG peripheral base address
|
||||
*/
|
||||
void WDOG_Refresh(WDOG_Type *base);
|
||||
/*@}*/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/*! @}*/
|
||||
|
||||
#endif /* _FSL_WDOG_H_ */
|
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
** ###################################################################
|
||||
** Processors: MIMXRT1052CVJ5B
|
||||
** MIMXRT1052CVL5B
|
||||
** MIMXRT1052DVJ6B
|
||||
** MIMXRT1052DVL6B
|
||||
**
|
||||
** Compilers: Freescale C/C++ for Embedded ARM
|
||||
** GNU C Compiler
|
||||
** IAR ANSI C/C++ Compiler for ARM
|
||||
** Keil ARM C/C++ Compiler
|
||||
** MCUXpresso Compiler
|
||||
**
|
||||
** Reference manual: IMXRT1050RM Rev.2.1, 12/2018
|
||||
** Version: rev. 1.2, 2018-11-27
|
||||
** Build: b181205
|
||||
**
|
||||
** 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-2018 NXP
|
||||
** All rights reserved.
|
||||
**
|
||||
** SPDX-License-Identifier: BSD-3-Clause
|
||||
**
|
||||
** http: www.nxp.com
|
||||
** mail: support@nxp.com
|
||||
**
|
||||
** Revisions:
|
||||
** - rev. 0.1 (2017-01-10)
|
||||
** Initial version.
|
||||
** - rev. 1.0 (2018-09-21)
|
||||
** Update interrupt vector table and dma request source.
|
||||
** Update register BEE_ADDR_OFFSET1's bitfield name to ADDR_OFFSET1.
|
||||
** Split GPIO_COMBINED_IRQS to GPIO_COMBINED_LOW_IRQS and GPIO_COMBINED_HIGH_IRQS.
|
||||
** - rev. 1.1 (2018-11-16)
|
||||
** Update header files to align with IMXRT1050RM Rev.1.
|
||||
** - rev. 1.2 (2018-11-27)
|
||||
** Update header files to align with IMXRT1050RM Rev.2.1.
|
||||
**
|
||||
** ###################################################################
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @file MIMXRT1052
|
||||
* @version 1.2
|
||||
* @date 2018-11-27
|
||||
* @brief Device specific configuration file for MIMXRT1052 (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_MIMXRT1052_H_
|
||||
#define _SYSTEM_MIMXRT1052_H_ /**< Symbol preventing repeated inclusion */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
#ifndef DISABLE_WDOG
|
||||
#define DISABLE_WDOG 1
|
||||
#endif
|
||||
|
||||
/* Define clock source values */
|
||||
|
||||
#define CPU_XTAL_CLK_HZ 24000000UL /* Value of the external crystal or oscillator clock frequency in Hz */
|
||||
|
||||
#define CPU_CLK1_HZ 0UL /* Value of the CLK1 (select the CLK1_N/CLK1_P as source) frequency in Hz */
|
||||
/* If CLOCK1_P,CLOCK1_N is choose as the pll bypass clock source, please implement the CLKPN_FREQ define, otherwise 0 will be returned. */
|
||||
|
||||
#define DEFAULT_SYSTEM_CLOCK 528000000UL /* 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_MIMXRT1052_H_ */
|
|
@ -0,0 +1,21 @@
|
|||
if BSP_USING_LCD
|
||||
config LCD_BUS_NAME
|
||||
string "lcd bus name"
|
||||
default "lcd"
|
||||
config LCD_DRV_NAME
|
||||
string "lcd bus driver name"
|
||||
default "lcd_drv"
|
||||
config LCD_DEVICE_NAME
|
||||
string "lcd bus device name"
|
||||
default "lcd_dev"
|
||||
config LCD_BL_GPIO_PIN
|
||||
int "BackLight pin number of rgb565 interface"
|
||||
default 31
|
||||
config BSP_LCD_X_MAX
|
||||
int "LCD Height"
|
||||
default 480
|
||||
config BSP_LCD_Y_MAX
|
||||
int "LCD Width"
|
||||
default 800
|
||||
|
||||
endif
|
|
@ -0,0 +1,4 @@
|
|||
SRC_FILES := connect_lcd.c fsl_elcdif.c
|
||||
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -0,0 +1,261 @@
|
|||
/*
|
||||
* Copyright (c) 2022 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 connect_lcd.c
|
||||
* @brief support imxrt1052 lcd function and register to bus framework
|
||||
* @version 2.0
|
||||
* @author AIIT XiUOS Lab
|
||||
* @date 2022-04-25
|
||||
*/
|
||||
|
||||
#include <connect_lcd.h>
|
||||
#include "fsl_common.h"
|
||||
#include "fsl_iomuxc.h"
|
||||
#include "fsl_elcdif.h"
|
||||
#include "fsl_gpio.h"
|
||||
|
||||
/* Back light. */
|
||||
#define LCD_BL_GPIO GPIO2
|
||||
#define LCD_HSW 20
|
||||
#define LCD_HFP 100
|
||||
#define LCD_HBP 26
|
||||
#define LCD_VSW 3
|
||||
#define LCD_VFP 22
|
||||
#define LCD_VBP 23
|
||||
|
||||
#define LCD_HEIGHT BSP_LCD_X_MAX
|
||||
#define LCD_WIDTH BSP_LCD_Y_MAX
|
||||
|
||||
|
||||
static uint16_t frame_buffer[LCD_HEIGHT][LCD_WIDTH] SECTION("NonCacheable.init");
|
||||
static void InitLcdifPixelClock(void)
|
||||
{
|
||||
/*
|
||||
* The desired output frame rate is 60Hz. So the pixel clock frequency is:
|
||||
* (480 + 41 + 4 + 18) * (272 + 10 + 4 + 2) * 60 = 9.2M.
|
||||
* Here set the LCDIF pixel clock to 9.3M.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Initialize the Video PLL.
|
||||
* Video PLL output clock is OSC24M * (loopDivider + (denominator / numerator)) / postDivider = 93MHz.
|
||||
*/
|
||||
clock_video_pll_config_t pll_config;
|
||||
|
||||
pll_config.loopDivider = 31;
|
||||
pll_config.postDivider = 4;
|
||||
pll_config.numerator = 0;
|
||||
pll_config.denominator = 0;
|
||||
|
||||
CLOCK_InitVideoPll(&pll_config);
|
||||
/*
|
||||
* 000 derive clock from PLL2
|
||||
* 001 derive clock from PLL3 PFD3
|
||||
* 010 derive clock from PLL5
|
||||
* 011 derive clock from PLL2 PFD0
|
||||
* 100 derive clock from PLL2 PFD1
|
||||
* 101 derive clock from PLL3 PFD1
|
||||
*/
|
||||
CLOCK_SetMux(kCLOCK_LcdifPreMux, 2);
|
||||
|
||||
CLOCK_SetDiv(kCLOCK_LcdifPreDiv, 2);
|
||||
|
||||
CLOCK_SetDiv(kCLOCK_LcdifDiv, 1);
|
||||
}
|
||||
|
||||
static void InitLcdBacklight(uint8_t level)
|
||||
{
|
||||
gpio_pin_config_t config = {
|
||||
kGPIO_DigitalOutput,
|
||||
0,
|
||||
};
|
||||
|
||||
/* Backlight. */
|
||||
config.outputLogic = level;
|
||||
GPIO_PinInit(LCD_BL_GPIO, LCD_BL_GPIO_PIN, &config);
|
||||
}
|
||||
|
||||
static void ELCDFramebuffSet(void)
|
||||
{
|
||||
/* LCD */
|
||||
elcdif_rgb_mode_config_t lcd_config;
|
||||
|
||||
lcd_config.panelWidth = LCD_WIDTH;
|
||||
lcd_config.panelHeight = LCD_HEIGHT;
|
||||
lcd_config.hsw = LCD_HSW;
|
||||
lcd_config.hfp = LCD_HFP;
|
||||
lcd_config.hbp = LCD_HBP;
|
||||
lcd_config.vsw = LCD_VSW;
|
||||
lcd_config.vfp = LCD_VFP;
|
||||
lcd_config.vbp = LCD_VBP;
|
||||
|
||||
lcd_config.polarityFlags = kELCDIF_DataEnableActiveHigh |
|
||||
kELCDIF_VsyncActiveLow |
|
||||
kELCDIF_HsyncActiveLow |
|
||||
kELCDIF_DriveDataOnRisingClkEdge;
|
||||
|
||||
lcd_config.bufferAddr = (uint32_t)frame_buffer;
|
||||
lcd_config.pixelFormat = kELCDIF_PixelFormatRGB565;
|
||||
lcd_config.dataBus = kELCDIF_DataBus16Bit;
|
||||
|
||||
ELCDIF_RgbModeInit (LCDIF, &lcd_config);
|
||||
}
|
||||
|
||||
static void HwLcdInit()
|
||||
{
|
||||
memset(frame_buffer, 0, sizeof(frame_buffer));
|
||||
|
||||
/*step1: config PLL clock */
|
||||
InitLcdifPixelClock();
|
||||
|
||||
/*step2: config backlight gpio*/
|
||||
InitLcdBacklight(GPIO_HIGH);
|
||||
|
||||
/*step3: fill framebuff*/
|
||||
ELCDFramebuffSet();
|
||||
|
||||
ELCDIF_RgbModeStart(LCDIF);
|
||||
|
||||
}
|
||||
static void DrvLcdSetPixelDot(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, void* color)
|
||||
{
|
||||
uint16_t i = 0;
|
||||
uint16_t j = 0;
|
||||
|
||||
for(i = y1; i <= y2; i++) {
|
||||
for(j = x1; j <= x2; j++) {
|
||||
frame_buffer[i][j] =(*(uint16_t*)color);
|
||||
color += sizeof(uint16_t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static uint32 LcdWrite(void *dev, struct BusBlockWriteParam *write_param)
|
||||
{
|
||||
x_err_t ret = EOK;
|
||||
|
||||
if (write_param->buffer)
|
||||
{
|
||||
LcdWriteParam *show = (LcdWriteParam *)write_param->buffer;
|
||||
//output string
|
||||
if(0 == show->type) {
|
||||
|
||||
}
|
||||
//output dot
|
||||
else if (1 == show->type) {
|
||||
DrvLcdSetPixelDot(show->pixel_info.x_startpos,show->pixel_info.y_startpos, show->pixel_info.x_endpos, show->pixel_info.y_endpos,show->pixel_info.pixel_color);
|
||||
} else {
|
||||
KPrintf("LcdWrite donnot support show type(0 string; 1 dot) %u\n", show->type);
|
||||
ret = -ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static uint32 LcdControl(void* drv, struct BusConfigureInfo *configure_info)
|
||||
{
|
||||
x_err_t ret = EOK;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct LcdDevDone dev_done =
|
||||
{
|
||||
NONE,
|
||||
NONE,
|
||||
LcdWrite,
|
||||
NONE,
|
||||
};
|
||||
|
||||
static int BoardLcdBusInit(struct LcdBus * lcd_bus, struct LcdDriver * lcd_driver,const char *bus_name, const char *drv_name)
|
||||
{
|
||||
x_err_t ret = EOK;
|
||||
|
||||
/*Init the lcd bus */
|
||||
ret = LcdBusInit( lcd_bus, bus_name);
|
||||
if (EOK != ret) {
|
||||
KPrintf("Board_lcd_init LcdBusInit error %d\n", ret);
|
||||
return -ERROR;
|
||||
}
|
||||
|
||||
/*Init the lcd driver*/
|
||||
ret = LcdDriverInit( lcd_driver, drv_name);
|
||||
if (EOK != ret) {
|
||||
KPrintf("Board_LCD_init LcdDriverInit error %d\n", ret);
|
||||
return -ERROR;
|
||||
}
|
||||
|
||||
/*Attach the lcd driver to the lcd bus*/
|
||||
ret = LcdDriverAttachToBus(drv_name, bus_name);
|
||||
if (EOK != ret) {
|
||||
KPrintf("Board_LCD_init LcdDriverAttachToBus error %d\n", ret);
|
||||
return -ERROR;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*Attach the lcd device to the lcd bus*/
|
||||
static int BoardLcdDevBend(struct LcdHardwareDevice *lcd_device, void *param, const char *bus_name, const char *dev_name)
|
||||
{
|
||||
x_err_t ret = EOK;
|
||||
|
||||
ret = LcdDeviceRegister(lcd_device, param, dev_name);
|
||||
if (EOK != ret) {
|
||||
KPrintf("Board_LCD_init LcdDeviceInit device %s error %d\n", dev_name, ret);
|
||||
return -ERROR;
|
||||
}
|
||||
|
||||
ret = LcdDeviceAttachToBus(dev_name, bus_name);
|
||||
if (EOK != ret) {
|
||||
KPrintf("Board_LCD_init LcdDeviceAttachToBus device %s error %d\n", dev_name, ret);
|
||||
return -ERROR;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int Imxrt1052HwLcdInit(void)
|
||||
{
|
||||
x_err_t ret = EOK;
|
||||
|
||||
static struct LcdBus lcd_bus;
|
||||
static struct LcdDriver lcd_drv;
|
||||
static struct LcdHardwareDevice lcd_dev;
|
||||
|
||||
memset(&lcd_bus, 0, sizeof(struct LcdBus));
|
||||
memset(&lcd_drv, 0, sizeof(struct LcdDriver));
|
||||
memset(&lcd_dev, 0, sizeof(struct LcdHardwareDevice));
|
||||
|
||||
|
||||
lcd_drv.configure = LcdControl;
|
||||
|
||||
ret = BoardLcdBusInit(&lcd_bus, &lcd_drv, LCD_BUS_NAME, LCD_DRV_NAME);
|
||||
if (EOK != ret) {
|
||||
KPrintf("HwLcdInit BoardLcdBusInit error ret %u\n", ret);
|
||||
return -ERROR;
|
||||
}
|
||||
|
||||
lcd_dev.dev_done = &dev_done;
|
||||
|
||||
ret = BoardLcdDevBend(&lcd_dev, NONE, LCD_BUS_NAME, LCD_DEVICE_NAME); //init lcd device
|
||||
if (EOK != ret) {
|
||||
KPrintf("HwLcdInit BoardLcdDevBend error ret %u\n", ret);
|
||||
return -ERROR;
|
||||
}
|
||||
|
||||
HwLcdInit();
|
||||
|
||||
return ret;
|
||||
}
|
|
@ -0,0 +1,371 @@
|
|||
/*
|
||||
* Copyright 2017 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "fsl_elcdif.h"
|
||||
|
||||
/* Component ID definition, used by tools. */
|
||||
#ifndef FSL_COMPONENT_ID
|
||||
#define FSL_COMPONENT_ID "platform.drivers.elcdif"
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
* Prototypes
|
||||
******************************************************************************/
|
||||
|
||||
/*!
|
||||
* @brief Get instance number for ELCDIF module.
|
||||
*
|
||||
* @param base ELCDIF peripheral base address
|
||||
*/
|
||||
static uint32_t ELCDIF_GetInstance(LCDIF_Type *base);
|
||||
|
||||
/*******************************************************************************
|
||||
* Variables
|
||||
******************************************************************************/
|
||||
|
||||
/*! @brief Pointers to ELCDIF bases for each instance. */
|
||||
static LCDIF_Type *const s_elcdifBases[] = LCDIF_BASE_PTRS;
|
||||
|
||||
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
|
||||
/*! @brief Pointers to eLCDIF apb_clk for each instance. */
|
||||
static const clock_ip_name_t s_elcdifApbClocks[] = LCDIF_CLOCKS;
|
||||
#if defined(LCDIF_PERIPH_CLOCKS)
|
||||
/*! @brief Pointers to eLCDIF pix_clk for each instance. */
|
||||
static const clock_ip_name_t s_elcdifPixClocks[] = LCDIF_PERIPH_CLOCKS;
|
||||
#endif
|
||||
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
|
||||
|
||||
/*! @brief The control register value to select different pixel format. */
|
||||
elcdif_pixel_format_reg_t s_pixelFormatReg[] = {
|
||||
/* kELCDIF_PixelFormatRAW8 */
|
||||
{/* Register CTRL. */
|
||||
LCDIF_CTRL_WORD_LENGTH(1U),
|
||||
/* Register CTRL1. */
|
||||
LCDIF_CTRL1_BYTE_PACKING_FORMAT(0x0FU)},
|
||||
/* kELCDIF_PixelFormatRGB565 */
|
||||
{/* Register CTRL. */
|
||||
LCDIF_CTRL_WORD_LENGTH(0U),
|
||||
/* Register CTRL1. */
|
||||
LCDIF_CTRL1_BYTE_PACKING_FORMAT(0x0FU)},
|
||||
/* kELCDIF_PixelFormatRGB666 */
|
||||
{/* Register CTRL. */
|
||||
LCDIF_CTRL_WORD_LENGTH(3U) | LCDIF_CTRL_DATA_FORMAT_24_BIT(1U),
|
||||
/* Register CTRL1. */
|
||||
LCDIF_CTRL1_BYTE_PACKING_FORMAT(0x07U)},
|
||||
/* kELCDIF_PixelFormatXRGB8888 */
|
||||
{/* Register CTRL. 24-bit. */
|
||||
LCDIF_CTRL_WORD_LENGTH(3U),
|
||||
/* Register CTRL1. */
|
||||
LCDIF_CTRL1_BYTE_PACKING_FORMAT(0x07U)},
|
||||
/* kELCDIF_PixelFormatRGB888 */
|
||||
{/* Register CTRL. 24-bit. */
|
||||
LCDIF_CTRL_WORD_LENGTH(3U),
|
||||
/* Register CTRL1. */
|
||||
LCDIF_CTRL1_BYTE_PACKING_FORMAT(0x0FU)},
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
* Codes
|
||||
******************************************************************************/
|
||||
static uint32_t ELCDIF_GetInstance(LCDIF_Type *base)
|
||||
{
|
||||
uint32_t instance;
|
||||
|
||||
/* Find the instance index from base address mappings. */
|
||||
for (instance = 0; instance < ARRAY_SIZE(s_elcdifBases); instance++)
|
||||
{
|
||||
if (s_elcdifBases[instance] == base)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assert(instance < ARRAY_SIZE(s_elcdifBases));
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
/*!
|
||||
* brief Initializes the eLCDIF to work in RGB mode (DOTCLK mode).
|
||||
*
|
||||
* This function ungates the eLCDIF clock and configures the eLCDIF peripheral according
|
||||
* to the configuration structure.
|
||||
*
|
||||
* param base eLCDIF peripheral base address.
|
||||
* param config Pointer to the configuration structure.
|
||||
*/
|
||||
void ELCDIF_RgbModeInit(LCDIF_Type *base, const elcdif_rgb_mode_config_t *config)
|
||||
{
|
||||
assert(config);
|
||||
assert(config->pixelFormat < ARRAY_SIZE(s_pixelFormatReg));
|
||||
|
||||
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
|
||||
uint32_t instance = ELCDIF_GetInstance(base);
|
||||
/* Enable the clock. */
|
||||
CLOCK_EnableClock(s_elcdifApbClocks[instance]);
|
||||
#if defined(LCDIF_PERIPH_CLOCKS)
|
||||
CLOCK_EnableClock(s_elcdifPixClocks[instance]);
|
||||
#endif
|
||||
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
|
||||
|
||||
/* Reset. */
|
||||
ELCDIF_Reset(base);
|
||||
|
||||
base->CTRL = s_pixelFormatReg[(uint32_t)config->pixelFormat].regCtrl | (uint32_t)(config->dataBus) |
|
||||
LCDIF_CTRL_DOTCLK_MODE_MASK | /* RGB mode. */
|
||||
LCDIF_CTRL_BYPASS_COUNT_MASK | /* Keep RUN bit set. */
|
||||
LCDIF_CTRL_MASTER_MASK;
|
||||
|
||||
base->CTRL1 = s_pixelFormatReg[(uint32_t)config->pixelFormat].regCtrl1;
|
||||
|
||||
base->TRANSFER_COUNT = ((uint32_t)config->panelHeight << LCDIF_TRANSFER_COUNT_V_COUNT_SHIFT) |
|
||||
((uint32_t)config->panelWidth << LCDIF_TRANSFER_COUNT_H_COUNT_SHIFT);
|
||||
|
||||
base->VDCTRL0 = LCDIF_VDCTRL0_ENABLE_PRESENT_MASK | /* Data enable signal. */
|
||||
LCDIF_VDCTRL0_VSYNC_PERIOD_UNIT_MASK | /* VSYNC period in the unit of display clock. */
|
||||
LCDIF_VDCTRL0_VSYNC_PULSE_WIDTH_UNIT_MASK | /* VSYNC pulse width in the unit of display clock. */
|
||||
(uint32_t)config->polarityFlags | (uint32_t)config->vsw;
|
||||
|
||||
base->VDCTRL1 = config->vsw + config->panelHeight + config->vfp + config->vbp;
|
||||
base->VDCTRL2 = ((uint32_t)config->hsw << LCDIF_VDCTRL2_HSYNC_PULSE_WIDTH_SHIFT) |
|
||||
((uint32_t)(config->hfp + config->hbp + config->panelWidth + config->hsw))
|
||||
<< LCDIF_VDCTRL2_HSYNC_PERIOD_SHIFT;
|
||||
|
||||
base->VDCTRL3 = (((uint32_t)config->hbp + config->hsw) << LCDIF_VDCTRL3_HORIZONTAL_WAIT_CNT_SHIFT) |
|
||||
(((uint32_t)config->vbp + config->vsw) << LCDIF_VDCTRL3_VERTICAL_WAIT_CNT_SHIFT);
|
||||
|
||||
base->VDCTRL4 = LCDIF_VDCTRL4_SYNC_SIGNALS_ON_MASK |
|
||||
((uint32_t)config->panelWidth << LCDIF_VDCTRL4_DOTCLK_H_VALID_DATA_CNT_SHIFT);
|
||||
|
||||
base->CUR_BUF = config->bufferAddr;
|
||||
base->NEXT_BUF = config->bufferAddr;
|
||||
}
|
||||
|
||||
/*!
|
||||
* brief Gets the eLCDIF default configuration structure for RGB (DOTCLK) mode.
|
||||
*
|
||||
* This function sets the configuration structure to default values.
|
||||
* The default configuration is set to the following values.
|
||||
* code
|
||||
config->panelWidth = 480U;
|
||||
config->panelHeight = 272U;
|
||||
config->hsw = 41;
|
||||
config->hfp = 4;
|
||||
config->hbp = 8;
|
||||
config->vsw = 10;
|
||||
config->vfp = 4;
|
||||
config->vbp = 2;
|
||||
config->polarityFlags = kELCDIF_VsyncActiveLow |
|
||||
kELCDIF_HsyncActiveLow |
|
||||
kELCDIF_DataEnableActiveLow |
|
||||
kELCDIF_DriveDataOnFallingClkEdge;
|
||||
config->bufferAddr = 0U;
|
||||
config->pixelFormat = kELCDIF_PixelFormatRGB888;
|
||||
config->dataBus = kELCDIF_DataBus24Bit;
|
||||
code
|
||||
*
|
||||
* param config Pointer to the eLCDIF configuration structure.
|
||||
*/
|
||||
void ELCDIF_RgbModeGetDefaultConfig(elcdif_rgb_mode_config_t *config)
|
||||
{
|
||||
assert(config);
|
||||
|
||||
/* Initializes the configure structure to zero. */
|
||||
memset(config, 0, sizeof(*config));
|
||||
|
||||
config->panelWidth = 480U;
|
||||
config->panelHeight = 272U;
|
||||
config->hsw = 41;
|
||||
config->hfp = 4;
|
||||
config->hbp = 8;
|
||||
config->vsw = 10;
|
||||
config->vfp = 4;
|
||||
config->vbp = 2;
|
||||
config->polarityFlags = kELCDIF_VsyncActiveLow | kELCDIF_HsyncActiveLow | kELCDIF_DataEnableActiveLow |
|
||||
kELCDIF_DriveDataOnFallingClkEdge;
|
||||
config->bufferAddr = 0U;
|
||||
config->pixelFormat = kELCDIF_PixelFormatRGB888;
|
||||
config->dataBus = kELCDIF_DataBus24Bit;
|
||||
}
|
||||
|
||||
/*!
|
||||
* brief Set the pixel format in RGB (DOTCLK) mode.
|
||||
*
|
||||
* param base eLCDIF peripheral base address.
|
||||
* param pixelFormat The pixel format.
|
||||
*/
|
||||
void ELCDIF_RgbModeSetPixelFormat(LCDIF_Type *base, elcdif_pixel_format_t pixelFormat)
|
||||
{
|
||||
assert(pixelFormat < ARRAY_SIZE(s_pixelFormatReg));
|
||||
|
||||
base->CTRL = (base->CTRL & ~(LCDIF_CTRL_WORD_LENGTH_MASK | LCDIF_CTRL_DATA_FORMAT_24_BIT_MASK |
|
||||
LCDIF_CTRL_DATA_FORMAT_18_BIT_MASK | LCDIF_CTRL_DATA_FORMAT_16_BIT_MASK)) |
|
||||
s_pixelFormatReg[(uint32_t)pixelFormat].regCtrl;
|
||||
|
||||
base->CTRL1 = s_pixelFormatReg[(uint32_t)pixelFormat].regCtrl1;
|
||||
}
|
||||
|
||||
/*!
|
||||
* brief Deinitializes the eLCDIF peripheral.
|
||||
*
|
||||
* param base eLCDIF peripheral base address.
|
||||
*/
|
||||
void ELCDIF_Deinit(LCDIF_Type *base)
|
||||
{
|
||||
ELCDIF_Reset(base);
|
||||
|
||||
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
|
||||
uint32_t instance = ELCDIF_GetInstance(base);
|
||||
/* Disable the clock. */
|
||||
#if defined(LCDIF_PERIPH_CLOCKS)
|
||||
CLOCK_DisableClock(s_elcdifPixClocks[instance]);
|
||||
#endif
|
||||
CLOCK_DisableClock(s_elcdifApbClocks[instance]);
|
||||
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
|
||||
}
|
||||
|
||||
/*!
|
||||
* brief Stop display in RGB (DOTCLK) mode and wait until finished.
|
||||
*
|
||||
* param base eLCDIF peripheral base address.
|
||||
*/
|
||||
void ELCDIF_RgbModeStop(LCDIF_Type *base)
|
||||
{
|
||||
base->CTRL_CLR = LCDIF_CTRL_DOTCLK_MODE_MASK;
|
||||
|
||||
/* Wait for data transfer finished. */
|
||||
while (base->CTRL & LCDIF_CTRL_DOTCLK_MODE_MASK)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* brief Reset the eLCDIF peripheral.
|
||||
*
|
||||
* param base eLCDIF peripheral base address.
|
||||
*/
|
||||
void ELCDIF_Reset(LCDIF_Type *base)
|
||||
{
|
||||
volatile uint32_t i = 0x100;
|
||||
|
||||
/* Disable the clock gate. */
|
||||
base->CTRL_CLR = LCDIF_CTRL_CLKGATE_MASK;
|
||||
/* Confirm the clock gate is disabled. */
|
||||
while (base->CTRL & LCDIF_CTRL_CLKGATE_MASK)
|
||||
{
|
||||
}
|
||||
|
||||
/* Reset the block. */
|
||||
base->CTRL_SET = LCDIF_CTRL_SFTRST_MASK;
|
||||
/* Confirm the reset bit is set. */
|
||||
while (!(base->CTRL & LCDIF_CTRL_SFTRST_MASK))
|
||||
{
|
||||
}
|
||||
|
||||
/* Delay for the reset. */
|
||||
while (i--)
|
||||
{
|
||||
}
|
||||
|
||||
/* Bring the module out of reset. */
|
||||
base->CTRL_CLR = LCDIF_CTRL_SFTRST_MASK;
|
||||
/* Disable the clock gate. */
|
||||
base->CTRL_CLR = LCDIF_CTRL_CLKGATE_MASK;
|
||||
}
|
||||
|
||||
#if !(defined(FSL_FEATURE_LCDIF_HAS_NO_AS) && FSL_FEATURE_LCDIF_HAS_NO_AS)
|
||||
/*!
|
||||
* brief Set the configuration for alpha surface buffer.
|
||||
*
|
||||
* param base eLCDIF peripheral base address.
|
||||
* param config Pointer to the configuration structure.
|
||||
*/
|
||||
void ELCDIF_SetAlphaSurfaceBufferConfig(LCDIF_Type *base, const elcdif_as_buffer_config_t *config)
|
||||
{
|
||||
assert(config);
|
||||
|
||||
base->AS_CTRL = (base->AS_CTRL & ~LCDIF_AS_CTRL_FORMAT_MASK) | LCDIF_AS_CTRL_FORMAT(config->pixelFormat);
|
||||
base->AS_BUF = config->bufferAddr;
|
||||
base->AS_NEXT_BUF = config->bufferAddr;
|
||||
}
|
||||
|
||||
/*!
|
||||
* brief Set the alpha surface blending configuration.
|
||||
*
|
||||
* param base eLCDIF peripheral base address.
|
||||
* param config Pointer to the configuration structure.
|
||||
*/
|
||||
void ELCDIF_SetAlphaSurfaceBlendConfig(LCDIF_Type *base, const elcdif_as_blend_config_t *config)
|
||||
{
|
||||
assert(config);
|
||||
uint32_t reg;
|
||||
|
||||
reg = base->AS_CTRL;
|
||||
reg &= ~(LCDIF_AS_CTRL_ALPHA_INVERT_MASK | LCDIF_AS_CTRL_ROP_MASK | LCDIF_AS_CTRL_ALPHA_MASK |
|
||||
LCDIF_AS_CTRL_ALPHA_CTRL_MASK);
|
||||
reg |= (LCDIF_AS_CTRL_ROP(config->ropMode) | LCDIF_AS_CTRL_ALPHA(config->alpha) |
|
||||
LCDIF_AS_CTRL_ALPHA_CTRL(config->alphaMode));
|
||||
|
||||
if (config->invertAlpha)
|
||||
{
|
||||
reg |= LCDIF_AS_CTRL_ALPHA_INVERT_MASK;
|
||||
}
|
||||
|
||||
base->AS_CTRL = reg;
|
||||
}
|
||||
#endif /* FSL_FEATURE_LCDIF_HAS_NO_AS */
|
||||
|
||||
#if (defined(FSL_FEATURE_LCDIF_HAS_LUT) && FSL_FEATURE_LCDIF_HAS_LUT)
|
||||
/*!
|
||||
* brief Load the LUT value.
|
||||
*
|
||||
* This function loads the LUT value to the specific LUT memory, user can
|
||||
* specify the start entry index.
|
||||
*
|
||||
* param base eLCDIF peripheral base address.
|
||||
* param lut Which LUT to load.
|
||||
* param startIndex The start index of the LUT entry to update.
|
||||
* param lutData The LUT data to load.
|
||||
* param count Count of p lutData.
|
||||
* retval kStatus_Success Initialization success.
|
||||
* retval kStatus_InvalidArgument Wrong argument.
|
||||
*/
|
||||
status_t ELCDIF_UpdateLut(
|
||||
LCDIF_Type *base, elcdif_lut_t lut, uint16_t startIndex, const uint32_t *lutData, uint16_t count)
|
||||
{
|
||||
volatile uint32_t *regLutAddr;
|
||||
volatile uint32_t *regLutData;
|
||||
uint32_t i;
|
||||
|
||||
/* Only has 256 entries. */
|
||||
if (startIndex + count > ELCDIF_LUT_ENTRY_NUM)
|
||||
{
|
||||
return kStatus_InvalidArgument;
|
||||
}
|
||||
|
||||
if (kELCDIF_Lut0 == lut)
|
||||
{
|
||||
regLutAddr = &(base->LUT0_ADDR);
|
||||
regLutData = &(base->LUT0_DATA);
|
||||
}
|
||||
else
|
||||
{
|
||||
regLutAddr = &(base->LUT1_ADDR);
|
||||
regLutData = &(base->LUT1_DATA);
|
||||
}
|
||||
|
||||
*regLutAddr = startIndex;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
*regLutData = lutData[i];
|
||||
}
|
||||
|
||||
return kStatus_Success;
|
||||
}
|
||||
#endif /* FSL_FEATURE_LCDIF_HAS_LUT */
|
|
@ -0,0 +1,24 @@
|
|||
if BSP_USING_SDIO
|
||||
config SDIO_BUS_NAME
|
||||
string "sdio bus name"
|
||||
default "sdio"
|
||||
|
||||
config SDIO_DRIVER_NAME
|
||||
string "sdio driver name"
|
||||
default "sdio_drv"
|
||||
|
||||
config SDIO_DEVICE_NAME
|
||||
string "sdio device name"
|
||||
default "sdio_dev"
|
||||
|
||||
config MOUNT_SDCARD_FS
|
||||
bool "mount cd card file system"
|
||||
default n
|
||||
select MOUNT_SDCARD
|
||||
|
||||
if MOUNT_SDCARD_FS
|
||||
config MOUNT_SDCARD_FS_TYPE
|
||||
int "choose file system type : FATFS(0) LWEXT4(3)"
|
||||
default 0
|
||||
endif
|
||||
endif
|
|
@ -0,0 +1,5 @@
|
|||
SRC_DIR := sdmmc
|
||||
|
||||
SRC_FILES := connect_sdio.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -0,0 +1,455 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2017 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file connect_sdio.c
|
||||
* @brief support sdio function using bus driver framework on xidatong board
|
||||
* @version 2.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022-01-24
|
||||
*/
|
||||
|
||||
/*************************************************
|
||||
File name: connect_sdio.c
|
||||
Description: support imxrt1052-board sd card configure and sdio bus register function
|
||||
Others: take SDK_2.6.1_MIMXRT1052xxxxB/boards/evkbimxrt1050/driver_examples/sdcard/polling/sdcard_polling.c for references
|
||||
History:
|
||||
1. Date: 2022-01-24
|
||||
Author: AIIT XUOS Lab
|
||||
Modification:
|
||||
1. support imxrt1052-board sdio configure, write and read
|
||||
2. support imxrt1052-board sdio bus device and driver register
|
||||
*************************************************/
|
||||
|
||||
#include <connect_sdio.h>
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
#define SDCARD_POWER_CTRL_FUNCTION_EXIST
|
||||
|
||||
/*! @brief Data block count accessed in card */
|
||||
#define DATA_BLOCK_COUNT (5U)
|
||||
/*! @brief Start data block number accessed in card */
|
||||
#define DATA_BLOCK_START (2U)
|
||||
/*! @brief Data buffer size. */
|
||||
#define DATA_BUFFER_SIZE (FSL_SDMMC_DEFAULT_BLOCK_SIZE * DATA_BLOCK_COUNT)
|
||||
|
||||
#define BOARD_USDHC_SDCARD_POWER_CONTROL(state) \
|
||||
(GPIO_PinWrite(BOARD_SD_POWER_RESET_GPIO, BOARD_SD_POWER_RESET_GPIO_PIN, state))
|
||||
|
||||
/*******************************************************************************
|
||||
* Prototypes
|
||||
******************************************************************************/
|
||||
static void BoardPowerOffSdCard(void);
|
||||
static void BoardPowerOnSdCard(void);
|
||||
|
||||
/*!
|
||||
* @brief printf the card information log.
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
*/
|
||||
static void CardInformationLog(sd_card_t *card);
|
||||
|
||||
/*******************************************************************************
|
||||
* Variables
|
||||
******************************************************************************/
|
||||
|
||||
/* @brief decription about the read/write buffer
|
||||
* The size of the read/write buffer should be a multiple of 512, since SDHC/SDXC card uses 512-byte fixed
|
||||
* block length and this driver example is enabled with a SDHC/SDXC card.If you are using a SDSC card, you
|
||||
* can define the block length by yourself if the card supports partial access.
|
||||
* The address of the read/write buffer should align to the specific DMA data buffer address align value if
|
||||
* DMA transfer is used, otherwise the buffer address is not important.
|
||||
* At the same time buffer address/size should be aligned to the cache line size if cache is supported.
|
||||
*/
|
||||
/*! @brief Data written to the card */
|
||||
SDK_ALIGN(uint8_t g_data_write[SDK_SIZEALIGN(DATA_BUFFER_SIZE, SDMMC_DATA_BUFFER_ALIGN_CACHE)],
|
||||
MAX(SDMMC_DATA_BUFFER_ALIGN_CACHE, SDMMCHOST_DMA_BUFFER_ADDR_ALIGN));
|
||||
/*! @brief Data read from the card */
|
||||
SDK_ALIGN(uint8_t g_data_read[SDK_SIZEALIGN(DATA_BUFFER_SIZE, SDMMC_DATA_BUFFER_ALIGN_CACHE)],
|
||||
MAX(SDMMC_DATA_BUFFER_ALIGN_CACHE, SDMMCHOST_DMA_BUFFER_ADDR_ALIGN));
|
||||
|
||||
/*! @brief SDMMC host detect card configuration */
|
||||
static const sdmmchost_detect_card_t s_sdcard_detect = {
|
||||
#ifndef BOARD_SD_DETECT_TYPE
|
||||
.cdType = kSDMMCHOST_DetectCardByGpioCD,
|
||||
#else
|
||||
.cdType = BOARD_SD_DETECT_TYPE,
|
||||
#endif
|
||||
.cdTimeOut_ms = (~0U),
|
||||
};
|
||||
|
||||
/*! @brief SDMMC card power control configuration */
|
||||
#if defined SDCARD_POWER_CTRL_FUNCTION_EXIST
|
||||
static const sdmmchost_pwr_card_t s_sdcard_pwr_ctrl = {
|
||||
.powerOn = BoardPowerOnSdCard,
|
||||
.powerOnDelay_ms = 0U,
|
||||
.powerOff = BoardPowerOffSdCard,
|
||||
.powerOffDelay_ms = 0U,
|
||||
};
|
||||
#endif
|
||||
|
||||
/*! @brief SDMMC card power control configuration */
|
||||
#if defined SDCARD_SWITCH_VOLTAGE_FUNCTION_EXIST
|
||||
static const sdmmchost_card_switch_voltage_func_t s_sdcard_voltage_switch = {
|
||||
.cardSignalLine1V8 = BOARD_USDHC_Switch_VoltageTo1V8,
|
||||
.cardSignalLine3V3 = BOARD_USDHC_Switch_VoltageTo3V3,
|
||||
};
|
||||
#endif
|
||||
|
||||
/*! @brief Card descriptor. */
|
||||
static sd_card_t g_sd;
|
||||
static int sd_lock = -1;
|
||||
|
||||
static void BoardUSDHCClockConfiguration(void)
|
||||
{
|
||||
CLOCK_InitSysPll(&sysPllConfig_BOARD_BootClockRUN);
|
||||
/*configure system pll PFD0 fractional divider to 24, output clock is 528MHZ * 18 / 24 = 396 MHZ*/
|
||||
CLOCK_InitSysPfd(kCLOCK_Pfd0, 24U);
|
||||
/* Configure USDHC clock source and divider */
|
||||
CLOCK_SetDiv(kCLOCK_Usdhc1Div, 0U);
|
||||
CLOCK_SetMux(kCLOCK_Usdhc1Mux, 1U);
|
||||
}
|
||||
|
||||
static void BoardPowerOffSdCard(void)
|
||||
{
|
||||
/*
|
||||
Do nothing here.
|
||||
|
||||
SD card will not be detected correctly if the card VDD is power off,
|
||||
the reason is caused by card VDD supply to the card detect circuit, this issue is exist on EVK board rev A1 and
|
||||
A2.
|
||||
|
||||
If power off function is not implemented after soft reset and prior to SD Host initialization without
|
||||
remove/insert card,
|
||||
a UHS-I card may not reach its highest speed mode during the second card initialization.
|
||||
Application can avoid this issue by toggling the SD_VDD (GPIO) before the SD host initialization.
|
||||
*/
|
||||
}
|
||||
|
||||
static void BoardPowerOnSdCard(void)
|
||||
{
|
||||
BOARD_USDHC_SDCARD_POWER_CONTROL(1);
|
||||
}
|
||||
|
||||
static void CardInformationLog(sd_card_t *card)
|
||||
{
|
||||
NULL_PARAM_CHECK(card);
|
||||
|
||||
KPrintf("\r\nCard size %d * %d bytes\r\n", card->blockCount, card->blockSize);
|
||||
KPrintf("\r\nWorking condition:\r\n");
|
||||
if (card->operationVoltage == kCARD_OperationVoltage330V) {
|
||||
KPrintf("\r\n Voltage : 3.3V\r\n");
|
||||
} else if (card->operationVoltage == kCARD_OperationVoltage180V) {
|
||||
KPrintf("\r\n Voltage : 1.8V\r\n");
|
||||
}
|
||||
|
||||
if (card->currentTiming == kSD_TimingSDR12DefaultMode) {
|
||||
if (card->operationVoltage == kCARD_OperationVoltage330V) {
|
||||
KPrintf("\r\n Timing mode: Default mode\r\n");
|
||||
} else if (card->operationVoltage == kCARD_OperationVoltage180V) {
|
||||
KPrintf("\r\n Timing mode: SDR12 mode\r\n");
|
||||
}
|
||||
} else if (card->currentTiming == kSD_TimingSDR25HighSpeedMode) {
|
||||
if (card->operationVoltage == kCARD_OperationVoltage180V) {
|
||||
KPrintf("\r\n Timing mode: SDR25\r\n");
|
||||
} else {
|
||||
KPrintf("\r\n Timing mode: High Speed\r\n");
|
||||
}
|
||||
} else if (card->currentTiming == kSD_TimingSDR50Mode) {
|
||||
KPrintf("\r\n Timing mode: SDR50\r\n");
|
||||
} else if (card->currentTiming == kSD_TimingSDR104Mode) {
|
||||
KPrintf("\r\n Timing mode: SDR104\r\n");
|
||||
} else if (card->currentTiming == kSD_TimingDDR50Mode) {
|
||||
KPrintf("\r\n Timing mode: DDR50\r\n");
|
||||
}
|
||||
|
||||
KPrintf("\r\n Freq : %d HZ\r\n", card->busClock_Hz);
|
||||
}
|
||||
|
||||
static uint32 SdioConfigure(void *drv, struct BusConfigureInfo *configure_info)
|
||||
{
|
||||
NULL_PARAM_CHECK(drv);
|
||||
NULL_PARAM_CHECK(configure_info);
|
||||
|
||||
if (configure_info->configure_cmd == OPER_BLK_GETGEOME) {
|
||||
NULL_PARAM_CHECK(configure_info->private_data);
|
||||
struct DeviceBlockArrange *args = (struct DeviceBlockArrange *)configure_info->private_data;
|
||||
|
||||
args->size_perbank = g_sd.blockSize;
|
||||
args->block_size = g_sd.blockSize;
|
||||
args->bank_num = g_sd.blockCount;
|
||||
}
|
||||
|
||||
return EOK;
|
||||
}
|
||||
|
||||
static uint32 SdioOpen(void *dev)
|
||||
{
|
||||
NULL_PARAM_CHECK(dev);
|
||||
|
||||
if(sd_lock >= 0) {
|
||||
KSemaphoreDelete(sd_lock);
|
||||
}
|
||||
sd_lock = KSemaphoreCreate(1);
|
||||
if (sd_lock < 0){
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
return EOK;
|
||||
}
|
||||
|
||||
static uint32 SdioClose(void *dev)
|
||||
{
|
||||
NULL_PARAM_CHECK(dev);
|
||||
|
||||
KSemaphoreDelete(sd_lock);
|
||||
|
||||
return EOK;
|
||||
}
|
||||
|
||||
static uint32 SdioRead(void *dev, struct BusBlockReadParam *read_param)
|
||||
{
|
||||
uint8 ret = EOK;
|
||||
uint32 sector = read_param->pos;
|
||||
uint32 block_num = read_param->size;
|
||||
uint8 *read_buffer = (uint8 *)read_param->buffer;
|
||||
|
||||
KSemaphoreObtain(sd_lock, WAITING_FOREVER);
|
||||
|
||||
if (kStatus_Success != SD_ReadBlocks(&g_sd, read_buffer, sector, block_num)) {
|
||||
KPrintf("Read multiple data blocks failed.\r\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
KSemaphoreAbandon(sd_lock);
|
||||
|
||||
return read_param->size;
|
||||
}
|
||||
|
||||
static uint32 SdioWrite(void *dev, struct BusBlockWriteParam *write_param)
|
||||
{
|
||||
uint8 ret = EOK;
|
||||
uint32 sector = write_param->pos;
|
||||
uint32 block_num = write_param->size;
|
||||
const uint8 *write_buffer = (uint8 *)write_param->buffer;
|
||||
|
||||
KSemaphoreObtain(sd_lock, WAITING_FOREVER);
|
||||
|
||||
if (kStatus_Success != SD_WriteBlocks(&g_sd, write_buffer, sector, block_num)) {
|
||||
KPrintf("Write multiple data blocks failed.\r\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
KSemaphoreAbandon(sd_lock);
|
||||
|
||||
return write_param->size;
|
||||
}
|
||||
|
||||
static int SdioControl(struct HardwareDev *dev, struct HalDevBlockParam *block_param)
|
||||
{
|
||||
NULL_PARAM_CHECK(dev);
|
||||
|
||||
if (OPER_BLK_GETGEOME == block_param->cmd) {
|
||||
block_param->dev_block.size_perbank = g_sd.blockSize;
|
||||
block_param->dev_block.block_size = g_sd.blockSize;
|
||||
block_param->dev_block.bank_num = g_sd.blockCount;
|
||||
}
|
||||
|
||||
return EOK;
|
||||
}
|
||||
|
||||
static struct SdioDevDone dev_done =
|
||||
{
|
||||
SdioOpen,
|
||||
SdioClose,
|
||||
SdioWrite,
|
||||
SdioRead,
|
||||
};
|
||||
|
||||
#if defined(FS_VFS) && defined(MOUNT_SDCARD_FS)
|
||||
#include <iot-vfs.h>
|
||||
|
||||
/**
|
||||
* @description: Mount SD card
|
||||
* @return 0
|
||||
*/
|
||||
static int MountSDCardFs(enum FilesystemType fs_type)
|
||||
{
|
||||
if (MountFilesystem(SDIO_BUS_NAME, SDIO_DEVICE_NAME, SDIO_DRIVER_NAME, fs_type, "/") == 0)
|
||||
KPrintf("Sd card mount to '/'");
|
||||
else
|
||||
KPrintf("Sd card mount to '/' failed!");
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void SdCardAttach(void)
|
||||
{
|
||||
bool is_read_only;
|
||||
static sd_card_t *card = &g_sd;
|
||||
|
||||
KPrintf("\r\nCard inserted.\r\n");
|
||||
/* reset host once card re-plug in */
|
||||
SD_HostReset(&(card->host));
|
||||
/* power on the card */
|
||||
SD_PowerOnCard(card->host.base, card->usrParam.pwr);
|
||||
KPrintf("Power on done\n");
|
||||
|
||||
/* Init card. */
|
||||
if (SD_CardInit(card)) {
|
||||
KPrintf("\r\nSD card init failed.\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* card information log */
|
||||
CardInformationLog(card);
|
||||
|
||||
/* Check if card is readonly. */
|
||||
is_read_only = SD_CheckReadOnly(card);
|
||||
|
||||
#ifdef MOUNT_SDCARD_FS
|
||||
/*mount file system*/
|
||||
MountSDCardFs(MOUNT_SDCARD_FS_TYPE);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void SdCardDetach(void)
|
||||
{
|
||||
/*unmount file system*/
|
||||
KPrintf("\r\nCard detect extracted.\r\n");
|
||||
|
||||
#ifdef MOUNT_SDCARD_FS
|
||||
UnmountFileSystem("/");
|
||||
#endif
|
||||
}
|
||||
|
||||
static uint8 SdCardReadCd(void)
|
||||
{
|
||||
BusType pin;
|
||||
|
||||
pin = BusFind(PIN_BUS_NAME);
|
||||
|
||||
pin->owner_haldev = BusFindDevice(pin, PIN_DEVICE_NAME);
|
||||
|
||||
struct PinStat PinStat;
|
||||
|
||||
struct BusBlockReadParam read_param;
|
||||
read_param.buffer = (void *)&PinStat;
|
||||
|
||||
PinStat.pin = IMXRT_GET_PIN(2, 28);
|
||||
|
||||
return BusDevReadData(pin->owner_haldev, &read_param);
|
||||
}
|
||||
|
||||
static void SdCardTask(void* parameter)
|
||||
{
|
||||
static int sd_card_status = 0;
|
||||
|
||||
while (1) {
|
||||
if (!SdCardReadCd()) {
|
||||
if (!sd_card_status) {
|
||||
SdCardAttach();
|
||||
sd_card_status = 1;
|
||||
}
|
||||
} else {
|
||||
if (sd_card_status) {
|
||||
SdCardDetach();
|
||||
sd_card_status = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef MOUNT_SDCARD
|
||||
int MountSDCard()
|
||||
{
|
||||
int sd_card_task = 0;
|
||||
sd_card_task = KTaskCreate("sd_card", SdCardTask, NONE,
|
||||
SD_CARD_STACK_SIZE, 8);
|
||||
if(sd_card_task < 0) {
|
||||
KPrintf("sd_card_task create failed ...%s %d.\n", __FUNCTION__,__LINE__);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
StartupKTask(sd_card_task);
|
||||
|
||||
return EOK;
|
||||
}
|
||||
#endif
|
||||
|
||||
int Imxrt1052HwSdioInit(void)
|
||||
{
|
||||
x_err_t ret = EOK;
|
||||
|
||||
static struct SdioBus sdio_bus;
|
||||
static struct SdioDriver sdio_drv;
|
||||
static struct SdioHardwareDevice sdio_dev;
|
||||
static sd_card_t *card = &g_sd;
|
||||
|
||||
memset(&sdio_bus, 0, sizeof(struct SdioBus));
|
||||
memset(&sdio_drv, 0, sizeof(struct SdioDriver));
|
||||
memset(&sdio_dev, 0, sizeof(struct SdioHardwareDevice));
|
||||
|
||||
BoardUSDHCClockConfiguration();
|
||||
|
||||
card->host.base = SD_HOST_BASEADDR;
|
||||
card->host.sourceClock_Hz = SD_HOST_CLK_FREQ;
|
||||
|
||||
/* card detect type */
|
||||
card->usrParam.cd = &s_sdcard_detect;
|
||||
|
||||
#if defined SDCARD_POWER_CTRL_FUNCTION_EXIST
|
||||
card->usrParam.pwr = &s_sdcard_pwr_ctrl;
|
||||
#endif
|
||||
|
||||
#if defined DEMO_SDCARD_SWITCH_VOLTAGE_FUNCTION_EXIST
|
||||
card->usrParam.cardVoltage = &s_sdcard_voltage_switch;
|
||||
#endif
|
||||
|
||||
/* SD host init function */
|
||||
if (SD_HostInit(card) != kStatus_Success) {
|
||||
KPrintf("\r\nSD host init fail\r\n");
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
ret = SdioBusInit(&sdio_bus, SDIO_BUS_NAME);
|
||||
if (ret != EOK) {
|
||||
KPrintf("Sdio bus init error %d\n", ret);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
ret = SdioDriverInit(&sdio_drv, SDIO_DRIVER_NAME);
|
||||
if (ret != EOK) {
|
||||
KPrintf("Sdio driver init error %d\n", ret);
|
||||
return ERROR;
|
||||
}
|
||||
ret = SdioDriverAttachToBus(SDIO_DRIVER_NAME, SDIO_BUS_NAME);
|
||||
if (ret != EOK) {
|
||||
KPrintf("Sdio driver attach error %d\n", ret);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
sdio_dev.dev_done = &dev_done;
|
||||
sdio_dev.haldev.dev_block_control = SdioControl;
|
||||
ret = SdioDeviceRegister(&sdio_dev, SDIO_DEVICE_NAME);
|
||||
if (ret != EOK) {
|
||||
KPrintf("Sdio device register error %d\n", ret);
|
||||
return ERROR;
|
||||
}
|
||||
ret = SdioDeviceAttachToBus(SDIO_DEVICE_NAME, SDIO_BUS_NAME);
|
||||
if (ret != EOK) {
|
||||
KPrintf("Sdio device register error %d\n", ret);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
SRC_DIR += port src
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -0,0 +1,321 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2018 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _FSL_MMC_H_
|
||||
#define _FSL_MMC_H_
|
||||
|
||||
#include "fsl_sdmmc_common.h"
|
||||
|
||||
/*!
|
||||
* @addtogroup MMCCARD
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
/*! @brief MMC card flags */
|
||||
enum _mmc_card_flag
|
||||
{
|
||||
kMMC_SupportHighSpeed26MHZFlag = (1U << 0U), /*!< Support high speed 26MHZ */
|
||||
kMMC_SupportHighSpeed52MHZFlag = (1U << 1U), /*!< Support high speed 52MHZ */
|
||||
kMMC_SupportHighSpeedDDR52MHZ180V300VFlag = (1 << 2U), /*!< ddr 52MHZ 1.8V or 3.0V */
|
||||
kMMC_SupportHighSpeedDDR52MHZ120VFlag = (1 << 3U), /*!< DDR 52MHZ 1.2V */
|
||||
kMMC_SupportHS200200MHZ180VFlag = (1 << 4U), /*!< HS200 ,200MHZ,1.8V */
|
||||
kMMC_SupportHS200200MHZ120VFlag = (1 << 5U), /*!< HS200, 200MHZ, 1.2V */
|
||||
kMMC_SupportHS400DDR200MHZ180VFlag = (1 << 6U), /*!< HS400, DDR, 200MHZ,1.8V */
|
||||
kMMC_SupportHS400DDR200MHZ120VFlag = (1 << 7U), /*!< HS400, DDR, 200MHZ,1.2V */
|
||||
kMMC_SupportHighCapacityFlag = (1U << 8U), /*!< Support high capacity */
|
||||
kMMC_SupportAlternateBootFlag = (1U << 9U), /*!< Support alternate boot */
|
||||
kMMC_SupportDDRBootFlag = (1U << 10U), /*!< support DDR boot flag*/
|
||||
kMMC_SupportHighSpeedBootFlag = (1U << 11U), /*!< support high speed boot flag*/
|
||||
};
|
||||
|
||||
/*!
|
||||
* @brief mmc card state
|
||||
*
|
||||
* Define the card structure including the necessary fields to identify and describe the card.
|
||||
*/
|
||||
typedef struct _mmc_card
|
||||
{
|
||||
SDMMCHOST_CONFIG host; /*!< Host information */
|
||||
mmccard_usr_param_t usrParam; /*!< user parameter */
|
||||
|
||||
bool isHostReady; /*!< Use this flag to indicate if need host re-init or not*/
|
||||
bool noInteralAlign; /*!< use this flag to disable sdmmc align. If disable, sdmmc will not make sure the
|
||||
data buffer address is word align, otherwise all the transfer are align to low level driver */
|
||||
uint32_t busClock_Hz; /*!< MMC bus clock united in Hz */
|
||||
uint32_t relativeAddress; /*!< Relative address of the card */
|
||||
bool enablePreDefinedBlockCount; /*!< Enable PRE-DEFINED block count when read/write */
|
||||
uint32_t flags; /*!< Capability flag in _mmc_card_flag */
|
||||
uint32_t rawCid[4U]; /*!< Raw CID content */
|
||||
uint32_t rawCsd[4U]; /*!< Raw CSD content */
|
||||
uint32_t rawExtendedCsd[MMC_EXTENDED_CSD_BYTES / 4U]; /*!< Raw MMC Extended CSD content */
|
||||
uint32_t ocr; /*!< Raw OCR content */
|
||||
mmc_cid_t cid; /*!< CID */
|
||||
mmc_csd_t csd; /*!< CSD */
|
||||
mmc_extended_csd_t extendedCsd; /*!< Extended CSD */
|
||||
uint32_t blockSize; /*!< Card block size */
|
||||
uint32_t userPartitionBlocks; /*!< Card total block number in user partition */
|
||||
uint32_t bootPartitionBlocks; /*!< Boot partition size united as block size */
|
||||
uint32_t eraseGroupBlocks; /*!< Erase group size united as block size */
|
||||
mmc_access_partition_t currentPartition; /*!< Current access partition */
|
||||
mmc_voltage_window_t hostVoltageWindowVCCQ; /*!< Host IO voltage window */
|
||||
mmc_voltage_window_t hostVoltageWindowVCC; /*!< application must set this value according to board specific */
|
||||
mmc_high_speed_timing_t busTiming; /*!< indicate the current work timing mode*/
|
||||
mmc_data_bus_width_t busWidth; /*!< indicate the current work bus width */
|
||||
} mmc_card_t;
|
||||
|
||||
/*************************************************************************************************
|
||||
* API
|
||||
************************************************************************************************/
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @name MMCCARD Function
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Initializes the MMC card and host.
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
*
|
||||
* @retval kStatus_SDMMC_HostNotReady host is not ready.
|
||||
* @retval kStatus_SDMMC_GoIdleFailed Go idle failed.
|
||||
* @retval kStatus_SDMMC_SendOperationConditionFailed Send operation condition failed.
|
||||
* @retval kStatus_SDMMC_AllSendCidFailed Send CID failed.
|
||||
* @retval kStatus_SDMMC_SetRelativeAddressFailed Set relative address failed.
|
||||
* @retval kStatus_SDMMC_SendCsdFailed Send CSD failed.
|
||||
* @retval kStatus_SDMMC_CardNotSupport Card not support.
|
||||
* @retval kStatus_SDMMC_SelectCardFailed Send SELECT_CARD command failed.
|
||||
* @retval kStatus_SDMMC_SendExtendedCsdFailed Send EXT_CSD failed.
|
||||
* @retval kStatus_SDMMC_SetBusWidthFailed Set bus width failed.
|
||||
* @retval kStatus_SDMMC_SwitchHighSpeedFailed Switch high speed failed.
|
||||
* @retval kStatus_SDMMC_SetCardBlockSizeFailed Set card block size failed.
|
||||
* @retval kStatus_Success Operate successfully.
|
||||
*/
|
||||
status_t MMC_Init(mmc_card_t *card);
|
||||
|
||||
/*!
|
||||
* @brief Deinitializes the card and host.
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
*/
|
||||
void MMC_Deinit(mmc_card_t *card);
|
||||
|
||||
/*!
|
||||
* @brief intialize the card.
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
*
|
||||
* @retval kStatus_SDMMC_HostNotReady host is not ready.
|
||||
* @retval kStatus_SDMMC_GoIdleFailed Go idle failed.
|
||||
* @retval kStatus_SDMMC_SendOperationConditionFailed Send operation condition failed.
|
||||
* @retval kStatus_SDMMC_AllSendCidFailed Send CID failed.
|
||||
* @retval kStatus_SDMMC_SetRelativeAddressFailed Set relative address failed.
|
||||
* @retval kStatus_SDMMC_SendCsdFailed Send CSD failed.
|
||||
* @retval kStatus_SDMMC_CardNotSupport Card not support.
|
||||
* @retval kStatus_SDMMC_SelectCardFailed Send SELECT_CARD command failed.
|
||||
* @retval kStatus_SDMMC_SendExtendedCsdFailed Send EXT_CSD failed.
|
||||
* @retval kStatus_SDMMC_SetBusWidthFailed Set bus width failed.
|
||||
* @retval kStatus_SDMMC_SwitchHighSpeedFailed Switch high speed failed.
|
||||
* @retval kStatus_SDMMC_SetCardBlockSizeFailed Set card block size failed.
|
||||
* @retval kStatus_Success Operate successfully.
|
||||
*/
|
||||
status_t MMC_CardInit(mmc_card_t *card);
|
||||
|
||||
/*!
|
||||
* @brief Deinitializes the card.
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
*/
|
||||
void MMC_CardDeinit(mmc_card_t *card);
|
||||
|
||||
/*!
|
||||
* @brief initialize the host.
|
||||
*
|
||||
* This function deinitializes the specific host.
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
*/
|
||||
status_t MMC_HostInit(mmc_card_t *card);
|
||||
|
||||
/*!
|
||||
* @brief Deinitializes the host.
|
||||
*
|
||||
* This function deinitializes the host.
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
*/
|
||||
void MMC_HostDeinit(mmc_card_t *card);
|
||||
|
||||
/*!
|
||||
* @brief reset the host.
|
||||
*
|
||||
* This function reset the specific host.
|
||||
*
|
||||
* @param host host descriptor.
|
||||
*/
|
||||
void MMC_HostReset(SDMMCHOST_CONFIG *host);
|
||||
|
||||
/*!
|
||||
* @brief power on card.
|
||||
*
|
||||
* The power on operation depend on host or the user define power on function.
|
||||
* @param base host base address.
|
||||
* @param pwr user define power control configuration
|
||||
*/
|
||||
void MMC_PowerOnCard(SDMMCHOST_TYPE *base, const sdmmchost_pwr_card_t *pwr);
|
||||
|
||||
/*!
|
||||
* @brief power off card.
|
||||
*
|
||||
* The power off operation depend on host or the user define power on function.
|
||||
* @param base host base address.
|
||||
* @param pwr user define power control configuration
|
||||
*/
|
||||
void MMC_PowerOffCard(SDMMCHOST_TYPE *base, const sdmmchost_pwr_card_t *pwr);
|
||||
|
||||
/*!
|
||||
* @brief Checks if the card is read-only.
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
* @retval true Card is read only.
|
||||
* @retval false Card isn't read only.
|
||||
*/
|
||||
bool MMC_CheckReadOnly(mmc_card_t *card);
|
||||
|
||||
/*!
|
||||
* @brief Reads data blocks from the card.
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
* @param buffer The buffer to save data.
|
||||
* @param startBlock The start block index.
|
||||
* @param blockCount The number of blocks to read.
|
||||
* @retval kStatus_InvalidArgument Invalid argument.
|
||||
* @retval kStatus_SDMMC_CardNotSupport Card not support.
|
||||
* @retval kStatus_SDMMC_SetBlockCountFailed Set block count failed.
|
||||
* @retval kStatus_SDMMC_TransferFailed Transfer failed.
|
||||
* @retval kStatus_SDMMC_StopTransmissionFailed Stop transmission failed.
|
||||
* @retval kStatus_Success Operate successfully.
|
||||
*/
|
||||
status_t MMC_ReadBlocks(mmc_card_t *card, uint8_t *buffer, uint32_t startBlock, uint32_t blockCount);
|
||||
|
||||
/*!
|
||||
* @brief Writes data blocks to the card.
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
* @param buffer The buffer to save data blocks.
|
||||
* @param startBlock Start block number to write.
|
||||
* @param blockCount Block count.
|
||||
* @retval kStatus_InvalidArgument Invalid argument.
|
||||
* @retval kStatus_SDMMC_NotSupportYet Not support now.
|
||||
* @retval kStatus_SDMMC_SetBlockCountFailed Set block count failed.
|
||||
* @retval kStatus_SDMMC_WaitWriteCompleteFailed Send status failed.
|
||||
* @retval kStatus_SDMMC_TransferFailed Transfer failed.
|
||||
* @retval kStatus_SDMMC_StopTransmissionFailed Stop transmission failed.
|
||||
* @retval kStatus_Success Operate successfully.
|
||||
*/
|
||||
status_t MMC_WriteBlocks(mmc_card_t *card, const uint8_t *buffer, uint32_t startBlock, uint32_t blockCount);
|
||||
|
||||
/*!
|
||||
* @brief Erases groups of the card.
|
||||
*
|
||||
* Erase group is the smallest erase unit in MMC card. The erase range is [startGroup, endGroup].
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
* @param startGroup Start group number.
|
||||
* @param endGroup End group number.
|
||||
* @retval kStatus_InvalidArgument Invalid argument.
|
||||
* @retval kStatus_SDMMC_WaitWriteCompleteFailed Send status failed.
|
||||
* @retval kStatus_SDMMC_TransferFailed Transfer failed.
|
||||
* @retval kStatus_Success Operate successfully.
|
||||
*/
|
||||
status_t MMC_EraseGroups(mmc_card_t *card, uint32_t startGroup, uint32_t endGroup);
|
||||
|
||||
/*!
|
||||
* @brief Selects the partition to access.
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
* @param partitionNumber The partition number.
|
||||
* @retval kStatus_SDMMC_ConfigureExtendedCsdFailed Configure EXT_CSD failed.
|
||||
* @retval kStatus_Success Operate successfully.
|
||||
*/
|
||||
status_t MMC_SelectPartition(mmc_card_t *card, mmc_access_partition_t partitionNumber);
|
||||
|
||||
/*!
|
||||
* @brief Configures the boot activity of the card.
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
* @param config Boot configuration structure.
|
||||
* @retval kStatus_SDMMC_NotSupportYet Not support now.
|
||||
* @retval kStatus_SDMMC_ConfigureExtendedCsdFailed Configure EXT_CSD failed.
|
||||
* @retval kStatus_SDMMC_ConfigureBootFailed Configure boot failed.
|
||||
* @retval kStatus_Success Operate successfully.
|
||||
*/
|
||||
status_t MMC_SetBootConfig(mmc_card_t *card, const mmc_boot_config_t *config);
|
||||
|
||||
/*!
|
||||
* @brief MMC card start boot.
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
* @param mmcConfig mmc Boot configuration structure.
|
||||
* @param buffer address to recieve data.
|
||||
* @param hostConfig host boot configurations.
|
||||
* @retval kStatus_Fail fail.
|
||||
* @retval kStatus_SDMMC_TransferFailed transfer fail.
|
||||
* @retval kStatus_SDMMC_GoIdleFailed reset card fail.
|
||||
* @retval kStatus_Success Operate successfully.
|
||||
*/
|
||||
status_t MMC_StartBoot(mmc_card_t *card,
|
||||
const mmc_boot_config_t *mmcConfig,
|
||||
uint8_t *buffer,
|
||||
SDMMCHOST_BOOT_CONFIG *hostConfig);
|
||||
|
||||
/*!
|
||||
* @brief MMC card set boot configuration write protect.
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
* @param wp write protect value.
|
||||
*/
|
||||
status_t MMC_SetBootConfigWP(mmc_card_t *card, uint8_t wp);
|
||||
|
||||
/*!
|
||||
* @brief MMC card continous read boot data.
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
* @param buffer buffer address.
|
||||
* @param hostConfig host boot configurations.
|
||||
*/
|
||||
status_t MMC_ReadBootData(mmc_card_t *card, uint8_t *buffer, SDMMCHOST_BOOT_CONFIG *hostConfig);
|
||||
|
||||
/*!
|
||||
* @brief MMC card stop boot mode.
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
* @param bootMode boot mode.
|
||||
*/
|
||||
status_t MMC_StopBoot(mmc_card_t *card, uint32_t bootMode);
|
||||
|
||||
/*!
|
||||
* @brief MMC card set boot partition write protect.
|
||||
*
|
||||
* @param card Card descriptor.
|
||||
* @param bootPartitionWP boot partition write protect value.
|
||||
*/
|
||||
status_t MMC_SetBootPartitionWP(mmc_card_t *card, mmc_boot_partition_wp_t bootPartitionWP);
|
||||
|
||||
/* @} */
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
/*! @} */
|
||||
#endif /* _FSL_MMC_H_*/
|