未验证 提交 adf17c42 编写于 作者: S Shell 提交者: GitHub

[bsp] rpi 4b smart & rtos fixups (#7114)

* [bsp] rpi 4b smart & rtos fixups

* [format] remove spaces & modify readme

* [bsp] update rpi4b readme
上级 f2dd21cc
此差异已折叠。
......@@ -21,10 +21,11 @@ source "$PKGS_DIR/Kconfig"
config BCM2711_SOC
bool
select ARCH_ARMV8
select ARCH_ARM_MMU
select RT_USING_CACHE
select RT_USING_COMPONENTS_INIT
select RT_USING_USER_MAIN
select ARCH_CPU_64BIT
default y
source "driver/Kconfig"
source "drivers/Kconfig"
......@@ -11,89 +11,78 @@
## 2. 编译说明
推荐使用[env工具](https://www.rt-thread.org/page/download.html),可以在console下进入到`bsp\raspberry-pi\raspi4-64`目录中,运行以下命令:
```
scons
```
### 2.1 Window上的环境搭建
来编译这个板级支持包。如果编译正确无误,会产生 `rtthread.elf`, `rtthread.bin` 文件。
Windows环境下推荐使用[env工具](https://www.rt-thread.org/page/download.html)进行编译。
## 3. 环境搭建
### 3.1 准备好串口线
首先下载windows上的aarch64的gcc交叉编译工具,版本为gcc-arm-8.3选择aarch64-elf就可以。
目前版本是使用raspi4的 GPIO 14, GPIO 15来作路口输出,连线情况如下图所示:
将推荐将gcc解压到`\env\tools\gnu_gcc\arm_gcc`目录下。
![raspi2](../raspi3-32/figures/raspberrypi-console.png)
接着修改`bsp\raspberry-pi\raspi4-64\rtconfig.py`
串口参数: 115200 8N1 ,硬件和软件流控为关。
修改路径:
### 3.2 RTT固件放在SD卡运行
```
EXEC_PATH = r'E:/env_released_1.1.2/env/tools/gnu_gcc/arm_gcc/gcc-arm-8.3-2019.03-i686-mingw32-aarch64-elf/bin'
```
暂时不支持,需要使用 u-boot 加载。
然后在`bsp\raspberry-pi\raspi4-64\`下输入scons编译即可。
### 3.3 RTT程序用uboot加载
**window环境搭建注意**
此 bsp 的 `tools` 下可以找到 [u-boot64.bin](./tools/u-boot64.bin)[config.txt](./tools/config.txt) 两个文件。将其与准备好的 sd 卡中文件替换即可。sd 卡推荐通过树莓派 [imager](https://www.raspberrypi.com/software/) 制作。
下载完成`gcc-arm-8.3-2019.03-i686-mingw32-aarch64-elf.tar.xz`交叉编译工具链后,最好采用7-zip解压工具进行两次解压。
确保解压目录下的`/bin/aarch64-elf-ld.exe`文件的size不为0。
否则编译会出现如下错误:
需要注意的以下步骤:
```
collect2.exe:fatal error:CreateProcess:No such file or directory
```
**1.电脑上启动tftp服务器**
### 2.2 Linux上的环境搭建
windows系统电脑上可以安装tftpd搭建tftp服务器。将目录指定到`bsp\raspberry-pi\raspi4-64`
Linux下推荐使用[gcc工具][2]。Linux版本下gcc版本可采用`gcc-arm-8.3-2019.03-x86_64-aarch64-elf`。
**2.修改设置uboot**
将工具链解压到指定目录,并修改当前bsp下的`EXEC_PATH`为自定义gcc目录。
在控制台输入下列命令:
```
PLATFORM = 'gcc'
EXEC_PATH = r'/opt/gcc-arm-8.3-2019.03-x86_64-aarch64-elf/bin/'
setenv bootcmd "dhcp 0x00208000 x.x.x.x:rtthread.bin;dcache flush;go 0x00208000"
saveenv
reset
```
直接进入`bsp\raspberry-pi\raspi4-64`,输入scons编译即可。
## 3. 执行
### 3.1 下载**Raspberry Pi Imager**,生成可以运行的raspbian SD卡
其中`x.x.x.x`为tftp服务器的pc的ip地址。
首先下载镜像
**3.修改链接脚本**
* [Raspberry Pi Imager for Ubuntu](https://downloads.raspberrypi.org/imager/imager_amd64.deb)
* [Raspberry Pi Imager for Windows](https://downloads.raspberrypi.org/imager/imager.exe)
* [Raspberry Pi Imager for macOS](https://downloads.raspberrypi.org/imager/imager.dmg)
链接脚本会在 python 脚本中自行替换,不用处理
### 3.2 准备好串口线
**3.插入网线**
目前版本是使用raspi4的 GPIO 14, GPIO 15来作路口输出,连线情况如下图所示:
![raspi2](../raspi3-32/figures/raspberrypi-console.png)
串口参数: 115200 8N1 ,硬件和软件流控为关。
### 3.3 程序下载
上述准备完成后,将网线插入,保证开发板和tftp服务器在同一个网段的路由器上。上电后uboot可以自动从tftp服务器上获取固件,然后开始执行了。
当编译生成了rtthread.bin文件后,我们可以将该文件放到sd卡上,并修改sd卡中的`config.txt`文件如下:
完成后可以看到串口的输出信息
```
enable_uart=1
arm_64bit=1
kernel=rtthread.bin
core_freq=250
```
按上面的方法做好SD卡后,插入树莓派4,通电可以在串口上看到如下所示的输出信息:
```text
heap: 0x000c9350 - 0x040c9350
\ | /
- RT - Thread Operating System
/ | \ 4.0.3 build Apr 16 2020
2006 - 2020 Copyright by rt-thread team
Hi, this is RT-Thread!!
/ | \ 5.0.0 build Mar 29 2023 10:56:23
2006 - 2022 Copyright by RT-Thread team
lwIP-2.1.2 initialized!
EMMC: assuming clock rate to be 100MHz
[I/sal.skt] Socket Abstraction Layer initialize success.
[I/utest] utest is initialize success.
[I/utest] total utest testcase num: (0)
[I/DBG] version is B1
[I/SDIO] SD card capacity 31166976 KB.
found part[0], begin: 4194304, size: 256.0MB
found part[1], begin: 272629760, size: 3.856GB
file system initialization done!
cpu 2 boot success
cpu 1 boot success
cpu 3 boot success
msh />
```
......@@ -103,11 +92,18 @@ msh />
| ------ | ---- | :------: |
| UART | 支持 | UART0,UART2,UART3,UART4,UART5 |
| GPIO | 支持 | - |
| SPI | 支持 | SPI0 |
| MAILBOX | 支持 | - |
| WATCHDOG | 支持 | - |
| HDMI | 支持 | - |
| SDIO | 支持 | - |
| ETH | 支持 | - |
## 5. 联系人信息
## 5. 注意事项
目前rt-thread程序可以使用的内存在100MB以内,可以通过调整`board.c``platform_mem_desc`表的数据进行相关内存的映射以及修改`board.h`来确定程序使用的堆栈大小。
## 6. 联系人信息
维护人:[bernard][5]
......
......@@ -11,20 +11,24 @@ TARGET = 'rtthread.' + rtconfig.TARGET_EXT
DefaultEnvironment(tools=[])
env = Environment(tools = ['mingw'],
AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS,
CC = rtconfig.CC, CFLAGS = rtconfig.CFLAGS,
CXX = rtconfig.CXX, CXXFLAGS = rtconfig.CXXFLAGS,
AR = rtconfig.AR, ARFLAGS = '-rc',
AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS,
CC = rtconfig.CC, CFLAGS = rtconfig.CFLAGS,
CXX = rtconfig.CXX, CXXFLAGS = rtconfig.CXXFLAGS,
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, has_libcpu = False)
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)
from building import *
import os
cwd = GetCurrentDir()
src = Glob('*.c')
CPPPATH = [cwd]
cwd = GetCurrentDir()
src = Glob('*.c') + Glob('*.cpp')
CPPPATH = [cwd, str(Dir('#'))]
group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH)
......
from building import *
cwd = GetCurrentDir()
src = Glob('*.c') + Glob('*.cpp')
CPPPATH = [cwd, str(Dir('#'))]
group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH)
Return('group')
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-04-16 bigmagic first version
* 2021-12-28 GuEe-GUI add smp support
*/
#include <rthw.h>
#include <rtthread.h>
#include "board.h"
#include "drv_uart.h"
#include "mmu.h"
#include "gic.h"
#include "gtimer.h"
#include "cpuport.h"
#include "interrupt.h"
#include "mbox.h"
struct mem_desc platform_mem_desc[] =
{
{0, 0x6400000, 0, NORMAL_MEM},
{0xFE200000, 0xFE400000, 0xFE200000, DEVICE_MEM}, /* uart gpio */
{0xFF800000, 0xFFA00000, 0xFF800000, DEVICE_MEM}, /* gic timer */
{WDT_BASE, WDT_BASE + 0x1000, WDT_BASE, DEVICE_MEM}, /* wdt */
{MBOX_ADDR, MBOX_ADDR + 0x200000, MBOX_ADDR, DEVICE_MEM}, /* mbox msg */
{STIMER_BASE, STIMER_BASE + 0x200000, STIMER_BASE, DEVICE_MEM}, /* stimer */
{MAC_BASE_ADDR, MAC_BASE_ADDR + 0x80000, MAC_BASE_ADDR, DEVICE_MEM}, /* mac */
{MMC2_BASE_ADDR, MMC2_BASE_ADDR + 0x200000, MMC2_BASE_ADDR, DEVICE_MEM}, /* mmc */
{ARM_TIMER_BASE, ARM_TIMER_BASE + 0x200000, ARM_TIMER_BASE, DEVICE_MEM}, /* arm timer */
{SEND_DATA_NO_CACHE, SEND_DATA_NO_CACHE + 0x200000, SEND_DATA_NO_CACHE, NORMAL_MEM}, /* eth send */
{RECV_DATA_NO_CACHE, RECV_DATA_NO_CACHE + 0x200000, RECV_DATA_NO_CACHE, NORMAL_MEM}, /* eth recv */
};
const rt_uint32_t platform_mem_desc_size = sizeof(platform_mem_desc)/sizeof(platform_mem_desc[0]);
#if !defined(BSP_USING_CORETIMER) && !defined(RT_USING_SMP)
void rt_hw_timer_isr(int vector, void *parameter)
{
ARM_TIMER_IRQCLR = 0;
rt_tick_increase();
}
#endif
void rt_hw_timer_init(void)
{
#if defined(BSP_USING_CORETIMER) || defined(RT_USING_SMP)
rt_hw_gtimer_init();
core_timer_enable(0);
#else
rt_uint32_t apb_clock = 0;
rt_uint32_t timer_clock = 1000000;
apb_clock = bcm271x_mbox_clock_get_rate(CORE_CLK_ID);
ARM_TIMER_PREDIV = (apb_clock/timer_clock - 1);
ARM_TIMER_RELOAD = 0;
ARM_TIMER_LOAD = 0;
ARM_TIMER_IRQCLR = 1;
ARM_TIMER_CTRL = 0;
ARM_TIMER_RELOAD = 1000000 / RT_TICK_PER_SECOND;
ARM_TIMER_LOAD = 1000000 / RT_TICK_PER_SECOND;
/* 23-bit counter, enable interrupt, enable timer */
ARM_TIMER_CTRL = (1 << 1) | (1 << 5) | (1 << 7);
rt_hw_interrupt_install(ARM_TIMER_IRQ, rt_hw_timer_isr, RT_NULL, "tick");
rt_hw_interrupt_umask(ARM_TIMER_IRQ);
#endif
}
void idle_wfi(void)
{
asm volatile ("wfi");
}
/**
* Initialize the Hardware related stuffs. Called from rtthread_startup()
* after interrupt disabled.
*/
void rt_hw_board_init(void)
{
extern void *MMUTable;
rt_hw_mmu_map_init(&rt_kernel_space, (void*)0x80000000, 0x10000000, MMUTable, 0);
rt_hw_mmu_setup(&rt_kernel_space, platform_mem_desc, platform_mem_desc_size);
/* initialize hardware interrupt */
rt_hw_interrupt_init(); // in libcpu/interrupt.c. Set some data structures, no operation on device
/* initialize uart */
rt_hw_uart_init(); // driver/drv_uart.c
#if defined(RT_USING_CONSOLE) && defined(RT_USING_DEVICE)
/* set console device */
rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
#endif
#ifdef RT_USING_HEAP
/* initialize memory system */
rt_kprintf("heap: 0x%08x - 0x%08x\n", RT_HW_HEAP_BEGIN, RT_HW_HEAP_END);
rt_system_heap_init(RT_HW_HEAP_BEGIN, RT_HW_HEAP_END);
#endif
/* initialize timer for os tick */
rt_hw_timer_init();
rt_thread_idle_sethook(idle_wfi);
#ifdef RT_USING_COMPONENTS_INIT
rt_components_board_init();
#endif
#ifdef RT_USING_SMP
/* install IPI handle */
rt_hw_ipi_handler_install(IRQ_ARM_IPI_KICK, rt_scheduler_ipi_handler);
arm_gic_umask(0, IRQ_ARM_IPI_KICK);
#endif
}
#ifdef RT_USING_SMP
static unsigned long cpu_release_paddr[] =
{
[0] = 0xd8,
[1] = 0xe0,
[2] = 0xe8,
[3] = 0xf0,
[4] = 0
};
void rt_hw_secondary_cpu_up(void)
{
int i;
extern void secondary_cpu_start(void);
for (i = 1; i < RT_CPUS_NR && cpu_release_paddr[i]; ++i)
{
__asm__ volatile ("str %0, [%1]"::"rZ"((unsigned long)secondary_cpu_start), "r"(cpu_release_paddr[i]));
rt_hw_dcache_flush_range(cpu_release_paddr[i], sizeof(cpu_release_paddr[i]));
__DSB();
__SEV();
}
}
void secondary_cpu_c_start(void)
{
int id;
rt_hw_mmu_init();
id = rt_hw_cpu_id();
rt_hw_spin_lock(&_cpus_lock);
arm_gic_cpu_init(0, platform_get_gic_cpu_base());
rt_hw_vector_init();
rt_hw_gtimer_local_enable();
core_timer_enable(id);
arm_gic_umask(0, IRQ_ARM_IPI_KICK);
rt_kprintf("\rcall cpu %d on success\n", id);
rt_system_scheduler_start();
}
void rt_hw_secondary_cpu_idle_exec(void)
{
__WFE();
}
#endif
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-04-16 bigmagic first version
*/
#include "drv_gpio.h"
#ifdef BSP_USING_PIN
uint32_t raspi_get_pin_state(uint32_t fselnum)
{
uint32_t gpfsel = 0;
switch (fselnum)
{
case 0:
gpfsel = GPIO_REG_GPFSEL0(GPIO_BASE);
break;
case 1:
gpfsel = GPIO_REG_GPFSEL1(GPIO_BASE);
break;
case 2:
gpfsel = GPIO_REG_GPFSEL2(GPIO_BASE);
break;
case 3:
gpfsel = GPIO_REG_GPFSEL3(GPIO_BASE);
break;
case 4:
gpfsel = GPIO_REG_GPFSEL4(GPIO_BASE);
break;
case 5:
gpfsel = GPIO_REG_GPFSEL5(GPIO_BASE);
break;
default:
break;
}
return gpfsel;
}
void raspi_set_pin_state(uint32_t fselnum, uint32_t gpfsel)
{
switch (fselnum)
{
case 0:
GPIO_REG_GPFSEL0(GPIO_BASE) = gpfsel;
break;
case 1:
GPIO_REG_GPFSEL1(GPIO_BASE) = gpfsel;
break;
case 2:
GPIO_REG_GPFSEL2(GPIO_BASE) = gpfsel;
break;
case 3:
GPIO_REG_GPFSEL3(GPIO_BASE) = gpfsel;
break;
case 4:
GPIO_REG_GPFSEL4(GPIO_BASE) = gpfsel;
break;
case 5:
GPIO_REG_GPFSEL5(GPIO_BASE) = gpfsel;
break;
default:
break;
}
}
static void raspi_pin_mode(struct rt_device *dev, rt_base_t pin, rt_base_t mode)
{
uint32_t fselnum = pin / 10;
uint32_t fselrest = pin % 10;
uint32_t gpfsel = 0;
gpfsel &= ~((uint32_t)(0x07 << (fselrest * 3)));
gpfsel |= (uint32_t)(mode << (fselrest * 3));
switch (fselnum)
{
case 0:
GPIO_REG_GPFSEL0(GPIO_BASE) = gpfsel;
break;
case 1:
GPIO_REG_GPFSEL1(GPIO_BASE) = gpfsel;
break;
case 2:
GPIO_REG_GPFSEL2(GPIO_BASE) = gpfsel;
break;
case 3:
GPIO_REG_GPFSEL3(GPIO_BASE) = gpfsel;
break;
case 4:
GPIO_REG_GPFSEL4(GPIO_BASE) = gpfsel;
break;
case 5:
GPIO_REG_GPFSEL5(GPIO_BASE) = gpfsel;
break;
default:
break;
}
}
void prev_raspi_pin_mode(GPIO_PIN pin, GPIO_FUNC mode)
{
uint32_t fselnum = pin / 10;
uint32_t fselrest = pin % 10;
uint32_t gpfsel = 0;
gpfsel = raspi_get_pin_state(fselnum);
gpfsel &= ~((uint32_t)(0x07 << (fselrest * 3)));
gpfsel |= (uint32_t)(mode << (fselrest * 3));
raspi_set_pin_state(fselnum, gpfsel);
}
static void raspi_pin_write(struct rt_device *dev, rt_base_t pin, rt_base_t value)
{
uint32_t num = pin / 32;
if(num == 0)
{
if(value == 0)
{
GPIO_REG_GPSET0(GPIO_BASE) = 1 << (pin % 32);
}
else
{
GPIO_REG_GPCLR0(GPIO_BASE) = 1 << (pin % 32);
}
}
else
{
if(value == 0)
{
GPIO_REG_GPSET1(GPIO_BASE) = 1 << (pin % 32);
}
else
{
GPIO_REG_GPCLR1(GPIO_BASE) = 1 << (pin % 32);
}
}
}
static int raspi_pin_read(struct rt_device *device, rt_base_t pin)
{
return 0;
}
static rt_err_t raspi_pin_attach_irq(struct rt_device *device, rt_int32_t pin, rt_uint32_t mode, void (*hdr)(void *args), void *args)
{
return RT_EOK;
}
static rt_err_t raspi_pin_detach_irq(struct rt_device *device, rt_int32_t pin)
{
return RT_EOK;
}
rt_err_t raspi_pin_irq_enable(struct rt_device *device, rt_base_t pin, rt_uint32_t enabled)
{
return RT_EOK;
}
static const struct rt_pin_ops ops =
{
raspi_pin_mode,
raspi_pin_write,
raspi_pin_read,
raspi_pin_attach_irq,
raspi_pin_detach_irq,
raspi_pin_irq_enable,
RT_NULL,
};
#endif
int rt_hw_gpio_init(void)
{
#ifdef BSP_USING_PIN
rt_device_pin_register("gpio", &ops, RT_NULL);
#endif
return 0;
}
INIT_DEVICE_EXPORT(rt_hw_gpio_init);
#ifndef __RASPI4_H__
#define __RASPI4_H__
#include <rthw.h>
#define __REG32(x) (*((volatile unsigned int *)(x)))
//base address
#define PER_BASE (0xFE000000)
//gpio offset
#define GPIO_BASE_OFFSET (0x00200000)
//pl011 offset
#define PL011_UART_BASE_OFFSET (0x00201000)
//pactl cs offset
#define PACTL_CS_OFFSET (0x00204E00)
//aux offset
#define AUX_BASE_OFFSET (0x00215000)
//gpio
#define GPIO_BASE (PER_BASE + GPIO_BASE_OFFSET)
#define GPIO_IRQ_NUM (3) //40 pin mode
#define IRQ_GPIO0 (96 + 49) //bank0 (0 to 27)
#define IRQ_GPIO1 (96 + 50) //bank1 (28 to 45)
#define IRQ_GPIO2 (96 + 51) //bank2 (46 to 57)
#define IRQ_GPIO3 (96 + 52) //bank3
//system timer
#define ARM_TIMER_IRQ (64)
#define ARM_TIMER_BASE (PER_BASE + 0xB000)
#define ARM_TIMER_LOAD HWREG32(ARM_TIMER_BASE + 0x400)
#define ARM_TIMER_VALUE HWREG32(ARM_TIMER_BASE + 0x404)
#define ARM_TIMER_CTRL HWREG32(ARM_TIMER_BASE + 0x408)
#define ARM_TIMER_IRQCLR HWREG32(ARM_TIMER_BASE + 0x40C)
#define ARM_TIMER_RAWIRQ HWREG32(ARM_TIMER_BASE + 0x410)
#define ARM_TIMER_MASKIRQ HWREG32(ARM_TIMER_BASE + 0x414)
#define ARM_TIMER_RELOAD HWREG32(ARM_TIMER_BASE + 0x418)
#define ARM_TIMER_PREDIV HWREG32(ARM_TIMER_BASE + 0x41C)
#define ARM_TIMER_CNTR HWREG32(ARM_TIMER_BASE + 0x420)
//uart
#define UART_BASE (PER_BASE + PL011_UART_BASE_OFFSET)
#define UART0_BASE (UART_BASE + 0x0)
#define UART2_BASE (UART_BASE + 0x400)
#define UART3_BASE (UART_BASE + 0x600)
#define UART4_BASE (UART_BASE + 0x800)
#define UART5_BASE (UART_BASE + 0xA00)
#define IRQ_AUX_UART (96 + 29)
#define UART_REFERENCE_CLOCK (48000000)
//aux
#define AUX_BASE (PER_BASE + AUX_BASE_OFFSET)
#define IRQ_PL011 (96 + 57)
//pactl cs
#define PACTL_CS_ADDR (PER_BASE + PACTL_CS_OFFSET)
#define PACTL_CS HWREG32(PACTL_CS_ADDR)
typedef enum
{
IRQ_SPI0 = 0x00000000,
IRQ_SPI1 = 0x00000002,
IRQ_SPI2 = 0x00000004,
IRQ_SPI3 = 0x00000008,
IRQ_SPI4 = 0x00000010,
IRQ_SPI5 = 0x00000020,
IRQ_SPI6 = 0x00000040,
IRQ_I2C0 = 0x00000100,
IRQ_I2C1 = 0x00000200,
IRQ_I2C2 = 0x00000400,
IRQ_I2C3 = 0x00000800,
IRQ_I2C4 = 0x00001000,
IRQ_I2C5 = 0x00002000,
IRQ_I2C6 = 0x00004000,
IRQ_I2C7 = 0x00008000,
IRQ_UART5 = 0x00010000,
IRQ_UART4 = 0x00020000,
IRQ_UART3 = 0x00040000,
IRQ_UART2 = 0x00080000,
IRQ_UART0 = 0x00100000
} PACTL_CS_VAL;
// 0x40, 0x44, 0x48, 0x4c: Core 0~3 Timers interrupt control
#define CORE_TIMER_IRQ_CTRL(n) HWREG32((unsigned long)(0xFF800040 + (n) * 4))
#define TIMER_IRQ 30
#define NON_SECURE_TIMER_IRQ (1 << 1)
rt_inline void core_timer_enable(int cpu_id)
{
CORE_TIMER_IRQ_CTRL(cpu_id) |= NON_SECURE_TIMER_IRQ;
}
//core timer
#define ST_BASE_OFFSET (0x003000)
#define STIMER_BASE (PER_BASE + ST_BASE_OFFSET)
#define STIMER_CS HWREG32(STIMER_BASE + 0x0000)
#define STIMER_CLO HWREG32(STIMER_BASE + 0x0004)
#define STIMER_CHI HWREG32(STIMER_BASE + 0x0008)
#define STIMER_C0 HWREG32(STIMER_BASE + 0x000C)
#define STIMER_C1 HWREG32(STIMER_BASE + 0x0010)
#define STIMER_C2 HWREG32(STIMER_BASE + 0x0014)
#define STIMER_C3 HWREG32(STIMER_BASE + 0x0018)
#define DELAY_MICROS(micros) \
do { \
rt_uint32_t compare = STIMER_CLO + micros * 25; \
while (STIMER_CLO < compare); \
} while (0) \
//mmc
#define MMC0_BASE_ADDR (PER_BASE + 0x300000)
#define MMC2_BASE_ADDR (PER_BASE + 0x340000)
//eth
#define MAC_BASE_ADDR (0xfd580000)
#define MAC_REG_BASE_ADDR (void *)(MAC_BASE_ADDR)
#define ETH_IRQ (160 + 29)
#define SEND_DATA_NO_CACHE (0x08200000)
#define RECV_DATA_NO_CACHE (0x08400000)
//watchdog
#define WDT_BASE (PER_BASE + 0x00100000)
#define PM_RSTC HWREG32(WDT_BASE + 0x0000001c)
#define PM_RSTS HWREG32(WDT_BASE + 0x00000020)
#define PM_WDOG HWREG32(WDT_BASE + 0x00000024)
#define PM_PASSWORD (0x5A000000)
#define PM_WDOG_TIME_SET (0x000fffff)
#define PM_RSTS_HADWRH_SET (0x00000040)
#define PM_RSTC_WRCFG_FULL_RESET (0x00000020)
#define PM_RSTC_WRCFG_CLR (0xffffffcf)
#define PM_RSTC_RESET (0x00000102)
//gic max
#define MAX_HANDLERS (256)
#define ARM_GIC_NR_IRQS (512)
#define INTC_BASE (0xff800000)
#define ARM_GIC_MAX_NR (512)
#define GIC_V2_BASE (INTC_BASE + 0x00040000)
#define GIC_V2_DISTRIBUTOR_BASE (INTC_BASE + 0x00041000)
#define GIC_V2_CPU_INTERFACE_BASE (INTC_BASE + 0x00042000)
#define GIC_V2_HYPERVISOR_BASE (INTC_BASE + 0x00044000)
#define GIC_V2_VIRTUAL_CPU_BASE (INTC_BASE + 0x00046000)
/* ipi interrupt number */
#define IRQ_ARM_IPI_KICK 0
#define IRQ_ARM_IPI_CALL 1
#define GIC_IRQ_START 0
#define GIC_ACK_INTID_MASK 0x000003ff
#define GIC_PL400_DISTRIBUTOR_PPTR GIC_V2_DISTRIBUTOR_BASE
#define GIC_PL400_CONTROLLER_PPTR GIC_V2_CPU_INTERFACE_BASE
/* the basic constants and interfaces needed by gic */
rt_inline rt_uint32_t platform_get_gic_dist_base(void)
{
return GIC_PL400_DISTRIBUTOR_PPTR;
}
rt_inline rt_uint32_t platform_get_gic_cpu_base(void)
{
return GIC_PL400_CONTROLLER_PPTR;
}
#endif
config BSP_SUPPORT_FPU
bool "Using Float"
default n
menuconfig BSP_USING_VM_MODE
bool "Enable VM mode"
default n
menu "Hardware Drivers Config"
menu "BCM Peripheral Drivers"
menuconfig BSP_USING_UART
......@@ -26,20 +35,44 @@ menu "Hardware Drivers Config"
bool "Enable UART 5"
default n
endif
config BSP_USING_GIC
bool
menuconfig BSP_USING_GIC
bool "Enable GIC"
select RT_USING_GIC
default y
if BSP_USING_GIC
config BSP_USING_GICV2
bool
bool "Enable GIC400(GICV2)"
default y
config BSP_USING_GICV3
bool "Enable GIC500(GICV3)"
default n
endif
config BSP_USING_PIN
bool "Using PIN"
select RT_USING_PIN
default y
menuconfig BSP_USING_SPI
bool "Enable SPI"
select RT_USING_SPI
default n
if BSP_USING_SPI
config BSP_USING_SPI0_BUS
bool "Enable SPI0 BUS"
default n
config BSP_USING_SPI0_DEVICE0
bool "Enable SPI0 DEVICE0"
select BSP_USING_SPI0_BUS
default n
config BSP_USING_SPI0_DEVICE1
bool "Enable SPI0 DEVICE1"
select BSP_USING_SPI0_BUS
default n
endif
config BSP_USING_CORETIMER
bool "Using core timer"
select RT_USING_CORETIMER
......@@ -59,10 +92,6 @@ menu "Hardware Drivers Config"
default n
endif
config BSP_USING_ETH
bool "Enable ETH"
default n
config BSP_USING_WDT
bool "Enable WDT"
select RT_USING_WDT
......@@ -103,5 +132,9 @@ menu "Hardware Drivers Config"
bool "HDMI DISPLAY"
default n
endif
menuconfig BSP_USING_TOUCH
bool "Enable Touch"
default n
endmenu
endmenu
from building import *
cwd = GetCurrentDir()
src = Glob('*.c') + Glob('*.cpp') + Glob('*.S')
CPPPATH = [cwd, str(Dir('#'))]
group = DefineGroup('driver', src, depend = [''], CPPPATH = CPPPATH)
# build for sub-directory
list = os.listdir(cwd)
objs = []
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'))
group = group + objs
Return('group')
/*
* Copyright (c) 2006-2020, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-04-16 bigmagic first version
* 2021-12-28 GuEe-GUI add smp support
* 2023-03-28 WangXiaoyao sync works & memory layout fixups
* code formats
*/
#include <rthw.h>
#include <rtthread.h>
#include <mm_aspace.h>
#include "board.h"
#include "drv_uart.h"
#include "cp15.h"
#include "mmu.h"
#include "mbox.h"
#include <mm_page.h>
#ifdef RT_USING_SMART
#include <lwp_arch.h>
#endif
extern size_t MMUTable[];
size_t gpio_base_addr = GPIO_BASE_ADDR;
size_t uart_base_addr = UART_BASE;
size_t gic_base_addr = GIC_V2_BASE;
size_t arm_timer_base = ARM_TIMER_BASE;
size_t pactl_cs_base = PACTL_CS_ADDR;
size_t stimer_base_addr = STIMER_BASE;
size_t mmc2_base_addr = MMC2_BASE_ADDR;
size_t videocore_mbox = VIDEOCORE_MBOX;
size_t mbox_addr = MBOX_ADDR;
size_t wdt_base_addr = WDT_BASE;
uint8_t *mac_reg_base_addr = (uint8_t *)MAC_REG;
uint8_t *eth_send_no_cache = (uint8_t *)SEND_DATA_NO_CACHE;
uint8_t *eth_recv_no_cache = (uint8_t *)RECV_DATA_NO_CACHE;
#ifdef RT_USING_SMART
struct mem_desc platform_mem_desc[] = {
{KERNEL_VADDR_START, KERNEL_VADDR_START + 0x0fffffff, (rt_size_t)ARCH_MAP_FAILED, NORMAL_MEM}
};
#else
struct mem_desc platform_mem_desc[] = {
{0x00200000, (128ul << 20) - 1, 0x00200000, NORMAL_MEM},
{0xFC000000, 0x000100000000 - 1, 0xFC000000, DEVICE_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
*/
extern size_t MMUTable[];
int rt_hw_gtimer_init(void);
rt_region_t init_page_region = {
PAGE_START,
PAGE_END,
};
/**
* Initialize the Hardware related stuffs. Called from rtthread_startup()
* after interrupt disabled.
*/
void rt_hw_board_init(void)
{
extern void (*system_off)(void);
extern void reboot(void);
system_off = reboot;
/* io device remap */
#ifdef RT_USING_SMART
rt_hw_mmu_map_init(&rt_kernel_space, (void*)0xfffffffff0000000, 0x10000000, MMUTable, PV_OFFSET);
#else
rt_hw_mmu_map_init(&rt_kernel_space, (void*)0x000400000000, 0x10000000, MMUTable, 0);
#endif
rt_page_init(init_page_region);
rt_hw_mmu_setup(&rt_kernel_space, platform_mem_desc, platform_mem_desc_size);
/* map peripheral address to virtual address */
#ifdef RT_USING_HEAP
/* initialize system heap */
rt_system_heap_init((void *)HEAP_BEGIN, (void *)HEAP_END);
#endif
/* initialize hardware interrupt */
rt_hw_interrupt_init();
//gpio
gpio_base_addr = (size_t)rt_ioremap((void*)GPIO_BASE_ADDR, 0x1000);
//pactl
pactl_cs_base = (size_t)rt_ioremap((void*)PACTL_CS_ADDR, 0x1000);
//stimer
stimer_base_addr = (size_t)rt_ioremap((void*)STIMER_BASE, 0x1000);
//mmc2_base_addr
mmc2_base_addr = (size_t)rt_ioremap((void*)MMC2_BASE_ADDR, 0x1000);
//mbox
videocore_mbox = (size_t)rt_ioremap((void*)VIDEOCORE_MBOX, 0x1000);
// mbox msg
mbox = (volatile unsigned int *)rt_pages_alloc(0);
//wdt
wdt_base_addr = (size_t)rt_ioremap((void*)WDT_BASE, 0x1000);
//mac
mac_reg_base_addr = (void *)rt_ioremap((void*)MAC_REG, 0x80000);
// eth data
eth_send_no_cache = (void *)rt_pages_alloc(rt_page_bits(0x200000));
eth_recv_no_cache = (void *)rt_pages_alloc(rt_page_bits(0x200000));
/* initialize uart */
rt_hw_uart_init();
/* initialize timer for os tick */
rt_hw_gtimer_init();
#ifdef RT_USING_CONSOLE
/* set console device */
rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
#endif /* RT_USING_CONSOLE */
rt_kprintf("heap: 0x%08x - 0x%08x\n", HEAP_BEGIN, HEAP_END);
#ifdef RT_USING_COMPONENTS_INIT
rt_components_board_init();
#endif
rt_thread_idle_sethook(idle_wfi);
}
#ifdef RT_USING_SMP
#include <gic.h>
void rt_hw_mmu_ktbl_set(unsigned long tbl);
void _secondary_cpu_entry(void);
static unsigned long cpu_release_paddr[] =
{
[0] = 0xd8,
[1] = 0xe0,
[2] = 0xe8,
[3] = 0xf0,
[4] = 0x00
};
#ifndef RT_USING_SMART
static void *_remap(void *paddr, size_t size)
{
int ret;
static void *va = 0;
size_t low_off = (size_t)paddr & ARCH_PAGE_MASK;
if (va)
return va + low_off;
va = rt_kernel_space.start;
while (1)
{
int rt_kmem_map_phy(void *va, void *pa, rt_size_t length, rt_size_t attr);
ret = rt_kmem_map_phy(va, 0x0, ARCH_PAGE_SIZE, MMU_MAP_K_DEVICE);
if (ret == RT_EOK)
{
break;
}
else
{
va += ARCH_PAGE_SIZE;
}
}
return va + low_off;
}
#endif /* RT_USING_SMART */
void rt_hw_secondary_cpu_up(void)
{
int i;
void *release_addr;
for (i = 1; i < RT_CPUS_NR && cpu_release_paddr[i]; ++i)
{
#ifdef RT_USING_SMART
release_addr = rt_ioremap((void *)cpu_release_paddr[i], sizeof(cpu_release_paddr[0]));
#else
release_addr = _remap((void *)cpu_release_paddr[i], sizeof(cpu_release_paddr[0]));
#endif
__asm__ volatile ("str %0, [%1]"::"rZ"((unsigned long)_secondary_cpu_entry + PV_OFFSET), "r"(release_addr));
rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, release_addr, sizeof(release_addr));
asm volatile ("dsb sy");
asm volatile ("sev");
}
}
void rt_hw_secondary_cpu_bsp_start(void)
{
rt_hw_spin_lock(&_cpus_lock);
rt_hw_mmu_ktbl_set((unsigned long)MMUTable);
rt_hw_vector_init();
arm_gic_cpu_init(0, 0);
rt_hw_gtimer_init();
rt_kprintf("\rcpu %d boot success\n", rt_hw_cpu_id());
rt_system_scheduler_start();
}
void rt_hw_secondary_cpu_idle_exec(void)
{
asm volatile ("wfe":::"memory", "cc");
}
#endif
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
* Copyright (c) 2006-2020, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
......@@ -13,16 +13,22 @@
#include <stdint.h>
#include "raspi4.h"
#include "mmu.h"
#include "ioremap.h"
extern unsigned char __bss_start;
extern unsigned char __bss_end;
extern int __bss_end;
#define HEAP_BEGIN ((void*)&__bss_end)
#define RT_HW_HEAP_BEGIN (void*)&__bss_end
#define RT_HW_HEAP_END (void*)(RT_HW_HEAP_BEGIN + 64 * 1024 * 1024)
#ifdef RT_USING_SMART
#define HEAP_END ((size_t)KERNEL_VADDR_START + 32 * 1024 * 1024)
#define PAGE_START HEAP_END
#define PAGE_END ((size_t)KERNEL_VADDR_START + 128 * 1024 * 1024)
#else
#define KERNEL_VADDR_START 0x0
#ifndef RT_USING_SMART
#define PV_OFFSET 0
#define KERNEL_VADDR_START 0
#define HEAP_END (KERNEL_VADDR_START + 64 * 1024 * 1024)
#define PAGE_START HEAP_END
#define PAGE_END ((size_t)PAGE_START + 64 * 1024 * 1024)
#endif
void rt_hw_board_init(void);
......
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-11-26 bigmagic first version
*/
#include <rtthread.h>
#include <rtdevice.h>
#include <drivers/touch.h>
#include <ioremap.h>
#include <mmu.h>
#ifdef RT_USING_SMART
#include <lwp.h>
#include <lwp_user_mm.h>
#endif
#include <hypercall.h>
#ifdef BSP_USING_TOUCH
#include "mbox.h"
#include "drv_dsi_touch.h"
#define DBG_TAG "dsi_touch"
#define DBG_LVL DBG_INFO
#include <rtdbg.h>
static rt_touch_t touch_device = RT_NULL;
static struct rt_semaphore dsi_touch_ack;
static rt_uint32_t touch_x;
static rt_uint32_t touch_y;
static rt_uint32_t touch_state = 0;
static rt_thread_t dsi_touch_tid = RT_NULL;
#define DSI_TOUCH_THREAD_STACK_SIZE (4096)
#define DSI_TOUCH_THREAD_PRIORITY (25)
#define DSI_TOUCH_THREAD_TIMESLICE (10)
#define MAXIMUM_SUPPORTED_POINTS (10)
struct touch_regs
{
uint8_t device_mode;
uint8_t gesture_id;
uint8_t num_points;
struct touch
{
uint8_t xh;
uint8_t xl;
uint8_t yh;
uint8_t yl;
uint8_t res1;
uint8_t res2;
} point[MAXIMUM_SUPPORTED_POINTS];
};
struct drv_mouse_device
{
struct rt_device parent;
struct rt_touch_data touchdata;
int channel;
};
struct drv_mouse_device _mouse;
static void post_event(rt_uint16_t x, rt_uint16_t y, rt_uint8_t event)
{
struct rt_touch_data *minfo = &_mouse.touchdata;
struct rt_channel_msg ch_msg;
LOG_D("event:%d, x:%d, y:%d\n", event, x, y);
minfo->x_coordinate = x;
minfo->y_coordinate = y;
minfo->event = event;
ch_msg.type = RT_CHANNEL_RAW;
ch_msg.u.d = (void *)(size_t)event;
rt_channel_send(_mouse.channel, &ch_msg);
}
static void dsi_touch_thread_entry(void *param)
{
static volatile unsigned long touchbuf;
touchbuf = bcm271x_mbox_get_touch();
if (touchbuf == RT_NULL)
{
rt_kprintf("init dsi touch err!\n");
return;
}
#ifdef BSP_USING_VM_MODE
if (rt_hv_stage2_map((unsigned long)touchbuf, 0x1000))
{
rt_kprintf("alloc mmio from hyper fail!\n");
return;
}
#endif
touchbuf = (unsigned long)rt_ioremap((void *)touchbuf, 0x1000);
while (1)
{
struct touch_regs *regs = (struct touch_regs *)touchbuf;
if ((regs->num_points > 0) && (regs->num_points < MAXIMUM_SUPPORTED_POINTS))
{
/* only one touch point */
touch_x = (((int)regs->point[0].xh & 0xf) << 8) + regs->point[0].xl;
touch_y = (((int)regs->point[0].yh & 0xf) << 8) + regs->point[0].yl;
if (!touch_state)
{
post_event(touch_x, touch_y, RT_TOUCH_EVENT_DOWN);
}
else
{
post_event(touch_x, touch_y, RT_TOUCH_EVENT_MOVE);
}
touch_state = 1;
}
else
{
if (touch_state)
{
post_event(touch_x, touch_y, RT_TOUCH_EVENT_UP);
}
touch_state = 0;
}
rt_thread_mdelay(1);
}
}
static rt_size_t dsi_read_point(struct rt_touch_device *touch, void *buf, rt_size_t read_num)
{
rt_uint16_t* touchxy = (rt_uint16_t *)buf;
if ((read_num != 0) && (touch_state == 1))
{
touchxy[0] = touch_x;
touchxy[1] = touch_y;
touch_state = 0;
return read_num;
}
else
{
return 0;
}
}
static rt_err_t dsi_control(struct rt_touch_device *device, int cmd, void *data)
{
return RT_EOK;
}
static struct rt_touch_ops dsi_touch_ops =
{
.touch_readpoint = dsi_read_point,
.touch_control = dsi_control,
};
static rt_err_t drv_mouse_init(struct rt_device *device)
{
struct drv_mouse_device *mouse = (struct drv_mouse_device*)device;
return RT_EOK;
}
static rt_err_t drv_mouse_control(struct rt_device *device, int cmd, void *args)
{
switch (cmd)
{
#define CMD_MOUSE_SET_NOTIFY 0 /* arg is shmid, in the shm, a sem point is given */
case CMD_MOUSE_SET_NOTIFY:
*(unsigned long *)args = (rt_uint32_t)(unsigned long)lwp_map_user_phy(lwp_self(), RT_NULL, (uint32_t*)((size_t)&_mouse.touchdata + PV_OFFSET), sizeof(struct rt_touch_data), 1);
break;
default:
break;
}
return RT_EOK;
}
#ifdef RT_USING_DEVICE_OPS
const static struct rt_device_ops _mouse_ops =
{
drv_mouse_init,
RT_NULL,
RT_NULL,
RT_NULL,
RT_NULL,
drv_mouse_control
};
#endif
static int hw_dsi_touch_init(void)
{
struct rt_device *device = &_mouse.parent;
#ifdef RT_USING_DEVICE_OPS
device->ops = &_mouse_ops;
#else
device->init = drv_mouse_init;
device->open = RT_NULL;
device->close = RT_NULL;
device->read = RT_NULL;
device->write = RT_NULL;
device->control = drv_mouse_control;
#endif
rt_device_register(device, "mouse", RT_DEVICE_FLAG_RDWR);
_mouse.channel = rt_channel_open("mouse", O_CREAT);
/* touch sem */
rt_sem_init(&dsi_touch_ack, "dsi_touch_ack", 0, RT_IPC_FLAG_FIFO);
dsi_touch_tid = rt_thread_create("dsi_touch",
dsi_touch_thread_entry, RT_NULL,
DSI_TOUCH_THREAD_STACK_SIZE,
DSI_TOUCH_THREAD_PRIORITY, DSI_TOUCH_THREAD_TIMESLICE);
if (dsi_touch_tid != RT_NULL)
{
rt_thread_startup(dsi_touch_tid);
}
touch_device = (rt_touch_t)rt_malloc(sizeof(struct rt_touch_device));
if (touch_device == RT_NULL)
{
return -RT_ERROR;
}
/* register touch device */
touch_device->info.type = RT_TOUCH_TYPE_RESISTANCE;
touch_device->info.vendor = RT_TOUCH_VENDOR_UNKNOWN;
touch_device->ops = &dsi_touch_ops;
rt_hw_touch_register(touch_device, "dsi_touch", RT_DEVICE_FLAG_INT_RX, RT_NULL);
return 0;
}
INIT_APP_EXPORT(hw_dsi_touch_init);
#endif /* BSP_USING_TOUCH */
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
* Copyright (c) 2006-2020, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
......@@ -11,44 +12,46 @@
#ifndef __DRV_ETH_H__
#define __DRV_ETH_H__
#define MAC_REG (void *)(0xfd580000)
#define SYS_REV_CTRL (0x00)
#define SYS_PORT_CTRL (0x04)
#define PORT_MODE_EXT_GPHY (3)
#define GENET_SYS_OFF (0x0000)
#define SYS_RBUF_FLUSH_CTRL (GENET_SYS_OFF + 0x08)
#define SYS_TBUF_FLUSH_CTRL (GENET_SYS_OFF + 0x0c)
#define GENET_EXT_OFF (0x0080)
#define EXT_RGMII_OOB_CTRL (GENET_EXT_OFF + 0x0c)
#define RGMII_LINK BIT(4)
#define OOB_DISABLE BIT(5)
#define RGMII_MODE_EN BIT(6)
#define ID_MODE_DIS BIT(16)
#define GENET_RBUF_OFF (0x0300)
#define RBUF_TBUF_SIZE_CTRL (GENET_RBUF_OFF + 0xb4)
#define RBUF_CTRL (GENET_RBUF_OFF + 0x00)
#define RBUF_ALIGN_2B BIT(1)
#define GENET_UMAC_OFF (0x0800)
#define UMAC_MIB_CTRL (GENET_UMAC_OFF + 0x580)
#define UMAC_MAX_FRAME_LEN (GENET_UMAC_OFF + 0x014)
#define UMAC_MAC0 (GENET_UMAC_OFF + 0x00c)
#define UMAC_MAC1 (GENET_UMAC_OFF + 0x010)
#define UMAC_CMD (GENET_UMAC_OFF + 0x008)
#define MDIO_CMD (GENET_UMAC_OFF + 0x614)
#define UMAC_TX_FLUSH (GENET_UMAC_OFF + 0x334)
#define MDIO_START_BUSY BIT(29)
#define MDIO_READ_FAIL BIT(28)
#define MDIO_RD (2 << 26)
#define MDIO_WR BIT(26)
#define MDIO_PMD_SHIFT (21)
#define MDIO_PMD_MASK (0x1f)
#define MDIO_REG_SHIFT (16)
#define MDIO_REG_MASK (0x1f)
//#define BIT(nr) (1UL << (nr))
#define ENET_FRAME_MAX_FRAMELEN 1518U
#define SYS_REV_CTRL (0x00)
#define SYS_PORT_CTRL (0x04)
#define PORT_MODE_EXT_GPHY (3)
#define GENET_SYS_OFF (0x0000)
#define SYS_RBUF_FLUSH_CTRL (GENET_SYS_OFF + 0x08)
#define SYS_TBUF_FLUSH_CTRL (GENET_SYS_OFF + 0x0c)
#define GENET_EXT_OFF (0x0080)
#define EXT_RGMII_OOB_CTRL (GENET_EXT_OFF + 0x0c)
#define RGMII_LINK BIT(4)
#define OOB_DISABLE BIT(5)
#define RGMII_MODE_EN BIT(6)
#define ID_MODE_DIS BIT(16)
#define GENET_RBUF_OFF (0x0300)
#define RBUF_TBUF_SIZE_CTRL (GENET_RBUF_OFF + 0xb4)
#define RBUF_CTRL (GENET_RBUF_OFF + 0x00)
#define RBUF_ALIGN_2B BIT(1)
#define GENET_UMAC_OFF (0x0800)
#define UMAC_MIB_CTRL (GENET_UMAC_OFF + 0x580)
#define UMAC_MAX_FRAME_LEN (GENET_UMAC_OFF + 0x014)
#define UMAC_MAC0 (GENET_UMAC_OFF + 0x00c)
#define UMAC_MAC1 (GENET_UMAC_OFF + 0x010)
#define UMAC_CMD (GENET_UMAC_OFF + 0x008)
#define MDIO_CMD (GENET_UMAC_OFF + 0x614)
#define UMAC_TX_FLUSH (GENET_UMAC_OFF + 0x334)
#define MDIO_START_BUSY BIT(29)
#define MDIO_READ_FAIL BIT(28)
#define MDIO_RD (2 << 26)
#define MDIO_WR BIT(26)
#define MDIO_PMD_SHIFT (21)
#define MDIO_PMD_MASK (0x1f)
#define MDIO_REG_SHIFT (16)
#define MDIO_REG_MASK (0x1f)
#define GENET_INTRL2_OFF (0x0200)
#define GENET_INTRL2_CPU_STAT (GENET_INTRL2_OFF + 0x00)
......@@ -61,83 +64,88 @@
#define GENET_IRQ_TXDMA_DONE BIT(16)
#define GENET_IRQ_RXDMA_DONE BIT(13)
#define CMD_TX_EN BIT(0)
#define CMD_RX_EN BIT(1)
#define UMAC_SPEED_10 (0)
#define UMAC_SPEED_100 (1)
#define UMAC_SPEED_1000 (2)
#define UMAC_SPEED_2500 (3)
#define CMD_SPEED_SHIFT (2)
#define CMD_SPEED_MASK (3)
#define CMD_SW_RESET BIT(13)
#define CMD_LCL_LOOP_EN BIT(15)
#define CMD_TX_EN BIT(0)
#define CMD_RX_EN BIT(1)
#define MIB_RESET_RX BIT(0)
#define MIB_RESET_RUNT BIT(1)
#define MIB_RESET_TX BIT(2)
#define CMD_TX_EN BIT(0)
#define CMD_RX_EN BIT(1)
#define UMAC_SPEED_10 (0)
#define UMAC_SPEED_100 (1)
#define UMAC_SPEED_1000 (2)
#define UMAC_SPEED_2500 (3)
#define CMD_SPEED_SHIFT (2)
#define CMD_SPEED_MASK (3)
#define CMD_SW_RESET BIT(13)
#define CMD_LCL_LOOP_EN BIT(15)
#define CMD_TX_EN BIT(0)
#define CMD_RX_EN BIT(1)
#define MIB_RESET_RX BIT(0)
#define MIB_RESET_RUNT BIT(1)
#define MIB_RESET_TX BIT(2)
/* total number of Buffer Descriptors, same for Rx/Tx */
#define TOTAL_DESCS (256)
#define RX_DESCS TOTAL_DESCS
#define TX_DESCS TOTAL_DESCS
#define TOTAL_DESCS (256)
#define RX_DESCS TOTAL_DESCS
#define TX_DESCS TOTAL_DESCS
#define DEFAULT_Q (0x10)
#define DEFAULT_Q (0x10)
#define ETH_DATA_LEN (1500)
#define ETH_HLEN (14)
#define VLAN_HLEN (4)
#define ETH_FCS_LEN (4)
/*
* Body(1500) + EH_SIZE(14) + VLANTAG(4) + BRCMTAG(6) + FCS(4) = 1528.
#define ETH_DATA_LEN (1500)
#define ETH_HLEN (14)
#define VLAN_HLEN (4)
#define ETH_FCS_LEN (4)
/* Body(1500) + EH_SIZE(14) + VLANTAG(4) + BRCMTAG(6) + FCS(4) = 1528.
* 1536 is multiple of 256 bytes
*/
#define ENET_BRCM_TAG_LEN (6)
#define ENET_PAD (8)
#define ENET_MAX_MTU_SIZE (ETH_DATA_LEN + ETH_HLEN + VLAN_HLEN + ENET_BRCM_TAG_LEN + ETH_FCS_LEN + ENET_PAD)
#define ENET_BRCM_TAG_LEN (6)
#define ENET_PAD (8)
#define ENET_MAX_MTU_SIZE (ETH_DATA_LEN + ETH_HLEN + \
VLAN_HLEN + ENET_BRCM_TAG_LEN + \
ETH_FCS_LEN + ENET_PAD)
/* Tx/Rx Dma Descriptor common bits */
#define DMA_EN BIT(0)
#define DMA_RING_BUF_EN_SHIFT (0x01)
#define DMA_RING_BUF_EN_MASK (0xffff)
#define DMA_BUFLENGTH_MASK (0x0fff)
#define DMA_BUFLENGTH_SHIFT (16)
#define DMA_RING_SIZE_SHIFT (16)
#define DMA_OWN (0x8000)
#define DMA_EOP (0x4000)
#define DMA_SOP (0x2000)
#define DMA_WRAP (0x1000)
#define DMA_MAX_BURST_LENGTH (0x8)
#define DMA_EN BIT(0)
#define DMA_RING_BUF_EN_SHIFT (0x01)
#define DMA_RING_BUF_EN_MASK (0xffff)
#define DMA_BUFLENGTH_MASK (0x0fff)
#define DMA_BUFLENGTH_SHIFT (16)
#define DMA_RING_SIZE_SHIFT (16)
#define DMA_OWN (0x8000)
#define DMA_EOP (0x4000)
#define DMA_SOP (0x2000)
#define DMA_WRAP (0x1000)
#define DMA_MAX_BURST_LENGTH (0x8)
/* Tx specific DMA descriptor bits */
#define DMA_TX_UNDERRUN (0x0200)
#define DMA_TX_APPEND_CRC (0x0040)
#define DMA_TX_OW_CRC (0x0020)
#define DMA_TX_DO_CSUM (0x0010)
#define DMA_TX_QTAG_SHIFT (7)
#define DMA_TX_UNDERRUN (0x0200)
#define DMA_TX_APPEND_CRC (0x0040)
#define DMA_TX_OW_CRC (0x0020)
#define DMA_TX_DO_CSUM (0x0010)
#define DMA_TX_QTAG_SHIFT (7)
/* DMA rings size */
#define DMA_RING_SIZE (0x40)
#define DMA_RINGS_SIZE (DMA_RING_SIZE * (DEFAULT_Q + 1))
#define DMA_RING_SIZE (0x40)
#define DMA_RINGS_SIZE (DMA_RING_SIZE * (DEFAULT_Q + 1))
/* DMA descriptor */
#define DMA_DESC_LENGTH_STATUS (0x00)
#define DMA_DESC_ADDRESS_LO (0x04)
#define DMA_DESC_ADDRESS_HI (0x08)
#define DMA_DESC_SIZE (12)
#define GENET_RX_OFF (0x2000)
#define GENET_RDMA_REG_OFF (GENET_RX_OFF + TOTAL_DESCS * DMA_DESC_SIZE)
#define GENET_TX_OFF (0x4000)
#define GENET_TDMA_REG_OFF (GENET_TX_OFF + TOTAL_DESCS * DMA_DESC_SIZE)
#define DMA_FC_THRESH_HI (RX_DESCS >> 4)
#define DMA_FC_THRESH_LO (5)
#define DMA_FC_THRESH_VALUE ((DMA_FC_THRESH_LO << 16) | DMA_FC_THRESH_HI)
#define DMA_XOFF_THRESHOLD_SHIFT (16)
#define TDMA_RING_REG_BASE (GENET_TDMA_REG_OFF + DEFAULT_Q * DMA_RING_SIZE)
#define DMA_DESC_LENGTH_STATUS (0x00)
#define DMA_DESC_ADDRESS_LO (0x04)
#define DMA_DESC_ADDRESS_HI (0x08)
#define DMA_DESC_SIZE (12)
#define GENET_RX_OFF (0x2000)
#define GENET_RDMA_REG_OFF \
(GENET_RX_OFF + TOTAL_DESCS * DMA_DESC_SIZE)
#define GENET_TX_OFF (0x4000)
#define GENET_TDMA_REG_OFF \
(GENET_TX_OFF + TOTAL_DESCS * DMA_DESC_SIZE)
#define DMA_FC_THRESH_HI (RX_DESCS >> 4)
#define DMA_FC_THRESH_LO (5)
#define DMA_FC_THRESH_VALUE ((DMA_FC_THRESH_LO << 16) | \
DMA_FC_THRESH_HI)
#define DMA_XOFF_THRESHOLD_SHIFT (16)
#define TDMA_RING_REG_BASE \
(GENET_TDMA_REG_OFF + DEFAULT_Q * DMA_RING_SIZE)
#define TDMA_READ_PTR (TDMA_RING_REG_BASE + 0x00)
#define TDMA_CONS_INDEX (TDMA_RING_REG_BASE + 0x08)
#define TDMA_PROD_INDEX (TDMA_RING_REG_BASE + 0x0c)
......@@ -148,7 +156,8 @@
#define TDMA_FLOW_PERIOD (TDMA_RING_REG_BASE + 0x28)
#define TDMA_WRITE_PTR (TDMA_RING_REG_BASE + 0x2c)
#define RDMA_RING_REG_BASE (GENET_RDMA_REG_OFF + DEFAULT_Q * DMA_RING_SIZE)
#define RDMA_RING_REG_BASE \
(GENET_RDMA_REG_OFF + DEFAULT_Q * DMA_RING_SIZE)
#define RDMA_WRITE_PTR (RDMA_RING_REG_BASE + 0x00)
#define RDMA_PROD_INDEX (RDMA_RING_REG_BASE + 0x08)
#define RDMA_CONS_INDEX (RDMA_RING_REG_BASE + 0x0c)
......
/*
* Copyright (c) 2006-2020, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-04-16 bigmagic first version
* 2020-06-16 bigmagic add gpio irq
*/
#include "drv_gpio.h"
#ifdef BSP_USING_PIN
/*
* gpio_int[0] for BANK0 (pins 0-27)
* gpio_int[1] for BANK1 (pins 28-45)
* gpio_int[2] for BANK2 (pins 46-53)
*/
static struct gpio_irq_def _g_gpio_irq_tbl[GPIO_IRQ_NUM];
uint32_t raspi_get_pin_state(uint32_t fselnum)
{
uint32_t gpfsel = 0;
switch (fselnum)
{
case 0:
gpfsel = GPIO_REG_GPFSEL0(gpio_base_addr);
break;
case 1:
gpfsel = GPIO_REG_GPFSEL1(gpio_base_addr);
break;
case 2:
gpfsel = GPIO_REG_GPFSEL2(gpio_base_addr);
break;
case 3:
gpfsel = GPIO_REG_GPFSEL3(gpio_base_addr);
break;
case 4:
gpfsel = GPIO_REG_GPFSEL4(gpio_base_addr);
break;
case 5:
gpfsel = GPIO_REG_GPFSEL5(gpio_base_addr);
break;
default:
break;
}
return gpfsel;
}
void raspi_set_pin_state(uint32_t fselnum, uint32_t gpfsel)
{
switch (fselnum)
{
case 0:
GPIO_REG_GPFSEL0(gpio_base_addr) = gpfsel;
break;
case 1:
GPIO_REG_GPFSEL1(gpio_base_addr) = gpfsel;
break;
case 2:
GPIO_REG_GPFSEL2(gpio_base_addr) = gpfsel;
break;
case 3:
GPIO_REG_GPFSEL3(gpio_base_addr) = gpfsel;
break;
case 4:
GPIO_REG_GPFSEL4(gpio_base_addr) = gpfsel;
break;
case 5:
GPIO_REG_GPFSEL5(gpio_base_addr) = gpfsel;
break;
default:
break;
}
}
static void gpio_set_pud(GPIO_PIN pin, GPIO_PUPD_FUNC mode)
{
uint32_t fselnum = pin / 16;
uint32_t fselrest = pin % 16;
uint32_t reg_value = 0;
switch (fselnum)
{
case 0:
reg_value = GPIO_PUP_PDN_CNTRL_REG0(gpio_base_addr);
GPIO_PUP_PDN_CNTRL_REG0(gpio_base_addr) = (reg_value | (mode << (fselrest*2)));
break;
case 1:
reg_value = GPIO_PUP_PDN_CNTRL_REG1(gpio_base_addr);
GPIO_PUP_PDN_CNTRL_REG1(gpio_base_addr) = (reg_value | (mode << (fselrest*2)));
break;
case 2:
reg_value = GPIO_PUP_PDN_CNTRL_REG2(gpio_base_addr);
GPIO_PUP_PDN_CNTRL_REG2(gpio_base_addr) = (reg_value | (mode << (fselrest*2)));
break;
case 3:
reg_value = GPIO_PUP_PDN_CNTRL_REG3(gpio_base_addr);
GPIO_PUP_PDN_CNTRL_REG3(gpio_base_addr) = (reg_value | (mode << (fselrest*2)));
break;
default:
break;
}
}
void prev_raspi_pin_mode(GPIO_PIN pin, GPIO_FUNC mode)
{
uint32_t fselnum = pin / 10;
uint32_t fselrest = pin % 10;
uint32_t gpfsel = 0;
gpfsel = raspi_get_pin_state(fselnum);
gpfsel &= ~((uint32_t)(0x07 << (fselrest * 3)));
gpfsel |= (uint32_t)(mode << (fselrest * 3));
raspi_set_pin_state(fselnum, gpfsel);
}
void prev_raspi_pin_write(GPIO_PIN pin, int pin_value)
{
uint32_t num = pin / 32;
if(num == 0)
{
if(pin_value == 1)
{
GPIO_REG_GPSET0(gpio_base_addr) = 1 << (pin % 32);
}
else
{
GPIO_REG_GPCLR0(gpio_base_addr) = 1 << (pin % 32);
}
}
else
{
if(pin_value == 1)
{
GPIO_REG_GPSET1(gpio_base_addr) = 1 << (pin % 32);
}
else
{
GPIO_REG_GPCLR1(gpio_base_addr) = 1 << (pin % 32);
}
}
}
static void raspi_pin_mode(struct rt_device *dev, rt_base_t pin, rt_uint8_t mode)
{
GPIO_FUNC raspi_mode = OUTPUT;
switch (mode)
{
case PIN_MODE_OUTPUT:
raspi_mode = OUTPUT;
break;
case PIN_MODE_INPUT:
raspi_mode = INPUT;
break;
case PIN_MODE_INPUT_PULLUP:
gpio_set_pud(pin, RASPI_PULL_UP);
raspi_mode = INPUT;
break;
case PIN_MODE_INPUT_PULLDOWN:
gpio_set_pud(pin, RASPI_PULL_DOWN);
raspi_mode = INPUT;
break;
case PIN_MODE_OUTPUT_OD:
raspi_mode = OUTPUT;
break;
}
prev_raspi_pin_mode((GPIO_PIN)pin, raspi_mode);
}
static void raspi_pin_write(struct rt_device *dev, rt_base_t pin, rt_uint8_t value)
{
prev_raspi_pin_write(pin, value);
}
static rt_int8_t raspi_pin_read(struct rt_device *device, rt_base_t pin)
{
uint32_t num = pin / 32;
uint32_t pin_level = 0;
if(num == 0)
{
if(GPIO_REG_GPLEV0(gpio_base_addr) & (1 << pin))
{
pin_level = 1;
}
else
{
pin_level = 0;
}
}
else
{
if(GPIO_REG_GPLEV1(gpio_base_addr) & (1 << pin))
{
pin_level = 1;
}
else
{
pin_level = 0;
}
}
return pin_level;
}
static rt_err_t raspi_pin_attach_irq(struct rt_device *device, rt_base_t pin, rt_uint8_t mode, void (*hdr)(void *args), void *args)
{
rt_uint8_t index;
rt_uint32_t reg_value;
if (pin <= 27)
index = 0;
else if (pin <= 45)
index = 1;
else
index = 2;
_g_gpio_irq_tbl[index].irq_cb[pin] = hdr;
_g_gpio_irq_tbl[index].irq_arg[pin] = args;
_g_gpio_irq_tbl[index].irq_type[pin] = mode;
rt_uint8_t shift = pin % 32;
rt_uint8_t pin_num = pin / 32;
rt_uint32_t mask = 1 << shift;
switch (mode)
{
case PIN_IRQ_MODE_RISING:
if(pin_num == 0)
{
reg_value = GPIO_REG_GPREN0(gpio_base_addr);
GPIO_REG_GPREN0(gpio_base_addr) = (reg_value & ~ mask) | (mask);
}
else
{
reg_value = GPIO_REG_GPREN1(gpio_base_addr);
GPIO_REG_GPREN1(gpio_base_addr) = (reg_value & ~ mask) | (mask);
}
break;
case PIN_IRQ_MODE_FALLING:
if(pin_num == 0)
{
reg_value = GPIO_REG_GPFEN0(gpio_base_addr);
GPIO_REG_GPFEN0(gpio_base_addr) = (reg_value & ~ mask) | (mask);
}
else
{
reg_value = GPIO_REG_GPFEN1(gpio_base_addr);
GPIO_REG_GPFEN1(gpio_base_addr) = (reg_value & ~ mask) | (mask);
}
break;
case PIN_IRQ_MODE_RISING_FALLING:
if(pin_num == 0)
{
reg_value = GPIO_REG_GPAREN0(gpio_base_addr);
GPIO_REG_GPAREN0(gpio_base_addr) = (reg_value & ~ mask) | (mask);
reg_value = GPIO_REG_GPFEN0(gpio_base_addr);
GPIO_REG_GPFEN0(gpio_base_addr) = (reg_value & ~ mask) | (mask);
}
else
{
reg_value = GPIO_REG_GPAREN1(gpio_base_addr);
GPIO_REG_GPAREN1(gpio_base_addr) = (reg_value & ~ mask) | (mask);
reg_value = GPIO_REG_GPFEN1(gpio_base_addr);
GPIO_REG_GPFEN1(gpio_base_addr) = (reg_value & ~ mask) | (mask);
}
break;
case PIN_IRQ_MODE_HIGH_LEVEL:
if(pin_num == 0)
{
reg_value = GPIO_REG_GPHEN0(gpio_base_addr);
GPIO_REG_GPHEN0(gpio_base_addr) = (reg_value & ~ mask) | (mask);
}
else
{
reg_value = GPIO_REG_GPHEN1(gpio_base_addr);
GPIO_REG_GPHEN1(gpio_base_addr) = (reg_value & ~ mask) | ( mask);
}
break;
case PIN_IRQ_MODE_LOW_LEVEL:
if(pin_num == 0)
{
reg_value = GPIO_REG_GPLEN0(gpio_base_addr);
GPIO_REG_GPLEN0(gpio_base_addr) = (reg_value & ~ mask) | (mask);
}
else
{
reg_value = GPIO_REG_GPLEN1(gpio_base_addr);
GPIO_REG_GPLEN1(gpio_base_addr) = (reg_value & ~ mask) | (mask);
}
break;
}
return RT_EOK;
}
static rt_err_t raspi_pin_detach_irq(struct rt_device *device, rt_base_t pin)
{
rt_uint8_t index;
if (pin <= 27)
index = 0;
else if (pin <= 45)
index = 1;
else
index = 2;
_g_gpio_irq_tbl[index].irq_cb[pin] = RT_NULL;
_g_gpio_irq_tbl[index].irq_arg[pin] = RT_NULL;
_g_gpio_irq_tbl[index].irq_type[pin] = RT_NULL;
_g_gpio_irq_tbl[index].state[pin] = RT_NULL;
return RT_EOK;
}
rt_err_t raspi_pin_irq_enable(struct rt_device *device, rt_base_t pin, rt_uint8_t enabled)
{
rt_uint8_t index;
if (pin <= 27)
index = 0;
else if (pin <= 45)
index = 1;
else
index = 2;
if (enabled)
_g_gpio_irq_tbl[index].state[pin] = 1;
else
_g_gpio_irq_tbl[index].state[pin] = 0;
return RT_EOK;
}
static const struct rt_pin_ops ops =
{
raspi_pin_mode,
raspi_pin_write,
raspi_pin_read,
raspi_pin_attach_irq,
raspi_pin_detach_irq,
raspi_pin_irq_enable,
RT_NULL,
};
static void gpio_irq_handler(int irq, void *param)
{
struct gpio_irq_def *irq_def = (struct gpio_irq_def *)param;
rt_uint32_t pin;
rt_uint32_t value;
rt_uint32_t tmpvalue;
if(irq == IRQ_GPIO0)
{
/* 0~27 */
value = GPIO_REG_GPEDS0(gpio_base_addr);
value &= 0x0fffffff;
pin = 0;
GPIO_REG_GPEDS0(gpio_base_addr) = value;
}
else if(irq == IRQ_GPIO1)
{
/* 28-45 */
tmpvalue = GPIO_REG_GPEDS0(gpio_base_addr);
tmpvalue &= (~0x0fffffff);
GPIO_REG_GPEDS0(gpio_base_addr) = tmpvalue;
value = GPIO_REG_GPEDS1(gpio_base_addr);
value &= 0x3fff;
GPIO_REG_GPEDS1(gpio_base_addr) = value;
value = (value) | tmpvalue;
pin = 28;
}
else if (irq == IRQ_GPIO2)
{
/* 46-53 */
value = GPIO_REG_GPEDS1(gpio_base_addr);
value &= (~0x3fff);
GPIO_REG_GPEDS1(gpio_base_addr) = value;
pin = 46;
}
while (value)
{
if ((value & 0x1) && (irq_def->irq_cb[pin] != RT_NULL))
{
if(irq_def->state[pin])
{
irq_def->irq_cb[pin](irq_def->irq_arg[pin]);
}
}
pin++;
value = value >> 1;
}
}
#endif
int rt_hw_gpio_init(void)
{
#ifdef BSP_USING_PIN
rt_device_pin_register("gpio", &ops, RT_NULL);
//disable all intr
GPIO_REG_GPEDS0(gpio_base_addr) = 0xffffffff;
GPIO_REG_GPEDS1(gpio_base_addr) = 0xffffffff;
GPIO_REG_GPREN0(gpio_base_addr) = 0x0;
GPIO_REG_GPREN1(gpio_base_addr) = 0x0;
GPIO_REG_GPFEN0(gpio_base_addr) = 0x0;
GPIO_REG_GPFEN1(gpio_base_addr) = 0x0;
GPIO_REG_GPHEN0(gpio_base_addr) = 0x0;
GPIO_REG_GPHEN1(gpio_base_addr) = 0x0;
GPIO_REG_GPAREN0(gpio_base_addr) = 0x0;
GPIO_REG_GPAREN1(gpio_base_addr) = 0x0;
GPIO_REG_GPAFEN0(gpio_base_addr) = 0x0;
GPIO_REG_GPAFEN0(gpio_base_addr) = 0x0;
rt_hw_interrupt_install(IRQ_GPIO0, gpio_irq_handler, &_g_gpio_irq_tbl[0], "gpio0_irq");
rt_hw_interrupt_umask(IRQ_GPIO0);
rt_hw_interrupt_install(IRQ_GPIO1, gpio_irq_handler, &_g_gpio_irq_tbl[1], "gpio1_irq");
rt_hw_interrupt_umask(IRQ_GPIO1);
rt_hw_interrupt_install(IRQ_GPIO2, gpio_irq_handler, &_g_gpio_irq_tbl[2], "gpio2_irq");
rt_hw_interrupt_umask(IRQ_GPIO2);
#endif
return 0;
}
INIT_DEVICE_EXPORT(rt_hw_gpio_init);
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
......@@ -17,6 +17,14 @@
#include "board.h"
#include "interrupt.h"
struct gpio_irq_def
{
void *irq_arg[32];
void (*irq_cb[32])(void *param);
rt_uint8_t irq_type[32];
rt_uint8_t state[32];
};
#define GPIO_REG_GPFSEL0(BASE) HWREG32(BASE + 0x00)
#define GPIO_REG_GPFSEL1(BASE) HWREG32(BASE + 0x04)
#define GPIO_REG_GPFSEL2(BASE) HWREG32(BASE + 0x08)
......@@ -59,6 +67,10 @@
#define GPIO_REG_GPPUDCLK1(BASE) HWREG32(BASE + 0x9C)
#define GPIO_REG_REV9(BASE) HWREG32(BASE + 0xA0)
#define GPIO_REG_TEST(BASE) HWREG32(BASE + 0xA4)
#define GPIO_PUP_PDN_CNTRL_REG0(BASE) HWREG32(BASE + 0xE4)
#define GPIO_PUP_PDN_CNTRL_REG1(BASE) HWREG32(BASE + 0xE8)
#define GPIO_PUP_PDN_CNTRL_REG2(BASE) HWREG32(BASE + 0xEC)
#define GPIO_PUP_PDN_CNTRL_REG3(BASE) HWREG32(BASE + 0xF0)
typedef enum {
GPIO_PIN_0,
......@@ -115,6 +127,12 @@ typedef enum {
ALT5 = 0b010
} GPIO_FUNC;
typedef enum {
RASPI_NO_RESISTOR = 0x00,
RASPI_PULL_UP = 0x01,
RASPI_PULL_DOWN = 0x10
} GPIO_PUPD_FUNC;
void prev_raspi_pin_mode(GPIO_PIN pin, GPIO_FUNC mode);
void prev_raspi_pin_write(GPIO_PIN pin, int pin_value);
int rt_hw_gpio_init(void);
......
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <rtthread.h>
#include "interrupt.h"
#ifndef RT_CPUS_NR
#define RT_CPUS_NR 1
#endif
#define GTIMER_IRQ (27)
static uint64_t _tickval[RT_CPUS_NR];
static uint64_t _increaseval[RT_CPUS_NR];
#define tickval _tickval[cpu_id]
#define increaseval _increaseval[cpu_id]
/**
* This function is the gtimer isr handler.
*
* @param vector interrupt ID
* @param parameter the parameter specified by rt_hw_interrupt_install
*
* @return none
*/
static void _hw_timer_isr(int vector, void *parameter)
{
#ifdef RT_USING_SMP
int cpu_id = rt_hw_cpu_id();
#else
int cpu_id = 0;
#endif
uint64_t cntvct_el0;
do
{
tickval += increaseval;
__asm__ volatile("msr CNTV_CVAL_EL0, %0"::"r"(tickval));
__asm__ volatile("mrs %0, CNTVCT_EL0":"=r"(cntvct_el0));
} while (cntvct_el0 >= tickval);
rt_tick_increase();
}
/**
* The function will initialize the general timer used for the system tick.
*
* @param none
*
* @return none
*/
rt_weak int rt_hw_gtimer_init(void)
{
#ifdef RT_USING_SMP
int cpu_id = rt_hw_cpu_id();
#else
int cpu_id = 0;
#endif
uint64_t val;
rt_hw_interrupt_install(GTIMER_IRQ, _hw_timer_isr, RT_NULL, "tick");
rt_hw_interrupt_umask(GTIMER_IRQ);
__asm__ volatile("mrs %0, CNTFRQ_EL0":"=r"(val));
increaseval = val / RT_TICK_PER_SECOND;
__asm__ volatile("msr CNTV_CTL_EL0, %0"::"r"(val));
tickval = increaseval;
__asm__ volatile("msr CNTV_CVAL_EL0, %0"::"r"(tickval));
val = 1;
__asm__ volatile("msr CNTV_CTL_EL0, %0"::"r"(val));
return 0;
}
INIT_BOARD_EXPORT(rt_hw_gtimer_init);
/*
* Copyright (c) 2006-2020, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-10-26 bigmagic first version
*/
#include <stdint.h>
#include <rtthread.h>
#include <ioremap.h>
#if defined(BSP_USING_HDMI) && defined(RT_USING_SMART)
#include <lwp.h>
#include <lwp_user_mm.h>
#include <hypercall.h>
#include "mbox.h"
#include "drv_hdmi.h"
#define LCD_WIDTH (800)
#define LCD_HEIGHT (480)
#define LCD_DEPTH (32)
#define LCD_BPP (32)
#define TAG_ALLOCATE_BUFFER 0x00040001
#define TAG_SET_PHYS_WIDTH_HEIGHT 0x00048003
#define TAG_SET_VIRT_WIDTH_HEIGHT 0x00048004
#define TAG_SET_DEPTH 0x00048005
#define TAG_SET_PIXEL_ORDER 0x00048006
#define TAG_GET_PITCH 0x00040008
#define TAG_SET_VIRT_OFFSET 0x00048009
#define TAG_END 0x00000000
enum {
MBOX_TAG_FB_GET_GPIOVIRT = 0x00040010,
MBOX_TAG_FB_ALLOCATE_BUFFER = 0x00040001,
MBOX_TAG_FB_RELEASE_BUFFER = 0x00048001,
MBOX_TAG_FB_BLANK_SCREEN = 0x00040002,
MBOX_TAG_FB_GET_PHYS_WH = 0x00040003,
MBOX_TAG_FB_TEST_PHYS_WH = 0x00044003,
MBOX_TAG_FB_SET_PHYS_WH = 0x00048003,
MBOX_TAG_FB_GET_VIRT_WH = 0x00040004,
MBOX_TAG_FB_TEST_VIRT_WH = 0x00044004,
MBOX_TAG_FB_SET_VIRT_WH = 0x00048004,
MBOX_TAG_FB_GET_DEPTH = 0x00040005,
MBOX_TAG_FB_TEST_DEPTH = 0x00044005,
MBOX_TAG_FB_SET_DEPTH = 0x00048005,
MBOX_TAG_FB_GET_PIXEL_ORDER = 0x00040006,
MBOX_TAG_FB_TEST_PIXEL_ORDER = 0x00044006,
MBOX_TAG_FB_SET_PIXEL_ORDER = 0x00048006,
MBOX_TAG_FB_GET_ALPHA_MODE = 0x00040007,
MBOX_TAG_FB_TEST_ALPHA_MODE = 0x00044007,
MBOX_TAG_FB_SET_ALPHA_MODE = 0x00048007,
MBOX_TAG_FB_GET_PITCH = 0x00040008,
MBOX_TAG_FB_GET_VIRT_OFFSET = 0x00040009,
MBOX_TAG_FB_TEST_VIRT_OFFSET = 0x00044009,
MBOX_TAG_FB_SET_VIRT_OFFSET = 0x00048009,
MBOX_TAG_FB_GET_OVERSCAN = 0x0004000a,
MBOX_TAG_FB_TEST_OVERSCAN = 0x0004400a,
MBOX_TAG_FB_SET_OVERSCAN = 0x0004800a,
MBOX_TAG_FB_GET_PALETTE = 0x0004000b,
MBOX_TAG_FB_TEST_PALETTE = 0x0004400b,
MBOX_TAG_FB_SET_PALETTE = 0x0004800b,
};
#define LCD_DEVICE(dev) (struct rt_hdmi_fb_device*)(dev)
static struct rt_hdmi_fb_device _hdmi;
typedef rt_uint16_t color_t;
rt_err_t hdmi_fb_open(rt_device_t dev, rt_uint16_t oflag)
{
return RT_EOK;
}
rt_err_t hdmi_fb_close(rt_device_t dev)
{
return RT_EOK;
}
rt_ssize_t hdmi_fb_read(rt_device_t dev, rt_off_t pos, void *buf, rt_size_t size)
{
return 0;
}
rt_ssize_t hdmi_fb_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
{
return size;
}
rt_err_t hdmi_fb_control(rt_device_t dev, int cmd, void *args)
{
static unsigned long smem_start = 0;
static unsigned long smem_len = 0;
struct rt_hdmi_fb_device *lcd = LCD_DEVICE(dev);
switch (cmd)
{
case RTGRAPHIC_CTRL_RECT_UPDATE:
{
if (smem_start != 0)
{
rt_hw_cpu_dcache_clean_and_invalidate((void *)smem_start, smem_len);
}
}
break;
case RTGRAPHIC_CTRL_GET_INFO:
{
struct rt_device_graphic_info *lcd_info = (struct rt_device_graphic_info *)args;
lcd_info->bits_per_pixel = 32;
lcd_info->pixel_format = RTGRAPHIC_PIXEL_FORMAT_ARGB888; /* should be coherent to adding layers */
lcd_info->width = lcd->width;
lcd_info->height = lcd->height;
lcd_info->framebuffer = (void *)lwp_map_user_phy(lwp_self(), RT_NULL, lcd->fb, lcd->width * lcd->height * sizeof(rt_uint32_t), 1);
}
break;
#define FBIOGET_FSCREENINFO 0x4602
case FBIOGET_FSCREENINFO:
{
struct fb_fix_screeninfo
{
char id[16];
unsigned long smem_start;
uint32_t smem_len;
uint32_t line_length;
} *info = (struct fb_fix_screeninfo *)args;
rt_strncpy(info->id, "lcd", sizeof(info->id));
info->smem_len = lcd->width * lcd->height * sizeof(rt_uint32_t);
info->smem_start = (size_t)lwp_map_user_phy(lwp_self(), RT_NULL, lcd->fb, info->smem_len, 1);
info->line_length = lcd->width * sizeof(rt_uint32_t);
rt_memset((void *)info->smem_start, 0, info->smem_len);
smem_start = info->smem_start;
smem_len = info->smem_len;
}
break;
}
return RT_EOK;
}
#ifdef RT_USING_DEVICE_OPS
const static struct rt_device_ops hdmi_fb_ops =
{
RT_NULL,
hdmi_fb_open,
hdmi_fb_close,
hdmi_fb_read,
hdmi_fb_write,
hdmi_fb_control,
};
#endif
rt_err_t rt_hdmi_fb_device_init(struct rt_hdmi_fb_device *hdmi_fb, const char *name)
{
struct rt_device *device;
RT_ASSERT(hdmi_fb != RT_NULL);
device = &hdmi_fb->parent;
/* set device type */
device->type = RT_Device_Class_Graphic;
/* initialize device interface */
#ifdef RT_USING_DEVICE_OPS
device->ops = &hdmi_fb_ops;
#else
device->init = RT_NULL;
device->open = hdmi_fb_open;
device->close = hdmi_fb_close;
device->read = hdmi_fb_read;
device->write = hdmi_fb_write;
device->control = hdmi_fb_control;
#endif
/* register to device manager */
rt_device_register(device, name, RT_DEVICE_FLAG_RDWR);
return RT_EOK;
}
rt_uint32_t bcm271x_mbox_fb_get_gpiovirt(void)
{
mbox[0] = 8*4; // length of the message
mbox[1] = MBOX_REQUEST; // this is a request message
mbox[2] = MBOX_TAG_FB_GET_GPIOVIRT;
mbox[3] = 4; // buffer size
mbox[4] = 0; // len
mbox[5] = 0; // id
mbox[6] = 0;
mbox[7] = MBOX_TAG_LAST;
mbox_call(8, MMU_DISABLE);
return (mbox[5] & 0x3fffffff);
}
rt_uint32_t bcm271x_mbox_fb_get_pitch(void)
{
mbox[0] = 8*4; // length of the message
mbox[1] = MBOX_REQUEST; // this is a request message
mbox[2] = MBOX_TAG_FB_GET_PITCH;
mbox[3] = 4; // buffer size
mbox[4] = 0; // len
mbox[5] = 0; // id
mbox[6] = 0;
mbox[7] = MBOX_TAG_LAST;
mbox_call(8, MMU_DISABLE);
return mbox[5];
}
void bcm271x_mbox_fb_set_porder(int rgb)
{
mbox[0] = 8*4; // length of the message
mbox[1] = MBOX_REQUEST; // this is a request message
mbox[2] = MBOX_TAG_FB_SET_PIXEL_ORDER;
mbox[3] = 4; // buffer size
mbox[4] = 4; // len
mbox[5] = rgb; // id
mbox[6] = 0;
mbox[7] = MBOX_TAG_LAST;
mbox_call(8, MMU_DISABLE);
}
void bcm271x_mbox_fb_setoffset(int xoffset, int yoffset)
{
mbox[0] = 8*4; // length of the message
mbox[1] = MBOX_REQUEST; // this is a request message
mbox[2] = MBOX_TAG_FB_SET_VIRT_OFFSET;
mbox[3] = 8; // buffer size
mbox[4] = 8; // len
mbox[5] = xoffset; // id
mbox[6] = yoffset;
mbox[7] = MBOX_TAG_LAST;
mbox_call(8, MMU_DISABLE);
}
void bcm271x_mbox_fb_setalpha(int alpha)
{
mbox[0] = 8*4; // length of the message
mbox[1] = MBOX_REQUEST; // this is a request message
mbox[2] = MBOX_TAG_FB_SET_ALPHA_MODE;
mbox[3] = 4; // buffer size
mbox[4] = 4; // len
mbox[5] = alpha; // id
mbox[6] = 0;
mbox[7] = MBOX_TAG_LAST;
mbox_call(8, MMU_DISABLE);
}
void *bcm271x_mbox_fb_alloc(int width, int height, int bpp, int nrender)
{
mbox[0] = 4 * 35;
mbox[1] = MBOX_REQUEST;
mbox[2] = TAG_ALLOCATE_BUFFER;//get framebuffer, gets alignment on request
mbox[3] = 8; //size
mbox[4] = 4; //len
mbox[5] = 4096; //The design of MBOX driver forces us to give the virtual address 0x3C100000
mbox[6] = 0; //FrameBufferInfo.size
mbox[7] = TAG_SET_PHYS_WIDTH_HEIGHT;
mbox[8] = 8;
mbox[9] = 8;
mbox[10] = width;
mbox[11] = height;
mbox[12] = TAG_SET_VIRT_WIDTH_HEIGHT;
mbox[13] = 8;
mbox[14] = 8;
mbox[15] = width;
mbox[16] = height * nrender;
mbox[17] = TAG_SET_DEPTH;
mbox[18] = 4;
mbox[19] = 4;
mbox[20] = bpp;
mbox[21] = TAG_SET_PIXEL_ORDER;
mbox[22] = 4;
mbox[23] = 0;
mbox[24] = 0; //RGB, not BGR preferably
mbox[25] = TAG_GET_PITCH;
mbox[26] = 4;
mbox[27] = 0;
mbox[28] = 0;
mbox[29] = TAG_SET_VIRT_OFFSET;
mbox[30] = 8;
mbox[31] = 8;
mbox[32] = 0;
mbox[33] = 0;
mbox[34] = TAG_END;
mbox_call(8, MMU_DISABLE);
return (void *)((size_t)(mbox[5] & 0x3fffffff));
}
int hdmi_fb_init(void)
{
_hdmi.fb = (rt_uint8_t *)bcm271x_mbox_fb_alloc(LCD_WIDTH, LCD_HEIGHT, LCD_BPP, 1);
if (_hdmi.fb == RT_NULL)
{
rt_kprintf("init hdmi fb err!\n");
return -RT_ERROR;
}
#ifdef BSP_USING_VM_MODE
if (rt_hv_stage2_map((unsigned long)_hdmi.fb, 0x1400000))
{
rt_kprintf("alloc mmio from hyper fail!\n");
return -RT_ERROR;
}
#endif
bcm271x_mbox_fb_setoffset(0, 0);
bcm271x_mbox_fb_set_porder(0);
_hdmi.width = LCD_WIDTH;
_hdmi.height = LCD_HEIGHT;
_hdmi.depth = LCD_DEPTH;
_hdmi.pitch = 0;
_hdmi.pixel_format = RTGRAPHIC_PIXEL_FORMAT_RGB888;
//rt_kprintf("_hdmi.fb is %p\n", _hdmi.fb);
rt_hdmi_fb_device_init(&_hdmi, "lcd");
return 0;
}
INIT_DEVICE_EXPORT(hdmi_fb_init);
#endif /*BSP_USING_HDMI */
/*
* Copyright (c) 2006-2020, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-10-26 bigmagic first version
*/
#ifndef __DRV_HDMI_H__
#define __DRV_HDMI_H__
#define RGB(r, g, b) ((((r))<<16) | (((g))<<8) | ((b)))
struct rt_hdmi_fb_device
{
struct rt_device parent;
rt_uint32_t width;
rt_uint32_t height;
rt_uint32_t depth;
rt_uint32_t pitch;
rt_uint32_t pixel_format;
rt_uint8_t *fb;
};
#endif/* __DRV_HDMI_H__ */
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
* Copyright (c) 2006-2020, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
......@@ -41,7 +41,7 @@
#define SDXC_BLKCNT_EN BIT(1)
#define SDXC_AUTO_CMD12_EN BIT(2)
#define SDXC_AUTO_CMD23_EN BIT(3)
#define SDXC_DAT_DIR BIT(4) // from card to host
#define SDXC_DAT_DIR BIT(4) //from card to host
#define SDXC_MULTI_BLOCK BIT(5)
#define SDXC_CMD_RSPNS_136 BIT(16)
#define SDXC_CMD_RSPNS_48 BIT(17)
......@@ -72,7 +72,7 @@ struct sdhci_cmd_t
struct sdhci_data_t
{
rt_uint8_t *buf;
rt_uint8_t * buf;
rt_uint32_t flag;
rt_uint32_t blksz;
rt_uint32_t blkcnt;
......@@ -80,18 +80,18 @@ struct sdhci_data_t
struct sdhci_t
{
char *name;
char * name;
rt_uint32_t voltages;
rt_uint32_t width;
rt_uint32_t clock;
rt_err_t removeable;
void *sdcard;
void * sdcard;
rt_err_t (*detect)(struct sdhci_t *sdhci);
rt_err_t (*setwidth)(struct sdhci_t *sdhci, rt_uint32_t width);
rt_err_t (*setclock)(struct sdhci_t *sdhci, rt_uint32_t clock);
rt_err_t (*transfer)(struct sdhci_t *sdhci, struct sdhci_cmd_t *cmd, struct sdhci_data_t *dat);
void *priv;
rt_err_t (*detect)(struct sdhci_t * sdhci);
rt_err_t (*setwidth)(struct sdhci_t * sdhci, rt_uint32_t width);
rt_err_t (*setclock)(struct sdhci_t * sdhci, rt_uint32_t clock);
rt_err_t (*transfer)(struct sdhci_t * sdhci, struct sdhci_cmd_t * cmd, struct sdhci_data_t * dat);
void * priv;
};
struct sdhci_pdata_t
......@@ -100,163 +100,148 @@ struct sdhci_pdata_t
};
// EMMC command flags
#define CMD_TYPE_NORMAL (0x00000000)
#define CMD_TYPE_SUSPEND (0x00400000)
#define CMD_TYPE_RESUME (0x00800000)
#define CMD_TYPE_ABORT (0x00c00000)
#define CMD_IS_DATA (0x00200000)
#define CMD_IXCHK_EN (0x00100000)
#define CMD_CRCCHK_EN (0x00080000)
#define CMD_RSPNS_NO (0x00000000)
#define CMD_RSPNS_136 (0x00010000)
#define CMD_RSPNS_48 (0x00020000)
#define CMD_RSPNS_48B (0x00030000)
#define TM_MULTI_BLOCK (0x00000020)
#define TM_DAT_DIR_HC (0x00000000)
#define TM_DAT_DIR_CH (0x00000010)
#define TM_AUTO_CMD23 (0x00000008)
#define TM_AUTO_CMD12 (0x00000004)
#define TM_BLKCNT_EN (0x00000002)
#define TM_MULTI_DATA (CMD_IS_DATA|TM_MULTI_BLOCK|TM_BLKCNT_EN)
#define CMD_TYPE_NORMAL (0x00000000)
#define CMD_TYPE_SUSPEND (0x00400000)
#define CMD_TYPE_RESUME (0x00800000)
#define CMD_TYPE_ABORT (0x00c00000)
#define CMD_IS_DATA (0x00200000)
#define CMD_IXCHK_EN (0x00100000)
#define CMD_CRCCHK_EN (0x00080000)
#define CMD_RSPNS_NO (0x00000000)
#define CMD_RSPNS_136 (0x00010000)
#define CMD_RSPNS_48 (0x00020000)
#define CMD_RSPNS_48B (0x00030000)
#define TM_MULTI_BLOCK (0x00000020)
#define TM_DAT_DIR_HC (0x00000000)
#define TM_DAT_DIR_CH (0x00000010)
#define TM_AUTO_CMD23 (0x00000008)
#define TM_AUTO_CMD12 (0x00000004)
#define TM_BLKCNT_EN (0x00000002)
#define TM_MULTI_DATA (CMD_IS_DATA|TM_MULTI_BLOCK|TM_BLKCNT_EN)
#define RCA_NO (1)
#define RCA_YES (2)
// INTERRUPT register settings
#define INT_AUTO_ERROR (0x01000000)
#define INT_DATA_END_ERR (0x00400000)
#define INT_DATA_CRC_ERR (0x00200000)
#define INT_DATA_TIMEOUT (0x00100000)
#define INT_INDEX_ERROR (0x00080000)
#define INT_END_ERROR (0x00040000)
#define INT_CRC_ERROR (0x00020000)
#define INT_CMD_TIMEOUT (0x00010000)
#define INT_ERR (0x00008000)
#define INT_ENDBOOT (0x00004000)
#define INT_BOOTACK (0x00002000)
#define INT_RETUNE (0x00001000)
#define INT_CARD (0x00000100)
#define INT_READ_RDY (0x00000020)
#define INT_WRITE_RDY (0x00000010)
#define INT_BLOCK_GAP (0x00000004)
#define INT_DATA_DONE (0x00000002)
#define INT_CMD_DONE (0x00000001)
#define INT_ERROR_MASK \
( \
INT_CRC_ERROR | \
INT_END_ERROR | \
INT_INDEX_ERROR | \
INT_DATA_TIMEOUT | \
INT_DATA_CRC_ERR | \
INT_DATA_END_ERR | \
INT_ERR|INT_AUTO_ERROR \
)
#define INT_ALL_MASK \
(\
INT_CMD_DONE | \
INT_DATA_DONE | \
INT_READ_RDY | \
INT_WRITE_RDY | \
INT_ERROR_MASK \
)
#define EMMC_ARG2 (0x00)
#define EMMC_BLKSIZECNT (0x04)
#define EMMC_ARG1 (0x08)
#define EMMC_CMDTM (0x0c)
#define EMMC_RESP0 (0x10)
#define EMMC_RESP1 (0x14)
#define EMMC_RESP2 (0x18)
#define EMMC_RESP3 (0x1c)
#define EMMC_DATA (0x20)
#define EMMC_STATUS (0x24)
#define EMMC_CONTROL0 (0x28)
#define EMMC_CONTROL1 (0x2c)
#define EMMC_INTERRUPT (0x30)
#define EMMC_IRPT_MASK (0x34)
#define EMMC_IRPT_EN (0x38)
#define EMMC_CONTROL2 (0x3c)
#define EMMC_CAPABILITIES_0 (0x40)
#define EMMC_CAPABILITIES_1 (0x44)
#define EMMC_BOOT_TIMEOUT (0x70)
#define EMMC_EXRDFIFO_EN (0x84)
#define EMMC_SPI_INT_SPT (0xf0)
#define EMMC_SLOTISR_VER (0xfc)
#define INT_AUTO_ERROR (0x01000000)
#define INT_DATA_END_ERR (0x00400000)
#define INT_DATA_CRC_ERR (0x00200000)
#define INT_DATA_TIMEOUT (0x00100000)
#define INT_INDEX_ERROR (0x00080000)
#define INT_END_ERROR (0x00040000)
#define INT_CRC_ERROR (0x00020000)
#define INT_CMD_TIMEOUT (0x00010000)
#define INT_ERR (0x00008000)
#define INT_ENDBOOT (0x00004000)
#define INT_BOOTACK (0x00002000)
#define INT_RETUNE (0x00001000)
#define INT_CARD (0x00000100)
#define INT_READ_RDY (0x00000020)
#define INT_WRITE_RDY (0x00000010)
#define INT_BLOCK_GAP (0x00000004)
#define INT_DATA_DONE (0x00000002)
#define INT_CMD_DONE (0x00000001)
#define INT_ERROR_MASK (INT_CRC_ERROR|INT_END_ERROR|INT_INDEX_ERROR| \
INT_DATA_TIMEOUT|INT_DATA_CRC_ERR|INT_DATA_END_ERR| \
INT_ERR|INT_AUTO_ERROR)
#define INT_ALL_MASK (INT_CMD_DONE|INT_DATA_DONE|INT_READ_RDY|INT_WRITE_RDY|INT_ERROR_MASK)
#define EMMC_ARG2 (0x00)
#define EMMC_BLKSIZECNT (0x04)
#define EMMC_ARG1 (0x08)
#define EMMC_CMDTM (0x0c)
#define EMMC_RESP0 (0x10)
#define EMMC_RESP1 (0x14)
#define EMMC_RESP2 (0x18)
#define EMMC_RESP3 (0x1c)
#define EMMC_DATA (0x20)
#define EMMC_STATUS (0x24)
#define EMMC_CONTROL0 (0x28)
#define EMMC_CONTROL1 (0x2c)
#define EMMC_INTERRUPT (0x30)
#define EMMC_IRPT_MASK (0x34)
#define EMMC_IRPT_EN (0x38)
#define EMMC_CONTROL2 (0x3c)
#define EMMC_CAPABILITIES_0 (0x40)
#define EMMC_CAPABILITIES_1 (0x44)
#define EMMC_BOOT_TIMEOUT (0x70)
#define EMMC_EXRDFIFO_EN (0x84)
#define EMMC_SPI_INT_SPT (0xf0)
#define EMMC_SLOTISR_VER (0xfc)
// CONTROL register settings
#define C0_SPI_MODE_EN (0x00100000)
#define C0_HCTL_HS_EN (0x00000004)
#define C0_HCTL_DWITDH (0x00000002)
#define C1_SRST_DATA (0x04000000)
#define C1_SRST_CMD (0x02000000)
#define C1_SRST_HC (0x01000000)
#define C1_TOUNIT_DIS (0x000f0000)
#define C1_TOUNIT_MAX (0x000e0000)
#define C1_CLK_GENSEL (0x00000020)
#define C1_CLK_EN (0x00000004)
#define C1_CLK_STABLE (0x00000002)
#define C1_CLK_INTLEN (0x00000001)
#define FREQ_SETUP (400000) // 400 Khz
#define FREQ_NORMAL (25000000) // 25 Mhz
#define C0_SPI_MODE_EN (0x00100000)
#define C0_HCTL_HS_EN (0x00000004)
#define C0_HCTL_DWITDH (0x00000002)
#define C1_SRST_DATA (0x04000000)
#define C1_SRST_CMD (0x02000000)
#define C1_SRST_HC (0x01000000)
#define C1_TOUNIT_DIS (0x000f0000)
#define C1_TOUNIT_MAX (0x000e0000)
#define C1_CLK_GENSEL (0x00000020)
#define C1_CLK_EN (0x00000004)
#define C1_CLK_STABLE (0x00000002)
#define C1_CLK_INTLEN (0x00000001)
#define FREQ_SETUP (400000) // 400 Khz
#define FREQ_NORMAL (25000000) // 25 Mhz
// SLOTISR_VER values
#define HOST_SPEC_NUM 0x00ff0000
#define HOST_SPEC_NUM_SHIFT 16
#define HOST_SPEC_V3 2
#define HOST_SPEC_V2 1
#define HOST_SPEC_V1 0
#define HOST_SPEC_NUM 0x00ff0000
#define HOST_SPEC_NUM_SHIFT 16
#define HOST_SPEC_V3 2
#define HOST_SPEC_V2 1
#define HOST_SPEC_V1 0
// STATUS register settings
#define SR_DAT_LEVEL1 (0x1e000000)
#define SR_CMD_LEVEL (0x01000000)
#define SR_DAT_LEVEL0 (0x00f00000)
#define SR_DAT3 (0x00800000)
#define SR_DAT2 (0x00400000)
#define SR_DAT1 (0x00200000)
#define SR_DAT0 (0x00100000)
#define SR_WRITE_PROT (0x00080000) // From SDHC spec v2, BCM says reserved
#define SR_READ_AVAILABLE (0x00000800) // ???? undocumented
#define SR_WRITE_AVAILABLE (0x00000400) // ???? undocumented
#define SR_READ_TRANSFER (0x00000200)
#define SR_WRITE_TRANSFER (0x00000100)
#define SR_DAT_ACTIVE (0x00000004)
#define SR_DAT_INHIBIT (0x00000002)
#define SR_CMD_INHIBIT (0x00000001)
#define SR_DAT_LEVEL1 (0x1e000000)
#define SR_CMD_LEVEL (0x01000000)
#define SR_DAT_LEVEL0 (0x00f00000)
#define SR_DAT3 (0x00800000)
#define SR_DAT2 (0x00400000)
#define SR_DAT1 (0x00200000)
#define SR_DAT0 (0x00100000)
#define SR_WRITE_PROT (0x00080000) // From SDHC spec v2, BCM says reserved
#define SR_READ_AVAILABLE (0x00000800) // ???? undocumented
#define SR_WRITE_AVAILABLE (0x00000400) // ???? undocumented
#define SR_READ_TRANSFER (0x00000200)
#define SR_WRITE_TRANSFER (0x00000100)
#define SR_DAT_ACTIVE (0x00000004)
#define SR_DAT_INHIBIT (0x00000002)
#define SR_CMD_INHIBIT (0x00000001)
#define CONFIG_MMC_USE_DMA
#define DMA_ALIGN (32U)
#define SD_CMD_INDEX(a) ((a) << 24)
#define SD_CMD_RESERVED(a) (0xffffffff)
#define SD_CMD_INDEX(a) ((a) << 24)
#define SD_CMD_TYPE_NORMAL (0x0)
#define SD_CMD_TYPE_SUSPEND (1 << 22)
#define SD_CMD_TYPE_RESUME (2 << 22)
#define SD_CMD_TYPE_ABORT (3 << 22)
#define SD_CMD_TYPE_MASK (3 << 22)
#define SD_CMD_ISDATA (1 << 21)
#define SD_CMD_IXCHK_EN (1 << 20)
#define SD_CMD_CRCCHK_EN (1 << 19)
#define SD_CMD_RSPNS_TYPE_NONE (0) // For no response
#define SD_CMD_RSPNS_TYPE_136 (1 << 16) // For response R2 (with CRC), R3,4 (no CRC)
#define SD_CMD_RSPNS_TYPE_48 (2 << 16) // For responses R1, R5, R6, R7 (with CRC)
#define SD_CMD_RSPNS_TYPE_48B (3 << 16) // For responses R1b, R5b (with CRC)
#define SD_CMD_RSPNS_TYPE_MASK (3 << 16)
#define SD_CMD_MULTI_BLOCK (1 << 5)
#define SD_CMD_DAT_DIR_HC (0)
#define SD_CMD_DAT_DIR_CH (1 << 4)
#define DMA_ALIGN (32U)
#define SD_CMD_INDEX(a) ((a) << 24)
#define SD_CMD_RESERVED(a) (0xffffffff)
#define SD_CMD_INDEX(a) ((a) << 24)
#define SD_CMD_TYPE_NORMAL (0x0)
#define SD_CMD_TYPE_SUSPEND (1 << 22)
#define SD_CMD_TYPE_RESUME (2 << 22)
#define SD_CMD_TYPE_ABORT (3 << 22)
#define SD_CMD_TYPE_MASK (3 << 22)
#define SD_CMD_ISDATA (1 << 21)
#define SD_CMD_IXCHK_EN (1 << 20)
#define SD_CMD_CRCCHK_EN (1 << 19)
#define SD_CMD_RSPNS_TYPE_NONE (0) // For no response
#define SD_CMD_RSPNS_TYPE_136 (1 << 16) // For response R2 (with CRC), R3,4 (no CRC)
#define SD_CMD_RSPNS_TYPE_48 (2 << 16) // For responses R1, R5, R6, R7 (with CRC)
#define SD_CMD_RSPNS_TYPE_48B (3 << 16) // For responses R1b, R5b (with CRC)
#define SD_CMD_RSPNS_TYPE_MASK (3 << 16)
#define SD_CMD_MULTI_BLOCK (1 << 5)
#define SD_CMD_DAT_DIR_HC (0)
#define SD_CMD_DAT_DIR_CH (1 << 4)
#define SD_CMD_AUTO_CMD_EN_NONE (0)
#define SD_CMD_AUTO_CMD_EN_CMD12 (1 << 2)
#define SD_CMD_AUTO_CMD_EN_CMD23 (2 << 2)
#define SD_CMD_BLKCNT_EN (1 << 1)
#define SD_CMD_DMA (1)
#define SD_RESP_NONE SD_CMD_RSPNS_TYPE_NONE
#define SD_RESP_R1 (SD_CMD_RSPNS_TYPE_48)
#define SD_RESP_R1b (SD_CMD_RSPNS_TYPE_48B)
#define SD_RESP_R2 (SD_CMD_RSPNS_TYPE_136)
#define SD_RESP_R1 (SD_CMD_RSPNS_TYPE_48) // | SD_CMD_CRCCHK_EN)
#define SD_RESP_R1b (SD_CMD_RSPNS_TYPE_48B) // | SD_CMD_CRCCHK_EN)
#define SD_RESP_R2 (SD_CMD_RSPNS_TYPE_136) // | SD_CMD_CRCCHK_EN)
#define SD_RESP_R3 SD_CMD_RSPNS_TYPE_48
#define SD_RESP_R4 SD_CMD_RSPNS_TYPE_136
#define SD_RESP_R5 (SD_CMD_RSPNS_TYPE_48 | SD_CMD_CRCCHK_EN)
......
此差异已折叠。
此差异已折叠。
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
......@@ -81,26 +81,26 @@
/*
* Auxiliary
*/
#define AUX_IRQ(BASE) HWREG32(BASE + 0x00) /* Auxiliary Interrupt status 3 */
#define AUX_ENABLES(BASE) HWREG32(BASE + 0x04) /* Auxiliary enables 3bit */
#define AUX_MU_IO_REG(BASE) HWREG32(BASE + 0x40) /* Mini Uart I/O Data 8bit */
#define AUX_MU_IER_REG(BASE) HWREG32(BASE + 0x44) /* Mini Uart Interrupt Enable 8bit */
#define AUX_MU_IIR_REG(BASE) HWREG32(BASE + 0x48) /* Mini Uart Interrupt Identify 8bit */
#define AUX_MU_LCR_REG(BASE) HWREG32(BASE + 0x4C) /* Mini Uart Line Control 8bit */
#define AUX_MU_MCR_REG(BASE) HWREG32(BASE + 0x50) /* Mini Uart Modem Control 8bit */
#define AUX_MU_LSR_REG(BASE) HWREG32(BASE + 0x54) /* Mini Uart Line Status 8bit */
#define AUX_MU_MSR_REG(BASE) HWREG32(BASE + 0x58) /* Mini Uart Modem Status 8bit */
#define AUX_MU_SCRATCH(BASE) HWREG32(BASE + 0x5C) /* Mini Uart Scratch 8bit */
#define AUX_MU_CNTL_REG(BASE) HWREG32(BASE + 0x60) /* Mini Uart Extra Control 8bit */
#define AUX_MU_STAT_REG(BASE) HWREG32(BASE + 0x64) /* Mini Uart Extra Status 32bit */
#define AUX_MU_BAUD_REG(BASE) HWREG32(BASE + 0x68) /* Mini Uart Baudrate 16bit */
#define AUX_SPI0_CNTL0_REG(BASE) HWREG32(BASE + 0x80) /* SPI 1 Control register 0 32bit */
#define AUX_SPI0_CNTL1_REG(BASE) HWREG32(BASE + 0x84) /* SPI 1 Control register 1 8bit */
#define AUX_SPI0_STAT_REG(BASE) HWREG32(BASE + 0x88) /* SPI 1 Status 32bit */
#define AUX_SPI0_IO_REG(BASE) HWREG32(BASE + 0x90) /* SPI 1 Data 32bit */
#define AUX_SPI0_PEEK_REG(BASE) HWREG32(BASE + 0x94) /* SPI 1 Peek 16bit */
#define AUX_SPI1_CNTL0_REG(BASE) HWREG32(BASE + 0xC0) /* SPI 2 Control register 0 32bit */
#define AUX_SPI1_CNTL1_REG(BASE) HWREG32(BASE + 0xC4) /* SPI 2 Control register 1 8bit */
#define AUX_IRQ(BASE) HWREG32(BASE + 0x00) /* Auxiliary Interrupt status 3 */
#define AUX_ENABLES(BASE) HWREG32(BASE + 0x04) /* Auxiliary enables 3bit */
#define AUX_MU_IO_REG(BASE) HWREG32(BASE + 0x40) /* Mini Uart I/O Data 8bit */
#define AUX_MU_IER_REG(BASE) HWREG32(BASE + 0x44) /* Mini Uart Interrupt Enable 8bit */
#define AUX_MU_IIR_REG(BASE) HWREG32(BASE + 0x48) /* Mini Uart Interrupt Identify 8bit */
#define AUX_MU_LCR_REG(BASE) HWREG32(BASE + 0x4C) /* Mini Uart Line Control 8bit */
#define AUX_MU_MCR_REG(BASE) HWREG32(BASE + 0x50) /* Mini Uart Modem Control 8bit */
#define AUX_MU_LSR_REG(BASE) HWREG32(BASE + 0x54) /* Mini Uart Line Status 8bit */
#define AUX_MU_MSR_REG(BASE) HWREG32(BASE + 0x58) /* Mini Uart Modem Status 8bit */
#define AUX_MU_SCRATCH(BASE) HWREG32(BASE + 0x5C) /* Mini Uart Scratch 8bit */
#define AUX_MU_CNTL_REG(BASE) HWREG32(BASE + 0x60) /* Mini Uart Extra Control 8bit */
#define AUX_MU_STAT_REG(BASE) HWREG32(BASE + 0x64) /* Mini Uart Extra Status 32bit */
#define AUX_MU_BAUD_REG(BASE) HWREG32(BASE + 0x68) /* Mini Uart Baudrate 16bit */
#define AUX_SPI0_CNTL0_REG(BASE) HWREG32(BASE + 0x80) /* SPI 1 Control register 0 32bit */
#define AUX_SPI0_CNTL1_REG(BASE) HWREG32(BASE + 0x84) /* SPI 1 Control register 1 8bit */
#define AUX_SPI0_STAT_REG(BASE) HWREG32(BASE + 0x88) /* SPI 1 Status 32bit */
#define AUX_SPI0_IO_REG(BASE) HWREG32(BASE + 0x90) /* SPI 1 Data 32bit */
#define AUX_SPI0_PEEK_REG(BASE) HWREG32(BASE + 0x94) /* SPI 1 Peek 16bit */
#define AUX_SPI1_CNTL0_REG(BASE) HWREG32(BASE + 0xC0) /* SPI 2 Control register 0 32bit */
#define AUX_SPI1_CNTL1_REG(BASE) HWREG32(BASE + 0xC4) /* SPI 2 Control register 1 8bit */
int rt_hw_uart_init(void);
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册