[bsp] add imx6ull smart board bsp (#7716)

This commit is contained in:
Bernard Xiong
2023-06-27 08:20:45 +08:00
committed by GitHub
parent 6c55d81120
commit ce4a9c324d
139 changed files with 260863 additions and 0 deletions

File diff suppressed because it is too large Load Diff

5
bsp/imx/imx6ull-smart/.gitignore vendored Normal file
View File

@@ -0,0 +1,5 @@
*.img
*.imx
*.bin
*.elf
*.map

View File

@@ -0,0 +1,45 @@
mainmenu "RT-Thread Project Configuration"
config BSP_DIR
string
option env="BSP_ROOT"
default "."
config RTT_DIR
string
option env="RTT_ROOT"
default "../../.."
config PKGS_DIR
string
option env="PKGS_ROOT"
default "packages"
source "$RTT_DIR/Kconfig"
source "$PKGS_DIR/Kconfig"
config SOC_IMX6ULL
bool
select ARCH_ARM_CORTEX_A7
select RT_USING_CACHE
select ARCH_ARM_MMU
select RT_USING_COMPONENTS_INIT
select RT_USING_USER_MAIN
select RT_USING_FPU
select RT_USING_GIC_V2
default y
if SOC_IMX6ULL
config CPU_MCIMX6Y2CVM05
bool
default y
config FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL
depends on RT_USING_CACHE
int
default 1
config FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL
int "Disable Clock control in fsl files"
default 1
endif
source "$BSP_DIR/drivers/Kconfig"

View File

@@ -0,0 +1,41 @@
# RT-Thread Smart for i.MX6ULL
这是一份ART-pi smart开发板的BSP支持smart模式也支持传统的RTOS模式
ART-pi smart采用了米尔科技的imx6ull核心板硬件由韦东山团队完成由社区来完成整体的BSP。硬件规格情况如下
![硬件资源](figures/hw_resources.png)
## 如何编译
如果使用smart的模式请使用smart sdk环境然后进入到这个bsp目录执行
```bash
scons
```
进行编译;
如果使用RTOS模式请确保在menuconfig中不选择smart模式然后执行
```bash
scons
```
进行编译。
## 如何运行
* 从eMMC中加载运行
```bash
bootcmd=fatload mmc 1:1 0x80001000 /kernel/rtthread.bin; dcache flush; go 0x80001000
```
* 网络方式启动
```bash
tftp 0x80001000 rtthread.bin
dcache flush
go 0x80001000
```

View File

@@ -0,0 +1,14 @@
# for module compiling
import os
from building import *
cwd = GetCurrentDir()
objs = []
list = os.listdir(cwd)
for d in list:
path = os.path.join(cwd, d)
if os.path.isfile(os.path.join(path, 'SConscript')):
objs = objs + SConscript(os.path.join(d, 'SConscript'))
Return('objs')

View File

@@ -0,0 +1,43 @@
import os
import sys
import rtconfig
import re
RTT_ROOT = os.getenv('RTT_ROOT') or os.path.join('..', '..', '..')
sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')]
from building import *
TARGET = 'rtthread.' + rtconfig.TARGET_EXT
content = ""
TRACE_CONFIG = ''
with open("rtconfig.h") as f:
for line in f.readlines():
if line.find("RT_BACKTRACE_FUNCTION_NAME") != -1:
for token in line.split(" "):
if re.match(r'RT_BACKTRACE_FUNCTION_NAME$', token, flags=0):
TRACE_CONFIG = " -mpoke-function-name"
DefaultEnvironment(tools=[])
env = Environment(tools = ['mingw'],
AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS + TRACE_CONFIG,
CC = rtconfig.CC, CFLAGS = rtconfig.CFLAGS + TRACE_CONFIG,
CXX = rtconfig.CXX, CXXFLAGS = rtconfig.CXXFLAGS + TRACE_CONFIG,
AR = rtconfig.AR, ARFLAGS = '-rc',
LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS)
env.PrependENVPath('PATH', rtconfig.EXEC_PATH)
env['ASCOM'] = env['ASPPCOM']
env['LINKCOM'] = '$LINK -o $TARGET $LINKFLAGS $__RPATH $SOURCES $_LIBDIRFLAGS -Wl,--start-group $_LIBFLAGS -Wl,--end-group'
Export('RTT_ROOT')
Export('rtconfig')
# prepare building environment
objs = PrepareBuilding(env, RTT_ROOT)
if GetDepend('RT_USING_SMART'):
# use smart link.lds
env['LINKFLAGS'] = env['LINKFLAGS'].replace('link.lds', 'link_smart.lds')
# make a building
DoBuilding(TARGET, objs)

View File

@@ -0,0 +1,11 @@
Import('RTT_ROOT')
Import('rtconfig')
from building import *
cwd = GetCurrentDir()
src = Glob('*.c') + Glob('*.cpp')
CPPPATH = [cwd]
group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH)
Return('group')

View File

@@ -0,0 +1,50 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022/01/20 bernard the first version
*/
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <rtthread.h>
#include <msh.h>
int em_init(void)
{
int count = 5;
char *em_cmd = "/services/em.elf &";
while (count --)
{
int fd;
fd = open("/services/em.elf", O_RDONLY);
if (fd >= 0)
{
close(fd);
msh_exec(em_cmd, rt_strlen(em_cmd) + 1);
return 0;
}
else
{
rt_thread_mdelay(500);
}
}
if (count <= 0)
{
printf("open em failed!\n");
}
return -1;
}
INIT_APP_EXPORT(em_init);

View File

@@ -0,0 +1,134 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
*/
#include <rtthread.h>
#if defined(RT_USING_DFS)
#include <dfs.h>
#include <dfs_fs.h>
#include <dfs_file.h>
#include <ioremap.h>
#include <drv_sdio.h>
#define DBG_TAG "app.filesystem"
#define DBG_LVL DBG_INFO
#include <rtdbg.h>
void filesysytem_try_mount(char *device_name, char *mount_point, char *fs_type_name, int mkfs_count)
{
struct statfs fs_stat;
int rc = 0;
LOG_I("mount(\"%s\",\"%s\",\"%s\");", device_name, mount_point, fs_type_name);
if (rt_device_find(device_name) == NULL)
{
LOG_I("%s not find!!!", device_name);
return;
}
mkdir(mount_point, 0);
_remount:
rc = dfs_mount(device_name, mount_point, fs_type_name, 0, 0);
if (rc == 0)
{
LOG_I("mounted %s on %s", device_name, mount_point);
if (dfs_statfs(mount_point, &fs_stat) >= 0)
{
LOG_I("%s size:%d, total: %d, free: %d", mount_point,
fs_stat.f_bsize, fs_stat.f_blocks, fs_stat.f_bfree);
}
}
else
{
if (mkfs_count > 0)
{
LOG_I("[%s]try mkfs -t %s %s ", mkfs_count, fs_type_name, device_name);
dfs_mkfs(fs_type_name, device_name);
mkfs_count--;
goto _remount;
}
LOG_I("mount failed :%d ", rc);
}
}
void filesysytem_try_unmount(char *mount_point)
{
struct stat filestat = {0};
LOG_I("unmount(\"%s\");", mount_point);
if ((dfs_file_stat(mount_point, &filestat) >= 0) && (S_ISDIR(filestat.st_mode)))
{
dfs_unmount(mount_point);
}
}
static void sd_task_entry(void *parameter)
{
volatile unsigned int *IN_STATUS;
IN_STATUS = (volatile unsigned int *)rt_ioremap((void *)0x2190030, 4); // cd status
int change = 0;
while (1)
{
rt_thread_mdelay(200);
change = 0;
if (((*IN_STATUS >> 6) & 0x1) == 1)
{
*IN_STATUS = 0x40;
change = 1;
}
if (((*IN_STATUS >> 7) & 0x1) == 1)
{
*IN_STATUS = (0x80);
change = 2;
}
if (change > 0)
{
LOG_D("sdio host change: %d", change);
mmcsd_wait_cd_changed(0); // clear
host_change(); // send cd change to host
int result = mmcsd_wait_cd_changed(RT_TICK_PER_SECOND);
if (result == MMCSD_HOST_PLUGED)
{
LOG_D("mmcsd change pluged");
filesysytem_try_mount("sd0", "/mnt/sd0", "elm", 0);
}
else if (result == MMCSD_HOST_UNPLUGED)
{
LOG_D("mmcsd change unpluged");
filesysytem_try_unmount("/mnt/sd0");
}
else
{
LOG_I("mmcsd wait_cd_changed %d", result);
}
}
}
}
int sd_task_init(void)
{
rt_thread_t tid;
tid = rt_thread_create("tsdcard", sd_task_entry, RT_NULL,
2048, RT_THREAD_PRIORITY_MAX - 2, 20);
if (tid != RT_NULL)
{
rt_thread_startup(tid);
}
else
{
LOG_E("create sd mount task error!");
}
return RT_EOK;
}
INIT_APP_EXPORT(sd_task_init);
#endif

View File

@@ -0,0 +1,34 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022/01/20 bernard the first version
*/
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <rtthread.h>
#ifdef PKG_USING_RW007
#define WIFI_SH_PATH "/sd/wifi.sh"
int rw007_wifi_init(void)
{
if (access(WIFI_SH_PATH, 0) != -1)
{
msh_exec(WIFI_SH_PATH, rt_strlen(WIFI_SH_PATH));
}
else
{
rt_kprintf("%s wi-fi configuration file not exist in sd card!\n", WIFI_SH_PATH);
}
return 0
}
INIT_APP_EXPORT(rw007_wifi_init);
#endif

View File

@@ -0,0 +1,19 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020/10/7 bernard the first version
*/
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
printf("hello rt-smart\n");
return 0;
}

View File

@@ -0,0 +1,57 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
*/
#include <rtthread.h>
#ifdef RT_USING_DFS
#include <dfs_fs.h>
#include <dfs_romfs.h>
int mnt_init(void)
{
#ifdef RT_USING_SDIO2
rt_thread_mdelay(500);
int part_id = 0;
if (dfs_mount("emmc0", "/", "elm", 0, (void *)part_id) != 0)
{
rt_kprintf("Dir / emmc mount failed!\n");
return -1;
}
else
{
rt_kprintf("emmc file system initialization done!\n");
}
part_id = 0;
if (dfs_mount("sd0", "/mnt/sd0", "elm", 0, (void *)part_id) != 0)
{
rt_kprintf("Dir /mnt/sd0 mount failed!\n");
return -1;
}
else
{
rt_kprintf("sd0 file system initialization done!\n");
}
#else
rt_thread_mdelay(500);
if (dfs_mount(NULL, "/", "rom", 0, &romfs_root) != 0)
{
rt_kprintf("Dir / mount failed!\n");
return -1;
}
rt_kprintf("file system initialization done!\n");
#endif
return 0;
}
INIT_ENV_EXPORT(mnt_init);
#endif

View File

@@ -0,0 +1,20 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020/10/7 bernard the first version
*/
#include <dfs_romfs.h>
static const struct romfs_dirent _romfs_root[] = {
{ROMFS_DIRENT_DIR, "bin", RT_NULL, 0},
{ROMFS_DIRENT_DIR, "dev", RT_NULL, 0},
{ROMFS_DIRENT_DIR, "etc", RT_NULL, 0},
{ROMFS_DIRENT_DIR, "mnt", RT_NULL, 0},
};
const struct romfs_dirent romfs_root = {
ROMFS_DIRENT_DIR, "/", (rt_uint8_t *)_romfs_root, sizeof(_romfs_root) / sizeof(_romfs_root[0])};

View File

@@ -0,0 +1,242 @@
menu "Platform Driver Configuration"
menu "Select UART Driver"
if RT_USING_SERIAL
config BSP_USING_UART1
bool "Enable UART1"
default y
config BSP_USING_UART2
bool "Enable UART2"
default n
config BSP_USING_UART3
bool "Enable UART3"
default n
config BSP_USING_UART4
bool "Enable UART4"
default n
config BSP_USING_UART5
bool "Enable UART5"
default n
config BSP_USING_UART6
bool "Enable UART6"
default n
config BSP_USING_UART7
bool "Enable UART7"
default n
config BSP_USING_UART8
bool "Enable UART8"
default n
endif
endmenu
menu "Select SPI Driver"
config BSP_USING_SPI
bool "Enable SPI"
select RT_USING_SPI
default n
if BSP_USING_SPI
config BSP_USING_SPI1
bool "Enable SPI1"
default n
config BSP_USING_SPI2
bool "Enable SPI2"
default n
config BSP_USING_SPI3
bool "Enable SPI3"
default y
config BSP_USING_SPI4
bool "Enable SPI4"
default n
endif
endmenu
menu "Select I2C Driver"
config BSP_USING_I2C
bool "Enable I2C"
select RT_USING_I2C
default n
if BSP_USING_I2C
config BSP_USING_I2C1
bool "Enable I2C1"
default n
if BSP_USING_I2C1
config I2C1_BAUD_RATE
int "Set i2c1 baud rate (HZ)"
default 100000
endif
config BSP_USING_I2C2
bool "Enable I2C2"
default n
if BSP_USING_I2C2
config I2C2_BAUD_RATE
int "Set i2c2 baud rate (HZ)"
default 100000
endif
config BSP_USING_I2C3
bool "Enable I2C3"
default n
if BSP_USING_I2C3
config I2C3_BAUD_RATE
int "Set i2c3 baud rate (HZ)"
default 100000
endif
config BSP_USING_I2C4
bool "Enable I2C4"
default n
if BSP_USING_I2C4
config I2C4_BAUD_RATE
int "Set i2c4 baud rate (HZ)"
default 100000
endif
endif
endmenu
menu "Select LCD Driver"
config BSP_USING_LCD
bool "Enable LCD"
select RT_USING_LCD
default y
if BSP_USING_LCD
config BSP_LCD_WIDTH
int "Width of LCD panel"
default 1000
config BSP_LCD_HEIGHT
int "Height of LCD panel"
default 600
config BSP_LCD_VSW
int "value of LCD_VSW"
default 2
config BSP_LCD_VBP
int "value of LCD_VBP"
default 23
config BSP_LCD_VFP
int "value of LCD_VFP"
default 22
config BSP_LCD_HSW
int "value of LCD_HSW"
default 2
config BSP_LCD_HBP
int "value of LCD_HBP"
default 46
config BSP_LCD_HFP
int "value of LCD_HFP"
default 210
config BSP_LCD_PLL_DIV
int "value of PLL DIV"
default 8
endif
endmenu
menu "Select SDHC Driver"
if RT_USING_SDIO
config RT_USING_SDIO1
bool "Enable SDHC1"
default n
config RT_USING_SDIO2
bool "Enable SDHC2"
default n
endif
endmenu
menu "Select RTC Driver"
if RT_USING_RTC
config BSP_USING_ONCHIP_RTC
bool "Enable On-Chip RTC"
default y
endif
endmenu
menu "Select PWM Driver"
config RT_USING_PWM
bool "Enable PWM"
default n
if RT_USING_PWM
config BSP_USING_PWM1
bool "Enable PWM1"
default n
config BSP_USING_PWM2
bool "Enable PWM2"
default n
config BSP_USING_PWM3
bool "Enable PWM3"
default n
config BSP_USING_PWM4
bool "Enable PWM4"
default n
endif
endmenu
menu "Select ADC Driver"
config RT_USING_ADC
bool "Enable ADC"
default n
if RT_USING_ADC
config BSP_USING_ADC1_1
bool "Enable ADC1 CH1"
default n
config BSP_USING_ADC1_2
bool "Enable ADC1 CH2"
default n
config BSP_USING_ADC1_3
bool "Enable ADC1 CH3"
default n
config BSP_USING_ADC1_4
bool "Enable ADC1 CH4"
default n
endif
endmenu
menu "Select WDT Driver"
if RT_USING_WDT
config RT_USING_WDT1
bool "Enable WDT1"
default n
config RT_USING_WDT2
bool "Enable WDT2"
default n
config RT_USING_WDT3
bool "Enable WDT3"
default n
endif
endmenu
menu "Select ENET Driver"
config RT_USING_ENET1
bool "Enable ENET1"
default y
config RT_USING_ENET2
bool "Enable ENET2"
default n
endmenu
menu "Select Wifi Driver"
config RT_USING_WIFI_RW007
bool "Enable wifi RW007"
select BSP_USING_SPI2
select PKG_USING_RW007
select RT_USING_WIFI
default n
if RT_USING_WIFI_RW007
config RW007_DAFAULT_SSID
string "default ssid"
default "rt-thread"
config RW007_DAFAULT_PASSWARD
string "default passward"
default "12345678"
endif
endmenu
menu "Select USB Driver"
config BSP_USING_USB_DEVICE
bool "Enable USB device"
default y
endmenu
endmenu

View File

@@ -0,0 +1,22 @@
from building import *
cwd = GetCurrentDir()
src = Glob('*.c') + Glob('iomux/*.c')
if GetDepend(['BSP_USING_USB_DEVICE']):
src += Glob('usb/device/*.c')
src += Glob('usb/phy/*.c')
list = os.listdir(cwd)
CPPPATH = [cwd]
objs = []
group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH)
for d in list:
path = os.path.join(cwd, d)
if os.path.isfile(os.path.join(path, 'SConscript')):
objs = objs + SConscript(os.path.join(d, 'SConscript'))
objs = objs + group
Return('objs')

View File

@@ -0,0 +1,133 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2012-11-20 Bernard the first version
* 2018-11-22 Jesven add rt_hw_spin_lock
* add rt_hw_spin_unlock
* add smp ipi init
*/
#include <rthw.h>
#include <rtthread.h>
#include <rtdbg.h>
#include "board.h"
#include "mm_aspace.h"
#include <mmu.h>
#ifdef RT_USING_SMART
#include <page.h>
#include <lwp_arch.h>
#endif
#ifdef RT_USING_SMART
extern size_t MMUTable[];
struct mem_desc platform_mem_desc[] = { /* 100ask_imx6ull ddr 512M */
{KERNEL_VADDR_START, KERNEL_VADDR_START + 0x1FFFFFFF, (rt_size_t)ARCH_MAP_FAILED, NORMAL_MEM}
};
#else
struct mem_desc platform_mem_desc[] = {
{0x00000000, 0x80000000, 0x00000000, DEVICE_MEM},
{0x80000000, 0xFFF00000, 0x80000000, NORMAL_MEM}
};
#endif
const rt_uint32_t platform_mem_desc_size = sizeof(platform_mem_desc)/sizeof(platform_mem_desc[0]);
void idle_wfi(void)
{
asm volatile ("wfi");
}
/**
* This function will initialize board
*/
#ifdef RT_USING_SMART
rt_region_t init_page_region = {
(uint32_t)PAGE_START,
(uint32_t)PAGE_END,
};
#endif
int board_reboot(int argc, char **argv)
{
wdog_config_t config;
SRC_Type *src = (SRC_Type*)g_src_vbase;
WDOG_Type *wdog = (WDOG_Type*)g_wdog1_vbase;
LOG_E("resetting ...\n");
rt_hw_ms_delay(50);
src->SCR &= ~SRC_SCR_WARM_RESET_ENABLE_MASK;
CLOCK_EnableClock(kCLOCK_Wdog1);
WDOG_GetDefaultConfig(&config);
config.timeoutValue = 0x00u;
WDOG_Init(wdog, &config);
while (1)
{
//waiting...
}
return 0;
}
MSH_CMD_EXPORT_ALIAS(board_reboot, reboot, reboot system);
void assert_handler(const char *ex_string, const char *func, rt_size_t line)
{
volatile char dummy = 0;
extern int list_thread(void);
extern void rt_backtrace(void);
list_thread();
rt_backtrace();
rt_kprintf("(%s) assertion failed at function:%s, line number:%d \n", ex_string, func, line);
while (dummy == 0)
;
}
#define PUTC(periph, ch) \
do { \
while (0 == (periph->USR2 & UART_USR2_TXDC_MASK)); \
periph->UTXD = ch; \
} while (0)
void rt_hw_board_init(void)
{
#ifdef RT_USING_SMART
rt_hw_mmu_map_init(&rt_kernel_space, (void*)0xf0000000, 0x10000000, MMUTable, PV_OFFSET);
rt_page_init(init_page_region);
rt_hw_mmu_ioremap_init(&rt_kernel_space, (void*)0xf0000000, 0x10000000);
arch_kuser_init(&rt_kernel_space, (void*)0xffff0000);
#else
rt_hw_mmu_map_init(&rt_kernel_space, (void*)0x80000000, 0x10000000, MMUTable, 0);
rt_hw_mmu_ioremap_init(&rt_kernel_space, (void*)0x80000000, 0x10000000);
#endif
/* initialize system heap */
rt_system_heap_init(HEAP_BEGIN, HEAP_END);
/* initialize hardware interrupt */
rt_hw_interrupt_init();
SystemAddressMapping();
SystemClockInit();
rt_components_board_init();
rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
rt_thread_idle_sethook(idle_wfi);
rt_assert_set_hook(assert_handler);
}

View File

@@ -0,0 +1,46 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
*/
#ifndef __BOARD_H__
#define __BOARD_H__
#include <rtconfig.h>
#include "imx6ull.h"
#include "mmu.h"
#if defined(__CC_ARM)
extern int Image$$RW_IRAM1$$ZI$$Limit;
#define HEAP_BEGIN ((void*)&Image$$RW_IRAM1$$ZI$$Limit)
#elif defined(__GNUC__)
extern int __bss_end;
#define HEAP_BEGIN ((void*)&__bss_end)
#endif
#ifdef RT_USING_SMART
#define HEAP_END (void*)(KERNEL_VADDR_START + 16 * 1024 * 1024)
#define PAGE_START HEAP_END
#define PAGE_END (void*)(KERNEL_VADDR_START + 128 * 1024 * 1024)
#else
#define HEAP_END (void*)(0x80000000 + 64 * 1024 * 1024)
#endif
/*
* memory map for peripherals
*/
/*
start addr - end addr , size
0x0090_0000 - 0x0091_FFFF, 128KB, OCRAM
0x0200_0000 - 0x020F_FFFF, 1MB, AIPS-1
0x0210_0000 - 0x021F_FFFF, 1MB, AIPS-2
0x0220_0000 - 0x022F_FFFF, 1MB, AIPS-3
*/
void rt_hw_board_init(void);
#endif

View File

@@ -0,0 +1,235 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-12-20 Lyons first version
* 2021-06-24 RiceChen add spi and lcd clock config
*/
#include "board.h"
#include "fsl_clock.h"
#define _K_GPT_LOAD_VALUE RT_UINT32_MAX
/* only used by MCIMX6Y2.h */
uint32_t *g_ccm_vbase = (uint32_t*)IMX6ULL_CCM_BASE;
uint32_t *g_ccm_analog_vbase = (uint32_t*)IMX6ULL_CCM_ANALOGY_BASE;
uint32_t *g_pmu_vbase = (uint32_t*)IMX6ULL_PMU_BASE;
uint32_t g_usbphy1_base = IMX6ULL_USBPHY1_BASE;
uint32_t g_usbphy2_base = IMX6ULL_USBPHY2_BASE;
uint32_t g_usb1_base = IMX6ULL_USB1_BASE;
uint32_t g_usb2_base = IMX6ULL_USB2_BASE;
uint32_t g_usb_analog_base = IMX6ULL_USB_ANALOG_BASE;
/* used by all files */
uint32_t *g_iomuxc_vbase = (uint32_t*)IMX6ULL_IOMUXC_BASE;
uint32_t *g_iomuxc_snvs_vbase = (uint32_t*)IMX6ULL_IOMUXC_SNVS_BASE;
uint32_t *g_src_vbase = (uint32_t*)IMX6ULL_SRC_BASE;
uint32_t *g_wdog1_vbase = (uint32_t*)IMX6ULL_WATCHDOG1_BASE;
uint32_t *g_snvs_vbase = (uint32_t*)IMX6ULL_SNVS_BASE;
_internal_rw uint32_t *_s_gpt1_vbase = (uint32_t*)IMX6ULL_GPT1_BASE;
static void _clk_enable( CCM_Type *base )
{
base->CCGR0 = 0XFFFFFFFF;
base->CCGR1 = 0XFFFFFFFF;
base->CCGR2 = 0XFFFFFFFF;
base->CCGR3 = 0XFFFFFFFF;
base->CCGR4 = 0XFFFFFFFF;
base->CCGR5 = 0XFFFFFFFF;
base->CCGR6 = 0XFFFFFFFF;
}
void BOARD_BootClockRUN(void)
{
rt_uint32_t reg_value;
/* Boot ROM did initialize the XTAL, here we only sets external XTAL OSC freq */
CLOCK_SetXtalFreq(24000000U);
CLOCK_SetRtcXtalFreq(32768U);
/*
* ARM_CLK from 'pll1_sw_clk', whitch from 'pll1_main_clk' or 'step_clk'
* if edit 'pll1_main_clk', switch to 'step_clk' first
*/
reg_value = CCM->CCSR;
if (0 == (reg_value & CCM_CCSR_PLL1_SW_CLK_SEL_MASK)) //if sel 'pll1_main_clk'
{
reg_value &= ~CCM_CCSR_STEP_SEL_MASK;
reg_value |= CCM_CCSR_STEP_SEL(0); //sel 'osc_clk(24M)'
reg_value |= CCM_CCSR_PLL1_SW_CLK_SEL(1); //sel 'step_clk'
CCM->CCSR = reg_value;
}
/*
* set PLL1(ARM PLL) at 1056MHz
* set ARM_CLK at 528MHz
* PLL output frequency = Fref * DIV_SEL / 2
* = 24M * DIV_SEL / 2 = 1056M
*/
CCM_ANALOG->PLL_ARM = CCM_ANALOG_PLL_ARM_ENABLE(1)
| CCM_ANALOG_PLL_ARM_DIV_SELECT(88);
reg_value = CCM->CCSR;
reg_value &= ~CCM_CCSR_PLL1_SW_CLK_SEL_MASK;
reg_value |= CCM_CCSR_PLL1_SW_CLK_SEL(0); //resel 'pll1_main_clk'
CCM->CCSR = reg_value;
CCM->CACRR = CCM_CACRR_ARM_PODF(1); //'CACRR[ARM_PODF]=0b001' divide by 2
/*
* set PLL2(System PLL) at fixed 528MHz
* PLL2_PFD0: 528M * 18 / FRAC
* PLL2_PFD1: 528M * 18 / FRAC
* PLL2_PFD2: 528M * 18 / FRAC
* PLL2_PFD3: 528M * 18 / FRAC
*/
reg_value = CCM_ANALOG->PFD_528;
reg_value &= ~0x3F3F3F3F;
reg_value |= CCM_ANALOG_PFD_528_SET_PFD0_FRAC(27); //27: 352MHz
reg_value |= CCM_ANALOG_PFD_528_SET_PFD1_FRAC(16); //16: 594MHz
reg_value |= CCM_ANALOG_PFD_528_SET_PFD2_FRAC(24); //24: 396MHz
reg_value |= CCM_ANALOG_PFD_528_SET_PFD3_FRAC(32); //32: 297MHz
CCM_ANALOG->PFD_528 = reg_value;
/*
* set PLL3(USB PLL) at fixed 480MHz
* PLL3_PFD0: 480M * 18 / FRAC
* PLL3_PFD1: 480M * 18 / FRAC
* PLL3_PFD2: 480M * 18 / FRAC
* PLL3_PFD3: 480M * 18 / FRAC
*/
reg_value = CCM_ANALOG->PFD_480;
reg_value &= ~0x3F3F3F3F;
reg_value |= CCM_ANALOG_PFD_480_SET_PFD0_FRAC(12); //12: 720MHz
reg_value |= CCM_ANALOG_PFD_480_SET_PFD1_FRAC(16); //16: 540MHz
reg_value |= CCM_ANALOG_PFD_480_SET_PFD2_FRAC(17); //17: 508.24MHz
reg_value |= CCM_ANALOG_PFD_480_SET_PFD3_FRAC(19); //19: 457.74MHz
CCM_ANALOG->PFD_480 = reg_value;
/*
* set PERCLK_CLK at 66MHz from IPG_CLK
*/
reg_value = CCM->CSCMR1;
reg_value &= ~CCM_CSCMR1_PERCLK_CLK_SEL_MASK;
reg_value |= CCM_CSCMR1_PERCLK_CLK_SEL(0); //sel IPG_CLK
reg_value &= ~CCM_CSCMR1_PERCLK_PODF_MASK;
reg_value |= CCM_CSCMR1_PERCLK_PODF(0); //'CSCMR1[PERCLK_PODF]=0b000000' divide by 1
CCM->CSCMR1 = reg_value;
CLOCK_DeinitAudioPll();
CLOCK_DeinitVideoPll();
CLOCK_DeinitEnetPll();
/* Configure UART divider to default */
CLOCK_SetMux(kCLOCK_UartMux, 0); /* Set UART source to PLL3 80M */
CLOCK_SetDiv(kCLOCK_UartDiv, 0); /* Set UART divider to 1 */
/* Configure ECSPI divider to default */
CLOCK_SetMux(kCLOCK_EcspiMux, 0); /* Set ECSPI source to PLL3 60M */
CLOCK_SetDiv(kCLOCK_EcspiDiv, 0); /* Set ECSPI divider to 1 */
/* Set LCDIF_PRED. */
CLOCK_SetDiv(kCLOCK_Lcdif1PreDiv, 2);
/* Set LCDIF_CLK_PODF. */
CLOCK_SetDiv(kCLOCK_Lcdif1Div, 4);
/* Set Lcdif pre clock source. */
CLOCK_SetMux(kCLOCK_Lcdif1PreMux, 2);
CLOCK_SetMux(kCLOCK_Lcdif1Mux, 0);
}
void BOARD_DelayInit(void)
{
GPT_Type *_GPT = (GPT_Type*)_s_gpt1_vbase;
_GPT->CR = 0;
_GPT->CR = GPT_CR_SWR(1);
while (_GPT->CR & GPT_CR_SWR_MASK);
/*
* 000 No clock
* 001 derive clock from ipg_clk
* 010 derive clock from ipg_clk_highfreq
* 011 derive clock from External Clock
* 100 derive clock from ipg_clk_32k
* 101 derive clock from ipg_clk_24M
*/
_GPT->CR = GPT_CR_CLKSRC(0x1);
_GPT->PR = GPT_PR_PRESCALER(65); //Set GPT1 Clock to 66MHz/66 = 1MHz
_GPT->OCR[0] = GPT_OCR_COMP(_K_GPT_LOAD_VALUE);
_GPT->CR |= GPT_CR_EN(1);
}
//execution before SystemClockInit called
void SystemAddressMapping(void)
{
g_ccm_vbase = (uint32_t*)platform_get_periph_vaddr((rt_uint32_t)g_ccm_vbase);
g_ccm_analog_vbase = (uint32_t*)platform_get_periph_vaddr((rt_uint32_t)g_ccm_analog_vbase);
g_pmu_vbase = (uint32_t*)platform_get_periph_vaddr((rt_uint32_t)g_pmu_vbase);
g_iomuxc_vbase = (uint32_t*)platform_get_periph_vaddr((rt_uint32_t)g_iomuxc_vbase);
g_iomuxc_snvs_vbase = (uint32_t*)platform_get_periph_vaddr((rt_uint32_t)g_iomuxc_snvs_vbase);
g_src_vbase = (uint32_t*)platform_get_periph_vaddr((rt_uint32_t)g_src_vbase);
g_wdog1_vbase = (uint32_t*)platform_get_periph_vaddr((rt_uint32_t)g_wdog1_vbase);
g_snvs_vbase = (uint32_t*)platform_get_periph_vaddr((rt_uint32_t)g_snvs_vbase);
_s_gpt1_vbase = (uint32_t*)platform_get_periph_vaddr((rt_uint32_t)_s_gpt1_vbase);
g_usbphy1_base = (uint32_t)platform_get_periph_vaddr((rt_uint32_t)g_usbphy1_base);
g_usbphy2_base = (uint32_t)platform_get_periph_vaddr((rt_uint32_t)g_usbphy2_base);
g_usb1_base = (uint32_t)platform_get_periph_vaddr((rt_uint32_t)g_usb1_base);
g_usb2_base = (uint32_t)platform_get_periph_vaddr((rt_uint32_t)g_usb2_base);
g_usb_analog_base = (uint32_t)platform_get_periph_vaddr((rt_uint32_t)g_usb_analog_base);
}
void SystemClockInit(void)
{
BOARD_BootClockRUN();
BOARD_DelayInit();
_clk_enable(CCM);
}
void rt_hw_us_delay(uint32_t us)
{
GPT_Type *_GPT = (GPT_Type*)_s_gpt1_vbase;
rt_uint64_t old_cnt, new_cnt;
rt_uint64_t total = 0;
old_cnt = _GPT->CNT;
while (1)
{
new_cnt = _GPT->CNT;
if (old_cnt != new_cnt)
{
if (new_cnt > old_cnt)
{
total += (new_cnt - old_cnt);
} else {
total += (new_cnt + _K_GPT_LOAD_VALUE - old_cnt);
}
old_cnt = new_cnt;
if (total >= us)
break;
}
}
}
void rt_hw_ms_delay(uint32_t ms)
{
while (ms--)
{
rt_hw_us_delay(1000);
}
}

View File

@@ -0,0 +1,26 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-12-20 Lyons first version
*/
#ifndef __BSP_CLOCK_H__
#define __BSP_CLOCK_H__
extern uint32_t *g_iomuxc_vbase;
extern uint32_t *g_iomuxc_snvs_vbase;
extern uint32_t *g_src_vbase;
extern uint32_t *g_wdog1_vbase;
extern uint32_t *g_snvs_vbase;
void SystemAddressMapping(void);
void SystemClockInit(void);
void rt_hw_us_delay(uint32_t us);
void rt_hw_ms_delay(uint32_t ms);
#endif //#ifndef __BSP_CLOCK_H__

View File

@@ -0,0 +1,244 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2019-04-28 tyustli first version
*
*/
#include <rtthread.h>
#define RT_USING_ADC
#ifdef RT_USING_ADC
#define LOG_TAG "drv.adc"
#include <drv_log.h>
#include <rtdevice.h>
#include <ioremap.h>
#include "fsl_adc.h"
#include "drv_adc.h"
#include <drv_common.h>
#include <drivers/adc.h>
static rt_err_t imx6ull_adc_enabled(struct rt_adc_device *device, rt_uint32_t channel, rt_bool_t enabled)
{
return RT_EOK;
}
static rt_err_t imx6ull_adc_convert(struct rt_adc_device *device, rt_uint32_t channel, rt_uint32_t *value)
{
adc_channel_config_t adc_channel;
ADC_Type *base;
base = (ADC_Type *)(device->parent.user_data);
adc_channel.channelNumber = channel;
adc_channel.enableInterruptOnConversionCompleted = 0;
ADC_SetChannelConfig(base, 0, &adc_channel);
while (0U == ADC_GetChannelStatusFlags(base, 0))
{
continue;
}
*value = ADC_GetChannelConversionValue(base, 0);
return RT_EOK;
}
#if defined(BSP_USING_ADC1_1) || defined(BSP_USING_ADC1_2) || defined(BSP_USING_ADC1_3) || defined(BSP_USING_ADC1_4)
static struct rt_adc_ops imx6ull_adc_ops =
{
.enabled = imx6ull_adc_enabled,
.convert = imx6ull_adc_convert,
};
#endif
int imx6ull_adc_gpio_init(void)
{
#ifdef BSP_USING_ADC1_1
do {
struct imx6ull_iomuxc gpio;
uint32_t pin_fun_id[5]={IOMUXC_GPIO1_IO01_GPIO1_IO01};
gpio.muxRegister = pin_fun_id[0];
gpio.muxMode = pin_fun_id[1];
gpio.inputRegister = pin_fun_id[2];
gpio.inputDaisy = pin_fun_id[3];
gpio.configRegister = pin_fun_id[4];
gpio.inputOnfield = 0;
gpio.configValue = IOMUXC_SW_PAD_CTL_PAD_DSE(2U) | IOMUXC_SW_PAD_CTL_PAD_SPEED(2U);
imx6ull_gpio_init(&gpio);
}while(0);
#endif
#ifdef BSP_USING_ADC1_2
do {
struct imx6ull_iomuxc gpio;
uint32_t pin_fun_id[5]={IOMUXC_GPIO1_IO02_GPIO1_IO02};
gpio.muxRegister = pin_fun_id[0];
gpio.muxMode = pin_fun_id[1];
gpio.inputRegister = pin_fun_id[2];
gpio.inputDaisy = pin_fun_id[3];
gpio.configRegister = pin_fun_id[4];
gpio.inputOnfield = 0;
gpio.configValue = IOMUXC_SW_PAD_CTL_PAD_DSE(2U) | IOMUXC_SW_PAD_CTL_PAD_SPEED(2U);
imx6ull_gpio_init(&gpio);
}while(0);
#endif
#ifdef BSP_USING_ADC1_3
do {
struct imx6ull_iomuxc gpio;
uint32_t pin_fun_id[5]={IOMUXC_GPIO1_IO03_GPIO1_IO03};
gpio.muxRegister = pin_fun_id[0];
gpio.muxMode = pin_fun_id[1];
gpio.inputRegister = pin_fun_id[2];
gpio.inputDaisy = pin_fun_id[3];
gpio.configRegister = pin_fun_id[4];
gpio.inputOnfield = 0;
gpio.configValue = IOMUXC_SW_PAD_CTL_PAD_DSE(2U) | IOMUXC_SW_PAD_CTL_PAD_SPEED(2U);
imx6ull_gpio_init(&gpio);
}while(0);
#endif
#ifdef BSP_USING_ADC1_4
do {
struct imx6ull_iomuxc gpio;
uint32_t pin_fun_id[5]={IOMUXC_GPIO1_IO04_GPIO1_IO04};
gpio.muxRegister = pin_fun_id[0];
gpio.muxMode = pin_fun_id[1];
gpio.inputRegister = pin_fun_id[2];
gpio.inputDaisy = pin_fun_id[3];
gpio.configRegister = pin_fun_id[4];
gpio.inputOnfield = 0;
gpio.configValue = IOMUXC_SW_PAD_CTL_PAD_DSE(2U) | IOMUXC_SW_PAD_CTL_PAD_SPEED(2U);
imx6ull_gpio_init(&gpio);
}while(0);
#endif
return 0;
}
int rt_hw_adc_init(void)
{
rt_err_t ret = RT_EOK;
imx6ull_adc_gpio_init();
#if defined(BSP_USING_ADC1_1) || defined(BSP_USING_ADC1_2) || defined(BSP_USING_ADC1_3) || defined(BSP_USING_ADC1_4)
static adc_config_t ADC1_config_value;
static struct rt_adc_device adc1_device;
ADC_Type *adc1_base;
adc1_base = (ADC_Type *)rt_ioremap((void*)ADC1, 0x1000);
ADC_GetDefaultConfig(&ADC1_config_value);
ADC_Init(adc1_base, &ADC1_config_value);
ADC_DoAutoCalibration(adc1_base);
ret = rt_hw_adc_register(&adc1_device, "adc1", &imx6ull_adc_ops, adc1_base);
if (ret != RT_EOK)
{
LOG_E("register adc1 device failed error code = %d\n", ret);
}
#endif
return ret;
}
INIT_DEVICE_EXPORT(rt_hw_adc_init);
void set_adc_default(void *parameter)
{
int result = 0;
result = result;
#ifdef BSP_USING_ADC1_1
do {
struct rt_adc_device *device = RT_NULL;
device = (struct rt_adc_device *)rt_device_find("adc1");
if (!device)
{
result = -RT_EIO;
return;
}
result = rt_adc_enable(device, 1);
result = rt_adc_read(device, 1);
rt_kprintf("adc ch1 read result is %d\n",result);
} while(0);
#endif
#ifdef BSP_USING_ADC1_2
do {
struct rt_adc_device *device = RT_NULL;
device = (struct rt_adc_device *)rt_device_find("adc1");
if (!device)
{
result = -RT_EIO;
return;
}
result = rt_adc_enable(device, 2);
result = rt_adc_read(device, 2);
rt_kprintf("adc ch2 read result is %d\n",result);
} while(0);
#endif
#ifdef BSP_USING_ADC1_3
do {
struct rt_adc_device *device = RT_NULL;
device = (struct rt_adc_device *)rt_device_find("adc1");
if (!device)
{
result = -RT_EIO;
return;
}
result = rt_adc_enable(device, 3);
result = rt_adc_read(device, 3);
rt_kprintf("adc ch3 read result is %d\n",result);
} while(0);
#endif
#ifdef BSP_USING_ADC1_4
do {
struct rt_adc_device *device = RT_NULL;
device = (struct rt_adc_device *)rt_device_find("adc1");
if (!device)
{
result = -RT_EIO;
return;
}
result = rt_adc_enable(device, 4);
result = rt_adc_read(device, 4);
rt_kprintf("adc ch4 read result is %d\n",result);
} while(0);
#endif
}
static int set_adc_init(void)
{
rt_thread_t tid = rt_thread_create("adc_loop", set_adc_default, RT_NULL, 1024, 16, 20);
RT_ASSERT(tid != RT_NULL);
rt_thread_startup(tid);
return(RT_EOK);
}
INIT_APP_EXPORT(set_adc_init);
#endif /* BSP_USING_ADC */

View File

@@ -0,0 +1,18 @@
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2019-04-20 Lee the first version.
*/
#ifndef DRV_ADC_H__
#define DRV_ADC_H__
#include <rtdevice.h>
int rt_hw_adc_init(void);
#endif /* DRV_ADC_H__ */

View File

@@ -0,0 +1,43 @@
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-04-11 RiceChen the first version
*
*/
#include <rthw.h>
#include <rtdevice.h>
#include "board.h"
#include "mmu.h"
#include "ioremap.h"
#include "fsl_iomuxc.h"
#include "drv_common.h"
void *imx6ull_get_periph_vaddr(rt_uint32_t paddr)
{
return rt_ioremap((void *)paddr, sizeof(sizeof(rt_uint32_t)));
}
void *imx6ull_get_periph_paddr(rt_uint32_t vaddr)
{
return rt_kmem_v2p((void *)vaddr);
}
void imx6ull_gpio_init(const struct imx6ull_iomuxc *gpio)
{
rt_uint32_t mux_reg_vaddr = 0;
rt_uint32_t input_reg_vaddr = 0;
rt_uint32_t config_reg_vaddr = 0;
mux_reg_vaddr = (rt_uint32_t)(gpio->muxRegister ? (rt_uint32_t)imx6ull_get_periph_vaddr(gpio->muxRegister) : gpio->muxRegister);
input_reg_vaddr = (rt_uint32_t)(gpio->inputRegister ? (rt_uint32_t)imx6ull_get_periph_vaddr(gpio->inputRegister) : gpio->inputRegister);
config_reg_vaddr = (rt_uint32_t)(gpio->configRegister ? (rt_uint32_t)imx6ull_get_periph_vaddr(gpio->configRegister) : gpio->configRegister);
IOMUXC_SetPinMux(mux_reg_vaddr, gpio->muxMode, input_reg_vaddr, gpio->inputDaisy, config_reg_vaddr, gpio->inputOnfield);
IOMUXC_SetPinConfig(mux_reg_vaddr, gpio->muxMode, input_reg_vaddr, gpio->inputDaisy, config_reg_vaddr, gpio->configValue);
}

View File

@@ -0,0 +1,35 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-04-11 RiceChen the first version
*
*/
#ifndef __DRV_COMMON_H__
#define __DRV_COMMON_H__
#include <board.h>
struct imx6ull_iomuxc
{
rt_uint32_t muxRegister;
rt_uint32_t muxMode;
rt_uint32_t inputRegister;
rt_uint32_t inputDaisy;
rt_uint32_t configRegister;
rt_uint32_t inputOnfield;
rt_uint32_t configValue;
};
void *imx6ull_get_periph_vaddr(rt_uint32_t paddr);
void *imx6ull_get_periph_paddr(rt_uint32_t vaddr);
void imx6ull_gpio_init(const struct imx6ull_iomuxc *gpio);
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,58 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-06-16 songchao first version
* 2021-08-13 songchao add more device info
*/
#ifndef __DRV_ETH_H__
#define __DRV_ETH_H__
#include <rtthread.h>
#include <netif/ethernetif.h>
#include "fsl_phy.h"
#include "imx6ull.h"
#include "drv_common.h"
#ifdef __cplusplus
extern "C" {
#endif
#define MAX_ADDR_LEN 6
struct rt_imx6ul_ethps
{
/* inherit from ethernet device */
struct eth_device parent;
/* interface address info, hw address */
rt_uint8_t dev_addr[MAX_ADDR_LEN];
/* ETH_Speed */
uint32_t ETH_Speed;
/* ETH_Duplex_Mode */
uint32_t ETH_Mode;
rt_bool_t phy_link_status;
const char *mac_name;
const char *irq_name;
enum _imx_interrupts irq_num;
uint8_t phy_num;
const ENET_Type *enet_phy_base_addr;
ENET_Type *enet_virtual_base_addr;
uint32_t mac_num;
enet_buffer_config_t buffConfig;
enet_config_t config;
enet_handle_t handle;
struct imx6ull_iomuxc gpio[9];
GPIO_Type *phy_base_addr;
uint32_t phy_gpio_pin;
uint32_t phy_id;
};
int32_t get_instance_by_base(void *base);
#ifdef __cplusplus
}
#endif
#endif /* __DRV_ETH_H__ */

View File

@@ -0,0 +1,204 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-01-13 Lyons first version
* 2021-06-23 RiceChen refactor
*/
#include <rthw.h>
#include <rtdevice.h>
#ifdef BSP_USING_I2C
#define LOG_TAG "drv.i2c"
#include <drv_log.h>
#if !defined(BSP_USING_I2C1) && !defined(BSP_USING_I2C2) && !defined(BSP_USING_I2C3) && !defined(BSP_USING_I2C4)
#error "Please define at least one BSP_USING_I2Cx"
#endif
#include "fsl_iomuxc.h"
#include "drv_i2c.h"
static struct imx6ull_i2c_config i2c_config[] =
{
#ifdef BSP_USING_I2C1
I2C1_BUS_CONFIG,
#endif
#ifdef BSP_USING_I2C2
I2C2_BUS_CONFIG,
#endif
#ifdef BSP_USING_I2C3
I2C3_BUS_CONFIG,
#endif
#ifdef BSP_USING_I2C4
I2C4_BUS_CONFIG,
#endif
};
static struct imx6ull_i2c_bus i2c_obj[sizeof(i2c_config) / sizeof(i2c_config[0])];
static char i2c_buff_temp[4][1024];
extern uint32_t I2C_GetInstance(I2C_Type *base);
#ifdef IMX_I2C_IRQ_MODE
static uint32_t g_MasterCompletionFlag[4] = {0,0,0,0};
static void i2c_master_callback(I2C_Type *base, i2c_master_handle_t *handle, status_t status, void *userData)
{
/* Signal transfer success when received success status. */
struct imx6ull_i2c_config *config;
config = (struct imx6ull_i2c_config*)userData;
uint32_t instance = I2C_GetInstance(config->hw_base);
if (status == kStatus_Success)
{
g_MasterCompletionFlag[instance-1] = 1;
}
}
#endif
static rt_ssize_t imx6ull_i2c_mst_xfer(struct rt_i2c_bus_device *bus, struct rt_i2c_msg msgs[], rt_uint32_t num)
{
rt_ssize_t i = 0;
struct imx6ull_i2c_bus *i2c_bus = RT_NULL;
static i2c_master_transfer_t xfer = {0};
RT_ASSERT(bus != RT_NULL);
#ifdef IMX_I2C_IRQ_MODE
uint32_t timeout_cnt = 100;
#endif
uint32_t instance = 0;
i2c_bus = (struct imx6ull_i2c_bus *)bus;
instance = I2C_GetInstance(i2c_bus->config->hw_base);
for(i = 0 ;i < num; i++)
{
if(msgs[i].flags & RT_I2C_RD)
{
xfer.flags = kI2C_TransferNoStartFlag;
xfer.slaveAddress = msgs[i].addr;
xfer.direction = kI2C_Read;
xfer.subaddress = 0;
xfer.subaddressSize = 0;
xfer.data = (uint8_t *volatile)i2c_buff_temp[instance - 1];
xfer.dataSize = msgs[i].len ;
#ifdef IMX_I2C_IRQ_MODE
I2C_MasterTransferNonBlocking(i2c_bus->config->I2C, &i2c_bus->config->master_handle,&xfer);
while(!g_MasterCompletionFlag[instance - 1])
{
rt_thread_delay(1);
timeout_cnt--;
if(timeout_cnt == 0)
{
break;
}
}
timeout_cnt = 100;
g_MasterCompletionFlag[instance - 1] = 0;
#else
I2C_MasterTransferBlocking(i2c_bus->config->I2C, &xfer);
#endif
rt_memcpy(msgs[i].buf,i2c_buff_temp[instance - 1],msgs[i].len);
}
else
{
xfer.flags = kI2C_TransferNoStartFlag;
xfer.slaveAddress = msgs[i].addr;
xfer.direction = kI2C_Write;
xfer.subaddress = 0;
xfer.subaddressSize = 0;
xfer.data = (uint8_t *volatile)i2c_buff_temp[instance - 1];
xfer.dataSize = msgs[i].len;
rt_memcpy(i2c_buff_temp[instance - 1],msgs[i].buf,msgs[i].len);
#ifdef IMX_I2C_IRQ_MODE
I2C_MasterTransferNonBlocking(i2c_bus->config->I2C, &i2c_bus->config->master_handle,&xfer);
while(!g_MasterCompletionFlag[instance - 1])
{
timeout_cnt--;
rt_thread_delay(1);
if(timeout_cnt == 0)
{
break;
}
}
timeout_cnt = 100;
g_MasterCompletionFlag[instance - 1] = 0;
#else
I2C_MasterTransferBlocking(i2c_bus->config->I2C, &xfer);
#endif
}
}
return i;
}
static rt_err_t imx6ull_i2c_bus_control(struct rt_i2c_bus_device *bus, rt_uint32_t cmd, rt_uint32_t arg)
{
return RT_EOK;
}
static rt_err_t imx6ull_i2c_gpio_init(struct imx6ull_i2c_bus *bus)
{
struct imx6ull_i2c_bus *i2c_bus = RT_NULL;
i2c_bus = (struct imx6ull_i2c_bus *)bus;
imx6ull_gpio_init(&i2c_bus->config->scl_gpio);
imx6ull_gpio_init(&i2c_bus->config->sda_gpio);
return RT_EOK;
}
#ifdef RT_USING_DEVICE_OPS
static const struct rt_i2c_bus_device_ops imx6ull_i2c_ops =
{
.master_xfer = imx6ull_i2c_mst_xfer,
.slave_xfer = RT_NULL,
.i2c_bus_control = imx6ull_i2c_bus_control,
};
#endif
extern void I2C_DriverIRQHandler(int irq, void *base);
int rt_hw_i2c_init(void)
{
rt_uint16_t obj_num = 0;
rt_uint32_t src_clock;
i2c_master_config_t masterConfig = {0};
obj_num = sizeof(i2c_config) / sizeof(i2c_config[0]);
src_clock = (CLOCK_GetFreq(kCLOCK_IpgClk) / (CLOCK_GetDiv(kCLOCK_PerclkDiv) + 1U));
for(int i = 0; i < obj_num; i++)
{
i2c_obj[i].config = &i2c_config[i];
i2c_obj[i].config->hw_base = i2c_obj[i].config->I2C;
i2c_obj[i].config->I2C = (I2C_Type *)imx6ull_get_periph_vaddr((rt_uint32_t)i2c_obj[i].config->hw_base);
i2c_obj[i].parent.ops = &imx6ull_i2c_ops;
imx6ull_i2c_gpio_init(&i2c_obj[i]);
I2C_MasterGetDefaultConfig(&masterConfig);
masterConfig.baudRate_Bps = i2c_config[i].baud_rate;
CLOCK_EnableClock(i2c_obj[i].config->clk_ip_name);
I2C_MasterInit(i2c_obj[i].config->I2C, &masterConfig, src_clock);
rt_i2c_bus_device_register(&i2c_obj[i].parent, i2c_obj[i].config->name);
#ifdef IMX_I2C_IRQ_MODE
I2C_MasterTransferCreateHandle(i2c_obj[i].config->hw_base, &i2c_obj[i].config->master_handle, i2c_master_callback, i2c_obj[i].config);
rt_hw_interrupt_install(i2c_obj[i].config->irq_num, (rt_isr_handler_t)I2C_DriverIRQHandler, i2c_obj[i].config, i2c_obj[i].config->name);
#endif
}
return RT_EOK;
}
INIT_DEVICE_EXPORT(rt_hw_i2c_init);
#endif

View File

@@ -0,0 +1,97 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-01-13 Lyons first version
* 2021-06-23 RiceChen refactor
*/
#ifndef __DRV_I2C_H__
#define __DRV_I2C_H__
#include <board.h>
#include "drv_common.h"
#include "fsl_iomuxc.h"
#include "fsl_clock.h"
#include "fsl_i2c.h"
#define IMX_I2C_IRQ_MODE
struct imx6ull_i2c_config
{
void *hw_base; /* hardware physical address base */
I2C_Type *I2C;
char *name;
rt_uint32_t baud_rate;
rt_uint32_t clk_ip_name;
rt_uint32_t irq_num;
struct imx6ull_iomuxc scl_gpio;
struct imx6ull_iomuxc sda_gpio;
i2c_master_handle_t master_handle;
};
struct imx6ull_i2c_bus
{
struct rt_i2c_bus_device parent;
struct imx6ull_i2c_config *config;
};
#ifdef BSP_USING_I2C1
#define I2C1_BUS_CONFIG \
{ \
.I2C = I2C1, \
.name = "i2c1", \
.clk_ip_name = kCLOCK_I2c1S, \
.baud_rate = I2C1_BAUD_RATE, \
.irq_num = IMX_INT_I2C1, \
.scl_gpio = {IOMUXC_UART4_TX_DATA_I2C1_SCL, 1, 0x70B0}, \
.sda_gpio = {IOMUXC_UART4_RX_DATA_I2C1_SDA, 1, 0x70B0}, \
}
#endif /* BSP_USING_I2C1 */
#ifdef BSP_USING_I2C2
#define I2C2_BUS_CONFIG \
{ \
.I2C = I2C2, \
.name = "i2c2", \
.clk_ip_name = kCLOCK_I2c2S, \
.baud_rate = I2C2_BAUD_RATE, \
.irq_num = IMX_INT_I2C2, \
.scl_gpio = {IOMUXC_UART5_TX_DATA_I2C2_SCL, 1, 0x70B0}, \
.sda_gpio = {IOMUXC_UART5_RX_DATA_I2C2_SDA, 1, 0x70B0}, \
}
#endif /* BSP_USING_I2C2 */
#ifdef BSP_USING_I2C3
#define I2C3_BUS_CONFIG \
{ \
.I2C = I2C3, \
.name = "i2c3", \
.clk_ip_name = kCLOCK_I2c3S, \
.baud_rate = I2C3_BAUD_RATE, \
.irq_num = IMX_INT_I2C3, \
.scl_gpio = {IOMUXC_ENET2_RX_DATA0_I2C3_SCL, 1, 0x70B0}, \
.sda_gpio = {IOMUXC_ENET2_RX_DATA1_I2C3_SDA, 1, 0x70B0}, \
}
#endif /* BSP_USING_I2C3 */
#ifdef BSP_USING_I2C4
#define I2C4_BUS_CONFIG \
{ \
.I2C = I2C4, \
.name = "i2c4", \
.clk_ip_name = kCLOCK_I2c4S, \
.baud_rate = I2C4_BAUD_RATE, \
.irq_num = IMX_INT_I2C4, \
.scl_gpio = {IOMUXC_UART2_TX_DATA_I2C4_SCL, 1, 0x70B0}, \
.sda_gpio = {IOMUXC_UART2_RX_DATA_I2C4_SDA, 1, 0x70B0}, \
}
#endif /* BSP_USING_I2C4 */
#endif

View File

@@ -0,0 +1,223 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-01-11 Lyons first version
* 2021-06-24 RiceChen refactor
* 2021-07-28 songchao add cmd
*/
#include <rthw.h>
#include <rtdevice.h>
#ifdef BSP_USING_LCD
#define LOG_TAG "drv.lcd"
#include <drv_log.h>
#include "fsl_iomuxc.h"
#include "drv_lcd.h"
#include <lwp_user_mm.h>
static struct imx6ull_lcd_config _lcd_config = LCD_BUS_CONFIG;
static struct imx6ull_lcd_bus _lcd_obj;
static rt_err_t imx6ull_elcd_init(rt_device_t device)
{
struct imx6ull_lcd_bus *elcd_dev = RT_NULL;
clock_video_pll_config_t pll_config;
elcdif_rgb_mode_config_t lcd_config;
RT_ASSERT(device != RT_NULL);
elcd_dev = (struct imx6ull_lcd_bus *)device;
ELCDIF_Reset(elcd_dev->config->ELCDIF);
pll_config.loopDivider = 32;
pll_config.postDivider = LCD_PLL_DIV;
pll_config.numerator = 0;
pll_config.denominator = 0;
CLOCK_InitVideoPll(&pll_config);
lcd_config.hfp = LCD_HFP;
lcd_config.vfp = LCD_VFP;
lcd_config.hbp = LCD_HBP;
lcd_config.vbp = LCD_VBP;
lcd_config.hsw = LCD_HSW;
lcd_config.vsw = LCD_VSW;
lcd_config.polarityFlags = kELCDIF_DataEnableActiveHigh |
kELCDIF_VsyncActiveLow |
kELCDIF_HsyncActiveLow |
kELCDIF_DriveDataOnRisingClkEdge;
switch(elcd_dev->info.pixel_format)
{
case RTGRAPHIC_PIXEL_FORMAT_RGB888:
lcd_config.pixelFormat = kELCDIF_PixelFormatRGB888;
break;
case RTGRAPHIC_PIXEL_FORMAT_RGB565:
lcd_config.pixelFormat = kELCDIF_PixelFormatRGB565;
break;
default:
LOG_E("not support this pixel_format %d\n",elcd_dev->info.pixel_format);
return RT_ERROR;
}
lcd_config.panelWidth = elcd_dev->info.width;
lcd_config.panelHeight = elcd_dev->info.height;
lcd_config.bufferAddr = (uint32_t)elcd_dev->fb_phy;
lcd_config.dataBus = kELCDIF_DataBus24Bit;
ELCDIF_RgbModeInit(elcd_dev->config->ELCDIF, &lcd_config);
ELCDIF_RgbModeStart(elcd_dev->config->ELCDIF);
return RT_EOK;
}
static rt_err_t imx6ull_elcd_control(rt_device_t device, int cmd, void *args)
{
struct imx6ull_lcd_bus *elcd_dev = RT_NULL;
int mem_size = 0;
RT_ASSERT(device != RT_NULL);
elcd_dev = (struct imx6ull_lcd_bus *)device;
switch(cmd)
{
case RTGRAPHIC_CTRL_RECT_UPDATE:
{
mem_size = elcd_dev->info.width * elcd_dev->info.height * elcd_dev->info.bits_per_pixel / 8;
rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, (void *)(_lcd_obj.info.framebuffer), mem_size);
break;
}
case RTGRAPHIC_CTRL_POWERON:
{
rt_pin_write(IMX6ULL_LCD_BL_PIN, PIN_HIGH);
break;
}
case RTGRAPHIC_CTRL_POWEROFF:
{
rt_pin_write(IMX6ULL_LCD_BL_PIN, PIN_LOW);
break;
}
case RTGRAPHIC_CTRL_GET_INFO:
{
struct lcd_info *info = (struct lcd_info *)args;
RT_ASSERT(info != RT_NULL);
rt_memcpy(&info->graphic, &elcd_dev->info, sizeof(struct rt_device_graphic_info));
info->screen.shamem_len = elcd_dev->info.width * elcd_dev->info.height * elcd_dev->info.bits_per_pixel / 8;
info->screen.shamem_start = (rt_uint32_t)lwp_map_user_phy(lwp_self(), RT_NULL,
elcd_dev->fb_phy,
info->screen.shamem_len, 1);
break;
}
case RTGRAPHIC_CTRL_SET_MODE:
{
break;
}
case FBIOGET_FSCREENINFO:
{
struct fb_fix_screeninfo *info = (struct fb_fix_screeninfo *)args;
rt_memcpy(info->id, elcd_dev->config->name, (strlen(elcd_dev->config->name)+1));
info->smem_len = elcd_dev->info.width * elcd_dev->info.height * elcd_dev->info.bits_per_pixel / 8;
info->smem_start = (rt_uint32_t)lwp_map_user_phy(lwp_self(), RT_NULL,
elcd_dev->fb_phy,
info->smem_len, 1);
info->line_length = elcd_dev->info.width * 2;
break;
}
case FBIOGET_VSCREENINFO:
{
struct fb_var_screeninfo *info = (struct fb_var_screeninfo *)args;
info->bits_per_pixel = elcd_dev->info.bits_per_pixel;
info->xres = elcd_dev->info.width;
info->yres = elcd_dev->info.height;
break;
}
}
return RT_EOK;
}
#ifdef RT_USING_DEVICE_OPS
const static struct rt_device_ops elcd_ops =
{
imx6ull_elcd_init,
RT_NULL,
RT_NULL,
RT_NULL,
RT_NULL,
imx6ull_elcd_control,
};
#endif
int rt_hw_elcd_init(void)
{
rt_err_t ret = 0;
_lcd_config.ELCDIF = (LCDIF_Type *)imx6ull_get_periph_vaddr((rt_uint32_t)(_lcd_config.ELCDIF));
_lcd_config.lcd_mux_base = (rt_uint32_t)imx6ull_get_periph_vaddr((rt_uint32_t)(_lcd_config.lcd_mux_base));
_lcd_config.lcd_cfg_base = (rt_uint32_t)imx6ull_get_periph_vaddr((rt_uint32_t)(_lcd_config.lcd_cfg_base));
for(int i = 0; i < LCD_GPIO_MAX; i++)
{
IOMUXC_SetPinMux((_lcd_config.lcd_mux_base + i * 4),
0x0U, 0x0U, 0x0U, (_lcd_config.lcd_cfg_base + i * 4), 0);
IOMUXC_SetPinConfig((_lcd_config.lcd_mux_base + i * 4),
0x0U, 0x0U, 0x0U, (_lcd_config.lcd_cfg_base + i * 4), 0xB9);
}
CLOCK_EnableClock(_lcd_config.apd_clk_name);
CLOCK_EnableClock(_lcd_config.pix_clk_name);
_lcd_obj.config = &_lcd_config;
_lcd_obj.fb_virt = rt_pages_alloc(rt_page_bits(LCD_BUF_SIZE));
_lcd_obj.fb_phy = _lcd_obj.fb_virt + PV_OFFSET;
LOG_D("fb address => 0x%08x\n", _lcd_obj.fb_phy);
if(_lcd_obj.fb_phy == RT_NULL)
{
LOG_E("initialize frame buffer failed!\n");
return -RT_ERROR;
}
_lcd_obj.info.width = LCD_WIDTH;
_lcd_obj.info.height = LCD_HEIGHT;
_lcd_obj.info.pixel_format = RTGRAPHIC_PIXEL_FORMAT_RGB888;
_lcd_obj.info.bits_per_pixel = LCD_BITS_PER_PIXEL;
_lcd_obj.info.framebuffer = (void *)_lcd_obj.fb_virt;
_lcd_obj.parent.type = RT_Device_Class_Graphic;
#ifdef RT_USING_DEVICE_OPS
_lcd_obj.parent.ops = &elcd_ops;
#else
_lcd_obj.parent.init = imx6ull_elcd_init;
_lcd_obj.parent.open = RT_NULL;
_lcd_obj.parent.close = RT_NULL;
_lcd_obj.parent.read = RT_NULL;
_lcd_obj.parent.write = RT_NULL;
_lcd_obj.parent.control = imx6ull_elcd_control;
#endif
_lcd_obj.parent.user_data = (void *)&_lcd_obj.info;
ret = rt_device_register(&_lcd_obj.parent, _lcd_obj.config->name, RT_DEVICE_FLAG_RDWR);
/* LCD_BL */
rt_pin_mode(IMX6ULL_LCD_BL_PIN, PIN_MODE_OUTPUT);
rt_pin_write(IMX6ULL_LCD_BL_PIN, PIN_HIGH);
rt_memset((rt_uint8_t *)_lcd_obj.fb_virt, 0xff, LCD_BUF_SIZE);
return ret;
}
INIT_DEVICE_EXPORT(rt_hw_elcd_init);
#endif

View File

@@ -0,0 +1,90 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-01-11 Lyons first version
* 2021-06-24 RiceChen refactor
*/
#ifndef __DRV_LCD_H__
#define __DRV_LCD_H__
#include <board.h>
#include "drv_pin.h"
#include "drv_common.h"
#include "fsl_iomuxc.h"
#include "fsl_clock.h"
#include "fsl_elcdif.h"
#define LCD_GPIO_MAX 29
#define LCD_MUX_BASE 0x020E0104U
#define LCD_CONFIG_BASE 0x020E0390U
#define LCD_WIDTH BSP_LCD_WIDTH
#define LCD_HEIGHT BSP_LCD_HEIGHT
#define LCD_VSW BSP_LCD_VSW
#define LCD_VBP BSP_LCD_VBP
#define LCD_VFP BSP_LCD_VFP
#define LCD_HSW BSP_LCD_HSW
#define LCD_HBP BSP_LCD_HBP
#define LCD_HFP BSP_LCD_HFP
#define LCD_PLL_DIV BSP_LCD_PLL_DIV
#define LCD_BITS_PER_PIXEL 32
#define LCD_BUF_SIZE (LCD_WIDTH * LCD_HEIGHT * LCD_BITS_PER_PIXEL / 8)
#define IMX6ULL_LCD_BL_PIN GET_PIN(1, 8)
struct fb_fix_screen_info
{
rt_uint32_t shamem_start;
rt_uint32_t shamem_len;
};
struct lcd_info
{
struct rt_device_graphic_info graphic;
struct fb_fix_screen_info screen;
};
struct imx6ull_lcd_config
{
LCDIF_Type *ELCDIF;
char *name;
rt_uint32_t apd_clk_name;
rt_uint32_t pix_clk_name;
rt_uint32_t lcd_mux_base;
rt_uint32_t lcd_cfg_base;
};
struct imx6ull_lcd_bus
{
struct rt_device parent;
struct rt_device_graphic_info info;
struct imx6ull_lcd_config *config;
rt_uint8_t *fb_phy;
rt_uint8_t *fb_virt;
};
#ifdef BSP_USING_LCD
#define LCD_BUS_CONFIG \
{ \
.ELCDIF = LCDIF, \
.name = "lcd", \
.apd_clk_name = kCLOCK_Lcd, \
.pix_clk_name = kCLOCK_Lcdif1, \
.lcd_mux_base = LCD_MUX_BASE, \
.lcd_cfg_base = LCD_CONFIG_BASE, \
}
#endif /* BSP_USING_LCD */
#endif

View File

@@ -0,0 +1,27 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-01-03 RiceChen first version
*/
/*
* NOTE: DO NOT include this file on the header file.
*/
#ifndef LOG_TAG
#define DBG_TAG "drv"
#else
#define DBG_TAG LOG_TAG
#endif /* LOG_TAG */
#ifdef DRV_DEBUG
#define DBG_LVL DBG_LOG
#else
#define DBG_LVL DBG_INFO
#endif /* DRV_DEBUG */
#include <rtdbg.h>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,19 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-01-13 Lyons first version
* 2021-06-23 RiceChen add get pin API
*/
#ifndef __DRV_PIN_H__
#define __DRV_PIN_H__
#include "board.h"
#define GET_PIN(PORTx, PIN) (32 * (PORTx - 1) + (PIN & 31))
#endif //#ifndef __DRV_PIN_H__

View File

@@ -0,0 +1,347 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2019-04-28 tyustli first version
*
*/
#include <rtthread.h>
#ifdef RT_USING_PWM
#define LOG_TAG "drv.pwm"
#include <drv_log.h>
#include <rtdevice.h>
#include <ioremap.h>
#include "fsl_pwm.h"
#include "drv_pwm.h"
#include <drv_common.h>
#include <drivers/rt_drv_pwm.h>
#define PWM_SRC_CLK_FREQ CLOCK_GetFreq(kCLOCK_IpgClk)
/* PWMPR register value of 0xffff has the same effect as 0xfffe */
#define IMX_PWMPR_MAX 0xfffe
#define NSEC_PER_MSEC 1000000
#define NSEC_PER_SEC 1000
#define MX3_PWMCR_SWR BIT(3)
#define MX3_PWM_SWR_LOOP 5
#define MX3_PWMSR_FIFOAV_EMPTY 0
#define MX3_PWMSR_FIFOAV_1WORD 1
#define MX3_PWMSR_FIFOAV_2WORDS 2
#define MX3_PWMSR_FIFOAV_3WORDS 3
#define MX3_PWMSR_FIFOAV_4WORDS 4
#define MX3_PWMCR_STOPEN BIT(25)
#define MX3_PWMCR_DOZEN BIT(24)
#define MX3_PWMCR_WAITEN BIT(23)
#define MX3_PWMCR_DBGEN BIT(22)
#define MX3_PWMCR_BCTR BIT(21)
#define MX3_PWMCR_HCTR BIT(20)
#define MX3_PWMCR_CLKSRC BIT(17)
#define MX3_PWMCR_EN BIT(0)
static rt_err_t imx6ull_drv_pwm_control(struct rt_device_pwm *device, int cmd, void *arg);
static struct rt_pwm_ops imxrt_drv_ops =
{
.control = imx6ull_drv_pwm_control
};
static void imx6ull_pwm_reset(PWM_Type *base)
{
int wait_count = 0;
uint32_t cr = 0;
base->PWMCR = MX3_PWMCR_SWR;
do {
rt_thread_mdelay(1);
cr = base->PWMCR;
} while ((cr & MX3_PWMCR_SWR) &&
(wait_count++ < MX3_PWM_SWR_LOOP));
if (cr & MX3_PWMCR_SWR)
{
LOG_E("software reset timeout\n");
}
}
static void imx6ull_pwm_wait_fifo_slot(PWM_Type *base, struct rt_pwm_configuration *configuration)
{
unsigned int period_ms = 0;
int fifoav = 0;
uint32_t sr = 0;
sr = base->PWMSR;
fifoav = sr & 0x7;
if (fifoav == MX3_PWMSR_FIFOAV_4WORDS) {
period_ms = configuration->period / NSEC_PER_MSEC;
rt_thread_mdelay(period_ms);
sr = base->PWMSR;
if (fifoav == (sr & 0x7))
{
LOG_E("there is no free FIFO slot\n");
}
}
}
static rt_err_t imx6ull_pwm_enable(struct rt_device_pwm *device, rt_bool_t enable)
{
PWM_Type *base = (PWM_Type *)device->parent.user_data;
if (!enable)
{
pwm_stop_timer(base);
}
else
{
pwm_start_timer(base);
}
return RT_EOK;
}
static rt_err_t imx6ull_pwm_get(struct rt_device_pwm *device, struct rt_pwm_configuration *configuration)
{
uint32_t period = 0, prescaler = 0, val = 0;
uint64_t tmp = 0;
PWM_Type *base = (PWM_Type *)device->parent.user_data;
uint32_t pwm_src_clk;
pwm_src_clk = PWM_SRC_CLK_FREQ / 1000000;
val = base->PWMCR;
prescaler = ((val >> 4) & 0xfff)+1;
val = base->PWMPR;
period = val >= IMX_PWMPR_MAX ? IMX_PWMPR_MAX : val;
tmp = NSEC_PER_SEC * (uint64_t)(period + 2) * prescaler;
configuration->period = (tmp) / pwm_src_clk;
val = base->PWMSAR;
tmp = NSEC_PER_SEC * (uint64_t)(val) * prescaler;
configuration->pulse = (tmp) / pwm_src_clk;
return RT_EOK;
}
static rt_err_t imx6ull_pwm_set(struct rt_device_pwm *device, struct rt_pwm_configuration *configuration)
{
RT_ASSERT(configuration->period > 0);
RT_ASSERT(configuration->pulse <= configuration->period);
PWM_Type *base = (PWM_Type *)device->parent.user_data;
uint32_t period_cycles = 0, duty_cycles = 0, prescale = 0;
uint32_t cr = 0;
uint32_t pwm_src_clk = 0;
pwm_src_clk = PWM_SRC_CLK_FREQ / 1000000;
period_cycles = pwm_src_clk * configuration->period / NSEC_PER_SEC;
prescale = period_cycles / 0x10000 + 1;
period_cycles /= prescale;
duty_cycles = configuration->pulse * pwm_src_clk / NSEC_PER_SEC ;
duty_cycles /= prescale;
/*
* according to imx pwm RM, the real period value should be PERIOD
* value in PWMPR plus 2.
*/
if (period_cycles > 2)
{
period_cycles -= 2;
}
else
{
period_cycles = 0;
}
if (((base->PWMCR) & 0x1) == 1)
{
imx6ull_pwm_wait_fifo_slot(base, configuration);
}
else
{
pwm_start_timer(base);
imx6ull_pwm_reset(base);
}
base->PWMSAR = duty_cycles;
base->PWMPR = period_cycles;
cr = ((prescale -1 ) << 4) |
MX3_PWMCR_STOPEN | MX3_PWMCR_DOZEN | MX3_PWMCR_WAITEN | MX3_PWMCR_CLKSRC | MX3_PWMCR_DBGEN;
cr |= MX3_PWMCR_EN;
base->PWMCR = cr;
return RT_EOK;
}
static rt_err_t imx6ull_drv_pwm_control(struct rt_device_pwm *device, int cmd, void *arg)
{
struct rt_pwm_configuration *configuration = (struct rt_pwm_configuration *)arg;
switch (cmd)
{
case PWM_CMD_ENABLE:
return imx6ull_pwm_enable(device, RT_TRUE);
case PWM_CMD_DISABLE:
return imx6ull_pwm_enable(device, RT_FALSE);
case PWM_CMD_SET:
return imx6ull_pwm_set(device, configuration);
case PWM_CMD_GET:
return imx6ull_pwm_get(device, configuration);
default:
return RT_EINVAL;
}
}
static rt_err_t imx6ull_drv_pwm_init(PWM_Type *base)
{
pwm_config_t PwmConfig;
pwm_get_default_config(&PwmConfig);
if (pwm_init(base, &PwmConfig) == kStatus_Fail)
{
LOG_E("init pwm failed \n");
return RT_ERROR;
}
return RT_EOK;
}
int imx6ull_pwm_gpio_init(void)
{
#ifdef BSP_USING_PWM1
struct imx6ull_iomuxc gpio;
gpio.muxRegister = 0x020E007C;
gpio.muxMode = 0x0;
gpio.inputRegister = 0x00000000;
gpio.inputDaisy = 0x0;
gpio.configRegister = 0x020E0308;
gpio.inputOnfield = 0;
gpio.configValue = IOMUXC_SW_PAD_CTL_PAD_DSE(2U) | IOMUXC_SW_PAD_CTL_PAD_SPEED(2U);
imx6ull_gpio_init(&gpio);
#endif
return 0;
}
int rt_hw_pwm_init(void)
{
rt_err_t ret = RT_EOK;
#ifdef BSP_USING_PWM1
static struct rt_device_pwm pwm1_device;
PWM_Type *pwm1_base;
imx6ull_pwm_gpio_init();
pwm1_base = (PWM_Type *)rt_ioremap((void*)PWM1, 0x1000);
if (imx6ull_drv_pwm_init(pwm1_base) != RT_EOK)
{
LOG_E("init pwm1 failed\n");
}
ret = rt_device_pwm_register(&pwm1_device, "pwm1", &imxrt_drv_ops, pwm1_base);
if (ret != RT_EOK)
{
LOG_E("%s register failed", "pwm1");
}
#endif /* BSP_USING_PWM1 */
#ifdef BSP_USING_PWM2
static struct rt_device_pwm pwm2_device;
imx6ull_pwm_gpio_init();
if (imx6ull_drv_pwm_init(PWM2) != RT_EOK)
{
LOG_E("init pwm2 failed\n");
}
ret = rt_device_pwm_register(&pwm2_device, "pwm2", &imxrt_drv_ops, PWM2);
if (ret != RT_EOK)
{
LOG_E("%s register failed", "pwm2");
}
#endif /* BSP_USING_PWM2 */
#ifdef BSP_USING_PWM3
static struct rt_device_pwm pwm3_device;
imx6ull_pwm_gpio_init();
if (imx6ull_drv_pwm_init(PWM3) != RT_EOK)
{
LOG_E("init pwm3 failed\n");
}
ret = rt_device_pwm_register(&pwm3_device, "pwm3", &imxrt_drv_ops, PWM3);
if (ret != RT_EOK)
{
LOG_E("%s register failed", "pwm3");
}
#endif /* BSP_USING_PWM3 */
#ifdef BSP_USING_PWM4
static struct rt_device_pwm pwm4_device;
imx6ull_pwm_gpio_init();
if (imx6ull_drv_pwm_init(PWM4) != RT_EOK)
{
LOG_E("init pwm4 failed\n");
}
ret = rt_device_pwm_register(&pwm4_device, "pwm4", &imxrt_drv_ops, PWM4);
if (ret != RT_EOK)
{
LOG_E("%s register failed", "pwm4");
}
#endif /* BSP_USING_PWM4 */
return ret;
}
INIT_DEVICE_EXPORT(rt_hw_pwm_init);
int set_pwm_default(void)
{
int result = 0;
struct rt_device_pwm *device = RT_NULL;
device = (struct rt_device_pwm *)rt_device_find("pwm1");
if (!device)
{
result = -RT_EIO;
goto _exit;
}
result = rt_pwm_set(device, 1, 1000000, 500000);
result = rt_pwm_enable(device, 1);
_exit:
return result;
}
INIT_APP_EXPORT(set_pwm_default);
#endif /* BSP_USING_PWM */

View File

@@ -0,0 +1,21 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2019-04-28 tyustli the first version.
*
*/
#ifndef DRV_PWM_H__
#define DRV_PWM_H__
#include <rtdevice.h>
#define BIT(nr) ((1) << (nr))
int rt_hw_pwm_init(void);
#endif

View File

@@ -0,0 +1,167 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-04-25 Lyons first version
*/
#include <rtconfig.h>
#ifdef BSP_USING_ONCHIP_RTC
#include "board.h"
#define DBG_TAG "drv.rtc"
#define DBG_LVL DBG_WARNING
#include <rtdbg.h>
#define _DEVICE_NAME "rtc"
_internal_rw struct rt_device _s_rtc_device;
static time_t _get_rtc_timestamp(void)
{
snvs_hp_rtc_datetime_t rtcDate;
SNVS_Type *snvs = (SNVS_Type*)g_snvs_vbase;
struct tm tm_new;
SNVS_HP_RTC_GetDatetime(snvs, &rtcDate);
tm_new.tm_sec = rtcDate.second;
tm_new.tm_min = rtcDate.minute;
tm_new.tm_hour = rtcDate.hour;
tm_new.tm_mday = rtcDate.day;
tm_new.tm_mon = rtcDate.month - 1;
tm_new.tm_year = rtcDate.year - 1900;
return mktime(&tm_new);
}
static rt_err_t _set_rtc_time_stamp(time_t time_stamp)
{
snvs_hp_rtc_datetime_t rtcDate;
SNVS_Type *snvs = (SNVS_Type*)g_snvs_vbase;
struct tm *p_tm;
p_tm = localtime(&time_stamp);
rtcDate.second = p_tm->tm_sec;
rtcDate.minute = p_tm->tm_min;
rtcDate.hour = p_tm->tm_hour;
rtcDate.day = p_tm->tm_mday;
rtcDate.month = p_tm->tm_mon + 1;
rtcDate.year = p_tm->tm_year + 1900;
if (kStatus_Success != SNVS_HP_RTC_SetDatetime(snvs, &rtcDate))
{
return -RT_ERROR;
}
return RT_EOK;
}
static void _rtc_init(void)
{
snvs_hp_rtc_config_t snvsRtcConfig;
SNVS_Type *snvs = (SNVS_Type*)g_snvs_vbase;
SNVS_HP_RTC_GetDefaultConfig(&snvsRtcConfig);
SNVS_HP_RTC_Init(snvs, &snvsRtcConfig);
SNVS_HP_RTC_StartTimer(snvs);
}
static rt_err_t _rtc_config(struct rt_device *dev)
{
return RT_EOK;
}
static rt_err_t _rtc_ops_control( rt_device_t dev, int cmd, void *args )
{
rt_err_t result;
RT_ASSERT(RT_NULL != dev);
result = RT_EOK;
switch (cmd)
{
case RT_DEVICE_CTRL_RTC_GET_TIME:
*(time_t *)args = _get_rtc_timestamp();
LOG_D("RTC: get rtc_time %x", *(time_t *)args);
break;
case RT_DEVICE_CTRL_RTC_SET_TIME:
if (_set_rtc_time_stamp(*(time_t *)args))
{
result = -RT_ERROR;
}
LOG_D("RTC: set rtc_time %x", *(time_t *)args);
break;
}
return result;
}
#ifdef RT_USING_DEVICE_OPS
_internal_ro struct rt_device_ops _k_rtc_ops =
{
RT_NULL, /* init */
RT_NULL, /* open */
RT_NULL, /* close */
RT_NULL, /* read */
RT_NULL, /* write */
_rtc_ops_control, /* control */
};
#endif
static rt_err_t _rt_rtc_register( rt_device_t device, const char *name, rt_uint32_t flag )
{
RT_ASSERT(RT_NULL != device);
_rtc_init();
if (RT_EOK != _rtc_config(device))
{
return -RT_ERROR;
}
device->type = RT_Device_Class_RTC;
#ifdef RT_USING_DEVICE_OPS
device->ops = &_k_rtc_ops;
#else
device->init = RT_NULL;
device->open = RT_NULL;
device->close = RT_NULL;
device->read = RT_NULL;
device->write = RT_NULL;
device->control = _rtc_ops_control;
#endif
device->user_data = RT_NULL;
device->rx_indicate = RT_NULL;
device->tx_complete = RT_NULL;
/* register a character device */
return rt_device_register(device, name, flag);
}
int rt_hw_rtc_init(void)
{
rt_err_t result;
result = _rt_rtc_register(&_s_rtc_device, _DEVICE_NAME, RT_DEVICE_FLAG_RDWR);
if (RT_EOK != result)
{
LOG_E("rtc register err code: %d", result);
return result;
}
LOG_D("rtc init success.");
return RT_EOK;
}
INIT_DEVICE_EXPORT(rt_hw_rtc_init);
#endif /* BSP_USING_ONCHIP_RTC */

View File

@@ -0,0 +1,94 @@
#include <rtthread.h>
#ifdef PKG_USING_RW007
#include <rtdevice.h>
#include <drv_spi.h>
#include <drv_pin.h>
#include <board.h>
#include <spi_wifi_rw007.h>
#ifndef PKG_USING_RW007_LATEST_VERSION
#error "please select rw007 latest version."
#endif
#define RW007_SPI_BUS_NAME "spi2"
#define RW007_CS_PIN GET_PIN(1, 29) /* IOMUXC_UART4_RX_DATA_ECSPI2_SS0 IOMUXC_UART4_RX_DATA_GPIO1_IO29 */
#define RW007_INT_BUSY_PIN GET_PIN(5, 0) /* IOMUXC_SNVS_SNVS_TAMPER0_GPIO5_IO00 */
#define RW007_RST_PIN GET_PIN(5, 1) /* IOMUXC_SNVS_SNVS_TAMPER1_GPIO5_IO01 */
extern void spi_wifi_isr(int vector);
static int rw007_gpio_init(void)
{
int ret = 0;
uint8_t errorCnt = 10;
/* Configure IO */
rt_pin_mode(RW007_RST_PIN, PIN_MODE_OUTPUT);
rt_pin_mode(RW007_INT_BUSY_PIN, PIN_MODE_INPUT_PULLDOWN);
/* Reset rw007 and config mode */
rt_pin_write(RW007_RST_PIN, PIN_LOW);
rt_thread_delay(rt_tick_from_millisecond(100));
rt_pin_write(RW007_RST_PIN, PIN_HIGH);
/* Wait rw007 ready(exit busy stat) */
while(!rt_pin_read(RW007_INT_BUSY_PIN))
{
rt_thread_delay(rt_tick_from_millisecond(100));
if (errorCnt)
{
errorCnt--;
}
else
{
ret = -1;
break;
}
}
rt_thread_delay(rt_tick_from_millisecond(200));
rt_pin_mode(RW007_INT_BUSY_PIN, PIN_MODE_INPUT_PULLUP);
return ret;
}
int wifi_spi_device_init(void)
{
char sn_version[32];
if (rw007_gpio_init() == -1)
{
rt_hw_wifi_init("rw007 gpio init fault!\n");
return -1;
}
rt_hw_spi_device_attach(RW007_SPI_BUS_NAME, "rw007", RW007_CS_PIN);
rt_hw_wifi_init("rw007");
rt_wlan_set_mode(RT_WLAN_DEVICE_STA_NAME, RT_WLAN_STATION);
rt_wlan_set_mode(RT_WLAN_DEVICE_AP_NAME, RT_WLAN_AP);
rw007_sn_get(sn_version);
rt_kprintf("\nrw007 sn: [%s]\n", sn_version);
rw007_version_get(sn_version);
rt_kprintf("rw007 ver: [%s]\n\n", sn_version);
#ifdef RW007_DAFAULT_SSID
rt_wlan_connect(RW007_DAFAULT_SSID, RW007_DAFAULT_PASSWARD);
#endif
return 0;
}
INIT_APP_EXPORT(wifi_spi_device_init);
static void int_wifi_irq(void * p)
{
((void)p);
spi_wifi_isr(0);
}
void spi_wifi_hw_init(void)
{
rt_pin_attach_irq(RW007_INT_BUSY_PIN, PIN_IRQ_MODE_FALLING, int_wifi_irq, 0);
rt_pin_irq_enable(RW007_INT_BUSY_PIN, RT_TRUE);
}
#endif /* RW007_USING_STM32_DRIVERS */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,15 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-07-14 linzhenxing first version
*/
#ifndef __DRV_SDIO_H__
#define __DRV_SDIO_H__
void host_change(void);
#endif

View File

@@ -0,0 +1,207 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-01-13 Lyons first version
* 2021-06-23 RiceChen refactor
*/
#include <rthw.h>
#include <rtdevice.h>
#ifdef BSP_USING_SPI
#define LOG_TAG "drv.spi"
#include <drv_log.h>
#include "fsl_iomuxc.h"
#include "drv_spi.h"
static struct imx6ull_spi_config spi_config[] =
{
#ifdef BSP_USING_SPI1
SPI1_BUS_CONFIG,
#endif
#ifdef BSP_USING_SPI2
SPI2_BUS_CONFIG,
#endif
#ifdef BSP_USING_SPI3
SPI3_BUS_CONFIG,
#endif
#ifdef BSP_USING_SPI4
SPI4_BUS_CONFIG,
#endif
};
static struct imx6ull_spi_bus spi_obj[sizeof(spi_config) / sizeof(spi_config[0])];
static rt_err_t imx6ull_ecspi_configure(struct rt_spi_device *device, struct rt_spi_configuration *cfg)
{
struct imx6ull_spi_bus *spi_dev = RT_NULL;
ecspi_master_config_t config;
rt_uint32_t scr_clock = 0;
spi_dev = (struct imx6ull_spi_bus *)(device->bus->parent.user_data);
ECSPI_MasterGetDefaultConfig(&config);
config.samplePeriod = 10;
config.txFifoThreshold = 0;
config.channelConfig.dataLineInactiveState = kECSPI_DataLineInactiveStateHigh;
if (cfg->data_width == 8)
{
config.burstLength = 8;
}
else
{
return -RT_EINVAL;
}
if (cfg->mode & RT_SPI_SLAVE)
{
config.channelConfig.channelMode = kECSPI_Slave;
}
else
{
config.channelConfig.channelMode = kECSPI_Master;
}
if(cfg->mode & RT_SPI_CPHA)
{
config.channelConfig.phase = kECSPI_ClockPhaseSecondEdge;
}
else
{
config.channelConfig.phase = kECSPI_ClockPhaseFirstEdge;
}
if(cfg->mode & RT_SPI_CPOL)
{
config.channelConfig.polarity = kECSPI_PolarityActiveLow;
}
else
{
config.channelConfig.polarity = kECSPI_PolarityActiveHigh;
}
config.baudRate_Bps = cfg->max_hz;
scr_clock = (CLOCK_GetPllFreq(kCLOCK_PllUsb1) / 8U);
ECSPI_MasterInit(spi_dev->config->ECSPI, &config, scr_clock);
return RT_EOK;
}
static rt_ssize_t imx6ull_ecspi_xfer(struct rt_spi_device *device, struct rt_spi_message *message)
{
struct imx6ull_spi_bus *spi_dev = RT_NULL;
struct imx6ull_spi_cs *cs = RT_NULL;
const rt_uint8_t *send_ptr = RT_NULL;
rt_uint8_t *recv_ptr = RT_NULL;
rt_uint16_t size = 0;
rt_uint8_t temp_data;
spi_dev = (struct imx6ull_spi_bus *)(device->bus->parent.user_data);
cs = (struct imx6ull_spi_cs *)device->parent.user_data;
recv_ptr = (rt_uint8_t *)message->recv_buf;
send_ptr = (rt_uint8_t *)message->send_buf;
size = message->length;
if(message->cs_take && cs)
{
rt_pin_write(cs->pin, PIN_LOW);
}
ECSPI_SetChannelSelect(spi_dev->config->ECSPI, kECSPI_Channel0);
while (size--)
{
temp_data = (send_ptr != RT_NULL) ? (*send_ptr++) : 0xff;
while (!(spi_dev->config->ECSPI->STATREG & ECSPI_STATREG_TE_MASK));
ECSPI_WriteData(spi_dev->config->ECSPI, temp_data);
while (!(spi_dev->config->ECSPI->STATREG & ECSPI_STATREG_RR_MASK));
temp_data = ECSPI_ReadData(spi_dev->config->ECSPI);
if (recv_ptr != RT_NULL)
{
*recv_ptr++ = temp_data;
}
}
if(message->cs_release && cs)
{
rt_pin_write(cs->pin, PIN_HIGH);
}
return message->length;
}
rt_err_t rt_hw_spi_device_attach(const char *bus_name, const char *device_name, rt_uint32_t pin)
{
rt_err_t ret = RT_EOK;
struct rt_spi_device *spi_device = (struct rt_spi_device *)rt_malloc(sizeof(struct rt_spi_device));
RT_ASSERT(spi_device != RT_NULL);
struct imx6ull_spi_cs *cs_pin = (struct imx6ull_spi_cs *)rt_malloc(sizeof(struct imx6ull_spi_cs));
RT_ASSERT(cs_pin != RT_NULL);
cs_pin->pin = pin;
rt_pin_mode(pin, PIN_MODE_OUTPUT);
rt_pin_write(pin, PIN_HIGH);
ret = rt_spi_bus_attach_device(spi_device, device_name, bus_name, (void *)cs_pin);
return ret;
}
static rt_err_t imx6ull_spi_gpio_init(struct imx6ull_spi_bus *bus)
{
struct imx6ull_spi_bus *spi_bus = RT_NULL;
spi_bus = (struct imx6ull_spi_bus *)bus;
imx6ull_gpio_init(&spi_bus->config->clk_gpio);
imx6ull_gpio_init(&spi_bus->config->miso_gpio);
imx6ull_gpio_init(&spi_bus->config->mosi_gpio);
return RT_EOK;
}
#ifdef RT_USING_DEVICE_OPS
static const struct rt_spi_ops imxrt_spi_ops =
{
.configure = imx6ull_ecspi_configure,
.xfer = imx6ull_ecspi_xfer,
};
#endif
int rt_hw_spi_init(void)
{
rt_uint16_t obj_num = 0;
obj_num = sizeof(spi_config) / sizeof(spi_config[0]);
for(int i = 0; i < obj_num; i++)
{
spi_obj[i].config = &spi_config[i];
spi_obj[i].config->ECSPI = (ECSPI_Type *)imx6ull_get_periph_vaddr((rt_uint32_t)(spi_obj[i].config->ECSPI));
imx6ull_spi_gpio_init(&spi_obj[i]);
CLOCK_EnableClock(spi_obj[i].config->clk_ip_name);
spi_obj[i].parent.parent.user_data = &spi_obj[i];
rt_spi_bus_register(&spi_obj[i].parent, spi_obj[i].config->name, &imxrt_spi_ops);
}
return RT_EOK;
}
INIT_DEVICE_EXPORT(rt_hw_spi_init);
#endif

View File

@@ -0,0 +1,98 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-01-13 Lyons first version
* 2021-06-23 RiceChen refactor
*/
#ifndef __DRV_SPI_H__
#define __DRV_SPI_H__
#include <board.h>
#include "drv_common.h"
#include "fsl_iomuxc.h"
#include "fsl_clock.h"
#include "fsl_ecspi.h"
struct imx6ull_spi_cs
{
rt_uint32_t pin;
};
struct imx6ull_spi_config
{
ECSPI_Type *ECSPI;
char *name;
rt_uint32_t clk_ip_name;
struct imx6ull_iomuxc clk_gpio;
struct imx6ull_iomuxc miso_gpio;
struct imx6ull_iomuxc mosi_gpio;
};
struct imx6ull_spi_bus
{
struct rt_spi_bus parent;
struct imx6ull_spi_config *config;
};
#ifdef BSP_USING_SPI1
#define SPI1_BUS_CONFIG \
{ \
.ECSPI = ECSPI1, \
.name = "spi1", \
.clk_ip_name = kCLOCK_Ecspi1, \
.clk_gpio = {IOMUXC_CSI_DATA04_ECSPI1_SCLK, 0, 0X10B1}, \
.miso_gpio = {IOMUXC_CSI_DATA07_ECSPI1_MISO, 0, 0X10B1}, \
.mosi_gpio = {IOMUXC_CSI_DATA06_ECSPI1_MOSI, 0, 0X10B1}, \
}
#endif /* BSP_USING_SPI1 */
#ifdef BSP_USING_SPI2
#define SPI2_BUS_CONFIG \
{ \
.ECSPI = ECSPI2, \
.name = "spi2", \
.clk_ip_name = kCLOCK_Ecspi2, \
.clk_gpio = {IOMUXC_UART4_TX_DATA_ECSPI2_SCLK, 0, 0X10B1}, \
.miso_gpio = {IOMUXC_UART5_RX_DATA_ECSPI2_MISO, 0, 0X10B1}, \
.mosi_gpio = {IOMUXC_UART5_TX_DATA_ECSPI2_MOSI, 0, 0X10B1}, \
}
#endif /* BSP_USING_SPI2 */
#ifdef BSP_USING_SPI3
#define SPI3_BUS_CONFIG \
{ \
.ECSPI = ECSPI3, \
.name = "spi3", \
.clk_ip_name = kCLOCK_Ecspi3, \
.clk_gpio = {IOMUXC_UART2_RX_DATA_ECSPI3_SCLK, 0, 0X10B1}, \
.miso_gpio = {IOMUXC_UART2_RTS_B_ECSPI3_MISO, 0, 0X10B1}, \
.mosi_gpio = {IOMUXC_UART2_CTS_B_ECSPI3_MOSI, 0, 0X10B1}, \
}
#endif /* BSP_USING_SPI3 */
#ifdef BSP_USING_SPI4
#define SPI4_BUS_CONFIG \
{ \
.ECSPI = ECSPI4, \
.name = "spi4", \
.clk_ip_name = kCLOCK_Ecspi4, \
.clk_gpio = {IOMUXC_ENET2_TX_DATA1_ECSPI4_SCLK, 0, 0X10B1}, \
.miso_gpio = {IOMUXC_ENET2_TX_CLK_ECSPI4_MISO, 0, 0X10B1}, \
.mosi_gpio = {IOMUXC_ENET2_TX_EN_ECSPI4_MOSI, 0, 0X10B1}, \
}
#endif /* BSP_USING_SPI4 */
rt_err_t rt_hw_spi_device_attach(const char *bus_name, const char *device_name, rt_uint32_t pin);
#endif

View File

@@ -0,0 +1,172 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-11-22 Jesven first version
*/
#include <rthw.h>
#include <rtthread.h>
#include <stdint.h>
#include <board.h>
#include "mmu.h"
#define TICK_PERIOD (g_sys_freq / RT_TICK_PER_SECOND)
static int g_sys_freq;
#define IRQ_SECURE_PHY_TIMER 29 /* Secure physical timer event */
#define IRQ_NOSECURE_PHY_TIMER 30 /* No-Secure physical timer event */
#define IRQ_SYS_TICK IRQ_SECURE_PHY_TIMER
/* System Counter */
struct sctr_regs {
rt_uint32_t cntcr;
rt_uint32_t cntsr;
rt_uint32_t cntcv1;
rt_uint32_t cntcv2;
rt_uint32_t resv1[4];
rt_uint32_t cntfid0;
rt_uint32_t cntfid1;
rt_uint32_t cntfid2;
rt_uint32_t resv2[1001];
rt_uint32_t counterid[1];
};
#define SC_CNTCR_ENABLE (1 << 0)
#define SC_CNTCR_HDBG (1 << 1)
#define SC_CNTCR_FREQ0 (1 << 8)
#define SC_CNTCR_FREQ1 (1 << 9)
#define isb() __asm__ __volatile__ ("" : : : "memory")
#define dsb() __asm__ __volatile__ ("" : : : "memory")
#define dmb() __asm__ __volatile__ ("" : : : "memory")
static inline void enable_cntp(void)
{
rt_uint32_t cntv_ctl;
cntv_ctl = 1;
asm volatile ("mcr p15, 0, %0, c14, c2, 1" :: "r"(cntv_ctl)); // write CNTP_CTL
isb();
}
static inline void disable_cntp(void)
{
rt_uint32_t cntv_ctl;
cntv_ctl = 0;
asm volatile ("mcr p15, 0, %0, c14, c2, 1" :: "r"(cntv_ctl)); // write CNTP_CTL
isb();
}
static inline rt_uint32_t read_cntfrq(void)
{
rt_uint32_t val;
asm volatile ("mrc p15, 0, %0, c14, c0, 0" : "=r"(val));
return val;
}
static inline void write_cntp_tval(rt_uint32_t val)
{
asm volatile ("mcr p15, 0, %0, c14, c2, 0" :: "r"(val));
isb();
return;
}
static inline void write_cntp_cval(rt_uint64_t val)
{
asm volatile ("mcrr p15, 2, %Q0, %R0, c14" :: "r" (val));
isb();
return;
}
static inline rt_uint64_t read_cntp_cval(void)
{
rt_uint64_t val;
asm volatile ("mrrc p15, 2, %Q0, %R0, c14" : "=r" (val));
return (val);
}
volatile unsigned int *CCM_CLPCR;
static void imx6ull_enable_clk_in_waitmode(void)
{
CCM_CLPCR = rt_ioremap((void*)0x20C4054, 4);
*CCM_CLPCR &= ~((1 << 5) | 0x3);
}
static void system_counter_clk_source_init(void)
{
/* to do */
}
static void system_counter_init(void)
{
/* enable system_counter */
#define SCTR_BASE_ADDR 0x021DC000
#define CONFIG_SC_TIMER_CLK 8000000
/* imx6ull, enable system counter */
struct sctr_regs *sctr = (struct sctr_regs *)rt_ioremap((void*)SCTR_BASE_ADDR, sizeof(struct sctr_regs));
unsigned long val, freq;
freq = CONFIG_SC_TIMER_CLK;
asm volatile("mcr p15, 0, %0, c14, c0, 0" : : "r" (freq));
sctr->cntfid0 = freq;
/* Enable system counter */
val = sctr->cntcr;
val &= ~(SC_CNTCR_FREQ0 | SC_CNTCR_FREQ1);
val |= SC_CNTCR_FREQ0 | SC_CNTCR_ENABLE | SC_CNTCR_HDBG;
sctr->cntcr = val;
imx6ull_enable_clk_in_waitmode();
}
static void arch_timer_init(void)
{
g_sys_freq = read_cntfrq();
/* set timeout val */
disable_cntp();
write_cntp_tval(TICK_PERIOD);
/* start timer */
enable_cntp();
/* enable irq */
}
static void rt_hw_timer_isr(int vector, void *param)
{
rt_tick_increase();
/* setup for next irq */
/* clear interrupt */
disable_cntp();
write_cntp_cval(read_cntp_cval() + TICK_PERIOD);
enable_cntp();
}
int rt_hw_timer_init(void)
{
/* Setup Timer for generating irq */
/* enable timer */
system_counter_clk_source_init();
system_counter_init();
arch_timer_init();
/* insall irq, enable irq */
rt_hw_interrupt_install(IRQ_SYS_TICK, rt_hw_timer_isr, RT_NULL, "tick");
rt_hw_interrupt_umask(IRQ_SYS_TICK);
return 0;
}
INIT_BOARD_EXPORT(rt_hw_timer_init);

View File

@@ -0,0 +1,17 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-11-22 Jesven first version
*/
#ifndef DRV_TIMER_H__
#define DRV_TIMER_H__
void timer_init(int timer, unsigned int preload);
void timer_clear_pending(int timer);
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,39 @@
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-01-13 RiceChen the first version
*/
#ifndef __GT911_H__
#define __GT911_H__
#define GT911_ADDR_LEN 2
#define GT911_REGITER_LEN 2
#define GT911_MAX_TOUCH 5
#define GT911_POINT_INFO_NUM 5
#define GT911_ADDRESS_HIGH 0x5D
#define GT911_ADDRESS_LOW 0x14
#define GT911_COMMAND_REG 0x8040
#define GT911_CONFIG_REG 0x8047
#define GT911_PRODUCT_ID 0x8140
#define GT911_VENDOR_ID 0x814A
#define GT911_READ_STATUS 0x814E
#define GT911_POINT1_REG 0x814F
#define GT911_POINT2_REG 0x8157
#define GT911_POINT3_REG 0x815F
#define GT911_POINT4_REG 0x8167
#define GT911_POINT5_REG 0x816F
#define GT911_CHECK_SUM 0x80FF
int rt_hw_gt911_init(const char *name, struct rt_touch_config *cfg);
#endif /* gt911.h */

View File

@@ -0,0 +1,350 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-01-09 Lyons first version
*/
#include <rtconfig.h>
#ifdef RT_USING_SERIAL
#include "board.h"
#include "drv_uart.h"
#include "drv_common.h"
enum
{
#ifdef BSP_USING_UART1
eDevUart_UART1,
#endif
#ifdef BSP_USING_UART2
eDevUart_UART2,
#endif
#ifdef BSP_USING_UART3
eDevUart_UART3,
#endif
#ifdef BSP_USING_UART4
eDevUart_UART4,
#endif
#ifdef BSP_USING_UART5
eDevUart_UART5,
#endif
#ifdef BSP_USING_UART6
eDevUart_UART6,
#endif
#ifdef BSP_USING_UART7
eDevUart_UART7,
#endif
#ifdef BSP_USING_UART8
eDevUart_UART8,
#endif
eDevUart_Max,
};
_internal_rw struct imx_uart _s_uart[eDevUart_Max] = {
#ifdef BSP_USING_UART1
{
.name = "uart0",
.periph.paddr = IMX6ULL_UART1_BASE,
.irqno = UART1_IRQn,
.gpio = {
{IOMUXC_UART1_TX_DATA_UART1_TX, 0, 0x10B0},
{IOMUXC_UART1_RX_DATA_UART1_RX, 0, 0x10B0},
},
.flag = (RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX),
.param = RT_SERIAL_CONFIG_115200N81,
},
#endif
#ifdef BSP_USING_UART2
{
.name = "uart1",
.periph.paddr = IMX6ULL_UART2_BASE,
.irqno = UART2_IRQn,
.gpio = {
{IOMUXC_UART2_TX_DATA_UART2_TX, 0, 0x10B0},
{IOMUXC_UART2_RX_DATA_UART2_RX, 0, 0x10B0},
},
.flag = (RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX),
.param = RT_SERIAL_CONFIG_DEFAULT,
},
#endif
#ifdef BSP_USING_UART3
{
.name = "uart2",
.periph.paddr = IMX6ULL_UART3_BASE,
.irqno = UART3_IRQn,
.gpio = {
{IOMUXC_UART3_TX_DATA_UART3_TX, 0, 0x10B0},
{IOMUXC_UART3_RX_DATA_UART3_RX, 0, 0x10B0},
},
.flag = (RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX),
.param = RT_SERIAL_CONFIG_DEFAULT,
},
#endif
#ifdef BSP_USING_UART4
{
.name = "uart3",
.periph.paddr = IMX6ULL_UART4_BASE,
.irqno = UART4_IRQn,
.gpio = {
{IOMUXC_UART4_TX_DATA_UART4_TX, 0, 0x10B0},
{IOMUXC_UART4_RX_DATA_UART4_RX, 0, 0x10B0},
},
.flag = (RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX),
.param = RT_SERIAL_CONFIG_DEFAULT,
},
#endif
#ifdef BSP_USING_UART5
{
.name = "uart4",
.periph.paddr = IMX6ULL_UART5_BASE,
.irqno = UART5_IRQn,
.gpio = {
{IOMUXC_UART5_TX_DATA_UART5_TX, 0, 0x10B0},
{IOMUXC_UART5_RX_DATA_UART5_RX, 0, 0x10B0},
},
.flag = (RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX),
.param = RT_SERIAL_CONFIG_DEFAULT,
},
#endif
#ifdef BSP_USING_UART6
{
.name = "uart5",
.periph.paddr = IMX6ULL_UART6_BASE,
.irqno = UART6_IRQn,
.gpio = {
{IOMUXC_ENET2_RX_DATA1_UART6_TX, 0, 0x10B0},
{IOMUXC_ENET2_RX_DATA0_UART6_RX, 0, 0x10B0},
},
.flag = (RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX),
.param = RT_SERIAL_CONFIG_DEFAULT,
},
#endif
#ifdef BSP_USING_UART7
{
.name = "uart6",
.periph.paddr = IMX6ULL_UART7_BASE,
.irqno = UART7_IRQn,
.gpio = {
{IOMUXC_ENET2_TX_DATA0_UART7_TX, 0, 0x10B0},
{IOMUXC_ENET2_RX_EN_UART7_RX, 0, 0x10B0},
},
.flag = (RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX),
.param = RT_SERIAL_CONFIG_DEFAULT,
},
#endif
#ifdef BSP_USING_UART8
{
.name = "uart7",
.periph.paddr = IMX6ULL_UART8_BASE,
.irqno = UART8_IRQn,
.gpio = {
{IOMUXC_ENET2_TX_DATA1_UART8_TX, 0, 0x10B0},
{IOMUXC_ENET2_TX_EN_UART8_RX, 0, 0x10B0},
},
.flag = (RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX),
.param = RT_SERIAL_CONFIG_DEFAULT,
},
#endif
};
static void _uart_gpio_init( struct imx_uart *device )
{
for (int i=0; i<GET_ARRAY_NUM(device->gpio); i++)
{
imx6ull_gpio_init(&device->gpio[i]);
}
}
static rt_err_t _uart_ops_configure( struct rt_serial_device *dev,
struct serial_configure *cfg )
{
struct imx_uart *uart = RT_NULL;
UART_Type *periph = RT_NULL;
rt_uint32_t reg_value;
RT_ASSERT(RT_NULL != dev);
RT_ASSERT(RT_NULL != cfg);
uart = (struct imx_uart*)dev;
periph = (UART_Type*)uart->periph.vaddr;
_uart_gpio_init(uart);
periph->UCR1 &= ~UART_UCR1_UARTEN_MASK;
periph->UFCR &= ~UART_UFCR_RFDIV_MASK;
periph->UFCR |= UART_UFCR_RFDIV(5);
RT_ASSERT(cfg->baud_rate <= BAUD_RATE_921600);
periph->UBIR = UART_UBIR_INC(15);
periph->UBMR = UART_UBMR_MOD(HW_UART_BUS_CLOCK / cfg->baud_rate - 1);
reg_value = 0;
switch (cfg->data_bits)
{
case DATA_BITS_7:
reg_value |= UART_UCR2_WS(0);
break;
default:
reg_value |= UART_UCR2_WS(1);
break;
}
switch (cfg->stop_bits)
{
case STOP_BITS_2:
reg_value |= UART_UCR2_STPB(1);
break;
default:
reg_value |= UART_UCR2_STPB(0);
break;
}
switch (cfg->parity)
{
case PARITY_ODD:
reg_value |= UART_UCR2_PREN(1);
reg_value |= UART_UCR2_PROE(1);
break;
case PARITY_EVEN:
reg_value |= UART_UCR2_PREN(1);
reg_value |= UART_UCR2_PROE(0);
break;
default:
reg_value |= UART_UCR2_PREN(0);
reg_value |= UART_UCR2_PROE(0);
break;
}
periph->UCR3 |= UART_UCR3_RXDMUXSEL(1); //this bit should always be set!
periph->UCR2 |= reg_value | UART_UCR2_IRTS(1) | UART_UCR2_TXEN(1) | UART_UCR2_RXEN(1);
periph->UCR1 |= UART_UCR1_UARTEN(1);
return RT_EOK;
}
static rt_err_t _uart_ops_control( struct rt_serial_device *dev,
int cmd,
void *arg )
{
struct imx_uart *uart = RT_NULL;
UART_Type *periph = RT_NULL;
rt_err_t result;
RT_ASSERT(RT_NULL != dev);
uart = (struct imx_uart*)dev;
periph = (UART_Type*)uart->periph.vaddr;
result = RT_EOK;
switch (cmd)
{
case RT_DEVICE_CTRL_CLR_INT:
periph->UCR4 &= ~UART_UCR4_DREN_MASK;
periph->UCR4 |= UART_UCR4_DREN(0);
break;
case RT_DEVICE_CTRL_SET_INT:
periph->UCR4 |= UART_UCR4_DREN(1);
rt_hw_interrupt_umask(uart->irqno);
break;
default:
result = -RT_EINVAL;
break;
}
return result;
}
static int _uart_ops_putc( struct rt_serial_device *dev,
char ch )
{
struct imx_uart *uart = RT_NULL;
UART_Type *periph = RT_NULL;
RT_ASSERT(RT_NULL != dev);
uart = (struct imx_uart*)dev;
periph = (UART_Type*)uart->periph.vaddr;
while (0 == (periph->USR2 & UART_USR2_TXDC_MASK));
periph->UTXD = ch;
return 1;
}
static int _uart_ops_getc( struct rt_serial_device *dev )
{
struct imx_uart *uart = RT_NULL;
UART_Type *periph = RT_NULL;
int ch;
RT_ASSERT(RT_NULL != dev);
uart = (struct imx_uart*)dev;
periph = (UART_Type*)uart->periph.vaddr;
ch = (0 == (periph->USR2 & UART_USR2_RDR_MASK)) ? -1 : periph->URXD;
return ch;
}
_internal_ro struct rt_uart_ops _k_uart_ops =
{
_uart_ops_configure, /* configure */
_uart_ops_control, /* control */
_uart_ops_putc, /* putc */
_uart_ops_getc, /* getc */
RT_NULL, /* dma_transmit */
};
static void _uart_isr( int irqno, void* parameter )
{
struct rt_serial_device *serial;
rt_interrupt_enter();
serial = (struct rt_serial_device *)parameter;
rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
rt_interrupt_leave();
}
int rt_hw_uart_init(void)
{
for (int idx=0; idx<GET_ARRAY_NUM(_s_uart); idx++)
{
_s_uart[idx].periph.vaddr = platform_get_periph_vaddr(_s_uart[idx].periph.paddr);
_s_uart[idx].parent.ops = &_k_uart_ops;
rt_memcpy(&_s_uart[idx].parent.config, &_s_uart[idx].param, sizeof(struct serial_configure));
rt_hw_serial_register( &_s_uart[idx].parent,
_s_uart[idx].name,
_s_uart[idx].flag,
RT_NULL );
rt_hw_interrupt_install(_s_uart[idx].irqno, _uart_isr, &_s_uart[idx].parent, _s_uart[idx].name);
}
return RT_EOK;
}
INIT_BOARD_EXPORT(rt_hw_uart_init);
#endif //#ifdef RT_USING_SERIAL

View File

@@ -0,0 +1,58 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-01-09 Lyons first version
*/
#ifndef __DRV_UART_H__
#define __DRV_UART_H__
#include "board.h"
#include "drv_common.h"
#ifdef RT_USING_SERIAL
#ifndef HW_UART_BUS_CLOCK
#define HW_UART_BUS_CLOCK 80000000
#endif
#define RT_SERIAL_CONFIG_115200N81 \
{ \
BAUD_RATE_115200, \
DATA_BITS_8, \
STOP_BITS_1, \
PARITY_NONE, \
BIT_ORDER_LSB, \
NRZ_NORMAL, \
RT_SERIAL_RB_BUFSZ, \
0 \
}
struct imx_periph
{
rt_uint32_t paddr;
rt_uint32_t vaddr;
};
struct imx_uart
{
struct rt_serial_device parent;
const char *name;
struct imx_periph periph;
rt_uint32_t irqno;
//[0]-tx [1]-rx
struct imx6ull_iomuxc gpio[2];
rt_uint32_t flag;
struct serial_configure param;
};
#endif //#ifdef RT_USING_SERIAL
#endif //#ifndef __DRV_UART_H__

View File

@@ -0,0 +1,366 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2017-12-04 ZYH first implementation
*/
#include <usb/include/usb_device_config.h>
#include <usb/include/usb.h>
#include <rtthread.h>
#include <usb/phy/usb_phy.h>
#include <usb/device/usb_device.h>
#include <usb/device/usb_device_dci.h>
#include <rtdevice.h>
#include <imx6ull.h>
#define USB0_IRQNUM 75
/* USB PHY condfiguration */
#define BOARD_USB_PHY_D_CAL (0x0CU)
#define BOARD_USB_PHY_TXCAL45DP (0x06U)
#define BOARD_USB_PHY_TXCAL45DM (0x06U)
#ifdef BSP_USING_USB_DEVICE
static usb_device_handle ehci0_handle;
static struct udcd _fsl_udc_0;
static usb_status_t usb_device_callback(usb_device_handle handle, uint32_t callbackEvent, void *eventParam);
static usb_status_t usb_device_endpoint_callback(usb_device_handle handle, usb_device_endpoint_callback_message_struct_t *message, void *callbackParam);
static void USB_DeviceIsrEnable(uint8_t controllerId)
{
uint8_t irqNumber;
#if defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0U)
uint8_t usbDeviceEhciIrq[] = USBHS_IRQS;
irqNumber = usbDeviceEhciIrq[controllerId - kUSB_ControllerEhci0];
#endif
/* Install isr, set priority, and enable IRQ. */
#if defined(__GIC_PRIO_BITS)
GIC_SetPriority((IRQn_Type)irqNumber, 3);
#else
NVIC_SetPriority((IRQn_Type)irqNumber, 3);
#endif
EnableIRQ((IRQn_Type)irqNumber);
}
/*!
* @brief Initializes USB specific setting that was not set by the Clocks tool.
*/
static void USB_DeviceClockInit(uint8_t controllerId)
{
#if defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0U)
usb_phy_config_struct_t phyConfig = {
BOARD_USB_PHY_D_CAL, BOARD_USB_PHY_TXCAL45DP, BOARD_USB_PHY_TXCAL45DM,
};
#endif
#if defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0U)
if (controllerId == kUSB_ControllerEhci0)
{
CLOCK_EnableUsbhs0PhyPllClock(kCLOCK_Usbphy480M, 480000000U);
CLOCK_EnableUsbhs0Clock(kCLOCK_Usb480M, 480000000U);
}
else
{
CLOCK_EnableUsbhs1PhyPllClock(kCLOCK_Usbphy480M, 480000000U);
CLOCK_EnableUsbhs1Clock(kCLOCK_Usb480M, 480000000U);
}
USB_EhciPhyInit(controllerId, 0, &phyConfig);
#endif
}
static struct ep_id _ehci0_ep_pool[] =
{
{0x0, USB_EP_ATTR_CONTROL, USB_DIR_INOUT, 64, ID_ASSIGNED },
{0x1, USB_EP_ATTR_BULK, USB_DIR_IN, 64, ID_UNASSIGNED},
{0x1, USB_EP_ATTR_BULK, USB_DIR_OUT, 64, ID_UNASSIGNED},
{0x2, USB_EP_ATTR_INT, USB_DIR_IN, 64, ID_UNASSIGNED},
{0x2, USB_EP_ATTR_INT, USB_DIR_OUT, 64, ID_UNASSIGNED},
{0x3, USB_EP_ATTR_BULK, USB_DIR_IN, 64, ID_UNASSIGNED},
{0x3, USB_EP_ATTR_BULK, USB_DIR_OUT, 64, ID_UNASSIGNED},
{0x4, USB_EP_ATTR_INT, USB_DIR_IN, 64, ID_UNASSIGNED},
{0x4, USB_EP_ATTR_INT, USB_DIR_OUT, 64, ID_UNASSIGNED},
{0x5, USB_EP_ATTR_BULK, USB_DIR_IN, 64, ID_UNASSIGNED},
{0x5, USB_EP_ATTR_BULK, USB_DIR_OUT, 64, ID_UNASSIGNED},
{0x6, USB_EP_ATTR_INT, USB_DIR_IN, 64, ID_UNASSIGNED},
{0x6, USB_EP_ATTR_INT, USB_DIR_OUT, 64, ID_UNASSIGNED},
{0x7, USB_EP_ATTR_BULK, USB_DIR_IN, 64, ID_UNASSIGNED},
{0x7, USB_EP_ATTR_BULK, USB_DIR_OUT, 64, ID_UNASSIGNED},
{0xFF, USB_EP_ATTR_TYPE_MASK, USB_DIR_MASK, 0, ID_ASSIGNED },
};
/*!
* @brief USB Interrupt service routine.
*
* This function serves as the USB interrupt service routine.
*
* @return None.
*/
static struct rt_workqueue *usb0_wq = NULL;
static struct rt_work usb0_work;
void ehci0_work(struct rt_work *work, void *work_data)
{
USB_DeviceEhciIsrFunction(ehci0_handle);
rt_hw_interrupt_umask(USB0_IRQNUM);
}
void USB_OTG1_IRQHandler(int irq, void *base)
{
// USB_DeviceEhciIsrFunction(ehci0_handle);
rt_hw_interrupt_mask(USB0_IRQNUM);
rt_workqueue_dowork(usb0_wq, &usb0_work);
}
static rt_err_t _ehci0_ep_set_stall(rt_uint8_t address)
{
USB_DeviceStallEndpoint(ehci0_handle, address);
return RT_EOK;
}
static rt_err_t _ehci0_ep_clear_stall(rt_uint8_t address)
{
USB_DeviceUnstallEndpoint(ehci0_handle, address);
return RT_EOK;
}
static rt_err_t _ehci0_set_address(rt_uint8_t address)
{
USB_DeviceSetStatus(ehci0_handle, kUSB_DeviceStatusAddress, &address);
return RT_EOK;
}
static rt_err_t _ehci0_set_config(rt_uint8_t address)
{
return RT_EOK;
}
static rt_err_t _ehci0_ep_enable(uep_t ep)
{
usb_device_endpoint_init_struct_t ep_init;
usb_device_endpoint_callback_struct_t ep_callback;
rt_uint32_t param = ep->ep_desc->bEndpointAddress;
RT_ASSERT(ep != RT_NULL);
RT_ASSERT(ep->ep_desc != RT_NULL);
ep_init.maxPacketSize = ep->ep_desc->wMaxPacketSize;
ep_init.endpointAddress = ep->ep_desc->bEndpointAddress;
ep_init.transferType = ep->ep_desc->bmAttributes;
ep_init.zlt = 0;
ep_callback.callbackFn = usb_device_endpoint_callback;
ep_callback.callbackParam = (void *)param;
ep_callback.isBusy = 0;
USB_DeviceInitEndpoint(ehci0_handle, &ep_init, &ep_callback);
return RT_EOK;
}
static rt_err_t _ehci0_ep_disable(uep_t ep)
{
RT_ASSERT(ep != RT_NULL);
RT_ASSERT(ep->ep_desc != RT_NULL);
USB_DeviceDeinitEndpoint(ehci0_handle, ep->ep_desc->bEndpointAddress);
return RT_EOK;
}
static rt_size_t _ehci0_ep_read(rt_uint8_t address, void *buffer)
{
rt_size_t size = 0;
RT_ASSERT(buffer != RT_NULL);
return size;
}
static rt_size_t _ehci0_ep_read_prepare(rt_uint8_t address, void *buffer, rt_size_t size)
{
USB_DeviceRecvRequest(ehci0_handle, address, buffer, size);
return size;
}
static rt_size_t _ehci0_ep_write(rt_uint8_t address, void *buffer, rt_size_t size)
{
USB_DeviceSendRequest(ehci0_handle, address, buffer, size);
return size;
}
static rt_err_t _ehci0_ep0_send_status(void)
{
_ehci0_ep_write(0x00, NULL, 0);
return RT_EOK;
}
static rt_err_t _ehci0_suspend(void)
{
return RT_EOK;
}
static rt_err_t _ehci0_wakeup(void)
{
return RT_EOK;
}
const static struct udcd_ops _ehci0_udc_ops =
{
_ehci0_set_address,
_ehci0_set_config,
_ehci0_ep_set_stall,
_ehci0_ep_clear_stall,
_ehci0_ep_enable,
_ehci0_ep_disable,
_ehci0_ep_read_prepare,
_ehci0_ep_read,
_ehci0_ep_write,
_ehci0_ep0_send_status,
_ehci0_suspend,
_ehci0_wakeup,
};
extern void rt_hw_interrupt_umask(int vector);
static rt_err_t drv_ehci0_usbd_init(rt_device_t device)
{
usb_status_t result;
USB_DeviceClockInit(kUSB_ControllerEhci0);
result = USB_DeviceInit(kUSB_ControllerEhci0, usb_device_callback, &ehci0_handle);
RT_ASSERT(ehci0_handle);
if(result == kStatus_USB_Success)
{
usb0_wq = rt_workqueue_create("u0wq", 4096, 3);
rt_work_init(&usb0_work, ehci0_work, NULL);
rt_hw_interrupt_install(USB0_IRQNUM, USB_OTG1_IRQHandler, (void *)ehci0_handle, "usb1_intr");
rt_hw_interrupt_umask(USB0_IRQNUM);
USB_DeviceRun(ehci0_handle);
}
else
{
rt_kprintf("USB_DeviceInit ehci0 error\r\n");
return RT_ERROR;
}
return RT_EOK;
}
struct rt_device_ops imx6ull_usb_ops =
{
drv_ehci0_usbd_init,
RT_NULL,
RT_NULL,
RT_NULL,
RT_NULL,
RT_NULL,
};
static int rt_usbd_init(void)
{
rt_memset((void *)&_fsl_udc_0, 0, sizeof(struct udcd));
_fsl_udc_0.parent.type = RT_Device_Class_USBDevice;
_fsl_udc_0.parent.ops = &imx6ull_usb_ops;
_fsl_udc_0.ops = &_ehci0_udc_ops;
/* Register endpoint infomation */
_fsl_udc_0.ep_pool = _ehci0_ep_pool;
_fsl_udc_0.ep0.id = &_ehci0_ep_pool[0];
_fsl_udc_0.device_is_hs = RT_FALSE;
rt_device_register((rt_device_t)&_fsl_udc_0, "usbd", 0);
rt_usb_device_init();
return 0;
}
// INIT_DEVICE_EXPORT(rt_usbd_init);
static usb_status_t usb_device_endpoint_callback(usb_device_handle handle, usb_device_endpoint_callback_message_struct_t *message, void *callbackParam)
{
rt_uint32_t ep_addr = (rt_uint32_t)callbackParam;
usb_device_struct_t *deviceHandle = (usb_device_struct_t *)handle;
udcd_t udcd = RT_NULL;
uint8_t state;
if(deviceHandle->controllerId == kUSB_ControllerEhci0)
udcd = &_fsl_udc_0;
if(message->isSetup)
{
rt_usbd_ep0_setup_handler(udcd, (struct urequest*)message->buffer);
}
else if(ep_addr == 0x00)
{
USB_DeviceGetStatus(handle, kUSB_DeviceStatusDeviceState, &state);
if(state == kUSB_DeviceStateAddressing)
{
if (kStatus_USB_Success == USB_DeviceSetStatus(handle, kUSB_DeviceStatusAddress, NULL))
{
state = kUSB_DeviceStateAddress;
USB_DeviceSetStatus(handle, kUSB_DeviceStatusDeviceState, &state);
}
}
rt_usbd_ep0_out_handler(udcd, message->length);
}
else if(ep_addr == 0x80)
{
USB_DeviceGetStatus(handle, kUSB_DeviceStatusDeviceState, &state);
if(state == kUSB_DeviceStateAddressing)
{
if (kStatus_USB_Success == USB_DeviceSetStatus(handle, kUSB_DeviceStatusAddress, NULL))
{
state = kUSB_DeviceStateAddress;
USB_DeviceSetStatus(handle, kUSB_DeviceStatusDeviceState, &state);
}
}
rt_usbd_ep0_in_handler(udcd);
}
else if(ep_addr & 0x80)
{
rt_usbd_ep_in_handler(udcd, ep_addr, message->length);
}
else
{
rt_usbd_ep_out_handler(udcd, ep_addr, message->length);
}
return kStatus_USB_Success;
}
static usb_status_t usb_device_callback(usb_device_handle handle, uint32_t callbackEvent, void *eventParam)
{
usb_status_t error = kStatus_USB_Error;
usb_device_struct_t *deviceHandle = (usb_device_struct_t *)handle;
usb_device_endpoint_init_struct_t ep0_init =
{
0x40,
0x00,
USB_EP_ATTR_CONTROL,
0
};
usb_device_endpoint_callback_struct_t ep0_callback =
{
usb_device_endpoint_callback,
0,
0
};
udcd_t udcd = RT_NULL;
if(deviceHandle->controllerId == kUSB_ControllerEhci0)
udcd = &_fsl_udc_0;
switch (callbackEvent)
{
case kUSB_DeviceEventBusReset:
ep0_init.endpointAddress = 0x00;
ep0_callback.callbackParam = (void *)0x00;
USB_DeviceInitEndpoint(deviceHandle, &ep0_init, &ep0_callback);
ep0_init.endpointAddress = 0x80;
ep0_callback.callbackParam = (void *)0x80;
USB_DeviceInitEndpoint(deviceHandle, &ep0_init, &ep0_callback);
rt_usbd_reset_handler(udcd);
break;
case kUSB_DeviceEventAttach:
rt_usbd_connect_handler(udcd);
break;
case kUSB_DeviceEventDetach:
rt_usbd_disconnect_handler(udcd);
break;
}
return error;
}
#endif
/********************* end of file ************************/

View File

@@ -0,0 +1,203 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-07-28 songchao first version
*/
#include <rtconfig.h>
#ifdef RT_USING_WDT
#include <rtthread.h>
#include <rtdbg.h>
#include "drv_wdt.h"
#include "fsl_wdog.h"
#include "imx6ull.h"
enum
{
#ifdef RT_USING_WDT1
DEV_WDT1,
#endif
#ifdef RT_USING_WDT2
DEV_WDT2,
#endif
#ifdef RT_USING_WDT3
DEV_WDT3,
#endif
DEV_MAX,
};
#ifdef RT_USING_WDT1
static wdog_config_t WDOG_1_config =
{
.timeoutValue = 0xffu,
.enablePowerDown = false,
.softwareResetExtension = false,
.softwareAssertion = true,
.softwareResetSignal = true,
.enableWdog = true,
.workMode =
{
.enableWait = false,
.enableStop = false,
.enableDebug = false,
},
.enableInterrupt = false,
.interruptTimeValue = 0x04u,
};
#endif
#ifdef RT_USING_WDT2
static wdog_config_t WDOG_2_config =
{
.timeoutValue = 0xffu,
.enablePowerDown = false,
.softwareResetExtension = false,
.softwareAssertion = true,
.softwareResetSignal = true,
.enableWdog = true,
.workMode =
{
.enableWait = false,
.enableStop = false,
.enableDebug = false,
},
.enableInterrupt = false,
.interruptTimeValue = 0x04u,
};
#endif
#ifdef RT_USING_WDT3
static wdog_config_t WDOG_3_config =
{
.timeoutValue = 0xffu,
.enablePowerDown = false,
.softwareResetExtension = false,
.softwareAssertion = true,
.softwareResetSignal = true,
.enableWdog = true,
.workMode =
{
.enableWait = false,
.enableStop = false,
.enableDebug = false,
},
.enableInterrupt = false,
.interruptTimeValue = 0x04u,
};
#endif
static rt_watchdog_t imx6ull_watchdog[DEV_MAX] =
{
#ifdef RT_USING_WDT1
{
.name = "wdt1",
.paddr = IMX6ULL_WATCHDOG1_BASE,
.config = &WDOG_1_config,
},
#endif
#ifdef RT_USING_WDT2
{
.name = "wdt2",
.paddr = IMX6ULL_WATCHDOG2_BASE,
.config = &WDOG_2_config,
},
#endif
#ifdef RT_USING_WDT3
{
.name = "wdt3",
.paddr = IMX6ULL_WATCHDOG3_BASE,
.config = &WDOG_3_config,
},
#endif
};
static rt_err_t imx6ull_wdog_init(rt_watchdog_t *wdt)
{
WDOG_Type *base = RT_NULL;
base = (WDOG_Type *)wdt->vaddr;
WDOG_Init(base, wdt->config);
WDOG_Disable(base);
return RT_EOK;
}
static rt_err_t imx6ull_wdog_control(rt_watchdog_t *wdt, int cmd, void *args)
{
RT_ASSERT(wdt != NULL);
WDOG_Type *base = RT_NULL;
base = (WDOG_Type *)wdt->vaddr;
switch(cmd)
{
case RT_DEVICE_CTRL_WDT_GET_TIMEOUT:
{
*(uint16_t *)args = (base->WCR >> 8) / 2;
}
break;
case RT_DEVICE_CTRL_WDT_SET_TIMEOUT:
{
RT_ASSERT(*(uint16_t *)args != 0);
WDOG_SetTimeoutValue(base, (*(uint16_t *)args) * 2);
WDOG_Disable(base);
}
break;
case RT_DEVICE_CTRL_WDT_KEEPALIVE:
{
WDOG_Refresh(base);
}
break;
case RT_DEVICE_CTRL_WDT_START:
{
WDOG_Enable(base);
}
break;
case RT_DEVICE_CTRL_WDT_STOP:
{
WDOG_Disable(base);
}
break;
default:
return RT_EINVAL;
}
return RT_EOK;
}
static struct rt_watchdog_ops imx6ull_wdog_ops =
{
.init = imx6ull_wdog_init,
.control = imx6ull_wdog_control,
};
int rt_hw_wdt_init(void)
{
rt_err_t ret = RT_EOK;
for(int idx = 0; idx < GET_ARRAY_NUM(imx6ull_watchdog); idx++)
{
imx6ull_watchdog[idx].ops = &imx6ull_wdog_ops;
imx6ull_watchdog[idx].vaddr = platform_get_periph_vaddr(imx6ull_watchdog[idx].paddr);
ret = rt_hw_watchdog_register(&imx6ull_watchdog[idx], imx6ull_watchdog[idx].name,
RT_DEVICE_FLAG_DEACTIVATE, RT_NULL);
if (ret != RT_EOK)
{
LOG_E("rt device register failed %d\n", ret);
}
}
return ret;
}
INIT_DEVICE_EXPORT(rt_hw_wdt_init);
#endif

View File

@@ -0,0 +1,48 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-07-28 songchao first version
*/
#ifndef __WATCHDOG_H__
#define __WATCHDOG_H__
#include <rtthread.h>
#include "fsl_wdog.h"
#define RT_DEVICE_CTRL_WDT_GET_TIMEOUT (1) /* get timeout(in seconds) */
#define RT_DEVICE_CTRL_WDT_SET_TIMEOUT (2) /* set timeout(in seconds) */
#define RT_DEVICE_CTRL_WDT_GET_TIMELEFT (3) /* get the left time before reboot(in seconds) */
#define RT_DEVICE_CTRL_WDT_KEEPALIVE (4) /* refresh watchdog */
#define RT_DEVICE_CTRL_WDT_START (5) /* start watchdog */
#define RT_DEVICE_CTRL_WDT_STOP (6) /* stop watchdog */
struct rt_watchdog_ops;
struct rt_watchdog_device
{
struct rt_device parent;
const struct rt_watchdog_ops *ops;
const char *name;
rt_uint32_t paddr;
rt_uint32_t vaddr;
rt_uint32_t irqno;
wdog_config_t *config;
};
typedef struct rt_watchdog_device rt_watchdog_t;
struct rt_watchdog_ops
{
rt_err_t (*init)(rt_watchdog_t *wdt);
rt_err_t (*control)(rt_watchdog_t *wdt, int cmd, void *arg);
};
rt_err_t rt_hw_watchdog_register(rt_watchdog_t *wdt,
const char *name,
rt_uint32_t flag,
void *data);
#endif /* __WATCHDOG_H__ */

View File

@@ -0,0 +1,386 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-03-22 quanzhao first version
*/
#ifndef __IMX6UL_H__
#define __IMX6UL_H__
#include <rthw.h>
#include <rtthread.h>
#ifdef RT_USING_LWP
#include <lwp.h>
#include <ioremap.h>
#endif
enum _gic_base_offsets
{
kGICDBaseOffset = 0x1000, //!< GIC distributor offset.
kGICCBaseOffset = 0x2000 //!< GIC CPU interface offset.
};
/* SOC-relative definitions */
enum _imx_interrupts
{
SW_INTERRUPT_0 = 0, //!< Software interrupt 0.
SW_INTERRUPT_1 = 1, //!< Software interrupt 1.
SW_INTERRUPT_2 = 2, //!< Software interrupt 2.
SW_INTERRUPT_3 = 3, //!< Software interrupt 3.
SW_INTERRUPT_4 = 4, //!< Software interrupt 4.
SW_INTERRUPT_5 = 5, //!< Software interrupt 5.
SW_INTERRUPT_6 = 6, //!< Software interrupt 6.
SW_INTERRUPT_7 = 7, //!< Software interrupt 7.
SW_INTERRUPT_8 = 8, //!< Software interrupt 8.
SW_INTERRUPT_9 = 9, //!< Software interrupt 9.
SW_INTERRUPT_10 = 10, //!< Software interrupt 10.
SW_INTERRUPT_11 = 11, //!< Software interrupt 11.
SW_INTERRUPT_12 = 12, //!< Software interrupt 12.
SW_INTERRUPT_13 = 13, //!< Software interrupt 13.
SW_INTERRUPT_14 = 14, //!< Software interrupt 14.
SW_INTERRUPT_15 = 15, //!< Software interrupt 15.
RSVD_INTERRUPT_16 = 16, //!< Reserved.
RSVD_INTERRUPT_17 = 17, //!< Reserved.
RSVD_INTERRUPT_18 = 18, //!< Reserved.
RSVD_INTERRUPT_19 = 19, //!< Reserved.
RSVD_INTERRUPT_20 = 20, //!< Reserved.
RSVD_INTERRUPT_21 = 21, //!< Reserved.
RSVD_INTERRUPT_22 = 22, //!< Reserved.
RSVD_INTERRUPT_23 = 23, //!< Reserved.
RSVD_INTERRUPT_24 = 24, //!< Reserved.
RSVD_INTERRUPT_25 = 25, //!< Reserved.
RSVD_INTERRUPT_26 = 26, //!< Reserved.
RSVD_INTERRUPT_27 = 27, //!< Reserved.
RSVD_INTERRUPT_28 = 28, //!< Reserved.
RSVD_INTERRUPT_29 = 29, //!< Reserved.
RSVD_INTERRUPT_30 = 30, //!< Reserved.
RSVD_INTERRUPT_31 = 31, //!< Reserved.
IMX_INT_IOMUXC_GPR = 32, //!< General Purpose Register 1 from IOMUXC. Used to notify cores on exception condition while boot.
IMX_INT_CHEETAH_CSYSPWRUPREQ = 33, //!< @todo Listed as DAP in RM
IMX_INT_SDMA = 34, //!< Logical OR of all 48 SDMA interrupt requests/events from all channels.
IMX_INT_TSC = 35, //!< TSC
IMX_INT_SNVS_LP_SET_PWR_OFF = 36, //!< PMIC power off request.
IMX_INT_LCDIF = 37, //!< LCDIF interrupt request.
IMX_INT_BEE = 38, //!< BEE interrupt request.
IMX_INT_CSI = 39, //!< CMOS Sensor Interface interrupt request.
IMX_INT_PXP = 40, //!< PXP interrupt request.
IMX_INT_SCTR1 = 41, //!< SCTR1
IMX_INT_SCTR2 = 42, //!< SCTR2
IMX_INT_WDOG3 = 43, //!< WDOG3 timer reset interrupt request.
IMX_INT_INTERRUPT_44 = 44, //!< Reserved.
IMX_INT_APBH_DMA = 45, //!< APBH DMA
IMX_INT_EIM = 46, //!< EIM interrupt request.
IMX_INT_NAND_BCH = 47, //!< Reserved.
IMX_INT_NAND_GPMI = 48, //!< Reserved.
IMX_INT_UART6 = 49, //!< Logical OR of UART5 interrupt requests.
IMX_INT_INTERRUPT_50 = 50, //!< Reserved.
IMX_INT_SNVS = 51, //!< SNVS consolidated interrupt.
IMX_INT_SNVS_SEC = 52, //!< SNVS security interrupt.
IMX_INT_CSU = 53, //!< CSU interrupt request 1. Indicates to the processor that one or more alarm inputs were asserted.
IMX_INT_USDHC1 = 54, //!< uSDHC1 (Enhanced SDHC) interrupt request.
IMX_INT_USDHC2 = 55, //!< uSDHC2 (Enhanced SDHC) interrupt request.
IMX_INT_SAI3 = 56, //!< uSDHC3 (Enhanced SDHC) interrupt request.
IMX_INT_SAI4 = 57, //!< uSDHC4 (Enhanced SDHC) interrupt request.
IMX_INT_UART1 = 58, //!< Logical OR of UART1 interrupt requests.
IMX_INT_UART2 = 59, //!< Logical OR of UART2 interrupt requests.
IMX_INT_UART3 = 60, //!< Logical OR of UART3 interrupt requests.
IMX_INT_UART4 = 61, //!< Logical OR of UART4 interrupt requests.
IMX_INT_UART5 = 62, //!< Logical OR of UART5 interrupt requests.
IMX_INT_ECSPI1 = 63, //!< eCSPI1 interrupt request.
IMX_INT_ECSPI2 = 64, //!< eCSPI2 interrupt request.
IMX_INT_ECSPI3 = 65, //!< eCSPI3 interrupt request.
IMX_INT_ECSPI4 = 66, //!< eCSPI4 interrupt request.
IMX_INT_I2C4 = 67, //!< Reserved.
IMX_INT_I2C1 = 68, //!< I2C1 interrupt request.
IMX_INT_I2C2 = 69, //!< I2C2 interrupt request.
IMX_INT_I2C3 = 70, //!< I2C3 interrupt request.
IMX_INT_UART7 = 71, //!< Logical OR of UART5 interrupt requests.
IMX_INT_UART8 = 72, //!< Logical OR of UART5 interrupt requests.
IMX_INT_INTERRUPT_73 = 73, //!< Reserved.
IMX_INT_USB_OTG2 = 74, //!< USB Host 1 interrupt request.
IMX_INT_USB_OTG1 = 75, //!< USB OTG1 interrupt request.
IMX_INT_USB_UTMI0 = 76, //!< UTMI0 interrupt request.
IMX_INT_USB_UTMI1 = 77, //!< UTMI1 interrupt request.
IMX_INT_CAAM_JQ2 = 78, //!< SSI1 interrupt request.
IMX_INT_CAAM_ERR = 79, //!< SSI2 interrupt request.
IMX_INT_CAAM_RTIC = 80, //!< SSI3 interrupt request.
IMX_INT_TEMPERATURE = 81, //!< Temperature Sensor (temp. greater than threshold) interrupt request.
IMX_INT_ASRC = 82, //!< Reserved.
IMX_INT_INTERRUPT_83 = 83, //!< Reserved.
IMX_INT_SPDIF = 84, //!< Logical OR of SPDIF TX and SPDIF RX interrupts.
IMX_INT_INTERRUPT_85 = 85, //!< Reserved.
IMX_INT_PMU_ANA_BO = 86, //!< PMU analog regulator brown-out interrupt request.
IMX_INT_GPT1 = 87, //
IMX_INT_EPIT1 = 88, //!< EPIT1 output compare interrupt.
IMX_INT_EPIT2 = 89, //!< EPIT2 output compare interrupt.
IMX_INT_GPIO1_INT7 = 90, //!< INT7 interrupt request.
IMX_INT_GPIO1_INT6 = 91, //!< INT6 interrupt request.
IMX_INT_GPIO1_INT5 = 92, //!< INT5 interrupt request.
IMX_INT_GPIO1_INT4 = 93, //!< INT4 interrupt request.
IMX_INT_GPIO1_INT3 = 94, //!< INT3 interrupt request.
IMX_INT_GPIO1_INT2 = 95, //!< INT2 interrupt request.
IMX_INT_GPIO1_INT1 = 96, //!< INT1 interrupt request.
IMX_INT_GPIO1_INT0 = 97, //!< INT0 interrupt request.
IMX_INT_GPIO1_INT15_0 = 98, //!< Combined interrupt indication for GPIO1 signals 0 - 15.
IMX_INT_GPIO1_INT31_16 = 99, //!< Combined interrupt indication for GPIO1 signals 16 - 31.
IMX_INT_GPIO2_INT15_0 = 100, //!< Combined interrupt indication for GPIO2 signals 0 - 15.
IMX_INT_GPIO2_INT31_16 = 101, //!< Combined interrupt indication for GPIO2 signals 16 - 31.
IMX_INT_GPIO3_INT15_0 = 102, //!< Combined interrupt indication for GPIO3 signals 0 - 15.
IMX_INT_GPIO3_INT31_16 = 103, //!< Combined interrupt indication for GPIO3 signals 16 - 31.
IMX_INT_GPIO4_INT15_0 = 104, //!< Combined interrupt indication for GPIO4 signals 0 - 15.
IMX_INT_GPIO4_INT31_16 = 105, //!< Combined interrupt indication for GPIO4 signals 16 - 31.
IMX_INT_GPIO5_INT15_0 = 106, //!< Combined interrupt indication for GPIO5 signals 0 - 15.
IMX_INT_GPIO5_INT31_16 = 107, //!< Combined interrupt indication for GPIO5 signals 16 - 31.
IMX_INT_INTERRUPT_108 = 108, //!< Reserved.
IMX_INT_INTERRUPT_109 = 109, //!< Reserved.
IMX_INT_INTERRUPT_110 = 110, //!< Reserved.
IMX_INT_INTERRUPT_111 = 111, //!< Reserved.
IMX_INT_WDOG1 = 112, //!< WDOG1 timer reset interrupt request.
IMX_INT_WDOG2 = 113, //!< WDOG2 timer reset interrupt request.
IMX_INT_KPP = 114, //!< Key Pad interrupt request.
IMX_INT_PWM1 = 115, //!< Cumulative interrupt line for PWM1. Logical OR of rollover, compare, and FIFO waterlevel crossing interrupts.
IMX_INT_PWM2 = 116, //!< Cumulative interrupt line for PWM2. Logical OR of rollover, compare, and FIFO waterlevel crossing interrupts.
IMX_INT_PWM3 = 117, //!< Cumulative interrupt line for PWM3. Logical OR of rollover, compare, and FIFO waterlevel crossing interrupts.
IMX_INT_PWM4 = 118, //!< Cumulative interrupt line for PWM4. Logical OR of rollover, compare, and FIFO waterlevel crossing interrupts.
IMX_INT_CCM_INT1 = 119, //!< CCM interrupt request 1.
IMX_INT_CCM_INT2 = 120, //!< CCM interrupt request 2.
IMX_INT_GPC_INT1 = 121, //!< GPC interrupt request 1.
IMX_INT_INTERRUPT_122 = 122, //!< Reserved.
IMX_INT_SRC = 123, //!< SRC interrupt request.
IMX_INT_INTERRUPT_124 = 124, //!< Logical OR of all L2 interrupt requests.
IMX_INT_INTERRUPT_125 = 125, //!< Parity Check error interrupt request.
IMX_INT_CHEETAH_PERFORM = 126, //!< Logical OR of Performance Unit interrupts.
IMX_INT_CHEETAH_TRIGGER = 127, //!< Logical OR of CTI trigger outputs.
IMX_INT_SRC_CPU_WDOG = 128, //!< Combined CPU wdog interrupts (4x) out of SRC.
IMX_INT_SAI1 = 129, //!< EPDC interrupt request.
IMX_INT_SAI2 = 130, //!< EPDC interrupt request.
IMX_INT_INTERRUPT_131 = 131, //!< DCP general interrupt request.
IMX_INT_ADC1 = 132, //!< DCP channel 0 interrupt request.
IMX_INT_ADC2 = 133, //!< DCP secure interrupt request.
IMX_INT_INTERRUPT_134 = 134, //!< Reserved.
IMX_INT_INTERRUPT_135 = 135, //!< Reserved.
IMX_INT_SJC = 136, //!< SJC interrupt from General Purpose register.
IMX_INT_CAAM_0 = 137, //!< Reserved.
IMX_INT_CAAM_1 = 138, //!< Reserved.
IMX_INT_QSPI = 139, //!< Reserved.
IMX_INT_TZASC1 = 140, //!< ASC1 interrupt request.
IMX_INT_GPT2 = 141, //!< Reserved.
IMX_INT_CAN1 = 142, //!< Reserved.
IMX_INT_CAN2 = 143, //!< Reserved.
IMX_INT_SIM1 = 144, //!< Reserved.
IMX_INT_SIM2 = 145, //!< Reserved.
IMX_INT_PWM5 = 146, //!< Fast Ethernet Controller interrupt request.
IMX_INT_PWM6 = 147, //!< Reserved.
IMX_INT_PWM7 = 148, //!< Reserved.
IMX_INT_PWM8 = 149, //!< Reserved.
IMX_INT_ENET1 = 150, //!< Reserved.
IMX_INT_ENET1_TIMER = 151, //!< Reserved.
IMX_INT_ENET2 = 152, //!< Reserved.
IMX_INT_ENET2_TIMER = 153, //!< Reserved.
IMX_INT_INTERRUPT_154 = 154, //!< Reserved.
IMX_INT_INTERRUPT_155 = 155, //!< Reserved.
IMX_INT_INTERRUPT_156 = 156, //!< Reserved.
IMX_INT_INTERRUPT_157 = 157, //!< Reserved.
IMX_INT_INTERRUPT_158 = 158, //!< Reserved.
IMX_INT_PMU_DIG_BO = 159, //!< //!< PMU digital regulator brown-out interrupt request.
IMX_INTERRUPT_COUNT = 160 //!< Total number of interrupts.
};
/* SOC-relative definitions */
#include "MCIMX6Y2.h"
#include "fsl_cache.h"
#include "fsl_common.h"
#include "fsl_iomuxc.h"
#include "fsl_gpio.h"
#include "fsl_elcdif.h"
#include "fsl_usdhc.h"
#include "fsl_card.h"
#include "fsl_wdog.h"
#include "fsl_i2c.h"
#include "fsl_ecspi.h"
#include "fsl_snvs_hp.h"
#include "fsl_adc.h"
#define IMX6ULL_PERIPH_SIZE (16 * 1024)
/* Interrupt Control Interface */
#define ARM_GIC_CPU_BASE 0x00A00000
/*
* Peripheral addresses
*/
#define IMX6ULL_UART1_BASE UART1_BASE /* UART 1 */
#define IMX6ULL_UART2_BASE UART2_BASE /* UART 2 */
#define IMX6ULL_UART3_BASE UART3_BASE /* UART 3 */
#define IMX6ULL_UART4_BASE UART4_BASE /* UART 4 */
#define IMX6ULL_UART5_BASE UART5_BASE /* UART 5 */
#define IMX6ULL_UART6_BASE UART6_BASE /* UART 6 */
#define IMX6ULL_UART7_BASE UART7_BASE /* UART 7 */
#define IMX6ULL_UART8_BASE UART8_BASE /* UART 8 */
#define IMX6ULL_WATCHDOG1_BASE WDOG1_BASE /* watchdog 1 */
#define IMX6ULL_WATCHDOG2_BASE WDOG2_BASE /* watchdog 2 */
#define IMX6ULL_WATCHDOG3_BASE WDOG3_BASE /* watchdog 3 */
#define IMX6ULL_GPIO1_BASE GPIO1_BASE /* GPIO port 0 */
#define IMX6ULL_GPIO2_BASE GPIO2_BASE /* GPIO port 1 */
#define IMX6ULL_GPIO3_BASE GPIO3_BASE /* GPIO port 2 */
#define IMX6ULL_GPIO4_BASE GPIO4_BASE /* GPIO port 3 */
#define IMX6ULL_GPIO5_BASE GPIO5_BASE /* GPIO port 4 */
#define IMX6ULL_SNVS_BASE SNVS_BASE /* Real Time Clock */
#define IMX6ULL_SCTL_BASE 0x021DC000u /* System Controller */
#define IMX6ULL_CLCD_BASE LCDIF_BASE /* CLCD */
#define IMX6ULL_GIC_DIST_BASE (ARM_GIC_CPU_BASE+kGICDBaseOffset) /* Generic interrupt controller distributor */
#define IMX6ULL_GIC_CPU_BASE (ARM_GIC_CPU_BASE+kGICCBaseOffset) /* Generic interrupt controller CPU interface */
#define IMX6ULL_IOMUXC_BASE IOMUXC_BASE
#define IMX6ULL_IOMUXC_SNVS_BASE IOMUXC_SNVS_BASE
#define IMX6ULL_IOMUXC_GPR_BASE IOMUXC_GPR_BASE
#define IMX6ULL_CCM_BASE 0x20C4000u
#define IMX6ULL_CCM_ANALOGY_BASE 0x20C8000u
#define IMX6ULL_PMU_BASE 0x20C8110u
#define IMX6ULL_ENET1_BASE ENET1_BASE
#define IMX6ULL_ENET2_BASE ENET2_BASE
#define IMX6ULL_GPT1_BASE GPT1_BASE
#define IMX6ULL_GPT2_BASE GPT2_BASE
#define IMX6ULL_ECSPI1_BASE ECSPI1_BASE
#define IMX6ULL_ECSPI2_BASE ECSPI2_BASE
#define IMX6ULL_ECSPI3_BASE ECSPI3_BASE
#define IMX6ULL_ECSPI4_BASE ECSPI4_BASE
#define IMX6ULL_I2C1_BASE I2C1_BASE
#define IMX6ULL_I2C2_BASE I2C2_BASE
#define IMX6ULL_I2C3_BASE I2C3_BASE
#define IMX6ULL_I2C4_BASE I2C4_BASE
#define IMX6ULL_SDMA_BASE SDMAARM_BASE
#define IMX6ULL_USDHC1_BASE USDHC1_BASE
#define IMX6ULL_USDHC2_BASE USDHC2_BASE
#define IMX6ULL_SRC_BASE SRC_BASE
#define IMX6ULL_GPMI_BASE GPMI_BASE
#define IMX6ULL_BCH_BASE BCH_BASE
#define IMX6ULL_APBH_BASE APBH_BASE
#define IMX6ULL_CSI_BASE CSI_BASE
#define IMX6ULL_CAN1_BASE CAN1_BASE
#define IMX6ULL_CAN2_BASE CAN2_BASE
#define IMX6ULL_USBPHY1_BASE 0x20C9000u
#define IMX6ULL_USBPHY2_BASE 0x20CA000u
#define IMX6ULL_USB1_BASE 0x2184000u
#define IMX6ULL_USB2_BASE 0x2184200u
#define IMX6ULL_USB_ANALOG_BASE 0x20C81A0u
/* the maximum number of gic */
#define ARM_GIC_MAX_NR 1
#define _internal_ro static const
#define _internal_rw static
#define _internal_zi static
#define GET_ARRAY_NUM(ins) ((uint32_t)(sizeof(ins)/sizeof(ins[0])))
#include "bsp_clock.h"
/* the maximum number of interrupts */
#define ARM_GIC_NR_IRQS IMX_INTERRUPT_COUNT
/* the maximum entries of the interrupt table */
#define MAX_HANDLERS IMX_INTERRUPT_COUNT
/* the basic constants needed by gic */
rt_inline rt_uint32_t platform_get_gic_dist_base(void)
{
rt_uint32_t gic_base;
asm volatile ("mrc p15, 4, %0, c15, c0, 0" : "=r"(gic_base));
return gic_base + kGICDBaseOffset;
}
rt_inline rt_uint32_t platform_get_gic_cpu_base(void)
{
rt_uint32_t gic_base;
asm volatile ("mrc p15, 4, %0, c15, c0, 0" : "=r"(gic_base));
return gic_base + kGICCBaseOffset;
}
rt_inline rt_uint32_t platform_get_periph_vaddr(rt_uint32_t paddr)
{
#ifdef RT_USING_SMART
rt_uint32_t mask = IMX6ULL_PERIPH_SIZE - 1;
return (rt_uint32_t)rt_ioremap((void*)(paddr&(~mask)), IMX6ULL_PERIPH_SIZE) + (paddr & mask);
#else
return paddr;
#endif
}
#define GIC_IRQ_START 0
#define GIC_ACK_INTID_MASK 0x000003ff
/* the definition needed by gic.c */
#define __REG32(x) (*((volatile unsigned int *)(x)))
/* keep compatible with platform SDK */
typedef enum {
CPU_0,
CPU_1,
CPU_2,
CPU_3,
} cpuid_e;
enum _gicd_sgi_filter
{
//! Forward the interrupt to the CPU interfaces specified in the @a target_list parameter.
kGicSgiFilter_UseTargetList = 0,
//! Forward the interrupt to all CPU interfaces except that of the processor that requested
//! the interrupt.
kGicSgiFilter_AllOtherCPUs = 1,
//! Forward the interrupt only to the CPU interface of the processor that requested the
//! interrupt.
kGicSgiFilter_OnlyThisCPU = 2
};
typedef void (*irq_hdlr_t) (void);
extern void rt_hw_interrupt_mask(int vector);
extern void rt_hw_interrupt_umask(int vector);
extern rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler,
void *param, const char *name);
rt_inline void register_interrupt_routine(uint32_t irq_id, irq_hdlr_t isr)
{
rt_hw_interrupt_install(irq_id, (rt_isr_handler_t)isr, RT_NULL, "unknown");
}
rt_inline void enable_interrupt(uint32_t irq_id, uint32_t cpu_id, uint32_t priority)
{
rt_hw_interrupt_umask(irq_id);
}
rt_inline void disable_interrupt(uint32_t irq_id, uint32_t cpu_id)
{
rt_hw_interrupt_mask(irq_id);
}
#endif /* __IMX6UL_H__ */

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