[sync] sync code from internal

This commit is contained in:
jzlv 2023-02-24 21:33:12 +08:00
parent e70e482d21
commit dd161b698b
302 changed files with 36006 additions and 27903 deletions

BIN
BouffaloSDK.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 194 KiB

146
README.md
View file

@ -1,26 +1,30 @@
[![License](https://img.shields.io/badge/License-Apache--2.0-brightgreen)](LICENSE)
[![Release](https://img.shields.io/github/v/tag/bouffalolab/bl_mcu_sdk?color=s&label=release)]()
[中文版](README_zh.md)
# Introduction
**bl mcu sdk** is an MCU software development kit provided by the Bouffalo Lab Team, supports all the series of Bouffalo chips.
**BouffaloSDK** is an MCU software development kit provided by the Bouffalo Lab Team, supports all the series of Bouffalo chips.
# SDK Versions & Chip Support
# SDK Architecture
Note1: **drivers before v1.4.5 use v1.0hal + std, the later version will use v2.0 (lhal + soc)**。If you want to use **v1.4.5**, please checkout your branch to [release-v1.4.5](https://github.com/bouffalolab/bl_mcu_sdk/tree/release_v1.4.5).
![SDK Architecture](BouffaloSDK.png)
Note2: due to the non-generic peripherals, the code style and interface name in **soc** are still the previous version, but will be subsequently updated to the new code style.
# Code Directoryies
| CHIP | v1.4.5 | latest |
|:-------------:|:--------:|:-------:|
|BL602/BL604 | √ | √ |
|BL702/BL704/BL706 | √ | √ |
|BL616/BL618 | × | √ |
|BL808 | × | √ |
| Name | Description |
|:---:|:------:|
| bsp/board | clock, pinmux, memoryheap and console init |
| bsp/common | bsp common driver|
| components| components|
|docs | quick start、 api、demo doc|
|drivers/lhal| bouffalo common peripherals drivers which support all the chips|
|drivers/soc| bouffalo non-generic peripherals drivers|
|drivers/rfparam| rf param |
|examples| official samples|
|tools| tools |
## LHAL Support
# LHAL Support
**LHAL** is a low level hal driver for common peripherals designed by Bouffalo Lab, in order to support all the Bouffalo chips with the same api . Also it is convenient for users to use and port to other platforms.
@ -29,17 +33,18 @@ Note**√** means supported ; **×** means not supported; **○** means suppo
| Peripheral | BL602/BL604 | BL702/BL704/BL706 | BL616/BL618 | BL808 |
|:------------:|:--------------:|:--------------------:|:-----------:|:--------:|
| ADC | ○ | √ | √ | ○ |
| CAM | - | √ | √ | √ |
| CAM | - | × | × | × |
| CKS | ○ | √ | √ | ○ |
| DAC | ○ | √ | √ | ○ |
| DMA | ○ | √ | √ | √ |
| EFUSE | √ | √ | √ | √ |
| EFUSE | × | × | × | × |
| EMAC | - | √ | √ | √ |
| FLASH | √ | √ | √ | √ |
| GPIO | ○ | √ | √ | √ |
| I2C | ○ | √ | √ | √ |
| I2C | ○ | √ | √ | ○ |
| I2S | ○ | ○ | √ | ○ |
| IR | ○ | √ | √ | ○ |
| MJPEG | × | | √ | √ |
| MJPEG | × | × | √ | √ |
| PWM_v1 | ○ | √ | - | - |
| PWM_v2 | - | - | √ | √ |
| RTC | ○ | √ | √ | √ |
@ -54,56 +59,6 @@ Note**√** means supported ; **×** means not supported; **○** means suppo
| USB_v2 | - | - | √ | √ |
| WDG | ○ | √ | √ | ○ |
## Code Framework
```
bl_mcu_sdk
├── bsp
│ ├── board
│ │ └── bl602
│ │ └── bl702
│ │ └── bl616
│ │ └── bl808
│ └── common
├── components
│ ├── bflog
│ ├── cherryusb
│ ├── fatfs
│ ├── freertos
│ ├── lua
│ ├── lvgl
│ ├── lwip
│ └── shell
├── docs
├── drivers
│ ├── lhal
│ └── soc
├── examples
│ ├── bflog
│ ├── fatfs
│ ├── freertos
│ ├── helloworld
│ ├── lua
│ ├── lvgl
│ ├── peripherals
│ └── shell
└── tools
└── cmake
└── kconfig
└── make
```
- **bsp/board** : including clock, pinmux, memoryheap and console init
- **bsp/common** : including bsp common driver
- **components** : including third-party components
- **docs** : including docs
- **drivers/lhal** : including bouffalo common peripherals drivers which support all the chips
- **drivers/soc** : including bouffalo non-generic peripherals drivers
- **examples** : including samples
- **tools** : including compiler tools
# Environment Setup
## Toolchain
@ -114,7 +69,7 @@ bl_mcu_sdk
## Command Line Development
Before compiling with the command line, you need to select the corresponding toolchain according to your operating system, configure it to the system environment variables, and install the **make** or **ninja**, then you can do the following. For the details, you can visit [bl mcu sdk Environment Setup](https://bl-mcu-sdk.readthedocs.io/zh_CN/latest/get_started/index.html).
Before compiling with the command line, you need to select the corresponding toolchain according to your operating system, configure it to the system environment variables, and install the **make** or **ninja**, then you can do the following. For the details, you can visit [BouffaloSDK Environment Setup](https://bl-mcu-sdk.readthedocs.io/zh_CN/latest/get_started/index.html).
- Go to the demo directory where you want to compile and there are `main.c` and `Makefile` files in that directory
- Just execute the following command, take **BL616** as an example
@ -133,50 +88,65 @@ cd examples/helloworld
make ninja CHIP=bl616 BOARD=bl616dk
```
```
cd examples/helloworld
make CHIP=bl808 BOARD=bl808dk CPU_ID=m0
```
## CDK Development
TODO
## Debug
Only supports debug with CKLink currently. See [bl mcu sdk Debug Guide](https://bl-mcu-sdk.readthedocs.io/zh_CN/latest/get_started/debug.html).
Only supports debug with CKLink currently. See [BouffaloSDK Debug Guide](https://bl-mcu-sdk.readthedocs.io/zh_CN/latest/get_started/debug.html).
## Firmware Download
We recommend you to use this **BL DevCube** and download firmware with serial.
Note that if you are using linux, linux will deny access to the serial device due to permission issues, so add your own username to `dialout` for easy to use, restart your linux and then take effect. Or add `sudo` before command.
- [Bouffalo Lab Dev Cube](https://dev.bouffalolab.com/download)
- [Bouffalo Lab Dev Cube User Guide](https://bl-mcu-sdk.readthedocs.io/zh_CN/latest/get_started/devcube.html)
```
usermod -aG dialout xxx # xxx is your own name
```
```
cd examples/helloworld
make flash CHIP=chip_name COMX=xxx # chip_name should be bl602/bl702/bl616/bl808/bl606p, COMX in Windows, /dev/ttyxxx in Linux
```
- If you use **BL808** or **BL606P**, you need to add **CPU_ID** with m0 or d0.
```
cd examples/helloworld
make flash CHIP=chip_name CPU_ID=m0 COMX=xxx # chip_name should be bl602/bl702/bl616/bl808/bl606p, COMX in Windows, /dev/ttyxxx in Linux
```
If flash using serial port rather than USB, different USB2TTL chips support different max baudrates, need to pay attention to when flashing.
| chip | baudrate|
|:---:|:------:|
| ch340 | <= 500K |
| cp2102 | <= 2M |
| ft232 | <= 2M |
| bl702 | <= 8M |
| bl616 | <= 10M |
# Resources
## Chip Manual
**Chip Reference Manual** and **Chip Data Manual** are listed on [document](https://github.com/bouffalolab/bl_docs)
**Chip Reference Manual** and **Chip Data Manual** are listed on [document](https://dev.bouffalolab.com/document)
## Documentation Tutorial
To get more bl mcu sdk documentation tutorial, like api manual or peripheral demo and so on, please visit:
To get more BouffaloSDK documentation tutorial, like api manual or peripheral demo and so on, please visit:
- [bl mcu sdk v2.0 documentation tutorial](https://bl-mcu-sdk.readthedocs.io/zh_CN/latest/)
- [bl mcu sdk v1.4.5 documentation tutorial](https://dev.bouffalolab.com/media/doc/sdk/bl_mcu_sdk_en/index.html)
- [BouffaloSDK documentation tutorial](https://bl-mcu-sdk.readthedocs.io/zh_CN/latest/)
## Video Tutorial
- [BL706 MCU Development Series Video Tutorial](https://www.bilibili.com/video/BV1xK4y1P7ur)
TODO
## Forum
Bouffalolab Developer Forum: [https://bbs.bouffalolab.com/](https://bbs.bouffalolab.com/)
# License
**bl mcu sdk** follows the Apache License 2.0 open source license agreement. It can be used in commercial products for free and does not require public private code.
```
/*
* Copyright (c) 2022 Bouffalolab team
*
* SPDX-License-Identifier: Apache-2.0
*/
```

View file

@ -1,26 +1,30 @@
[![License](https://img.shields.io/badge/License-Apache--2.0-brightgreen)](LICENSE)
[![Release](https://img.shields.io/github/v/tag/bouffalolab/bl_mcu_sdk?color=s&label=release)]()
[English Version](README.md)
# 简介
**bl mcu sdk** 是 Bouffalo Lab 提供的 MCU 软件开发包,支持博流智能所有系列芯片。
**BouffaloSDK** 是 Bouffalo Lab 提供的软件开发包,支持博流智能所有系列芯片。
# SDK 版本与芯片支持情况
# SDK 架构
注意1**v1.4.5 版本之前的驱动库使用 1.0 版本hal + std之后的版本都将使用 2.0 版本 (lhal + soc)**。如果使用 **v1.4.5** ,请切换分支到 [release-v1.4.5](https://github.com/bouffalolab/bl_mcu_sdk/tree/release_v1.4.5)。
![SDK Architecture](BouffaloSDK.png)
注意2**soc** 由于是非通用的外设,代码风格和接口名还是延续之前版本,但是后续会更新到新的代码风格。
# 代码目录
| 芯片 | v1.4.5 | latest |
|:-------------:|:--------:|:-------:|
|BL602/BL604 | √ | √ |
|BL702/BL704/BL706 | √ | √ |
|BL616/BL618 | × | √ |
|BL808 | × | √ |
| 名称 | 描述|
|:---:|:------:|
| bsp/board | 包含时钟、引脚、内存管理和 console 的板级初始化 |
| bsp/common | 板级相关的常用外设驱动|
| components| 组件|
|docs | 快速上手、 api、demo 文档|
|drivers/lhal| 博流智能系列芯片通用外设驱动,支持所有系列芯片|
|drivers/soc| 博流智能系列芯片非通用外设驱动|
|drivers/rfparam| 射频参数配置|
|examples| 官方示例代码|
|tools| 工具 |
## LHAL 支持情况
# LHAL 支持
**LHAL** 是博流为统一通用外设接口而设计的驱动库,代码精炼并且支持博流所有系列芯片,方便用户使用和移植到其他平台。
@ -29,17 +33,18 @@
| 外设 | BL602/BL604 | BL702/BL704/BL706 | BL616/BL618 | BL808 |
|:------------:|:--------------:|:--------------------:|:-----------:|:--------:|
| ADC | ○ | √ | √ | ○ |
| CAM | - | √ | √ | √ |
| CAM | - | × | × | × |
| CKS | ○ | √ | √ | ○ |
| DAC | ○ | √ | √ | ○ |
| DMA | ○ | √ | √ | √ |
| EFUSE | | √ | √ | √ |
| EFUSE | × | √ | √ | √ |
| EMAC | - | √ | √ | √ |
| FLASH | √ | √ | √ | √ |
| GPIO | ○ | √ | √ | √ |
| I2C | ○ | √ | √ | √ |
| I2C | ○ | √ | √ | ○ |
| I2S | ○ | ○ | √ | ○ |
| IR | ○ | √ | √ | ○ |
| MJPEG | × | | √ | √ |
| MJPEG | × | × | √ | √ |
| PWM_v1 | ○ | √ | - | - |
| PWM_v2 | - | - | √ | √ |
| RTC | ○ | √ | √ | √ |
@ -54,56 +59,6 @@
| USB_v2 | - | - | √ | √ |
| WDG | ○ | √ | √ | ○ |
# 代码框架
```
bl_mcu_sdk
├── bsp
│ ├── board
│ │ └── bl602
│ │ └── bl702
│ │ └── bl616
│ │ └── bl808
│ └── common
├── components
│ ├── bflog
│ ├── cherryusb
│ ├── fatfs
│ ├── freertos
│ ├── lua
│ ├── lvgl
│ ├── lwip
│ └── shell
├── docs
├── drivers
│ ├── lhal
│ └── soc
├── examples
│ ├── bflog
│ ├── fatfs
│ ├── freertos
│ ├── helloworld
│ ├── lua
│ ├── lvgl
│ ├── peripherals
│ └── shell
└── tools
└── cmake
└── kconfig
└── make
```
- **bsp/board** : 包含时钟、引脚、内存管理和 console 的板级初始化
- **bsp/common** : 存放一些板级相关的常用外设驱动代码
- **components** : 存放第三方库公共组件
- **docs** : 存放教程文档以及其他帮助信息
- **drivers/lhal** : 存放博流智能系列芯片通用外设驱动,支持所有系列芯片
- **drivers/soc** : 存放博流智能系列芯片非通用外设驱动,各个芯片独有的部分
- **examples** : 存放官方提供的示例代码
- **tools** : 存放编译下载相关的工具包
# 环境搭建
## 工具链
@ -114,7 +69,7 @@ bl_mcu_sdk
## 命令行编译
在进行命令行编译之前,需要根据你的操作系统,选择对应的工具链,并配置到系统环境变量,并安装了 **make** 或者 **ninja** 工具,然后才能进行下面操作。更详细的搭建过程,参考 [bl mcu sdk 环境搭建](https://bl-mcu-sdk.readthedocs.io/zh_CN/latest/get_started/index.html).
在进行命令行编译之前,需要根据你的操作系统,选择对应的工具链,并配置到系统环境变量,并安装了 **make** 或者 **ninja** 工具,然后才能进行下面操作。更详细的搭建过程,参考 [BouffaloSDK 环境搭建](https://bl-mcu-sdk.readthedocs.io/zh_CN/latest/get_started/index.html).
- 进入要编译的 demo 目录,且该目录下有 `main.c``Makefile` 文件
- 执行下面命令即可,以 **BL616** 为例
@ -135,7 +90,7 @@ make CHIP=bl808 BOARD=bl808dk CPU_ID=m0
```
cd examples/helloworld
make ninja CHIP=bl616 BOARD=bl616dk
make ninja CHIP=bl808 BOARD=bl808dk CPU_ID=m0
```
## CDK 编译
@ -144,43 +99,52 @@ TODO
## 调试
当前仅支持使用 CKLink 调试。详细参考 [bl mcu sdk 调试指南](https://bl-mcu-sdk.readthedocs.io/zh_CN/latest/get_started/debug.html)。
当前仅支持使用 CKLink 调试。详细参考 [BouffaloSDK 调试指南](https://bl-mcu-sdk.readthedocs.io/zh_CN/latest/get_started/debug.html)。
## 固件烧录
推荐使用 **BL DevCube** 并通过串口进行固件的烧录
需要注意,如果使用的是 linuxlinux 由于权限问题会拒绝访问串口设备,所以,为了方便后续使用,将你自己的用户名添加到 `dialout` 中。然后重启 linux 生效。或者在命令的前面加上 `sudo`
- [Bouffalo Lab Dev Cube](https://dev.bouffalolab.com/download)
- [Bouffalo Lab Dev Cube User Guide](https://bl-mcu-sdk.readthedocs.io/zh_CN/latest/get_started/devcube.html)
```
sudo usermod -aG dialout xxx # xxx 是你自己的用户名
```
```
cd examples/helloworld
make flash CHIP=chip_name COMX=xxx # chip_name should be bl602/bl702/bl616/bl808/bl606p, COMX in Windows, /dev/ttyxxx in Linux
```
- 如果使用 **BL808** 或者 **BL606P** ,需要添加 **CPU_ID**
```
cd examples/helloworld
make flash CHIP=chip_name CPU_ID=m0 COMX=xxx # chip_name should be bl602/bl702/bl616/bl808/bl606p, COMX in Windows, /dev/ttyxxx in Linux
```
如果使用串口烧录而非 USB 烧录,不同的 USB2TTL 芯片支持的最高波特率不一样,烧录的时候需要注意。
| 芯片 | 波特率|
|:---:|:------:|
| ch340 | <= 500K |
| cp2102 | <= 2M |
| ft232 | <= 2M |
| bl702 | <= 8M |
| bl616 | <= 10M |
# 芯片手册
芯片数据手册和参考手册见 [文档](https://github.com/bouffalolab/bl_docs)。
芯片数据手册和参考手册见 [文档](https://dev.bouffalolab.com/document)。
# 文档教程
获取更多 bl mcu sdk 开发相关的教程,如环境搭建、 api 手册、外设 demo 等,请参考:
获取更多 BouffaloSDK 开发相关的教程,如环境搭建、 api 手册、外设 demo 等,请参考:
- [bl mcu sdk v2.0 文档教程](https://bl-mcu-sdk.readthedocs.io/zh_CN/latest/)
- [bl mcu sdk v1.4.5 文档教程](https://dev.bouffalolab.com/media/doc/sdk/bl_mcu_sdk_zh/index.html)
- [BouffaloSDK 文档教程](https://bl-mcu-sdk.readthedocs.io/zh_CN/latest/)
# 视频教程
- [BL706 MCU 开发系列视频教程](https://www.bilibili.com/video/BV1xK4y1P7ur)
TODO
# 论坛
博流开发者交流论坛: [https://bbs.bouffalolab.com/](https://bbs.bouffalolab.com/)
# 许可协议
**bl mcu sdk** 遵循 Apache License 2.0 开源许可协议,可以免费在商业产品中使用,并且不需要公开私有代码。
```
/*
* Copyright (c) 2022 Bouffalolab team
*
* SPDX-License-Identifier: Apache-2.0
*/
```

View file

@ -24,10 +24,21 @@ if(CONFIG_BSP_LCD)
target_sources(app PRIVATE lcd/lcd.c)
target_sources(app PRIVATE lcd/font.c)
target_sources(app PRIVATE lcd/mipi_dbi/bl_mipi_dbi_typeb_pec.c)
target_sources(app PRIVATE lcd/mipi_dbi/bl_mipi_dbi.c)
target_sources(app PRIVATE lcd/mipi_dbi/ili9488_dbi.c)
target_sources(app PRIVATE lcd/mipi_dbi/ili9341_dbi.c)
target_sources(app PRIVATE lcd/spi/bl_spi_hard_4.c)
target_sources(app PRIVATE lcd/spi/ili9341_spi.c)
target_sources(app PRIVATE lcd/spi/ili9488_spi.c)
target_sources(app PRIVATE lcd/spi/st7796_spi.c)
target_sources(app PRIVATE lcd/spi/st7789v_spi.c)
target_sources(app PRIVATE lcd/mipi_dpi/bl_mipi_dpi_pec.c)
target_sources(app PRIVATE lcd/mipi_dpi/standard_dpi.c)
target_sources(app PRIVATE lcd/mipi_dpi/ili9488_dpi.c)
target_sources(app PRIVATE lcd/mipi_dpi/gc9503v_dpi.c)
sdk_add_include_directories(lcd)
endif()

View file

@ -25,6 +25,11 @@
#include "font.h"
#include "bflb_core.h"
#if defined(LCD_RESET_EN)
#include "bflb_gpio.h"
#include "bflb_mtimer.h"
#endif
uint8_t lcd_dir = 0;
uint16_t lcd_max_x = LCD_W - 1, lcd_max_y = LCD_H - 1;
@ -40,11 +45,43 @@ int lcd_init(void)
{
int res;
#if defined(LCD_RESET_EN)
struct bflb_device_s *gpio;
/* gpio init */
gpio = bflb_device_get_by_name("gpio");
bflb_gpio_init(gpio, LCD_RESET_PIN, GPIO_OUTPUT | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_2);
/* lcd reset */
#if LCD_RESET_ACTIVE_LEVEL
bflb_gpio_set(gpio, LCD_RESET_PIN);
#else
bflb_gpio_reset(gpio, LCD_RESET_PIN);
#endif
bflb_mtimer_delay_ms(LCD_RESET_HOLD_MS);
/* lcd recovery */
#if LCD_RESET_ACTIVE_LEVEL
bflb_gpio_reset(gpio, LCD_RESET_PIN);
#else
bflb_gpio_set(gpio, LCD_RESET_PIN);
#endif
bflb_mtimer_delay_ms(LCD_RESET_DELAY);
#endif
res = _LCD_FUNC_DEFINE(init);
return res;
}
static int lcd_async_callback_enable(bool enable)
{
_LCD_FUNC_DEFINE(async_callback_enable, enable);
return 0;
}
int lcd_async_callback_register(void (*callback)(void))
{
_LCD_FUNC_DEFINE(async_callback_register, callback);
@ -281,13 +318,15 @@ int lcd_draw_str_ascii16(uint16_t x, uint16_t y, lcd_color_t color, lcd_color_t
uint8_t ch, temp;
uint16_t x0 = x;
lcd_async_callback_enable(false);
for (uint16_t i = 0; i < num && str[i]; i++) {
if (str[i] < 128) {
// if (x > LCD_W - 8) {
// x = x0;
// y += 16;
// }
if (x > LCD_W - 8 || y > LCD_H - 16)
if (x > lcd_max_x - 8) {
x = x0;
y += 16;
}
if (x > lcd_max_x - 8 || y > lcd_max_y - 16)
break;
ch = str[i];
@ -326,6 +365,8 @@ int lcd_draw_str_ascii16(uint16_t x, uint16_t y, lcd_color_t color, lcd_color_t
}
while (lcd_draw_is_busy()) {
};
lcd_async_callback_enable(true);
return 0;
}
#endif

View file

@ -26,42 +26,15 @@
#include "font.h"
#include "bflb_core.h"
#include "lcd_conf.h"
/* List of supported LCD */
/* mipi dbi interface
LCD_DBI_ILI9488
LCD_DISP_QSPI_GC9C01
*/
/* mipi dpi (RGB) interface
LCD_DPI_ILI9488
LCD_DPI_ST7701S
LCD_DPI_STANDARD
*/
/* mipi dsi vidio interface
LCD_DSI_VIDIO_ILI9881C
*/
/* spi interface
LCD_SPI_ILI9488
LCD_SPI_ILI9481
LCD_SPI_ILI9341
LCD_SPI_ST7796
LCD_SPI_ST7789V
*/
/* Select screen Type */
#define LCD_SPI_ST7789V
/* Do not modify the following */
#define LCD_INTERFACE_SPI 1
#define LCD_INTERFACE_DBI 2
#define LCD_INTERFACE_DPI 3
#define LCD_INTERFACE_DSI_VIDIO 4
/* */
#if defined LCD_DBI_ILI9488
#include "mipi_dbi/ili9488_dbi.h"
@ -71,6 +44,15 @@
#define LCD_COLOR_DEPTH ILI9488_DBI_COLOR_DEPTH
#define _LCD_FUNC_DEFINE(_func, ...) ili9488_dbi_##_func(__VA_ARGS__)
#elif defined LCD_DBI_ILI9341
#include "mipi_dbi/ili9341_dbi.h"
#define LCD_INTERFACE_TYPE LCD_INTERFACE_DBI
#define LCD_W ILI9341_DBI_W
#define LCD_H ILI9341_DBI_H
#define LCD_COLOR_DEPTH ILI9341_DBI_COLOR_DEPTH
#define _LCD_FUNC_DEFINE(_func, ...) ili9341_dbi_##_func(__VA_ARGS__)
#elif defined LCD_DISP_QSPI_GC9C01
#include "disp_qspi/gc9c01_disp_qspi.h"
@ -89,6 +71,15 @@
#define LCD_COLOR_DEPTH ILI9488_DPI_COLOR_DEPTH
#define _LCD_FUNC_DEFINE(_func, ...) ili9488_dpi_##_func(__VA_ARGS__)
#elif defined LCD_DPI_GC9503V
#include "mipi_dpi/gc9503v_dpi.h"
#define LCD_INTERFACE_TYPE LCD_INTERFACE_DPI
#define LCD_W GC9503V_DPI_W
#define LCD_H GC9503V_DPI_H
#define LCD_COLOR_DEPTH GC9503V_DPI_COLOR_DEPTH
#define _LCD_FUNC_DEFINE(_func, ...) gc9503v_dpi_##_func(__VA_ARGS__)
#elif defined LCD_DPI_ST7701S
#include "mipi_dpi/st7701s_dpi.h"

528
bsp/common/lcd/lcd_conf.h Normal file
View file

@ -0,0 +1,528 @@
#ifndef _LCD_CONF_H_
#define _LCD_CONF_H_
#if __has_include("lcd_conf_user.h")
/* User external configuration, User need to use this file as a template */
#include "lcd_conf_user.h"
#else
#warning "There is no user LCD conf file and the default conf will be used"
/* clang-format off */
/* Select screen Type, Optional:
mipi dbi interface
LCD_DBI_ILI9488
mipi dpi (RGB) interface
LCD_DPI_ILI9488
LCD_DPI_GC9503V
LCD_DPI_STANDARD
mipi dsi vidio interface
LCD_DSI_VIDIO_ILI9881C
spi interface
LCD_SPI_ILI9488
LCD_SPI_ILI9341
LCD_SPI_ST7796
LCD_SPI_ST7789V
*/
#define LCD_DBI_ILI9488
/* dbi ili9488 config */
#if defined LCD_DBI_ILI9488
/* Selecting interface type, more configuration of peripherals comes later
1: DBI peripheral, supported functions: typeC-3wire, typeC-4wire, typeB-x8(8080); (support chips: bl616, bl606p, bl808),
2: PEC simulation, supported functions: typeB-x8; (support chips: bl616),
*/
#define LCD_DBI_INTERFACE_TYPE 1
/* enable the lcd reset function
0: Does not care about lcd hard reset
1: use gpio to reset the lcd
*/
#define LCD_RESET_EN 1
/* Selecting pixel format
1: rgb565 (16-bit, output rgb565)
2: nrgb8888 (32-bit, output rgb888)
*/
#define ILI9488_DBI_PIXEL_FORMAT 1
/* ILI9488 LCD width and height */
#define ILI9488_DBI_W 320
#define ILI9488_DBI_H 480
/* The offset of the area can be displayed */
#define ILI9488_DBI_OFFSET_X 0
#define ILI9488_DBI_OFFSET_Y 0
/* Color reversal, Some screens are required
0: disable
1: enable
*/
#define ILI9488_DBI_COLOR_REVERSAL 0
/* dbi ili9341 config */
#elif defined LCD_DBI_ILI9341
/* Selecting interface type, more configuration of peripherals comes later
1: DBI peripheral, supported functions: typeC-3wire, typeC-4wire, typeB-x8(8080); (support chips: bl616, bl606p, bl808),
2: PEC simulation, supported functions: typeB-x8; (support chips: bl616),
*/
#define LCD_DBI_INTERFACE_TYPE 1
/* enable the lcd reset function
0: Does not care about lcd hard reset
1: use gpio to reset the lcd
*/
#define LCD_RESET_EN 1
/* Selecting pixel format
1: rgb565 (16-bit, output rgb565)
2: nrgb8888 (32-bit, output rgb888)
*/
#define ILI9341_DBI_PIXEL_FORMAT 1
/* ILI9341 LCD width and height */
#define ILI9341_DBI_W 240
#define ILI9341_DBI_H 320
/* The offset of the area can be displayed */
#define ILI9341_DBI_OFFSET_X 0
#define ILI9341_DBI_OFFSET_Y 0
/* Color reversal, Some screens are required
0: disable
1: enable
*/
#define ILI9341_DBI_COLOR_REVERSAL 0
#endif
/* dpi gc9503v config */
#if defined LCD_DPI_GC9503V
/* Selecting DPI working mode
1: DPI peripheral (support: bl808)
2: PEC simulation (support: bl616, bl628)
*/
#define GC9503V_DPI_MODE 2
/* Selecting initialization interface
1: Software spi 9-bit mode
*/
#define GC9503V_DPI_INIT_INTERFACE 1
#if(GC9503V_DPI_INIT_INTERFACE == 1)
#define GC9503V_DPI_SPI_CS_PIN GPIO_PIN_12
#define GC9503V_DPI_SPI_CLK_PIN GPIO_PIN_24
#define GC9503V_DPI_SPI_DAT_PIN GPIO_PIN_25
#endif
/* enable the lcd reset function
0: Does not care about lcd hard reset
1: use gpio to reset the lcd
*/
#define LCD_RESET_EN 1
/* Selecting pixel format
1: rgb565 (16-bits)
2: nrgb8888 (32-bits, Do not support PEC simulation)
*/
#define GC9503V_DPI_PIXEL_FORMAT 1
/* ILI9488 LCD width and height */
#define GC9503V_DPI_W 480
#define GC9503V_DPI_H 480
/* dpi ili9488 config */
#elif defined LCD_DPI_ILI9488
/* Selecting DPI working mode
1: DPI peripheral (support: bl808)
2: PEC simulation (support: bl616, bl628)
*/
#define ILI9488_DPI_MODE 2
/* Selecting initialization interface
1: Hardware spi 8-bit mode
2: Hardware dbi peripheral typeC (support: bl616, bl606p, bl808)
*/
#define ILI9488_DPI_INIT_INTERFACE 1
#if(ILI9488_DPI_INIT_INTERFACE == 1)
#define ILI9488_DPI_SPI_CS_PIN GPIO_PIN_20
#define ILI9488_DPI_SPI_DC_PIN GPIO_PIN_3
#endif
/* enable the lcd reset function
0: Does not care about lcd hard reset
1: use gpio to reset the lcd
*/
#define LCD_RESET_EN 1
/* Selecting pixel format
1: rgb565 (16-bits)
2: nrgb8888 (32-bits, Do not support PEC simulation)
*/
#define ILI9488_DPI_PIXEL_FORMAT 1
/* ILI9488 LCD width and height */
#define ILI9488_DPI_W 320
#define ILI9488_DPI_H 480
/* dpi standard config */
#elif defined LCD_DPI_STANDARD
/* Selecting DPI working mode
1: DPI peripheral (support: bl808)
2: PEC simulation (support: bl616, bl628)
*/
#define STANDARD_DPI_MODE 2
/* enable the lcd reset function
0: Does not care about lcd hard reset
1: use gpio to reset the lcd
*/
#define LCD_RESET_EN 0
/* Selecting pixel format
1: rgb565 (16-bits)
2: nrgb8888 (32-bits, Do not support PEC simulation)
*/
#define STANDARD_DPI_PIXEL_FORMAT 1
/* STANDARD LCD width and height */
#define STANDARD_DPI_W 800
#define STANDARD_DPI_H 480
/* RGB timing parameter Settings
Total Width = HSW + HBP + Active_Width + HFP
Total Height = VSW + VBP + Active_Height + VFP */
/* Hsync Pulse Width */
#define STANDARD_DPI_HSW 4
/* Hsync Back Porch */
#define STANDARD_DPI_HBP 82
/* Hsync Front Porch */
#define STANDARD_DPI_HFP 14
/* Vsync Pulse Width */
#define STANDARD_DPI_VSW 5
/* Vsync Back Porch */
#define STANDARD_DPI_VBP 6
/* Vsync Front Porch */
#define STANDARD_DPI_VFP 39
/* Maximum refresh frame rate per second, Used to automatically calculate the clock frequency */
#define STANDARD_DPI_FRAME_RATE 70
/* spi ili9488 config */
#elif defined LCD_SPI_ILI9488
/* Selecting interface type, more configuration of peripherals comes later
1: SPI peripheral, supported functions: spi-4wire,
*/
#define LCD_SPI_INTERFACE_TYPE 1
/* Selecting pixel format
1: rgb565
*/
#define ILI9488_SPI_PIXEL_FORMAT 1
/* enable the lcd reset function
0: Does not care about lcd hard reset
1: use gpio to reset the lcd
*/
#define LCD_RESET_EN 1
/* ILI9488 LCD width and height */
#define ILI9488_SPI_W 320
#define ILI9488_SPI_H 480
/* The offset of the area can be displayed */
#define ILI9488_SPI_OFFSET_X 0
#define ILI9488_SPI_OFFSET_Y 0
/* Color reversal, Some screens are required
0: disable
1: enable
*/
#define ILI9488_SPI_COLOR_REVERSAL 0
/* spi ili9341 config */
#elif defined LCD_SPI_ILI9341
/* Selecting interface type, more configuration of peripherals comes later
1: SPI peripheral, supported functions: spi-4wire,
*/
#define LCD_SPI_INTERFACE_TYPE 1
/* Selecting pixel format
1: rgb565, 16-bit/pixel
*/
#define ILI9341_SPI_PIXEL_FORMAT 1
/* enable the lcd reset function
0: Does not care about lcd hard reset
1: use gpio to reset the lcd
*/
#define LCD_RESET_EN 1
/* LCD width and height */
#define ILI9341_SPI_W 240
#define ILI9341_SPI_H 320
/* The offset of the area can be displayed */
#define ILI9341_SPI_OFFSET_X 0
#define ILI9341_SPI_OFFSET_Y 0
/* Color reversal, Some screens are required
0: disable
1: enable
*/
#define ILI341_SPI_COLOR_REVERSAL 0
/* spi st7789v config */
#elif defined LCD_SPI_ST7789V
/* Selecting interface type, more configuration of peripherals comes later
1: SPI peripheral, supported functions: spi-4wire,
*/
#define LCD_SPI_INTERFACE_TYPE 1
/* Selecting pixel format
1: rgb565
*/
#define ST7789V_SPI_PIXEL_FORMAT 1
/* enable the lcd reset function
0: Does not care about lcd hard reset
1: use gpio to reset the lcd
*/
#define LCD_RESET_EN 1
/* LCD width and height */
#define ST7789V_SPI_W 320
#define ST7789V_SPI_H 480
/* The offset of the area can be displayed */
#define ST7789V_SPI_OFFSET_X 0
#define ST7789V_SPI_OFFSET_Y 0
/* spi st7796 config */
#elif defined LCD_SPI_ST7796
/* Selecting interface type, more configuration of peripherals comes later
1: SPI peripheral, supported functions: spi-4wire,
*/
#define LCD_SPI_INTERFACE_TYPE 1
/* Selecting pixel format
1: rgb565
*/
#define ST7796_SPI_PIXEL_FORMAT 1
/* enable the lcd reset function
0: Does not care about lcd hard reset
1: use gpio to reset the lcd
*/
#define LCD_RESET_EN 1
/* LCD width and height */
#define ST7796_SPI_W 320
#define ST7796_SPI_H 480
/* The offset of the area can be displayed */
#define ST7796_SPI_OFFSET_X 0
#define ST7796_SPI_OFFSET_Y 0
/* Color reversal, Some screens are required
0: disable
1: enable
*/
#define ST7796_SPI_COLOR_REVERSAL 0
#endif
/********** PEC simulation DPI configuration **********/
#if ((defined ILI9488_DPI_MODE) && (ILI9488_DPI_MODE == 2)) || \
((defined GC9503V_DPI_MODE) && (GC9503V_DPI_MODE == 2)) || \
((defined STANDARD_DPI_MODE) && (STANDARD_DPI_MODE == 2))
/* supports 16-wire and 8-wire-latch output modes */
/* For internal use, do not modify */
#define LCD_PEC_SIMU_DPI_ENABLE
/* dma used by pec */
#define LCD_PEC_DPI_DMA_NAME "dma0_ch3"
/* The mode of data latch.
0: 16-bit *1-cycle date out;
1: 8-bit *2-cycle date out, Low 8-bit latch, high 8-bit pass-through, Additional latch devices are required */
#define LCD_PEC_DPI_DATA_LATCH_MODE 1
/* enable the lcd reset function
0: Does not care about lcd hard reset
1: use gpio to reset the lcd
*/
#define LCD_RESET_EN 1
/* Signal polarity selection */
#define LCD_PEC_DPI_V_SYNC_SIN_POL 0
#define LCD_PEC_DPI_H_SYNC_SIN_POL 0
#define LCD_PEC_DPI_DE_SIN_POL 1
/* Selecting pin
The numbers of some pins must be consecutive, and cannot cross the 32 boundary.
Rules: PIN_DE = PIN_CLK + 1; PIN_LATCH = PIN_CLK + 2;
PIN_VSYNC = PIN_HSYNC + 1;
PIN_DATA_n = PIN_DATA_START + n;
*/
#define LCD_DPI_PEC_SIMU_PIN_CLK GPIO_PIN_32
#define LCD_DPI_PEC_SIMU_PIN_HSYNC GPIO_PIN_18
#define LCD_DPI_PEC_SIMU_PIN_DATA_START GPIO_PIN_24 /* 8-wire(latch mode) or 16-wire */
/* Maximum number of DPI invalid rows, >= (VHW + VBP + VFP) */
#define LCD_DPI_PEC_INVALID_LIN_MAX 300
/* cache num of dma_lli, >= 2,
Performance is best when the value is no less than the number of disp_buffs used */
#define LCD_DPI_PEC_DMA_LLI_CACHE_NUM 3
#endif
/********** DBI peripheral configuration ***********/
#if (defined(LCD_DBI_INTERFACE_TYPE) && (LCD_DBI_INTERFACE_TYPE == 1))
/* Select the working mode of DBI
1: DBI TypeC 4-wire mode
2: DBI TypeC 3-wire mode
3: DBI TypeB x8 mode (8080)
4: DBI QSPI mode (Not the mipi standard. Extra support for QSPI mode)
*/
#define LCD_DBI_WORK_MODE 1
/* dma used by DBI */
#define LCD_DBI_DMA_NAME "dma0_ch3"
/* The maximum amount of data to be transferred affects the number of LLI memory pools */
#define DBI_DBI_DATA_SIZE_MAX (800 * 640 * 4)
/* pin cfg */
#if(LCD_DBI_WORK_MODE == 1)
#define LCD_DBI_TYPEC_PIN_CLK GPIO_PIN_12
#define LCD_DBI_TYPEC_PIN_CS GPIO_PIN_13
#define LCD_DBI_TYPEC_PIN_DAT GPIO_PIN_14
#define LCD_DBI_TYPEC_PIN_DC GPIO_PIN_15
#elif(LCD_DBI_WORK_MODE == 2)
#define LCD_DBI_TYPEC_PIN_CLK GPIO_PIN_12
#define LCD_DBI_TYPEC_PIN_CS GPIO_PIN_13
#define LCD_DBI_TYPEC_PIN_DAT GPIO_PIN_14
#elif(LCD_DBI_WORK_MODE == 3)
#define LCD_DBI_TYPEB_PIN_WR GPIO_PIN_4
#define LCD_DBI_TYPEB_PIN_CS GPIO_PIN_5
#define LCD_DBI_TYPEB_PIN_RD GPIO_PIN_6
#define LCD_DBI_TYPEB_PIN_DC GPIO_PIN_7
#define LCD_DBI_TYPEB_PIN_DAT0 GPIO_PIN_8
#define LCD_DBI_TYPEB_PIN_DAT1 GPIO_PIN_9
#define LCD_DBI_TYPEB_PIN_DAT2 GPIO_PIN_10
#define LCD_DBI_TYPEB_PIN_DAT3 GPIO_PIN_11
#define LCD_DBI_TYPEB_PIN_DAT4 GPIO_PIN_12
#define LCD_DBI_TYPEB_PIN_DAT5 GPIO_PIN_13
#define LCD_DBI_TYPEB_PIN_DAT6 GPIO_PIN_14
#define LCD_DBI_TYPEB_PIN_DAT7 GPIO_PIN_15
#elif(LCD_DBI_WORK_MODE == 4)
#define LCD_DBI_QSPI_PIN_CLK GPIO_PIN_10
#define LCD_DBI_QSPI_PIN_CS GPIO_PIN_11
#define LCD_DBI_QSPI_PIN_DAT0 GPIO_PIN_12
#define LCD_DBI_QSPI_PIN_DAT1 GPIO_PIN_13
#define LCD_DBI_QSPI_PIN_DAT2 GPIO_PIN_14
#define LCD_DBI_QSPI_PIN_DAT3 GPIO_PIN_15
#endif
#endif
/********** PEC simulation DBI configuration ***********/
#if (defined(LCD_DBI_INTERFACE_TYPE) && (LCD_DBI_INTERFACE_TYPE == 2))
/* pec simulation mipi-dbi-typeB config, only 8-wire is supported, the read operation is not supported */
/* dma used by pec */
#define LCD_PEC_DBI_B_DMA_NAME "dma0_ch3"
/* The maximum amount of data to be transferred affects the number of LLI memory pools */
#define DBI_PEC_DBI_DATA_SIZE_MAX (800 * 640 * 4)
/* Selecting pin */
#define LCD_DBI_PEC_SIMU_PIN_DC GPIO_PIN_23
#define LCD_DBI_PEC_SIMU_PIN_WR GPIO_PIN_34
#define LCD_DBI_PEC_SIMU_PIN_DATA GPIO_PIN_24 /* The lowest line of an 8-bit data line */
#endif
/********** SPI hard 4-wire configuration ***********/
#if (defined(LCD_SPI_INTERFACE_TYPE) && (LCD_SPI_INTERFACE_TYPE == 1))
/* spi idx */
#define LCD_SPI_HARD_4_NAME "spi0"
/* dma used by spi */
#define LCD_SPI_HARD_4_DMA_NAME "dma0_ch3"
/* The maximum pixel cnt to be transferred affects the number of LLI memory pools */
#define LCD_SPI_HARD_4_PIXEL_CNT_MAX (800 * 640)
/* spi pin, hardware controlled */
#define LCD_SPI_HARD_4_PIN_CLK GPIO_PIN_13
#define LCD_SPI_HARD_4_PIN_DAT GPIO_PIN_15
/* cs/dc pin, software controlled */
#define LCD_SPI_HARD_4_PIN_CS GPIO_PIN_14
#define LCD_SPI_HARD_4_PIN_DC GPIO_PIN_16
#endif
/********** lcd reset configuration ***********/
#if (defined(LCD_RESET_EN) && LCD_RESET_EN)
/* lcd reset signal pin, please leave blank if not needed */
#define LCD_RESET_PIN GPIO_PIN_12
/* lcd reset signal active level
0: lcd reset at low level
1: lcd reset at high level
*/
#define LCD_RESET_ACTIVE_LEVEL 0
/* lcd reset active hold time (ms) */
#define LCD_RESET_HOLD_MS 10
/* lcd recovery time after reset end (ms) */
#define LCD_RESET_DELAY 100
#endif
#endif
/* clang-format on */
#endif

View file

@ -0,0 +1,303 @@
#include "../lcd.h"
#if (defined(LCD_DBI_INTERFACE_TYPE) && (LCD_DBI_INTERFACE_TYPE == 1))
#if (__has_include("bflb_dbi.h"))
#if ((LCD_DBI_WORK_MODE == 4) && (DBI_QSPI_SUPPORT == 0))
#error : "The DBI of this chip does not support QSPI mode."
#endif
#include "bl_mipi_dbi.h"
#include "bflb_dbi.h"
#include "bflb_dma.h"
#include "bflb_gpio.h"
#include "bflb_l1c.h"
#define LCD_DBI_DMA_LLI_NUM (DBI_DBI_DATA_SIZE_MAX / 4 / 4064 + 1)
/* asynchronous flush interrupt callback */
typedef void (*dbi_callback)(void);
static volatile dbi_callback dbi_async_callback = NULL;
static volatile bool dbi_async_callback_en_flag = true;
/* dma device */
static struct bflb_device_s *dbi_dma_hd;
/* pec dbi typeB device */
static struct bflb_device_s *dbi_hd;
/* The memory space of DMA */
static struct bflb_dma_channel_lli_pool_s dma_tx_llipool[LCD_DBI_DMA_LLI_NUM];
static struct bflb_dma_channel_lli_transfer_s dma_tx_transfers[1];
static volatile bool dbi_async_flag = false;
static volatile bool dbi_async_cycle_fill_flag = false;
static void dbi_tc_callback(int irq, void *arg)
{
/* disable dbi dma */
bflb_dbi_link_txdma(dbi_hd, false);
/* clear flag and mask int */
bflb_dbi_int_clear(dbi_hd, DBI_INTCLR_TC);
bflb_dbi_tcint_mask(dbi_hd, true);
if (dbi_async_flag == false && dbi_async_cycle_fill_flag == false) {
return;
}
if (dbi_async_cycle_fill_flag == true) {
/* enable dma addr increment */
bflb_dma_feature_control(dbi_dma_hd, DMA_CMD_SET_SRCADDR_INCREMENT, true);
}
/* disable DMA request for dbi */
bflb_dbi_link_txdma(dbi_hd, false);
dbi_async_flag = false;
dbi_async_cycle_fill_flag = false;
/* async callback */
if (dbi_async_callback_en_flag && dbi_async_callback != NULL) {
dbi_async_callback();
}
}
int lcd_dbi_async_callback_register(void (*callback)(void))
{
dbi_async_callback = callback;
return 0;
}
int lcd_dbi_async_callback_enable(bool enable)
{
dbi_async_callback_en_flag = enable;
return 0;
}
int lcd_dbi_init(lcd_dbi_init_t *dbi_parra)
{
struct bflb_device_s *gpio;
/* dbi cfg */
struct bflb_dbi_config_s dbi_cfg = {
.clk_mode = DBI_CLOCK_MODE_1,
.clk_freq_hz = dbi_parra->clock_freq,
.tx_fifo_threshold = 3,
#if (LCD_DBI_WORK_MODE == 4)
.cmd_wire_mode = dbi_parra->cmd_wire_dual_en,
.addr_wire_mode = dbi_parra->addr_wire_dual_en,
.data_wire_mode = dbi_parra->data_wire_dual_en,
#endif
};
/* dma cfg */
struct bflb_dma_channel_config_s dma_dbi_config = {
.direction = DMA_MEMORY_TO_PERIPH,
.src_req = DMA_REQUEST_NONE,
.dst_req = DMA_REQUEST_DBI_TX,
.src_addr_inc = DMA_ADDR_INCREMENT_ENABLE,
.dst_addr_inc = DMA_ADDR_INCREMENT_DISABLE,
.src_burst_count = DMA_BURST_INCR4,
.dst_burst_count = DMA_BURST_INCR4,
.src_width = DMA_DATA_WIDTH_32BIT,
.dst_width = DMA_DATA_WIDTH_32BIT,
};
#if (LCD_DBI_WORK_MODE == 1)
/* dbi typeC 4-wire mode */
dbi_cfg.dbi_mode = DBI_MODE_TYPE_C_4_WIRE;
uint32_t dbi_gpio_func = GPIO_FUNC_DBI_C;
uint8_t dbi_gpio_list[] = { LCD_DBI_TYPEC_PIN_CLK, LCD_DBI_TYPEC_PIN_CS, LCD_DBI_TYPEC_PIN_DAT, LCD_DBI_TYPEC_PIN_DC };
#elif (LCD_DBI_WORK_MODE == 2)
/* dbi typeC 3-wire mode */
dbi_cfg.dbi_mode = DBI_MODE_TYPE_C_3_WIRE;
uint32_t dbi_gpio_func = GPIO_FUNC_DBI_C;
uint8_t dbi_gpio_list[] = { LCD_DBI_TYPEC_PIN_CLK, LCD_DBI_TYPEC_PIN_CS, LCD_DBI_TYPEC_PIN_DAT };
#elif (LCD_DBI_WORK_MODE == 3)
/* dbi typeB x8 mode */
dbi_cfg.dbi_mode = DBI_MODE_TYPE_B;
uint32_t dbi_gpio_func = GPIO_FUNC_DBI_B;
uint8_t dbi_gpio_list[] = { LCD_DBI_TYPEB_PIN_WR, LCD_DBI_TYPEB_PIN_CS, LCD_DBI_TYPEB_PIN_RD, LCD_DBI_TYPEB_PIN_DC,
LCD_DBI_TYPEB_PIN_DAT0, LCD_DBI_TYPEB_PIN_DAT1, LCD_DBI_TYPEB_PIN_DAT2, LCD_DBI_TYPEB_PIN_DAT3,
LCD_DBI_TYPEB_PIN_DAT4, LCD_DBI_TYPEB_PIN_DAT5, LCD_DBI_TYPEB_PIN_DAT6, LCD_DBI_TYPEB_PIN_DAT7 };
#elif (LCD_DBI_WORK_MODE == 4)
/* dbi Ex QSPI */
dbi_cfg.dbi_mode = DBI_MODE_EX_QSPI;
uint32_t dbi_gpio_func = GPIO_FUNC_DBI_QSPI;
uint8_t dbi_gpio_list[] = { LCD_DBI_QSPI_PIN_CLK, LCD_DBI_QSPI_PIN_CS,
LCD_DBI_QSPI_PIN_DAT0, LCD_DBI_QSPI_PIN_DAT1, LCD_DBI_QSPI_PIN_DAT2, LCD_DBI_QSPI_PIN_DAT3 };
#endif
if (dbi_parra->pixel_format == LCD_DBI_LCD_PIXEL_FORMAT_RGB565) {
dbi_cfg.pixel_input_format = DBI_PIXEL_INPUT_FORMAT_RGB_565;
dbi_cfg.pixel_output_format = DBI_PIXEL_OUTPUT_FORMAT_RGB_565;
} else if (dbi_parra->pixel_format == LCD_DBI_LCD_PIXEL_FORMAT_NRGB8888) {
dbi_cfg.pixel_input_format = DBI_PIXEL_INPUT_FORMAT_NRGB_8888;
dbi_cfg.pixel_output_format = DBI_PIXEL_INPUT_FORMAT_NRGB_8888;
}
/* gpio init */
gpio = bflb_device_get_by_name("gpio");
for (uint8_t i = 0; i < sizeof(dbi_gpio_list) / sizeof(dbi_gpio_list[0]); i++) {
bflb_gpio_init(gpio, dbi_gpio_list[i], dbi_gpio_func | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_2);
}
/* dbi init */
dbi_hd = bflb_device_get_by_name("dbi");
bflb_dbi_init(dbi_hd, &dbi_cfg);
/* cs continuous mode */
bflb_dbi_feature_control(dbi_hd, DBI_CMD_CS_CONTINUE, true);
/* dbi tx intertupt init */
bflb_dbi_tcint_mask(dbi_hd, true);
bflb_irq_attach(dbi_hd->irq_num, dbi_tc_callback, NULL);
bflb_irq_enable(dbi_hd->irq_num);
/* dma init */
dbi_dma_hd = bflb_device_get_by_name(LCD_DBI_DMA_NAME);
bflb_dma_channel_init(dbi_dma_hd, &dma_dbi_config);
return 0;
}
#if (LCD_DBI_WORK_MODE == 4)
int lcd_dbi_ex_qspi_addr_cfg(uint8_t addr_byte_size, uint32_t addr_val)
{
bflb_dbi_qspi_set_addr(dbi_hd, addr_byte_size, addr_val);
return 0;
}
#endif
int lcd_dbi_is_busy(void)
{
if (dbi_async_flag || dbi_async_cycle_fill_flag) {
return 1;
} else {
return 0;
}
}
int lcd_dbi_transmit_cmd_para(uint8_t cmd, uint32_t *para, size_t para_num)
{
bflb_dbi_send_cmd_data(dbi_hd, cmd, para_num, (void *)para);
return 0;
}
int lcd_dbi_transmit_cmd_pixel_sync(uint8_t cmd, uint32_t *pixel, size_t pixel_num)
{
bflb_dbi_send_cmd_pixel(dbi_hd, cmd, pixel_num, (void *)pixel);
return 0;
}
int lcd_dbi_transmit_cmd_pixel_async(uint8_t cmd, uint32_t *pixel, size_t pixel_num)
{
uint32_t data_size;
dbi_async_flag = true;
/* get data size */
data_size = bflb_dbi_feature_control(dbi_hd, DBI_CMD_GET_SIZE_OF_PIXEL_CNT, pixel_num);
/* dma transfers cfg */
dma_tx_transfers[0].src_addr = (uint32_t)pixel;
dma_tx_transfers[0].dst_addr = DMA_ADDR_DBI_TDR;
dma_tx_transfers[0].nbytes = data_size;
bflb_dma_channel_lli_reload(dbi_dma_hd, dma_tx_llipool, LCD_DBI_DMA_LLI_NUM, dma_tx_transfers, 1);
/* clean cache */
bflb_l1c_dcache_clean_range((void *)pixel, data_size);
/* trigger dbi data transfer */
bflb_dbi_send_cmd_pixel(dbi_hd, cmd, pixel_num, NULL);
/* unmask int */
bflb_dbi_tcint_mask(dbi_hd, false);
/* enabled DMA request for dbi */
bflb_dbi_link_txdma(dbi_hd, true);
/* enable dma */
bflb_dma_channel_start(dbi_dma_hd);
return 0;
}
int lcd_dbi_transmit_cmd_pixel_fill_sync(uint8_t cmd, uint32_t pixel_val, size_t pixel_num)
{
uint32_t words_cnt;
uint8_t fifo_cnt;
/* get data size */
words_cnt = bflb_dbi_feature_control(dbi_hd, DBI_CMD_GET_SIZE_OF_PIXEL_CNT, pixel_num) / 4;
/* trigger dbi data transfer */
bflb_dbi_send_cmd_pixel(dbi_hd, cmd, pixel_num, NULL);
/* fill data into fifo */
for (; words_cnt > 0;) {
fifo_cnt = bflb_dbi_feature_control(dbi_hd, DBI_CMD_GET_TX_FIFO_CNT, 0);
fifo_cnt = words_cnt > fifo_cnt ? fifo_cnt : words_cnt;
words_cnt -= fifo_cnt;
for (; fifo_cnt > 0; fifo_cnt--) {
putreg32(pixel_val, DMA_ADDR_DBI_TDR);
}
}
/* wait transfer complete */
while ((bflb_dbi_get_intstatus(dbi_hd) & DBI_INTSTS_TC) == 0) {
};
/* clear end flag */
bflb_dbi_int_clear(dbi_hd, DBI_INTCLR_TC);
return 0;
}
int lcd_dbi_transmit_cmd_pixel_fill_async(uint8_t cmd, uint32_t pixel_val, size_t pixel_num)
{
uint32_t data_size;
dbi_async_cycle_fill_flag = true;
/* get data size */
data_size = bflb_dbi_feature_control(dbi_hd, DBI_CMD_GET_SIZE_OF_PIXEL_CNT, pixel_num);
/* dma cycle fill mode */
bflb_dma_feature_control(dbi_dma_hd, DMA_CMD_SET_SRCADDR_INCREMENT, false);
/* dma transfers cfg */
dma_tx_transfers[0].src_addr = (uint32_t)&pixel_val;
dma_tx_transfers[0].dst_addr = DMA_ADDR_DBI_TDR;
dma_tx_transfers[0].nbytes = data_size;
bflb_dma_channel_lli_reload(dbi_dma_hd, dma_tx_llipool, LCD_DBI_DMA_LLI_NUM, dma_tx_transfers, 1);
/* clean cache */
bflb_l1c_dcache_clean_range((void *)&pixel_val, sizeof(pixel_val));
/* trigger dbi data transfer */
bflb_dbi_send_cmd_pixel(dbi_hd, cmd, pixel_num, NULL);
/* unmask int */
bflb_dbi_tcint_mask(dbi_hd, false);
/* enabled DMA request for dbi */
bflb_dbi_link_txdma(dbi_hd, true);
/* enable dma */
bflb_dma_channel_start(dbi_dma_hd);
return 0;
}
#else
#error "Devices that do not support PEC-DBI! Replace the driver port (lcd_conf.h)"
#endif
#endif

View file

@ -0,0 +1,42 @@
#ifndef _BL_MIPI_DBI_PORT_H
#define _BL_MIPI_DBI_PORT_H
#include "../lcd_conf.h"
#if (defined(LCD_DBI_INTERFACE_TYPE) && (LCD_DBI_INTERFACE_TYPE == 1))
/* Do not modify this file ! */
/* Optional pixel format */
#define LCD_DBI_LCD_PIXEL_FORMAT_RGB565 1
#define LCD_DBI_LCD_PIXEL_FORMAT_NRGB8888 2
typedef struct {
uint32_t pixel_format;
uint32_t clock_freq; /* No use */
#if (LCD_DBI_WORK_MODE == 4)
uint8_t cmd_wire_dual_en;
uint8_t addr_wire_dual_en;
uint8_t data_wire_dual_en;
#endif
} lcd_dbi_init_t;
int lcd_dbi_init(lcd_dbi_init_t *dbi_parra);
#if (LCD_DBI_WORK_MODE == 4)
int lcd_dbi_ex_qspi_addr_cfg(uint8_t addr_byte_size, uint32_t addr_val);
#endif
int lcd_dbi_transmit_cmd_para(uint8_t cmd, uint32_t *para, size_t para_num);
int lcd_dbi_transmit_cmd_pixel_sync(uint8_t cmd, uint32_t *pixel, size_t pixel_num);
int lcd_dbi_transmit_cmd_pixel_fill_sync(uint8_t cmd, uint32_t pixel_val, size_t pixel_num);
int lcd_dbi_is_busy(void);
int lcd_dbi_async_callback_enable(bool enable);
int lcd_dbi_async_callback_register(void (*callback)(void));
int lcd_dbi_transmit_cmd_pixel_async(uint8_t cmd, uint32_t *pixel, size_t pixel_num);
int lcd_dbi_transmit_cmd_pixel_fill_async(uint8_t cmd, uint32_t pixel_val, size_t pixel_num);
#endif
#endif

View file

@ -0,0 +1,375 @@
#include "../lcd.h"
#if (defined(LCD_DBI_INTERFACE_TYPE) && (LCD_DBI_INTERFACE_TYPE == 2))
#if (defined(BL616) && __has_include("bflb_pec_ip.h"))
#include "bl_mipi_dbi_typeb_pec.h"
#include "bflb_pec_ip.h"
#include "bflb_dma.h"
#include "bflb_gpio.h"
#include "bflb_l1c.h"
#define LCD_DBI_PEC_DMA_LLI_NUM (DBI_PEC_DBI_DATA_SIZE_MAX / 4 / 4064 + 1)
/* asynchronous flush interrupt callback */
typedef void (*pec_dbi_b_callback)(void);
static volatile pec_dbi_b_callback pec_dbi_b_async_callback = NULL;
static volatile bool pec_dbi_b_async_callback_en_flag = true;
/* dma device */
static struct bflb_device_s *pec_dbi_b_dma_handle;
static struct bflb_dma_channel_config_s dma_pec_config;
/* pec dbi typeB device */
static struct bflb_pec_dbi_b_s pec_dbi_b_handle;
/* The memory space of DMA */
static struct bflb_dma_channel_lli_pool_s dma_tx_llipool[LCD_DBI_PEC_DMA_LLI_NUM];
static struct bflb_dma_channel_lli_transfer_s dma_tx_transfers[1];
static volatile uint32_t pixel_format;
static volatile bool pec_dbi_b_async_flag = false;
static volatile bool pec_dbi_b_async_cycle_fill_flag = false;
/**
* @brief pec_dbi_b_dma_flush_callback
*
* @return
*/
static void pec_dbi_b_dma_flush_callback(void *args)
{
/* disable pec dma */
bflb_pec_dbi_b_dma_enable(&pec_dbi_b_handle, false);
if (pec_dbi_b_async_flag == false && pec_dbi_b_async_cycle_fill_flag == false) {
return;
}
if (pec_dbi_b_async_cycle_fill_flag == true) {
/* enable dma addr increment */
bflb_dma_feature_control(pec_dbi_b_dma_handle, DMA_CMD_SET_SRCADDR_INCREMENT, true);
}
pec_dbi_b_async_flag = false;
pec_dbi_b_async_cycle_fill_flag = false;
/* async callback */
if (pec_dbi_b_async_callback_en_flag && pec_dbi_b_async_callback != NULL) {
pec_dbi_b_async_callback();
}
}
/**
* @brief pec_dbi_b_async_callback_register
*
* @return int
*/
int pec_dbi_b_async_callback_register(void (*callback)(void))
{
pec_dbi_b_async_callback = callback;
return 0;
}
/**
* @brief pec_dbi_b_async_callback_enable
*
* @return int
*/
int pec_dbi_b_async_callback_enable(bool enable)
{
pec_dbi_b_async_callback_en_flag = enable;
return 0;
}
/**
* @brief pec_dbi_b_init
*
* @return int
*/
int pec_dbi_b_init(lcd_mipi_dbi_init_t *dbi_parra)
{
/* pec gpio init */
struct bflb_device_s *gpio;
gpio = bflb_device_get_by_name("gpio");
bflb_gpio_init(gpio, LCD_DBI_PEC_SIMU_PIN_DC, GPIO_FUNC_PEC | GPIO_ALTERNATE | GPIO_PULLDOWN | GPIO_SMT_EN | GPIO_DRV_2);
bflb_gpio_init(gpio, LCD_DBI_PEC_SIMU_PIN_WR, GPIO_FUNC_PEC | GPIO_ALTERNATE | GPIO_PULLDOWN | GPIO_SMT_EN | GPIO_DRV_2);
for (uint8_t i = 0; i < 8; i++) {
bflb_gpio_init(gpio, LCD_DBI_PEC_SIMU_PIN_DATA + i, GPIO_FUNC_PEC | GPIO_ALTERNATE | GPIO_PULLDOWN | GPIO_SMT_EN | GPIO_DRV_2);
}
/* pec init */
pec_dbi_b_handle.clk_src = 40 * 1000 * 1000;
pec_dbi_b_handle.clk = 10 * 1000 * 1000;
pixel_format = dbi_parra->pixel_format;
if (pixel_format == LCD_DBI_LCD_PIXEL_FORMAT_RGB565) {
pec_dbi_b_handle.pixel_format = PEC_DBI_B_PIXEL_FORMAT_RGB565;
} else if (pixel_format == LCD_DBI_LCD_PIXEL_FORMAT_NRGB8888) {
pec_dbi_b_handle.pixel_format = PEC_DBI_B_PIXEL_FORMAT_NRGB8888;
}
pec_dbi_b_handle.pin_dc = LCD_DBI_PEC_SIMU_PIN_DC;
pec_dbi_b_handle.pin_wr = LCD_DBI_PEC_SIMU_PIN_WR;
pec_dbi_b_handle.pin_data = LCD_DBI_PEC_SIMU_PIN_DATA;
pec_dbi_b_handle.pec = PEC0;
pec_dbi_b_handle.sm = PEC_SM3;
pec_dbi_b_handle.fifo_threshold = 3;
bflb_pec_dbi_b_init(&pec_dbi_b_handle);
/* dma init */
dma_pec_config.direction = DMA_MEMORY_TO_PERIPH;
dma_pec_config.src_req = DMA_REQUEST_NONE;
dma_pec_config.dst_req = DMA_REQUEST_PEC0_SM0_TX + pec_dbi_b_handle.sm;
dma_pec_config.src_addr_inc = DMA_ADDR_INCREMENT_ENABLE;
dma_pec_config.dst_addr_inc = DMA_ADDR_INCREMENT_DISABLE;
dma_pec_config.src_burst_count = DMA_BURST_INCR4;
dma_pec_config.dst_burst_count = DMA_BURST_INCR4;
dma_pec_config.src_width = DMA_DATA_WIDTH_32BIT;
dma_pec_config.dst_width = DMA_DATA_WIDTH_32BIT;
pec_dbi_b_dma_handle = bflb_device_get_by_name(LCD_PEC_DBI_B_DMA_NAME);
bflb_dma_channel_init(pec_dbi_b_dma_handle, &dma_pec_config);
/* dma int cfg */
bflb_dma_channel_irq_attach(pec_dbi_b_dma_handle, pec_dbi_b_dma_flush_callback, NULL);
return 0;
}
/**
* @brief pec_dbi_b_dma_is_busy, After the call ili9488_spi_draw_picture_dma must check this,
* if pec_dbi_b_dma_is_busy() == 1, Don't allow other draw !!
* can run in the DMA interrupt callback function.
*
* @return int 0:draw end; 1:Being draw
*/
int pec_dbi_b_dma_is_busy(void)
{
if (pec_dbi_b_async_flag || pec_dbi_b_async_cycle_fill_flag) {
return 1;
} else {
return 0;
}
}
int pec_dbi_b_transmit_cmd_para(uint8_t cmd, uint32_t *para, size_t para_num)
{
uint32_t pec_dbi_head;
uint32_t pec_dbi_fifo_address;
int fifo_cnt = 0;
/* Build pec-dbi control head */
pec_dbi_head = bflb_pec_dbi_b_build_head(&pec_dbi_b_handle, PEC_DBI_TRANSMIT_MODE_CMD, cmd, para_num);
/* get pec tx fifo address */
pec_dbi_fifo_address = bflb_pec_dbi_b_get_fifo_address(&pec_dbi_b_handle);
/* uint8 to uint32 */
para_num = (para_num + 3) / 4;
/* get tx fifo level */
do {
fifo_cnt = bflb_pec_dbi_b_get_fifo_cnt(&pec_dbi_b_handle);
} while (fifo_cnt == 0);
/* Write control head with cmd */
putreg32(pec_dbi_head, pec_dbi_fifo_address);
fifo_cnt--;
/* Write parameter */
for (size_t i = 0; i < para_num; i++) {
/* Get the available fifo depth */
while (fifo_cnt == 0) {
fifo_cnt = bflb_pec_dbi_b_get_fifo_cnt(&pec_dbi_b_handle);
}
putreg32(para[i], pec_dbi_fifo_address);
fifo_cnt--;
}
return 0;
}
int pec_dbi_b_transmit_cmd_pixel_sync(uint8_t cmd, uint32_t *pixel, size_t pixel_num)
{
uint32_t pec_dbi_head;
uint32_t pec_dbi_fifo_address;
int fifo_cnt = 0;
/* Build pec-dbi control head */
pec_dbi_head = bflb_pec_dbi_b_build_head(&pec_dbi_b_handle, PEC_DBI_TRANSMIT_MODE_PIXEL, cmd, pixel_num);
/* get pec tx fifo address (rgb565) */
pec_dbi_fifo_address = bflb_pec_dbi_b_get_fifo_address(&pec_dbi_b_handle);
if (pixel_format == LCD_DBI_LCD_PIXEL_FORMAT_RGB565) {
/* uint16 to uint32 */
pixel_num = (pixel_num + 1) / 2;
} else if (pixel_format == LCD_DBI_LCD_PIXEL_FORMAT_NRGB8888) {
pixel_num = pixel_num;
}
/* get tx fifo level */
do {
fifo_cnt = bflb_pec_dbi_b_get_fifo_cnt(&pec_dbi_b_handle);
} while (fifo_cnt == 0);
/* Write control head */
putreg32(pec_dbi_head, pec_dbi_fifo_address);
fifo_cnt--;
/* Write pixel */
for (size_t i = 0; i < pixel_num; i++) {
/* Get the available fifo depth */
while (fifo_cnt == 0) {
fifo_cnt = bflb_pec_dbi_b_get_fifo_cnt(&pec_dbi_b_handle);
}
putreg32(pixel[i], pec_dbi_fifo_address);
fifo_cnt--;
}
return 0;
}
int pec_dbi_b_transmit_cmd_pixel_async(uint8_t cmd, uint32_t *pixel, size_t pixel_num)
{
uint32_t pec_dbi_head;
uint32_t pec_dbi_fifo_address;
pec_dbi_b_async_flag = true;
/* Build pec-dbi control head */
pec_dbi_head = bflb_pec_dbi_b_build_head(&pec_dbi_b_handle, PEC_DBI_TRANSMIT_MODE_PIXEL, cmd, pixel_num);
/* get pec tx fifo address */
pec_dbi_fifo_address = bflb_pec_dbi_b_get_fifo_address(&pec_dbi_b_handle);
if (pixel_format == LCD_DBI_LCD_PIXEL_FORMAT_RGB565) {
/* uint16 to uint32 */
pixel_num = (pixel_num + 1) / 2;
} else if (pixel_format == LCD_DBI_LCD_PIXEL_FORMAT_NRGB8888) {
pixel_num = pixel_num;
}
/* get tx fifo level */
while (bflb_pec_dbi_b_get_fifo_cnt(&pec_dbi_b_handle) == 0) {
};
/* Write control head */
putreg32(pec_dbi_head, pec_dbi_fifo_address);
/* Use dma to do asynchronous writes */
bflb_pec_dbi_b_dma_enable(&pec_dbi_b_handle, true);
/* dma transfers cfg */
dma_tx_transfers[0].src_addr = (uint32_t)pixel;
dma_tx_transfers[0].dst_addr = pec_dbi_fifo_address;
dma_tx_transfers[0].nbytes = pixel_num * 4;
bflb_dma_channel_lli_reload(pec_dbi_b_dma_handle, dma_tx_llipool, LCD_DBI_PEC_DMA_LLI_NUM, dma_tx_transfers, 1);
/* clean cache */
bflb_l1c_dcache_clean_range((void *)pixel, pixel_num * 4);
/* enable dma */
bflb_dma_channel_start(pec_dbi_b_dma_handle);
return 0;
}
int pec_dbi_b_transmit_cmd_pixel_fill_sync(uint8_t cmd, uint32_t pixel_val, size_t pixel_num)
{
uint32_t pec_dbi_head;
uint32_t pec_dbi_fifo_address;
int fifo_cnt = 0;
/* Build pec-dbi control head */
pec_dbi_head = bflb_pec_dbi_b_build_head(&pec_dbi_b_handle, PEC_DBI_TRANSMIT_MODE_PIXEL, cmd, pixel_num);
/* get pec tx fifo address */
pec_dbi_fifo_address = bflb_pec_dbi_b_get_fifo_address(&pec_dbi_b_handle);
if (pixel_format == LCD_DBI_LCD_PIXEL_FORMAT_RGB565) {
/* uint16 to uint32 */
pixel_num = (pixel_num + 1) / 2;
} else if (pixel_format == LCD_DBI_LCD_PIXEL_FORMAT_NRGB8888) {
pixel_num = pixel_num;
}
/* get tx fifo level */
do {
fifo_cnt = bflb_pec_dbi_b_get_fifo_cnt(&pec_dbi_b_handle);
} while (fifo_cnt == 0);
/* Write control head */
putreg32(pec_dbi_head, pec_dbi_fifo_address);
fifo_cnt--;
/* Write pixel */
for (size_t i = 0; i < pixel_num; i++) {
/* Get the available fifo depth */
while (fifo_cnt == 0) {
fifo_cnt = bflb_pec_dbi_b_get_fifo_cnt(&pec_dbi_b_handle);
}
putreg32(pixel_val, pec_dbi_fifo_address);
fifo_cnt--;
}
return 0;
}
int pec_dbi_b_transmit_cmd_pixel_fill_async(uint8_t cmd, uint32_t pixel_val, size_t pixel_num)
{
uint32_t pec_dbi_head;
uint32_t pec_dbi_fifo_address;
pec_dbi_b_async_cycle_fill_flag = true;
/* Build pec-dbi control head */
pec_dbi_head = bflb_pec_dbi_b_build_head(&pec_dbi_b_handle, PEC_DBI_TRANSMIT_MODE_PIXEL, cmd, pixel_num);
/* get pec tx fifo address */
pec_dbi_fifo_address = bflb_pec_dbi_b_get_fifo_address(&pec_dbi_b_handle);
if (pixel_format == LCD_DBI_LCD_PIXEL_FORMAT_RGB565) {
/* uint16 to uint32 */
pixel_num = (pixel_num + 1) / 2;
} else if (pixel_format == LCD_DBI_LCD_PIXEL_FORMAT_NRGB8888) {
pixel_num = pixel_num;
}
/* get tx fifo level */
while (bflb_pec_dbi_b_get_fifo_cnt(&pec_dbi_b_handle) == 0) {
};
/* Write control head */
putreg32(pec_dbi_head, pec_dbi_fifo_address);
/* Use dma to do asynchronous writes */
bflb_pec_dbi_b_dma_enable(&pec_dbi_b_handle, true);
/* dma cycle fill mode */
bflb_dma_feature_control(pec_dbi_b_dma_handle, DMA_CMD_SET_SRCADDR_INCREMENT, false);
/* dma transfers cfg */
dma_tx_transfers[0].src_addr = (uint32_t)&pixel_val;
dma_tx_transfers[0].dst_addr = pec_dbi_fifo_address;
dma_tx_transfers[0].nbytes = pixel_num * 4;
bflb_dma_channel_lli_reload(pec_dbi_b_dma_handle, dma_tx_llipool, LCD_DBI_PEC_DMA_LLI_NUM, dma_tx_transfers, 1);
/* clean cache */
bflb_l1c_dcache_clean_range((void *)&pixel_val, sizeof(pixel_val));
/* enable dma */
bflb_dma_channel_start(pec_dbi_b_dma_handle);
return 0;
}
#else
#error "Devices that do not support PEC-DBI! Replace the driver port (lcd_conf.h)"
#endif
#endif

View file

@ -0,0 +1,32 @@
#ifndef _BL_MIPI_DBI_PORT_H
#define _BL_MIPI_DBI_PORT_H
#include "../lcd_conf.h"
#if (defined(LCD_DBI_INTERFACE_TYPE) && (LCD_DBI_INTERFACE_TYPE == 2))
/* Do not modify this file ! */
/* Optional pixel format */
#define LCD_DBI_LCD_PIXEL_FORMAT_RGB565 1
#define LCD_DBI_LCD_PIXEL_FORMAT_NRGB8888 2
typedef struct {
uint16_t pixel_format;
uint32_t clock_freq; /* No use */
} lcd_mipi_dbi_init_t;
int pec_dbi_b_init(lcd_mipi_dbi_init_t *dbi_parra);
int pec_dbi_b_transmit_cmd_para(uint8_t cmd, uint32_t *para, size_t para_num);
int pec_dbi_b_transmit_cmd_pixel_sync(uint8_t cmd, uint32_t *pixel, size_t pixel_num);
int pec_dbi_b_transmit_cmd_pixel_fill_sync(uint8_t cmd, uint32_t pixel_val, size_t pixel_num);
int pec_dbi_b_dma_is_busy(void);
int pec_dbi_b_async_callback_register(void (*callback)(void));
int pec_dbi_b_async_callback_enable(bool enable);
int pec_dbi_b_transmit_cmd_pixel_async(uint8_t cmd, uint32_t *pixel, size_t pixel_num);
int pec_dbi_b_transmit_cmd_pixel_fill_async(uint8_t cmd, uint32_t pixel_val, size_t pixel_num);
#endif
#endif

View file

@ -0,0 +1,340 @@
/**
* @file ili9341_dbi.c
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#include "../lcd.h"
#include "ili9341_dbi.h"
#if defined(LCD_DBI_ILI9341)
#if (LCD_DBI_INTERFACE_TYPE == 1)
/* dbi */
#include "bl_mipi_dbi.h"
#define lcd_dbi_init lcd_dbi_init
#define lcd_dbi_isbusy lcd_dbi_is_busy
#define lcd_dbi_transmit_cmd_para lcd_dbi_transmit_cmd_para
#define lcd_dbi_transmit_cmd_pixel_sync lcd_dbi_transmit_cmd_pixel_sync
#define lcd_dbi_transmit_cmd_pixel_fill_sync lcd_dbi_transmit_cmd_pixel_fill_sync
#define lcd_dbi_sync_callback_enable lcd_dbi_async_callback_enable
#define lcd_dbi_async_callback_register lcd_dbi_async_callback_register
#define lcd_dbi_transmit_cmd_pixel_async lcd_dbi_transmit_cmd_pixel_async
#define lcd_dbi_transmit_cmd_pixel_fill_async lcd_dbi_transmit_cmd_pixel_fill_async
lcd_dbi_init_t dbi_para = {
.clock_freq = 40 * 1000 * 1000,
#if (ILI9341_DBI_PIXEL_FORMAT == 1)
.pixel_format = LCD_DBI_LCD_PIXEL_FORMAT_RGB565,
#elif (ILI9341_DBI_PIXEL_FORMAT == 2)
.pixel_format = LCD_DBI_LCD_PIXEL_FORMAT_NRGB8888,
#endif
};
#elif (LCD_DBI_INTERFACE_TYPE == 2)
/* pec sumi dbi 8080 x8 */
#include "bl_mipi_dbi_typeb_pec.h"
#define lcd_dbi_init pec_dbi_b_init
#define lcd_dbi_isbusy pec_dbi_b_dma_is_busy
#define lcd_dbi_transmit_cmd_para pec_dbi_b_transmit_cmd_para
#define lcd_dbi_transmit_cmd_pixel_sync pec_dbi_b_transmit_cmd_pixel_sync
#define lcd_dbi_transmit_cmd_pixel_fill_sync pec_dbi_b_transmit_cmd_pixel_fill_sync
#define lcd_dbi_sync_callback_enable pec_dbi_b_async_callback_enable
#define lcd_dbi_async_callback_register pec_dbi_b_async_callback_register
#define lcd_dbi_transmit_cmd_pixel_async pec_dbi_b_transmit_cmd_pixel_async
#define lcd_dbi_transmit_cmd_pixel_fill_async pec_dbi_b_transmit_cmd_pixel_fill_async
lcd_mipi_dbi_init_t dbi_para = {
.clock_freq = 20 * 1000 * 1000,
#if (ILI9341_DBI_PIXEL_FORMAT == 1)
.pixel_format = LCD_DBI_LCD_PIXEL_FORMAT_RGB565,
#elif (ILI9341_DBI_PIXEL_FORMAT == 2)
.pixel_format = LCD_DBI_LCD_PIXEL_FORMAT_NRGB8888,
#endif
};
#else
#error "Configuration error"
#endif
const ili9341_dbi_init_cmd_t ili9341_dbi_init_cmds[] = {
{ 0x01, NULL, 0 },
{ 0xFF, NULL, 20 },
{ 0x11, NULL, 0 }, /* Exit sleep */
{ 0xFF, NULL, 120 },
{ 0xCF, "\x00\xd9\x30", 3 },
{ 0xED, "\x64\x03\x12\x81", 4 },
{ 0xE8, "\x85\x01\x78", 3 },
{ 0xCB, "\x39\x2C\x00\x34\x02", 5 },
{ 0xF7, "\x20", 1 },
{ 0xEA, "\x00\x00", 2 },
{ 0xC0, "\x23", 1 }, /*Power control*/
{ 0xC1, "\x12", 1 }, /*Power control */
{ 0xC2, "\x11", 1 },
{ 0xC5, "\x40\x30", 2 }, /*VCOM control 1*/
{ 0xC7, "\xa9", 1 }, /*VCOM control 2*/
{ 0x36, "\x08", 1 }, /*Memory Access Control*/
#if (ILI9341_DBI_PIXEL_FORMAT == 1)
{ 0x3A, "\x55", 1 }, /* Interface Pixel Format RGB565 */
#elif (ILI9341_DBI_PIXEL_FORMAT == 2)
{ 0x3A, "\x66", 1 }, /* Interface Pixel Format RGB666 */
#endif
{ 0xB1, "\x00\x18", 2 }, /* Frame Rate Control */
{ 0xB6, "\x0a\xa2", 2 }, /* Display Function Control */
{ 0x0C, "\xd5", 1 }, /* display pixel format,RGB 16bits,MCU 16bits */
{ 0xF2, "\x00", 1 }, /* 3Gamma Function Disable */
{ 0xF7, "\x20", 1 },
{ 0x26, "\x01", 1 }, /* Gamma curve selected */
{ 0xE0, "\x1F\x1A\x18\x0A\x0F\x06\x45\x87\x32\x0A\x07\x02\x07\x05\x00", 15 }, /* Set Gamma */
{ 0XE1, "\x00\x25\x27\x05\x10\x09\x3A\x78\x4D\x05\x18\x0D\x38\x3A\x1F", 15 }, /* Set Gamma */
{ 0xB7, "\x07", 1 },
#if ILI9341_DBI_COLOR_REVERSAL
{ 0x21, NULL, 0 }, /* Color reversal */
#endif
{ 0x29, NULL, 0 }, /* Display On */
{ 0xFF, NULL, 10 },
};
/**
* @brief ili9341_dbi_async_callback_enable
*
* @return
*/
void ili9341_dbi_async_callback_enable(bool enable)
{
lcd_dbi_sync_callback_enable(enable);
}
/**
* @brief ili9341_dbi_async_callback_register
*
* @return
*/
void ili9341_dbi_async_callback_register(void (*callback)(void))
{
lcd_dbi_async_callback_register(callback);
}
/**
* @brief ili9341_dbi_draw_is_busy, After the call ili9341_dbi_draw_picture_dma must check this,
* if ili9341_dbi_draw_is_busy() == 1, Don't allow other draw !!
* can run in the DMA interrupt callback function.
*
* @return int 0:draw end; 1:Being draw
*/
int ili9341_dbi_draw_is_busy(void)
{
return lcd_dbi_isbusy();
}
/**
* @brief ili9341_dbi_init
*
* @return int
*/
int ili9341_dbi_init()
{
lcd_dbi_init(&dbi_para);
for (uint16_t i = 0; i < (sizeof(ili9341_dbi_init_cmds) / sizeof(ili9341_dbi_init_cmd_t)); i++) {
if (ili9341_dbi_init_cmds[i].cmd == 0xFF && ili9341_dbi_init_cmds[i].data == NULL && ili9341_dbi_init_cmds[i].databytes) {
bflb_mtimer_delay_ms(ili9341_dbi_init_cmds[i].databytes);
} else {
lcd_dbi_transmit_cmd_para(ili9341_dbi_init_cmds[i].cmd, (void *)(ili9341_dbi_init_cmds[i].data), ili9341_dbi_init_cmds[i].databytes);
}
}
return 0;
}
/**
* @brief
*
* @param dir
* @param mir_flag
*/
int ili9341_dbi_set_dir(uint8_t dir, uint8_t mir_flag)
{
uint8_t param;
switch (dir) {
case 0:
if (!mir_flag)
param = 0x00;
else
param = 0x01;
break;
case 1:
if (!mir_flag)
param = 0x60;
else
param = 0x20;
break;
case 2:
if (!mir_flag)
param = 0xC0;
else
param = 0x80;
break;
case 3:
if (!mir_flag)
param = 0xA0;
else
param = 0xE0;
break;
default:
return -1;
break;
}
lcd_dbi_transmit_cmd_para(0x36, (void *)&param, 1);
return dir;
}
/**
* @brief ili9341_dbi_set_draw_window
*
* @param x1
* @param y1
* @param x2
* @param y2
*/
void ili9341_dbi_set_draw_window(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2)
{
#if ILI9341_DBI_OFFSET_X
x1 += ILI9341_DBI_OFFSET_X;
x2 += ILI9341_DBI_OFFSET_X;
#endif
#if ILI9341_DBI_OFFSET_Y
y1 += ILI9341_DBI_OFFSET_Y;
y2 += ILI9341_DBI_OFFSET_Y;
#endif
uint8_t param[4];
param[0] = (y1 >> 8) & 0xFF;
param[1] = y1 & 0xFF;
param[2] = (y2 >> 8) & 0xFF;
param[3] = y2 & 0xFF;
lcd_dbi_transmit_cmd_para(0x2B, (void *)param, 4);
param[0] = (x1 >> 8) & 0xFF;
param[1] = x1 & 0xFF;
param[2] = (x2 >> 8) & 0xFF;
param[3] = x2 & 0xFF;
lcd_dbi_transmit_cmd_para(0x2A, (void *)param, 4);
}
/**
* @brief ili9341_dbi_draw_point
*
* @param x
* @param y
* @param color
*/
void ili9341_dbi_draw_point(uint16_t x, uint16_t y, ili9341_dbi_color_t color)
{
/* set window */
ili9341_dbi_set_draw_window(x, y, x, y);
lcd_dbi_transmit_cmd_pixel_sync(0x2C, (void *)&color, 1);
}
/**
* @brief ili9341_dbi_draw_area
*
* @param x1
* @param y1
* @param x2
* @param y2
* @param color
*/
void ili9341_dbi_draw_area(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, ili9341_dbi_color_t color)
{
uint32_t pixel_num = (x2 - x1 + 1) * (y2 - y1 + 1);
uint32_t color_src;
#if ILI9341_DBI_COLOR_DEPTH == 16
color_src = color << 16 | color;
#elif ILI9341_DBI_COLOR_DEPTH == 32
color_src = color;
#endif
/* set window */
ili9341_dbi_set_draw_window(x1, y1, x2, y2);
lcd_dbi_transmit_cmd_pixel_fill_sync(0x2C, color_src, pixel_num);
}
/**
* @brief ili9341_dbi_draw_picture_dma, Non-blocking! Using DMA acceleration, Not waiting for the draw end
* After the call, No other operations are allowed until (ili9341_dbi_draw_is_busy()==0)
*
* @param x1
* @param y1
* @param x2
* @param y2
* @param picture
*/
void ili9341_dbi_draw_picture_nonblocking(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, ili9341_dbi_color_t *picture)
{
uint32_t pixel_num = (x2 - x1 + 1) * (y2 - y1 + 1);
/* set window */
ili9341_dbi_set_draw_window(x1, y1, x2, y2);
lcd_dbi_transmit_cmd_pixel_async(0x2C, (void *)picture, pixel_num);
}
/**
* @brief ili9341_dbi_draw_picture,BlockingUsing DMA acceleration,Waiting for the draw end
*
* @param x1
* @param y1
* @param x2
* @param y2
* @param picture
*/
void ili9341_dbi_draw_picture_blocking(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, ili9341_dbi_color_t *picture)
{
uint32_t pixel_num = (x2 - x1 + 1) * (y2 - y1 + 1);
/* set window */
ili9341_dbi_set_draw_window(x1, y1, x2, y2);
lcd_dbi_transmit_cmd_pixel_sync(0x2C, (void *)picture, pixel_num);
}
#endif

View file

@ -0,0 +1,59 @@
/**
* @file ili9341_dpi.h
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#ifndef _ILI9341_DBI_H_
#define _ILI9341_DBI_H_
#include "../lcd_conf.h"
#if defined LCD_DBI_ILI9341
/* Do not modify the following */
#if (ILI9341_DBI_PIXEL_FORMAT == 1)
#define ILI9341_DBI_COLOR_DEPTH 16
typedef uint16_t ili9341_dbi_color_t;
#elif (ILI9341_DBI_PIXEL_FORMAT == 2)
#define ILI9341_DBI_COLOR_DEPTH 32
typedef uint32_t ili9341_dbi_color_t;
#endif
typedef struct {
uint8_t cmd; /* 0xFF : delay(databytes)ms */
const char *data;
uint8_t databytes; /* Num of data in data; or delay time */
} ili9341_dbi_init_cmd_t;
int ili9341_dbi_init();
void ili9341_dbi_async_callback_enable(bool enable);
void ili9341_dbi_async_callback_register(void (*callback)(void));
int ili9341_dbi_set_dir(uint8_t dir, uint8_t mir_flag);
void ili9341_dbi_set_draw_window(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2);
void ili9341_dbi_draw_point(uint16_t x, uint16_t y, ili9341_dbi_color_t color);
void ili9341_dbi_draw_area(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, ili9341_dbi_color_t color);
void ili9341_dbi_draw_picture_nonblocking(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, ili9341_dbi_color_t *picture);
void ili9341_dbi_draw_picture_blocking(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, ili9341_dbi_color_t *picture);
int ili9341_dbi_draw_is_busy(void);
#endif
#endif

View file

@ -0,0 +1,333 @@
/**
* @file ili9488_dbi.c
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#include "../lcd.h"
#include "ili9488_dbi.h"
#if defined(LCD_DBI_ILI9488)
#if (LCD_DBI_INTERFACE_TYPE == 1)
/* dbi */
#include "bl_mipi_dbi.h"
#define lcd_dbi_init lcd_dbi_init
#define lcd_dbi_isbusy lcd_dbi_is_busy
#define lcd_dbi_transmit_cmd_para lcd_dbi_transmit_cmd_para
#define lcd_dbi_transmit_cmd_pixel_sync lcd_dbi_transmit_cmd_pixel_sync
#define lcd_dbi_transmit_cmd_pixel_fill_sync lcd_dbi_transmit_cmd_pixel_fill_sync
#define lcd_dbi_sync_callback_enable lcd_dbi_async_callback_enable
#define lcd_dbi_async_callback_register lcd_dbi_async_callback_register
#define lcd_dbi_transmit_cmd_pixel_async lcd_dbi_transmit_cmd_pixel_async
#define lcd_dbi_transmit_cmd_pixel_fill_async lcd_dbi_transmit_cmd_pixel_fill_async
lcd_dbi_init_t dbi_para = {
.clock_freq = 40 * 1000 * 1000,
#if (ILI9488_DBI_PIXEL_FORMAT == 1)
.pixel_format = LCD_DBI_LCD_PIXEL_FORMAT_RGB565,
#elif (ILI9488_DBI_PIXEL_FORMAT == 2)
.pixel_format = LCD_DBI_LCD_PIXEL_FORMAT_NRGB8888,
#endif
};
#elif (LCD_DBI_INTERFACE_TYPE == 2)
/* pec sumi dbi 8080 x8 */
#include "bl_mipi_dbi_typeb_pec.h"
#define lcd_dbi_init pec_dbi_b_init
#define lcd_dbi_isbusy pec_dbi_b_dma_is_busy
#define lcd_dbi_transmit_cmd_para pec_dbi_b_transmit_cmd_para
#define lcd_dbi_transmit_cmd_pixel_sync pec_dbi_b_transmit_cmd_pixel_sync
#define lcd_dbi_transmit_cmd_pixel_fill_sync pec_dbi_b_transmit_cmd_pixel_fill_sync
#define lcd_dbi_sync_callback_enable pec_dbi_b_async_callback_enable
#define lcd_dbi_async_callback_register pec_dbi_b_async_callback_register
#define lcd_dbi_transmit_cmd_pixel_async pec_dbi_b_transmit_cmd_pixel_async
#define lcd_dbi_transmit_cmd_pixel_fill_async pec_dbi_b_transmit_cmd_pixel_fill_async
lcd_mipi_dbi_init_t dbi_para = {
.clock_freq = 20 * 1000 * 1000,
#if (ILI9488_DBI_PIXEL_FORMAT == 1)
.pixel_format = LCD_DBI_LCD_PIXEL_FORMAT_RGB565,
#elif (ILI9488_DBI_PIXEL_FORMAT == 2)
.pixel_format = LCD_DBI_LCD_PIXEL_FORMAT_NRGB8888,
#endif
};
#else
#error "Configuration error"
#endif
const ili9488_dbi_init_cmd_t ili9488_dbi_init_cmds[] = {
{ 0x01, NULL, 0 }, /* software reset */
{ 0xFF, NULL, 10 }, /* delay 10ms */
{ 0x11, NULL, 0 }, /* Sleep Out */
{ 0xFF, NULL, 120 }, /* delay 120ms */
{ 0xE0, "\x00\x07\x0F\x0D\x1B\x0A\x3C\x78\x4A\x07\x0E\x09\x1B\x1E\x0F", 15 }, /* PGAMCTRL (Positive Gamma Control) */
{ 0xE1, "\x00\x22\x24\x26\x12\x07\x36\x47\x47\x06\x0A\x07\x30\x37\x0F", 15 }, /* NGAMCTRL (Negative Gamma Control) */
{ 0xC0, "\x10\x10", 2 }, /* Power Control 1 */
{ 0xC1, "\x41", 1 }, /* Power Control 2 */
{ 0xC5, "\x00\x2C\x80", 3 }, /* VCOM Control */
{ 0x36, "\x08", 1 }, /* Memory Access Control */
#if (ILI9488_DBI_PIXEL_FORMAT == 1)
{ 0x3A, "\x55", 1 }, /* Interface Pixel Format RGB565 */
#elif (ILI9488_DBI_PIXEL_FORMAT == 2)
{ 0x3A, "\x66", 1 }, /* Interface Pixel Format RGB666 */
#endif
{ 0xB0, "\x00", 1 }, /* Interface Mode Control */
{ 0xB1, "\xB0", 1 }, /* Frame rate 70Hz */
{ 0xB4, "\x02", 1 }, /* Display Inversion Control */
{ 0xB6, "\x02\x22", 2 }, /* Display Function Control */
{ 0xE9, "\x00", 1 }, /* Set Image Function */
{ 0xF7, "\xA9\x51\x2C\x82", 4 }, /* Adjust Control 3 */
#if ILI9488_DBI_COLOR_REVERSAL
{ 0x21, NULL, 0 }, /* Color reversal */
#endif
{ 0x29, NULL, 0 }, /* Display On */
{ 0xFF, NULL, 10 },
};
/**
* @brief ili9488_dbi_async_callback_enable
*
* @return
*/
void ili9488_dbi_async_callback_enable(bool enable)
{
lcd_dbi_sync_callback_enable(enable);
}
/**
* @brief ili9488_dbi_async_callback_register
*
* @return
*/
void ili9488_dbi_async_callback_register(void (*callback)(void))
{
lcd_dbi_async_callback_register(callback);
}
/**
* @brief ili9488_dbi_draw_is_busy, After the call ili9488_dbi_draw_picture_dma must check this,
* if ili9488_dbi_draw_is_busy() == 1, Don't allow other draw !!
* can run in the DMA interrupt callback function.
*
* @return int 0:draw end; 1:Being draw
*/
int ili9488_dbi_draw_is_busy(void)
{
return lcd_dbi_isbusy();
}
/**
* @brief ili9488_dbi_init
*
* @return int
*/
int ili9488_dbi_init()
{
lcd_dbi_init(&dbi_para);
for (uint16_t i = 0; i < (sizeof(ili9488_dbi_init_cmds) / sizeof(ili9488_dbi_init_cmd_t)); i++) {
if (ili9488_dbi_init_cmds[i].cmd == 0xFF && ili9488_dbi_init_cmds[i].data == NULL && ili9488_dbi_init_cmds[i].databytes) {
bflb_mtimer_delay_ms(ili9488_dbi_init_cmds[i].databytes);
} else {
lcd_dbi_transmit_cmd_para(ili9488_dbi_init_cmds[i].cmd, (void *)(ili9488_dbi_init_cmds[i].data), ili9488_dbi_init_cmds[i].databytes);
}
}
return 0;
}
/**
* @brief
*
* @param dir
* @param mir_flag
*/
int ili9488_dbi_set_dir(uint8_t dir, uint8_t mir_flag)
{
uint8_t param;
switch (dir) {
case 0:
if (!mir_flag)
param = 0x00;
else
param = 0x01;
break;
case 1:
if (!mir_flag)
param = 0x60;
else
param = 0x20;
break;
case 2:
if (!mir_flag)
param = 0xC0;
else
param = 0x80;
break;
case 3:
if (!mir_flag)
param = 0xA0;
else
param = 0xE0;
break;
default:
return -1;
break;
}
lcd_dbi_transmit_cmd_para(0x36, (void *)&param, 1);
return dir;
}
/**
* @brief ili9488_dbi_set_draw_window
*
* @param x1
* @param y1
* @param x2
* @param y2
*/
void ili9488_dbi_set_draw_window(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2)
{
#if ILI9488_DBI_OFFSET_X
x1 += ILI9488_DBI_OFFSET_X;
x2 += ILI9488_DBI_OFFSET_X;
#endif
#if ILI9488_DBI_OFFSET_Y
y1 += ILI9488_DBI_OFFSET_Y;
y2 += ILI9488_DBI_OFFSET_Y;
#endif
uint8_t param[4];
param[0] = (y1 >> 8) & 0xFF;
param[1] = y1 & 0xFF;
param[2] = (y2 >> 8) & 0xFF;
param[3] = y2 & 0xFF;
lcd_dbi_transmit_cmd_para(0x2B, (void *)param, 4);
param[0] = (x1 >> 8) & 0xFF;
param[1] = x1 & 0xFF;
param[2] = (x2 >> 8) & 0xFF;
param[3] = x2 & 0xFF;
lcd_dbi_transmit_cmd_para(0x2A, (void *)param, 4);
}
/**
* @brief ili9488_dbi_draw_point
*
* @param x
* @param y
* @param color
*/
void ili9488_dbi_draw_point(uint16_t x, uint16_t y, ili9488_dbi_color_t color)
{
/* set window */
ili9488_dbi_set_draw_window(x, y, x, y);
lcd_dbi_transmit_cmd_pixel_sync(0x2C, (void *)&color, 1);
}
/**
* @brief ili9488_dbi_draw_area
*
* @param x1
* @param y1
* @param x2
* @param y2
* @param color
*/
void ili9488_dbi_draw_area(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, ili9488_dbi_color_t color)
{
uint32_t pixel_num = (x2 - x1 + 1) * (y2 - y1 + 1);
uint32_t color_src;
#if ILI9488_DBI_COLOR_DEPTH == 16
color_src = color << 16 | color;
#elif ILI9488_DBI_COLOR_DEPTH == 32
color_src = color;
#endif
/* set window */
ili9488_dbi_set_draw_window(x1, y1, x2, y2);
lcd_dbi_transmit_cmd_pixel_fill_sync(0x2C, color_src, pixel_num);
}
/**
* @brief ili9488_dbi_draw_picture_dma, Non-blocking! Using DMA acceleration, Not waiting for the draw end
* After the call, No other operations are allowed until (ili9488_dbi_draw_is_busy()==0)
*
* @param x1
* @param y1
* @param x2
* @param y2
* @param picture
*/
void ili9488_dbi_draw_picture_nonblocking(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, ili9488_dbi_color_t *picture)
{
uint32_t pixel_num = (x2 - x1 + 1) * (y2 - y1 + 1);
/* set window */
ili9488_dbi_set_draw_window(x1, y1, x2, y2);
lcd_dbi_transmit_cmd_pixel_async(0x2C, (void *)picture, pixel_num);
}
/**
* @brief ili9488_dbi_draw_picture,BlockingUsing DMA acceleration,Waiting for the draw end
*
* @param x1
* @param y1
* @param x2
* @param y2
* @param picture
*/
void ili9488_dbi_draw_picture_blocking(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, ili9488_dbi_color_t *picture)
{
uint32_t pixel_num = (x2 - x1 + 1) * (y2 - y1 + 1);
/* set window */
ili9488_dbi_set_draw_window(x1, y1, x2, y2);
lcd_dbi_transmit_cmd_pixel_sync(0x2C, (void *)picture, pixel_num);
}
#endif

View file

@ -0,0 +1,59 @@
/**
* @file ili9488_dpi.h
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#ifndef _ILI9488_DBI_H_
#define _ILI9488_DBI_H_
#include "../lcd_conf.h"
#if defined LCD_DBI_ILI9488
/* Do not modify the following */
#if (ILI9488_DBI_PIXEL_FORMAT == 1)
#define ILI9488_DBI_COLOR_DEPTH 16
typedef uint16_t ili9488_dbi_color_t;
#elif (ILI9488_DBI_PIXEL_FORMAT == 2)
#define ILI9488_DBI_COLOR_DEPTH 32
typedef uint32_t ili9488_dbi_color_t;
#endif
typedef struct {
uint8_t cmd; /* 0xFF : delay(databytes)ms */
const char *data;
uint8_t databytes; /* Num of data in data; or delay time */
} ili9488_dbi_init_cmd_t;
int ili9488_dbi_init();
void ili9488_dbi_async_callback_enable(bool enable);
void ili9488_dbi_async_callback_register(void (*callback)(void));
int ili9488_dbi_set_dir(uint8_t dir, uint8_t mir_flag);
void ili9488_dbi_set_draw_window(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2);
void ili9488_dbi_draw_point(uint16_t x, uint16_t y, ili9488_dbi_color_t color);
void ili9488_dbi_draw_area(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, ili9488_dbi_color_t color);
void ili9488_dbi_draw_picture_nonblocking(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, ili9488_dbi_color_t *picture);
void ili9488_dbi_draw_picture_blocking(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, ili9488_dbi_color_t *picture);
int ili9488_dbi_draw_is_busy(void);
#endif
#endif

View file

@ -0,0 +1,382 @@
/**
* @file bl_mipi_dpi.c
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#include "../lcd.h"
#if (defined LCD_PEC_SIMU_DPI_ENABLE)
#if (defined(BL616) && __has_include("bflb_pec_ip.h"))
#include "bl_mipi_dpi_pec.h"
#include "bflb_pec_ip.h"
#include "bflb_gpio.h"
#include "bflb_l1c.h"
#include "bflb_dma.h"
#include "hardware/dma_reg.h"
/* Video memory used for this frame, Update in frame interrupt*/
static volatile void *screen_last = NULL;
typedef void (*standard_dpi_callback)(void);
static volatile standard_dpi_callback lcd_mipi_dpi_frame_callback = NULL;
static volatile standard_dpi_callback lcd_mipi_dpi_frame_swap_callback = NULL;
struct bflb_device_s *pec_dpi_dma_handle;
/* DMA linked list of PEC controls data */
static struct bflb_dma_channel_lli_pool_s dma_lli_dpi_header, dma_dpi_lli_tail;
/* DMA linked list of display buffer */
static struct bflb_dma_channel_lli_pool_s dma_lli_dpi_pool[LCD_DPI_PEC_DMA_LLI_CACHE_NUM][DPI_PEC_VALID_PIXEL_MAX / DMA_MAX_COUNT + 1];
/* Invalid row control parameter, Will be sent to PEC before and after the buffer */
static uint32_t pec_dpi_invalid_lin_para[(LCD_DPI_PEC_INVALID_LIN_MAX + 1) * 2];
/* dma lli cache table */
static volatile pec_dpi_dma_lli_cache_t dma_lli_cache_table[LCD_DPI_PEC_DMA_LLI_CACHE_NUM];
/* Total number of dma_transfer */
static volatile uint32_t pec_dpi_dma_lli_num;
/* next display buffer */
static volatile void *next_disp_buffer;
/* record pix_format, width, height */
static volatile uint16_t pix_format, width, height;
static int pec_dpi_dma_lli_init(lcd_mipi_dpi_init_t *dpi_para);
static int pec_dpi_dma_lli_update(void *disp_buff);
static void pec_dpi_dma_interrupt(void *arg);
int lcd_mipi_dpi_init(lcd_mipi_dpi_init_t *dpi_para)
{
if (dpi_para == NULL) {
return -1;
}
if (dpi_para->frame_buff == NULL) {
return -1;
}
/* pec gpio init */
struct bflb_device_s *gpio;
gpio = bflb_device_get_by_name("gpio");
/* clk pin */
bflb_gpio_init(gpio, LCD_DPI_PEC_SIMU_PIN_CLK, GPIO_FUNC_PEC | GPIO_ALTERNATE | GPIO_PULLDOWN | GPIO_SMT_EN | GPIO_DRV_2);
#if (LCD_PEC_DPI_DE_MODE)
/* de pin */
bflb_gpio_init(gpio, LCD_DPI_PEC_SIMU_PIN_CLK + 1, GPIO_FUNC_PEC | GPIO_ALTERNATE | GPIO_PULLDOWN | GPIO_SMT_EN | GPIO_DRV_2);
#endif
#if (LCD_PEC_DPI_DATA_LATCH_MODE)
/* latch pin */
bflb_gpio_init(gpio, LCD_DPI_PEC_SIMU_PIN_CLK + 2, GPIO_FUNC_PEC | GPIO_ALTERNATE | GPIO_PULLDOWN | GPIO_SMT_EN | GPIO_DRV_2);
#endif
/* hsync pin */
bflb_gpio_init(gpio, LCD_DPI_PEC_SIMU_PIN_HSYNC, GPIO_FUNC_PEC | GPIO_ALTERNATE | GPIO_PULLDOWN | GPIO_SMT_EN | GPIO_DRV_2);
/* vsync pin */
bflb_gpio_init(gpio, LCD_DPI_PEC_SIMU_PIN_HSYNC + 1, GPIO_FUNC_PEC | GPIO_ALTERNATE | GPIO_PULLDOWN | GPIO_SMT_EN | GPIO_DRV_2);
#if (LCD_PEC_DPI_DATA_LATCH_MODE)
/* data pin x8 */
for (uint8_t i = 0; i < 8; i++) {
bflb_gpio_init(gpio, LCD_DPI_PEC_SIMU_PIN_DATA_START + i, GPIO_FUNC_PEC | GPIO_ALTERNATE | GPIO_PULLDOWN | GPIO_SMT_EN | GPIO_DRV_2);
}
#else
/* data pin x16 */
for (uint8_t i = 0; i < 16; i++) {
bflb_gpio_init(gpio, LCD_DPI_PEC_SIMU_PIN_DATA_START + i, GPIO_FUNC_PEC | GPIO_ALTERNATE | GPIO_PULLDOWN | GPIO_SMT_EN | GPIO_DRV_2);
}
#endif
/* pec init */
struct bflb_pec_dpi_s dpi_pec;
pix_format = dpi_para->pixel_format;
width = dpi_para->width;
height = dpi_para->height;
if (dpi_para->pixel_format == LCD_MIPI_DPI_PIXEL_FORMAT_RGB565) {
dpi_pec.data_format = 16;
} else if (dpi_para->pixel_format == LCD_MIPI_DPI_PIXEL_FORMAT_NRGB888) {
dpi_pec.data_format = 24;
} else {
return -2;
}
/* pec init */
dpi_pec.width = dpi_para->width;
dpi_pec.height = dpi_para->height;
dpi_pec.hsw = dpi_para->hsw;
dpi_pec.hbp = dpi_para->hbp;
dpi_pec.hfp = dpi_para->hfp;
dpi_pec.vsw = dpi_para->vsw;
dpi_pec.vbp = dpi_para->vbp;
dpi_pec.vfp = dpi_para->vfp;
dpi_pec.data_latch_mode = LCD_PEC_DPI_DATA_LATCH_MODE;
dpi_pec.de_sig_enable = LCD_PEC_DPI_DE_MODE;
dpi_pec.de_sig_polarity = LCD_PEC_DPI_DE_SIN_POL;
dpi_pec.v_sync_sig_polarity = LCD_PEC_DPI_V_SYNC_SIN_POL;
dpi_pec.h_sync_sig_polarity = LCD_PEC_DPI_H_SYNC_SIN_POL;
dpi_pec.invalid_row_para = pec_dpi_invalid_lin_para;
dpi_pec.frame_rate = dpi_para->frame_rate;
dpi_pec.pin_clk = LCD_DPI_PEC_SIMU_PIN_CLK;
dpi_pec.pin_hs = LCD_DPI_PEC_SIMU_PIN_HSYNC;
dpi_pec.pin_data = LCD_DPI_PEC_SIMU_PIN_DATA_START;
dpi_pec.pec = PEC_ID_USE;
dpi_pec.sm = SM_ID_USE;
bflb_pec_dpi_init(&dpi_pec);
/* dma lli init */
pec_dpi_dma_lli_init(dpi_para);
pec_dpi_dma_lli_update(dpi_para->frame_buff);
/* init DMA */
pec_dpi_dma_handle = bflb_device_get_by_name(LCD_PEC_DPI_DMA_NAME);
struct bflb_dma_channel_config_s tx_config = {
.direction = DMA_MEMORY_TO_PERIPH,
.src_req = DMA_REQUEST_NONE,
.dst_req = DMA_REQUEST_PEC_USE,
.src_addr_inc = DMA_ADDR_INCREMENT_ENABLE,
.dst_addr_inc = DMA_ADDR_INCREMENT_DISABLE,
.src_burst_count = DMA_BURST_INCR4,
.dst_burst_count = DMA_BURST_INCR4,
.src_width = DMA_DATA_WIDTH_32BIT,
.dst_width = DMA_DATA_WIDTH_32BIT,
};
bflb_dma_channel_init(pec_dpi_dma_handle, &tx_config);
/* attach interrupt */
bflb_dma_channel_irq_attach(pec_dpi_dma_handle, pec_dpi_dma_interrupt, NULL);
/* update lli to register */
uint32_t channel_base = pec_dpi_dma_handle->reg_base;
putreg32(dma_lli_dpi_header.src_addr, channel_base + DMA_CxSRCADDR_OFFSET);
putreg32(dma_lli_dpi_header.dst_addr, channel_base + DMA_CxDSTADDR_OFFSET);
putreg32(dma_lli_dpi_header.nextlli, channel_base + DMA_CxLLI_OFFSET);
putreg32(dma_lli_dpi_header.control.WORD, channel_base + DMA_CxCONTROL_OFFSET);
/* start dma */
bflb_dma_channel_start(pec_dpi_dma_handle);
return 0;
}
int lcd_mipi_dpi_screen_switch(void *screen_buffer)
{
/* clean cache */
if (pix_format == LCD_MIPI_DPI_PIXEL_FORMAT_RGB565) {
bflb_l1c_dcache_clean_range((void *)(screen_buffer), width * height * 2);
} else if (pix_format == LCD_MIPI_DPI_PIXEL_FORMAT_NRGB888) {
bflb_l1c_dcache_clean_range((void *)(screen_buffer), width * height * 4);
}
next_disp_buffer = screen_buffer;
return 0;
}
void *lcd_mipi_dpi_get_screen_using(void)
{
return (void *)screen_last;
}
static void pec_dpi_dma_interrupt(void *arg)
{
uint8_t swap_flag = 0;
/* update dma for frame */
pec_dpi_dma_lli_update((void *)next_disp_buffer);
/* stop dma channel */
bflb_dma_channel_stop(pec_dpi_dma_handle);
/* update lli to register */
uint32_t channel_base = pec_dpi_dma_handle->reg_base;
putreg32(dma_lli_dpi_header.src_addr, channel_base + DMA_CxSRCADDR_OFFSET);
putreg32(dma_lli_dpi_header.dst_addr, channel_base + DMA_CxDSTADDR_OFFSET);
putreg32(dma_lli_dpi_header.nextlli, channel_base + DMA_CxLLI_OFFSET);
putreg32(dma_lli_dpi_header.control.WORD, channel_base + DMA_CxCONTROL_OFFSET);
/* start dma channel */
bflb_dma_channel_start(pec_dpi_dma_handle);
if (screen_last != next_disp_buffer) {
swap_flag = 1;
screen_last = next_disp_buffer;
}
if (lcd_mipi_dpi_frame_callback != NULL) {
lcd_mipi_dpi_frame_callback();
}
if (lcd_mipi_dpi_frame_swap_callback != 0 && swap_flag) {
lcd_mipi_dpi_frame_swap_callback();
}
}
int lcd_mipi_dpi_frame_callback_register(uint32_t callback_type, void (*callback)(void))
{
if (callback_type == LCD_MIPI_DPI_FRAME_INT_TYPE_SWAP) {
lcd_mipi_dpi_frame_swap_callback = callback;
} else if (callback_type == LCD_MIPI_DPI_FRAME_INT_TYPE_CYCLE) {
lcd_mipi_dpi_frame_callback = callback;
}
return 0;
}
static int pec_dpi_dma_lli_init(lcd_mipi_dpi_init_t *dpi_para)
{
uint16_t i, j;
uint32_t temp, dma_count;
/* get total number of dma_transfer */
if (dpi_para->pixel_format == LCD_MIPI_DPI_PIXEL_FORMAT_RGB565) {
dma_count = (dpi_para->width * dpi_para->height) * 2 / 4;
} else if (dpi_para->pixel_format == LCD_MIPI_DPI_PIXEL_FORMAT_NRGB888) {
dma_count = (dpi_para->width * dpi_para->height);
} else {
return -1;
}
if (dma_count == 0) {
return -1;
}
/* Initialize DMA and controls data lli */
dma_lli_dpi_header.control.bits.SBSize = DMA_BURST_INCR4;
dma_lli_dpi_header.control.bits.dst_min_mode = 0;
dma_lli_dpi_header.control.bits.DBSize = DMA_BURST_INCR4;
dma_lli_dpi_header.control.bits.dst_add_mode = 0;
dma_lli_dpi_header.control.bits.SWidth = DMA_DATA_WIDTH_32BIT;
dma_lli_dpi_header.control.bits.DWidth = DMA_DATA_WIDTH_32BIT;
dma_lli_dpi_header.control.bits.fix_cnt = 0;
dma_lli_dpi_header.control.bits.SI = DMA_ADDR_INCREMENT_ENABLE;
dma_lli_dpi_header.control.bits.DI = DMA_ADDR_INCREMENT_DISABLE;
dma_lli_dpi_header.control.bits.I = 0;
dma_lli_dpi_header.dst_addr = 0x2005A010; // PEC_BASE + PEC_TXF0_OFFSET + SM_ID_USE * 4;
dma_lli_dpi_header.src_addr = (uint32_t)(uintptr_t)pec_dpi_invalid_lin_para;
dma_lli_dpi_header.control.bits.TransferSize = (dpi_para->vsw + dpi_para->vbp) * 2 + 1;
dma_lli_dpi_header.nextlli = (uint32_t)(uintptr_t)NULL;
dma_dpi_lli_tail = dma_lli_dpi_header;
dma_dpi_lli_tail.control.bits.I = 1;
dma_dpi_lli_tail.src_addr = (uint32_t)(uintptr_t)&pec_dpi_invalid_lin_para[(dpi_para->vsw + dpi_para->vbp + 1) * 2];
dma_dpi_lli_tail.control.bits.TransferSize = dpi_para->vfp * 2;
bflb_l1c_dcache_clean_range(pec_dpi_invalid_lin_para, sizeof(pec_dpi_invalid_lin_para));
bflb_l1c_dcache_clean_range((void *)&dma_dpi_lli_tail, sizeof(dma_dpi_lli_tail));
/* Initialize display buffer data lli, but do not load data */
dma_lli_dpi_pool[0][0].control.bits.SBSize = DMA_BURST_INCR4;
dma_lli_dpi_pool[0][0].control.bits.dst_min_mode = 0;
dma_lli_dpi_pool[0][0].control.bits.DBSize = DMA_BURST_INCR4;
dma_lli_dpi_pool[0][0].control.bits.dst_add_mode = 0;
dma_lli_dpi_pool[0][0].control.bits.SWidth = DMA_DATA_WIDTH_32BIT;
dma_lli_dpi_pool[0][0].control.bits.DWidth = DMA_DATA_WIDTH_32BIT;
dma_lli_dpi_pool[0][0].control.bits.fix_cnt = 0;
dma_lli_dpi_pool[0][0].control.bits.SI = DMA_ADDR_INCREMENT_ENABLE;
dma_lli_dpi_pool[0][0].control.bits.DI = DMA_ADDR_INCREMENT_DISABLE;
dma_lli_dpi_pool[0][0].control.bits.I = 0;
dma_lli_dpi_pool[0][0].dst_addr = 0x2005A010; //PEC_BASE + PEC_TXF0_OFFSET + SM_ID_USE * 4;
dma_lli_dpi_pool[0][0].src_addr = (uint32_t)(uintptr_t)(NULL);
dma_lli_dpi_pool[0][0].control.bits.TransferSize = DMA_MAX_COUNT;
dma_lli_dpi_pool[0][0].nextlli = (uint32_t)(uintptr_t)NULL;
for (i = 0; i < LCD_DPI_PEC_DMA_LLI_CACHE_NUM; i++) {
temp = dma_count;
for (j = 0; temp > 0; j++) {
dma_lli_dpi_pool[i][j] = dma_lli_dpi_pool[0][0];
dma_lli_dpi_pool[i][j].nextlli = (uint32_t)(uintptr_t)(&dma_lli_dpi_pool[i][j + 1]);
temp = (temp > DMA_MAX_COUNT) ? (temp - DMA_MAX_COUNT) : (0);
}
dma_lli_dpi_pool[i][j - 1].nextlli = (uint32_t)(uintptr_t)(&dma_dpi_lli_tail);
dma_lli_dpi_pool[i][j - 1].control.bits.TransferSize = dma_count % DMA_MAX_COUNT;
bflb_l1c_dcache_clean_range((void *)dma_lli_dpi_pool[i], sizeof(struct bflb_dma_channel_lli_pool_s) * (j + 1));
}
pec_dpi_dma_lli_num = j;
for (i = 0; i < LCD_DPI_PEC_DMA_LLI_CACHE_NUM; i++) {
dma_lli_cache_table[i].disp_buff = NULL;
dma_lli_cache_table[i].dma_lli = dma_lli_dpi_pool[i];
dma_lli_cache_table[i].lru_value = LCD_DPI_PEC_DMA_LLI_CACHE_NUM;
}
return 0;
}
static int pec_dpi_dma_lli_update(void *disp_buff)
{
uint16_t idx, idx_oldest = 0, lru_v = 0;
/* Looking for the cache table */
for (idx = 0; idx < LCD_DPI_PEC_DMA_LLI_CACHE_NUM; idx++) {
if (dma_lli_cache_table[idx].disp_buff == disp_buff) {
lru_v = dma_lli_cache_table[idx].lru_value;
break;
} else if (dma_lli_cache_table[idx].lru_value > lru_v) {
lru_v = dma_lli_cache_table[idx].lru_value;
idx_oldest = idx;
}
}
/* Not cached, Add to the cache table */
if (idx >= LCD_DPI_PEC_DMA_LLI_CACHE_NUM) {
idx = idx_oldest;
/* update dma lli */
struct bflb_dma_channel_lli_pool_s *lli_p = dma_lli_cache_table[idx].dma_lli;
for (uint16_t i = 0; i < pec_dpi_dma_lli_num; i++) {
lli_p[i].src_addr = (uint32_t)(uintptr_t)(disp_buff) + (i * DMA_MAX_COUNT * 4);
}
bflb_l1c_dcache_clean_range((void *)lli_p, sizeof(struct bflb_dma_channel_lli_pool_s) * pec_dpi_dma_lli_num);
dma_lli_cache_table[idx].disp_buff = disp_buff;
}
dma_lli_dpi_header.nextlli = (uint32_t)(uintptr_t)(dma_lli_cache_table[idx].dma_lli);
/* update cache table lru_value */
dma_lli_cache_table[idx].lru_value = 0;
for (idx = 0; idx < LCD_DPI_PEC_DMA_LLI_CACHE_NUM; idx++) {
if (dma_lli_cache_table[idx].lru_value < lru_v) {
dma_lli_cache_table[idx].lru_value++;
}
}
return 0;
}
#else
#error "Devices that do not support PEC-DPI! Replace the driver port (lcd_conf.h)"
#endif
#endif

View file

@ -0,0 +1,89 @@
/**
* @file bl_mipi_dpi.c
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#ifndef _BL_MIPI_DPI_H_
#define _BL_MIPI_DPI_H_
#include "../lcd_conf.h"
#if defined LCD_PEC_SIMU_DPI_ENABLE
/* Do not modify this file ! */
#define LCD_MIPI_DPI_PIXEL_FORMAT_RGB565 0
#define LCD_MIPI_DPI_PIXEL_FORMAT_NRGB888 1
#define LCD_MIPI_DPI_FRAME_INT_TYPE_CYCLE 0
#define LCD_MIPI_DPI_FRAME_INT_TYPE_SWAP 1
typedef struct {
uint16_t width; /* LCD Active Width */
uint16_t height; /* LCD Active Height */
/* Total Width = HSW + HBP + Active_Width + HFP */
uint16_t hsw; /* LCD HSW (Hsync Pulse Width) */
uint16_t hbp; /* LCD HBP (Hsync Back Porch) */
uint16_t hfp; /* LCD HFP (Hsync Front Porch) */
/* Total Height = VSW + VBP + Active_Height + VFP */
uint16_t vsw; /* LCD VSW (Vsync Pulse Width) */
uint16_t vbp; /* LCD VBP (Vsync Back Porch) */
uint16_t vfp; /* LCD VFP (Vsync Front Porch) */
uint16_t frame_rate; /* Maximum refresh frame rate per second, Used to automatically calculate the clock frequency */
uint16_t pixel_format;
void *frame_buff; /* The frame buffer */
} lcd_mipi_dpi_init_t;
typedef struct {
void *disp_buff;
void *dma_lli;
uint16_t lru_value;
} pec_dpi_dma_lli_cache_t;
/* PEC select */
#define PEC_ID_USE PEC0
#define SM_ID_USE PEC_SM0
/* DMA select */
#define DMA_MAX_COUNT 4032
#define DMA_REQUEST_PEC_USE DMA_REQUEST_PEC0_SM0_TX
#if ((defined ILI9488_DPI_MODE) && (ILI9488_DPI_MODE == 2))
#define DPI_PEC_VALID_PIXEL_MAX (ILI9488_DPI_W * ILI9488_DPI_H)
#elif ((defined GC9503V_DPI_MODE) && (GC9503V_DPI_MODE == 2))
#define DPI_PEC_VALID_PIXEL_MAX (GC9503V_DPI_W * GC9503V_DPI_H)
#elif ((defined STANDARD_DPI_MODE) && (STANDARD_DPI_MODE == 2))
#define DPI_PEC_VALID_PIXEL_MAX (STANDARD_DPI_W * STANDARD_DPI_W)
#else
/* Maximum number of DPI valid pixels, >= (Width * Height) */
#define DPI_PEC_VALID_PIXEL_MAX (800 * 480)
#endif
int lcd_mipi_dpi_init(lcd_mipi_dpi_init_t *dpi_para);
int lcd_mipi_dpi_screen_switch(void *screen_buffer);
void *lcd_mipi_dpi_get_screen_using(void);
int lcd_mipi_dpi_frame_callback_register(uint32_t callback_type, void (*callback)(void));
#endif
#endif

View file

@ -0,0 +1,223 @@
/**
* @file gc9503v_dpi.c
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#include "../lcd.h"
#if defined(LCD_DPI_GC9503V)
#include "gc9503v_dpi.h"
#include "bl_mipi_dpi_pec.h"
#include "bflb_mtimer.h"
#include "bflb_gpio.h"
/* mipi dpi (RGB) paramant */
static lcd_mipi_dpi_init_t dpi_para = {
.width = GC9503V_DPI_W, /* LCD Active Width */
.height = GC9503V_DPI_H, /* LCD Active Height */
/* Total Width = HSW + HBP + Active_Width + HFP */
.hsw = 10, /* LCD HSW (Hsync Pulse Width) */
.hbp = 10, /* LCD HBP (Hsync Back Porch) */
.hfp = 10, /* LCD HFP (Hsync Front Porch) */
/* Total Height = VSW + VBP + Active_Height + VFP */
.vsw = 3, /* LCD VSW (Vsync Pulse Width) */
.vbp = 12, /* LCD VBP (Vsync Back Porch) */
.vfp = 14, /* LCD VFP (Vsync Front Porch) */
.frame_rate = 60, /* Maximum refresh frame rate per second, Used to automatically calculate the clock frequency */
#if (GC9503V_DPI_PIXEL_FORMAT == 1)
.pixel_format = LCD_MIPI_DPI_PIXEL_FORMAT_RGB565,
#endif
.frame_buff = NULL,
};
#if (GC9503V_DPI_INIT_INTERFACE == 1)
static struct bflb_device_s *gc9503v_gpio;
/* gpio spi init */
static void gc9503v_soft_spi_init(void)
{
/* gpio24 spi clk init */
/* gpio25 spi mosi init */
/* gpio12 spi cs init */
gc9503v_gpio = bflb_device_get_by_name("gpio");
bflb_gpio_init(gc9503v_gpio, GC9503V_DPI_SPI_CS_PIN, GPIO_OUTPUT | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_2);
bflb_gpio_init(gc9503v_gpio, GC9503V_DPI_SPI_CLK_PIN, GPIO_OUTPUT | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_2);
bflb_gpio_init(gc9503v_gpio, GC9503V_DPI_SPI_DAT_PIN, GPIO_OUTPUT | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_2);
GC9503V_SPI_CS_HIGH;
GC9503V_SPI_CLK_HIGH;
GC9503V_SPI_MOSI_HIGH;
}
/* gpio spi send byte */
static ATTR_TCM_SECTION void spi_send_byte(uint8_t data)
{
for (uint32_t i = 0; i < 8; i++) {
GC9503V_SPI_CLK_LOW;
if (data & 0x80) {
GC9503V_SPI_MOSI_HIGH;
} else {
GC9503V_SPI_MOSI_LOW;
}
GC9503V_SPI_CLK_HIGH;
data <<= 1;
DUMMY_DELAY;
}
}
/* spi write cmd */
static ATTR_TCM_SECTION int gc9503v_spi_write_cmd(uint8_t cmd)
{
GC9503V_SPI_CLK_LOW;
GC9503V_SPI_CS_LOW;
GC9503V_SPI_MOSI_LOW;
GC9503V_SPI_CLK_HIGH;
spi_send_byte(cmd);
GC9503V_SPI_CLK_LOW;
GC9503V_SPI_CS_HIGH;
GC9503V_SPI_MOSI_HIGH;
return 0;
}
/* spi write data */
static ATTR_TCM_SECTION int gc9503v_spi_write_data_byte(uint8_t data)
{
GC9503V_SPI_CLK_LOW;
GC9503V_SPI_CS_LOW;
GC9503V_SPI_MOSI_HIGH;
GC9503V_SPI_CLK_HIGH;
spi_send_byte(data);
GC9503V_SPI_CLK_LOW;
GC9503V_SPI_CS_HIGH;
GC9503V_SPI_MOSI_HIGH;
return 0;
}
#endif
static const gc9503v_dpi_init_cmd_t gc9503v_dpi_mode_init_cmds[] = {
{ 0x10, NULL, 0 }, /* enter sleep mode */
{ 0xF0, "\x55\xAA\x52\x08\x00", 5 },
{ 0xF6, "\x5A\x87", 2 },
{ 0xC1, "\x3F", 1 },
{ 0xC2, "\x0E", 1 },
{ 0xC6, "\xF8", 1 },
{ 0xC9, "\x10", 1 },
{ 0xCD, "\x25", 1 },
{ 0xF8, "\x8A", 1 },
{ 0xAC, "\x45", 1 },
{ 0xA0, "\xDD", 1 },
{ 0xA7, "\x47", 1 },
{ 0xFA, "\x00\x00\x00\x04", 4 },
{ 0xA3, "\xEE", 1 },
{ 0xFD, "\x28\x28\x00", 3 },
{ 0x71, "\x48", 1 },
{ 0x72, "\x48", 1 },
{ 0x73, "\x00\x44", 2 },
{ 0x97, "\xEE", 1 },
{ 0x83, "\x93", 1 },
{ 0x9A, "\x72", 1 },
{ 0x9B, "\x5A", 1 },
{ 0x82, "\x2C\x2C", 2 },
{ 0xB1, "\x10", 1 },
{ 0x6D, "\x00\x1F\x19\x1A\x10\x0E\x0C\x0A\x02\x07\x1E\x1E\x1E\x1E\x1E\x1E\x1E\x1E\x1E\x1E\x1E\x1E\x08\x01\x09\x0B\x0D\x0F\x1A\x19\x1F\x00", 32 },
{ 0x64, "\x38\x05\x01\xDB\x03\x03\x38\x04\x01\xDC\x03\x03\x7A\x7A\x7A\x7A", 16 },
{ 0x65, "\x38\x03\x01\xDD\x03\x03\x38\x02\x01\xDE\x03\x03\x7A\x7A\x7A\x7A", 16 },
{ 0x66, "\x38\x01\x01\xDF\x03\x03\x38\x00\x01\xE0\x03\x03\x7A\x7A\x7A\x7A", 16 },
{ 0x67, "\x30\x01\x01\xE1\x03\x03\x30\x02\x01\xE2\x03\x03\x7A\x7A\x7A\x7A", 16 },
{ 0x68, "\x00\x08\x15\x08\x15\x7A\x7A\x08\x15\x08\x15\x7A\x7A", 13 },
{ 0x60, "\x38\x08\x7A\x7A\x38\x09\x7A\x7A", 8 },
{ 0x63, "\x31\xE4\x7A\x7A\x31\xE5\x7A\x7A", 8 },
{ 0x6B, "\x07", 1 },
{ 0x7A, "\x08\x13", 2 },
{ 0x7B, "\x08\x13", 2 },
{ 0xD1, "\x00\x00\x00\x04\x00\x12\x00\x18\x00\x21\x00\x2A\x00\x35\x00\x47\x00\x56\x00\x90\x00\xE5\x01\x68\x01\xD5\x01\xD7\x02\x36\x02\xA6\x02\xEE\x03\x48\x03\xA0\x03\xBA\x03\xC5\x03\xD0\x03\xE0\x03\xEA\x03\xFA\x03\xFF", 52 },
{ 0xD2, "\x00\x00\x00\x04\x00\x12\x00\x18\x00\x21\x00\x2A\x00\x35\x00\x47\x00\x56\x00\x90\x00\xE5\x01\x68\x01\xD5\x01\xD7\x02\x36\x02\xA6\x02\xEE\x03\x48\x03\xA0\x03\xBA\x03\xC5\x03\xD0\x03\xE0\x03\xEA\x03\xFA\x03\xFF", 52 },
{ 0xD3, "\x00\x00\x00\x04\x00\x12\x00\x18\x00\x21\x00\x2A\x00\x35\x00\x47\x00\x56\x00\x90\x00\xE5\x01\x68\x01\xD5\x01\xD7\x02\x36\x02\xA6\x02\xEE\x03\x48\x03\xA0\x03\xBA\x03\xC5\x03\xD0\x03\xE0\x03\xEA\x03\xFA\x03\xFF", 52 },
{ 0xD4, "\x00\x00\x00\x04\x00\x12\x00\x18\x00\x21\x00\x2A\x00\x35\x00\x47\x00\x56\x00\x90\x00\xE5\x01\x68\x01\xD5\x01\xD7\x02\x36\x02\xA6\x02\xEE\x03\x48\x03\xA0\x03\xBA\x03\xC5\x03\xD0\x03\xE0\x03\xEA\x03\xFA\x03\xFF", 52 },
{ 0xD5, "\x00\x00\x00\x04\x00\x12\x00\x18\x00\x21\x00\x2A\x00\x35\x00\x47\x00\x56\x00\x90\x00\xE5\x01\x68\x01\xD5\x01\xD7\x02\x36\x02\xA6\x02\xEE\x03\x48\x03\xA0\x03\xBA\x03\xC5\x03\xD0\x03\xE0\x03\xEA\x03\xFA\x03\xFF", 52 },
{ 0xD6, "\x00\x00\x00\x04\x00\x12\x00\x18\x00\x21\x00\x2A\x00\x35\x00\x47\x00\x56\x00\x90\x00\xE5\x01\x68\x01\xD5\x01\xD7\x02\x36\x02\xA6\x02\xEE\x03\x48\x03\xA0\x03\xBA\x03\xC5\x03\xD0\x03\xE0\x03\xEA\x03\xFA\x03\xFF", 52 },
{ 0x3A, "\x66", 1 }, /* pixel format set 16bits:0x55;18bits:0x66 */
{ 0x11, NULL, 0 }, /* sleep out */
{ 0xFF, NULL, 200 }, /* delay 200ms */
{ 0x29, NULL, 0 }, /* display on */
{ 0xFF, NULL, 30 }, /* delay 30ms */
};
int ATTR_TCM_SECTION gc9503v_dpi_init(gc9503v_dpi_color_t *screen_buffer)
{
#if (GC9503V_DPI_INIT_INTERFACE == 1)
/* spi init */
gc9503v_soft_spi_init();
for (uint16_t i = 0; i < (sizeof(gc9503v_dpi_mode_init_cmds) / sizeof(gc9503v_dpi_init_cmd_t)); i++) {
if ((gc9503v_dpi_mode_init_cmds[i].cmd == 0xFF) && (gc9503v_dpi_mode_init_cmds[i].data == NULL) && (gc9503v_dpi_mode_init_cmds[i].databytes)) {
bflb_mtimer_delay_ms(gc9503v_dpi_mode_init_cmds[i].databytes);
} else {
/* send register address */
gc9503v_spi_write_cmd(gc9503v_dpi_mode_init_cmds[i].cmd);
bflb_mtimer_delay_us(22);
/* send register data */
for (uint8_t j = 0; j < (gc9503v_dpi_mode_init_cmds[i].databytes); j++) {
gc9503v_spi_write_data_byte(gc9503v_dpi_mode_init_cmds[i].data[j]);
bflb_mtimer_delay_us(22);
}
}
}
#endif
/* mipi dpi init */
if (screen_buffer == NULL) {
return -1;
}
dpi_para.frame_buff = (void *)screen_buffer;
return lcd_mipi_dpi_init(&dpi_para);
}
int gc9503v_dpi_screen_switch(gc9503v_dpi_color_t *screen_buffer)
{
return lcd_mipi_dpi_screen_switch((void *)screen_buffer);
}
gc9503v_dpi_color_t *gc9503v_dpi_get_screen_using(void)
{
return (gc9503v_dpi_color_t *)lcd_mipi_dpi_get_screen_using();
}
int gc9503v_dpi_frame_callback_register(uint32_t callback_type, void (*callback)(void))
{
if (callback_type == FRAME_INT_TYPE_CYCLE) {
lcd_mipi_dpi_frame_callback_register(LCD_MIPI_DPI_FRAME_INT_TYPE_CYCLE, callback);
} else if (callback_type == FRAME_INT_TYPE_SWAP) {
lcd_mipi_dpi_frame_callback_register(LCD_MIPI_DPI_FRAME_INT_TYPE_SWAP, callback);
}
return 0;
}
#endif

View file

@ -0,0 +1,86 @@
/**
* @file gc9503v_dpi.h
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#ifndef _GC9503V_DPI_H_
#define _GC9503V_DPI_H_
#include "../lcd_conf.h"
/* Do not modify the following information */
#if defined LCD_DPI_GC9503V
#if (GC9503V_DPI_INIT_INTERFACE == 1)
/* Software spi 9-bit mode PIN */
#define GC9503V_SPI_CS_HIGH bflb_gpio_set(gc9503v_gpio, GC9503V_DPI_SPI_CS_PIN)
#define GC9503V_SPI_CS_LOW bflb_gpio_reset(gc9503v_gpio, GC9503V_DPI_SPI_CS_PIN)
#define GC9503V_SPI_CLK_HIGH bflb_gpio_set(gc9503v_gpio, GC9503V_DPI_SPI_CLK_PIN)
#define GC9503V_SPI_CLK_LOW bflb_gpio_reset(gc9503v_gpio, GC9503V_DPI_SPI_CLK_PIN)
#define GC9503V_SPI_MOSI_HIGH bflb_gpio_set(gc9503v_gpio, GC9503V_DPI_SPI_DAT_PIN)
#define GC9503V_SPI_MOSI_LOW bflb_gpio_reset(gc9503v_gpio, GC9503V_DPI_SPI_DAT_PIN)
#define DUMMY_DELAY \
asm volatile("nop"); \
asm volatile("nop"); \
asm volatile("nop"); \
asm volatile("nop"); \
asm volatile("nop"); \
asm volatile("nop"); \
asm volatile("nop"); \
asm volatile("nop"); \
asm volatile("nop"); \
asm volatile("nop"); \
asm volatile("nop"); \
asm volatile("nop"); \
asm volatile("nop"); \
asm volatile("nop");
#endif
#if (GC9503V_DPI_PIXEL_FORMAT == 1)
#define GC9503V_DPI_COLOR_DEPTH 16
typedef uint16_t gc9503v_dpi_color_t;
#elif (GC9503V_DPI_PIXEL_FORMAT == 2)
#define GC9503V_DPI_COLOR_DEPTH 32
typedef uint32_t gc9503v_dpi_color_t;
#else
#error "GC9503V pixel format select error"
#endif
/* Gc9503v needs to be initialized using the DBI(typeC) or SPI interface */
typedef struct {
uint8_t cmd; /* 0xFF : delay(databytes)ms */
const char *data;
uint8_t databytes; /* Num of data in data; or delay time */
} gc9503v_dpi_init_cmd_t;
int gc9503v_dpi_init(gc9503v_dpi_color_t *screen_buffer);
int gc9503v_dpi_screen_switch(gc9503v_dpi_color_t *screen_buffer);
gc9503v_dpi_color_t *gc9503v_dpi_get_screen_using(void);
int gc9503v_dpi_frame_callback_register(uint32_t callback_type, void (*callback)(void));
#endif
#endif

View file

@ -0,0 +1,240 @@
/**
* @file ili9488_dpi.c
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#include "../lcd.h"
#if defined(LCD_DPI_ILI9488)
#include "bflb_mtimer.h"
#include "bflb_gpio.h"
#include "ili9488_dpi.h"
#include "bl_mipi_dpi_pec.h"
#if (ILI9488_DPI_INIT_INTERFACE == 2)
#if defined(BL808)
#include "bl808_dbi.h"
#elif defined(BL616)
#include "bl616_dbi.h"
#endif
#elif (ILI9488_DPI_INIT_INTERFACE == 1)
#include "bflb_spi.h"
// #define ILI9488_SPI_INDEX SPI0_INDEX
#define ILI9488_SPI_ID 0
#define ILI9488_SPI_NAME "spi0"
#endif
/* mipi dpi (RGB) paramant */
static lcd_mipi_dpi_init_t dpi_para = {
.width = ILI9488_DPI_W, /* LCD Active Width */
.height = ILI9488_DPI_H, /* LCD Active Height */
/* Total Width = HSW + HBP + Active_Width + HFP */
.hsw = 4, /* LCD HSW (Hsync Pulse Width) */
.hbp = 4, /* LCD HBP (Hsync Back Porch) */
.hfp = 12, /* LCD HFP (Hsync Front Porch) */
/* Total Height = VSW + VBP + Active_Height + VFP */
.vsw = 6, /* LCD VSW (Vsync Pulse Width) */
.vbp = 6, /* LCD VBP (Vsync Back Porch) */
.vfp = 18, /* LCD VFP (Vsync Front Porch) */
.frame_rate = 60, /* Maximum refresh frame rate per second, Used to automatically calculate the clock frequency */
#if (ILI9488_DPI_PIXEL_FORMAT == 1)
.pixel_format = LCD_MIPI_DPI_PIXEL_FORMAT_RGB565,
#endif
.frame_buff = NULL,
};
#if (ILI9488_DPI_INIT_INTERFACE == 2)
/* dbi config */
static DBI_CFG_Type dbiCfg = {
.mode = DBI_TYPE_C_4_WIRE, /* DBI type B or C select */
.pixelFormat = DBI_PIXEL_RGB888, /* DBI pixel format */
.fifoFormat = DBI_FIFO_888_NBGR, /* DBI fifo format */
.continueEn = ENABLE, /* Enable:CS will stay asserted between each consecutive pixel, disable:CS will de-assert between each pixel */
.dummyEn = DISABLE, /* Enable:dummy cycle will be inserted between command phase adn data phase, disable:no dummy cycle */
.dummyCnt = 0, /* Dummy cycle count,effective only in type C(fixed to 1 in type B) */
.clkPhase = DBI_SCL_CLK_PHASE_0, /* DBI clock phase */
.clkPolarity = DBI_SCL_CLK_POLARITY_LOW, /* DBI clock polarity */
.period.startLen = 9,
.period.dataPhase0Len = 9,
.period.dataPhase1Len = 9,
.period.intervalLen = 9
};
#elif (ILI9488_DPI_INIT_INTERFACE == 1)
static struct bflb_device_s *ili9488_gpio;
static struct bflb_device_s *ili9488_spi;
/* spi write cmd */
static int ili9488_spi_write_cmd(uint8_t cmd)
{
ILI9488_SPI_DC_LOW;
ILI9488_SPI_CS_LOW;
bflb_spi_poll_send(ili9488_spi, cmd);
ILI9488_SPI_CS_HIGH;
ILI9488_SPI_DC_HIGH;
return 0;
}
/* spi write data */
static int ili9488_spi_write_data_byte(uint8_t data)
{
ILI9488_SPI_CS_LOW;
bflb_spi_poll_send(ili9488_spi, data);
ILI9488_SPI_CS_HIGH;
return 0;
}
#endif
static const ili9488_dpi_init_cmd_t ili9488_dpi_mode_init_cmds[] = {
{ 0x01, NULL, 0 }, /* software reset */
{ 0xFF, NULL, 10 }, /* delay 10ms */
{ 0x11, NULL, 0 }, /* Sleep Out */
{ 0xFF, NULL, 120 }, /* delay 120ms */
{ 0xE0, "\x00\x07\x0F\x0D\x1B\x0A\x3C\x78\x4A\x07\x0E\x09\x1B\x1E\x0F", 15 }, /* PGAMCTRL (Positive Gamma Control) */
{ 0xE1, "\x00\x22\x24\x26\x12\x07\x36\x47\x47\x06\x0A\x07\x30\x37\x0F", 15 }, /* NGAMCTRL (Negative Gamma Control) */
{ 0xC0, "\x10\x10", 2 }, /* Power Control 1 */
{ 0xC1, "\x41", 1 }, /* Power Control 2 */
{ 0xC5, "\x00\x20\xd0", 3 }, /* VCOM Control */
{ 0x36, "\x08", 1 }, /* Memory Access Control */
{ 0x3A, "\x50", 1 }, /* Interface Pixel 16bits/pixel*/
{ 0xB0, "\x00", 1 }, /* Interface Mode Control */
{ 0xB1, "\xB0", 1 }, /* Frame rate 70Hz */
{ 0xB4, "\x02", 1 }, /* Display Inversion Control */
// { 0xB5, "\x08\x08\x06\x12", 4},/* Display Inversion Control */
{ 0xB6, "\x30\x22\x3B", 3 }, /* Display Function Control, DE Mode */
{ 0xBE, "\x00\x04", 1 },
{ 0xE9, "\x00", 1 }, /* Set Image Function */
{ 0xF7, "\xA9\x51\x2C\x82", 4 }, /* Adjust Control 3 */
{ 0x29, NULL, 0 }, /* Display On */
{ 0xFF, NULL, 10 },
};
int ili9488_dpi_init(ili9488_dpi_color_t *screen_buffer)
{
/* Ili9488 needs to be initialized using the DBI(typeC) or SPI interface */
#if (ILI9488_DPI_INIT_INTERFACE == 2)
DBI_Init(&dbiCfg);
for (uint16_t i = 0; i < (sizeof(ili9488_dpi_mode_init_cmds) / sizeof(ili9488_dpi_init_cmd_t)); i++) {
if (ili9488_dpi_mode_init_cmds[i].cmd == 0xFF) {
bflb_mtimer_delay_ms(ili9488_dpi_mode_init_cmds[i].databytes);
} else {
DBI_SetPhaseState(ENABLE, DISABLE);
DBI_SendCmdWithNormalData(ili9488_dpi_mode_init_cmds[i].cmd, 0, NULL);
DBI_SetPhaseState(DISABLE, ENABLE);
for (uint8_t j = 0; j < ili9488_dpi_mode_init_cmds[i].databytes; j++) {
DBI_SendCmdWithNormalData(0xFF, 1, (uint8_t *)&ili9488_dpi_mode_init_cmds[i].data[j]);
}
}
}
DBI_SetPhaseState(DISABLE, DISABLE);
#elif (ILI9488_DPI_INIT_INTERFACE == 1)
/* spi */
struct bflb_spi_config_s spi_cfg = {
.freq = 8 * 1000 * 1000,
.role = SPI_ROLE_MASTER,
.mode = SPI_MODE3,
.data_width = SPI_DATA_WIDTH_8BIT,
.bit_order = SPI_BIT_MSB,
.byte_order = SPI_BYTE_LSB,
.tx_fifo_threshold = 0,
.rx_fifo_threshold = 0,
};
/* CS and DC pin init */
ili9488_gpio = bflb_device_get_by_name("gpio");
bflb_gpio_init(ili9488_gpio, ILI9488_DPI_SPI_CS_PIN, GPIO_OUTPUT | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1);
bflb_gpio_init(ili9488_gpio, ILI9488_DPI_SPI_DC_PIN, GPIO_OUTPUT | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1);
ILI9488_SPI_CS_HIGH;
ILI9488_SPI_DC_HIGH;
/* spi init */
ili9488_spi = bflb_device_get_by_name(ILI9488_SPI_NAME);
bflb_spi_init(ili9488_spi, &spi_cfg);
for (uint16_t i = 0; i < (sizeof(ili9488_dpi_mode_init_cmds) / sizeof(ili9488_dpi_init_cmd_t)); i++) {
if ((ili9488_dpi_mode_init_cmds[i].cmd == 0xFF) && (ili9488_dpi_mode_init_cmds[i].data == NULL) && (ili9488_dpi_mode_init_cmds[i].databytes)) {
bflb_mtimer_delay_ms(ili9488_dpi_mode_init_cmds[i].databytes);
} else {
/* send register address */
ili9488_spi_write_cmd(ili9488_dpi_mode_init_cmds[i].cmd);
/* send register data */
for (uint8_t j = 0; j < (ili9488_dpi_mode_init_cmds[i].databytes & 0x7F); j++) {
ili9488_spi_write_data_byte(ili9488_dpi_mode_init_cmds[i].data[j]);
}
}
}
#endif
if (screen_buffer == NULL) {
return -1;
}
/* mipi dpi init */
dpi_para.frame_buff = (void *)screen_buffer;
return lcd_mipi_dpi_init(&dpi_para);
}
int ili9488_dpi_screen_switch(ili9488_dpi_color_t *screen_buffer)
{
return lcd_mipi_dpi_screen_switch((void *)screen_buffer);
}
ili9488_dpi_color_t *ili9488_dpi_get_screen_using(void)
{
return (ili9488_dpi_color_t *)lcd_mipi_dpi_get_screen_using();
}
int ili9488_dpi_frame_callback_register(uint32_t callback_type, void (*callback)(void))
{
if (callback_type == FRAME_INT_TYPE_CYCLE) {
lcd_mipi_dpi_frame_callback_register(LCD_MIPI_DPI_FRAME_INT_TYPE_CYCLE, callback);
} else if (callback_type == FRAME_INT_TYPE_SWAP) {
lcd_mipi_dpi_frame_callback_register(LCD_MIPI_DPI_FRAME_INT_TYPE_SWAP, callback);
}
return 0;
}
#endif

View file

@ -0,0 +1,66 @@
/**
* @file ili9488_dpi.h
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#ifndef _ILI9488_DPI_H_
#define _ILI9488_DPI_H_
#include "../lcd_conf.h"
/* Do not modify the following information */
#if defined LCD_DPI_ILI9488
/* Select SPI Initialize interface pin */
#if ILI9488_DPI_INIT_INTERFACE == 1
#define ILI9488_SPI_CS_HIGH bflb_gpio_set(ili9488_gpio, ILI9488_DPI_SPI_CS_PIN)
#define ILI9488_SPI_CS_LOW bflb_gpio_reset(ili9488_gpio, ILI9488_DPI_SPI_CS_PIN)
#define ILI9488_SPI_DC_HIGH bflb_gpio_set(ili9488_gpio, ILI9488_DPI_SPI_DC_PIN)
#define ILI9488_SPI_DC_LOW bflb_gpio_reset(ili9488_gpio, ILI9488_DPI_SPI_DC_PIN)
#endif
#if (ILI9488_DPI_PIXEL_FORMAT == 1)
#define ILI9488_DPI_COLOR_DEPTH 16
typedef uint16_t ili9488_dpi_color_t;
#elif (ILI9488_DPI_PIXEL_FORMAT == 2)
#define ILI9488_DPI_COLOR_DEPTH 32
typedef uint32_t ili9488_dpi_color_t;
#else
#error "ILI9488 pixel format select error"
#endif
/* Ili9488 needs to be initialized using the DBI(typeC) or SPI interface */
typedef struct {
uint8_t cmd; /* 0xFF : delay(databytes)ms */
const char *data;
uint8_t databytes; /* Num of data in data; or delay time */
} ili9488_dpi_init_cmd_t;
int ili9488_dpi_init(ili9488_dpi_color_t *screen_buffer);
int ili9488_dpi_screen_switch(ili9488_dpi_color_t *screen_buffer);
ili9488_dpi_color_t *ili9488_dpi_get_screen_using(void);
int ili9488_dpi_frame_callback_register(uint32_t callback_type, void (*callback)(void));
#endif
#endif

View file

@ -0,0 +1,85 @@
/**
* @file standard_dpi.c
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#include "../lcd.h"
#if defined(LCD_DPI_STANDARD)
#include "standard_dpi.h"
#include "bl_mipi_dpi_pec.h"
/* mipi dpi (RGB) paramant */
static lcd_mipi_dpi_init_t dpi_para = {
.width = STANDARD_DPI_W, /* LCD Active Width */
.height = STANDARD_DPI_H, /* LCD Active Height */
/* Total Width = HSW + HBP + Active_Width + HFP */
.hsw = STANDARD_DPI_HSW, /* LCD HSW (Hsync Pulse Width) */
.hbp = STANDARD_DPI_HBP, /* LCD HBP (Hsync Back Porch) */
.hfp = STANDARD_DPI_HFP, /* LCD HFP (Hsync Front Porch) */
/* Total Height = VSW + VBP + Active_Height + VFP */
.vsw = STANDARD_DPI_VSW, /* LCD VSW (Vsync Pulse Width) */
.vbp = STANDARD_DPI_VBP, /* LCD VBP (Vsync Back Porch) */
.vfp = STANDARD_DPI_VFP, /* LCD VFP (Vsync Front Porch) */
.frame_rate = STANDARD_DPI_FRAME_RATE, /* Maximum refresh frame rate per second, Used to automatically calculate the clock frequency */
#if (STANDARD_DPI_PIXEL_FORMAT == 1)
.pixel_format = LCD_MIPI_DPI_PIXEL_FORMAT_RGB565,
#endif
.frame_buff = NULL,
};
int standard_dpi_init(standard_dpi_color_t *screen_buffer)
{
if (screen_buffer == NULL) {
return -1;
}
/* mipi dpi init */
dpi_para.frame_buff = (void *)screen_buffer;
return lcd_mipi_dpi_init(&dpi_para);
}
int standard_dpi_screen_switch(standard_dpi_color_t *screen_buffer)
{
return lcd_mipi_dpi_screen_switch((void *)screen_buffer);
}
standard_dpi_color_t *standard_dpi_get_screen_using(void)
{
return (standard_dpi_color_t *)lcd_mipi_dpi_get_screen_using();
}
int standard_dpi_frame_callback_register(uint32_t callback_type, void (*callback)(void))
{
if (callback_type == FRAME_INT_TYPE_CYCLE) {
lcd_mipi_dpi_frame_callback_register(LCD_MIPI_DPI_FRAME_INT_TYPE_CYCLE, callback);
} else if (callback_type == FRAME_INT_TYPE_SWAP) {
lcd_mipi_dpi_frame_callback_register(LCD_MIPI_DPI_FRAME_INT_TYPE_SWAP, callback);
}
return 0;
}
#endif

View file

@ -0,0 +1,47 @@
/**
* @file standard_dpi.h
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#ifndef _STANDARD_DBI_H_
#define _STANDARD_DBI_H_
#include "../lcd_conf.h"
#if defined LCD_DPI_STANDARD
/* Do not modify the following */
#if (STANDARD_DPI_PIXEL_FORMAT == 1)
#define STANDARD_DPI_COLOR_DEPTH 16
typedef uint16_t standard_dpi_color_t;
#elif (STANDARD_DPI_PIXEL_FORMAT == 2)
#define STANDARD_DPI_COLOR_DEPTH 32
typedef uint32_t standard_dpi_color_t;
#endif
int standard_dpi_init(standard_dpi_color_t *screen_buffer);
int standard_dpi_screen_switch(standard_dpi_color_t *screen_buffer);
standard_dpi_color_t *standard_dpi_get_screen_using(void);
int standard_dpi_frame_callback_register(uint32_t callback_type, void (*callback)(void));
#endif
#endif

View file

@ -0,0 +1,376 @@
#include "../lcd.h"
#if (defined(LCD_SPI_INTERFACE_TYPE) && (LCD_SPI_INTERFACE_TYPE == 1))
#if (__has_include("bflb_spi.h"))
#include "bl_spi_hard_4.h"
#include "bflb_spi.h"
#include "bflb_dma.h"
#include "bflb_gpio.h"
#include "bflb_l1c.h"
#define LCD_SPI_HARD_4_DMA_LLI_NUM (LCD_SPI_HARD_4_PIXEL_CNT_MAX / 4064 + 1)
/* asynchronous flush interrupt callback */
typedef void (*spi_callback)(void);
static volatile spi_callback spi_async_callback = NULL;
static volatile bool spi_async_callback_en_flag = true;
/* dma device */
static struct bflb_device_s *spi_dma_hd;
/* spi */
static struct bflb_device_s *spi_hd;
/* goio */
static struct bflb_device_s *gpio;
/* The memory space of DMA */
static struct bflb_dma_channel_lli_pool_s dma_tx_llipool[LCD_SPI_HARD_4_DMA_LLI_NUM];
static struct bflb_dma_channel_lli_transfer_s dma_tx_transfers[1];
static uint32_t spi_tx_fifo_address;
static volatile bool spi_async_flag = false;
static volatile bool spi_async_cycle_fill_flag = false;
static uint8_t pixel_format;
static void spi_dma_callback(void *arg)
{
/* Wait for the SPI bus to be idle */
while (bflb_spi_isbusy(spi_hd)) {
__ASM volatile("nop");
};
/* Switch the SPI to non-DMA mode */
bflb_spi_link_txdma(spi_hd, false);
/* clear rx fifo */
bflb_spi_feature_control(spi_hd, SPI_CMD_CLEAR_RX_FIFO, 0);
LCD_SPI_HARD_4_CS_HIGH;
/* 8-bit data */
bflb_spi_feature_control(spi_hd, SPI_CMD_SET_DATA_WIDTH, SPI_DATA_WIDTH_8BIT);
if (spi_async_flag == false && spi_async_cycle_fill_flag == false) {
return;
}
if (spi_async_cycle_fill_flag == true) {
/* enable dma addr increment */
bflb_dma_feature_control(spi_dma_hd, DMA_CMD_SET_SRCADDR_INCREMENT, true);
}
spi_async_flag = false;
spi_async_cycle_fill_flag = false;
/* async callback */
if (spi_async_callback_en_flag && spi_async_callback != NULL) {
spi_async_callback();
}
}
int lcd_spi_hard_4_async_callback_register(void (*callback)(void))
{
spi_async_callback = callback;
return 0;
}
int lcd_spi_hard_4_async_callback_enable(bool enable)
{
spi_async_callback_en_flag = enable;
return 0;
}
int lcd_spi_hard_4_init(lcd_spi_hard_4_init_t *dbi_parra)
{
/* spi */
struct bflb_spi_config_s spi_cfg = {
.freq = dbi_parra->clock_freq,
.role = SPI_ROLE_MASTER,
.mode = SPI_MODE3,
.data_width = SPI_DATA_WIDTH_8BIT,
.bit_order = SPI_BIT_MSB,
.byte_order = SPI_BYTE_LSB,
.tx_fifo_threshold = 0,
.rx_fifo_threshold = 0,
};
/* dma cfg */
struct bflb_dma_channel_config_s dma_spi_tx_cfg = {
.direction = DMA_MEMORY_TO_PERIPH,
.src_req = DMA_REQUEST_NONE,
.dst_req = DMA_REQUEST_SPI0_TX,
.src_addr_inc = DMA_ADDR_INCREMENT_ENABLE,
.dst_addr_inc = DMA_ADDR_INCREMENT_DISABLE,
.src_burst_count = DMA_BURST_INCR4,
.dst_burst_count = DMA_BURST_INCR4,
.src_width = DMA_DATA_WIDTH_16BIT,
.dst_width = DMA_DATA_WIDTH_16BIT,
};
pixel_format = dbi_parra->pixel_format;
#if (SPI_FIFO_WIDTH_VARIABLE_SUPPORT)
/* SPI support burst*4 */
spi_cfg.tx_fifo_threshold = (2 * 4 - 1);
spi_cfg.rx_fifo_threshold = (2 * 4 - 1);
spi_cfg.byte_order = SPI_BYTE_MSB;
#elif
spi_cfg.tx_fifo_threshold = 4 - 1;
spi_cfg.rx_fifo_threshold = 4 - 1;
#endif
spi_hd = bflb_device_get_by_name(LCD_SPI_HARD_4_NAME);
/* CS and DC pin init */
gpio = bflb_device_get_by_name("gpio");
bflb_gpio_init(gpio, LCD_SPI_HARD_4_PIN_CS, GPIO_OUTPUT | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1);
bflb_gpio_init(gpio, LCD_SPI_HARD_4_PIN_DC, GPIO_OUTPUT | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1);
LCD_SPI_HARD_4_CS_HIGH;
LCD_SPI_HARD_4_DC_HIGH;
if (spi_hd->idx == 0) {
bflb_gpio_init(gpio, LCD_SPI_HARD_4_PIN_CLK, GPIO_FUNC_SPI0 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_2);
bflb_gpio_init(gpio, LCD_SPI_HARD_4_PIN_DAT, GPIO_FUNC_SPI0 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_2);
}
#if defined(GPIO_FUNC_SPI1)
else if (spi_hd->idx == 1) {
bflb_gpio_init(gpio, LCD_SPI_HARD_4_PIN_CLK, GPIO_FUNC_SPI1 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_2);
bflb_gpio_init(gpio, LCD_SPI_HARD_4_PIN_DAT, GPIO_FUNC_SPI1 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_2);
}
#endif
/* spi init */
bflb_spi_init(spi_hd, &spi_cfg);
/* spi enabled continuous mode */
// bflb_spi_feature_control(spi_hd, SPI_CMD_SET_CS_INTERVAL, true);
if (pixel_format == LCD_SPI_LCD_PIXEL_FORMAT_RGB565) {
dma_spi_tx_cfg.src_width = DMA_DATA_WIDTH_16BIT;
dma_spi_tx_cfg.dst_width = DMA_DATA_WIDTH_16BIT;
}
if (spi_hd->idx == 0) {
dma_spi_tx_cfg.dst_req = DMA_REQUEST_SPI0_TX;
spi_tx_fifo_address = DMA_ADDR_SPI0_TDR;
}
#if defined(DMA_REQUEST_SPI1_TX)
else if (spi_hd->idx == 1) {
dma_spi_tx_cfg.dst_req = DMA_REQUEST_SPI1_TX;
spi_tx_fifo_address = DMA_ADDR_SPI1_TDR;
}
#endif
/* dma init */
spi_dma_hd = bflb_device_get_by_name(LCD_SPI_HARD_4_DMA_NAME);
bflb_dma_channel_init(spi_dma_hd, &dma_spi_tx_cfg);
/* dma int cfg */
bflb_dma_channel_irq_attach(spi_dma_hd, spi_dma_callback, NULL);
return 0;
}
#if (SPI_FIFO_WIDTH_VARIABLE_SUPPORT == 0)
static int lcd_swap_color_data16(uint16_t *dst, uint16_t *src, uint32_t color_num)
{
for (size_t i = 0; i < color_num; i++) {
dst[i] = (src[i] << 8) | (src[i] >> 8);
}
return 0;
}
#endif
int lcd_spi_hard_4_is_busy(void)
{
if (spi_async_flag || spi_async_cycle_fill_flag) {
return 1;
} else {
return 0;
}
}
int lcd_spi_hard_4_transmit_cmd_para(uint8_t cmd, uint32_t *para, size_t para_num)
{
LCD_SPI_HARD_4_DC_LOW;
LCD_SPI_HARD_4_CS_LOW;
/* send cmd */
bflb_spi_poll_send(spi_hd, cmd);
LCD_SPI_HARD_4_DC_HIGH;
/* send para */
if (para_num && para != NULL) {
bflb_spi_poll_exchange(spi_hd, para, NULL, para_num);
}
LCD_SPI_HARD_4_CS_HIGH;
return 0;
}
int lcd_spi_hard_4_transmit_cmd_pixel_sync(uint8_t cmd, uint32_t *pixel, size_t pixel_num)
{
#if (SPI_FIFO_WIDTH_VARIABLE_SUPPORT == 0)
lcd_swap_color_data16(picture, picture, pixel_num);
#endif
LCD_SPI_HARD_4_DC_LOW;
LCD_SPI_HARD_4_CS_LOW;
/* send cmd */
bflb_spi_poll_send(spi_hd, cmd);
LCD_SPI_HARD_4_DC_HIGH;
if (pixel_num && pixel != NULL) {
if (pixel_format == LCD_SPI_LCD_PIXEL_FORMAT_RGB565) {
/* spi 16-bit data mode */
bflb_spi_feature_control(spi_hd, SPI_CMD_SET_DATA_WIDTH, SPI_DATA_WIDTH_16BIT);
}
/* send pixel */
if (pixel_format == LCD_SPI_LCD_PIXEL_FORMAT_RGB565) {
bflb_spi_poll_exchange(spi_hd, pixel, NULL, pixel_num * 2);
}
/* spi 8-bit data mode */
bflb_spi_feature_control(spi_hd, SPI_CMD_SET_DATA_WIDTH, SPI_DATA_WIDTH_8BIT);
}
LCD_SPI_HARD_4_CS_HIGH;
return 0;
}
int lcd_spi_hard_4_transmit_cmd_pixel_async(uint8_t cmd, uint32_t *pixel, size_t pixel_num)
{
#if (SPI_FIFO_WIDTH_VARIABLE_SUPPORT == 0)
lcd_swap_color_data16(picture, picture, pixel_num);
#endif
LCD_SPI_HARD_4_DC_LOW;
LCD_SPI_HARD_4_CS_LOW;
/* send cmd */
bflb_spi_poll_send(spi_hd, cmd);
LCD_SPI_HARD_4_DC_HIGH;
if (pixel_num && pixel != NULL) {
spi_async_flag = true;
if (pixel_format == LCD_SPI_LCD_PIXEL_FORMAT_RGB565) {
/* spi 16-bit data mode */
bflb_spi_feature_control(spi_hd, SPI_CMD_SET_DATA_WIDTH, SPI_DATA_WIDTH_16BIT);
}
/* enable spi dma mode */
bflb_spi_link_txdma(spi_hd, true);
dma_tx_transfers[0].src_addr = (uint32_t)(uintptr_t)pixel;
dma_tx_transfers[0].dst_addr = spi_tx_fifo_address;
if (pixel_format == LCD_SPI_LCD_PIXEL_FORMAT_RGB565) {
dma_tx_transfers[0].nbytes = pixel_num * 2;
/* clean cache */
bflb_l1c_dcache_clean_range((void *)pixel, pixel_num * 2);
}
bflb_dma_channel_lli_reload(spi_dma_hd, dma_tx_llipool, LCD_SPI_HARD_4_DMA_LLI_NUM, dma_tx_transfers, 1);
bflb_dma_channel_start(spi_dma_hd);
} else {
LCD_SPI_HARD_4_CS_HIGH;
}
return 0;
}
int lcd_spi_hard_4_transmit_cmd_pixel_fill_sync(uint8_t cmd, uint32_t pixel_val, size_t pixel_num)
{
#if (SPI_FIFO_WIDTH_VARIABLE_SUPPORT == 0)
pixel_val = ((pixel_val >> 8) & 0xFF) | pixel_val << 8;
#endif
LCD_SPI_HARD_4_DC_LOW;
LCD_SPI_HARD_4_CS_LOW;
/* send cmd */
bflb_spi_poll_send(spi_hd, cmd);
LCD_SPI_HARD_4_DC_HIGH;
if (pixel_num) {
if (pixel_format == LCD_SPI_LCD_PIXEL_FORMAT_RGB565) {
/* spi 16-bit data mode */
bflb_spi_feature_control(spi_hd, SPI_CMD_SET_DATA_WIDTH, SPI_DATA_WIDTH_16BIT);
}
/* send pixel */
for (size_t i = 0; i < pixel_num; i++) {
bflb_spi_poll_send(spi_hd, pixel_val);
}
/* spi 8-bit data mode */
bflb_spi_feature_control(spi_hd, SPI_CMD_SET_DATA_WIDTH, SPI_DATA_WIDTH_8BIT);
}
LCD_SPI_HARD_4_CS_HIGH;
return 0;
}
int lcd_spi_hard_4_transmit_cmd_pixel_fill_async(uint8_t cmd, uint32_t pixel_val, size_t pixel_num)
{
#if (SPI_FIFO_WIDTH_VARIABLE_SUPPORT == 0)
pixel_val = ((pixel_val >> 8) & 0xFF) | pixel_val << 8;
#endif
LCD_SPI_HARD_4_DC_LOW;
LCD_SPI_HARD_4_CS_LOW;
/* send cmd */
bflb_spi_poll_send(spi_hd, cmd);
LCD_SPI_HARD_4_DC_HIGH;
if (pixel_num) {
spi_async_cycle_fill_flag = true;
if (pixel_format == LCD_SPI_LCD_PIXEL_FORMAT_RGB565) {
/* spi 16-bit data mode */
bflb_spi_feature_control(spi_hd, SPI_CMD_SET_DATA_WIDTH, SPI_DATA_WIDTH_16BIT);
}
/* enable spi dma mode */
bflb_spi_link_txdma(spi_hd, true);
/* disable dma src_addr_inc */
bflb_dma_feature_control(spi_hd, DMA_CMD_SET_SRCADDR_INCREMENT, false);
dma_tx_transfers[0].src_addr = (uint32_t)(uintptr_t)&pixel_val;
dma_tx_transfers[0].dst_addr = spi_tx_fifo_address;
if (pixel_format == LCD_SPI_LCD_PIXEL_FORMAT_RGB565) {
dma_tx_transfers[0].nbytes = pixel_num * 2;
}
/* clean cache */
bflb_l1c_dcache_clean_range((void *)&pixel_val, sizeof(pixel_val));
bflb_dma_channel_lli_reload(spi_dma_hd, dma_tx_llipool, LCD_SPI_HARD_4_DMA_LLI_NUM, dma_tx_transfers, 1);
bflb_dma_channel_start(spi_dma_hd);
} else {
LCD_SPI_HARD_4_CS_HIGH;
}
return 0;
}
#else
#error "Devices that do not support SPI! Replace the driver port (lcd_conf.h)"
#endif
#endif

View file

@ -0,0 +1,38 @@
#ifndef _BL_SPI_HARD_4_H
#define _BL_SPI_HARD_4_H
#include "../lcd_conf.h"
#if (defined(LCD_SPI_INTERFACE_TYPE) && (LCD_SPI_INTERFACE_TYPE == 1))
/* Do not modify this file ! */
/* Optional pixel format */
#define LCD_SPI_LCD_PIXEL_FORMAT_RGB565 1
#define LCD_SPI_LCD_PIXEL_FORMAT_NRGB8888 2
#define LCD_SPI_HARD_4_CS_HIGH bflb_gpio_set(gpio, LCD_SPI_HARD_4_PIN_CS)
#define LCD_SPI_HARD_4_CS_LOW bflb_gpio_reset(gpio, LCD_SPI_HARD_4_PIN_CS)
#define LCD_SPI_HARD_4_DC_HIGH bflb_gpio_set(gpio, LCD_SPI_HARD_4_PIN_DC)
#define LCD_SPI_HARD_4_DC_LOW bflb_gpio_reset(gpio, LCD_SPI_HARD_4_PIN_DC)
typedef struct {
uint32_t pixel_format;
uint32_t clock_freq;
} lcd_spi_hard_4_init_t;
int lcd_spi_hard_4_init(lcd_spi_hard_4_init_t *spi_parra);
int lcd_spi_hard_4_transmit_cmd_para(uint8_t cmd, uint32_t *para, size_t para_num);
int lcd_spi_hard_4_transmit_cmd_pixel_sync(uint8_t cmd, uint32_t *pixel, size_t pixel_num);
int lcd_spi_hard_4_transmit_cmd_pixel_fill_sync(uint8_t cmd, uint32_t pixel_val, size_t pixel_num);
int lcd_spi_hard_4_is_busy(void);
int lcd_spi_hard_4_async_callback_enable(bool enable);
int lcd_spi_hard_4_async_callback_register(void (*callback)(void));
int lcd_spi_hard_4_transmit_cmd_pixel_async(uint8_t cmd, uint32_t *pixel, size_t pixel_num);
int lcd_spi_hard_4_transmit_cmd_pixel_fill_async(uint8_t cmd, uint32_t pixel_val, size_t pixel_num);
#endif
#endif

View file

@ -25,37 +25,35 @@
#if defined(LCD_SPI_ILI9341)
#include "bflb_mtimer.h"
#include "bflb_spi.h"
#include "bflb_dma.h"
#include "bflb_gpio.h"
#include "bflb_l1c.h"
#include "ili9341_spi.h"
#if (LCD_SPI_INTERFACE_TYPE == 1)
#include "bl_spi_hard_4.h"
#if (defined(BL808) || defined(BL606P)) && defined(CPU_D0)
#define ILI9341_SPI_ID 1
#define ILI9341_SPI_NAME "spi1"
#define ILI9341_SPI_DMA_NAME "dma2_ch0"
#else
#define ILI9341_SPI_ID 0
#define ILI9341_SPI_NAME "spi0"
#define ILI9341_SPI_DMA_NAME "dma0_ch3"
#define lcd_spi_init lcd_spi_hard_4_init
#define lcd_spi_isbusy lcd_spi_hard_4_is_busy
#define lcd_spi_transmit_cmd_para lcd_spi_hard_4_transmit_cmd_para
#define lcd_spi_transmit_cmd_pixel_sync lcd_spi_hard_4_transmit_cmd_pixel_sync
#define lcd_spi_transmit_cmd_pixel_fill_sync lcd_spi_hard_4_transmit_cmd_pixel_fill_sync
#define lcd_spi_sync_callback_enable lcd_spi_hard_4_async_callback_enable
#define lcd_spi_async_callback_register lcd_spi_hard_4_async_callback_register
#define lcd_spi_transmit_cmd_pixel_async lcd_spi_hard_4_transmit_cmd_pixel_async
#define lcd_spi_transmit_cmd_pixel_fill_async lcd_spi_hard_4_transmit_cmd_pixel_fill_async
static lcd_spi_hard_4_init_t spi_para = {
.clock_freq = 40 * 1000 * 1000,
#if (ILI9341_SPI_PIXEL_FORMAT == 1)
.pixel_format = LCD_SPI_LCD_PIXEL_FORMAT_RGB565,
#elif (ILI9341_SPI_PIXEL_FORMAT == 2)
.pixel_format = LCD_SPI_LCD_PIXEL_FORMAT_NRGB8888,
#endif
};
#define ILI9341_DMA_LLI_NUM (ILI9341_SPI_W * ILI9341_SPI_H / 4064 + 1)
#else
/* asynchronous flush interrupt callback */
typedef void (*ili9341_spi_callback)(void);
static volatile ili9341_spi_callback ili9341_spi_async_callback = NULL;
static volatile bool ili9341_spi_sync_flush_flag = false;
#error "Configuration error"
static struct bflb_device_s *ili9341_gpio;
static struct bflb_device_s *ili9341_spi;
static struct bflb_device_s *ili9341_dma_spi_tx;
/* The memory space of DMA */
static struct bflb_dma_channel_lli_pool_s dam_tx_llipool[ILI9341_DMA_LLI_NUM];
static struct bflb_dma_channel_lli_transfer_s dma_tx_transfers[1];
#endif
const ili9341_spi_init_cmd_t ili9341_spi_init_cmds[] = {
{ 0x01, NULL, 0 },
@ -93,24 +91,13 @@ const ili9341_spi_init_cmd_t ili9341_spi_init_cmds[] = {
};
/**
* @brief ili9341_spi_dma_flush_callback
* @brief ili9341_spi_async_callback_enable
*
* @return
*/
void ili9341_spi_dma_flush_callback(void *arg)
void ili9341_spi_async_callback_enable(bool enable)
{
if (ili9341_spi_sync_flush_flag == true) {
ili9341_spi_sync_flush_flag = false;
return;
}
while (ili9341_spi_draw_is_busy()) {
__ASM volatile("nop");
};
if (ili9341_spi_async_callback != NULL) {
ili9341_spi_async_callback();
}
lcd_spi_sync_callback_enable(enable);
}
/**
@ -120,123 +107,7 @@ void ili9341_spi_dma_flush_callback(void *arg)
*/
void ili9341_spi_async_callback_register(void (*callback)(void))
{
ili9341_spi_async_callback = callback;
}
/**
* @brief ili9341_spi_init
*
* @return int 0:succes 1:error
*/
static int ili9341_spi_peripheral_init(void)
{
/* spi */
struct bflb_spi_config_s spi_cfg = {
.freq = 40 * 1000 * 1000,
.role = SPI_ROLE_MASTER,
.mode = SPI_MODE3,
.data_width = SPI_DATA_WIDTH_8BIT,
.bit_order = SPI_BIT_MSB,
.byte_order = SPI_BYTE_LSB,
.tx_fifo_threshold = 0,
.rx_fifo_threshold = 0,
};
/* dma */
struct bflb_dma_channel_config_s dma_spi_tx_cfg = {
.direction = DMA_MEMORY_TO_PERIPH,
.src_req = DMA_REQUEST_NONE,
.dst_req = DMA_REQUEST_SPI0_TX,
.src_addr_inc = DMA_ADDR_INCREMENT_ENABLE,
.dst_addr_inc = DMA_ADDR_INCREMENT_DISABLE,
.src_burst_count = DMA_BURST_INCR1,
.dst_burst_count = DMA_BURST_INCR1,
.src_width = DMA_DATA_WIDTH_16BIT,
.dst_width = DMA_DATA_WIDTH_16BIT,
};
/* CS and DC pin init */
ili9341_gpio = bflb_device_get_by_name("gpio");
bflb_gpio_init(ili9341_gpio, ILI9341_SPI_CS_PIN, GPIO_OUTPUT | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1);
bflb_gpio_init(ili9341_gpio, ILI9341_SPI_DC_PIN, GPIO_OUTPUT | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1);
ILI9341_SPI_CS_HIGH;
ILI9341_SPI_DC_HIGH;
#if (SPI_FIFO_WIDTH_VARIABLE_SUPPORT) && (SPI_FIFO_BYTE_NUM_MAX > (2 * 4))
/* SPI support burst*4 */
spi_cfg.tx_fifo_threshold = 2 * 4 - 1;
spi_cfg.rx_fifo_threshold = 2 * 4 - 1;
#elif (!SPI_FIFO_WIDTH_VARIABLE_SUPPORT) && (SPI_FIFO_WORD_NUM_MAX > 4)
/* SPI support burst*4 */
spi_cfg.tx_fifo_threshold = 4 - 1;
spi_cfg.rx_fifo_threshold = 4 - 1;
#endif
#if (SPI_FIFO_WIDTH_VARIABLE_SUPPORT)
spi_cfg.byte_order = SPI_BYTE_MSB;
#endif
/* spi init */
ili9341_spi = bflb_device_get_by_name(ILI9341_SPI_NAME);
bflb_spi_init(ili9341_spi, &spi_cfg);
/* spi enabled continuous mode */
bflb_spi_feature_control(ili9341_spi, SPI_CMD_SET_CS_INTERVAL, true);
#if (ILI9341_SPI_ID == 0)
dma_spi_tx_cfg.dst_req = DMA_REQUEST_SPI0_TX;
#elif (ILI9341_SPI_ID == 1)
dma_spi_tx_cfg.dst_req = DMA_REQUEST_SPI1_TX;
#endif
#if (SPI_FIFO_WIDTH_VARIABLE_SUPPORT) && (SPI_FIFO_BYTE_NUM_MAX > (2 * 4))
/* DMA support burst*4 */
dma_spi_tx_cfg.src_burst_count = DMA_BURST_INCR4;
dma_spi_tx_cfg.dst_burst_count = DMA_BURST_INCR4;
#elif (!SPI_FIFO_WIDTH_VARIABLE_SUPPORT) && (SPI_FIFO_WORD_NUM_MAX > 4)
/* DMA support burst*4 */
dma_spi_tx_cfg.src_burst_count = DMA_BURST_INCR4;
dma_spi_tx_cfg.dst_burst_count = DMA_BURST_INCR4;
#endif
/* dma init */
ili9341_dma_spi_tx = bflb_device_get_by_name(ILI9341_SPI_DMA_NAME);
bflb_dma_channel_init(ili9341_dma_spi_tx, &dma_spi_tx_cfg);
/* dma int cfg */
bflb_dma_channel_irq_attach(ili9341_dma_spi_tx, ili9341_spi_dma_flush_callback, NULL);
return 0;
}
/**
* @brief ili9341_spi_write_cmd
*
* @param cmd
* @return int 0:succes 1:error
*/
static int ili9341_spi_write_cmd(uint8_t cmd)
{
ILI9341_SPI_DC_LOW;
ILI9341_SPI_CS_LOW;
bflb_spi_poll_send(ili9341_spi, cmd);
ILI9341_SPI_CS_HIGH;
ILI9341_SPI_DC_HIGH;
return 0;
}
/**
* @brief ili9341_spi_write_data_byte
*
* @param data
* @return int 0:succes 1:error
*/
static int ili9341_spi_write_data_byte(uint8_t data)
{
ILI9341_SPI_CS_LOW;
bflb_spi_poll_send(ili9341_spi, data);
ILI9341_SPI_CS_HIGH;
return 0;
lcd_spi_async_callback_register(callback);
}
/**
@ -248,23 +119,7 @@ static int ili9341_spi_write_data_byte(uint8_t data)
*/
int ili9341_spi_draw_is_busy(void)
{
if (bflb_dma_channel_isbusy(ili9341_dma_spi_tx)) {
return 1;
} else {
/* Wait for the SPI bus to be idle */
while (bflb_spi_isbusy(ili9341_spi)) {
__ASM volatile("nop");
};
/* Switch the SPI to non-DMA mode */
bflb_spi_link_txdma(ili9341_spi, false);
/* clear rx fifo */
bflb_spi_feature_control(ili9341_spi, SPI_CMD_CLEAR_RX_FIFO, 0);
/* */
ILI9341_SPI_CS_HIGH;
/* 8-bit data */
bflb_spi_feature_control(ili9341_spi, SPI_CMD_SET_DATA_WIDTH, SPI_DATA_WIDTH_8BIT);
return 0;
}
return lcd_spi_isbusy();
}
/**
@ -274,48 +129,19 @@ int ili9341_spi_draw_is_busy(void)
*/
int ili9341_spi_init()
{
int res = ili9341_spi_peripheral_init();
if (res < 0) {
return res;
}
lcd_spi_init(&spi_para);
for (uint16_t i = 0; i < (sizeof(ili9341_spi_init_cmds) / sizeof(ili9341_spi_init_cmd_t)); i++) {
if (ili9341_spi_init_cmds[i].cmd == 0xFF && ili9341_spi_init_cmds[i].data == NULL) {
for (uint16_t i = 0; i < (sizeof(ili9341_spi_init_cmds) / sizeof(ili9341_spi_init_cmds[0])); i++) {
if (ili9341_spi_init_cmds[i].cmd == 0xFF && ili9341_spi_init_cmds[i].data == NULL && ili9341_spi_init_cmds[i].databytes) {
bflb_mtimer_delay_ms(ili9341_spi_init_cmds[i].databytes);
} else {
/* send register address */
ili9341_spi_write_cmd(ili9341_spi_init_cmds[i].cmd);
/* send register data */
for (uint8_t j = 0; j < (ili9341_spi_init_cmds[i].databytes); j++) {
ili9341_spi_write_data_byte(ili9341_spi_init_cmds[i].data[j]);
}
lcd_spi_transmit_cmd_para(ili9341_spi_init_cmds[i].cmd, (void *)(ili9341_spi_init_cmds[i].data), ili9341_spi_init_cmds[i].databytes);
}
}
ili9341_spi_set_draw_window(0, 0, ILI9341_SPI_H, ILI9341_SPI_W);
return res;
}
#if (SPI_FIFO_WIDTH_VARIABLE_SUPPORT == 0)
/**
* @brief lcd_swap_color_data16
*
* @param dst destination
* @param src source
* @param color_num color num
* @return int
*/
static int lcd_swap_color_data16(uint16_t *dst, uint16_t *src, uint32_t color_num)
{
for (size_t i = 0; i < color_num; i++) {
dst[i] = (src[i] << 8) | (src[i] >> 8);
}
return 0;
}
#endif
/**
* @brief
*
@ -357,8 +183,7 @@ int ili9341_spi_set_dir(uint8_t dir, uint8_t mir_flag)
break;
}
ili9341_spi_write_cmd(0x36);
ili9341_spi_write_data_byte(param);
lcd_spi_transmit_cmd_para(0x36, (void *)&param, 1);
return dir;
}
@ -371,7 +196,7 @@ int ili9341_spi_set_dir(uint8_t dir, uint8_t mir_flag)
* @param x2
* @param y2
*/
void ili9341_spi_set_draw_window(uint32_t x1, uint32_t y1, uint32_t x2, uint32_t y2)
void ili9341_spi_set_draw_window(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2)
{
#if ILI9341_SPI_OFFSET_X
x1 += ILI9341_SPI_OFFSET_X;
@ -382,19 +207,21 @@ void ili9341_spi_set_draw_window(uint32_t x1, uint32_t y1, uint32_t x2, uint32_t
y2 += ILI9341_SPI_OFFSET_Y;
#endif
ili9341_spi_write_cmd(0x2a);
ili9341_spi_write_data_byte(x1 >> 8);
ili9341_spi_write_data_byte(x1);
ili9341_spi_write_data_byte(x2 >> 8);
ili9341_spi_write_data_byte(x2);
int8_t param[4];
ili9341_spi_write_cmd(0x2b);
ili9341_spi_write_data_byte(y1 >> 8);
ili9341_spi_write_data_byte(y1);
ili9341_spi_write_data_byte(y2 >> 8);
ili9341_spi_write_data_byte(y2);
param[0] = (x1 >> 8) & 0xFF;
param[1] = x1 & 0xFF;
param[2] = (x2 >> 8) & 0xFF;
param[3] = x2 & 0xFF;
ili9341_spi_write_cmd(0x2c);
lcd_spi_transmit_cmd_para(0x2A, (void *)param, 4);
param[0] = (y1 >> 8) & 0xFF;
param[1] = y1 & 0xFF;
param[2] = (y2 >> 8) & 0xFF;
param[3] = y2 & 0xFF;
lcd_spi_transmit_cmd_para(0x2B, (void *)param, 4);
}
/**
@ -406,16 +233,10 @@ void ili9341_spi_set_draw_window(uint32_t x1, uint32_t y1, uint32_t x2, uint32_t
*/
void ili9341_spi_draw_point(uint16_t x, uint16_t y, ili9341_spi_color_t color)
{
#if (SPI_FIFO_WIDTH_VARIABLE_SUPPORT == 0)
color = ((color >> 8) & 0xFF) | color << 8;
#endif
/* set window */
ili9341_spi_set_draw_window(x, y, x, y);
ILI9341_SPI_DC_HIGH;
ILI9341_SPI_CS_LOW;
bflb_spi_poll_send(ili9341_spi, color & 0x00ff);
bflb_spi_poll_send(ili9341_spi, (color >> 8) & 0x00ff);
ILI9341_SPI_CS_HIGH;
lcd_spi_transmit_cmd_pixel_sync(0x2C, (void *)&color, 1);
}
/**
@ -429,57 +250,12 @@ void ili9341_spi_draw_point(uint16_t x, uint16_t y, ili9341_spi_color_t color)
*/
void ili9341_spi_draw_area(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, ili9341_spi_color_t color)
{
uint32_t pixelDataSize, PixelCount = (x2 - x1 + 1) * (y2 - y1 + 1);
uint32_t __attribute__((aligned(64))) color_src;
#if (SPI_FIFO_WIDTH_VARIABLE_SUPPORT)
color_src = color;
#else
color_src = ((color >> 8) & 0xFF) | color << 8;
#endif
/* clean cache */
bflb_l1c_dcache_clean_range((void *)&color_src, sizeof(color_src));
uint32_t pixel_cnt = (x2 - x1 + 1) * (y2 - y1 + 1);
/* set window */
ili9341_spi_set_draw_window(x1, y1, x2, y2);
/* get pixel Data Size */
pixelDataSize = PixelCount * 2;
/* spi 16-bit mode */
bflb_spi_feature_control(ili9341_spi, SPI_CMD_SET_DATA_WIDTH, SPI_DATA_WIDTH_16BIT);
/* enable spi dma mode */
bflb_spi_link_txdma(ili9341_spi, true);
ILI9341_SPI_CS_LOW;
/* sync mode flag, temporary shutdown interrupt */
ili9341_spi_sync_flush_flag = true;
/* disable dma src_addr_inc */
bflb_dma_feature_control(ili9341_dma_spi_tx, DMA_CMD_SET_SRCADDR_INCREMENT, false);
/* cfg and start dma */
dma_tx_transfers[0].src_addr = (uint32_t)(uintptr_t)&color_src;
#if (defined(BL808) || defined(BL606P)) && defined(CPU_D0)
dma_tx_transfers[0].dst_addr = (uint32_t)DMA_ADDR_SPI1_TDR;
#else
dma_tx_transfers[0].dst_addr = (uint32_t)DMA_ADDR_SPI0_TDR;
#endif
dma_tx_transfers[0].nbytes = pixelDataSize;
bflb_dma_channel_lli_reload(ili9341_dma_spi_tx, dam_tx_llipool, ILI9341_DMA_LLI_NUM, dma_tx_transfers, 1);
bflb_dma_channel_start(ili9341_dma_spi_tx);
/* Wait to finish, and cs high */
while (ili9341_spi_draw_is_busy()) {
__ASM volatile("nop");
};
/* enable src_addr_inc */
bflb_dma_feature_control(ili9341_dma_spi_tx, DMA_CMD_SET_SRCADDR_INCREMENT, true);
lcd_spi_transmit_cmd_pixel_fill_sync(0x2C, (uint32_t)color, pixel_cnt);
}
/**
@ -494,31 +270,12 @@ void ili9341_spi_draw_area(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, i
*/
void ili9341_spi_draw_picture_nonblocking(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, ili9341_spi_color_t *picture)
{
size_t picture_size = (x2 - x1 + 1) * (y2 - y1 + 1);
size_t pixel_cnt = (x2 - x1 + 1) * (y2 - y1 + 1);
/* set window */
ili9341_spi_set_draw_window(x1, y1, x2, y2);
#if (SPI_FIFO_WIDTH_VARIABLE_SUPPORT == 0)
lcd_swap_color_data16(picture, picture, picture_size);
#endif
/* clean dcache */
bflb_l1c_dcache_clean_range((void *)(picture), (picture_size * 2));
/* spi 16-bit data mode */
bflb_spi_feature_control(ili9341_spi, SPI_CMD_SET_DATA_WIDTH, SPI_DATA_WIDTH_16BIT);
/* spi dma mode enable */
bflb_spi_link_txdma(ili9341_spi, true);
ILI9341_SPI_CS_LOW;
/* dma cfg and start */
dma_tx_transfers[0].src_addr = (uint32_t)(uintptr_t)picture;
dma_tx_transfers[0].dst_addr = (uint32_t)DMA_ADDR_SPI0_TDR;
dma_tx_transfers[0].nbytes = picture_size * 2;
bflb_dma_channel_lli_reload(ili9341_dma_spi_tx, dam_tx_llipool, sizeof(dam_tx_llipool) / sizeof(dam_tx_llipool[0]), dma_tx_transfers, 1);
bflb_dma_channel_start(ili9341_dma_spi_tx);
lcd_spi_transmit_cmd_pixel_async(0x2C, (void *)picture, pixel_cnt);
}
/**
@ -532,13 +289,12 @@ void ili9341_spi_draw_picture_nonblocking(uint16_t x1, uint16_t y1, uint16_t x2,
*/
void ili9341_spi_draw_picture_blocking(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, ili9341_spi_color_t *picture)
{
/* sync mode, temporary shutdown interrupt */
ili9341_spi_sync_flush_flag = true;
size_t pixel_cnt = (x2 - x1 + 1) * (y2 - y1 + 1);
ili9341_spi_draw_picture_nonblocking(x1, y1, x2, y2, picture);
while (ili9341_spi_draw_is_busy()) {
__ASM volatile("nop");
};
/* set window */
ili9341_spi_set_draw_window(x1, y1, x2, y2);
lcd_spi_transmit_cmd_pixel_sync(0x2C, (void *)picture, pixel_cnt);
}
#endif

View file

@ -24,21 +24,11 @@
#ifndef _ILI9341_SPI_H_
#define _ILI9341_SPI_H_
#include "bflb_core.h"
#include "../lcd_conf.h"
#define ILI9341_SPI_CS_PIN GPIO_PIN_16
#define ILI9341_SPI_DC_PIN GPIO_PIN_18
#if defined LCD_SPI_ILI9341
#define ILI9341_SPI_CS_HIGH bflb_gpio_set(ili9341_gpio, ILI9341_SPI_CS_PIN)
#define ILI9341_SPI_CS_LOW bflb_gpio_reset(ili9341_gpio, ILI9341_SPI_CS_PIN)
#define ILI9341_SPI_DC_HIGH bflb_gpio_set(ili9341_gpio, ILI9341_SPI_DC_PIN)
#define ILI9341_SPI_DC_LOW bflb_gpio_reset(ili9341_gpio, ILI9341_SPI_DC_PIN)
#define ILI9341_SPI_W 240 /* ILI9341 LCD width */
#define ILI9341_SPI_H 320 /* ILI9341 LCD height */
#define ILI9341_SPI_OFFSET_X 0
#define ILI9341_SPI_OFFSET_Y 0
/* Do not modify the following */
#define ILI9341_SPI_COLOR_DEPTH 16
@ -51,9 +41,10 @@ typedef struct {
typedef uint16_t ili9341_spi_color_t;
int ili9341_spi_init();
void ili9341_spi_async_callback_enable(bool enable);
void ili9341_spi_async_callback_register(void (*callback)(void));
int ili9341_spi_set_dir(uint8_t dir, uint8_t mir_flag);
void ili9341_spi_set_draw_window(uint32_t x1, uint32_t y1, uint32_t x2, uint32_t y2);
void ili9341_spi_set_draw_window(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2);
void ili9341_spi_draw_point(uint16_t x, uint16_t y, ili9341_spi_color_t color);
void ili9341_spi_draw_area(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, ili9341_spi_color_t color);
void ili9341_spi_draw_picture_nonblocking(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, ili9341_spi_color_t *picture);
@ -61,3 +52,4 @@ void ili9341_spi_draw_picture_blocking(uint16_t x1, uint16_t y1, uint16_t x2, ui
int ili9341_spi_draw_is_busy(void);
#endif
#endif

View file

@ -25,37 +25,35 @@
#if defined(LCD_SPI_ILI9488)
#include "bflb_mtimer.h"
#include "bflb_spi.h"
#include "bflb_dma.h"
#include "bflb_gpio.h"
#include "bflb_l1c.h"
#include "ili9488_spi.h"
#if (LCD_SPI_INTERFACE_TYPE == 1)
#include "bl_spi_hard_4.h"
#if (defined(BL808) || defined(BL606P)) && defined(CPU_D0)
#define ILI9488_SPI_ID 1
#define ILI9488_SPI_NAME "spi1"
#define ILI9488_SPI_DMA_NAME "dma2_ch0"
#else
#define ILI9488_SPI_ID 0
#define ILI9488_SPI_NAME "spi0"
#define ILI9488_SPI_DMA_NAME "dma0_ch3"
#define lcd_spi_init lcd_spi_hard_4_init
#define lcd_spi_isbusy lcd_spi_hard_4_is_busy
#define lcd_spi_transmit_cmd_para lcd_spi_hard_4_transmit_cmd_para
#define lcd_spi_transmit_cmd_pixel_sync lcd_spi_hard_4_transmit_cmd_pixel_sync
#define lcd_spi_transmit_cmd_pixel_fill_sync lcd_spi_hard_4_transmit_cmd_pixel_fill_sync
#define lcd_spi_sync_callback_enable lcd_spi_hard_4_async_callback_enable
#define lcd_spi_async_callback_register lcd_spi_hard_4_async_callback_register
#define lcd_spi_transmit_cmd_pixel_async lcd_spi_hard_4_transmit_cmd_pixel_async
#define lcd_spi_transmit_cmd_pixel_fill_async lcd_spi_hard_4_transmit_cmd_pixel_fill_async
static lcd_spi_hard_4_init_t spi_para = {
.clock_freq = 40 * 1000 * 1000,
#if (ILI9488_SPI_PIXEL_FORMAT == 1)
.pixel_format = LCD_SPI_LCD_PIXEL_FORMAT_RGB565,
#elif (ILI9488_SPI_PIXEL_FORMAT == 2)
.pixel_format = LCD_SPI_LCD_PIXEL_FORMAT_NRGB8888,
#endif
};
#define ILI9488_DMA_LLI_NUM (ILI9488_SPI_W * ILI9488_SPI_H / 4064 + 1)
#else
/* asynchronous flush interrupt callback */
typedef void (*ili9488_spi_callback)(void);
static volatile ili9488_spi_callback ili9488_spi_async_callback = NULL;
static volatile bool ili9488_spi_sync_flush_flag = 0;
#error "Configuration error"
static struct bflb_device_s *ili9488_gpio;
static struct bflb_device_s *ili9488_spi;
static struct bflb_device_s *ili9488_dma_spi_tx;
/* The memory space of DMA */
static struct bflb_dma_channel_lli_pool_s dam_tx_llipool[ILI9488_DMA_LLI_NUM];
static struct bflb_dma_channel_lli_transfer_s dma_tx_transfers[1];
#endif
const ili9488_spi_init_cmd_t ili9488_spi_init_cmds[] = {
{ 0x01, NULL, 0 }, /* software reset */
@ -83,29 +81,22 @@ const ili9488_spi_init_cmd_t ili9488_spi_init_cmds[] = {
{ 0xF7, "\xA9\x51\x2C\x82", 4 }, /* Adjust Control 3 */
#if ILI9488_SPI_COLOR_REVERSAL
{ 0x21, NULL, 0 }, /* Color reversal */
#endif
{ 0x29, NULL, 0 }, /* Display On */
{ 0xFF, NULL, 10 },
};
/**
* @brief ili9488_spi_dma_flush_callback
* @brief ili9488_spi_async_callback_enable
*
* @return
*/
void ili9488_spi_dma_flush_callback(void *args)
void ili9488_spi_async_callback_enable(bool enable)
{
if (ili9488_spi_sync_flush_flag == true) {
ili9488_spi_sync_flush_flag = false;
return;
}
while (ili9488_spi_draw_is_busy()) {
__ASM volatile("nop");
};
if (ili9488_spi_async_callback != NULL) {
ili9488_spi_async_callback();
}
lcd_spi_sync_callback_enable(enable);
}
/**
@ -115,123 +106,7 @@ void ili9488_spi_dma_flush_callback(void *args)
*/
void ili9488_spi_async_callback_register(void (*callback)(void))
{
ili9488_spi_async_callback = callback;
}
/**
* @brief ili9488_spi_init
*
* @return int 0:succes 1:error
*/
static int ili9488_spi_peripheral_init(void)
{
/* spi */
struct bflb_spi_config_s spi_cfg = {
.freq = 40 * 1000 * 1000,
.role = SPI_ROLE_MASTER,
.mode = SPI_MODE3,
.data_width = SPI_DATA_WIDTH_8BIT,
.bit_order = SPI_BIT_MSB,
.byte_order = SPI_BYTE_LSB,
.tx_fifo_threshold = 0,
.rx_fifo_threshold = 0,
};
/* dma */
struct bflb_dma_channel_config_s dma_spi_tx_cfg = {
.direction = DMA_MEMORY_TO_PERIPH,
.src_req = DMA_REQUEST_NONE,
.dst_req = DMA_REQUEST_SPI0_TX,
.src_addr_inc = DMA_ADDR_INCREMENT_ENABLE,
.dst_addr_inc = DMA_ADDR_INCREMENT_DISABLE,
.src_burst_count = DMA_BURST_INCR1,
.dst_burst_count = DMA_BURST_INCR1,
.src_width = DMA_DATA_WIDTH_16BIT,
.dst_width = DMA_DATA_WIDTH_16BIT,
};
/* CS and DC pin init */
ili9488_gpio = bflb_device_get_by_name("gpio");
bflb_gpio_init(ili9488_gpio, ILI9488_SPI_CS_PIN, GPIO_OUTPUT | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1);
bflb_gpio_init(ili9488_gpio, ILI9488_SPI_DC_PIN, GPIO_OUTPUT | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1);
ILI9488_SPI_CS_HIGH;
ILI9488_SPI_DC_HIGH;
#if (SPI_FIFO_WIDTH_VARIABLE_SUPPORT) && (SPI_FIFO_BYTE_NUM_MAX > (2 * 4))
/* SPI support burst*4 */
spi_cfg.tx_fifo_threshold = 2 * 4 - 1;
spi_cfg.rx_fifo_threshold = 2 * 4 - 1;
#elif (!SPI_FIFO_WIDTH_VARIABLE_SUPPORT) && (SPI_FIFO_WORD_NUM_MAX > 4)
/* SPI support burst*4 */
spi_cfg.tx_fifo_threshold = 4 - 1;
spi_cfg.rx_fifo_threshold = 4 - 1;
#endif
#if (SPI_FIFO_WIDTH_VARIABLE_SUPPORT)
spi_cfg.byte_order = SPI_BYTE_MSB;
#endif
/* spi init */
ili9488_spi = bflb_device_get_by_name(ILI9488_SPI_NAME);
bflb_spi_init(ili9488_spi, &spi_cfg);
/* spi enabled continuous mode */
bflb_spi_feature_control(ili9488_spi, SPI_CMD_SET_CS_INTERVAL, true);
#if (ILI9488_SPI_ID == 0)
dma_spi_tx_cfg.dst_req = DMA_REQUEST_SPI0_TX;
#elif (ILI9488_SPI_ID == 1)
dma_spi_tx_cfg.dst_req = DMA_REQUEST_SPI1_TX;
#endif
#if (SPI_FIFO_WIDTH_VARIABLE_SUPPORT) && (SPI_FIFO_BYTE_NUM_MAX > (2 * 4))
/* DMA support burst*4 */
dma_spi_tx_cfg.src_burst_count = DMA_BURST_INCR4;
dma_spi_tx_cfg.dst_burst_count = DMA_BURST_INCR4;
#elif (!SPI_FIFO_WIDTH_VARIABLE_SUPPORT) && (SPI_FIFO_WORD_NUM_MAX > 4)
/* DMA support burst*4 */
dma_spi_tx_cfg.src_burst_count = DMA_BURST_INCR4;
dma_spi_tx_cfg.dst_burst_count = DMA_BURST_INCR4;
#endif
/* dma init */
ili9488_dma_spi_tx = bflb_device_get_by_name(ILI9488_SPI_DMA_NAME);
bflb_dma_channel_init(ili9488_dma_spi_tx, &dma_spi_tx_cfg);
/* dma int cfg */
bflb_dma_channel_irq_attach(ili9488_dma_spi_tx, ili9488_spi_dma_flush_callback, NULL);
return 0;
}
/**
* @brief ili9488_spi_write_cmd
*
* @param cmd
* @return int 0:succes 1:error
*/
static int ili9488_spi_write_cmd(uint8_t cmd)
{
ILI9488_SPI_DC_LOW;
ILI9488_SPI_CS_LOW;
bflb_spi_poll_send(ili9488_spi, cmd);
ILI9488_SPI_CS_HIGH;
ILI9488_SPI_DC_HIGH;
return 0;
}
/**
* @brief ili9488_spi_write_data_byte
*
* @param data
* @return int 0:succes 1:error
*/
static int ili9488_spi_write_data_byte(uint8_t data)
{
ILI9488_SPI_CS_LOW;
bflb_spi_poll_send(ili9488_spi, data);
ILI9488_SPI_CS_HIGH;
return 0;
lcd_spi_async_callback_register(callback);
}
/**
@ -243,23 +118,7 @@ static int ili9488_spi_write_data_byte(uint8_t data)
*/
int ili9488_spi_draw_is_busy(void)
{
if (bflb_dma_channel_isbusy(ili9488_dma_spi_tx)) {
return 1;
} else {
/* Wait for the SPI bus to be idle */
while (bflb_spi_isbusy(ili9488_spi)) {
__ASM volatile("nop");
};
/* Switch the SPI to non-DMA mode */
bflb_spi_link_txdma(ili9488_spi, false);
/* clear rx fifo */
bflb_spi_feature_control(ili9488_spi, SPI_CMD_CLEAR_RX_FIFO, 0);
/* */
ILI9488_SPI_CS_HIGH;
/* 8-bit data */
bflb_spi_feature_control(ili9488_spi, SPI_CMD_SET_DATA_WIDTH, SPI_DATA_WIDTH_8BIT);
return 0;
}
return lcd_spi_isbusy();
}
/**
@ -269,48 +128,19 @@ int ili9488_spi_draw_is_busy(void)
*/
int ili9488_spi_init()
{
int res = ili9488_spi_peripheral_init();
if (res < 0) {
return res;
}
lcd_spi_init(&spi_para);
for (uint16_t i = 0; i < (sizeof(ili9488_spi_init_cmds) / sizeof(ili9488_spi_init_cmd_t)); i++) {
if (ili9488_spi_init_cmds[i].cmd == 0xFF && ili9488_spi_init_cmds[i].data == NULL) {
for (uint16_t i = 0; i < (sizeof(ili9488_spi_init_cmds) / sizeof(ili9488_spi_init_cmds[0])); i++) {
if (ili9488_spi_init_cmds[i].cmd == 0xFF && ili9488_spi_init_cmds[i].data == NULL && ili9488_spi_init_cmds[i].databytes) {
bflb_mtimer_delay_ms(ili9488_spi_init_cmds[i].databytes);
} else {
/* send register address */
ili9488_spi_write_cmd(ili9488_spi_init_cmds[i].cmd);
/* send register data */
for (uint8_t j = 0; j < (ili9488_spi_init_cmds[i].databytes); j++) {
ili9488_spi_write_data_byte(ili9488_spi_init_cmds[i].data[j]);
}
lcd_spi_transmit_cmd_para(ili9488_spi_init_cmds[i].cmd, (void *)(ili9488_spi_init_cmds[i].data), ili9488_spi_init_cmds[i].databytes);
}
}
ili9488_spi_set_draw_window(0, 0, ILI9488_SPI_H, ILI9488_SPI_W);
return res;
}
#if (SPI_FIFO_WIDTH_VARIABLE_SUPPORT == 0)
/**
* @brief lcd_swap_color_data16
*
* @param dst destination
* @param src source
* @param color_num color num
* @return int
*/
static int lcd_swap_color_data16(uint16_t *dst, uint16_t *src, uint32_t color_num)
{
for (size_t i = 0; i < color_num; i++) {
dst[i] = (src[i] << 8) | (src[i] >> 8);
}
return 0;
}
#endif
/**
* @brief
*
@ -320,6 +150,7 @@ static int lcd_swap_color_data16(uint16_t *dst, uint16_t *src, uint32_t color_nu
int ili9488_spi_set_dir(uint8_t dir, uint8_t mir_flag)
{
uint8_t param;
switch (dir) {
case 0:
if (!mir_flag)
@ -350,8 +181,9 @@ int ili9488_spi_set_dir(uint8_t dir, uint8_t mir_flag)
return -1;
break;
}
ili9488_spi_write_cmd(0x36);
ili9488_spi_write_data_byte(param);
lcd_spi_transmit_cmd_para(0x36, (void *)&param, 1);
return dir;
}
@ -374,19 +206,21 @@ void ili9488_spi_set_draw_window(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t
y2 += ILI9488_SPI_OFFSET_Y;
#endif
ili9488_spi_write_cmd(0x2a);
ili9488_spi_write_data_byte(x1 >> 8);
ili9488_spi_write_data_byte(x1);
ili9488_spi_write_data_byte(x2 >> 8);
ili9488_spi_write_data_byte(x2);
int8_t param[4];
ili9488_spi_write_cmd(0x2b);
ili9488_spi_write_data_byte(y1 >> 8);
ili9488_spi_write_data_byte(y1);
ili9488_spi_write_data_byte(y2 >> 8);
ili9488_spi_write_data_byte(y2);
param[0] = (x1 >> 8) & 0xFF;
param[1] = x1 & 0xFF;
param[2] = (x2 >> 8) & 0xFF;
param[3] = x2 & 0xFF;
ili9488_spi_write_cmd(0x2c);
lcd_spi_transmit_cmd_para(0x2A, (void *)param, 4);
param[0] = (y1 >> 8) & 0xFF;
param[1] = y1 & 0xFF;
param[2] = (y2 >> 8) & 0xFF;
param[3] = y2 & 0xFF;
lcd_spi_transmit_cmd_para(0x2B, (void *)param, 4);
}
/**
@ -398,20 +232,14 @@ void ili9488_spi_set_draw_window(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t
*/
void ili9488_spi_draw_point(uint16_t x, uint16_t y, ili9488_spi_color_t color)
{
#if (SPI_FIFO_WIDTH_VARIABLE_SUPPORT == 0)
color = ((color >> 8) & 0xFF) | color << 8;
#endif
/* set window */
ili9488_spi_set_draw_window(x, y, x, y);
ILI9488_SPI_DC_HIGH;
ILI9488_SPI_CS_LOW;
bflb_spi_poll_send(ili9488_spi, color & 0x00ff);
bflb_spi_poll_send(ili9488_spi, (color >> 8) & 0x00ff);
ILI9488_SPI_CS_HIGH;
lcd_spi_transmit_cmd_pixel_sync(0x2C, (void *)&color, 1);
}
/**
* @brief ili9488_spi_draw_area
* @brief ili9488_draw_area
*
* @param x1
* @param y1
@ -421,62 +249,17 @@ void ili9488_spi_draw_point(uint16_t x, uint16_t y, ili9488_spi_color_t color)
*/
void ili9488_spi_draw_area(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, ili9488_spi_color_t color)
{
uint32_t pixelDataSize, PixelCount = (x2 - x1 + 1) * (y2 - y1 + 1);
uint32_t __attribute__((aligned(64))) color_src;
#if (SPI_FIFO_WIDTH_VARIABLE_SUPPORT)
color_src = color;
#else
color_src = ((color >> 8) & 0xFF) | color << 8;
#endif
/* clean cache */
bflb_l1c_dcache_clean_range((void *)&color_src, sizeof(color_src));
uint32_t pixel_cnt = (x2 - x1 + 1) * (y2 - y1 + 1);
/* set window */
ili9488_spi_set_draw_window(x1, y1, x2, y2);
/* get pixel Data Size */
pixelDataSize = PixelCount * 2;
/* spi 16-bit mode */
bflb_spi_feature_control(ili9488_spi, SPI_CMD_SET_DATA_WIDTH, SPI_DATA_WIDTH_16BIT);
/* enable spi dma mode */
bflb_spi_link_txdma(ili9488_spi, true);
ILI9488_SPI_CS_LOW;
/* sync mode flag, temporary shutdown interrupt */
ili9488_spi_sync_flush_flag = true;
/* disable dma src_addr_inc */
bflb_dma_feature_control(ili9488_dma_spi_tx, DMA_CMD_SET_SRCADDR_INCREMENT, false);
/* cfg and start dma */
dma_tx_transfers[0].src_addr = (uint32_t)(uintptr_t)&color_src;
#if (defined(BL808) || defined(BL606P)) && defined(CPU_D0)
dma_tx_transfers[0].dst_addr = (uint32_t)DMA_ADDR_SPI1_TDR;
#else
dma_tx_transfers[0].dst_addr = (uint32_t)DMA_ADDR_SPI0_TDR;
#endif
dma_tx_transfers[0].nbytes = pixelDataSize;
bflb_dma_channel_lli_reload(ili9488_dma_spi_tx, dam_tx_llipool, ILI9488_DMA_LLI_NUM, dma_tx_transfers, 1);
bflb_dma_channel_start(ili9488_dma_spi_tx);
/* Wait to finish, and cs high */
while (ili9488_spi_draw_is_busy()) {
__ASM volatile("nop");
};
/* enable src_addr_inc */
bflb_dma_feature_control(ili9488_dma_spi_tx, DMA_CMD_SET_SRCADDR_INCREMENT, true);
lcd_spi_transmit_cmd_pixel_fill_sync(0x2C, (uint32_t)color, pixel_cnt);
}
/**
* @brief ili9488_spi_draw_picture_dma, Non-blocking! Using DMA acceleration, Not waiting for the draw end
* After the call, No other operations are allowed until (ili9488_spi_draw_is_busy()==0)
* @brief ili9488_draw_picture_dma, Non-blocking! Using DMA acceleration, Not waiting for the draw end
* After the call, No other operations are allowed until (ili9488_draw_is_busy()==0)
*
* @param x1
* @param y1
@ -484,38 +267,18 @@ void ili9488_spi_draw_area(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, i
* @param y2
* @param picture
*/
void ili9488_spi_draw_picture_nonblocking(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, ili9488_spi_color_t *picture)
{
size_t picture_size = (x2 - x1 + 1) * (y2 - y1 + 1);
size_t pixel_cnt = (x2 - x1 + 1) * (y2 - y1 + 1);
/* set window */
ili9488_spi_set_draw_window(x1, y1, x2, y2);
#if (SPI_FIFO_WIDTH_VARIABLE_SUPPORT == 0)
lcd_swap_color_data16(picture, picture, picture_size);
#endif
/* clean dcache */
bflb_l1c_dcache_clean_range((void *)(picture), (picture_size * 2));
/* spi 16-bit data mode */
bflb_spi_feature_control(ili9488_spi, SPI_CMD_SET_DATA_WIDTH, SPI_DATA_WIDTH_16BIT);
/* spi dma mode enable */
bflb_spi_link_txdma(ili9488_spi, true);
ILI9488_SPI_CS_LOW;
/* dma cfg and start */
dma_tx_transfers[0].src_addr = (uint32_t)(uintptr_t)picture;
dma_tx_transfers[0].dst_addr = (uint32_t)DMA_ADDR_SPI0_TDR;
dma_tx_transfers[0].nbytes = picture_size * 2;
bflb_dma_channel_lli_reload(ili9488_dma_spi_tx, dam_tx_llipool, sizeof(dam_tx_llipool) / sizeof(dam_tx_llipool[0]), dma_tx_transfers, 1);
bflb_dma_channel_start(ili9488_dma_spi_tx);
lcd_spi_transmit_cmd_pixel_async(0x2C, (void *)picture, pixel_cnt);
}
/**
* @brief ili9488_spi_draw_picture,BlockingUsing DMA acceleration,Waiting for the draw end
* @brief ili9488_draw_picture,Blocking,Using DMA acceleration,Waiting for the draw end
*
* @param x1
* @param y1
@ -525,12 +288,12 @@ void ili9488_spi_draw_picture_nonblocking(uint16_t x1, uint16_t y1, uint16_t x2,
*/
void ili9488_spi_draw_picture_blocking(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, ili9488_spi_color_t *picture)
{
/* sync mode, temporary shutdown interrupt */
ili9488_spi_sync_flush_flag = true;
size_t pixel_cnt = (x2 - x1 + 1) * (y2 - y1 + 1);
ili9488_spi_draw_picture_nonblocking(x1, y1, x2, y2, picture);
while (ili9488_spi_draw_is_busy()) {
};
/* set window */
ili9488_spi_set_draw_window(x1, y1, x2, y2);
lcd_spi_transmit_cmd_pixel_sync(0x2C, (void *)picture, pixel_cnt);
}
#endif

View file

@ -24,24 +24,11 @@
#ifndef _ILI9488_SPI_H_
#define _ILI9488_SPI_H_
#include "bflb_core.h"
#include "../lcd_conf.h"
#define ILI9488_SPI_CS_PIN GPIO_PIN_16
#define ILI9488_SPI_DC_PIN GPIO_PIN_18
#if defined LCD_SPI_ILI9488
#define ILI9488_SPI_CS_HIGH bflb_gpio_set(ili9488_gpio, ILI9488_SPI_CS_PIN)
#define ILI9488_SPI_CS_LOW bflb_gpio_reset(ili9488_gpio, ILI9488_SPI_CS_PIN)
#define ILI9488_SPI_DC_HIGH bflb_gpio_set(ili9488_gpio, ILI9488_SPI_DC_PIN)
#define ILI9488_SPI_DC_LOW bflb_gpio_reset(ili9488_gpio, ILI9488_SPI_DC_PIN)
/* ILI9488 LCD width */
#define ILI9488_SPI_W 320
/* ILI9488 LCD height */
#define ILI9488_SPI_H 480
/* The offset of the area can be displayed */
#define ILI9488_SPI_OFFSET_X 0
#define ILI9488_SPI_OFFSET_Y 0
/* Do not modify the following */
#define ILI9488_SPI_COLOR_DEPTH 16
@ -54,6 +41,7 @@ typedef struct {
typedef uint16_t ili9488_spi_color_t;
int ili9488_spi_init();
void ili9488_spi_async_callback_enable(bool enable);
void ili9488_spi_async_callback_register(void (*callback)(void));
int ili9488_spi_set_dir(uint8_t dir, uint8_t mir_flag);
void ili9488_spi_set_draw_window(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2);
@ -64,3 +52,4 @@ void ili9488_spi_draw_picture_blocking(uint16_t x1, uint16_t y1, uint16_t x2, ui
int ili9488_spi_draw_is_busy(void);
#endif
#endif

View file

@ -25,38 +25,35 @@
#if defined(LCD_SPI_ST7789V)
#include "bflb_mtimer.h"
#include "bflb_spi.h"
#include "bflb_dma.h"
#include "bflb_gpio.h"
#include "bflb_l1c.h"
#include "st7789v_spi.h"
#if (LCD_SPI_INTERFACE_TYPE == 1)
#include "bl_spi_hard_4.h"
#if (defined(BL808) || defined(BL606P)) && defined(CPU_D0)
#define ST7789V_SPI_ID 1
#define ST7789V_SPI_NAME "spi1"
#define ST7789V_SPI_DMA_NAME "dma2_ch0"
#else
#define ST7789V_SPI_ID 0
#define ST7789V_SPI_NAME "spi0"
#define ST7789V_SPI_DMA_NAME "dma0_ch3"
#define lcd_spi_init lcd_spi_hard_4_init
#define lcd_spi_isbusy lcd_spi_hard_4_is_busy
#define lcd_spi_transmit_cmd_para lcd_spi_hard_4_transmit_cmd_para
#define lcd_spi_transmit_cmd_pixel_sync lcd_spi_hard_4_transmit_cmd_pixel_sync
#define lcd_spi_transmit_cmd_pixel_fill_sync lcd_spi_hard_4_transmit_cmd_pixel_fill_sync
#define lcd_spi_sync_callback_enable lcd_spi_hard_4_async_callback_enable
#define lcd_spi_async_callback_register lcd_spi_hard_4_async_callback_register
#define lcd_spi_transmit_cmd_pixel_async lcd_spi_hard_4_transmit_cmd_pixel_async
#define lcd_spi_transmit_cmd_pixel_fill_async lcd_spi_hard_4_transmit_cmd_pixel_fill_async
static lcd_spi_hard_4_init_t spi_para = {
.clock_freq = 40 * 1000 * 1000,
#if (ST7789V_SPI_PIXEL_FORMAT == 1)
.pixel_format = LCD_SPI_LCD_PIXEL_FORMAT_RGB565,
#elif (ST7789V_SPI_PIXEL_FORMAT == 2)
.pixel_format = LCD_SPI_LCD_PIXEL_FORMAT_NRGB8888,
#endif
};
#define ST7789V_DMA_LLI_NUM (ST7789V_SPI_W * ST7789V_SPI_H / 4064 + 1)
#else
/* asynchronous flush interrupt callback */
typedef void (*st7789v_spi_callback)(void);
static volatile st7789v_spi_callback st7789v_spi_async_callback = NULL;
static volatile bool st7789v_spi_sync_flush_flag = 0;
static struct bflb_device_s *st7789v_gpio;
static struct bflb_device_s *st7789v_spi;
static struct bflb_device_s *st7789v_dma_spi_tx;
/* The memory space of DMA */
static struct bflb_dma_channel_lli_pool_s dam_tx_llipool[ST7789V_DMA_LLI_NUM];
static struct bflb_dma_channel_lli_transfer_s dma_tx_transfers[1];
#error "Configuration error"
#endif
const st7789v_spi_init_cmd_t st7789v_spi_init_cmds[] = {
{ 0x01, NULL, 0 },
{ 0xFF, NULL, 10 },
@ -71,23 +68,13 @@ const st7789v_spi_init_cmd_t st7789v_spi_init_cmds[] = {
};
/**
* @brief st7789v_spi_dma_flush_callback
* @brief st7789v_spi_async_callback_enable
*
* @return
*/
void st7789v_spi_dma_flush_callback(void *args)
void st7789v_spi_async_callback_enable(bool enable)
{
if (st7789v_spi_sync_flush_flag == true) {
st7789v_spi_sync_flush_flag = false;
return;
}
while (lcd_draw_is_busy()) {
};
if (st7789v_spi_async_callback != NULL) {
st7789v_spi_async_callback();
}
lcd_spi_sync_callback_enable(enable);
}
/**
@ -97,123 +84,7 @@ void st7789v_spi_dma_flush_callback(void *args)
*/
void st7789v_spi_async_callback_register(void (*callback)(void))
{
st7789v_spi_async_callback = callback;
}
/**
* @brief st7789v_spi_init
*
* @return int 0:succes 1:error
*/
static int st7789v_spi_peripheral_init(void)
{
/* spi */
struct bflb_spi_config_s spi_cfg = {
.freq = 80 * 1000 * 1000,
.role = SPI_ROLE_MASTER,
.mode = SPI_MODE3,
.data_width = SPI_DATA_WIDTH_8BIT,
.bit_order = SPI_BIT_MSB,
.byte_order = SPI_BYTE_LSB,
.tx_fifo_threshold = 0,
.rx_fifo_threshold = 0,
};
/* dma */
struct bflb_dma_channel_config_s dma_spi_tx_cfg = {
.direction = DMA_MEMORY_TO_PERIPH,
.src_req = DMA_REQUEST_NONE,
.dst_req = DMA_REQUEST_SPI0_TX,
.src_addr_inc = DMA_ADDR_INCREMENT_ENABLE,
.dst_addr_inc = DMA_ADDR_INCREMENT_DISABLE,
.src_burst_count = DMA_BURST_INCR1,
.dst_burst_count = DMA_BURST_INCR1,
.src_width = DMA_DATA_WIDTH_16BIT,
.dst_width = DMA_DATA_WIDTH_16BIT,
};
/* CS and DC pin init */
st7789v_gpio = bflb_device_get_by_name("gpio");
bflb_gpio_init(st7789v_gpio, ST7789V_SPI_CS_PIN, GPIO_OUTPUT | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1);
bflb_gpio_init(st7789v_gpio, ST7789V_SPI_DC_PIN, GPIO_OUTPUT | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1);
ST7789V_SPI_CS_HIGH;
ST7789V_SPI_DC_HIGH;
#if (SPI_FIFO_WIDTH_VARIABLE_SUPPORT) && (SPI_FIFO_BYTE_NUM_MAX > (2 * 4))
/* SPI support burst*4 */
spi_cfg.tx_fifo_threshold = 2 * 4 - 1;
spi_cfg.rx_fifo_threshold = 2 * 4 - 1;
#elif (!SPI_FIFO_WIDTH_VARIABLE_SUPPORT) && (SPI_FIFO_WORD_NUM_MAX > 4)
/* SPI support burst*4 */
spi_cfg.tx_fifo_threshold = 4 - 1;
spi_cfg.rx_fifo_threshold = 4 - 1;
#endif
#if (SPI_FIFO_WIDTH_VARIABLE_SUPPORT)
spi_cfg.byte_order = SPI_BYTE_MSB;
#endif
/* spi init */
st7789v_spi = bflb_device_get_by_name(ST7789V_SPI_NAME);
bflb_spi_init(st7789v_spi, &spi_cfg);
/* spi enabled continuous mode */
bflb_spi_feature_control(st7789v_spi, SPI_CMD_SET_CS_INTERVAL, true);
#if (ST7789V_SPI_ID == 0)
dma_spi_tx_cfg.dst_req = DMA_REQUEST_SPI0_TX;
#elif (ST7789V_SPI_ID == 1)
dma_spi_tx_cfg.dst_req = DMA_REQUEST_SPI1_TX;
#endif
#if (SPI_FIFO_WIDTH_VARIABLE_SUPPORT) && (SPI_FIFO_BYTE_NUM_MAX > (2 * 4))
/* DMA support burst*4 */
dma_spi_tx_cfg.src_burst_count = DMA_BURST_INCR4;
dma_spi_tx_cfg.dst_burst_count = DMA_BURST_INCR4;
#elif (!SPI_FIFO_WIDTH_VARIABLE_SUPPORT) && (SPI_FIFO_WORD_NUM_MAX > 4)
/* DMA support burst*4 */
dma_spi_tx_cfg.src_burst_count = DMA_BURST_INCR4;
dma_spi_tx_cfg.dst_burst_count = DMA_BURST_INCR4;
#endif
/* dma init */
st7789v_dma_spi_tx = bflb_device_get_by_name(ST7789V_SPI_DMA_NAME);
bflb_dma_channel_init(st7789v_dma_spi_tx, &dma_spi_tx_cfg);
/* dma int cfg */
bflb_dma_channel_irq_attach(st7789v_dma_spi_tx, st7789v_spi_dma_flush_callback, NULL);
return 0;
}
/**
* @brief st7789v_spi_write_cmd
*
* @param cmd
* @return int 0:succes 1:error
*/
static int st7789v_spi_write_cmd(uint8_t cmd)
{
ST7789V_SPI_DC_LOW;
ST7789V_SPI_CS_LOW;
bflb_spi_poll_send(st7789v_spi, cmd);
ST7789V_SPI_CS_HIGH;
ST7789V_SPI_DC_HIGH;
return 0;
}
/**
* @brief st7789v_spi_write_data_byte
*
* @param data
* @return int 0:succes 1:error
*/
static int st7789v_spi_write_data_byte(uint8_t data)
{
ST7789V_SPI_CS_LOW;
bflb_spi_poll_send(st7789v_spi, data);
ST7789V_SPI_CS_HIGH;
return 0;
lcd_spi_async_callback_register(callback);
}
/**
@ -225,23 +96,7 @@ static int st7789v_spi_write_data_byte(uint8_t data)
*/
int st7789v_spi_draw_is_busy(void)
{
if (bflb_dma_channel_isbusy(st7789v_dma_spi_tx)) {
return 1;
} else {
/* Wait for the SPI bus to be idle */
while (bflb_spi_isbusy(st7789v_spi)) {
__ASM volatile("nop");
};
/* Switch the SPI to non-DMA mode */
bflb_spi_link_txdma(st7789v_spi, false);
/* clear rx fifo */
bflb_spi_feature_control(st7789v_spi, SPI_CMD_CLEAR_RX_FIFO, 0);
/* */
ST7789V_SPI_CS_HIGH;
/* 8-bit data */
bflb_spi_feature_control(st7789v_spi, SPI_CMD_SET_DATA_WIDTH, SPI_DATA_WIDTH_8BIT);
return 0;
}
return lcd_spi_isbusy();
}
/**
@ -251,48 +106,19 @@ int st7789v_spi_draw_is_busy(void)
*/
int st7789v_spi_init()
{
int res = st7789v_spi_peripheral_init();
if (res < 0) {
return res;
}
lcd_spi_init(&spi_para);
for (uint16_t i = 0; i < (sizeof(st7789v_spi_init_cmds) / sizeof(st7789v_spi_init_cmd_t)); i++) {
if (st7789v_spi_init_cmds[i].cmd == 0xFF && st7789v_spi_init_cmds[i].data == NULL) {
for (uint16_t i = 0; i < (sizeof(st7789v_spi_init_cmds) / sizeof(st7789v_spi_init_cmds[0])); i++) {
if (st7789v_spi_init_cmds[i].cmd == 0xFF && st7789v_spi_init_cmds[i].data == NULL && st7789v_spi_init_cmds[i].databytes) {
bflb_mtimer_delay_ms(st7789v_spi_init_cmds[i].databytes);
} else {
/* send register address */
st7789v_spi_write_cmd(st7789v_spi_init_cmds[i].cmd);
/* send register data */
for (uint8_t j = 0; j < (st7789v_spi_init_cmds[i].databytes); j++) {
st7789v_spi_write_data_byte(st7789v_spi_init_cmds[i].data[j]);
}
lcd_spi_transmit_cmd_para(st7789v_spi_init_cmds[i].cmd, (void *)(st7789v_spi_init_cmds[i].data), st7789v_spi_init_cmds[i].databytes);
}
}
st7789v_spi_set_draw_window(0, 0, ST7789V_SPI_H, ST7789V_SPI_W);
return res;
}
#if (SPI_FIFO_WIDTH_VARIABLE_SUPPORT == 0)
/**
* @brief lcd_swap_color_data16
*
* @param dst destination
* @param src source
* @param color_num color num
* @return int
*/
static int lcd_swap_color_data16(uint16_t *dst, uint16_t *src, uint32_t color_num)
{
for (size_t i = 0; i < color_num; i++) {
dst[i] = (src[i] << 8) | (src[i] >> 8);
}
return 0;
}
#endif
/**
* @brief
*
@ -302,6 +128,7 @@ static int lcd_swap_color_data16(uint16_t *dst, uint16_t *src, uint32_t color_nu
int st7789v_spi_set_dir(uint8_t dir, uint8_t mir_flag)
{
uint8_t param;
switch (dir) {
case 0:
if (!mir_flag)
@ -332,8 +159,9 @@ int st7789v_spi_set_dir(uint8_t dir, uint8_t mir_flag)
return -1;
break;
}
st7789v_spi_write_cmd(0x36);
st7789v_spi_write_data_byte(param);
lcd_spi_transmit_cmd_para(0x36, (void *)&param, 1);
return dir;
}
@ -345,7 +173,7 @@ int st7789v_spi_set_dir(uint8_t dir, uint8_t mir_flag)
* @param x2
* @param y2
*/
void st7789v_spi_set_draw_window(uint32_t x1, uint32_t y1, uint32_t x2, uint32_t y2)
void st7789v_spi_set_draw_window(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2)
{
#if ST7789V_SPI_OFFSET_X
x1 += ST7789V_SPI_OFFSET_X;
@ -356,19 +184,21 @@ void st7789v_spi_set_draw_window(uint32_t x1, uint32_t y1, uint32_t x2, uint32_t
y2 += ST7789V_SPI_OFFSET_Y;
#endif
st7789v_spi_write_cmd(0x2a);
st7789v_spi_write_data_byte(x1 >> 8);
st7789v_spi_write_data_byte(x1);
st7789v_spi_write_data_byte(x2 >> 8);
st7789v_spi_write_data_byte(x2);
int8_t param[4];
st7789v_spi_write_cmd(0x2b);
st7789v_spi_write_data_byte(y1 >> 8);
st7789v_spi_write_data_byte(y1);
st7789v_spi_write_data_byte(y2 >> 8);
st7789v_spi_write_data_byte(y2);
param[0] = (x1 >> 8) & 0xFF;
param[1] = x1 & 0xFF;
param[2] = (x2 >> 8) & 0xFF;
param[3] = x2 & 0xFF;
st7789v_spi_write_cmd(0x2c);
lcd_spi_transmit_cmd_para(0x2A, (void *)param, 4);
param[0] = (y1 >> 8) & 0xFF;
param[1] = y1 & 0xFF;
param[2] = (y2 >> 8) & 0xFF;
param[3] = y2 & 0xFF;
lcd_spi_transmit_cmd_para(0x2B, (void *)param, 4);
}
/**
@ -380,16 +210,10 @@ void st7789v_spi_set_draw_window(uint32_t x1, uint32_t y1, uint32_t x2, uint32_t
*/
void st7789v_spi_draw_point(uint16_t x, uint16_t y, st7789v_spi_color_t color)
{
#if (SPI_FIFO_WIDTH_VARIABLE_SUPPORT == 0)
color = ((color >> 8) & 0xFF) | color << 8;
#endif
/* set window */
st7789v_spi_set_draw_window(x, y, x, y);
ST7789V_SPI_DC_HIGH;
ST7789V_SPI_CS_LOW;
bflb_spi_poll_send(st7789v_spi, color & 0x00ff);
bflb_spi_poll_send(st7789v_spi, (color >> 8) & 0x00ff);
ST7789V_SPI_CS_HIGH;
lcd_spi_transmit_cmd_pixel_sync(0x2C, (void *)&color, 1);
}
/**
@ -403,57 +227,12 @@ void st7789v_spi_draw_point(uint16_t x, uint16_t y, st7789v_spi_color_t color)
*/
void st7789v_spi_draw_area(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, st7789v_spi_color_t color)
{
uint32_t pixelDataSize, PixelCount = (x2 - x1 + 1) * (y2 - y1 + 1);
uint32_t __attribute__((aligned(64))) color_src;
#if (SPI_FIFO_WIDTH_VARIABLE_SUPPORT)
color_src = color;
#else
color_src = ((color >> 8) & 0xFF) | color << 8;
#endif
/* clean cache */
bflb_l1c_dcache_clean_range((void *)&color_src, sizeof(color_src));
uint32_t pixel_cnt = (x2 - x1 + 1) * (y2 - y1 + 1);
/* set window */
st7789v_spi_set_draw_window(x1, y1, x2, y2);
/* get pixel Data Size */
pixelDataSize = PixelCount * 2;
/* spi 16-bit mode */
bflb_spi_feature_control(st7789v_spi, SPI_CMD_SET_DATA_WIDTH, SPI_DATA_WIDTH_16BIT);
/* enable spi dma mode */
bflb_spi_link_txdma(st7789v_spi, true);
ST7789V_SPI_CS_LOW;
/* sync mode flag, temporary shutdown interrupt */
st7789v_spi_sync_flush_flag = true;
/* disable dma src_addr_inc */
bflb_dma_feature_control(st7789v_dma_spi_tx, DMA_CMD_SET_SRCADDR_INCREMENT, false);
/* cfg and start dma */
dma_tx_transfers[0].src_addr = (uint32_t)(uintptr_t)&color_src;
#if (defined(BL808) || defined(BL606P)) && defined(CPU_D0)
dma_tx_transfers[0].dst_addr = (uint32_t)DMA_ADDR_SPI1_TDR;
#else
dma_tx_transfers[0].dst_addr = (uint32_t)DMA_ADDR_SPI0_TDR;
#endif
dma_tx_transfers[0].nbytes = pixelDataSize;
bflb_dma_channel_lli_reload(st7789v_dma_spi_tx, dam_tx_llipool, ST7789V_DMA_LLI_NUM, dma_tx_transfers, 1);
bflb_dma_channel_start(st7789v_dma_spi_tx);
/* Wait to finish, and cs high */
while (st7789v_spi_draw_is_busy()) {
__ASM volatile("nop");
};
/* enable src_addr_inc */
bflb_dma_feature_control(st7789v_dma_spi_tx, DMA_CMD_SET_SRCADDR_INCREMENT, true);
lcd_spi_transmit_cmd_pixel_fill_sync(0x2C, (uint32_t)color, pixel_cnt);
}
/**
@ -468,31 +247,12 @@ void st7789v_spi_draw_area(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, s
*/
void st7789v_spi_draw_picture_nonblocking(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, st7789v_spi_color_t *picture)
{
size_t picture_size = (x2 - x1 + 1) * (y2 - y1 + 1);
size_t pixel_cnt = (x2 - x1 + 1) * (y2 - y1 + 1);
/* set window */
st7789v_spi_set_draw_window(x1, y1, x2, y2);
#if (SPI_FIFO_WIDTH_VARIABLE_SUPPORT == 0)
lcd_swap_color_data16(picture, picture, picture_size);
#endif
/* clean dcache */
bflb_l1c_dcache_clean_range((void *)(picture), (picture_size * 2));
/* spi 16-bit data mode */
bflb_spi_feature_control(st7789v_spi, SPI_CMD_SET_DATA_WIDTH, SPI_DATA_WIDTH_16BIT);
/* spi dma mode enable */
bflb_spi_link_txdma(st7789v_spi, true);
ST7789V_SPI_CS_LOW;
/* dma cfg and start */
dma_tx_transfers[0].src_addr = (uint32_t)(uintptr_t)picture;
dma_tx_transfers[0].dst_addr = (uint32_t)DMA_ADDR_SPI0_TDR;
dma_tx_transfers[0].nbytes = picture_size * 2;
bflb_dma_channel_lli_reload(st7789v_dma_spi_tx, dam_tx_llipool, sizeof(dam_tx_llipool) / sizeof(dam_tx_llipool[0]), dma_tx_transfers, 1);
bflb_dma_channel_start(st7789v_dma_spi_tx);
lcd_spi_transmit_cmd_pixel_async(0x2C, (void *)picture, pixel_cnt);
}
/**
@ -506,13 +266,12 @@ void st7789v_spi_draw_picture_nonblocking(uint16_t x1, uint16_t y1, uint16_t x2,
*/
void st7789v_spi_draw_picture_blocking(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, st7789v_spi_color_t *picture)
{
/* sync mode, temporary shutdown interrupt */
st7789v_spi_sync_flush_flag = true;
size_t pixel_cnt = (x2 - x1 + 1) * (y2 - y1 + 1);
st7789v_spi_draw_picture_nonblocking(x1, y1, x2, y2, picture);
while (st7789v_spi_draw_is_busy()) {
__ASM volatile("nop");
};
/* set window */
st7789v_spi_set_draw_window(x1, y1, x2, y2);
lcd_spi_transmit_cmd_pixel_sync(0x2C, (void *)picture, pixel_cnt);
}
#endif

View file

@ -24,21 +24,11 @@
#ifndef _ST7789V_SPI_H_
#define _ST7789V_SPI_H_
#include "bflb_core.h"
#include "../lcd_conf.h"
#define ST7789V_SPI_CS_PIN GPIO_PIN_12
#define ST7789V_SPI_DC_PIN GPIO_PIN_13
#if defined LCD_SPI_ST7789V
#define ST7789V_SPI_CS_HIGH bflb_gpio_set(st7789v_gpio, ST7789V_SPI_CS_PIN)
#define ST7789V_SPI_CS_LOW bflb_gpio_reset(st7789v_gpio, ST7789V_SPI_CS_PIN)
#define ST7789V_SPI_DC_HIGH bflb_gpio_set(st7789v_gpio, ST7789V_SPI_DC_PIN)
#define ST7789V_SPI_DC_LOW bflb_gpio_reset(st7789v_gpio, ST7789V_SPI_DC_PIN)
#define ST7789V_SPI_W 240 /* ST7789V LCD width */
#define ST7789V_SPI_H 280 /* ST7789V LCD height */
#define ST7789V_SPI_OFFSET_X 0
#define ST7789V_SPI_OFFSET_Y 20
/* Do not modify the following */
#define ST7789V_SPI_COLOR_DEPTH 16
@ -51,9 +41,10 @@ typedef struct {
typedef uint16_t st7789v_spi_color_t;
int st7789v_spi_init();
void st7789v_spi_async_callback_enable(bool enable);
void st7789v_spi_async_callback_register(void (*callback)(void));
int st7789v_spi_set_dir(uint8_t dir, uint8_t mir_flag);
void st7789v_spi_set_draw_window(uint32_t x1, uint32_t y1, uint32_t x2, uint32_t y2);
void st7789v_spi_set_draw_window(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2);
void st7789v_spi_draw_point(uint16_t x, uint16_t y, st7789v_spi_color_t color);
void st7789v_spi_draw_area(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, st7789v_spi_color_t color);
void st7789v_spi_draw_picture_nonblocking(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, st7789v_spi_color_t *picture);
@ -61,3 +52,4 @@ void st7789v_spi_draw_picture_blocking(uint16_t x1, uint16_t y1, uint16_t x2, ui
int st7789v_spi_draw_is_busy(void);
#endif
#endif

View file

@ -25,38 +25,35 @@
#if defined(LCD_SPI_ST7796)
#include "bflb_mtimer.h"
#include "bflb_spi.h"
#include "bflb_dma.h"
#include "bflb_gpio.h"
#include "bflb_l1c.h"
#include "st7796_spi.h"
#if (LCD_SPI_INTERFACE_TYPE == 1)
#include "bl_spi_hard_4.h"
#if (defined(BL808) || defined(BL606P)) && defined(CPU_D0)
#define ST7796_SPI_ID 1
#define ST7796_SPI_NAME "spi1"
#define ST7796_SPI_DMA_NAME "dma2_ch0"
#else
#define ST7796_SPI_ID 0
#define ST7796_SPI_NAME "spi0"
#define ST7796_SPI_DMA_NAME "dma0_ch3"
#define lcd_spi_init lcd_spi_hard_4_init
#define lcd_spi_isbusy lcd_spi_hard_4_is_busy
#define lcd_spi_transmit_cmd_para lcd_spi_hard_4_transmit_cmd_para
#define lcd_spi_transmit_cmd_pixel_sync lcd_spi_hard_4_transmit_cmd_pixel_sync
#define lcd_spi_transmit_cmd_pixel_fill_sync lcd_spi_hard_4_transmit_cmd_pixel_fill_sync
#define lcd_spi_sync_callback_enable lcd_spi_hard_4_async_callback_enable
#define lcd_spi_async_callback_register lcd_spi_hard_4_async_callback_register
#define lcd_spi_transmit_cmd_pixel_async lcd_spi_hard_4_transmit_cmd_pixel_async
#define lcd_spi_transmit_cmd_pixel_fill_async lcd_spi_hard_4_transmit_cmd_pixel_fill_async
static lcd_spi_hard_4_init_t spi_para = {
.clock_freq = 40 * 1000 * 1000,
#if (ST7796_SPI_PIXEL_FORMAT == 1)
.pixel_format = LCD_SPI_LCD_PIXEL_FORMAT_RGB565,
#elif (ST7796_SPI_PIXEL_FORMAT == 2)
.pixel_format = LCD_SPI_LCD_PIXEL_FORMAT_NRGB8888,
#endif
};
#define ST7796_DMA_LLI_NUM (ST7796_SPI_W * ST7796_SPI_H / 4064 + 1)
#else
/* asynchronous flush interrupt callback */
typedef void (*st7796_spi_callback)(void);
static volatile st7796_spi_callback st7796_spi_async_callback = NULL;
static volatile bool st7796_spi_sync_flush_flag = 0;
static struct bflb_device_s *st7796_gpio;
static struct bflb_device_s *st7796_spi;
static struct bflb_device_s *st7796_dma_spi_tx;
/* The memory space of DMA */
static struct bflb_dma_channel_lli_pool_s dam_tx_llipool[ST7796_DMA_LLI_NUM];
static struct bflb_dma_channel_lli_transfer_s dma_tx_transfers[1];
#error "Configuration error"
#endif
const st7796_spi_init_cmd_t st7796_spi_init_cmds[] = {
{ 0x01, NULL, 0 },
{ 0xFF, NULL, 10 },
@ -72,8 +69,8 @@ const st7796_spi_init_cmd_t st7796_spi_init_cmds[] = {
{ 0xE6, "\x0F\xF2\x3F\x4F\x4F\x28\x0E\x00", 8 },
{ 0xC5, "\x2A", 1 },
/* Display Inversion */
#if 0
/* Color reversal */
#if ST7796_SPI_COLOR_REVERSAL
{ 0xB4, "\x01", 1 },
{ 0x21, NULL, 0 },
#endif
@ -89,23 +86,13 @@ const st7796_spi_init_cmd_t st7796_spi_init_cmds[] = {
};
/**
* @brief st7796_spi_dma_flush_callback
* @brief st7796_spi_async_callback_enable
*
* @return
*/
void st7796_spi_dma_flush_callback(void *args)
void st7796_spi_async_callback_enable(bool enable)
{
if (st7796_spi_sync_flush_flag == true) {
st7796_spi_sync_flush_flag = false;
return;
}
while (lcd_draw_is_busy()) {
};
if (st7796_spi_async_callback != NULL) {
st7796_spi_async_callback();
}
lcd_spi_sync_callback_enable(enable);
}
/**
@ -115,123 +102,7 @@ void st7796_spi_dma_flush_callback(void *args)
*/
void st7796_spi_async_callback_register(void (*callback)(void))
{
st7796_spi_async_callback = callback;
}
/**
* @brief st7796_spi_init
*
* @return int 0:succes 1:error
*/
static int st7796_spi_peripheral_init(void)
{
/* spi */
struct bflb_spi_config_s spi_cfg = {
.freq = 40 * 1000 * 1000,
.role = SPI_ROLE_MASTER,
.mode = SPI_MODE3,
.data_width = SPI_DATA_WIDTH_8BIT,
.bit_order = SPI_BIT_MSB,
.byte_order = SPI_BYTE_LSB,
.tx_fifo_threshold = 0,
.rx_fifo_threshold = 0,
};
/* dma */
struct bflb_dma_channel_config_s dma_spi_tx_cfg = {
.direction = DMA_MEMORY_TO_PERIPH,
.src_req = DMA_REQUEST_NONE,
.dst_req = DMA_REQUEST_SPI0_TX,
.src_addr_inc = DMA_ADDR_INCREMENT_ENABLE,
.dst_addr_inc = DMA_ADDR_INCREMENT_DISABLE,
.src_burst_count = DMA_BURST_INCR1,
.dst_burst_count = DMA_BURST_INCR1,
.src_width = DMA_DATA_WIDTH_16BIT,
.dst_width = DMA_DATA_WIDTH_16BIT,
};
/* CS and DC pin init */
st7796_gpio = bflb_device_get_by_name("gpio");
bflb_gpio_init(st7796_gpio, ST7796_SPI_CS_PIN, GPIO_OUTPUT | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1);
bflb_gpio_init(st7796_gpio, ST7796_SPI_DC_PIN, GPIO_OUTPUT | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1);
ST7796_SPI_CS_HIGH;
ST7796_SPI_DC_HIGH;
#if (SPI_FIFO_WIDTH_VARIABLE_SUPPORT) && (SPI_FIFO_BYTE_NUM_MAX > (2 * 4))
/* SPI support burst*4 */
spi_cfg.tx_fifo_threshold = 2 * 4 - 1;
spi_cfg.rx_fifo_threshold = 2 * 4 - 1;
#elif (!SPI_FIFO_WIDTH_VARIABLE_SUPPORT) && (SPI_FIFO_WORD_NUM_MAX > 4)
/* SPI support burst*4 */
spi_cfg.tx_fifo_threshold = 4 - 1;
spi_cfg.rx_fifo_threshold = 4 - 1;
#endif
#if (SPI_FIFO_WIDTH_VARIABLE_SUPPORT)
spi_cfg.byte_order = SPI_BYTE_MSB;
#endif
/* spi init */
st7796_spi = bflb_device_get_by_name(ST7796_SPI_NAME);
bflb_spi_init(st7796_spi, &spi_cfg);
/* spi enabled continuous mode */
bflb_spi_feature_control(st7796_spi, SPI_CMD_SET_CS_INTERVAL, true);
#if (ST7796_SPI_ID == 0)
dma_spi_tx_cfg.dst_req = DMA_REQUEST_SPI0_TX;
#elif (ST7796_SPI_ID == 1)
dma_spi_tx_cfg.dst_req = DMA_REQUEST_SPI1_TX;
#endif
#if (SPI_FIFO_WIDTH_VARIABLE_SUPPORT) && (SPI_FIFO_BYTE_NUM_MAX > (2 * 4))
/* DMA support burst*4 */
dma_spi_tx_cfg.src_burst_count = DMA_BURST_INCR4;
dma_spi_tx_cfg.dst_burst_count = DMA_BURST_INCR4;
#elif (!SPI_FIFO_WIDTH_VARIABLE_SUPPORT) && (SPI_FIFO_WORD_NUM_MAX > 4)
/* DMA support burst*4 */
dma_spi_tx_cfg.src_burst_count = DMA_BURST_INCR4;
dma_spi_tx_cfg.dst_burst_count = DMA_BURST_INCR4;
#endif
/* dma init */
st7796_dma_spi_tx = bflb_device_get_by_name(ST7796_SPI_DMA_NAME);
bflb_dma_channel_init(st7796_dma_spi_tx, &dma_spi_tx_cfg);
/* dma int cfg */
bflb_dma_channel_irq_attach(st7796_dma_spi_tx, st7796_spi_dma_flush_callback, NULL);
return 0;
}
/**
* @brief st7796_spi_write_cmd
*
* @param cmd
* @return int 0:succes 1:error
*/
static int st7796_spi_write_cmd(uint8_t cmd)
{
ST7796_SPI_DC_LOW;
ST7796_SPI_CS_LOW;
bflb_spi_poll_send(st7796_spi, cmd);
ST7796_SPI_CS_HIGH;
ST7796_SPI_DC_HIGH;
return 0;
}
/**
* @brief st7796_spi_write_data_byte
*
* @param data
* @return int 0:succes 1:error
*/
static int st7796_spi_write_data_byte(uint8_t data)
{
ST7796_SPI_CS_LOW;
bflb_spi_poll_send(st7796_spi, data);
ST7796_SPI_CS_HIGH;
return 0;
lcd_spi_async_callback_register(callback);
}
/**
@ -243,23 +114,7 @@ static int st7796_spi_write_data_byte(uint8_t data)
*/
int st7796_spi_draw_is_busy(void)
{
if (bflb_dma_channel_isbusy(st7796_dma_spi_tx)) {
return 1;
} else {
/* Wait for the SPI bus to be idle */
while (bflb_spi_isbusy(st7796_spi)) {
__ASM volatile("nop");
};
/* Switch the SPI to non-DMA mode */
bflb_spi_link_txdma(st7796_spi, false);
/* clear rx fifo */
bflb_spi_feature_control(st7796_spi, SPI_CMD_CLEAR_RX_FIFO, 0);
/* */
ST7796_SPI_CS_HIGH;
/* 8-bit data */
bflb_spi_feature_control(st7796_spi, SPI_CMD_SET_DATA_WIDTH, SPI_DATA_WIDTH_8BIT);
return 0;
}
return lcd_spi_isbusy();
}
/**
@ -269,48 +124,19 @@ int st7796_spi_draw_is_busy(void)
*/
int st7796_spi_init()
{
int res = st7796_spi_peripheral_init();
if (res < 0) {
return res;
}
lcd_spi_init(&spi_para);
for (uint16_t i = 0; i < (sizeof(st7796_spi_init_cmds) / sizeof(st7796_spi_init_cmd_t)); i++) {
if (st7796_spi_init_cmds[i].cmd == 0xFF && st7796_spi_init_cmds[i].data == NULL) {
for (uint16_t i = 0; i < (sizeof(st7796_spi_init_cmds) / sizeof(st7796_spi_init_cmds[0])); i++) {
if (st7796_spi_init_cmds[i].cmd == 0xFF && st7796_spi_init_cmds[i].data == NULL && st7796_spi_init_cmds[i].databytes) {
bflb_mtimer_delay_ms(st7796_spi_init_cmds[i].databytes);
} else {
/* send register address */
st7796_spi_write_cmd(st7796_spi_init_cmds[i].cmd);
/* send register data */
for (uint8_t j = 0; j < (st7796_spi_init_cmds[i].databytes); j++) {
st7796_spi_write_data_byte(st7796_spi_init_cmds[i].data[j]);
}
lcd_spi_transmit_cmd_para(st7796_spi_init_cmds[i].cmd, (void *)(st7796_spi_init_cmds[i].data), st7796_spi_init_cmds[i].databytes);
}
}
st7796_spi_set_draw_window(0, 0, ST7796_SPI_H, ST7796_SPI_W);
return res;
}
#if (SPI_FIFO_WIDTH_VARIABLE_SUPPORT == 0)
/**
* @brief lcd_swap_color_data16
*
* @param dst destination
* @param src source
* @param color_num color num
* @return int
*/
static int lcd_swap_color_data16(uint16_t *dst, uint16_t *src, uint32_t color_num)
{
for (size_t i = 0; i < color_num; i++) {
dst[i] = (src[i] << 8) | (src[i] >> 8);
}
return 0;
}
#endif
/**
* @brief
*
@ -320,6 +146,7 @@ static int lcd_swap_color_data16(uint16_t *dst, uint16_t *src, uint32_t color_nu
int st7796_spi_set_dir(uint8_t dir, uint8_t mir_flag)
{
uint8_t param;
switch (dir) {
case 0:
if (!mir_flag)
@ -350,8 +177,9 @@ int st7796_spi_set_dir(uint8_t dir, uint8_t mir_flag)
return -1;
break;
}
st7796_spi_write_cmd(0x36);
st7796_spi_write_data_byte(param);
lcd_spi_transmit_cmd_para(0x36, (void *)&param, 1);
return dir;
}
@ -363,7 +191,7 @@ int st7796_spi_set_dir(uint8_t dir, uint8_t mir_flag)
* @param x2
* @param y2
*/
void st7796_spi_set_draw_window(uint32_t x1, uint32_t y1, uint32_t x2, uint32_t y2)
void st7796_spi_set_draw_window(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2)
{
#if ST7796_SPI_OFFSET_X
x1 += ST7796_SPI_OFFSET_X;
@ -374,19 +202,21 @@ void st7796_spi_set_draw_window(uint32_t x1, uint32_t y1, uint32_t x2, uint32_t
y2 += ST7796_SPI_OFFSET_Y;
#endif
st7796_spi_write_cmd(0x2a);
st7796_spi_write_data_byte(x1 >> 8);
st7796_spi_write_data_byte(x1);
st7796_spi_write_data_byte(x2 >> 8);
st7796_spi_write_data_byte(x2);
int8_t param[4];
st7796_spi_write_cmd(0x2b);
st7796_spi_write_data_byte(y1 >> 8);
st7796_spi_write_data_byte(y1);
st7796_spi_write_data_byte(y2 >> 8);
st7796_spi_write_data_byte(y2);
param[0] = (x1 >> 8) & 0xFF;
param[1] = x1 & 0xFF;
param[2] = (x2 >> 8) & 0xFF;
param[3] = x2 & 0xFF;
st7796_spi_write_cmd(0x2c);
lcd_spi_transmit_cmd_para(0x2A, (void *)param, 4);
param[0] = (y1 >> 8) & 0xFF;
param[1] = y1 & 0xFF;
param[2] = (y2 >> 8) & 0xFF;
param[3] = y2 & 0xFF;
lcd_spi_transmit_cmd_para(0x2B, (void *)param, 4);
}
/**
@ -398,16 +228,10 @@ void st7796_spi_set_draw_window(uint32_t x1, uint32_t y1, uint32_t x2, uint32_t
*/
void st7796_spi_draw_point(uint16_t x, uint16_t y, st7796_spi_color_t color)
{
#if (SPI_FIFO_WIDTH_VARIABLE_SUPPORT == 0)
color = ((color >> 8) & 0xFF) | color << 8;
#endif
/* set window */
st7796_spi_set_draw_window(x, y, x, y);
ST7796_SPI_DC_HIGH;
ST7796_SPI_CS_LOW;
bflb_spi_poll_send(st7796_spi, color & 0x00ff);
bflb_spi_poll_send(st7796_spi, (color >> 8) & 0x00ff);
ST7796_SPI_CS_HIGH;
lcd_spi_transmit_cmd_pixel_sync(0x2C, (void *)&color, 1);
}
/**
@ -421,57 +245,12 @@ void st7796_spi_draw_point(uint16_t x, uint16_t y, st7796_spi_color_t color)
*/
void st7796_spi_draw_area(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, st7796_spi_color_t color)
{
uint32_t pixelDataSize, PixelCount = (x2 - x1 + 1) * (y2 - y1 + 1);
uint32_t __attribute__((aligned(64))) color_src;
#if (SPI_FIFO_WIDTH_VARIABLE_SUPPORT)
color_src = color;
#else
color_src = ((color >> 8) & 0xFF) | color << 8;
#endif
/* clean cache */
bflb_l1c_dcache_clean_range((void *)&color_src, sizeof(color_src));
uint32_t pixel_cnt = (x2 - x1 + 1) * (y2 - y1 + 1);
/* set window */
st7796_spi_set_draw_window(x1, y1, x2, y2);
/* get pixel Data Size */
pixelDataSize = PixelCount * 2;
/* spi 16-bit mode */
bflb_spi_feature_control(st7796_spi, SPI_CMD_SET_DATA_WIDTH, SPI_DATA_WIDTH_16BIT);
/* enable spi dma mode */
bflb_spi_link_txdma(st7796_spi, true);
ST7796_SPI_CS_LOW;
/* sync mode flag, temporary shutdown interrupt */
st7796_spi_sync_flush_flag = true;
/* disable dma src_addr_inc */
bflb_dma_feature_control(st7796_dma_spi_tx, DMA_CMD_SET_SRCADDR_INCREMENT, false);
/* cfg and start dma */
dma_tx_transfers[0].src_addr = (uint32_t)(uintptr_t)&color_src;
#if (defined(BL808) || defined(BL606P)) && defined(CPU_D0)
dma_tx_transfers[0].dst_addr = (uint32_t)DMA_ADDR_SPI1_TDR;
#else
dma_tx_transfers[0].dst_addr = (uint32_t)DMA_ADDR_SPI0_TDR;
#endif
dma_tx_transfers[0].nbytes = pixelDataSize;
bflb_dma_channel_lli_reload(st7796_dma_spi_tx, dam_tx_llipool, ST7796_DMA_LLI_NUM, dma_tx_transfers, 1);
bflb_dma_channel_start(st7796_dma_spi_tx);
/* Wait to finish, and cs high */
while (st7796_spi_draw_is_busy()) {
__ASM volatile("nop");
};
/* enable src_addr_inc */
bflb_dma_feature_control(st7796_dma_spi_tx, DMA_CMD_SET_SRCADDR_INCREMENT, true);
lcd_spi_transmit_cmd_pixel_fill_sync(0x2C, (uint32_t)color, pixel_cnt);
}
/**
@ -486,31 +265,12 @@ void st7796_spi_draw_area(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, st
*/
void st7796_spi_draw_picture_nonblocking(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, st7796_spi_color_t *picture)
{
size_t picture_size = (x2 - x1 + 1) * (y2 - y1 + 1);
size_t pixel_cnt = (x2 - x1 + 1) * (y2 - y1 + 1);
/* set window */
st7796_spi_set_draw_window(x1, y1, x2, y2);
#if (SPI_FIFO_WIDTH_VARIABLE_SUPPORT == 0)
lcd_swap_color_data16(picture, picture, picture_size);
#endif
/* clean dcache */
bflb_l1c_dcache_clean_range((void *)(picture), (picture_size * 2));
/* spi 16-bit data mode */
bflb_spi_feature_control(st7796_spi, SPI_CMD_SET_DATA_WIDTH, SPI_DATA_WIDTH_16BIT);
/* spi dma mode enable */
bflb_spi_link_txdma(st7796_spi, true);
ST7796_SPI_CS_LOW;
/* dma cfg and start */
dma_tx_transfers[0].src_addr = (uint32_t)(uintptr_t)picture;
dma_tx_transfers[0].dst_addr = (uint32_t)DMA_ADDR_SPI0_TDR;
dma_tx_transfers[0].nbytes = picture_size * 2;
bflb_dma_channel_lli_reload(st7796_dma_spi_tx, dam_tx_llipool, sizeof(dam_tx_llipool) / sizeof(dam_tx_llipool[0]), dma_tx_transfers, 1);
bflb_dma_channel_start(st7796_dma_spi_tx);
lcd_spi_transmit_cmd_pixel_async(0x2C, (void *)picture, pixel_cnt);
}
/**
@ -524,13 +284,12 @@ void st7796_spi_draw_picture_nonblocking(uint16_t x1, uint16_t y1, uint16_t x2,
*/
void st7796_spi_draw_picture_blocking(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, st7796_spi_color_t *picture)
{
/* sync mode, temporary shutdown interrupt */
st7796_spi_sync_flush_flag = true;
size_t pixel_cnt = (x2 - x1 + 1) * (y2 - y1 + 1);
st7796_spi_draw_picture_nonblocking(x1, y1, x2, y2, picture);
while (st7796_spi_draw_is_busy()) {
__ASM volatile("nop");
};
/* set window */
st7796_spi_set_draw_window(x1, y1, x2, y2);
lcd_spi_transmit_cmd_pixel_sync(0x2C, (void *)picture, pixel_cnt);
}
#endif

View file

@ -24,21 +24,11 @@
#ifndef _ST7796_SPI_H_
#define _ST7796_SPI_H_
#include "bflb_core.h"
#include "../lcd_conf.h"
#define ST7796_SPI_CS_PIN GPIO_PIN_16
#define ST7796_SPI_DC_PIN GPIO_PIN_18
#if defined LCD_SPI_ST7796
#define ST7796_SPI_CS_HIGH bflb_gpio_set(st7796_gpio, ST7796_SPI_CS_PIN)
#define ST7796_SPI_CS_LOW bflb_gpio_reset(st7796_gpio, ST7796_SPI_CS_PIN)
#define ST7796_SPI_DC_HIGH bflb_gpio_set(st7796_gpio, ST7796_SPI_DC_PIN)
#define ST7796_SPI_DC_LOW bflb_gpio_reset(st7796_gpio, ST7796_SPI_DC_PIN)
#define ST7796_SPI_W 320 /* ST7796 LCD width */
#define ST7796_SPI_H 480 /* ST7796 LCD height */
#define ST7796_SPI_OFFSET_X 0
#define ST7796_SPI_OFFSET_Y 0
/* Do not modify the following */
#define ST7796_SPI_COLOR_DEPTH 16
@ -51,9 +41,10 @@ typedef struct {
typedef uint16_t st7796_spi_color_t;
int st7796_spi_init();
void st7796_spi_async_callback_enable(bool enable);
void st7796_spi_async_callback_register(void (*callback)(void));
int st7796_spi_set_dir(uint8_t dir, uint8_t mir_flag);
void st7796_spi_set_draw_window(uint32_t x1, uint32_t y1, uint32_t x2, uint32_t y2);
void st7796_spi_set_draw_window(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2);
void st7796_spi_draw_point(uint16_t x, uint16_t y, st7796_spi_color_t color);
void st7796_spi_draw_area(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, st7796_spi_color_t color);
void st7796_spi_draw_picture_nonblocking(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, st7796_spi_color_t *picture);
@ -61,3 +52,4 @@ void st7796_spi_draw_picture_blocking(uint16_t x1, uint16_t y1, uint16_t x2, uin
int st7796_spi_draw_is_busy(void);
#endif
#endif

View file

@ -232,6 +232,11 @@ void SDH_CMDTransferFinished_CallBack(SDH_Handle_Cfg_Type *handle, SDH_Stat_Type
}
}
extern void SDH_MMC1_IRQHandler(void);
static void sdh_isr(int irq, void *arg)
{
SDH_MMC1_IRQHandler();
}
/****************************************************************************/ /**
* @brief SDH INT init
*
@ -242,6 +247,9 @@ void SDH_CMDTransferFinished_CallBack(SDH_Handle_Cfg_Type *handle, SDH_Stat_Type
*******************************************************************************/
static void SDH_INT_Init(void)
{
bflb_irq_attach(33, sdh_isr, NULL);
bflb_irq_enable(33);
SDH_EnableIntStatus(SDH_INT_ALL);
SDH_DisableIntSource(SDH_INT_ALL);
SDH_Trans_Callback_Cfg_TypeInstance.SDH_CallBack_TransferFinished = SDH_DataTransferFinished_CallBack;

View file

@ -53,7 +53,7 @@
#define SWAP_WORD_BYTE_SEQUENCE(x) (__REV(x))
/*! @brief Default block size */
#define SDH_DEFAULT_BLOCK_SIZE (512U)
#define SDH_DEFAULT_BLOCK_SIZE (512U)
typedef enum {
SD_OK = 0,
@ -343,66 +343,66 @@ typedef struct _sd_card {
/**
* @brief SDIO Commands Index
*/
#define SD_CMD_GO_IDLE_STATE ((uint8_t)0)
#define SD_CMD_SEND_OP_COND ((uint8_t)1)
#define SD_CMD_ALL_SEND_CID ((uint8_t)2)
#define SD_CMD_SET_REL_ADDR ((uint8_t)3) /*!< SDIO_SEND_REL_ADDR for SD Card */
#define SD_CMD_SET_DSR ((uint8_t)4)
#define SD_CMD_SDIO_SEN_OP_COND ((uint8_t)5)
#define SD_CMD_HS_SWITCH ((uint8_t)6)
#define SD_CMD_SEL_DESEL_CARD ((uint8_t)7)
#define SD_CMD_HS_SEND_EXT_CSD ((uint8_t)8)
#define SDIO_SEND_IF_COND ((uint8_t)8)
#define SD_CMD_SEND_CSD ((uint8_t)9)
#define SD_CMD_SEND_CID ((uint8_t)10)
#define SD_CMD_READ_DAT_UNTIL_STOP ((uint8_t)11) /*!< SD Card doesn't support it */
#define SD_CMD_STOP_TRANSMISSION ((uint8_t)12)
#define SD_CMD_SEND_STATUS ((uint8_t)13)
#define SD_CMD_HS_BUSTEST_READ ((uint8_t)14)
#define SD_CMD_GO_INACTIVE_STATE ((uint8_t)15)
#define SD_CMD_SET_BLOCKLEN ((uint8_t)16)
#define SD_CMD_READ_SINGLE_BLOCK ((uint8_t)17)
#define SD_CMD_READ_MULT_BLOCK ((uint8_t)18)
#define SD_CMD_HS_BUSTEST_WRITE ((uint8_t)19)
#define SD_CMD_WRITE_DAT_UNTIL_STOP ((uint8_t)20) /*!< SD Card doesn't support it */
#define SD_CMD_SET_BLOCK_COUNT ((uint8_t)23) /*!< SD Card doesn't support it */
#define SD_CMD_WRITE_SINGLE_BLOCK ((uint8_t)24)
#define SD_CMD_WRITE_MULT_BLOCK ((uint8_t)25)
#define SD_CMD_PROG_CID ((uint8_t)26) /*!< reserved for manufacturers */
#define SD_CMD_PROG_CSD ((uint8_t)27)
#define SD_CMD_SET_WRITE_PROT ((uint8_t)28)
#define SD_CMD_CLR_WRITE_PROT ((uint8_t)29)
#define SD_CMD_SEND_WRITE_PROT ((uint8_t)30)
#define SD_CMD_SD_ERASE_GRP_START ((uint8_t)32) /*!< To set the address of the first write
#define SD_CMD_GO_IDLE_STATE ((uint8_t)0)
#define SD_CMD_SEND_OP_COND ((uint8_t)1)
#define SD_CMD_ALL_SEND_CID ((uint8_t)2)
#define SD_CMD_SET_REL_ADDR ((uint8_t)3) /*!< SDIO_SEND_REL_ADDR for SD Card */
#define SD_CMD_SET_DSR ((uint8_t)4)
#define SD_CMD_SDIO_SEN_OP_COND ((uint8_t)5)
#define SD_CMD_HS_SWITCH ((uint8_t)6)
#define SD_CMD_SEL_DESEL_CARD ((uint8_t)7)
#define SD_CMD_HS_SEND_EXT_CSD ((uint8_t)8)
#define SDIO_SEND_IF_COND ((uint8_t)8)
#define SD_CMD_SEND_CSD ((uint8_t)9)
#define SD_CMD_SEND_CID ((uint8_t)10)
#define SD_CMD_READ_DAT_UNTIL_STOP ((uint8_t)11) /*!< SD Card doesn't support it */
#define SD_CMD_STOP_TRANSMISSION ((uint8_t)12)
#define SD_CMD_SEND_STATUS ((uint8_t)13)
#define SD_CMD_HS_BUSTEST_READ ((uint8_t)14)
#define SD_CMD_GO_INACTIVE_STATE ((uint8_t)15)
#define SD_CMD_SET_BLOCKLEN ((uint8_t)16)
#define SD_CMD_READ_SINGLE_BLOCK ((uint8_t)17)
#define SD_CMD_READ_MULT_BLOCK ((uint8_t)18)
#define SD_CMD_HS_BUSTEST_WRITE ((uint8_t)19)
#define SD_CMD_WRITE_DAT_UNTIL_STOP ((uint8_t)20) /*!< SD Card doesn't support it */
#define SD_CMD_SET_BLOCK_COUNT ((uint8_t)23) /*!< SD Card doesn't support it */
#define SD_CMD_WRITE_SINGLE_BLOCK ((uint8_t)24)
#define SD_CMD_WRITE_MULT_BLOCK ((uint8_t)25)
#define SD_CMD_PROG_CID ((uint8_t)26) /*!< reserved for manufacturers */
#define SD_CMD_PROG_CSD ((uint8_t)27)
#define SD_CMD_SET_WRITE_PROT ((uint8_t)28)
#define SD_CMD_CLR_WRITE_PROT ((uint8_t)29)
#define SD_CMD_SEND_WRITE_PROT ((uint8_t)30)
#define SD_CMD_SD_ERASE_GRP_START ((uint8_t)32) /*!< To set the address of the first write
block to be erased. (For SD card only) */
#define SD_CMD_SD_ERASE_GRP_END ((uint8_t)33) /*!< To set the address of the last write block of the
#define SD_CMD_SD_ERASE_GRP_END ((uint8_t)33) /*!< To set the address of the last write block of the
continuous range to be erased. (For SD card only) */
#define SD_CMD_ERASE_GRP_START ((uint8_t)35) /*!< To set the address of the first write block to be erased.
#define SD_CMD_ERASE_GRP_START ((uint8_t)35) /*!< To set the address of the first write block to be erased.
(For MMC card only spec 3.31) */
#define SD_CMD_ERASE_GRP_END ((uint8_t)36) /*!< To set the address of the last write block of the
#define SD_CMD_ERASE_GRP_END ((uint8_t)36) /*!< To set the address of the last write block of the
continuous range to be erased. (For MMC card only spec 3.31) */
#define SD_CMD_ERASE ((uint8_t)38)
#define SD_CMD_FAST_IO ((uint8_t)39) /*!< SD Card doesn't support it */
#define SD_CMD_GO_IRQ_STATE ((uint8_t)40) /*!< SD Card doesn't support it */
#define SD_CMD_LOCK_UNLOCK ((uint8_t)42)
#define SD_CMD_APP_CMD ((uint8_t)55)
#define SD_CMD_GEN_CMD ((uint8_t)56)
#define SD_CMD_NO_CMD ((uint8_t)64)
#define SD_CMD_ERASE ((uint8_t)38)
#define SD_CMD_FAST_IO ((uint8_t)39) /*!< SD Card doesn't support it */
#define SD_CMD_GO_IRQ_STATE ((uint8_t)40) /*!< SD Card doesn't support it */
#define SD_CMD_LOCK_UNLOCK ((uint8_t)42)
#define SD_CMD_APP_CMD ((uint8_t)55)
#define SD_CMD_GEN_CMD ((uint8_t)56)
#define SD_CMD_NO_CMD ((uint8_t)64)
/**
* @brief Following commands are SD Card Specific commands.
* SDIO_APP_CMD :CMD55 should be sent before sending these commands.
*/
#define SD_CMD_APP_SD_SET_BUSWIDTH ((uint8_t)6) /*!< For SD Card only */
#define SD_CMD_SD_APP_STAUS ((uint8_t)13) /*!< For SD Card only */
#define SD_CMD_SD_APP_SEND_NUM_WRITE_BLOCKS ((uint8_t)22) /*!< For SD Card only */
#define SD_CMD_SD_APP_OP_COND ((uint8_t)41) /*!< For SD Card only */
#define SD_CMD_SD_APP_SET_CLR_CARD_DETECT ((uint8_t)42) /*!< For SD Card only */
#define SD_CMD_SD_APP_SEND_SCR ((uint8_t)51) /*!< For SD Card only */
#define SD_CMD_SDIO_RW_DIRECT ((uint8_t)52) /*!< For SD I/O Card only */
#define SD_CMD_SDIO_RW_EXTENDED ((uint8_t)53) /*!< For SD I/O Card only */
#define SD_CMD_APP_SD_SET_BUSWIDTH ((uint8_t)6) /*!< For SD Card only */
#define SD_CMD_SD_APP_STAUS ((uint8_t)13) /*!< For SD Card only */
#define SD_CMD_SD_APP_SEND_NUM_WRITE_BLOCKS ((uint8_t)22) /*!< For SD Card only */
#define SD_CMD_SD_APP_OP_COND ((uint8_t)41) /*!< For SD Card only */
#define SD_CMD_SD_APP_SET_CLR_CARD_DETECT ((uint8_t)42) /*!< For SD Card only */
#define SD_CMD_SD_APP_SEND_SCR ((uint8_t)51) /*!< For SD Card only */
#define SD_CMD_SDIO_RW_DIRECT ((uint8_t)52) /*!< For SD I/O Card only */
#define SD_CMD_SDIO_RW_EXTENDED ((uint8_t)53) /*!< For SD I/O Card only */
/**
* @brief Following commands are SD Card Specific security commands.
@ -423,58 +423,58 @@ typedef struct _sd_card {
/**
* @brief Mask for errors Card Status R1 (CSR Register)
*/
#define SD_CSR_ADDR_OUT_OF_RANGE ((uint32_t)0x80000000)
#define SD_CSR_ADDR_MISALIGNED ((uint32_t)0x40000000)
#define SD_CSR_BLOCK_LEN_ERR ((uint32_t)0x20000000)
#define SD_CSR_ERASE_SEQ_ERR ((uint32_t)0x10000000)
#define SD_CSR_BAD_ERASE_PARAM ((uint32_t)0x08000000)
#define SD_CSR_WRITE_PROT_VIOLATION ((uint32_t)0x04000000)
#define SD_CSR_LOCK_UNLOCK_FAILED ((uint32_t)0x01000000)
#define SD_CSR_COM_CRC_FAILED ((uint32_t)0x00800000)
#define SD_CSR_ILLEGAL_CMD ((uint32_t)0x00400000)
#define SD_CSR_CARD_ECC_FAILED ((uint32_t)0x00200000)
#define SD_CSR_CC_ERROR ((uint32_t)0x00100000)
#define SD_CSR_GENERAL_UNKNOWN_ERROR ((uint32_t)0x00080000)
#define SD_CSR_STREAM_READ_UNDERRUN ((uint32_t)0x00040000)
#define SD_CSR_STREAM_WRITE_OVERRUN ((uint32_t)0x00020000)
#define SD_CSR_CID_CSD_OVERWRIETE ((uint32_t)0x00010000)
#define SD_CSR_WP_ERASE_SKIP ((uint32_t)0x00008000)
#define SD_CSR_CARD_ECC_DISABLED ((uint32_t)0x00004000)
#define SD_CSR_ERASE_RESET ((uint32_t)0x00002000)
#define SD_CSR_AKE_SEQ_ERROR ((uint32_t)0x00000008)
#define SD_CSR_ERRORBITS ((uint32_t)0xFDFFE008)
#define SD_CSR_ADDR_OUT_OF_RANGE ((uint32_t)0x80000000)
#define SD_CSR_ADDR_MISALIGNED ((uint32_t)0x40000000)
#define SD_CSR_BLOCK_LEN_ERR ((uint32_t)0x20000000)
#define SD_CSR_ERASE_SEQ_ERR ((uint32_t)0x10000000)
#define SD_CSR_BAD_ERASE_PARAM ((uint32_t)0x08000000)
#define SD_CSR_WRITE_PROT_VIOLATION ((uint32_t)0x04000000)
#define SD_CSR_LOCK_UNLOCK_FAILED ((uint32_t)0x01000000)
#define SD_CSR_COM_CRC_FAILED ((uint32_t)0x00800000)
#define SD_CSR_ILLEGAL_CMD ((uint32_t)0x00400000)
#define SD_CSR_CARD_ECC_FAILED ((uint32_t)0x00200000)
#define SD_CSR_CC_ERROR ((uint32_t)0x00100000)
#define SD_CSR_GENERAL_UNKNOWN_ERROR ((uint32_t)0x00080000)
#define SD_CSR_STREAM_READ_UNDERRUN ((uint32_t)0x00040000)
#define SD_CSR_STREAM_WRITE_OVERRUN ((uint32_t)0x00020000)
#define SD_CSR_CID_CSD_OVERWRIETE ((uint32_t)0x00010000)
#define SD_CSR_WP_ERASE_SKIP ((uint32_t)0x00008000)
#define SD_CSR_CARD_ECC_DISABLED ((uint32_t)0x00004000)
#define SD_CSR_ERASE_RESET ((uint32_t)0x00002000)
#define SD_CSR_AKE_SEQ_ERROR ((uint32_t)0x00000008)
#define SD_CSR_ERRORBITS ((uint32_t)0xFDFFE008)
#define SD_MAX_VOLT_TRIAL ((uint32_t)0x0000FFFF)
#define SD_ALLZERO ((uint32_t)0x00000000)
#define SD_MAX_VOLT_TRIAL ((uint32_t)0x0000FFFF)
#define SD_ALLZERO ((uint32_t)0x00000000)
#define SD_WIDE_BUS_SUPPORT ((uint32_t)0x00040000)
#define SD_SINGLE_BUS_SUPPORT ((uint32_t)0x00010000)
#define SD_CARD_LOCKED ((uint32_t)0x02000000)
#define SD_WIDE_BUS_SUPPORT ((uint32_t)0x00040000)
#define SD_SINGLE_BUS_SUPPORT ((uint32_t)0x00010000)
#define SD_CARD_LOCKED ((uint32_t)0x02000000)
#define SD_0TO7BITS ((uint32_t)0x000000FF)
#define SD_8TO15BITS ((uint32_t)0x0000FF00)
#define SD_16TO23BITS ((uint32_t)0x00FF0000)
#define SD_24TO31BITS ((uint32_t)0xFF000000)
#define SD_MAX_DATA_LENGTH ((uint32_t)0x01FFFFFF)
#define SD_0TO7BITS ((uint32_t)0x000000FF)
#define SD_8TO15BITS ((uint32_t)0x0000FF00)
#define SD_16TO23BITS ((uint32_t)0x00FF0000)
#define SD_24TO31BITS ((uint32_t)0xFF000000)
#define SD_MAX_DATA_LENGTH ((uint32_t)0x01FFFFFF)
/**
* @brief Masks for R7 Response
*/
#define SD_VOLTAGE_WINDOW_SD ((uint32_t)0x00100000)
#define SD_HIGH_CAPACITY ((uint32_t)0x40000000)
#define SD_STD_CAPACITY ((uint32_t)0x00000000)
#define SD_CHECK_PATTERN ((uint32_t)0x000001AA)
#define SD_VOLTAGE_WINDOW_SD ((uint32_t)0x00100000)
#define SD_HIGH_CAPACITY ((uint32_t)0x40000000)
#define SD_STD_CAPACITY ((uint32_t)0x00000000)
#define SD_CHECK_PATTERN ((uint32_t)0x000001AA)
/**
* @brief Supported SD Memory Cards
*/
#define SDIO_STD_CAPACITY_SD_CARD_V1_1 ((uint32_t)0x00000000)
#define SDIO_STD_CAPACITY_SD_CARD_V2_0 ((uint32_t)0x00000001)
#define SDIO_HIGH_CAPACITY_SD_CARD ((uint32_t)0x00000002)
#define SDIO_MULTIMEDIA_CARD ((uint32_t)0x00000003)
#define SDIO_SECURE_DIGITAL_IO_CARD ((uint32_t)0x00000004)
#define SDIO_HIGH_SPEED_MULTIMEDIA_CARD ((uint32_t)0x00000005)
#define SDIO_SECURE_DIGITAL_IO_COMBO_CARD ((uint32_t)0x00000006)
#define SDIO_HIGH_CAPACITY_MMC_CARD ((uint32_t)0x00000007)
#define SDIO_STD_CAPACITY_SD_CARD_V1_1 ((uint32_t)0x00000000)
#define SDIO_STD_CAPACITY_SD_CARD_V2_0 ((uint32_t)0x00000001)
#define SDIO_HIGH_CAPACITY_SD_CARD ((uint32_t)0x00000002)
#define SDIO_MULTIMEDIA_CARD ((uint32_t)0x00000003)
#define SDIO_SECURE_DIGITAL_IO_CARD ((uint32_t)0x00000004)
#define SDIO_HIGH_SPEED_MULTIMEDIA_CARD ((uint32_t)0x00000005)
#define SDIO_SECURE_DIGITAL_IO_COMBO_CARD ((uint32_t)0x00000006)
#define SDIO_HIGH_CAPACITY_MMC_CARD ((uint32_t)0x00000007)
/*! @brief SD group number */
typedef enum _sd_group_num {

View file

@ -2,7 +2,7 @@ macro(sdk_generate_library)
if(${ARGC})
set(library_name ${ARGV0})
else()
get_filename_component(library_name ${CMAKE_CURRENT_LIST_DIR} NAME)
get_filename_component(library_name ${CMAKE_CURRENT_LIST_DIR} NAME)
endif()
message(STATUS "[register library : ${library_name}], path:${CMAKE_CURRENT_LIST_DIR}")
@ -16,21 +16,22 @@ endmacro()
function(sdk_library_add_sources)
foreach(arg ${ARGV})
if(IS_DIRECTORY ${arg})
message(FATAL_ERROR "sdk_library_add_sources() was called on a directory")
message(FATAL_ERROR "sdk_library_add_sources() was called on a directory")
endif()
if(IS_ABSOLUTE ${arg})
set(path ${arg})
set(path ${arg})
else()
set(path ${CMAKE_CURRENT_SOURCE_DIR}/${arg})
set(path ${CMAKE_CURRENT_SOURCE_DIR}/${arg})
endif()
target_sources(${CURRENT_STATIC_LIBRARY} PRIVATE ${path})
endforeach()
endfunction()
function(sdk_library_add_sources_ifdef feature)
if(${${feature}})
sdk_library_add_sources(${ARGN})
sdk_library_add_sources(${ARGN})
endif()
endfunction()
@ -41,6 +42,7 @@ function(sdk_add_include_directories)
else()
set(path ${CMAKE_CURRENT_SOURCE_DIR}/${arg})
endif()
target_include_directories(sdk_intf_lib INTERFACE ${path})
endforeach()
endfunction()
@ -52,19 +54,38 @@ function(sdk_add_private_include_directories)
else()
set(path ${CMAKE_CURRENT_SOURCE_DIR}/${arg})
endif()
target_include_directories(${CURRENT_STATIC_LIBRARY} PRIVATE ${path})
endforeach()
endfunction()
function(sdk_add_system_include_directories)
foreach(arg ${ARGV})
if(IS_ABSOLUTE ${arg})
set(path ${arg})
else()
set(path ${CMAKE_CURRENT_SOURCE_DIR}/${arg})
endif()
target_include_directories(sdk_intf_lib SYSTEM INTERFACE ${path})
endforeach()
endfunction()
function(sdk_add_include_directories_ifdef feature)
if(${${feature}})
sdk_add_include_directories(${ARGN})
sdk_add_include_directories(${ARGN})
endif()
endfunction()
function(sdk_add_private_include_directories_ifdef feature)
if(${${feature}})
sdk_add_private_include_directories(${ARGN})
sdk_add_private_include_directories(${ARGN})
endif()
endfunction()
function(sdk_add_system_include_directories_ifdef feature)
if(${${feature}})
sdk_add_system_include_directories(${ARGN})
endif()
endfunction()
@ -78,7 +99,7 @@ endfunction()
function(sdk_add_compile_definitions_ifdef feature)
if(${${feature}})
sdk_add_compile_definitions(${ARGN})
sdk_add_compile_definitions(${ARGN})
endif()
endfunction()
@ -98,13 +119,13 @@ endfunction()
function(sdk_add_compile_options_ifdef feature)
if(${${feature}})
sdk_add_compile_options(${ARGN})
sdk_add_compile_options(${ARGN})
endif()
endfunction()
function(sdk_add_private_compile_options_ifdef feature)
if(${${feature}})
sdk_add_private_compile_options(${ARGN})
sdk_add_private_compile_options(${ARGN})
endif()
endfunction()
@ -118,7 +139,7 @@ endfunction()
function(sdk_add_link_options_ifdef feature)
if(${${feature}})
sdk_add_link_options(${ARGN})
sdk_add_link_options(${ARGN})
endif()
endfunction()
@ -134,7 +155,7 @@ endfunction()
function(sdk_add_link_libraries_ifdef feature)
if(${${feature}})
sdk_add_link_libraries(${ARGN})
sdk_add_link_libraries(${ARGN})
endif()
endfunction()
@ -146,18 +167,19 @@ endfunction()
function(sdk_add_static_library)
foreach(arg ${ARGV})
if(IS_DIRECTORY ${arg})
message(FATAL_ERROR "sdk_add_static_library() was called on a directory")
endif()
if(IS_DIRECTORY ${arg})
message(FATAL_ERROR "sdk_add_static_library() was called on a directory")
endif()
if(IS_ABSOLUTE ${arg})
set(path ${arg})
else()
set(path ${CMAKE_CURRENT_SOURCE_DIR}/${arg})
endif()
get_filename_component(library_name ${path} NAME_WE)
message(STATUS "[register extern library : ${library_name}], path:${CMAKE_CURRENT_LIST_DIR}")
set_property(GLOBAL APPEND PROPERTY SDK_LIBS ${path})
if(IS_ABSOLUTE ${arg})
set(path ${arg})
else()
set(path ${CMAKE_CURRENT_SOURCE_DIR}/${arg})
endif()
get_filename_component(library_name ${path} NAME_WE)
message(STATUS "[register extern library : ${library_name}], path:${CMAKE_CURRENT_LIST_DIR}")
set_property(GLOBAL APPEND PROPERTY SDK_LIBS ${path})
endforeach()
endfunction()
@ -175,10 +197,11 @@ endmacro()
function(sdk_set_linker_script ld)
if(IS_ABSOLUTE ${ld})
set(path ${ld})
set(path ${ld})
else()
set(path ${CMAKE_CURRENT_SOURCE_DIR}/${ld})
set(path ${CMAKE_CURRENT_SOURCE_DIR}/${ld})
endif()
set_property(GLOBAL PROPERTY LINKER_SCRIPT ${path})
endfunction()
@ -191,20 +214,20 @@ macro(sdk_set_vscode_dir dir)
endmacro()
macro(sdk_set_main_file)
if(IS_ABSOLUTE ${ARGV0})
if(IS_ABSOLUTE ${ARGV0})
set(path ${ARGV0})
else()
else()
set(path ${CMAKE_CURRENT_SOURCE_DIR}/${ARGV0})
endif()
endif()
set(CURRENT_MAIN_FILE ${path})
endmacro()
macro(project name)
if(CPU_ID)
set(proj_name ${name}_${CHIP}_${CPU_ID})
set(proj_name ${name}_${CHIP}_${CPU_ID})
else()
set(proj_name ${name}_${CHIP})
set(proj_name ${name}_${CHIP})
endif()
_project(${proj_name} ASM C CXX)
@ -217,38 +240,41 @@ macro(project name)
add_executable(${proj_name}.elf ${CURRENT_MAIN_FILE})
target_link_libraries(${proj_name}.elf sdk_intf_lib)
get_property(LINKER_SCRIPT_PROPERTY GLOBAL PROPERTY LINKER_SCRIPT)
if(EXISTS ${LINKER_SCRIPT_PROPERTY})
set_target_properties(${proj_name}.elf PROPERTIES LINK_FLAGS "-T${LINKER_SCRIPT_PROPERTY} -Wl,-Map=${MAP_FILE}")
set_target_properties(${proj_name}.elf PROPERTIES LINK_DEPENDS ${LINKER_SCRIPT_PROPERTY})
endif()
get_property(SDK_LIBS_PROPERTY GLOBAL PROPERTY SDK_LIBS)
target_link_libraries(${proj_name}.elf -Wl,--start-group ${SDK_LIBS_PROPERTY} app -Wl,--end-group)
target_link_libraries(${proj_name}.elf -Wl,--whole-archive ${SDK_LIBS_PROPERTY} app -Wl,--no-whole-archive)
if(OUTPUT_DIR)
add_custom_command(TARGET ${proj_name}.elf POST_BUILD
COMMAND ${CMAKE_OBJCOPY} -Obinary $<TARGET_FILE:${proj_name}.elf> ${BIN_FILE}
COMMAND ${CMAKE_OBJDUMP} -d -S $<TARGET_FILE:${proj_name}.elf> >${ASM_FILE}
# COMMAND ${CMAKE_OBJCOPY} -Oihex $<TARGET_FILE:${proj_name}.elf> ${HEX_FILE}
# COMMAND ${SIZE} $<TARGET_FILE:${proj_name}.elf>
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:${proj_name}.elf> ${OUTPUT_DIR}/${name}/${proj_name}.elf
COMMAND ${CMAKE_COMMAND} -E copy ${ASM_FILE} ${OUTPUT_DIR}/${name}/${proj_name}.asm
COMMAND ${CMAKE_COMMAND} -E copy ${MAP_FILE} ${OUTPUT_DIR}/${name}/${proj_name}.map
COMMAND ${CMAKE_COMMAND} -E copy ${BIN_FILE} ${OUTPUT_DIR}/${name}/${proj_name}.bin
COMMAND ${CMAKE_COMMAND} -E copy ${BIN_FILE} ${OUTPUT_DIR}/project.bin
COMMENT "Generate ${BIN_FILE}\r\n"
)
add_custom_command(TARGET ${proj_name}.elf POST_BUILD
COMMAND ${CMAKE_OBJCOPY} -Obinary $<TARGET_FILE:${proj_name}.elf> ${BIN_FILE}
COMMAND ${CMAKE_OBJDUMP} -d -S $<TARGET_FILE:${proj_name}.elf> >${ASM_FILE}
# COMMAND ${CMAKE_OBJCOPY} -Oihex $<TARGET_FILE:${proj_name}.elf> ${HEX_FILE}
# COMMAND ${SIZE} $<TARGET_FILE:${proj_name}.elf>
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:${proj_name}.elf> ${OUTPUT_DIR}/${name}/${proj_name}.elf
COMMAND ${CMAKE_COMMAND} -E copy ${ASM_FILE} ${OUTPUT_DIR}/${name}/${proj_name}.asm
COMMAND ${CMAKE_COMMAND} -E copy ${MAP_FILE} ${OUTPUT_DIR}/${name}/${proj_name}.map
COMMAND ${CMAKE_COMMAND} -E copy ${BIN_FILE} ${OUTPUT_DIR}/${name}/${proj_name}.bin
COMMAND ${CMAKE_COMMAND} -E copy ${BIN_FILE} ${OUTPUT_DIR}/project.bin
COMMENT "Generate ${BIN_FILE}\r\n"
)
else()
add_custom_command(TARGET ${proj_name}.elf POST_BUILD
COMMAND ${CMAKE_OBJCOPY} -Obinary $<TARGET_FILE:${proj_name}.elf> ${BIN_FILE}
COMMAND ${CMAKE_OBJDUMP} -d -S $<TARGET_FILE:${proj_name}.elf> >${ASM_FILE}
# COMMAND ${CMAKE_OBJCOPY} -Oihex $<TARGET_FILE:${proj_name}.elf> ${HEX_FILE}
# COMMAND ${SIZE} $<TARGET_FILE:${proj_name}.elf>
COMMENT "Generate ${BIN_FILE}\r\n"
)
add_custom_command(TARGET ${proj_name}.elf POST_BUILD
COMMAND ${CMAKE_OBJCOPY} -Obinary $<TARGET_FILE:${proj_name}.elf> ${BIN_FILE}
COMMAND ${CMAKE_OBJDUMP} -d -S $<TARGET_FILE:${proj_name}.elf> >${ASM_FILE}
# COMMAND ${CMAKE_OBJCOPY} -Oihex $<TARGET_FILE:${proj_name}.elf> ${HEX_FILE}
# COMMAND ${SIZE} $<TARGET_FILE:${proj_name}.elf>
COMMENT "Generate ${BIN_FILE}\r\n"
)
endif()
# include(${BL_SDK_BASE}/cmake/bflb_flash.cmake)
# include(${BL_SDK_BASE}/cmake/gen_c_cpp_properties_json.cmake)
include(${BL_SDK_BASE}/cmake/bflb_flash.cmake)
include(${BL_SDK_BASE}/cmake/gen_c_cpp_properties_json.cmake)
endmacro()

View file

@ -1,4 +1,3 @@
add_subdirectory(ai)
sdk_add_subdirectory_ifdef(CONFIG_BFLOG bflog)
add_subdirectory(crypto)
add_subdirectory(fs)
@ -13,3 +12,4 @@ sdk_add_subdirectory_ifdef(CONFIG_SHELL shell)
add_subdirectory(usb)
add_subdirectory(utils)
add_subdirectory(wireless)
sdk_add_subdirectory_ifdef(CONFIG_HIBOOSTER hibooster)

View file

@ -150,13 +150,13 @@
#else
#define BFLOG_SIMPLE_LAYOUT_STRING(_color, _level, _tag, _tm, _msg) \
"%s" \
"[%c][%10lu]" \
"[%s:%s:%d]" \
"<%s> %s", \
"[%c:%10lu]" \
"[%s:%d]" \
"%10s> %s", \
(_color), \
(_level[0]), \
((_msg)->clkl), \
((_msg)->file), ((_msg)->func), ((_msg)->line), \
((_msg)->file), ((_msg)->line), \
(_tag), \
((_msg)->string)
#endif

View file

@ -1,18 +1,19 @@
sdk_generate_library()
sdk_generate_library()
sdk_library_add_sources(diskio.c)
sdk_library_add_sources(ff.c)
sdk_library_add_sources(ffsystem.c)
sdk_library_add_sources(ffunicode.c)
sdk_library_add_sources(diskio.c)
sdk_add_include_directories(.)
sdk_add_include_directories(port/.)
sdk_add_compile_definitions(-DCONFIG_FATFS)
if(CONFIG_FF_FS_REENTRANT)
sdk_add_compile_definitions(-DFF_FS_REENTRANT=${CONFIG_FF_FS_REENTRANT})
endif()
# fatfs use sdcard over sdio
if(CONFIG_FATFS_SDH_SDCARD)
sdk_add_compile_definitions(-DCONFIG_FATFS_SDH_SDCARD)
sdk_library_add_sources(port/fatfs_sdh_sdcard.c)
endif()
if(CONFIG_FATFS_FFCONF_USER)
sdk_add_compile_definitions(-DCONFIG_FATFS_FFCONF_USER)
endif()

View file

@ -11,78 +11,16 @@
#include "diskio.h" /* Declarations of disk functions */
#include "stddef.h"
/* Definitions of physical drive number for each drive */
#define DEV_RAM 0 /* Example: Map Ramdisk to physical drive 0 */
#define DEV_MMC 1 /* Example: Map MMC/SD card to physical drive 1 */
#define DEV_FLASH 2 /* Example: Map USB MSD to physical drive 2 */
#define DEV_USB 3 /* Example: Map USB MSD to physical drive 2 */
FATFS_DiskioDriverTypeDef pDiskioDriver = {
.RAM_disk_status = NULL,
.MMC_disk_status = NULL,
.USB_disk_status = NULL,
.RAM_disk_initialize = NULL,
.MMC_disk_initialize = NULL,
.USB_disk_initialize = NULL,
.RAM_disk_read = NULL,
.MMC_disk_read = NULL,
.USB_disk_read = NULL,
.RAM_disk_write = NULL,
.MMC_disk_write = NULL,
.USB_disk_write = NULL,
.RAM_disk_ioctl = NULL,
.MMC_disk_ioctl = NULL,
.USB_disk_ioctl = NULL,
.Translate_Result_Code = NULL,
};
FATFS_DiskioDriverTypeDef pDiskioDriver[DEV_NUM_MAX] = { NULL };
/*-----------------------------------------------------------------------*/
/* init driver callback */
/*-----------------------------------------------------------------------*/
void disk_driver_callback_init(FATFS_DiskioDriverTypeDef *pNewDriver)
void disk_driver_callback_init(uint8_t pdrv, FATFS_DiskioDriverTypeDef *pNewDriver)
{
if (pNewDriver->RAM_disk_status)
pDiskioDriver.RAM_disk_status = pNewDriver->RAM_disk_status;
if (pNewDriver->MMC_disk_status)
pDiskioDriver.MMC_disk_status = pNewDriver->MMC_disk_status;
if (pNewDriver->FLASH_disk_status)
pDiskioDriver.FLASH_disk_status = pNewDriver->FLASH_disk_status;
if (pNewDriver->USB_disk_status)
pDiskioDriver.USB_disk_status = pNewDriver->USB_disk_status;
if (pNewDriver->RAM_disk_initialize)
pDiskioDriver.RAM_disk_initialize = pNewDriver->RAM_disk_initialize;
if (pNewDriver->MMC_disk_initialize)
pDiskioDriver.MMC_disk_initialize = pNewDriver->MMC_disk_initialize;
if (pNewDriver->FLASH_disk_initialize)
pDiskioDriver.FLASH_disk_initialize = pNewDriver->FLASH_disk_initialize;
if (pNewDriver->USB_disk_initialize)
pDiskioDriver.USB_disk_initialize = pNewDriver->USB_disk_initialize;
if (pNewDriver->RAM_disk_read)
pDiskioDriver.RAM_disk_read = pNewDriver->RAM_disk_read;
if (pNewDriver->MMC_disk_read)
pDiskioDriver.MMC_disk_read = pNewDriver->MMC_disk_read;
if (pNewDriver->FLASH_disk_read)
pDiskioDriver.FLASH_disk_read = pNewDriver->FLASH_disk_read;
if (pNewDriver->USB_disk_read)
pDiskioDriver.USB_disk_read = pNewDriver->USB_disk_read;
if (pNewDriver->RAM_disk_write)
pDiskioDriver.RAM_disk_write = pNewDriver->RAM_disk_write;
if (pNewDriver->MMC_disk_write)
pDiskioDriver.MMC_disk_write = pNewDriver->MMC_disk_write;
if (pNewDriver->FLASH_disk_write)
pDiskioDriver.FLASH_disk_write = pNewDriver->FLASH_disk_write;
if (pNewDriver->USB_disk_write)
pDiskioDriver.USB_disk_write = pNewDriver->USB_disk_write;
if (pNewDriver->RAM_disk_ioctl)
pDiskioDriver.RAM_disk_ioctl = pNewDriver->RAM_disk_ioctl;
if (pNewDriver->MMC_disk_ioctl)
pDiskioDriver.MMC_disk_ioctl = pNewDriver->MMC_disk_ioctl;
if (pNewDriver->FLASH_disk_ioctl)
pDiskioDriver.FLASH_disk_ioctl = pNewDriver->FLASH_disk_ioctl;
if (pNewDriver->USB_disk_ioctl)
pDiskioDriver.USB_disk_ioctl = pNewDriver->USB_disk_ioctl;
if (pNewDriver->Translate_Result_Code)
pDiskioDriver.Translate_Result_Code = pNewDriver->Translate_Result_Code;
if (pdrv < DEV_NUM_MAX) {
pDiskioDriver[pdrv] = *pNewDriver;
}
}
/*-----------------------------------------------------------------------*/
@ -96,41 +34,19 @@ DSTATUS disk_status(
DSTATUS stat = STA_NOINIT;
int result = 0;
switch (pdrv) {
case DEV_RAM:
if (pDiskioDriver.RAM_disk_status) {
result = pDiskioDriver.RAM_disk_status();
}
if (pdrv > DEV_NUM_MAX) {
return STA_NOINIT;
}
break;
case DEV_MMC:
if (pDiskioDriver.MMC_disk_status) {
result = pDiskioDriver.MMC_disk_status();
}
break;
case DEV_FLASH:
if (pDiskioDriver.FLASH_disk_status) {
result = pDiskioDriver.FLASH_disk_status();
}
break;
case DEV_USB:
if (pDiskioDriver.USB_disk_status) {
result = pDiskioDriver.USB_disk_status();
}
break;
default:
return STA_NOINIT;
if (pDiskioDriver[pdrv].disk_status) {
result = pDiskioDriver[pdrv].disk_status();
}
/* translate the reslut code here */
if (pDiskioDriver.Translate_Result_Code) {
stat = pDiskioDriver.Translate_Result_Code(result);
if (pDiskioDriver[pdrv].error_code_parsing) {
stat = pDiskioDriver[pdrv].error_code_parsing(result);
} else {
stat = result;
}
return stat;
@ -147,41 +63,19 @@ DSTATUS disk_initialize(
DSTATUS stat = STA_NOINIT;
int result = 0;
switch (pdrv) {
case DEV_RAM:
if (pDiskioDriver.RAM_disk_initialize) {
result = pDiskioDriver.RAM_disk_initialize();
}
if (pdrv > DEV_NUM_MAX) {
return STA_NOINIT;
}
break;
case DEV_MMC:
if (pDiskioDriver.MMC_disk_initialize) {
result = pDiskioDriver.MMC_disk_initialize();
}
break;
case DEV_FLASH:
if (pDiskioDriver.FLASH_disk_initialize) {
result = pDiskioDriver.FLASH_disk_initialize();
}
break;
case DEV_USB:
if (pDiskioDriver.USB_disk_initialize) {
result = pDiskioDriver.USB_disk_initialize();
}
break;
default:
return STA_NOINIT;
if (pDiskioDriver[pdrv].disk_initialize) {
result = pDiskioDriver[pdrv].disk_initialize();
}
/* translate the reslut code here */
if (pDiskioDriver.Translate_Result_Code) {
stat = pDiskioDriver.Translate_Result_Code(result);
if (pDiskioDriver[pdrv].error_code_parsing) {
stat = pDiskioDriver[pdrv].error_code_parsing(result);
} else {
stat = result;
}
return stat;
@ -201,41 +95,19 @@ DRESULT disk_read(
DSTATUS stat = STA_NOINIT;
int result = 0;
switch (pdrv) {
case DEV_RAM:
if (pDiskioDriver.RAM_disk_read) {
result = pDiskioDriver.RAM_disk_read(buff, sector, count);
}
if (pdrv > DEV_NUM_MAX) {
return STA_NOINIT;
}
break;
case DEV_MMC:
if (pDiskioDriver.MMC_disk_read) {
result = pDiskioDriver.MMC_disk_read(buff, sector, count);
}
break;
case DEV_FLASH:
if (pDiskioDriver.FLASH_disk_read) {
result = pDiskioDriver.FLASH_disk_read(buff, sector, count);
}
break;
case DEV_USB:
if (pDiskioDriver.USB_disk_read) {
result = pDiskioDriver.USB_disk_read(buff, sector, count);
}
break;
default:
return RES_PARERR;
if (pDiskioDriver[pdrv].disk_read) {
result = pDiskioDriver[pdrv].disk_read(buff, sector, count);
}
/* translate the reslut code here */
if (pDiskioDriver.Translate_Result_Code) {
stat = pDiskioDriver.Translate_Result_Code(result);
if (pDiskioDriver[pdrv].error_code_parsing) {
stat = pDiskioDriver[pdrv].error_code_parsing(result);
} else {
stat = result;
}
return stat;
@ -257,41 +129,19 @@ DRESULT disk_write(
DSTATUS stat = STA_NOINIT;
int result = 0;
switch (pdrv) {
case DEV_RAM:
if (pDiskioDriver.RAM_disk_write) {
result = pDiskioDriver.RAM_disk_write(buff, sector, count);
}
if (pdrv > DEV_NUM_MAX) {
return STA_NOINIT;
}
break;
case DEV_MMC:
if (pDiskioDriver.MMC_disk_write) {
result = pDiskioDriver.MMC_disk_write(buff, sector, count);
}
break;
case DEV_FLASH:
if (pDiskioDriver.FLASH_disk_write) {
result = pDiskioDriver.FLASH_disk_write(buff, sector, count);
}
break;
case DEV_USB:
if (pDiskioDriver.USB_disk_write) {
result = pDiskioDriver.USB_disk_write(buff, sector, count);
}
break;
default:
return RES_PARERR;
if (pDiskioDriver[pdrv].disk_write) {
result = pDiskioDriver[pdrv].disk_write(buff, sector, count);
}
/* translate the reslut code here */
if (pDiskioDriver.Translate_Result_Code) {
stat = pDiskioDriver.Translate_Result_Code(result);
if (pDiskioDriver[pdrv].error_code_parsing) {
stat = pDiskioDriver[pdrv].error_code_parsing(result);
} else {
stat = result;
}
return stat;
@ -312,41 +162,19 @@ DRESULT disk_ioctl(
DSTATUS stat = STA_NOINIT;
int result = 0;
switch (pdrv) {
case DEV_RAM:
if (pDiskioDriver.RAM_disk_ioctl) {
result = pDiskioDriver.RAM_disk_ioctl(cmd, buff);
}
if (pdrv > DEV_NUM_MAX) {
return STA_NOINIT;
}
break;
case DEV_MMC:
if (pDiskioDriver.MMC_disk_ioctl) {
result = pDiskioDriver.MMC_disk_ioctl(cmd, buff);
}
break;
case DEV_FLASH:
if (pDiskioDriver.FLASH_disk_ioctl) {
result = pDiskioDriver.FLASH_disk_ioctl(cmd, buff);
}
break;
case DEV_USB:
if (pDiskioDriver.USB_disk_ioctl) {
result = pDiskioDriver.USB_disk_ioctl(cmd, buff);
}
break;
default:
return RES_PARERR;
if (pDiskioDriver[pdrv].disk_ioctl) {
result = pDiskioDriver[pdrv].disk_ioctl(cmd, buff);
}
/* translate the reslut code here */
if (pDiskioDriver.Translate_Result_Code) {
stat = pDiskioDriver.Translate_Result_Code(result);
if (pDiskioDriver[pdrv].error_code_parsing) {
stat = pDiskioDriver[pdrv].error_code_parsing(result);
} else {
stat = result;
}
return stat;

View file

@ -25,46 +25,31 @@ typedef enum {
} DRESULT;
/******************user code****************************/
/* Definitions of physical drive number for each drive
It must be in the same order as FF_VOLUME_STRS in ffconf.h */
#define DEV_RAM 0 /* Example: Map Ramdisk to physical drive 0 */
#define DEV_FLASH 1 /* Example: Map Flash to physical drive 1 */
#define DEV_SD 2 /* Example: Map MMC/SD card to physical drive 2 */
#define DEV_SD2 3
#define DEV_USB 4
#define DEV_NUM_MAX 5
typedef struct
{
/* get status */
int (*RAM_disk_status)(void);
int (*MMC_disk_status)(void);
int (*FLASH_disk_status)(void);
int (*USB_disk_status)(void);
/* init */
int (*RAM_disk_initialize)(void);
int (*MMC_disk_initialize)(void);
int (*FLASH_disk_initialize)(void);
int (*USB_disk_initialize)(void);
/* read */
int (*RAM_disk_read)(BYTE *buff, LBA_t sector, UINT count);
int (*MMC_disk_read)(BYTE *buff, LBA_t sector, UINT count);
int (*FLASH_disk_read)(BYTE *buff, LBA_t sector, UINT count);
int (*USB_disk_read)(BYTE *buff, LBA_t sector, UINT count);
/* write */
int (*RAM_disk_write)(const BYTE *buff, LBA_t sector, UINT count);
int (*MMC_disk_write)(const BYTE *buff, LBA_t sector, UINT count);
int (*FLASH_disk_write)(const BYTE *buff, LBA_t sector, UINT count);
int (*USB_disk_write)(const BYTE *buff, LBA_t sector, UINT count);
/* ioctl */
int (*RAM_disk_ioctl)(BYTE cmd, void *buff);
int (*MMC_disk_ioctl)(BYTE cmd, void *buff);
int (*FLASH_disk_ioctl)(BYTE cmd, void *buff);
int (*USB_disk_ioctl)(BYTE cmd, void *buff);
/* translate reslut code */
DSTATUS(*Translate_Result_Code)
int (*disk_status)(void);
int (*disk_initialize)(void);
int (*disk_read)(BYTE *buff, LBA_t sector, UINT count);
int (*disk_write)(const BYTE *buff, LBA_t sector, UINT count);
int (*disk_ioctl)(BYTE cmd, void *buff);
DSTATUS(*error_code_parsing)
(int result);
} FATFS_DiskioDriverTypeDef;
extern FATFS_DiskioDriverTypeDef pDiskioDriver;
extern FATFS_DiskioDriverTypeDef pDiskioDriver[];
void disk_driver_callback_init(FATFS_DiskioDriverTypeDef *pNewDriver);
void disk_driver_callback_init(uint8_t pdrv, FATFS_DiskioDriverTypeDef *pNewDriver);
/******************user code****************************/
/*---------------------------------------*/

View file

@ -1,22 +0,0 @@
const char *FR_Table[] = {
"FR_OK成功", /* (0) Succeeded */
"FR_DISK_ERR底层硬件错误", /* (1) A hard error occurred in the low level disk I/O layer */
"FR_INT_ERR断言失败", /* (2) Assertion failed */
"FR_NOT_READY物理驱动没有工作", /* (3) The physical drive cannot work */
"FR_NO_FILE文件不存在", /* (4) Could not find the file */
"FR_NO_PATH路径不存在", /* (5) Could not find the path */
"FR_INVALID_NAME无效文件名", /* (6) The path name format is invalid */
"FR_DENIED由于禁止访问或者目录已满访问被拒绝", /* (7) Access denied due to prohibited access or directory full */
"FR_EXIST文件已经存在", /* (8) Access denied due to prohibited access */
"FR_INVALID_OBJECT文件或者目录对象无效", /* (9) The file/directory object is invalid */
"FR_WRITE_PROTECTED物理驱动被写保护", /* (10) The physical drive is write protected */
"FR_INVALID_DRIVE逻辑驱动号无效", /* (11) The logical drive number is invalid */
"FR_NOT_ENABLED卷中无工作区", /* (12) The volume has no work area */
"FR_NO_FILESYSTEM没有有效的FAT卷", /* (13) There is no valid FAT volume */
"FR_MKFS_ABORTED由于参数错误f_mkfs()被终止", /* (14) The f_mkfs() aborted due to any parameter error */
"FR_TIMEOUT在规定的时间内无法获得访问卷的许可", /* (15) Could not get a grant to access the volume within defined period */
"FR_LOCKED由于文件共享策略操作被拒绝", /* (16) The operation is rejected according to the file sharing policy */
"FR_NOT_ENOUGH_CORE无法分配长文件名工作区", /* (17) LFN working buffer could not be allocated */
"FR_TOO_MANY_OPEN_FILES当前打开的文件数大于_FS_SHARE", /* (18) Number of open files > _FS_SHARE */
"FR_INVALID_PARAMETER参数无效" /* (19) Given parameter is invalid */
};

File diff suppressed because it is too large Load diff

View file

@ -1,8 +1,8 @@
/*----------------------------------------------------------------------------/
/ FatFs - Generic FAT Filesystem module R0.14 /
/ FatFs - Generic FAT Filesystem module R0.15 /
/-----------------------------------------------------------------------------/
/
/ Copyright (C) 2019, ChaN, all right reserved.
/ Copyright (C) 2022, ChaN, all right reserved.
/
/ FatFs module is an open source software. Redistribution and use of FatFs in
/ source and binary forms, with or without modification, are permitted provided
@ -19,7 +19,7 @@
/----------------------------------------------------------------------------*/
#ifndef FF_DEFINED
#define FF_DEFINED 86606 /* Revision ID */
#define FF_DEFINED 80286 /* Revision ID */
#ifdef __cplusplus
extern "C" {
@ -33,10 +33,14 @@ extern "C" {
/* Integer types used for FatFs API */
#if defined(_WIN32) /* Main development platform */
#if defined(_WIN32) /* Windows VC++ (for development only) */
#define FF_INTDEF 2
#include <windows.h>
typedef unsigned __int64 QWORD;
#include <float.h>
#define isnan(v) _isnan(v)
#define isinf(v) (!_finite(v))
#elif (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__cplusplus) /* C99 or later */
#define FF_INTDEF 2
#include <stdint.h>
@ -46,6 +50,7 @@ typedef uint16_t WORD; /* 16-bit unsigned integer */
typedef uint32_t DWORD; /* 32-bit unsigned integer */
typedef uint64_t QWORD; /* 64-bit unsigned integer */
typedef WORD WCHAR; /* UTF-16 character type */
#else /* Earlier than C99 */
#define FF_INTDEF 1
typedef unsigned int UINT; /* int must be 16-bit or 32-bit */
@ -55,50 +60,6 @@ typedef unsigned long DWORD; /* 32-bit unsigned integer */
typedef WORD WCHAR; /* UTF-16 character type */
#endif
/* Definitions of volume management */
#if FF_MULTI_PARTITION /* Multiple partition configuration */
typedef struct
{
BYTE pd; /* Physical drive number */
BYTE pt; /* Partition: 0:Auto detect, 1-4:Forced partition) */
} PARTITION;
extern PARTITION VolToPart[]; /* Volume - Partition mapping table */
#endif
#if FF_STR_VOLUME_ID
#ifndef FF_VOLUME_STRS
extern const char *VolumeStr[FF_VOLUMES]; /* User defied volume ID */
#endif
#endif
/* Type of path name strings on FatFs API */
#ifndef _INC_TCHAR
#define _INC_TCHAR
#if FF_USE_LFN && FF_LFN_UNICODE == 1 /* Unicode in UTF-16 encoding */
typedef WCHAR TCHAR;
#define _T(x) L##x
#define _TEXT(x) L##x
#elif FF_USE_LFN && FF_LFN_UNICODE == 2 /* Unicode in UTF-8 encoding */
typedef char TCHAR;
#define _T(x) u8##x
#define _TEXT(x) u8##x
#elif FF_USE_LFN && FF_LFN_UNICODE == 3 /* Unicode in UTF-32 encoding */
typedef DWORD TCHAR;
#define _T(x) U##x
#define _TEXT(x) U##x
#elif FF_USE_LFN && (FF_LFN_UNICODE < 0 || FF_LFN_UNICODE > 3)
#error Wrong FF_LFN_UNICODE setting
#else /* ANSI/OEM code in SBCS/DBCS */
typedef char TCHAR;
#define _T(x) x
#define _TEXT(x) x
#endif
#endif
/* Type of file size and LBA variables */
#if FF_FS_EXFAT
@ -119,15 +80,53 @@ typedef DWORD FSIZE_t;
typedef DWORD LBA_t;
#endif
/* Type of path name strings on FatFs API (TCHAR) */
#if FF_USE_LFN && FF_LFN_UNICODE == 1 /* Unicode in UTF-16 encoding */
typedef WCHAR TCHAR;
#define _T(x) L##x
#define _TEXT(x) L##x
#elif FF_USE_LFN && FF_LFN_UNICODE == 2 /* Unicode in UTF-8 encoding */
typedef char TCHAR;
#define _T(x) u8##x
#define _TEXT(x) u8##x
#elif FF_USE_LFN && FF_LFN_UNICODE == 3 /* Unicode in UTF-32 encoding */
typedef DWORD TCHAR;
#define _T(x) U##x
#define _TEXT(x) U##x
#elif FF_USE_LFN && (FF_LFN_UNICODE < 0 || FF_LFN_UNICODE > 3)
#error Wrong FF_LFN_UNICODE setting
#else /* ANSI/OEM code in SBCS/DBCS */
typedef char TCHAR;
#define _T(x) x
#define _TEXT(x) x
#endif
/* Definitions of volume management */
#if FF_MULTI_PARTITION /* Multiple partition configuration */
typedef struct {
BYTE pd; /* Physical drive number */
BYTE pt; /* Partition: 0:Auto detect, 1-4:Forced partition) */
} PARTITION;
extern PARTITION VolToPart[]; /* Volume - Partition mapping table */
#endif
#if FF_STR_VOLUME_ID
#ifndef FF_VOLUME_STRS
extern const char *VolumeStr[FF_VOLUMES]; /* User defied volume ID */
#endif
#endif
/* Filesystem object structure (FATFS) */
typedef struct
{
typedef struct {
BYTE fs_type; /* Filesystem type (0:not mounted) */
BYTE pdrv; /* Associated physical drive */
BYTE pdrv; /* Volume hosting physical drive */
BYTE ldrv; /* Logical drive number (used only when FF_FS_REENTRANT) */
BYTE n_fats; /* Number of FATs (1 or 2) */
BYTE wflag; /* win[] flag (b0:dirty) */
BYTE fsi_flag; /* FSINFO flags (b7:disabled, b0:dirty) */
BYTE wflag; /* win[] status (b0:dirty) */
BYTE fsi_flag; /* FSINFO status (b7:disabled, b0:dirty) */
WORD id; /* Volume mount ID */
WORD n_rootdir; /* Number of root directory entries (FAT12/16) */
WORD csize; /* Cluster size [sectors] */
@ -140,9 +139,6 @@ typedef struct
#if FF_FS_EXFAT
BYTE *dirbuf; /* Directory entry block scratchpad buffer for exFAT */
#endif
#if FF_FS_REENTRANT
FF_SYNC_t sobj; /* Identifier of sync object */
#endif
#if !FF_FS_READONLY
DWORD last_clst; /* Last allocated cluster */
DWORD free_clst; /* Number of free clusters */
@ -156,24 +152,23 @@ typedef struct
#endif
#endif
DWORD n_fatent; /* Number of FAT entries (number of clusters + 2) */
DWORD fsize; /* Size of an FAT [sectors] */
DWORD fsize; /* Number of sectors per FAT */
LBA_t volbase; /* Volume base sector */
LBA_t fatbase; /* FAT base sector */
LBA_t dirbase; /* Root directory base sector/cluster */
LBA_t dirbase; /* Root directory base sector (FAT12/16) or cluster (FAT32/exFAT) */
LBA_t database; /* Data base sector */
#if FF_FS_EXFAT
LBA_t bitbase; /* Allocation bitmap base sector */
#endif
LBA_t winsect; /* Current sector appearing in the win[] */
BYTE win[FF_MAX_SS] __attribute__((aligned(8))); /* Disk access window for Directory, FAT (and file data at tiny cfg) */
LBA_t winsect; /* Current sector appearing in the win[] */
BYTE win[FF_MAX_SS]; /* Disk access window for Directory, FAT (and file data at tiny cfg) */
} FATFS;
/* Object ID and allocation information (FFOBJID) */
typedef struct
{
typedef struct {
FATFS *fs; /* Pointer to the hosting volume of this object */
WORD id; /* Hosting volume mount ID */
WORD id; /* Hosting volume's mount ID */
BYTE attr; /* Object attribute */
BYTE stat; /* Object chain status (b1-0: =0:not contiguous, =2:contiguous, =3:fragmented in this session, b2:sub-directory stretched) */
DWORD sclust; /* Object data start cluster (0:no cluster or root directory) */
@ -192,8 +187,7 @@ typedef struct
/* File object structure (FIL) */
typedef struct
{
typedef struct {
FFOBJID obj; /* Object identifier (must be the 1st member to detect invalid object pointer) */
BYTE flag; /* File status flags */
BYTE err; /* Abort flag (error code) */
@ -208,14 +202,13 @@ typedef struct
DWORD *cltbl; /* Pointer to the cluster link map table (nulled on open, set by application) */
#endif
#if !FF_FS_TINY
BYTE buf[FF_MAX_SS] __attribute__((aligned(8))); /* File private data read/write window */
BYTE buf[FF_MAX_SS]; /* File private data read/write window */
#endif
} FIL;
/* Directory object structure (DIR) */
typedef struct
{
typedef struct {
FFOBJID obj; /* Object identifier */
DWORD dptr; /* Current read/write offset */
DWORD clust; /* Current cluster */
@ -232,14 +225,13 @@ typedef struct
/* File information structure (FILINFO) */
typedef struct
{
typedef struct {
FSIZE_t fsize; /* File size */
WORD fdate; /* Modified date */
WORD ftime; /* Modified time */
BYTE fattrib; /* File attribute */
#if FF_USE_LFN
TCHAR altname[FF_SFN_BUF + 1]; /* Altenative file name */
TCHAR altname[FF_SFN_BUF + 1]; /* Alternative file name */
TCHAR fname[FF_LFN_BUF + 1]; /* Primary file name */
#else
TCHAR fname[12 + 1]; /* File name */
@ -248,8 +240,7 @@ typedef struct
/* Format parameter structure (MKFS_PARM) */
typedef struct
{
typedef struct {
BYTE fmt; /* Format option (FM_FAT, FM_FAT32, FM_EXFAT and FM_SFD) */
BYTE n_fat; /* Number of FATs */
UINT align; /* Data area alignment (sector) */
@ -283,7 +274,8 @@ typedef enum {
} FRESULT;
/*--------------------------------------------------------------*/
/* FatFs module application interface */
/* FatFs Module Application Interface */
/*--------------------------------------------------------------*/
FRESULT f_open(FIL *fp, const TCHAR *path, BYTE mode); /* Open or create a file */
FRESULT f_close(FIL *fp); /* Close an open file object */
@ -320,6 +312,8 @@ int f_puts(const TCHAR *str, FIL *cp);
int f_printf(FIL *fp, const TCHAR *str, ...); /* Put a formatted string to the file */
TCHAR *f_gets(TCHAR *buff, int len, FIL *fp); /* Get a string from the file */
/* Some API fucntions are implemented as macro */
#define f_eof(fp) ((int)((fp)->fptr == (fp)->obj.objsize))
#define f_error(fp) ((fp)->err)
#define f_tell(fp) ((fp)->fptr)
@ -329,39 +323,39 @@ TCHAR *f_gets(TCHAR *buff, int len, FIL *fp);
#define f_rmdir(path) f_unlink(path)
#define f_unmount(path) f_mount(0, path, 0)
#ifndef EOF
#define EOF (-1)
#endif
/*--------------------------------------------------------------*/
/* Additional user defined functions */
/* Additional Functions */
/*--------------------------------------------------------------*/
/* RTC function */
/* RTC function (provided by user) */
#if !FF_FS_READONLY && !FF_FS_NORTC
DWORD get_fattime(void);
DWORD get_fattime(void); /* Get current time */
#endif
/* LFN support functions */
#if FF_USE_LFN >= 1 /* Code conversion (defined in unicode.c) */
/* LFN support functions (defined in ffunicode.c) */
#if FF_USE_LFN >= 1
WCHAR ff_oem2uni(WCHAR oem, WORD cp); /* OEM code to Unicode conversion */
WCHAR ff_uni2oem(DWORD uni, WORD cp); /* Unicode to OEM code conversion */
DWORD ff_wtoupper(DWORD uni); /* Unicode upper-case conversion */
#endif
/* O/S dependent functions (samples available in ffsystem.c) */
#if FF_USE_LFN == 3 /* Dynamic memory allocation */
void *ff_memalloc(UINT msize); /* Allocate memory block */
void ff_memfree(void *mblock); /* Free memory block */
#endif
/* Sync functions */
#if FF_FS_REENTRANT
int ff_cre_syncobj(BYTE vol, FF_SYNC_t *sobj); /* Create a sync object */
int ff_req_grant(FF_SYNC_t sobj); /* Lock sync object */
void ff_rel_grant(FF_SYNC_t sobj); /* Unlock sync object */
int ff_del_syncobj(FF_SYNC_t sobj); /* Delete a sync object */
#if FF_FS_REENTRANT /* Sync functions */
int ff_mutex_create(int vol); /* Create a sync object */
void ff_mutex_delete(int vol); /* Delete a sync object */
int ff_mutex_take(int vol); /* Lock sync object */
void ff_mutex_give(int vol); /* Unlock sync object */
#endif
/*--------------------------------------------------------------*/
/* Flags and offset address */
/* Flags and Offset Address */
/*--------------------------------------------------------------*/
/* File access mode and open method flags (3rd argument of f_open) */
#define FA_READ 0x01
@ -373,27 +367,27 @@ int ff_del_syncobj(FF_SYNC_t sobj); /* Delete a sync object */
#define FA_OPEN_APPEND 0x30
/* Fast seek controls (2nd argument of f_lseek) */
#define CREATE_LINKMAP ((FSIZE_t)0 - 1)
#define CREATE_LINKMAP ((FSIZE_t)0 - 1)
/* Format options (2nd argument of f_mkfs) */
#define FM_FAT 0x01
#define FM_FAT32 0x02
#define FM_EXFAT 0x04
#define FM_ANY 0x07
#define FM_SFD 0x08
#define FM_FAT 0x01
#define FM_FAT32 0x02
#define FM_EXFAT 0x04
#define FM_ANY 0x07
#define FM_SFD 0x08
/* Filesystem type (FATFS.fs_type) */
#define FS_FAT12 1
#define FS_FAT16 2
#define FS_FAT32 3
#define FS_EXFAT 4
#define FS_FAT12 1
#define FS_FAT16 2
#define FS_FAT32 3
#define FS_EXFAT 4
/* File attribute bits for directory entry (FILINFO.fattrib) */
#define AM_RDO 0x01 /* Read only */
#define AM_HID 0x02 /* Hidden */
#define AM_SYS 0x04 /* System */
#define AM_DIR 0x10 /* Directory */
#define AM_ARC 0x20 /* Archive */
#define AM_RDO 0x01 /* Read only */
#define AM_HID 0x02 /* Hidden */
#define AM_SYS 0x04 /* System */
#define AM_DIR 0x10 /* Directory */
#define AM_ARC 0x20 /* Archive */
#ifdef __cplusplus
}

View file

@ -1,12 +1,18 @@
/*---------------------------------------------------------------------------/
/ FatFs Functional Configurations
/ Configurations of FatFs Module
/---------------------------------------------------------------------------*/
#if defined(CONFIG_FFCONF_USER) && (CONFIG_FFCONF_USER)
#include "ffconf_user.h"
#endif
#define FFCONF_DEF 80286 /* Revision ID */
#define FFCONF_DEF 86606 /* Revision ID */
#if defined(CONFIG_FATFS_FFCONF_USER) && (CONFIG_FATFS_FFCONF_USER)
/* User external configuration, User need to use this file as a template.
All configuration items must be included in the file */
#include "ffconf_user.h"
#else
// #warning "There is no user FatFs conf file and the default conf will be used"
/*---------------------------------------------------------------------------/
/ Function Configurations
@ -36,17 +42,8 @@
/ 2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1.
/ 3: f_lseek() function is removed in addition to 2. */
#ifndef FF_USE_STRFUNC
#define FF_USE_STRFUNC 2
#endif
/* This option switches string functions, f_gets(), f_putc(), f_puts() and f_printf().
/
/ 0: Disable string functions.
/ 1: Enable without LF-CRLF conversion.
/ 2: Enable with LF-CRLF conversion. */
#ifndef FF_USE_FIND
#define FF_USE_FIND 0
#define FF_USE_FIND 1
#endif
/* This option switches filtered directory read functions, f_findfirst() and
/ f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */
@ -67,7 +64,7 @@
/* This option switches f_expand function. (0:Disable or 1:Enable) */
#ifndef FF_USE_CHMOD
#define FF_USE_CHMOD 0
#define FF_USE_CHMOD 1
#endif
/* This option switches attribute manipulation functions, f_chmod() and f_utime().
/ (0:Disable or 1:Enable) Also FF_FS_READONLY needs to be 0 to enable this option. */
@ -83,6 +80,40 @@
#endif
/* This option switches f_forward() function. (0:Disable or 1:Enable) */
#ifndef FF_USE_STRFUNC
#define FF_USE_STRFUNC 0
#endif
#ifndef FF_PRINT_LLI
#define FF_PRINT_LLI 1
#endif
#ifndef FF_PRINT_FLOAT
#define FF_PRINT_FLOAT 1
#endif
#ifndef FF_STRF_ENCODE
#define FF_STRF_ENCODE 3
#endif
/* FF_USE_STRFUNC switches string functions, f_gets(), f_putc(), f_puts() and
/ f_printf().
/
/ 0: Disable. FF_PRINT_LLI, FF_PRINT_FLOAT and FF_STRF_ENCODE have no effect.
/ 1: Enable without LF-CRLF conversion.
/ 2: Enable with LF-CRLF conversion.
/
/ FF_PRINT_LLI = 1 makes f_printf() support long long argument and FF_PRINT_FLOAT = 1/2
/ makes f_printf() support floating point argument. These features want C99 or later.
/ When FF_LFN_UNICODE >= 1 with LFN enabled, string functions convert the character
/ encoding in it. FF_STRF_ENCODE selects assumption of character encoding ON THE FILE
/ to be read/written via those functions.
/
/ 0: ANSI/OEM in current CP
/ 1: Unicode in UTF-16LE
/ 2: Unicode in UTF-16BE
/ 3: Unicode in UTF-8
*/
/*---------------------------------------------------------------------------/
/ Locale and Namespace Configurations
/---------------------------------------------------------------------------*/
@ -117,7 +148,9 @@
/ 0 - Include all code pages above and configured by f_setcp()
*/
#define FF_USE_LFN 3
#ifndef FF_USE_LFN
#define FF_USE_LFN 2
#endif
#define FF_MAX_LFN 255
/* The FF_USE_LFN switches the support for LFN (long file name).
/
@ -149,34 +182,15 @@
/ Also behavior of string I/O functions will be affected by this option.
/ When LFN is not enabled, this option has no effect. */
#ifndef FF_LFN_BUF
#define FF_LFN_BUF 255
#endif
#ifndef FF_SFN_BUF
#define FF_SFN_BUF 12
#endif
/* This set of options defines size of file name members in the FILINFO structure
/ which is used to read out directory items. These values should be suffcient for
/ the file names to read. The maximum possible length of the read file name depends
/ on character encoding. When LFN is not enabled, these options have no effect. */
#ifndef FF_STRF_ENCODE
#define FF_STRF_ENCODE 3
#endif
/* When FF_LFN_UNICODE >= 1 with LFN enabled, string I/O functions, f_gets(),
/ f_putc(), f_puts and f_printf() convert the character encoding in it.
/ This option selects assumption of character encoding ON THE FILE to be
/ read/written via those functions.
/
/ 0: ANSI/OEM in current CP
/ 1: Unicode in UTF-16LE
/ 2: Unicode in UTF-16BE
/ 3: Unicode in UTF-8
*/
#ifndef FF_FS_RPATH
#define FF_FS_RPATH 2
#define FF_FS_RPATH 1
#endif
/* This option configures support for relative path.
/
@ -189,18 +203,18 @@
/ Drive/Volume Configurations
/---------------------------------------------------------------------------*/
#define FF_VOLUMES 6
#define FF_VOLUMES 5
/* Number of volumes (logical drives) to be used. (1-10) */
#define FF_STR_VOLUME_ID 1
#define FF_VOLUME_STRS "ram", "sd", "flash", "usb", "cg", "sd2",
#define FF_STR_VOLUME_ID 2
#define FF_VOLUME_STRS "ram", "flash", "sd", "sd2", "usb"
/* FF_STR_VOLUME_ID switches support for volume ID in arbitrary strings.
/ When FF_STR_VOLUME_ID is set to 1 or 2, arbitrary strings can be used as drive
/ number in the path name. FF_VOLUME_STRS defines the volume ID strings for each
/ logical drives. Number of items must not be less than FF_VOLUMES. Valid
/ characters for the volume ID strings are A-Z, a-z and 0-9, however, they are
/ compared in case-insensitive. If FF_STR_VOLUME_ID >= 1 and FF_VOLUME_STRS is
/ not defined, a user defined volume string table needs to be defined as:
/ not defined, a user defined volume string table is needed as:
/
/ const char* VolumeStr[FF_VOLUMES] = {"ram","flash","sd","usb",...
*/
@ -213,32 +227,23 @@
/ number and only an FAT volume found on the physical drive will be mounted.
/ When this function is enabled (1), each logical drive number can be bound to
/ arbitrary physical drive and partition listed in the VolToPart[]. Also f_fdisk()
/ funciton will be available. */
/ function will be available. */
#ifndef FF_MIN_SS
#define FF_MIN_SS 512
#endif
#ifndef FF_MAX_SS
#define FF_MAX_SS 512
#endif
/* This set of options configures the range of sector size to be supported. (512,
/ 1024, 2048 or 4096) Always set both 512 for most systems, generic memory card and
/ harddisk. But a larger value may be required for on-board flash memory and some
/ harddisk, but a larger value may be required for on-board flash memory and some
/ type of optical media. When FF_MAX_SS is larger than FF_MIN_SS, FatFs is configured
/ for variable sector size mode and disk_ioctl() function needs to implement
/ GET_SECTOR_SIZE command. */
#ifndef FF_LBA64
#define FF_LBA64 0
#endif
/* This option switches support for 64-bit LBA. (0:Disable or 1:Enable)
/ To enable the 64-bit LBA, also exFAT needs to be enabled. (FF_FS_EXFAT == 1) */
#ifndef FF_MIN_GPT
#define FF_MIN_GPT 0x100000000
#endif
/* Minimum number of sectors to switch GPT format to create partition in f_mkfs and
#define FF_MIN_GPT 0x10000000
/* Minimum number of sectors to switch GPT as partitioning format in f_mkfs and
/ f_fdisk function. 0x100000000 max. This option has no effect when FF_LBA64 == 0. */
#ifndef FF_USE_TRIM
@ -251,7 +256,6 @@
/*---------------------------------------------------------------------------/
/ System Configurations
/---------------------------------------------------------------------------*/
#ifndef FF_FS_TINY
#define FF_FS_TINY 0
#endif
@ -268,23 +272,14 @@
/ Note that enabling exFAT discards ANSI C (C89) compatibility. */
#ifndef FF_FS_NORTC
#define FF_FS_NORTC 1
#define FF_FS_NORTC 1
#endif
#ifndef FF_NORTC_MON
#define FF_NORTC_MON 1
#endif
#ifndef FF_NORTC_MDAY
#define FF_NORTC_MON 1
#define FF_NORTC_MDAY 1
#endif
#ifndef FF_NORTC_YEAR
#define FF_NORTC_YEAR 2022
#endif
/* The option FF_FS_NORTC switches timestamp functiton. If the system does not have
/ any RTC function or valid timestamp is not needed, set FF_FS_NORTC = 1 to disable
/ the timestamp function. Every object modified by FatFs will have a fixed timestamp
/* The option FF_FS_NORTC switches timestamp feature. If the system does not have
/ an RTC or valid timestamp is not needed, set FF_FS_NORTC = 1 to disable the
/ timestamp feature. Every object modified by FatFs will have a fixed timestamp
/ defined by FF_NORTC_MON, FF_NORTC_MDAY and FF_NORTC_YEAR in local time.
/ To enable timestamp function (FF_FS_NORTC = 0), get_fattime() function need to be
/ added to the project to read current time form real-time clock. FF_NORTC_MON,
@ -295,7 +290,7 @@
#define FF_FS_NOFSINFO 0
#endif
/* If you need to know correct free space on the FAT32 volume, set bit 0 of this
/ option, and f_getfree() function at first time after volume mount will force
/ option, and f_getfree() function at the first time after volume mount will force
/ a full FAT scan. Bit 1 controls the use of last allocated cluster number.
/
/ bit0=0: Use free cluster count in the FSINFO if available.
@ -317,33 +312,25 @@
/ can be opened simultaneously under file lock control. Note that the file
/ lock control is independent of re-entrancy. */
/* #include <somertos.h> // O/S definitions */
#ifndef FF_FS_REENTRANT
#define FF_FS_REENTRANT 0
#endif
#if (FF_FS_REENTRANT)
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
#define FF_FS_TIMEOUT 1000
#define FF_SYNC_t SemaphoreHandle_t
#endif
#define FF_FS_TIMEOUT 1000
/* The option FF_FS_REENTRANT switches the re-entrancy (thread safe) of the FatFs
/ module itself. Note that regardless of this option, file access to different
/ volume is always re-entrant and volume control functions, f_mount(), f_mkfs()
/ and f_fdisk() function, are always not re-entrant. Only file/directory access
/ to the same volume is under control of this function.
/ to the same volume is under control of this featuer.
/
/ 0: Disable re-entrancy. FF_FS_TIMEOUT and FF_SYNC_t have no effect.
/ 0: Disable re-entrancy. FF_FS_TIMEOUT have no effect.
/ 1: Enable re-entrancy. Also user provided synchronization handlers,
/ ff_req_grant(), ff_rel_grant(), ff_del_syncobj() and ff_cre_syncobj()
/ function, must be added to the project. Samples are available in
/ option/syscall.c.
/ ff_mutex_create(), ff_mutex_delete(), ff_mutex_take() and ff_mutex_give()
/ function, must be added to the project. Samples are available in ffsystem.c.
/
/ The FF_FS_TIMEOUT defines timeout period in unit of time tick.
/ The FF_SYNC_t defines O/S dependent sync object type. e.g. HANDLE, ID, OS_EVENT*,
/ SemaphoreHandle_t and etc. A header file for O/S definitions needs to be
/ included somewhere in the scope of ff.h. */
/ The FF_FS_TIMEOUT defines timeout period in unit of O/S time tick.
*/
#endif
/*--- End of configuration options ---*/

View file

@ -1,163 +1,194 @@
/*------------------------------------------------------------------------*/
/* Sample Code of OS Dependent Functions for FatFs */
/* (C)ChaN, 2018 */
/* A Sample Code of User Provided OS Dependent Functions for FatFs */
/*------------------------------------------------------------------------*/
#include "ff.h"
#include "malloc.h"
#if FF_USE_LFN == 3 /* Dynamic memory allocation */
#if FF_USE_LFN == 3 /* Use dynamic memory allocation */
/*------------------------------------------------------------------------*/
/* Allocate a memory block */
/* Allocate/Free a Memory Block */
/*------------------------------------------------------------------------*/
#include <stdlib.h> /* with POSIX API */
void *ff_memalloc( /* Returns pointer to the allocated memory block (null if not enough core) */
UINT msize /* Number of bytes to allocate */
)
{
return malloc(msize); /* Allocate a new memory block with POSIX API */
return malloc((size_t)msize); /* Allocate a new memory block */
}
/*------------------------------------------------------------------------*/
/* Free a memory block */
/*------------------------------------------------------------------------*/
void ff_memfree(
void *mblock /* Pointer to the memory block to free (nothing to do if null) */
void *mblock /* Pointer to the memory block to free (no effect if null) */
)
{
free(mblock); /* Free the memory block with POSIX API */
free(mblock); /* Free the memory block */
}
#endif
#if FF_FS_REENTRANT /* Mutal exclusion */
/*------------------------------------------------------------------------*/
/* Definitions of Mutex */
/*------------------------------------------------------------------------*/
#define OS_TYPE 3 /* 0:Win32, 1:uITRON4.0, 2:uC/OS-II, 3:FreeRTOS, 4:CMSIS-RTOS */
#if OS_TYPE == 0 /* Win32 */
#include <windows.h>
static HANDLE Mutex[FF_VOLUMES + 1]; /* Table of mutex handle */
#elif OS_TYPE == 1 /* uITRON */
#include "itron.h"
#include "kernel.h"
static mtxid Mutex[FF_VOLUMES + 1]; /* Table of mutex ID */
#elif OS_TYPE == 2 /* uc/OS-II */
#include "includes.h"
static OS_EVENT *Mutex[FF_VOLUMES + 1]; /* Table of mutex pinter */
#elif OS_TYPE == 3 /* FreeRTOS */
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
static SemaphoreHandle_t Mutex[FF_VOLUMES + 1]; /* Table of mutex handle */
#elif OS_TYPE == 4 /* CMSIS-RTOS */
#include "cmsis_os.h"
static osMutexId Mutex[FF_VOLUMES + 1]; /* Table of mutex ID */
#endif
/*------------------------------------------------------------------------*/
/* Create a Synchronization Object */
/* Create a Mutex */
/*------------------------------------------------------------------------*/
/* This function is called in f_mount() function to create a new
/ synchronization object for the volume, such as semaphore and mutex.
/ When a 0 is returned, the f_mount() function fails with FR_INT_ERR.
/* This function is called in f_mount function to create a new mutex
/ or semaphore for the volume. When a 0 is returned, the f_mount function
/ fails with FR_INT_ERR.
*/
//const osMutexDef_t Mutex[FF_VOLUMES]; /* Table of CMSIS-RTOS mutex */
int ff_cre_syncobj( /* 1:Function succeeded, 0:Could not create the sync object */
BYTE vol, /* Corresponding volume (logical drive number) */
FF_SYNC_t *sobj /* Pointer to return the created sync object */
int ff_mutex_create( /* Returns 1:Function succeeded or 0:Could not create the mutex */
int vol /* Mutex ID: Volume mutex (0 to FF_VOLUMES - 1) or system mutex (FF_VOLUMES) */
)
{
/* Win32 */
// *sobj = CreateMutex(NULL, FALSE, NULL);
// return (int)(*sobj != INVALID_HANDLE_VALUE);
#if OS_TYPE == 0 /* Win32 */
Mutex[vol] = CreateMutex(NULL, FALSE, NULL);
return (int)(Mutex[vol] != INVALID_HANDLE_VALUE);
/* uITRON */
// T_CSEM csem = {TA_TPRI,1,1};
// *sobj = acre_sem(&csem);
// return (int)(*sobj > 0);
#elif OS_TYPE == 1 /* uITRON */
T_CMTX cmtx = { TA_TPRI, 1 };
/* uC/OS-II */
// OS_ERR err;
// *sobj = OSMutexCreate(0, &err);
// return (int)(err == OS_NO_ERR);
Mutex[vol] = acre_mtx(&cmtx);
return (int)(Mutex[vol] > 0);
/* FreeRTOS */
*sobj = xSemaphoreCreateMutex();
return (int)(*sobj != NULL);
#elif OS_TYPE == 2 /* uC/OS-II */
OS_ERR err;
/* CMSIS-RTOS */
// *sobj = osMutexCreate(&Mutex[vol]);
// return (int)(*sobj != NULL);
Mutex[vol] = OSMutexCreate(0, &err);
return (int)(err == OS_NO_ERR);
#elif OS_TYPE == 3 /* FreeRTOS */
Mutex[vol] = xSemaphoreCreateMutex();
return (int)(Mutex[vol] != NULL);
#elif OS_TYPE == 4 /* CMSIS-RTOS */
osMutexDef(cmsis_os_mutex);
Mutex[vol] = osMutexCreate(osMutex(cmsis_os_mutex));
return (int)(Mutex[vol] != NULL);
#endif
}
/*------------------------------------------------------------------------*/
/* Delete a Synchronization Object */
/* Delete a Mutex */
/*------------------------------------------------------------------------*/
/* This function is called in f_mount() function to delete a synchronization
/ object that created with ff_cre_syncobj() function. When a 0 is returned,
/ the f_mount() function fails with FR_INT_ERR.
/* This function is called in f_mount function to delete a mutex or
/ semaphore of the volume created with ff_mutex_create function.
*/
int ff_del_syncobj( /* 1:Function succeeded, 0:Could not delete due to an error */
FF_SYNC_t sobj /* Sync object tied to the logical drive to be deleted */
void ff_mutex_delete( /* Returns 1:Function succeeded or 0:Could not delete due to an error */
int vol /* Mutex ID: Volume mutex (0 to FF_VOLUMES - 1) or system mutex (FF_VOLUMES) */
)
{
/* Win32 */
// return (int)CloseHandle(sobj);
#if OS_TYPE == 0 /* Win32 */
CloseHandle(Mutex[vol]);
/* uITRON */
// return (int)(del_sem(sobj) == E_OK);
#elif OS_TYPE == 1 /* uITRON */
del_mtx(Mutex[vol]);
/* uC/OS-II */
// OS_ERR err;
// OSMutexDel(sobj, OS_DEL_ALWAYS, &err);
// return (int)(err == OS_NO_ERR);
#elif OS_TYPE == 2 /* uC/OS-II */
OS_ERR err;
/* FreeRTOS */
vSemaphoreDelete(sobj);
return 1;
OSMutexDel(Mutex[vol], OS_DEL_ALWAYS, &err);
/* CMSIS-RTOS */
// return (int)(osMutexDelete(sobj) == osOK);
#elif OS_TYPE == 3 /* FreeRTOS */
vSemaphoreDelete(Mutex[vol]);
#elif OS_TYPE == 4 /* CMSIS-RTOS */
osMutexDelete(Mutex[vol]);
#endif
}
/*------------------------------------------------------------------------*/
/* Request Grant to Access the Volume */
/* Request a Grant to Access the Volume */
/*------------------------------------------------------------------------*/
/* This function is called on entering file functions to lock the volume.
/* This function is called on enter file functions to lock the volume.
/ When a 0 is returned, the file function fails with FR_TIMEOUT.
*/
int ff_req_grant( /* 1:Got a grant to access the volume, 0:Could not get a grant */
FF_SYNC_t sobj /* Sync object to wait */
int ff_mutex_take( /* Returns 1:Succeeded or 0:Timeout */
int vol /* Mutex ID: Volume mutex (0 to FF_VOLUMES - 1) or system mutex (FF_VOLUMES) */
)
{
/* Win32 */
// return (int)(WaitForSingleObject(sobj, FF_FS_TIMEOUT) == WAIT_OBJECT_0);
#if OS_TYPE == 0 /* Win32 */
return (int)(WaitForSingleObject(Mutex[vol], FF_FS_TIMEOUT) == WAIT_OBJECT_0);
/* uITRON */
// return (int)(wai_sem(sobj) == E_OK);
#elif OS_TYPE == 1 /* uITRON */
return (int)(tloc_mtx(Mutex[vol], FF_FS_TIMEOUT) == E_OK);
/* uC/OS-II */
// OS_ERR err;
// OSMutexPend(sobj, FF_FS_TIMEOUT, &err));
// return (int)(err == OS_NO_ERR);
#elif OS_TYPE == 2 /* uC/OS-II */
OS_ERR err;
/* FreeRTOS */
return (int)(xSemaphoreTake(sobj, FF_FS_TIMEOUT) == pdTRUE);
OSMutexPend(Mutex[vol], FF_FS_TIMEOUT, &err));
return (int)(err == OS_NO_ERR);
/* CMSIS-RTOS */
// return (int)(osMutexWait(sobj, FF_FS_TIMEOUT) == osOK);
}
#elif OS_TYPE == 3 /* FreeRTOS */
return (int)(xSemaphoreTake(Mutex[vol], FF_FS_TIMEOUT) == pdTRUE);
/*------------------------------------------------------------------------*/
/* Release Grant to Access the Volume */
/*------------------------------------------------------------------------*/
/* This function is called on leaving file functions to unlock the volume.
*/
void ff_rel_grant(
FF_SYNC_t sobj /* Sync object to be signaled */
)
{
/* Win32 */
// ReleaseMutex(sobj);
/* uITRON */
// sig_sem(sobj);
/* uC/OS-II */
// OSMutexPost(sobj);
/* FreeRTOS */
xSemaphoreGive(sobj);
/* CMSIS-RTOS */
// osMutexRelease(sobj);
}
#elif OS_TYPE == 4 /* CMSIS-RTOS */
return (int)(osMutexWait(Mutex[vol], FF_FS_TIMEOUT) == osOK);
#endif
}
/*------------------------------------------------------------------------*/
/* Release a Grant to Access the Volume */
/*------------------------------------------------------------------------*/
/* This function is called on leave file functions to unlock the volume.
*/
void ff_mutex_give(
int vol /* Mutex ID: Volume mutex (0 to FF_VOLUMES - 1) or system mutex (FF_VOLUMES) */
)
{
#if OS_TYPE == 0 /* Win32 */
ReleaseMutex(Mutex[vol]);
#elif OS_TYPE == 1 /* uITRON */
unl_mtx(Mutex[vol]);
#elif OS_TYPE == 2 /* uC/OS-II */
OSMutexPost(Mutex[vol]);
#elif OS_TYPE == 3 /* FreeRTOS */
xSemaphoreGive(Mutex[vol]);
#elif OS_TYPE == 4 /* CMSIS-RTOS */
osMutexRelease(Mutex[vol]);
#endif
}
#endif /* FF_FS_REENTRANT */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,33 @@
/**
* @file sdh_sdcard.c
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#ifndef FATFS_DISKIO_REGISTER_H
#define FATFS_DISKIO_REGISTER_H
#if defined(BL616) || defined(BL808) || defined(BL628) || defined(BL606P)
void fatfs_sdh_driver_register(void);
#endif
#endif

View file

@ -21,15 +21,6 @@
*
*/
/*-----------------------------------------------------------------------*/
/* Low level disk I/O module skeleton for FatFs (C)ChaN, 2019 */
/*-----------------------------------------------------------------------*/
/* If a working storage control module is available, it should be */
/* attached to the FatFs via a glue function rather than modifying it. */
/* This is an example of glue functions to attach various exsisting */
/* storage control modules to the FatFs module with a defined API. */
/*-----------------------------------------------------------------------*/
#if defined(BL616) || defined(BL808) || defined(BL628) || defined(BL606P)
#include "ff.h" /* Obtains integer types */
@ -38,7 +29,6 @@
#include "bflb_irq.h"
static sd_card_t gSDCardInfo;
extern const char *FR_Table[];
int MMC_disk_status()
{
@ -108,33 +98,38 @@ int MMC_disk_ioctl(BYTE cmd, void *buff)
DSTATUS Translate_Result_Code(int result)
{
// MSG("%s\r\n",FR_Table[result]);
return result;
}
extern void SDH_MMC1_IRQHandler(void);
static void sdh_isr(int irq, void *arg)
{
SDH_MMC1_IRQHandler();
}
void fatfs_sdh_driver_register(void)
{
FATFS_DiskioDriverTypeDef pNewDiskioDriver;
FATFS_DiskioDriverTypeDef SDH_DiskioDriver = { NULL };
memset(&pNewDiskioDriver, 0, sizeof(FATFS_DiskioDriverTypeDef));
SDH_DiskioDriver.disk_status = MMC_disk_status;
SDH_DiskioDriver.disk_initialize = MMC_disk_initialize;
SDH_DiskioDriver.disk_write = MMC_disk_write;
SDH_DiskioDriver.disk_read = MMC_disk_read;
SDH_DiskioDriver.disk_ioctl = MMC_disk_ioctl;
SDH_DiskioDriver.error_code_parsing = Translate_Result_Code;
pNewDiskioDriver.MMC_disk_status = MMC_disk_status;
pNewDiskioDriver.MMC_disk_initialize = MMC_disk_initialize;
pNewDiskioDriver.MMC_disk_write = MMC_disk_write;
pNewDiskioDriver.MMC_disk_read = MMC_disk_read;
pNewDiskioDriver.MMC_disk_ioctl = MMC_disk_ioctl;
pNewDiskioDriver.Translate_Result_Code = Translate_Result_Code;
disk_driver_callback_init(&pNewDiskioDriver);
disk_driver_callback_init(DEV_SD, &SDH_DiskioDriver);
}
bflb_irq_attach(33, sdh_isr, NULL);
bflb_irq_enable(33);
uint32_t get_fattime(void)
{
uint16_t year = 2022;
uint8_t mon = 1;
uint8_t mday = 1;
uint8_t hour = 0;
uint8_t min = 0;
uint8_t sec = 0;
return ((uint32_t)(year - 1980) << 25 |
(uint32_t)mon << 21 |
(uint32_t)mday << 16 |
(uint32_t)hour << 11 |
(uint32_t)min << 5 |
(uint32_t)(sec / 2) << 0);
}
#endif

View file

@ -1,5 +1,9 @@
sdk_generate_library()
add_subdirectory(newlib)
# use newlib stdlib or nuttx stdlib
if(NOT CONFIG_NEWLIB_STANDARD)
sdk_library_add_sources(
nuttx/libc/stdlib/lib_abs.c
nuttx/libc/stdlib/lib_atof.c
@ -19,7 +23,10 @@ nuttx/libc/stdlib/lib_strtod.c
# nuttx/libc/stdlib/lib_strtoll.c
# nuttx/libc/stdlib/lib_strtoull.c
)
endif()
# use newlib string or nuttx string
if(NOT CONFIG_NEWLIB_STANDARD)
sdk_library_add_sources(
nuttx/libc/string/lib_ffs.c
nuttx/libc/string/lib_ffsl.c
@ -54,72 +61,51 @@ nuttx/libc/string/lib_strtokr.c
# nuttx/libc/string/lib_isbasedigit.c
# nuttx/libc/string/lib_skipspace.c
)
endif()
# is boot2
if(NOT CONFIG_BOOT2)
# use newlib memcpy or nuttx memcpy
if(NOT CONFIG_NEWLIB_STANDARD)
sdk_library_add_sources(
nuttx/libc/string/lib_vikmemcpy.c
)
endif()
else()
sdk_library_add_sources(
nuttx/libc/string/lib_memcpy.c
)
endif()
sdk_add_include_directories(.)
# libc or vlibc select
if(CONFIG_VLIBC)
# vsnprintf config
if(CONFIG_VSNPRINTF_FLOAT)
sdk_add_compile_definitions(-DCONFIG_VLIBC_FLOAT=${CONFIG_VSNPRINTF_FLOAT})
endif()
if(CONFIG_VSNPRINTF_FLOAT_EX)
sdk_add_compile_definitions(-DCONFIG_VLIBC_FLOAT_EX=${CONFIG_VSNPRINTF_FLOAT_EX})
endif()
if(CONFIG_VSNPRINTF_LONG_LONG)
sdk_add_compile_definitions(-DCONFIG_VLIBC_LONG_LONG=${CONFIG_VSNPRINTF_LONG_LONG})
endif()
if(CONFIG_VSNPRINTF_WRITEBACK)
sdk_add_compile_definitions(-DCONFIG_VLIBC_WRITEBACK=${CONFIG_VSNPRINTF_WRITEBACK})
endif()
sdk_add_compile_definitions(-DCONFIG_VLIBC)
# vlibc debug enable
if(CONFIG_VLIBC_DEBUG)
sdk_add_compile_definitions(-DCONFIG_VLIBC_DEBUG)
endif()
# vlibc fatfs port enable
if(CONFIG_VLIBC_FATFS)
sdk_add_compile_definitions(-DCONFIG_VLIBC_FATFS)
endif()
sdk_library_add_sources(vlibc/printf.c)
sdk_library_add_sources(vlibc/vlibc_stdio.c)
sdk_library_add_sources(vlibc/vlibc_vsnprintf.c)
sdk_add_include_directories(vlibc)
if(NOT CONFIG_NEWLIB_STANDARD)
if(CONFIG_VSNPRINTF_NANO)
sdk_library_add_sources(vsnprintf_nano.c)
else()
# vsnprintf config
if(CONFIG_VSNPRINTF_FLOAT)
sdk_add_compile_definitions(-DCONFIG_LIBC_FLOAT=${CONFIG_VSNPRINTF_FLOAT})
endif()
if(CONFIG_VSNPRINTF_FLOAT_EX)
sdk_add_compile_definitions(-DCONFIG_LIBC_FLOAT_EX=${CONFIG_VSNPRINTF_FLOAT_EX})
endif()
if(CONFIG_VSNPRINTF_LONG_LONG)
sdk_add_compile_definitions(-DCONFIG_LIBC_LONG_LONG=${CONFIG_VSNPRINTF_LONG_LONG})
endif()
if(CONFIG_VSNPRINTF_NANO)
sdk_library_add_sources(vsnprintf_nano.c)
else()
sdk_library_add_sources(vsnprintf.c)
endif()
sdk_library_add_sources(printf.c)
sdk_library_add_sources(vsnprintf.c)
endif()
endif()
if(NOT CONFIG_NEWLIB)
sdk_library_add_sources(snprintf.c)
sdk_library_add_sources(sprintf.c)
sdk_library_add_sources(vsprintf.c)
sdk_library_add_sources(printf.c)
endif()
# vsnprintf %f %F
if(CONFIG_VSNPRINTF_FLOAT)
sdk_add_compile_definitions(-DCONFIG_LIBC_FLOAT=${CONFIG_VSNPRINTF_FLOAT})
endif()
# vsnprintf %g %G %e %E
if(CONFIG_VSNPRINTF_FLOAT_EX)
sdk_add_compile_definitions(-DCONFIG_LIBC_FLOAT_EX=${CONFIG_VSNPRINTF_FLOAT_EX})
endif()
# vsnprintf %lld %lli %llu %llx %llX %llo
if(CONFIG_VSNPRINTF_LONG_LONG)
sdk_add_compile_definitions(-DCONFIG_LIBC_LONG_LONG=${CONFIG_VSNPRINTF_LONG_LONG})
endif()
# use custom apis first, if not exist, then use builtin apis
sdk_add_compile_options(-fno-builtin)

View file

@ -0,0 +1,33 @@
sdk_add_include_directories(.)
if(CONFIG_NEWLIB_STANDARD)
sdk_add_compile_definitions(-DCONFIG_NEWLIB_STANDARD=1)
get_target_property(SDK_INTF_LIB_LINK_OPTIONS sdk_intf_lib INTERFACE_LINK_OPTIONS)
list(REMOVE_ITEM SDK_INTF_LIB_LINK_OPTIONS --specs=nano.specs)
set_target_properties(sdk_intf_lib PROPERTIES INTERFACE_LINK_OPTIONS "")
foreach(item ${SDK_INTF_LIB_LINK_OPTIONS})
sdk_add_link_options(${item})
endforeach()
endif()
# newlib syscalls and ports
if(CONFIG_NEWLIB)
sdk_add_compile_definitions(-DCONFIG_NEWLIB=1)
sdk_library_add_sources(syscalls.c)
sdk_library_add_sources(port_tty.c)
sdk_library_add_sources(port_time.c)
sdk_library_add_sources(port_memory.c)
sdk_library_add_sources(port_init_fini.c)
if(CONFIG_NEWLIB_FATFS)
sdk_add_compile_definitions(-DCONFIG_NEWLIB_FATFS=1)
sdk_library_add_sources(port_file_fatfs.c)
else()
sdk_library_add_sources(port_file_nosys.c)
endif()
else()
sdk_library_add_sources(syscalls_nosys.c)
endif()

View file

@ -0,0 +1,9 @@
# Newlib Syscalls
## Configurations
| CONFIG | Description |
|:----------------------:|:---------------------------:|
| CONFIG_NEWLIB | Enable newlib support |
| CONFIG_NEWLIB_STANDARD | Enable newlib full standart support (default nano) |
| CONFIG_NEWLIB_FATFS | Enable newlib filesystem port fatfs support |

View file

@ -0,0 +1,561 @@
#include <errno.h>
#include <reent.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/fcntl.h>
#include "ff.h"
int fresult_table[20] = {
0, /* (0) Succeeded */
EIO, /* (1) A hard error occurred in the low level disk I/O layer */
EINVAL, /* (2) Assertion failed */
EIO, /* (3) The physical drive cannot work */
ENOENT, /* (4) Could not find the file */
ENOENT, /* (5) Could not find the path */
EBADF, /* (6) The path name format is invalid */
EACCES, /* (7) Access denied due to prohibited access or directory full */
EEXIST, /* (8) Access denied due to prohibited access */
ENOENT, /* (9) The file/directory object is invalid */
EROFS, /* (10) The physical drive is write protected */
ENODEV, /* (11) The logical drive number is invalid */
ENODEV, /* (12) The volume has no work area */
EPIPE, /* (13) There is no valid FAT volume */
EIO, /* (14) The f_mkfs() aborted due to any problem */
EBUSY, /* (15) Could not get a grant to access the volume within defined period */
EACCES, /* (16) The operation is rejected according to the file sharing policy */
ENOMEM, /* (17) LFN working buffer could not be allocated */
EMFILE, /* (18) Number of open files > FF_FS_LOCK */
EINVAL /* (19) Given parameter is invalid */
};
static void *fd_table[FOPEN_MAX] = { NULL };
/*****************************************************************************
* @brief c99 mode to fatfs mode
*
* @param[in] mode c99 mode
*
* @retval uint8_t fatfs mode
*****************************************************************************/
static uint8_t _open_r_helper_mode_to_fatfs(int mode)
{
uint8_t fatfs_mode;
switch (mode & O_ACCMODE) {
case O_RDONLY:
fatfs_mode = FA_READ;
break;
case O_WRONLY:
fatfs_mode = FA_WRITE;
break;
case O_RDWR:
fatfs_mode = (FA_READ | FA_WRITE);
break;
default:
fatfs_mode = FA_READ;
break;
}
if ((mode & (O_CREAT | O_TRUNC)) == (O_CREAT | O_TRUNC)) {
fatfs_mode |= FA_CREATE_ALWAYS;
} else if (mode & O_APPEND) {
fatfs_mode |= FA_OPEN_APPEND;
} else if (mode & O_EXCL) {
fatfs_mode |= FA_CREATE_NEW;
} else if (mode & O_CREAT) {
fatfs_mode |= FA_OPEN_ALWAYS;
}
return fatfs_mode;
}
/*****************************************************************************
* @brief open
*
* @param[in] reent pointer to reentrant struct
* @param[in] path file path string pointer
* @param[in] flags open mode in fcntl.h
* @param[in] mode permission mode
*
* @retval int >=0:fd -1:Error
*****************************************************************************/
int _open_file_r(struct _reent *reent, const char *path, int flags, int mode)
{
FRESULT fresult;
FIL *fp;
int fd = -1;
for (int i = 0; i < FOPEN_MAX; i++) {
if (fd_table[i] == NULL) {
fd_table[i] = (void *)0xffffffff;
fd = i;
break;
}
}
if (fd == -1) {
reent->_errno = EMFILE;
return -1;
}
fp = (FIL *)malloc(sizeof(FIL));
if (fp == NULL) {
reent->_errno = ENOMEM;
return -1;
}
fresult = f_open(fp, path, _open_r_helper_mode_to_fatfs(flags));
if (fresult != FR_OK) {
if (fresult <= FR_INVALID_PARAMETER) {
reent->_errno = fresult_table[fresult];
}
free(fp);
return -1;
}
fd_table[fd] = fp;
return 0x4000 | fd;
}
/*****************************************************************************
* @brief close
*
* @param[in] reent pointer to reentrant struct
* @param[in] fd file descriptors
*
* @retval int 0:Success -1:Error
*****************************************************************************/
int _close_file_r(struct _reent *reent, int fd)
{
FRESULT fresult;
FIL *fp;
fd &= ~0x4000;
if ((fd < 0) || (fd >= FOPEN_MAX) || (fd_table[fd] == NULL)) {
reent->_errno = EBADF;
return -1;
}
fp = fd_table[fd];
fresult = f_close(fp);
if (fresult != FR_OK) {
if (fresult <= FR_INVALID_PARAMETER) {
reent->_errno = fresult_table[fresult];
}
return -1;
}
free(fp);
fd_table[fd] = NULL;
return 0;
}
/*****************************************************************************
* @brief read
*
* @param[in] reent pointer to reentrant struct
* @param[in] fd file descriptors
* @param[in] ptr pointer to buffer
* @param[in] size number of bytes read
*
* @retval _ssize_t actual number of bytes read
*****************************************************************************/
_ssize_t _read_file_r(struct _reent *reent, int fd, void *ptr, size_t size)
{
size_t bytes = 0;
FRESULT fresult;
FIL *fp;
fd &= ~0x4000;
if ((fd < 0) || (fd >= FOPEN_MAX) || (fd_table[fd] == NULL)) {
reent->_errno = EBADF;
return -1;
}
fp = fd_table[fd];
fresult = f_read(fp, ptr, size, &bytes);
if (fresult != FR_OK) {
if (fresult <= FR_INVALID_PARAMETER) {
reent->_errno = fresult_table[fresult];
}
}
return bytes;
}
/*****************************************************************************
* @brief write
*
* @param[in] reent pointer to reentrant struct
* @param[in] fd file descriptors
* @param[in] ptr pointer to buffer
* @param[in] size number of bytes write
*
* @retval _ssize_t actual number of bytes write
*****************************************************************************/
_ssize_t _write_file_r(struct _reent *reent, int fd, const void *ptr, size_t size)
{
size_t bytes = 0;
FRESULT fresult;
FIL *fp;
fd &= ~0x4000;
if ((fd < 0) || (fd >= FOPEN_MAX) || (fd_table[fd] == NULL)) {
reent->_errno = EBADF;
return -1;
}
fp = fd_table[fd];
fresult = f_write(fp, ptr, size, &bytes);
if (fresult != FR_OK) {
if (fresult <= FR_INVALID_PARAMETER) {
reent->_errno = fresult_table[fresult];
}
} else {
f_sync(fp);
}
return bytes;
}
/*****************************************************************************
* @brief lseek
*
* @param[in] reent pointer to reentrant struct
* @param[in] fd file descriptors
* @param[in] offset number of offset bytes
* @param[in] whence offset type
*
* @retval _off_t absolute offset of file pointer
*****************************************************************************/
_off_t _lseek_file_r(struct _reent *reent, int fd, _off_t offset, int whence)
{
FRESULT fresult;
FIL *fp;
fd &= ~0x4000;
if ((fd < 0) || (fd >= FOPEN_MAX) || (fd_table[fd] == NULL)) {
reent->_errno = EBADF;
return -1;
}
fp = fd_table[fd];
switch (whence) {
case SEEK_SET:
fresult = f_lseek(fp, offset);
break;
case SEEK_CUR:
fresult = f_lseek(fp, f_tell((FIL *)fp) + offset);
break;
case SEEK_END:
fresult = f_lseek(fp, f_size((FIL *)fp) + offset);
break;
default:
reent->_errno = EINVAL;
return -1;
}
if (fresult != FR_OK) {
if (fresult <= FR_INVALID_PARAMETER) {
errno = fresult_table[fresult];
}
return EOF;
}
return f_tell((FIL *)fp);
}
/*****************************************************************************
* @brief rename
*
* @param[in] reent pointer to reentrant struct
* @param[in] oldname old file path
* @param[in] newname new file path
*
* @retval int 0:Success -1:Error
*****************************************************************************/
int _rename_file_r(struct _reent *reent, const char *oldname, const char *newname)
{
FRESULT fresult;
fresult = f_rename(oldname, newname);
if (fresult != FR_OK) {
if (fresult <= FR_INVALID_PARAMETER) {
reent->_errno = fresult_table[fresult];
}
return -1;
}
return 0;
}
/*****************************************************************************
* @brief unlink
*
* @param[in] reent pointer to reentrant struct
* @param[in] path file path
*
* @retval int 0:Success -1:Error
*****************************************************************************/
int _unlink_file_r(struct _reent *reent, const char *path)
{
FRESULT fresult;
fresult = f_unlink(path);
if (fresult != FR_OK) {
if (fresult <= FR_INVALID_PARAMETER) {
reent->_errno = fresult_table[fresult];
}
return -1;
}
return 0;
}
/*****************************************************************************
* @brief fstat (not supported)
*
* @param[in] reent pointer to reentrant struct
* @param[in] fd file descriptors
* @param[out] st file stat
*
* @retval int 0:Success -1:Error
*****************************************************************************/
int _fstat_file_r(struct _reent *reent, int fd, struct stat *st)
{
FIL *fp;
fd &= ~0x4000;
if ((fd < 0) || (fd >= FOPEN_MAX) || (fd_table[fd] == NULL)) {
reent->_errno = EBADF;
return -1;
}
fp = fd_table[fd];
st->st_mode = 0444 | S_IFREG;
if (!(fp->obj.attr & AM_RDO)) {
st->st_mode |= 0222;
}
st->st_size = f_size(fp);
// st->st_atime = 0;
// st->st_mtime = 0;
// st->st_ctime = 0;
return 0;
}
/*****************************************************************************
* @brief stat
*
* @param[in] reent pointer to reentrant struct
* @param[in] path file path
* @param[out] st file stat
*
* @retval int 0:Success -1:Error
*****************************************************************************/
int _stat_file_r(struct _reent *reent, const char *path, struct stat *st)
{
FRESULT fresult;
FILINFO fno;
fresult = f_stat(path, &fno);
if (fresult != FR_OK) {
if (fresult <= FR_INVALID_PARAMETER) {
reent->_errno = fresult_table[fresult];
}
return -1;
}
st->st_mode = 0444;
if (!(fno.fattrib & AM_RDO)) {
st->st_mode |= 0222;
}
if (fno.fattrib & AM_DIR) {
st->st_mode |= S_IFDIR;
} else {
st->st_mode |= S_IFREG;
}
st->st_size = fno.fsize;
time_t ftime_sec = ((fno.ftime >> 0) & 0x1F) * 2 +
((fno.ftime >> 5) & 0x3F) * 60 +
((fno.ftime >> 11) & 0x1F) * 3600;
st->st_atime = ftime_sec;
st->st_mtime = ftime_sec;
st->st_ctime = ftime_sec;
return 0;
}
/*****************************************************************************
* @brief mkdir
*
* @param[in] reent pointer to reentrant struct
* @param[in] path dir path
* @param[in] mode mode
*
* @retval int 0:Success -1:Error
*****************************************************************************/
int _mkdir_file_r(struct _reent *reent, const char *path, int mode)
{
int fresult;
fresult = f_mkdir(path);
if (fresult != FR_OK) {
if (fresult <= FR_INVALID_PARAMETER) {
reent->_errno = fresult_table[fresult];
}
return -1;
}
return 0;
}
/*****************************************************************************
* @brief rmdir
*
* @param[in] reent pointer to reentrant struct
* @param[in] path dir path
*
* @retval int 0:Success -1:Error
*****************************************************************************/
int _rmdir_file_r(struct _reent *reent, const char *path)
{
int fresult;
fresult = f_rmdir(path);
if (fresult != FR_OK) {
if (fresult <= FR_INVALID_PARAMETER) {
reent->_errno = fresult_table[fresult];
}
return -1;
}
return 0;
}
/*****************************************************************************
* @brief chmod
*
* @param[in] reent pointer to reentrant struct
* @param[in] path dir path
* @param[in] mode mode
*
* @retval int 0:Success -1:Error
*****************************************************************************/
int _chmod_file_r(struct _reent *reent, const char *path, mode_t mode)
{
FRESULT fresult;
if ((mode & S_IRWXU) == S_IRUSR) {
fresult = f_chmod(path, AM_RDO, AM_RDO);
} else {
fresult = f_chmod(path, 0, AM_RDO);
}
if (fresult != FR_OK) {
if (fresult <= FR_INVALID_PARAMETER) {
reent->_errno = fresult_table[fresult];
}
return -1;
}
return 0;
}
/*****************************************************************************
* @brief chdir
*
* @param[in] reent pointer to reentrant struct
* @param[in] path dir path
*
* @retval int 0:Success -1:Error
*****************************************************************************/
int _chdir_file_r(struct _reent *reent, const char *path)
{
FRESULT fresult;
fresult = f_chdir(path);
if (fresult != FR_OK) {
if (fresult <= FR_INVALID_PARAMETER) {
reent->_errno = fresult_table[fresult];
}
return -1;
}
return 0;
}
/*****************************************************************************
* @brief getcwd
*
* @param[in] reent pointer to reentrant struct
* @param[in] buf buf for path
* @param[in] size buf size
*
* @retval char* pointer to path string NULL:Error
*****************************************************************************/
char *_getcwd_file_r(struct _reent *reent, char *buf, size_t size)
{
FRESULT fresult;
fresult = f_getcwd(buf, size);
if (fresult != FR_OK) {
if (fresult <= FR_INVALID_PARAMETER) {
reent->_errno = fresult_table[fresult];
}
return NULL;
}
return buf;
}
/*****************************************************************************
* @brief chroot
*
* @param[in] path path
*
* @retval int 0:Success -1:Error
*****************************************************************************/
int _chroot_file_r(struct _reent *reent, const char *path)
{
FRESULT fresult;
fresult = f_chdrive("sd:/");
if (fresult != FR_OK) {
if (fresult <= FR_INVALID_PARAMETER) {
reent->_errno = fresult_table[fresult];
}
return -1;
}
return 0;
}

View file

@ -0,0 +1,229 @@
#include <errno.h>
#include <reent.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/fcntl.h>
/*****************************************************************************
* @brief open
*
* @param[in] reent pointer to reentrant struct
* @param[in] path file path string pointer
* @param[in] flags open mode in fcntl.h
* @param[in] mode permission mode
*
* @retval int >=0:fd -1:Error
*****************************************************************************/
int _open_file_r(struct _reent *reent, const char *path, int flags, int mode)
{
reent->_errno = ENOSYS;
return -1;
}
/*****************************************************************************
* @brief close
*
* @param[in] reent pointer to reentrant struct
* @param[in] fd file descriptors
*
* @retval int 0:Success -1:Error
*****************************************************************************/
int _close_file_r(struct _reent *reent, int fd)
{
reent->_errno = ENOSYS;
return -1;
}
/*****************************************************************************
* @brief read
*
* @param[in] reent pointer to reentrant struct
* @param[in] fd file descriptors
* @param[in] ptr pointer to buffer
* @param[in] size number of bytes read
*
* @retval _ssize_t actual number of bytes read
*****************************************************************************/
_ssize_t _read_file_r(struct _reent *reent, int fd, void *ptr, size_t size)
{
reent->_errno = ENOSYS;
return -1;
}
/*****************************************************************************
* @brief write
*
* @param[in] reent pointer to reentrant struct
* @param[in] fd file descriptors
* @param[in] ptr pointer to buffer
* @param[in] size number of bytes write
*
* @retval _ssize_t actual number of bytes write
*****************************************************************************/
_ssize_t _write_file_r(struct _reent *reent, int fd, const void *ptr, size_t size)
{
reent->_errno = ENOSYS;
return -1;
}
/*****************************************************************************
* @brief lseek
*
* @param[in] reent pointer to reentrant struct
* @param[in] fd file descriptors
* @param[in] offset number of offset bytes
* @param[in] whence offset type
*
* @retval _off_t absolute offset of file pointer
*****************************************************************************/
_off_t _lseek_file_r(struct _reent *reent, int fd, _off_t offset, int whence)
{
reent->_errno = ENOSYS;
return -1;
}
/*****************************************************************************
* @brief rename
*
* @param[in] reent pointer to reentrant struct
* @param[in] oldname old file path
* @param[in] newname new file path
*
* @retval int 0:Success -1:Error
*****************************************************************************/
int _rename_file_r(struct _reent *reent, const char *oldname, const char *newname)
{
reent->_errno = ENOSYS;
return -1;
}
/*****************************************************************************
* @brief unlink
*
* @param[in] reent pointer to reentrant struct
* @param[in] path file path
*
* @retval int 0:Success -1:Error
*****************************************************************************/
int _unlink_file_r(struct _reent *reent, const char *path)
{
reent->_errno = ENOSYS;
return -1;
}
/*****************************************************************************
* @brief fstat (not supported)
*
* @param[in] reent pointer to reentrant struct
* @param[in] fd file descriptors
* @param[out] st file stat
*
* @retval int 0:Success -1:Error
*****************************************************************************/
int _fstat_file_r(struct _reent *reent, int fd, struct stat *st)
{
reent->_errno = ENOSYS;
return -1;
}
/*****************************************************************************
* @brief stat
*
* @param[in] reent pointer to reentrant struct
* @param[in] path file path
* @param[out] st file stat
*
* @retval int 0:Success -1:Error
*****************************************************************************/
int _stat_file_r(struct _reent *reent, const char *path, struct stat *st)
{
reent->_errno = ENOSYS;
return -1;
}
/*****************************************************************************
* @brief mkdir
*
* @param[in] reent pointer to reentrant struct
* @param[in] path dir path
* @param[in] mode mode
*
* @retval int 0:Success -1:Error
*****************************************************************************/
int _mkdir_file_r(struct _reent *reent, const char *path, int mode)
{
reent->_errno = ENOSYS;
return -1;
}
/*****************************************************************************
* @brief rmdir
*
* @param[in] reent pointer to reentrant struct
* @param[in] path dir path
*
* @retval int 0:Success -1:Error
*****************************************************************************/
int _rmdir_file_r(struct _reent *reent, const char *path)
{
reent->_errno = ENOSYS;
return -1;
}
/*****************************************************************************
* @brief chmod
*
* @param[in] reent pointer to reentrant struct
* @param[in] path dir path
* @param[in] mode mode
*
* @retval int 0:Success -1:Error
*****************************************************************************/
int _chmod_file_r(struct _reent *reent, const char *path, mode_t mode)
{
reent->_errno = ENOSYS;
return -1;
}
/*****************************************************************************
* @brief chdir
*
* @param[in] reent pointer to reentrant struct
* @param[in] path dir path
*
* @retval int 0:Success -1:Error
*****************************************************************************/
int _chdir_file_r(struct _reent *reent, const char *path)
{
reent->_errno = ENOSYS;
return -1;
}
/*****************************************************************************
* @brief getcwd
*
* @param[in] reent pointer to reentrant struct
* @param[in] buf buf for path
* @param[in] size buf size
*
* @retval char* pointer to path string NULL:Error
*****************************************************************************/
char *_getcwd_file_r(struct _reent *reent, char *buf, size_t size)
{
reent->_errno = ENOSYS;
return NULL;
}
/*****************************************************************************
* @brief chroot
*
* @param[in] path path
*
* @retval int 0:Success -1:Error
*****************************************************************************/
int _chroot_file_r(struct _reent *reent, const char *path)
{
reent->_errno = ENOSYS;
return -1;
}

View file

@ -0,0 +1,53 @@
#include <sys/types.h>
/* These magic symbols are provided by the linker. */
extern void (*__preinit_array_start[])(void) __attribute__((weak));
extern void (*__preinit_array_end[])(void) __attribute__((weak));
extern void (*__init_array_start[])(void) __attribute__((weak));
extern void (*__init_array_end[])(void) __attribute__((weak));
extern void (*__fini_array_start[])(void) __attribute__((weak));
extern void (*__fini_array_end[])(void) __attribute__((weak));
extern void _init(void);
extern void _fini(void);
__attribute__((weak)) void _init(void)
{
}
__attribute__((weak)) void _fini(void)
{
}
/* Iterate over all the init routines. */
void __libc_init_array(void)
{
size_t count;
size_t i;
count = __preinit_array_end - __preinit_array_start;
for (i = 0; i < count; i++) {
__preinit_array_start[i]();
}
_init();
count = __init_array_end - __init_array_start;
for (i = 0; i < count; i++) {
__init_array_start[i]();
}
}
/* Run all the cleanup routines. */
void __libc_fini_array(void)
{
size_t count;
size_t i;
count = __fini_array_end - __fini_array_start;
for (i = count; i > 0; i--) {
__fini_array_start[i - 1]();
}
_fini();
}

View file

@ -0,0 +1,122 @@
#include <errno.h>
#include <reent.h>
#include "mem.h"
/*****************************************************************************
* @brief allocates space (disable)
*
* @param[in] reent pointer to reentrant struct
* @param[in] incr bytes of increment
*
* @retval void* pointer to allocated memory
*****************************************************************************/
void *_sbrk_r(struct _reent *reent, ptrdiff_t incr)
{
reent->_errno = ENOSYS;
return NULL;
}
/*****************************************************************************
* @brief allocate memory
*
* @param[in] reent pointer to reentrant struct
* @param[in] size bytes of allocated memory
*
* @retval void* pointer to allocated memory
*****************************************************************************/
void *_malloc_r(struct _reent *reent, size_t size)
{
void *mem;
mem = bflb_malloc(KMEM_HEAP, size);
if (mem == NULL) {
reent->_errno = ENOMEM;
}
return mem;
}
/*****************************************************************************
* @brief reallocate memory
*
* @param[in] reent pointer to reentrant struct
* @param[in] old pointer to old allocated memory
* @param[in] newlen bytes of new allocated memory
*
* @retval void* pointer to new allocated memory
*****************************************************************************/
void *_realloc_r(struct _reent *reent, void *old, size_t newlen)
{
void *mem;
mem = bflb_realloc(KMEM_HEAP, old, newlen);
if (mem == NULL) {
reent->_errno = ENOMEM;
}
return mem;
}
/*****************************************************************************
* @brief allocate and zero memory
*
* @param[in] reent pointer to reentrant struct
* @param[in] nmenb
* @param[in] size
*
* @retval void* pointer to allocated memory
*****************************************************************************/
void *_calloc_r(struct _reent *reent, size_t nmenb, size_t size)
{
void *mem;
mem = bflb_calloc(KMEM_HEAP, nmenb, size);
if (mem == NULL) {
reent->_errno = ENOMEM;
}
return mem;
}
/*****************************************************************************
* @brief allocate aligned memory
*
* @param[in] reent pointer to reentrant struct
* @param[in] align align bytes
* @param[in] size bytes of allocated memory
*
* @retval void* pointer to new allocated memory
*****************************************************************************/
void *_memalign_r(struct _reent *reent, size_t align, size_t size)
{
void *mem;
mem = bflb_malloc_align(KMEM_HEAP, align, size);
if (mem == NULL) {
reent->_errno = ENOMEM;
}
return mem;
}
/*****************************************************************************
* @brief free memory
*
* @param[in] reent pointer to reentrant struct
* @param[in] addr pointer to allocated memory
*
*****************************************************************************/
void _free_r(struct _reent *reent, void *addr)
{
if (addr == NULL) {
reent->_errno = EINVAL;
return;
}
bflb_free(KMEM_HEAP, addr);
}

View file

@ -0,0 +1,106 @@
#include <errno.h>
#include <reent.h>
#include <sys/time.h>
#include "bflb_rtc.h"
static struct bflb_device_s *rtc = NULL;
static uint32_t timestamp_base = 0;
static struct timezone tz = {
.tz_dsttime = 0,
.tz_minuteswest = 0
};
struct tms {
clock_t tms_utime; /* user time */
clock_t tms_stime; /* system time */
clock_t tms_cutime; /* user time, children */
clock_t tms_cstime; /* system time, children */
};
/*****************************************************************************
* @brief get times
*
* @param[in] reent pointer to reentrant struct
* @param[out] ptms pointer to tms struct
*
* @retval clock_t timeval now
*****************************************************************************/
clock_t _times_r(struct _reent *reent, struct tms *ptms)
{
clock_t timeval = bflb_mtimer_get_time_us();
if (ptms) {
ptms->tms_utime = timeval; /* user time */
ptms->tms_stime = 0; /* system time */
ptms->tms_cutime = 0; /* user time, children */
ptms->tms_cstime = 0; /* system time, children */
}
return timeval;
}
/*****************************************************************************
* @brief
*
* @param[in] reent pointer to reentrant struct
* @param[out] tp pointer to timeval struct
* @param[out] tzvp pointer to timezone struct
*
* @retval int
*****************************************************************************/
int _gettimeofday_r(struct _reent *reent, struct timeval *tp, void *tzvp)
{
struct timezone *tzp = tzvp;
if (rtc == NULL) {
rtc = bflb_device_get_by_name("rtc");
}
if (tp) {
uint64_t ticks = bflb_rtc_get_time(rtc);
tp->tv_sec = ticks / 32768 + timestamp_base;
tp->tv_usec = (ticks & 0x7fff) * 31;
}
if (tzp) {
tzp->tz_minuteswest = tz.tz_minuteswest;
tzp->tz_dsttime = tz.tz_dsttime;
}
return 0;
}
/*****************************************************************************
* @brief
*
* @param[in] reent pointer to reentrant struct
* @param[in] tp pointer to timeval struct
* @param[in] tzp pointer to timezone struct
*
* @retval int
*****************************************************************************/
int _settimeofday_r(struct _reent *reent, const struct timeval *tp, const struct timezone *tzp)
{
if (rtc == NULL) {
rtc = bflb_device_get_by_name("rtc");
}
if (tp) {
bflb_rtc_set_time(rtc, tp->tv_usec / 31);
timestamp_base = tp->tv_sec;
}
if (tzp) {
tz.tz_dsttime = tzp->tz_dsttime;
tz.tz_minuteswest = tzp->tz_minuteswest;
}
return 0;
}
int settimeofday(const struct timeval *tp, const struct timezone *tzp)
{
return _settimeofday_r(_REENT, tp, tzp);
}

View file

@ -0,0 +1,383 @@
#include <errno.h>
#include <reent.h>
#include <stdint.h>
#include <stdbool.h>
#include <sys/stat.h>
#include "bflb_uart.h"
/** @addtogroup ttyin_config
-----------------------------------------------------------------------------
* @{
----------------------------------------------------------------------------*/
/*!< the following configuration is only valid for tty input */
/*!< block mode or nonblock mode */
#ifndef CONFIG_TTYIN_NONBLOCK
#define CONFIG_TTYIN_NONBLOCK 0
#endif
/*!< use raw data */
#ifndef CONFIG_TTYIN_RAWMODE
#define CONFIG_TTYIN_RAWMODE 0
#endif
/*!< map crnl -> nl */
#ifndef CONFIG_TTYIN_CRNL2NL
#define CONFIG_TTYIN_CRNL2NL 1
#endif
/*!< map crnl -> cr */
#ifndef CONFIG_TTYIN_CRNL2CR
#define CONFIG_TTYIN_CRNL2CR 0
#endif
/*!< map nlcr -> nl */
#ifndef CONFIG_TTYIN_NLCR2NL
#define CONFIG_TTYIN_NLCR2NL 1
#endif
/*!< map nlcr -> cr */
#ifndef CONFIG_TTYIN_NLCR2CR
#define CONFIG_TTYIN_NLCR2CR 0
#endif
/*!< map cr -> nl */
#ifndef CONFIG_TTYIN_CR2NL
#define CONFIG_TTYIN_CR2NL 1
#endif
/*!< map nl -> cr */
#ifndef CONFIG_TTYIN_NL2CR
#define CONFIG_TTYIN_NL2CR 0
#endif
/*---------------------------------------------------------------------------
* @} ttyin_config
----------------------------------------------------------------------------*/
/** @addtogroup ttyin_fifo
-----------------------------------------------------------------------------
* @{
----------------------------------------------------------------------------*/
struct _ttyin_fifo {
volatile uint32_t in;
volatile uint32_t out;
volatile uint32_t mask;
volatile void *data;
};
/*****************************************************************************
* @brief macro to define and init a fifo object
*
* @param name name of the fifo
* @param size the number of elements in the fifo,
* this must be a power of 2 !!!
*****************************************************************************/
#define TTYIN_FIFO_DEFINE(name, size) \
struct { \
struct _ttyin_fifo fifo; \
uint8_t buf[(((size) < 2) || ((size) & ((size)-1))) ? -1 : (size)]; \
}(name) = { \
.fifo.in = 0, \
.fifo.out = 0, \
.fifo.mask = (size)-1, \
.fifo.data = (name).buf \
}
/*****************************************************************************
* @brief get fifo used space size
*
* @param[in] fifo fifo object
*
* @retval uint32_t used space size
*****************************************************************************/
static inline uint32_t _ttyin_fifo_used(struct _ttyin_fifo *fifo)
{
return fifo->in - fifo->out;
}
/*****************************************************************************
* @brief get fifo unused space size
*
* @param[in] fifo fifo object
*
* @retval uint32_t unused space size
*****************************************************************************/
static inline uint32_t _ttyin_fifo_free(struct _ttyin_fifo *fifo)
{
return (fifo->mask + 1) - (fifo->in - fifo->out);
}
/*****************************************************************************
* @brief returns true if the fifo is full
*
* @param[in] fifo fifo object
*
* @retval bool
*****************************************************************************/
static inline bool _ttyin_fifo_is_full(struct _ttyin_fifo *fifo)
{
return _ttyin_fifo_used(fifo) > fifo->mask;
}
/*****************************************************************************
* @brief returns true if the fifo is empty
*
* @param[in] name fifo object
*
* @retval bool
*****************************************************************************/
static inline bool _ttyin_fifo_is_empty(struct _ttyin_fifo *fifo)
{
return fifo->in == fifo->out;
}
/*****************************************************************************
* @brief put byte into the fifo
*
* @param[in] name fifo object
* @param[in] ch data
*
*****************************************************************************/
static inline void _ttyin_fifo_put(struct _ttyin_fifo *fifo, uint8_t ch)
{
#if defined(CONFIG_TTYIN_CR2NL) && CONFIG_TTYIN_CR2NL
ch = (ch == '\r') ? '\n' : ch;
#elif defined(CONFIG_TTYIN_NL2CR) && CONFIG_TTYIN_NL2CR
ch = (ch == '\n') ? '\r' : ch;
#endif
if (!_ttyin_fifo_is_full(fifo)) {
((volatile uint8_t *)(fifo->data))[fifo->in & fifo->mask] = ch;
fifo->in++;
}
}
/*****************************************************************************
* @brief get byte from the fifo
*
* @param[in] fifo fifo object
*
* @retval int data
*****************************************************************************/
static inline int _ttyin_fifo_get(struct _ttyin_fifo *fifo)
{
register int ch = -1;
#if defined(CONFIG_TTYIN_NONBLOCK) && CONFIG_TTYIN_NONBLOCK
if (!_ttyin_fifo_is_empty(fifo))
#else
while (_ttyin_fifo_is_empty(fifo)) {}
#endif
{
ch = ((volatile uint8_t *)(fifo->data))[fifo->out & fifo->mask];
fifo->out++;
}
return ch;
}
#define ttyin_fifo_used(__fifo) _ttyin_fifo_used(&((__fifo).fifo))
#define ttyin_fifo_free(__fifo) _ttyin_fifo_free(&((__fifo).fifo))
#define ttyin_fifo_is_full(__fifo) _ttyin_fifo_is_full(&((__fifo).fifo))
#define ttyin_fifo_is_empty(__fifo) _ttyin_fifo_is_empty(&((__fifo).fifo))
#define ttyin_fifo_put(__fifo, __ch) _ttyin_fifo_put(&((__fifo).fifo), (__ch))
#define ttyin_fifo_get(__fifo) _ttyin_fifo_get(&((__fifo).fifo))
/*---------------------------------------------------------------------------
* @} ttyin_fifo
----------------------------------------------------------------------------*/
struct bflb_device_s *console = NULL;
static TTYIN_FIFO_DEFINE(stdin_fifo, 512);
void console_receive_isr(int irq, void *arg)
{
uint32_t intstatus = bflb_uart_get_intstatus(console);
if (intstatus & UART_INTSTS_RX_FIFO) {
while (bflb_uart_rxavailable(console)) {
ttyin_fifo_put(stdin_fifo, bflb_uart_getchar(console));
}
}
if (intstatus & UART_INTSTS_RTO) {
while (bflb_uart_rxavailable(console)) {
ttyin_fifo_put(stdin_fifo, bflb_uart_getchar(console));
}
bflb_uart_int_clear(console, UART_INTCLR_RTO);
}
}
void bflb_uart_set_console(struct bflb_device_s *dev)
{
console = dev;
bflb_uart_rxint_mask(console, false);
bflb_irq_attach(console->irq_num, console_receive_isr, console);
bflb_irq_enable(console->irq_num);
}
/*****************************************************************************
* @brief open
*
* @param[in] reent pointer to reentrant struct
* @param[in] path file path string pointer
* @param[in] flags open mode in fcntl.h
* @param[in] mode permission mode
*
* @retval int >=0:fd -1:Error
*****************************************************************************/
int _open_tty_r(struct _reent *reent, const char *path, int flags, int mode)
{
if (strncmp("/dev/null", path, 9) == 0) {
return 0x3ff;
} else if (strncmp("/dev/stdin", path, 10) == 0) {
return 0;
} else if (strncmp("/dev/stdout", path, 11) == 0) {
return 1;
} else if (strncmp("/dev/stderr", path, 11) == 0) {
return 2;
} else {
reent->_errno = ENOENT;
return -1;
}
}
/*****************************************************************************
* @brief close
*
* @param[in] reent pointer to reentrant struct
* @param[in] fd file descriptors
*
* @retval int 0:Success -1:Error
*****************************************************************************/
int _close_tty_r(struct _reent *reent, int fd)
{
if (fd == 0x3ff) {
return 0;
} else if (fd == 0) {
return 0;
} else if (fd == 1) {
return 0;
} else if (fd == 2) {
return 0;
} else {
reent->_errno = EBADF;
return -1;
}
}
/*****************************************************************************
* @brief read
*
* @param[in] reent pointer to reentrant struct
* @param[in] fd file descriptors
* @param[in] ptr pointer to buffer
* @param[in] size number of bytes read
*
* @retval _ssize_t actual number of bytes read
*****************************************************************************/
_ssize_t _read_tty_r(struct _reent *reent, int fd, void *ptr, size_t size)
{
if (fd == 0x3ff) {
return -1;
} else if (fd == 0) {
int ch;
for (size_t i = 0; i < size; i++) {
if ((ch = ttyin_fifo_get(stdin_fifo)) <= -1) {
return i;
} else {
((uint8_t *)ptr)[i] = ch;
bflb_uart_putchar(console, ch);
}
}
return size;
} else if ((fd == 1) || (fd == 2)) {
reent->_errno = EACCES;
return -1;
} else {
reent->_errno = EBADF;
return -1;
}
}
/*****************************************************************************
* @brief write
*
* @param[in] reent pointer to reentrant struct
* @param[in] fd file descriptors
* @param[in] ptr pointer to buffer
* @param[in] size number of bytes write
*
* @retval _ssize_t actual number of bytes write
*****************************************************************************/
_ssize_t _write_tty_r(struct _reent *reent, int fd, const void *ptr, size_t size)
{
if (fd == 0x3ff) {
return size;
} else if (fd == 0) {
reent->_errno = EACCES;
return -1;
} else if ((fd == 1) || (fd == 2)) {
for (size_t i = 0; i < size; i++) {
bflb_uart_putchar(console, ((uint8_t *)ptr)[i]);
}
return size;
} else {
reent->_errno = EBADF;
return -1;
}
}
/*****************************************************************************
* @brief fstat (not supported)
*
* @param[in] reent pointer to reentrant struct
* @param[in] fd file descriptors
* @param[out] st file stat
*
* @retval int 0:Success -1:Error
*****************************************************************************/
int _fstat_tty_r(struct _reent *reent, int fd, struct stat *st)
{
if (fd == 0x3ff) {
st->st_mode = 0666 | S_IFCHR;
return 0;
} else if (fd == 0) {
st->st_mode = 0444 | S_IFCHR;
return 0;
} else if ((fd == 1) || (fd == 2)) {
st->st_mode = 0222 | S_IFCHR;
return 0;
} else {
reent->_errno = EBADF;
return -1;
}
}
/*****************************************************************************
* @brief stat
*
* @param[in] reent pointer to reentrant struct
* @param[in] path file path
* @param[out] st file stat
*
* @retval int 0:Success -1:Error
*****************************************************************************/
int _stat_tty_r(struct _reent *reent, const char *path, struct stat *st)
{
if (strncmp("/dev/null", path, 9) == 0) {
return _fstat_tty_r(reent, 0x3ff, st);
} else if (strncmp("/dev/stdin", path, 10) == 0) {
return _fstat_tty_r(reent, 0, st);
} else if (strncmp("/dev/stdout", path, 11) == 0) {
return _fstat_tty_r(reent, 1, st);
} else if (strncmp("/dev/stderr", path, 11) == 0) {
return _fstat_tty_r(reent, 2, st);
} else {
reent->_errno = EBADF;
return -1;
}
}

View file

@ -0,0 +1,538 @@
/* syscalls.c -- renntrant syscalls for bouffalo sdk.
*/
#include <errno.h>
#include <reent.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
/*****************************************************************************
* @brief get thread reent
*
*
* @retval struct _reent* pointer to reentrant struct
*****************************************************************************/
struct _reent *__getreent(void)
{
return _impure_ptr;
}
/*****************************************************************************
* @brief exit
*
* @param[in] rc exit status
*
*****************************************************************************/
void _exit(int rc)
{
fprintf(stderr, "exit status %d\r\n", rc);
for (;;) {}
}
void exit(int code)
{
_exit(code);
}
/*****************************************************************************
* @brief execve (not supported)
*
* @param[in] reent
* @param[in] name
* @param[in] argv
* @param[in] env
*
* @retval int
*****************************************************************************/
int _execve_r(struct _reent *reent, const char *name, char *const *argv, char *const *env)
{
reent->_errno = ENOSYS;
return -1;
}
/*****************************************************************************
* @brief fork (not supported)
*
* @param[in] reent
*
* @retval int
*****************************************************************************/
int _fork_r(struct _reent *reent)
{
reent->_errno = ENOSYS;
return -1;
}
/*****************************************************************************
* @brief getpid (not supported)
*
* @param[in] reent
*
* @retval int
*****************************************************************************/
int _getpid_r(struct _reent *reent)
{
reent->_errno = ENOSYS;
return -1;
}
/*****************************************************************************
* @brief kill (not supported)
*
* @param[in] reent
* @param[in] pid
* @param[in] sig
*
* @retval int
*****************************************************************************/
int _kill_r(struct _reent *reent, int pid, int sig)
{
reent->_errno = ENOSYS;
return -1;
}
/*****************************************************************************
* @brief wait (not supported)
*
* @param[in] reent
* @param[in] status
*
* @retval int
*****************************************************************************/
int _wait_r(struct _reent *reent, int *status)
{
reent->_errno = ENOSYS;
return -1;
}
/** @addtogroup file_stub
-----------------------------------------------------------------------------
* @{
----------------------------------------------------------------------------*/
extern int _open_tty_r(struct _reent *reent, const char *path, int flags, int mode);
extern int _close_tty_r(struct _reent *reent, int fd);
extern _ssize_t _read_tty_r(struct _reent *reent, int fd, void *ptr, size_t size);
extern _ssize_t _write_tty_r(struct _reent *reent, int fd, const void *ptr, size_t size);
extern int _fstat_tty_r(struct _reent *reent, int fd, struct stat *st);
extern int _stat_tty_r(struct _reent *reent, const char *path, struct stat *st);
extern int _open_file_r(struct _reent *reent, const char *path, int flags, int mode);
extern int _close_file_r(struct _reent *reent, int fd);
extern _ssize_t _read_file_r(struct _reent *reent, int fd, void *ptr, size_t size);
extern _ssize_t _write_file_r(struct _reent *reent, int fd, const void *ptr, size_t size);
extern _off_t _lseek_file_r(struct _reent *reent, int fd, _off_t offset, int whence);
extern int _rename_file_r(struct _reent *reent, const char *oldname, const char *newname);
extern int _unlink_file_r(struct _reent *reent, const char *path);
extern int _fstat_file_r(struct _reent *reent, int fd, struct stat *st);
extern int _stat_file_r(struct _reent *reent, const char *path, struct stat *st);
extern int _mkdir_file_r(struct _reent *reent, const char *path, int mode);
extern int _rmdir_file_r(struct _reent *reent, const char *path);
extern int _chmod_file_r(struct _reent *reent, const char *path, mode_t mode);
extern int _chdir_file_r(struct _reent *reent, const char *path);
extern char *_getcwd_file_r(struct _reent *reent, char *buf, size_t size);
extern int _chroot_file_r(struct _reent *reent, const char *path);
/*****************************************************************************
* @brief chekc fd is a tty
*
* @param[in] reent pointer to reentrant struct
* @param[in] fd file descriptors
*
* @retval int 0:not tty 1:tty
*****************************************************************************/
int _isatty_r(struct _reent *reent, int fd)
{
struct stat buf;
if (_fstat_r(reent, fd, &buf) < 0) {
reent->_errno = EBADF;
return 0;
}
if (S_ISCHR(buf.st_mode)) {
return 1;
}
reent->_errno = ENOTTY;
return 0;
}
/*****************************************************************************
* @brief open
*
* @param[in] reent pointer to reentrant struct
* @param[in] path file path string pointer
* @param[in] flags open mode in fcntl.h
* @param[in] mode permission mode
*
* @retval int >=0:fd -1:Error
*****************************************************************************/
int _open_r(struct _reent *reent, const char *path, int flags, int mode)
{
if (path == NULL) {
reent->_errno = EINVAL;
return -1;
}
if (strncmp("/dev", path, 4) == 0) {
return _open_tty_r(reent, path, flags, mode);
} else {
return _open_file_r(reent, path, flags, mode);
}
}
/*****************************************************************************
* @brief close
*
* @param[in] reent pointer to reentrant struct
* @param[in] fd file descriptors
*
* @retval int 0:Success -1:Error
*****************************************************************************/
int _close_r(struct _reent *reent, int fd)
{
if ((fd & 0x4000) == 0) {
return _close_tty_r(reent, fd);
} else {
return _close_file_r(reent, fd);
}
}
/*****************************************************************************
* @brief read
*
* @param[in] reent pointer to reentrant struct
* @param[in] fd file descriptors
* @param[in] ptr pointer to buffer
* @param[in] size number of bytes read
*
* @retval _ssize_t actual number of bytes read
*****************************************************************************/
_ssize_t _read_r(struct _reent *reent, int fd, void *ptr, size_t size)
{
if (ptr == NULL) {
reent->_errno = EINVAL;
return 0;
}
if ((fd & 0x4000) == 0) {
return _read_tty_r(reent, fd, ptr, size);
} else {
return _read_file_r(reent, fd, ptr, size);
}
}
/*****************************************************************************
* @brief write
*
* @param[in] reent pointer to reentrant struct
* @param[in] fd file descriptors
* @param[in] ptr pointer to buffer
* @param[in] size number of bytes write
*
* @retval _ssize_t actual number of bytes write
*****************************************************************************/
_ssize_t _write_r(struct _reent *reent, int fd, const void *ptr, size_t size)
{
if (ptr == NULL) {
reent->_errno = EINVAL;
return 0;
}
if ((fd & 0x4000) == 0) {
return _write_tty_r(reent, fd, ptr, size);
} else {
return _write_file_r(reent, fd, ptr, size);
}
}
/*****************************************************************************
* @brief lseek
*
* @param[in] reent pointer to reentrant struct
* @param[in] fd file descriptors
* @param[in] offset number of offset bytes
* @param[in] whence offset type
*
* @retval _off_t absolute offset of file pointer
*****************************************************************************/
_off_t _lseek_r(struct _reent *reent, int fd, _off_t offset, int whence)
{
if ((fd & 0x4000) == 0) {
reent->_errno = ESPIPE;
return -1;
} else {
return _lseek_file_r(reent, fd, offset, whence);
}
}
/*****************************************************************************
* @brief rename
*
* @param[in] reent pointer to reentrant struct
* @param[in] oldname old file path
* @param[in] newname new file path
*
* @retval int 0:Success -1:Error
*****************************************************************************/
int _rename_r(struct _reent *reent, const char *oldname, const char *newname)
{
if ((oldname == NULL) || (newname == NULL)) {
reent->_errno = EINVAL;
return -1;
}
return _rename_file_r(reent, oldname, newname);
}
/*****************************************************************************
* @brief unlink
*
* @param[in] reent pointer to reentrant struct
* @param[in] path file path
*
* @retval int 0:Success -1:Error
*****************************************************************************/
int _unlink_r(struct _reent *reent, const char *path)
{
if (path == NULL) {
reent->_errno = EINVAL;
return -1;
}
return _unlink_file_r(reent, path);
}
/*****************************************************************************
* @brief link (not supported)
*
* @param[in] reent pointer to reentrant struct
* @param[in] existing old file path
* @param[in] new new file path
*
* @retval int 0:Success -1:Error
*****************************************************************************/
int _link_r(struct _reent *reent, const char *existing, const char *new)
{
reent->_errno = ENOSYS;
return -1;
}
/*****************************************************************************
* @brief fcntl (not supported)
*
* @param[in] reent pointer to reentrant struct
* @param[in] fd file descriptors
* @param[in] cmd command
* @param[in] arg argument
*
* @retval int 0:Success -1:Error
*****************************************************************************/
int _fcntl_r(struct _reent *reent, int fd, int cmd, int arg)
{
reent->_errno = ENOSYS;
return -1;
}
/*****************************************************************************
* @brief fstat (not supported)
*
* @param[in] reent pointer to reentrant struct
* @param[in] fd file descriptors
* @param[out] st file stat
*
* @retval int 0:Success -1:Error
*****************************************************************************/
int _fstat_r(struct _reent *reent, int fd, struct stat *st)
{
if (st == NULL) {
reent->_errno = EINVAL;
return -1;
}
memset(st, 0, sizeof(*st));
if ((fd & 0x4000) == 0) {
return _fstat_tty_r(reent, fd, st);
} else {
return _fstat_file_r(reent, fd, st);
}
}
/*****************************************************************************
* @brief stat
*
* @param[in] reent pointer to reentrant struct
* @param[in] path file path
* @param[out] st file stat
*
* @retval int 0:Success -1:Error
*****************************************************************************/
int _stat_r(struct _reent *reent, const char *path, struct stat *st)
{
if ((path == NULL) || (st == NULL)) {
reent->_errno = EINVAL;
return -1;
}
memset(st, 0, sizeof(*st));
if (strncmp("/dev", path, 4) == 0) {
return _stat_tty_r(reent, path, st);
} else {
return _stat_file_r(reent, path, st);
}
}
/*****************************************************************************
* @brief mkdir
*
* @param[in] reent pointer to reentrant struct
* @param[in] path dir path
* @param[in] mode mode
*
* @retval int 0:Success -1:Error
*****************************************************************************/
int _mkdir_r(struct _reent *reent, const char *path, int mode)
{
if (path == NULL) {
reent->_errno = EINVAL;
return -1;
}
return _mkdir_file_r(reent, path, mode);
}
int mkdir(const char *path, mode_t mode)
{
return _mkdir_r(_REENT, path, mode);
}
/*****************************************************************************
* @brief rmdir
*
* @param[in] reent pointer to reentrant struct
* @param[in] path dir path
*
* @retval int 0:Success -1:Error
*****************************************************************************/
int _rmdir_r(struct _reent *reent, const char *path)
{
if (path == NULL) {
reent->_errno = EINVAL;
return -1;
}
return _rmdir_file_r(reent, path);
}
int rmdir(const char *path)
{
return _rmdir_r(_REENT, path);
}
/*****************************************************************************
* @brief chmod
*
* @param[in] reent pointer to reentrant struct
* @param[in] path dir path
* @param[in] mode mode
*
* @retval int 0:Success -1:Error
*****************************************************************************/
int _chmod_r(struct _reent *reent, const char *path, mode_t mode)
{
if (path == NULL) {
reent->_errno = EINVAL;
return -1;
}
if (strncmp("/dev", path, 4) == 0) {
reent->_errno = EPERM;
return -1;
} else {
return _chmod_file_r(reent, path, mode);
}
}
int chmod(const char *path, mode_t mode)
{
return _chmod_r(_REENT, path, mode);
}
/*****************************************************************************
* @brief chdir
*
* @param[in] reent pointer to reentrant struct
* @param[in] path dir path
*
* @retval int 0:Success -1:Error
*****************************************************************************/
int _chdir_r(struct _reent *reent, const char *path)
{
if (path == NULL) {
reent->_errno = EINVAL;
return -1;
}
return _chdir_file_r(reent, path);
}
int chdir(const char *path)
{
return _chdir_r(_REENT, path);
}
/*****************************************************************************
* @brief getcwd
*
* @param[in] reent pointer to reentrant struct
* @param[in] buf buf for path
* @param[in] size buf size
*
* @retval char* pointer to path string NULL:Error
*****************************************************************************/
char *_getcwd_r(struct _reent *reent, char *buf, size_t size)
{
if (buf == NULL) {
reent->_errno = EINVAL;
return NULL;
}
return _getcwd_file_r(reent, buf, size);
}
char *getcwd(char *buf, size_t size)
{
return _getcwd_r(_REENT, buf, size);
}
/*****************************************************************************
* @brief chroot
*
* @param[in] path path
*
* @retval int 0:Success -1:Error
*****************************************************************************/
int _chroot_r(struct _reent *reent, const char *path)
{
if (path == NULL) {
reent->_errno = EINVAL;
return 0;
}
return _chroot_file_r(reent, path);
}
int chroot(const char *path)
{
return _chroot_r(_REENT, path);
}
/*---------------------------------------------------------------------------
* @} file_stub
----------------------------------------------------------------------------*/

View file

@ -0,0 +1,144 @@
#include <limits.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/times.h>
#include <sys/stat.h>
#undef errno
int errno;
char *__env[1] = { 0 };
char **environ = __env;
void _exit(int rc)
{
for (;;)
;
}
int _chown(const char *path, uid_t owner, gid_t group)
{
errno = ENOSYS;
return -1;
}
int _close(int fildes)
{
errno = ENOSYS;
return -1;
}
int _execve(char *name, char **argv, char **env)
{
errno = ENOSYS;
return -1;
}
int _fork(void)
{
errno = ENOSYS;
return -1;
}
int _fstat(int fildes, struct stat *st)
{
errno = ENOSYS;
return -1;
}
int _getpid(void)
{
errno = ENOSYS;
return -1;
}
int _gettimeofday(struct timeval *ptimeval, void *ptimezone)
{
errno = ENOSYS;
return -1;
}
int _isatty(int file)
{
errno = ENOSYS;
return 0;
}
int _kill(int pid, int sig)
{
errno = ENOSYS;
return -1;
}
int _link(char *existing, char *new)
{
errno = ENOSYS;
return -1;
}
int _lseek(int file, int ptr, int dir)
{
errno = ENOSYS;
return -1;
}
int _open(char *file, int flags, int mode)
{
errno = ENOSYS;
return -1;
}
int _read(int file, char *ptr, int len)
{
errno = ENOSYS;
return -1;
}
int _readlink(const char *path, char *buf, size_t bufsize)
{
errno = ENOSYS;
return -1;
}
void *_sbrk(int incr)
{
errno = ENOSYS;
return NULL;
}
int _stat(const char *file, struct stat *st)
{
errno = ENOSYS;
return -1;
}
int _symlink(const char *path1, const char *path2)
{
errno = ENOSYS;
return -1;
}
clock_t _times(struct tms *buf)
{
errno = ENOSYS;
return -1;
}
int _unlink(char *name)
{
errno = ENOSYS;
return -1;
}
int _wait(int *status)
{
errno = ENOSYS;
return -1;
}
int _write(int file, char *ptr, int len)
{
errno = ENOSYS;
return -1;
}

25
components/libc/sprintf.c Normal file
View file

@ -0,0 +1,25 @@
#include <stdint.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdio.h>
/**
* This function will fill a formatted string to buffer
*
* @param buf the buffer to save formatted string.
*
* @param format is the format parameters.
*
* @return The number of characters actually written to buffer.
*/
int sprintf(char *buf, const char *format, ...)
{
int32_t n;
va_list arg_ptr;
va_start(arg_ptr, format);
n = vsprintf(buf, format, arg_ptr);
va_end(arg_ptr);
return n;
}

View file

@ -1,119 +0,0 @@
#include <errno.h>
#include <stdarg.h>
#include "bflb_uart.h"
#include "vlibc_stdio.h"
#define IOCONSOLE_IO ((uint32_t)0x00000001)
#define IOCONSOLE_NAME "console"
struct bflb_device_s *console = NULL;
int printf(const char *fmt, ...)
{
char print_buf[1024];
uint32_t len;
va_list ap;
if (console == NULL) {
return 0;
}
va_start(ap, fmt);
len = vsnprintf(print_buf, sizeof(print_buf), fmt, ap);
va_end(ap);
len = (len > sizeof(print_buf)) ? sizeof(print_buf) : len;
bflb_uart_put(console, (uint8_t *)print_buf, len);
return 0;
}
__WEAK uint32_t __vlibc_io_init(const char *name, uint8_t mode)
{
(void)mode;
if (strcmp(name, IOCONSOLE_NAME) == 0) {
return IOCONSOLE_IO;
} else {
}
return ENOENT;
}
__WEAK uint32_t __vlibc_io_deinit(struct __vlibc_io *io)
{
if (io->dev == IOCONSOLE_IO) {
return IOCONSOLE_IO;
} else {
}
return EOF;
}
__WEAK size_t __vlibc_io_mem2dev(struct __vlibc_io *io, const void *ptr, size_t size)
{
if (io->dev == IOCONSOLE_IO) {
for (size_t i = 0; i < size; i++) {
bflb_uart_putchar(console, ((char *)ptr)[i]);
}
return size;
} else {
}
return 0;
}
#define __is_print(ch) ((unsigned int)((ch) - ' ') < 127u - ' ')
void bflb_dump_hex(const void *ptr, uint32_t buflen)
{
unsigned char *buf = (unsigned char *)ptr;
int i, j;
for (i = 0; i < buflen; i += 16) {
printf("%08X:", i);
for (j = 0; j < 16; j++)
if (i + j < buflen) {
if ((j % 8) == 0) {
printf(" ");
}
printf("%02X ", buf[i + j]);
} else
printf(" ");
printf(" ");
for (j = 0; j < 16; j++)
if (i + j < buflen)
printf("%c", __is_print(buf[i + j]) ? buf[i + j] : '.');
printf("\n");
}
}
void bflb_reg_dump(uint32_t addr)
{
printf("%08lx[31:0]=%08lx\r\n", addr, *(volatile uint32_t *)(uintptr_t)(addr));
}
int bflb_data_compare(const uint8_t *expected, uint8_t *input, uint32_t len)
{
int i = 0;
for (i = 0; i < len; i++) {
if (input[i] != expected[i]) {
printf("Compare fail at %d,input %02x, but expect %02x\r\n", i, input[i], expected[i]);
return -1;
}
}
return 0;
}
void bflb_uart_set_console(struct bflb_device_s *dev)
{
console = dev;
/*!< vlibc_stdout and vlibc_stderr should config by user */
// vlibc_stdout = vlibc_fopen("<" IOCONSOLE_NAME, "w");
// vlibc_setvbuf(vlibc_stdout, NULL, _IONBF, 0);
// vlibc_stderr = vlibc_stdout;
}

File diff suppressed because it is too large Load diff

View file

@ -1,170 +0,0 @@
#ifndef _VLIBC_STDIO_H
#define _VLIBC_STDIO_H
#include <stdarg.h>
#include <stddef.h>
#include <stdio.h>
#include <stdint.h>
#ifdef CONFIG_VLIBC_FATFS
#include "ff.h"
#endif
/** @addtogroup Types
* @{
*/
struct __vlibc_io {
char *bg; /*!< buffer begin pointer */
char *wp; /*!< buffer write pointer */
char *rp; /*!< buffer read pointer */
char *ed; /*!< buffer end pointer */
uint32_t dev; /*!< io device */
uint8_t flag; /*!< io flag */
uint8_t vbuf; /*!< buffer mode */
uint8_t abuf; /*!< buffer auto */
uint8_t err; /*!< error */
};
typedef struct {
uint32_t magic;
union {
struct __vlibc_io *io;
#ifdef CONFIG_VLIBC_FATFS
FIL *file;
#else
int *file;
#endif
};
} vlibc_file_t;
/*!< file type */
#define VLIBC_FILE vlibc_file_t
/**
* @}
*/
/** @addtogroup stdio extra
* @{
*/
extern uint32_t __vlibc_io_init(const char *name, uint8_t mode);
extern uint32_t __vlibc_io_deinit(struct __vlibc_io *io);
extern size_t __vlibc_io_mem2dev(struct __vlibc_io *io, const void *ptr, size_t size);
extern size_t __vlibc_io_dev2mem(struct __vlibc_io *io, void *ptr, size_t size);
/**
* @}
*/
/** @addtogroup Marcos
* @{
*/
#define _VLIBC_MAGIC_MASK ((unsigned int)(0xffff0000))
#define _VLIBC_IO_MAGIC_CODE ((unsigned int)(0x10de0000))
#define _VLIBC_FILE_MAGIC_CODE ((unsigned int)(0xf11e0000))
#define _VLIBC_IO_WRITE ((unsigned char)(0x01))
#define _VLIBC_IO_READ ((unsigned char)(0x02))
/*!< io buffer size */
#define VLIBC_BUFSIZ 256
/*!< file stack buffer size */
#define VLIBC_FBUFSIZ 256
/*!< max open file count at the same time */
#define VLIBC_FOPEN_MAX 20
/*!< max file name length */
#define VLIBC_FILENAME_MAX 256
/*!< max io name length */
#define _VLIBC_IONAME_MAX 32
/*!< max tmpnam file name length */
#define VLIBC_L_tmpnam VLIBC_FILENAME_MAX
/*!< max tmpnam rand name */
#define VLIBC_TMP_MAX 0
/*!< stand io */
extern vlibc_file_t *__vlibc_stdio_fileptrs[3];
#define vlibc_stdin (__vlibc_stdio_fileptrs[0])
#define vlibc_stdout (__vlibc_stdio_fileptrs[1])
#define vlibc_stderr (__vlibc_stdio_fileptrs[2])
/**
* @}
*/
/** @addtogroup stdio functions
* @{
*/
extern void vlibc_clearerr(VLIBC_FILE *);
extern int vlibc_feof(VLIBC_FILE *);
extern int vlibc_ferror(VLIBC_FILE *);
extern VLIBC_FILE *vlibc_fopen(const char *, const char *);
extern VLIBC_FILE *vlibc_freopen(const char *, const char *, VLIBC_FILE *);
extern int vlibc_fclose(VLIBC_FILE *);
extern size_t vlibc_fread(void *, size_t, size_t, VLIBC_FILE *);
extern size_t vlibc_fwrite(const void *, size_t, size_t, VLIBC_FILE *);
extern int vlibc_fflush(VLIBC_FILE *);
extern int vlibc_fseek(VLIBC_FILE *, long, int);
extern long vlibc_ftell(VLIBC_FILE *);
extern int vlibc_remove(const char *);
extern int vlibc_rename(const char *, const char *);
extern void vlibc_rewind(VLIBC_FILE *);
extern void vlibc_setbuf(VLIBC_FILE *, char *);
extern int vlibc_setvbuf(VLIBC_FILE *, char *, int, size_t);
extern VLIBC_FILE *vlibc_tmpfile(void);
extern char *vlibc_tmpnam(char *);
extern int vlibc_fprintf(VLIBC_FILE *, const char *, ...);
extern int vlibc_printf(const char *, ...);
extern int vlibc_sprintf(char *, const char *, ...);
extern int vlibc_snprintf(char *, size_t, const char *, ...);
extern int vlibc_vfprintf(VLIBC_FILE *, const char *, va_list);
extern int vlibc_vprintf(const char *, va_list);
extern int vlibc_vsprintf(char *, const char *, va_list);
extern int vlibc_vsnprintf(char *, size_t, const char *, va_list);
extern int vlibc_fscanf(VLIBC_FILE *, const char *, ...);
extern int vlibc_scanf(const char *, ...);
extern int vlibc_sscanf(const char *, const char *, ...);
extern int vlibc_vfscanf(VLIBC_FILE *, const char *, va_list);
extern int vlibc_vscanf(const char *, va_list);
extern int vlibc_vsscanf(const char *, const char *, va_list);
extern int vlibc_fgetc(VLIBC_FILE *);
extern char *vlibc_fgets(char *, int, VLIBC_FILE *);
extern int vlibc_fputc(int, VLIBC_FILE *);
extern int vlibc_fputs(const char *, VLIBC_FILE *);
extern int vlibc_getc(VLIBC_FILE *);
extern int vlibc_getchar(void);
extern char *vlibc_gets(char *);
extern int vlibc_putc(int, VLIBC_FILE *);
extern int vlibc_putchar(int);
extern int vlibc_puts(const char *);
extern void vlibc_perror(const char *);
/**
* @}
*/
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,20 @@
#include <stdint.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdio.h>
/**
* This function will fill a formatted string to buffer.
*
* @param buf is the buffer to save formatted string.
*
* @param format is the format parameters.
*
* @param arg_ptr is a list of variable parameters.
*
* @return The number of characters actually written to buffer.
*/
int vsprintf(char *buf, const char *format, va_list arg_ptr)
{
return vsnprintf(buf, (size_t) - 1, format, arg_ptr);
}

View file

@ -4,8 +4,8 @@ sdk_add_compile_definitions(-DCONFIG_LWIP)
sdk_library_add_sources(src/apps/lwiperf/lwiperf.c)
sdk_library_add_sources(src/apps/http/fs.c)
sdk_library_add_sources(src/apps/http/fsdata_custom.c)
sdk_library_add_sources(src/apps/http/fsdata.c)
# sdk_library_add_sources(src/apps/http/fsdata_custom.c)
# sdk_library_add_sources(src/apps/http/fsdata.c)
# sdk_library_add_sources(src/apps/http/httpd.c)
sdk_library_add_sources(src/api/api_lib.c)

View file

@ -1,4 +1,8 @@
sdk_generate_library()
sdk_add_include_directories(core/inc)
sdk_add_include_directories(port/inc)
sdk_library_add_sources(core/src/lapi.c)
sdk_library_add_sources(core/src/lauxlib.c)
sdk_library_add_sources(core/src/lbaselib.c)
@ -27,14 +31,12 @@ sdk_library_add_sources(core/src/lstrlib.c)
sdk_library_add_sources(core/src/ltable.c)
sdk_library_add_sources(core/src/ltablib.c)
sdk_library_add_sources(core/src/ltm.c)
sdk_library_add_sources(core/src/luaport.c)
sdk_library_add_sources(core/src/lundump.c)
sdk_library_add_sources(core/src/lutf8lib.c)
sdk_library_add_sources(core/src/lvm.c)
sdk_library_add_sources(core/src/lzio.c)
sdk_library_add_sources(start/lua_start.c)
sdk_add_include_directories(core/inc)
sdk_add_compile_definitions(-DCONFIG_LUA)
sdk_library_add_sources(start/lua.c)
if(CONFIG_LUA_LHAL)
sdk_library_add_sources(lhal/llib_init.c)
@ -44,3 +46,5 @@ sdk_library_add_sources(lhal/llib_gpio.c)
sdk_add_include_directories(lhal)
sdk_add_compile_definitions(-DCONFIG_LUA_LHAL)
endif()
sdk_add_compile_definitions(-DCONFIG_LUA)

View file

@ -45,7 +45,7 @@
#define hastocloseCfunc(n) ((n) < LUA_MULTRET)
/* Map [-1, inf) (range of 'nresults') into (-inf, -2] */
#define codeNresults(n) (-(n)-3)
#define decodeNresults(n) (-(n)-3)
#define codeNresults(n) (-(n)-3)
#define decodeNresults(n) (-(n)-3)
#endif

View file

@ -19,10 +19,10 @@
typedef struct luaL_Buffer luaL_Buffer;
/* extra error code for 'luaL_loadfilex' */
#define LUA_ERRFILE (LUA_ERRERR + 1)
#define LUA_ERRFILE (LUA_ERRERR + 1)
/* key, in the registry, for table of loaded modules */
#define LUA_LOADED_TABLE "_LOADED"
#define LUA_LOADED_TABLE "_LOADED"
/* key, in the registry, for table of preloaded loaders */
#define LUA_PRELOAD_TABLE "_PRELOAD"
@ -128,7 +128,7 @@ LUALIB_API void(luaL_requiref)(lua_State *L, const char *modname,
#define luaL_checkstring(L, n) (luaL_checklstring(L, (n), NULL))
#define luaL_optstring(L, n, d) (luaL_optlstring(L, (n), (d), NULL))
#define luaL_typename(L, i) lua_typename(L, lua_type(L, (i)))
#define luaL_typename(L, i) lua_typename(L, lua_type(L, (i)))
#define luaL_dofile(L, fn) \
(luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0))
@ -136,9 +136,9 @@ LUALIB_API void(luaL_requiref)(lua_State *L, const char *modname,
#define luaL_dostring(L, s) \
(luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0))
#define luaL_getmetatable(L, n) (lua_getfield(L, LUA_REGISTRYINDEX, (n)))
#define luaL_getmetatable(L, n) (lua_getfield(L, LUA_REGISTRYINDEX, (n)))
#define luaL_opt(L, f, n, d) (lua_isnoneornil(L, (n)) ? (d) : f(L, (n)))
#define luaL_opt(L, f, n, d) (lua_isnoneornil(L, (n)) ? (d) : f(L, (n)))
#define luaL_loadbuffer(L, s, sz, n) luaL_loadbufferx(L, s, sz, n, NULL)
@ -159,7 +159,7 @@ LUALIB_API void(luaL_requiref)(lua_State *L, const char *modname,
#if defined LUAI_ASSERT
#include <assert.h>
#define lua_assert(c) assert(c)
#define lua_assert(c) luaport_assert(c)
#else
#define lua_assert(c) ((void)0)
#endif
@ -219,10 +219,10 @@ LUALIB_API char *(luaL_buffinitsize)(lua_State *L, luaL_Buffer *B, size_t sz);
** after that initial structure).
*/
#define LUA_FILEHANDLE LUAPORT_FILEHANDLE
#define LUA_FILEHANDLE "FILE*"
typedef struct luaL_Stream {
LUAPORT_FILE *f; /* stream (NULL for incompletely created streams) */
FILE *f; /* stream (NULL for incompletely created streams) */
lua_CFunction closef; /* to close stream (NULL for closed streams) */
} luaL_Stream;
@ -236,7 +236,7 @@ typedef struct luaL_Stream {
/* print a string */
#if !defined(lua_writestring)
#define lua_writestring(s, l) luaport_fwirte((s), sizeof(char), (l), luaport_stdout)
#define lua_writestring(s, l) luaport_fwrite((s), sizeof(char), (l), luaport_stdout)
#endif
/* print a newline and flush the output */
@ -263,8 +263,8 @@ typedef struct luaL_Stream {
#define luaL_optunsigned(L, a, d) \
((lua_Unsigned)luaL_optinteger(L, a, (lua_Integer)(d)))
#define luaL_checkint(L, n) ((int)luaL_checkinteger(L, (n)))
#define luaL_optint(L, n, d) ((int)luaL_optinteger(L, (n), (d)))
#define luaL_checkint(L, n) ((int)luaL_checkinteger(L, (n)))
#define luaL_optint(L, n, d) ((int)luaL_optinteger(L, (n), (d)))
#define luaL_checklong(L, n) ((long)luaL_checkinteger(L, (n)))
#define luaL_optlong(L, n, d) ((long)luaL_optinteger(L, (n), (d)))

View file

@ -52,7 +52,7 @@ typedef enum BinOpr {
} BinOpr;
/* true if operation is foldable (that is, it is arithmetic or bitwise) */
#define foldbinop(op) ((op) <= OPR_SHR)
#define foldbinop(op) ((op) <= OPR_SHR)
#define luaK_codeABC(fs, o, a, b, c) luaK_codeABCk(fs, o, a, b, c, 0)
@ -63,11 +63,11 @@ typedef enum UnOpr { OPR_MINUS,
OPR_NOUNOPR } UnOpr;
/* get (pointer to) instruction of given 'expdesc' */
#define getinstruction(fs, e) ((fs)->f->code[(e)->u.info])
#define getinstruction(fs, e) ((fs)->f->code[(e)->u.info])
#define luaK_setmultret(fs, e) luaK_setreturns(fs, e, LUA_MULTRET)
#define luaK_jumpto(fs, t) luaK_patchlist(fs, luaK_jump(fs), t)
#define luaK_jumpto(fs, t) luaK_patchlist(fs, luaK_jump(fs), t)
LUAI_FUNC int luaK_code(FuncState *fs, Instruction i);
LUAI_FUNC int luaK_codeABx(FuncState *fs, OpCode o, int A, unsigned int Bx);

View file

@ -33,13 +33,13 @@
#include "llimits.h"
#define ALPHABIT 0
#define DIGITBIT 1
#define PRINTBIT 2
#define SPACEBIT 3
#define XDIGITBIT 4
#define ALPHABIT 0
#define DIGITBIT 1
#define PRINTBIT 2
#define SPACEBIT 3
#define XDIGITBIT 4
#define MASK(B) (1 << (B))
#define MASK(B) (1 << (B))
/*
** add 1 to char to allow index -1 (EOZ)
@ -49,12 +49,12 @@
/*
** 'lalpha' (Lua alphabetic) and 'lalnum' (Lua alphanumeric) both include '_'
*/
#define lislalpha(c) testprop(c, MASK(ALPHABIT))
#define lislalnum(c) testprop(c, (MASK(ALPHABIT) | MASK(DIGITBIT)))
#define lisdigit(c) testprop(c, MASK(DIGITBIT))
#define lisspace(c) testprop(c, MASK(SPACEBIT))
#define lisprint(c) testprop(c, MASK(PRINTBIT))
#define lisxdigit(c) testprop(c, MASK(XDIGITBIT))
#define lislalpha(c) testprop(c, MASK(ALPHABIT))
#define lislalnum(c) testprop(c, (MASK(ALPHABIT) | MASK(DIGITBIT)))
#define lisdigit(c) testprop(c, MASK(DIGITBIT))
#define lisspace(c) testprop(c, MASK(SPACEBIT))
#define lisprint(c) testprop(c, MASK(PRINTBIT))
#define lisxdigit(c) testprop(c, MASK(XDIGITBIT))
/*
** In ASCII, this 'ltolower' is correct for alphabetic characters and
@ -84,7 +84,7 @@ LUAI_DDEC(const lu_byte luai_ctype_[UCHAR_MAX + 2];)
#define lisprint(c) (isprint(c))
#define lisxdigit(c) (isxdigit(c))
#define ltolower(c) (tolower(c))
#define ltolower(c) (tolower(c))
#endif /* } */

View file

@ -9,10 +9,10 @@
#include "lstate.h"
#define pcRel(pc, p) (cast_int((pc) - (p)->code) - 1)
#define pcRel(pc, p) (cast_int((pc) - (p)->code) - 1)
/* Active Lua function (given call info) */
#define ci_func(ci) (clLvalue(s2v((ci)->func)))
#define ci_func(ci) (clLvalue(s2v((ci)->func)))
#define resethookcount(L) (L->hookcount = L->basehookcount)
@ -20,7 +20,7 @@
** mark for entries in 'lineinfo' array that has absolute information in
** 'abslineinfo' array
*/
#define ABSLINEINFO (-0x80)
#define ABSLINEINFO (-0x80)
/*
** MAXimum number of successive Instructions WiTHout ABSolute line

View file

@ -32,8 +32,8 @@
/* In general, 'pre'/'pos' are empty (nothing to save) */
#define luaD_checkstack(L, n) luaD_checkstackaux(L, n, (void)0, (void)0)
#define savestack(L, p) ((char *)(p) - (char *)L->stack)
#define restorestack(L, n) ((StkId)((char *)L->stack + (n)))
#define savestack(L, p) ((char *)(p) - (char *)L->stack)
#define restorestack(L, n) ((StkId)((char *)L->stack + (n)))
/* macro to check stack size, preserving 'p' */
#define checkstackGCp(L, n, p) \

View file

@ -9,10 +9,10 @@
#include "lobject.h"
#define sizeCclosure(n) (cast_int(offsetof(CClosure, upvalue)) + \
#define sizeCclosure(n) (cast_int(luaport_offsetof(CClosure, upvalue)) + \
cast_int(sizeof(TValue)) * (n))
#define sizeLclosure(n) (cast_int(offsetof(LClosure, upvals)) + \
#define sizeLclosure(n) (cast_int(luaport_offsetof(LClosure, upvals)) + \
cast_int(sizeof(TValue *)) * (n))
/* test whether thread is in 'twups' list */
@ -22,20 +22,20 @@
** maximum number of upvalues in a closure (both C and Lua). (Value
** must fit in a VM register.)
*/
#define MAXUPVAL 255
#define MAXUPVAL 255
#define upisopen(up) ((up)->v != &(up)->u.value)
#define uplevel(up) check_exp(upisopen(up), cast(StkId, (up)->v))
#define uplevel(up) check_exp(upisopen(up), cast(StkId, (up)->v))
/*
** maximum number of misses before giving up the cache of closures
** in prototypes
*/
#define MAXMISS 10
#define MAXMISS 10
/* special status to close upvalues preserving the top of the stack */
#define CLOSEKTOP (-1)
#define CLOSEKTOP (-1)
LUAI_FUNC Proto *luaF_newproto(lua_State *L);
LUAI_FUNC CClosure *luaF_newCclosure(lua_State *L, int nupvals);

View file

@ -66,21 +66,21 @@
** used for object "age" in generational mode. Last bit is used
** by tests.
*/
#define WHITE0BIT 3 /* object is white (type 0) */
#define WHITE1BIT 4 /* object is white (type 1) */
#define BLACKBIT 5 /* object is black */
#define FINALIZEDBIT 6 /* object has been marked for finalization */
#define WHITE0BIT 3 /* object is white (type 0) */
#define WHITE1BIT 4 /* object is white (type 1) */
#define BLACKBIT 5 /* object is black */
#define FINALIZEDBIT 6 /* object has been marked for finalization */
#define TESTBIT 7
#define TESTBIT 7
#define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT)
#define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT)
#define iswhite(x) testbits((x)->marked, WHITEBITS)
#define isblack(x) testbit((x)->marked, BLACKBIT)
#define isgray(x) /* neither white nor black */ \
#define iswhite(x) testbits((x)->marked, WHITEBITS)
#define isblack(x) testbit((x)->marked, BLACKBIT)
#define isgray(x) /* neither white nor black */ \
(!testbits((x)->marked, WHITEBITS | bitmask(BLACKBIT)))
#define tofinalize(x) testbit((x)->marked, FINALIZEDBIT)
#define tofinalize(x) testbit((x)->marked, FINALIZEDBIT)
#define otherwhite(g) ((g)->currentwhite ^ WHITEBITS)
#define isdeadm(ow, m) ((m) & (ow))
@ -93,41 +93,41 @@
#define luaC_white(g) cast_byte((g)->currentwhite &WHITEBITS)
/* object age in generational mode */
#define G_NEW 0 /* created in current cycle */
#define G_SURVIVAL 1 /* created in previous cycle */
#define G_OLD0 2 /* marked old by frw. barrier in this cycle */
#define G_OLD1 3 /* first full cycle as old */
#define G_OLD 4 /* really old object (not to be visited) */
#define G_TOUCHED1 5 /* old object touched this cycle */
#define G_TOUCHED2 6 /* old object touched in previous cycle */
#define G_NEW 0 /* created in current cycle */
#define G_SURVIVAL 1 /* created in previous cycle */
#define G_OLD0 2 /* marked old by frw. barrier in this cycle */
#define G_OLD1 3 /* first full cycle as old */
#define G_OLD 4 /* really old object (not to be visited) */
#define G_TOUCHED1 5 /* old object touched this cycle */
#define G_TOUCHED2 6 /* old object touched in previous cycle */
#define AGEBITS 7 /* all age bits (111) */
#define AGEBITS 7 /* all age bits (111) */
#define getage(o) ((o)->marked & AGEBITS)
#define setage(o, a) ((o)->marked = cast_byte(((o)->marked & (~AGEBITS)) | a))
#define isold(o) (getage(o) > G_SURVIVAL)
#define getage(o) ((o)->marked & AGEBITS)
#define setage(o, a) ((o)->marked = cast_byte(((o)->marked & (~AGEBITS)) | a))
#define isold(o) (getage(o) > G_SURVIVAL)
#define changeage(o, f, t) \
check_exp(getage(o) == (f), (o)->marked ^= ((f) ^ (t)))
/* Default Values for GC parameters */
#define LUAI_GENMAJORMUL 100
#define LUAI_GENMINORMUL 20
#define LUAI_GENMAJORMUL 100
#define LUAI_GENMINORMUL 20
/* wait memory to double before starting new cycle */
#define LUAI_GCPAUSE 200
#define LUAI_GCPAUSE 200
/*
** some gc parameters are stored divided by 4 to allow a maximum value
** up to 1023 in a 'lu_byte'.
*/
#define getgcparam(p) ((p)*4)
#define setgcparam(p, v) ((p) = (v) / 4)
#define getgcparam(p) ((p)*4)
#define setgcparam(p, v) ((p) = (v) / 4)
#define LUAI_GCMUL 100
#define LUAI_GCMUL 100
/* how much to allocate before next GC step (log2) */
#define LUAI_GCSTEPSIZE 13 /* 8 KB */
#define LUAI_GCSTEPSIZE 13 /* 8 KB */
/*
** Check whether the declared GC mode is generational. While in
@ -139,10 +139,10 @@
/*
** Control when GC is running:
*/
#define GCSTPUSR 1 /* bit true when GC stopped by user */
#define GCSTPGC 2 /* bit true when GC stopped by itself */
#define GCSTPCLS 4 /* bit true when closing Lua state */
#define gcrunning(g) ((g)->gcstp == 0)
#define GCSTPUSR 1 /* bit true when GC stopped by user */
#define GCSTPGC 2 /* bit true when GC stopped by itself */
#define GCSTPCLS 4 /* bit true when closing Lua state */
#define gcrunning(g) ((g)->gcstp == 0)
/*
** Does one step of collection when debt becomes positive. 'pre'/'pos'
@ -161,7 +161,7 @@
}
/* more often than not, 'pre'/'pos' are empty */
#define luaC_checkGC(L) luaC_condGC(L, (void)0, (void)0)
#define luaC_checkGC(L) luaC_condGC(L, (void)0, (void)0)
#define luaC_barrier(L, p, v) ( \
(iscollectable(v) && isblack(p) && iswhite(gcvalue(v))) ? \

View file

@ -10,7 +10,7 @@
#define vmdispatch(x) goto *disptab[x];
#define vmcase(l) L_##l:
#define vmcase(l) L_##l:
#define vmbreak \
vmfetch(); \

View file

@ -33,30 +33,30 @@ typedef unsigned char lu_byte;
typedef signed char ls_byte;
/* maximum value for size_t */
#define MAX_SIZET ((size_t)(~(size_t)0))
#define MAX_SIZET ((size_t)(~(size_t)0))
/* maximum size visible for Lua (must be representable in a lua_Integer) */
#define MAX_SIZE (sizeof(size_t) < sizeof(lua_Integer) ? MAX_SIZET : (size_t)(LUA_MAXINTEGER))
#define MAX_SIZE (sizeof(size_t) < sizeof(lua_Integer) ? MAX_SIZET : (size_t)(LUA_MAXINTEGER))
#define MAX_LUMEM ((lu_mem)(~(lu_mem)0))
#define MAX_LUMEM ((lu_mem)(~(lu_mem)0))
#define MAX_LMEM ((l_mem)(MAX_LUMEM >> 1))
#define MAX_LMEM ((l_mem)(MAX_LUMEM >> 1))
#define MAX_INT INT_MAX /* maximum value of an int */
#define MAX_INT INT_MAX /* maximum value of an int */
/*
** floor of the log2 of the maximum signed value for integral type 't'.
** (That is, maximum 'n' such that '2^n' fits in the given signed type.)
*/
#define log2maxs(t) (sizeof(t) * 8 - 2)
#define log2maxs(t) (sizeof(t) * 8 - 2)
/*
** test whether an unsigned value is a power of 2 (or zero)
*/
#define ispow2(x) (((x) & ((x)-1)) == 0)
#define ispow2(x) (((x) & ((x)-1)) == 0)
/* number of chars of a literal string without the ending \0 */
#define LL(x) (sizeof(x) / sizeof(char) - 1)
#define LL(x) (sizeof(x) / sizeof(char) - 1)
/*
** conversion of pointer to unsigned integer:
@ -75,11 +75,11 @@ typedef LUAI_UACINT l_uacInt;
#if defined LUAI_ASSERT
#undef NDEBUG
#include <assert.h>
#define lua_assert(c) assert(c)
#define lua_assert(c) luaport_assert(c)
#endif
#if defined(lua_assert)
#define check_exp(c, e) (lua_assert(c), (e))
#define check_exp(c, e) (lua_assert(c), (e))
/* to avoid problems with conditions too long */
#define lua_longassert(c) ((c) ? (void)0 : lua_assert(0))
#else
@ -103,7 +103,7 @@ typedef LUAI_UACINT l_uacInt;
#endif
/* type casts (a macro highlights casts in the code) */
#define cast(t, exp) ((t)(exp))
#define cast(t, exp) ((t)(exp))
#define cast_void(i) cast(void, (i))
#define cast_voidp(i) cast(void *, (i))

View file

@ -15,14 +15,14 @@
/*
** Extra types for collectable non-values
*/
#define LUA_TUPVAL LUA_NUMTYPES /* upvalues */
#define LUA_TPROTO (LUA_NUMTYPES + 1) /* function prototypes */
#define LUA_TDEADKEY (LUA_NUMTYPES + 2) /* removed keys in tables */
#define LUA_TUPVAL LUA_NUMTYPES /* upvalues */
#define LUA_TPROTO (LUA_NUMTYPES + 1) /* function prototypes */
#define LUA_TDEADKEY (LUA_NUMTYPES + 2) /* removed keys in tables */
/*
** number of all possible types (including LUA_TNONE but excluding DEADKEY)
*/
#define LUA_TOTALTYPES (LUA_TPROTO + 2)
#define LUA_TOTALTYPES (LUA_TPROTO + 2)
/*
** tags for Tagged Values have the following use of bits:
@ -58,21 +58,21 @@ typedef struct TValue {
TValuefields;
} TValue;
#define val_(o) ((o)->value_)
#define valraw(o) (val_(o))
#define val_(o) ((o)->value_)
#define valraw(o) (val_(o))
/* raw type tag of a TValue */
#define rawtt(o) ((o)->tt_)
#define rawtt(o) ((o)->tt_)
/* tag with no variants (bits 0-3) */
#define novariant(t) ((t)&0x0F)
#define novariant(t) ((t)&0x0F)
/* type tag of a TValue (bits 0-3 for tags + variant bits 4-5) */
#define withvariant(t) ((t)&0x3F)
#define ttypetag(o) withvariant(rawtt(o))
#define withvariant(t) ((t)&0x3F)
#define ttypetag(o) withvariant(rawtt(o))
/* type of a TValue */
#define ttype(o) (novariant(rawtt(o)))
#define ttype(o) (novariant(rawtt(o)))
/* Macros to test type */
#define checktag(o, t) (rawtt(o) == (t))
@ -81,7 +81,7 @@ typedef struct TValue {
/* Macros for internal tests */
/* collectable object has the same tag as the original value */
#define righttt(obj) (ttypetag(obj) == gcvalue(obj)->tt)
#define righttt(obj) (ttypetag(obj) == gcvalue(obj)->tt)
/*
** Any value being manipulated by the program either is non
@ -117,13 +117,13 @@ typedef struct TValue {
/* from stack to stack */
#define setobjs2s(L, o1, o2) setobj(L, s2v(o1), s2v(o2))
/* to stack (not from same stack) */
#define setobj2s(L, o1, o2) setobj(L, s2v(o1), o2)
#define setobj2s(L, o1, o2) setobj(L, s2v(o1), o2)
/* from table to same table */
#define setobjt2t setobj
#define setobjt2t setobj
/* to new object */
#define setobj2n setobj
#define setobj2n setobj
/* to table */
#define setobj2t setobj
#define setobj2t setobj
/*
** Entries in a Lua stack. Field 'tbclist' forms a list of all
@ -145,7 +145,7 @@ typedef union StackValue {
typedef StackValue *StkId;
/* convert a 'StackValue' to a 'TValue' */
#define s2v(o) (&(o)->val)
#define s2v(o) (&(o)->val)
/*
** {==================================================================
@ -154,23 +154,23 @@ typedef StackValue *StkId;
*/
/* Standard nil */
#define LUA_VNIL makevariant(LUA_TNIL, 0)
#define LUA_VNIL makevariant(LUA_TNIL, 0)
/* Empty slot (which might be different from a slot containing nil) */
#define LUA_VEMPTY makevariant(LUA_TNIL, 1)
#define LUA_VEMPTY makevariant(LUA_TNIL, 1)
/* Value returned for a key not found in a table (absent key) */
#define LUA_VABSTKEY makevariant(LUA_TNIL, 2)
#define LUA_VABSTKEY makevariant(LUA_TNIL, 2)
/* macro to test for (any kind of) nil */
#define ttisnil(v) checktype((v), LUA_TNIL)
#define ttisnil(v) checktype((v), LUA_TNIL)
/* macro to test for a standard nil */
#define ttisstrictnil(o) checktag((o), LUA_VNIL)
#define ttisstrictnil(o) checktag((o), LUA_VNIL)
#define setnilvalue(obj) settt_(obj, LUA_VNIL)
#define setnilvalue(obj) settt_(obj, LUA_VNIL)
#define isabstkey(v) checktag((v), LUA_VABSTKEY)
#define isabstkey(v) checktag((v), LUA_VABSTKEY)
/*
** macro to detect non-standard nils (used only in assertions)
@ -182,13 +182,13 @@ typedef StackValue *StkId;
** (In any definition, values associated with absent keys must also
** be accepted as empty.)
*/
#define isempty(v) ttisnil(v)
#define isempty(v) ttisnil(v)
/* macro defining a value corresponding to an absent key */
#define ABSTKEYCONSTANT { NULL }, LUA_VABSTKEY
#define ABSTKEYCONSTANT { NULL }, LUA_VABSTKEY
/* mark an entry as empty */
#define setempty(v) settt_(v, LUA_VEMPTY)
#define setempty(v) settt_(v, LUA_VEMPTY)
/* }================================================================== */
@ -198,17 +198,17 @@ typedef StackValue *StkId;
** ===================================================================
*/
#define LUA_VFALSE makevariant(LUA_TBOOLEAN, 0)
#define LUA_VTRUE makevariant(LUA_TBOOLEAN, 1)
#define LUA_VFALSE makevariant(LUA_TBOOLEAN, 0)
#define LUA_VTRUE makevariant(LUA_TBOOLEAN, 1)
#define ttisboolean(o) checktype((o), LUA_TBOOLEAN)
#define ttisfalse(o) checktag((o), LUA_VFALSE)
#define ttistrue(o) checktag((o), LUA_VTRUE)
#define ttisboolean(o) checktype((o), LUA_TBOOLEAN)
#define ttisfalse(o) checktag((o), LUA_VFALSE)
#define ttistrue(o) checktag((o), LUA_VTRUE)
#define l_isfalse(o) (ttisfalse(o) || ttisnil(o))
#define l_isfalse(o) (ttisfalse(o) || ttisnil(o))
#define setbfvalue(obj) settt_(obj, LUA_VFALSE)
#define setbtvalue(obj) settt_(obj, LUA_VTRUE)
#define setbfvalue(obj) settt_(obj, LUA_VFALSE)
#define setbtvalue(obj) settt_(obj, LUA_VTRUE)
/* }================================================================== */
@ -218,11 +218,11 @@ typedef StackValue *StkId;
** ===================================================================
*/
#define LUA_VTHREAD makevariant(LUA_TTHREAD, 0)
#define LUA_VTHREAD makevariant(LUA_TTHREAD, 0)
#define ttisthread(o) checktag((o), ctb(LUA_VTHREAD))
#define ttisthread(o) checktag((o), ctb(LUA_VTHREAD))
#define thvalue(o) check_exp(ttisthread(o), gco2th(val_(o).gc))
#define thvalue(o) check_exp(ttisthread(o), gco2th(val_(o).gc))
#define setthvalue(L, obj, x) \
{ \
@ -260,14 +260,14 @@ typedef struct GCObject {
/* Bit mark for collectable types */
#define BIT_ISCOLLECTABLE (1 << 6)
#define iscollectable(o) (rawtt(o) & BIT_ISCOLLECTABLE)
#define iscollectable(o) (rawtt(o) & BIT_ISCOLLECTABLE)
/* mark a tag as collectable */
#define ctb(t) ((t) | BIT_ISCOLLECTABLE)
#define ctb(t) ((t) | BIT_ISCOLLECTABLE)
#define gcvalue(o) check_exp(iscollectable(o), val_(o).gc)
#define gcvalue(o) check_exp(iscollectable(o), val_(o).gc)
#define gcvalueraw(v) ((v).gc)
#define gcvalueraw(v) ((v).gc)
#define setgcovalue(L, obj, x) \
{ \
@ -286,17 +286,17 @@ typedef struct GCObject {
*/
/* Variant tags for numbers */
#define LUA_VNUMINT makevariant(LUA_TNUMBER, 0) /* integer numbers */
#define LUA_VNUMFLT makevariant(LUA_TNUMBER, 1) /* float numbers */
#define LUA_VNUMINT makevariant(LUA_TNUMBER, 0) /* integer numbers */
#define LUA_VNUMFLT makevariant(LUA_TNUMBER, 1) /* float numbers */
#define ttisnumber(o) checktype((o), LUA_TNUMBER)
#define ttisfloat(o) checktag((o), LUA_VNUMFLT)
#define ttisinteger(o) checktag((o), LUA_VNUMINT)
#define nvalue(o) check_exp(ttisnumber(o), \
#define nvalue(o) check_exp(ttisnumber(o), \
(ttisinteger(o) ? cast_num(ivalue(o)) : fltvalue(o)))
#define fltvalue(o) check_exp(ttisfloat(o), val_(o).n)
#define ivalue(o) check_exp(ttisinteger(o), val_(o).i)
#define fltvalue(o) check_exp(ttisfloat(o), val_(o).n)
#define ivalue(o) check_exp(ttisinteger(o), val_(o).i)
#define fltvalueraw(v) ((v).n)
#define ivalueraw(v) ((v).i)
@ -338,16 +338,16 @@ typedef struct GCObject {
*/
/* Variant tags for strings */
#define LUA_VSHRSTR makevariant(LUA_TSTRING, 0) /* short strings */
#define LUA_VLNGSTR makevariant(LUA_TSTRING, 1) /* long strings */
#define LUA_VSHRSTR makevariant(LUA_TSTRING, 0) /* short strings */
#define LUA_VLNGSTR makevariant(LUA_TSTRING, 1) /* long strings */
#define ttisstring(o) checktype((o), LUA_TSTRING)
#define ttisshrstring(o) checktag((o), ctb(LUA_VSHRSTR))
#define ttislngstring(o) checktag((o), ctb(LUA_VLNGSTR))
#define tsvalueraw(v) (gco2ts((v).gc))
#define tsvalueraw(v) (gco2ts((v).gc))
#define tsvalue(o) check_exp(ttisstring(o), gco2ts(val_(o).gc))
#define tsvalue(o) check_exp(ttisstring(o), gco2ts(val_(o).gc))
#define setsvalue(L, obj, x) \
{ \
@ -362,7 +362,7 @@ typedef struct GCObject {
#define setsvalue2s(L, o, s) setsvalue(L, s2v(o), s)
/* set a string to a new object */
#define setsvalue2n setsvalue
#define setsvalue2n setsvalue
/*
** Header for a string value.
@ -382,16 +382,16 @@ typedef struct TString {
/*
** Get the actual string (array of bytes) from a 'TString'.
*/
#define getstr(ts) ((ts)->contents)
#define getstr(ts) ((ts)->contents)
/* get the actual string (array of bytes) from a Lua value */
#define svalue(o) getstr(tsvalue(o))
#define svalue(o) getstr(tsvalue(o))
/* get string length from 'TString *s' */
#define tsslen(s) ((s)->tt == LUA_VSHRSTR ? (s)->shrlen : (s)->u.lnglen)
#define tsslen(s) ((s)->tt == LUA_VSHRSTR ? (s)->shrlen : (s)->u.lnglen)
/* get string length from 'TValue *o' */
#define vslen(o) tsslen(tsvalue(o))
#define vslen(o) tsslen(tsvalue(o))
/* }================================================================== */
@ -405,17 +405,17 @@ typedef struct TString {
** Light userdata should be a variant of userdata, but for compatibility
** reasons they are also different types.
*/
#define LUA_VLIGHTUSERDATA makevariant(LUA_TLIGHTUSERDATA, 0)
#define LUA_VLIGHTUSERDATA makevariant(LUA_TLIGHTUSERDATA, 0)
#define LUA_VUSERDATA makevariant(LUA_TUSERDATA, 0)
#define LUA_VUSERDATA makevariant(LUA_TUSERDATA, 0)
#define ttislightuserdata(o) checktag((o), LUA_VLIGHTUSERDATA)
#define ttisfulluserdata(o) checktag((o), ctb(LUA_VUSERDATA))
#define pvalue(o) check_exp(ttislightuserdata(o), val_(o).p)
#define uvalue(o) check_exp(ttisfulluserdata(o), gco2u(val_(o).gc))
#define pvalue(o) check_exp(ttislightuserdata(o), val_(o).p)
#define uvalue(o) check_exp(ttisfulluserdata(o), gco2u(val_(o).gc))
#define pvalueraw(v) ((v).p)
#define pvalueraw(v) ((v).p)
#define setpvalue(obj, x) \
{ \
@ -473,10 +473,10 @@ typedef struct Udata0 {
/* compute the offset of the memory area of a userdata */
#define udatamemoffset(nuv) \
((nuv) == 0 ? offsetof(Udata0, bindata) : offsetof(Udata, uv) + (sizeof(UValue) * (nuv)))
((nuv) == 0 ? luaport_offsetof(Udata0, bindata) : luaport_offsetof(Udata, uv) + (sizeof(UValue) * (nuv)))
/* get the address of the memory block inside 'Udata' */
#define getudatamem(u) (cast_charp(u) + udatamemoffset((u)->nuvalue))
#define getudatamem(u) (cast_charp(u) + udatamemoffset((u)->nuvalue))
/* compute the size of a userdata */
#define sizeudata(nuv, nb) (udatamemoffset(nuv) + (nb))
@ -489,7 +489,7 @@ typedef struct Udata0 {
** ===================================================================
*/
#define LUA_VPROTO makevariant(LUA_TPROTO, 0)
#define LUA_VPROTO makevariant(LUA_TPROTO, 0)
/*
** Description of an upvalue for function prototypes
@ -562,12 +562,12 @@ typedef struct Proto {
** ===================================================================
*/
#define LUA_VUPVAL makevariant(LUA_TUPVAL, 0)
#define LUA_VUPVAL makevariant(LUA_TUPVAL, 0)
/* Variant tags for functions */
#define LUA_VLCL makevariant(LUA_TFUNCTION, 0) /* Lua closure */
#define LUA_VLCF makevariant(LUA_TFUNCTION, 1) /* light C function */
#define LUA_VCCL makevariant(LUA_TFUNCTION, 2) /* C closure */
#define LUA_VLCL makevariant(LUA_TFUNCTION, 0) /* Lua closure */
#define LUA_VLCF makevariant(LUA_TFUNCTION, 1) /* light C function */
#define LUA_VCCL makevariant(LUA_TFUNCTION, 2) /* C closure */
#define ttisfunction(o) checktype(o, LUA_TFUNCTION)
#define ttisLclosure(o) checktag((o), ctb(LUA_VLCL))
@ -575,14 +575,14 @@ typedef struct Proto {
#define ttisCclosure(o) checktag((o), ctb(LUA_VCCL))
#define ttisclosure(o) (ttisLclosure(o) || ttisCclosure(o))
#define isLfunction(o) ttisLclosure(o)
#define isLfunction(o) ttisLclosure(o)
#define clvalue(o) check_exp(ttisclosure(o), gco2cl(val_(o).gc))
#define clLvalue(o) check_exp(ttisLclosure(o), gco2lcl(val_(o).gc))
#define fvalue(o) check_exp(ttislcf(o), val_(o).f)
#define clCvalue(o) check_exp(ttisCclosure(o), gco2ccl(val_(o).gc))
#define clvalue(o) check_exp(ttisclosure(o), gco2cl(val_(o).gc))
#define clLvalue(o) check_exp(ttisLclosure(o), gco2lcl(val_(o).gc))
#define fvalue(o) check_exp(ttislcf(o), val_(o).f)
#define clCvalue(o) check_exp(ttisCclosure(o), gco2ccl(val_(o).gc))
#define fvalueraw(v) ((v).f)
#define fvalueraw(v) ((v).f)
#define setclLvalue(L, obj, x) \
{ \
@ -649,7 +649,7 @@ typedef union Closure {
LClosure l;
} Closure;
#define getproto(o) (clLvalue(o)->p)
#define getproto(o) (clLvalue(o)->p)
/* }================================================================== */
@ -659,11 +659,11 @@ typedef union Closure {
** ===================================================================
*/
#define LUA_VTABLE makevariant(LUA_TTABLE, 0)
#define LUA_VTABLE makevariant(LUA_TTABLE, 0)
#define ttistable(o) checktag((o), ctb(LUA_VTABLE))
#define hvalue(o) check_exp(ttistable(o), gco2t(val_(o).gc))
#define hvalue(o) check_exp(ttistable(o), gco2t(val_(o).gc))
#define sethvalue(L, obj, x) \
{ \
@ -740,21 +740,21 @@ typedef struct Table {
/*
** Macros to manipulate keys inserted in nodes
*/
#define keytt(node) ((node)->u.key_tt)
#define keyval(node) ((node)->u.key_val)
#define keytt(node) ((node)->u.key_tt)
#define keyval(node) ((node)->u.key_val)
#define keyisnil(node) (keytt(node) == LUA_TNIL)
#define keyisinteger(node) (keytt(node) == LUA_VNUMINT)
#define keyival(node) (keyval(node).i)
#define keyisshrstr(node) (keytt(node) == ctb(LUA_VSHRSTR))
#define keystrval(node) (gco2ts(keyval(node).gc))
#define keyisnil(node) (keytt(node) == LUA_TNIL)
#define keyisinteger(node) (keytt(node) == LUA_VNUMINT)
#define keyival(node) (keyval(node).i)
#define keyisshrstr(node) (keytt(node) == ctb(LUA_VSHRSTR))
#define keystrval(node) (gco2ts(keyval(node).gc))
#define setnilkey(node) (keytt(node) = LUA_TNIL)
#define setnilkey(node) (keytt(node) = LUA_TNIL)
#define keyiscollectable(n) (keytt(n) & BIT_ISCOLLECTABLE)
#define gckey(n) (keyval(n).gc)
#define gckeyN(n) (keyiscollectable(n) ? gckey(n) : NULL)
#define gckey(n) (keyval(n).gc)
#define gckeyN(n) (keyiscollectable(n) ? gckey(n) : NULL)
/*
** Dead keys in tables have the tag DEADKEY but keep their original
@ -762,8 +762,8 @@ typedef struct Table {
** be found when searched in a special way. ('next' needs that to find
** keys removed from a table during a traversal.)
*/
#define setdeadkey(node) (keytt(node) = LUA_TDEADKEY)
#define keyisdead(node) (keytt(node) == LUA_TDEADKEY)
#define setdeadkey(node) (keytt(node) = LUA_TDEADKEY)
#define keyisdead(node) (keytt(node) == LUA_TDEADKEY)
/* }================================================================== */
@ -777,7 +777,7 @@ typedef struct Table {
#define sizenode(t) (twoto((t)->lsizenode))
/* size of buffer for 'luaO_utf8esc' function */
#define UTF8BUFFSZ 8
#define UTF8BUFFSZ 8
LUAI_FUNC int luaO_utf8esc(char *buff, unsigned long x);
LUAI_FUNC int luaO_ceillog2(unsigned int x);

View file

@ -36,27 +36,27 @@ enum OpMode { iABC,
/*
** size and position of opcode arguments.
*/
#define SIZE_C 8
#define SIZE_B 8
#define SIZE_Bx (SIZE_C + SIZE_B + 1)
#define SIZE_A 8
#define SIZE_Ax (SIZE_Bx + SIZE_A)
#define SIZE_sJ (SIZE_Bx + SIZE_A)
#define SIZE_C 8
#define SIZE_B 8
#define SIZE_Bx (SIZE_C + SIZE_B + 1)
#define SIZE_A 8
#define SIZE_Ax (SIZE_Bx + SIZE_A)
#define SIZE_sJ (SIZE_Bx + SIZE_A)
#define SIZE_OP 7
#define SIZE_OP 7
#define POS_OP 0
#define POS_OP 0
#define POS_A (POS_OP + SIZE_OP)
#define POS_k (POS_A + SIZE_A)
#define POS_B (POS_k + 1)
#define POS_C (POS_B + SIZE_B)
#define POS_A (POS_OP + SIZE_OP)
#define POS_k (POS_A + SIZE_A)
#define POS_B (POS_k + 1)
#define POS_C (POS_B + SIZE_B)
#define POS_Bx POS_k
#define POS_Bx POS_k
#define POS_Ax POS_A
#define POS_Ax POS_A
#define POS_sJ POS_A
#define POS_sJ POS_A
/*
** limits for opcode arguments.
@ -87,21 +87,21 @@ enum OpMode { iABC,
#define MAXARG_sJ MAX_INT
#endif
#define OFFSET_sJ (MAXARG_sJ >> 1)
#define OFFSET_sJ (MAXARG_sJ >> 1)
#define MAXARG_A ((1 << SIZE_A) - 1)
#define MAXARG_B ((1 << SIZE_B) - 1)
#define MAXARG_C ((1 << SIZE_C) - 1)
#define OFFSET_sC (MAXARG_C >> 1)
#define MAXARG_A ((1 << SIZE_A) - 1)
#define MAXARG_B ((1 << SIZE_B) - 1)
#define MAXARG_C ((1 << SIZE_C) - 1)
#define OFFSET_sC (MAXARG_C >> 1)
#define int2sC(i) ((i) + OFFSET_sC)
#define sC2int(i) ((i)-OFFSET_sC)
#define int2sC(i) ((i) + OFFSET_sC)
#define sC2int(i) ((i)-OFFSET_sC)
/* creates a mask with 'n' 1 bits at position 'p' */
#define MASK1(n, p) ((~((~(Instruction)0) << (n))) << (p))
#define MASK1(n, p) ((~((~(Instruction)0) << (n))) << (p))
/* creates a mask with 'n' 0 bits at position 'p' */
#define MASK0(n, p) (~MASK1(n, p))
#define MASK0(n, p) (~MASK1(n, p))
/*
** the following macros help to manipulate instructions
@ -111,26 +111,26 @@ enum OpMode { iABC,
#define SET_OPCODE(i, o) ((i) = (((i)&MASK0(SIZE_OP, POS_OP)) | \
((cast(Instruction, o) << POS_OP) & MASK1(SIZE_OP, POS_OP))))
#define checkopm(i, m) (getOpMode(GET_OPCODE(i)) == m)
#define checkopm(i, m) (getOpMode(GET_OPCODE(i)) == m)
#define getarg(i, pos, size) (cast_int(((i) >> (pos)) & MASK1(size, 0)))
#define setarg(i, v, pos, size) ((i) = (((i)&MASK0(size, pos)) | \
((cast(Instruction, v) << pos) & MASK1(size, pos))))
#define GETARG_A(i) getarg(i, POS_A, SIZE_A)
#define SETARG_A(i, v) setarg(i, v, POS_A, SIZE_A)
#define GETARG_A(i) getarg(i, POS_A, SIZE_A)
#define SETARG_A(i, v) setarg(i, v, POS_A, SIZE_A)
#define GETARG_B(i) check_exp(checkopm(i, iABC), getarg(i, POS_B, SIZE_B))
#define GETARG_sB(i) sC2int(GETARG_B(i))
#define SETARG_B(i, v) setarg(i, v, POS_B, SIZE_B)
#define GETARG_B(i) check_exp(checkopm(i, iABC), getarg(i, POS_B, SIZE_B))
#define GETARG_sB(i) sC2int(GETARG_B(i))
#define SETARG_B(i, v) setarg(i, v, POS_B, SIZE_B)
#define GETARG_C(i) check_exp(checkopm(i, iABC), getarg(i, POS_C, SIZE_C))
#define GETARG_sC(i) sC2int(GETARG_C(i))
#define SETARG_C(i, v) setarg(i, v, POS_C, SIZE_C)
#define GETARG_C(i) check_exp(checkopm(i, iABC), getarg(i, POS_C, SIZE_C))
#define GETARG_sC(i) sC2int(GETARG_C(i))
#define SETARG_C(i, v) setarg(i, v, POS_C, SIZE_C)
#define TESTARG_k(i) check_exp(checkopm(i, iABC), (cast_int(((i) & (1u << POS_k)))))
#define GETARG_k(i) check_exp(checkopm(i, iABC), getarg(i, POS_k, 1))
#define SETARG_k(i, v) setarg(i, v, POS_k, 1)
#define TESTARG_k(i) check_exp(checkopm(i, iABC), (cast_int(((i) & (1u << POS_k)))))
#define GETARG_k(i) check_exp(checkopm(i, iABC), getarg(i, POS_k, 1))
#define SETARG_k(i, v) setarg(i, v, POS_k, 1)
#define GETARG_Bx(i) check_exp(checkopm(i, iABx), getarg(i, POS_Bx, SIZE_Bx))
#define SETARG_Bx(i, v) setarg(i, v, POS_Bx, SIZE_Bx)
@ -149,11 +149,11 @@ enum OpMode { iABC,
#define CREATE_ABCk(o, a, b, c, k) ((cast(Instruction, o) << POS_OP) | (cast(Instruction, a) << POS_A) | (cast(Instruction, b) << POS_B) | (cast(Instruction, c) << POS_C) | (cast(Instruction, k) << POS_k))
#define CREATE_ABx(o, a, bc) ((cast(Instruction, o) << POS_OP) | (cast(Instruction, a) << POS_A) | (cast(Instruction, bc) << POS_Bx))
#define CREATE_ABx(o, a, bc) ((cast(Instruction, o) << POS_OP) | (cast(Instruction, a) << POS_A) | (cast(Instruction, bc) << POS_Bx))
#define CREATE_Ax(o, a) ((cast(Instruction, o) << POS_OP) | (cast(Instruction, a) << POS_Ax))
#define CREATE_Ax(o, a) ((cast(Instruction, o) << POS_OP) | (cast(Instruction, a) << POS_Ax))
#define CREATE_sJ(o, j, k) ((cast(Instruction, o) << POS_OP) | (cast(Instruction, j) << POS_sJ) | (cast(Instruction, k) << POS_k))
#define CREATE_sJ(o, j, k) ((cast(Instruction, o) << POS_OP) | (cast(Instruction, j) << POS_sJ) | (cast(Instruction, k) << POS_k))
#if !defined(MAXINDEXRK) /* (for debugging only) */
#define MAXINDEXRK MAXARG_B

View file

@ -98,13 +98,13 @@
#define getCcalls(L) ((L)->nCcalls & 0xffff)
/* Increment the number of non-yieldable calls */
#define incnny(L) ((L)->nCcalls += 0x10000)
#define incnny(L) ((L)->nCcalls += 0x10000)
/* Decrement the number of non-yieldable calls */
#define decnny(L) ((L)->nCcalls -= 0x10000)
#define decnny(L) ((L)->nCcalls -= 0x10000)
/* Non-yieldable call increment */
#define nyci (0x10000 | 1)
#define nyci (0x10000 | 1)
struct lua_longjmp; /* defined in ldo.c */
@ -113,8 +113,9 @@ struct lua_longjmp; /* defined in ldo.c */
** is thread safe
*/
#if !defined(l_signalT)
#include <signal.h>
#define l_signalT sig_atomic_t
// #include <signal.h>
// #define l_signalT sig_atomic_t
#define l_signalT int
#endif
/*
@ -124,15 +125,15 @@ struct lua_longjmp; /* defined in ldo.c */
** there will be a stack check soon after the push. Function frames
** never use this extra space, so it does not need to be kept clean.
*/
#define EXTRA_STACK 5
#define EXTRA_STACK 5
#define BASIC_STACK_SIZE (2 * LUA_MINSTACK)
#define stacksize(th) cast_int((th)->stack_last - (th)->stack)
#define stacksize(th) cast_int((th)->stack_last - (th)->stack)
/* kinds of Garbage Collection */
#define KGC_INC 0 /* incremental gc */
#define KGC_GEN 1 /* generational gc */
#define KGC_INC 0 /* incremental gc */
#define KGC_GEN 1 /* generational gc */
typedef struct stringtable {
TString **hash;
@ -198,7 +199,7 @@ typedef struct CallInfo {
#define CIST_TRAN (1 << 8) /* 'ci' has transfer information */
#define CIST_CLSRET (1 << 9) /* function is closing tbc variables */
/* Bits 10-12 are used for CIST_RECST (see below) */
#define CIST_RECST 10
#define CIST_RECST 10
#if defined(LUA_COMPAT_LT_LE)
#define CIST_LEQ (1 << 13) /* using __lt for __le */
#endif
@ -215,7 +216,7 @@ typedef struct CallInfo {
((ci)->callstatus = ((ci)->callstatus & ~(7 << CIST_RECST)) | ((st) << CIST_RECST)))
/* active function is a Lua function */
#define isLua(ci) (!((ci)->callstatus & CIST_C))
#define isLua(ci) (!((ci)->callstatus & CIST_C))
/* call is running Lua code (not a hook) */
#define isLuacode(ci) (!((ci)->callstatus & (CIST_C | CIST_HOOKED)))
@ -306,7 +307,7 @@ struct lua_State {
volatile l_signalT hookmask;
};
#define G(L) (L->l_G)
#define G(L) (L->l_G)
/*
** 'g->nilvalue' being a nil value flags that the state was completely
@ -349,16 +350,16 @@ union GCUnion {
#define gco2ccl(o) check_exp((o)->tt == LUA_VCCL, &((cast_u(o))->cl.c))
#define gco2cl(o) \
check_exp(novariant((o)->tt) == LUA_TFUNCTION, &((cast_u(o))->cl))
#define gco2t(o) check_exp((o)->tt == LUA_VTABLE, &((cast_u(o))->h))
#define gco2p(o) check_exp((o)->tt == LUA_VPROTO, &((cast_u(o))->p))
#define gco2th(o) check_exp((o)->tt == LUA_VTHREAD, &((cast_u(o))->th))
#define gco2upv(o) check_exp((o)->tt == LUA_VUPVAL, &((cast_u(o))->upv))
#define gco2t(o) check_exp((o)->tt == LUA_VTABLE, &((cast_u(o))->h))
#define gco2p(o) check_exp((o)->tt == LUA_VPROTO, &((cast_u(o))->p))
#define gco2th(o) check_exp((o)->tt == LUA_VTHREAD, &((cast_u(o))->th))
#define gco2upv(o) check_exp((o)->tt == LUA_VUPVAL, &((cast_u(o))->upv))
/*
** macro to convert a Lua object into a GCObject
** (The access to 'tt' tries to ensure that 'v' is actually a Lua object.)
*/
#define obj2gco(v) check_exp((v)->tt >= LUA_TSTRING, &(cast_u(v)->gc))
#define obj2gco(v) check_exp((v)->tt >= LUA_TSTRING, &(cast_u(v)->gc))
/* actual number of total bytes allocated */
#define gettotalbytes(g) cast(lu_mem, (g)->totalbytes + (g)->GCdebt)

View file

@ -15,13 +15,13 @@
** Memory-allocation error message must be preallocated (it cannot
** be created after memory is exhausted)
*/
#define MEMERRMSG "not enough memory"
#define MEMERRMSG "not enough memory"
/*
** Size of a TString: Size of the header plus space for the string
** itself (including final '\0').
*/
#define sizelstring(l) (offsetof(TString, contents) + ((l) + 1) * sizeof(char))
#define sizelstring(l) (luaport_offsetof(TString, contents) + ((l) + 1) * sizeof(char))
#define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \
(sizeof(s) / sizeof(char)) - 1))
@ -29,7 +29,7 @@
/*
** test whether a string is a reserved word
*/
#define isreserved(s) ((s)->tt == LUA_VSHRSTR && (s)->extra > 0)
#define isreserved(s) ((s)->tt == LUA_VSHRSTR && (s)->extra > 0)
/*
** equality for short strings, which are always internalized

View file

@ -9,9 +9,9 @@
#include "lobject.h"
#define gnode(t, i) (&(t)->node[i])
#define gval(n) (&(n)->i_val)
#define gnext(n) ((n)->u.next)
#define gnode(t, i) (&(t)->node[i])
#define gval(n) (&(n)->i_val)
#define gnext(n) ((n)->u.next)
/*
** Clear all bits of fast-access metamethods, which means that the table
@ -21,13 +21,13 @@
#define invalidateTMcache(t) ((t)->flags &= ~maskflags)
/* true when 't' is using 'dummynode' as its hash part */
#define isdummy(t) ((t)->lastfree == NULL)
#define isdummy(t) ((t)->lastfree == NULL)
/* allocated size for hash nodes */
#define allocsizenode(t) (isdummy(t) ? 0 : sizenode(t))
#define allocsizenode(t) (isdummy(t) ? 0 : sizenode(t))
/* returns the Node, given the value of a table entry */
#define nodefromval(v) cast(Node *, (v))
#define nodefromval(v) cast(Node *, (v))
LUAI_FUNC const TValue *luaH_getint(Table *t, lua_Integer key);
LUAI_FUNC void luaH_setint(lua_State *L, Table *t, lua_Integer key,

View file

@ -48,13 +48,13 @@ typedef enum {
** corresponding metamethod field. (Bit 7 of the flag is used for
** 'isrealasize'.)
*/
#define maskflags (~(~0u << (TM_EQ + 1)))
#define maskflags (~(~0u << (TM_EQ + 1)))
/*
** Test whether there is no tagmethod.
** (Because tagmethods use raw accesses, the result may be an "empty" nil.)
*/
#define notm(tm) ttisnil(tm)
#define notm(tm) ttisnil(tm)
#define gfasttm(g, et, e) ((et) == NULL ? NULL : \
((et)->flags & (1u << (e))) ? NULL : \
@ -62,7 +62,7 @@ typedef enum {
#define fasttm(l, et, e) gfasttm(G(l), et, e)
#define ttypename(x) luaT_typenames_[(x) + 1]
#define ttypename(x) luaT_typenames_[(x) + 1]
LUAI_DDEC(const char *const luaT_typenames_[LUA_TOTALTYPES];)

View file

@ -13,61 +13,61 @@
#include "luaconf.h"
#define LUA_VERSION_MAJOR "5"
#define LUA_VERSION_MINOR "4"
#define LUA_VERSION_RELEASE "4"
#define LUA_VERSION_MAJOR "5"
#define LUA_VERSION_MINOR "4"
#define LUA_VERSION_RELEASE "4"
#define LUA_VERSION_NUM 504
#define LUA_VERSION_RELEASE_NUM (LUA_VERSION_NUM * 100 + 4)
#define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR
#define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE
#define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2022 Lua.org, PUC-Rio"
#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo, W. Celes"
#define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR
#define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE
#define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2022 Lua.org, PUC-Rio"
#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo, W. Celes"
/* mark for precompiled code ('<esc>Lua') */
#define LUA_SIGNATURE "\x1bLua"
#define LUA_SIGNATURE "\x1bLua"
/* option for multiple returns in 'lua_pcall' and 'lua_call' */
#define LUA_MULTRET (-1)
#define LUA_MULTRET (-1)
/*
** Pseudo-indices
** (-LUAI_MAXSTACK is the minimum valid index; we keep some free empty
** space after that to help overflow detection)
*/
#define LUA_REGISTRYINDEX (-LUAI_MAXSTACK - 1000)
#define lua_upvalueindex(i) (LUA_REGISTRYINDEX - (i))
#define LUA_REGISTRYINDEX (-LUAI_MAXSTACK - 1000)
#define lua_upvalueindex(i) (LUA_REGISTRYINDEX - (i))
/* thread status */
#define LUA_OK 0
#define LUA_YIELD 1
#define LUA_ERRRUN 2
#define LUA_ERRSYNTAX 3
#define LUA_ERRMEM 4
#define LUA_ERRERR 5
#define LUA_OK 0
#define LUA_YIELD 1
#define LUA_ERRRUN 2
#define LUA_ERRSYNTAX 3
#define LUA_ERRMEM 4
#define LUA_ERRERR 5
typedef struct lua_State lua_State;
/*
** basic types
*/
#define LUA_TNONE (-1)
#define LUA_TNONE (-1)
#define LUA_TNIL 0
#define LUA_TBOOLEAN 1
#define LUA_TLIGHTUSERDATA 2
#define LUA_TNUMBER 3
#define LUA_TSTRING 4
#define LUA_TTABLE 5
#define LUA_TFUNCTION 6
#define LUA_TUSERDATA 7
#define LUA_TTHREAD 8
#define LUA_TNIL 0
#define LUA_TBOOLEAN 1
#define LUA_TLIGHTUSERDATA 2
#define LUA_TNUMBER 3
#define LUA_TSTRING 4
#define LUA_TTABLE 5
#define LUA_TFUNCTION 6
#define LUA_TUSERDATA 7
#define LUA_TTHREAD 8
#define LUA_NUMTYPES 9
#define LUA_NUMTYPES 9
/* minimum Lua stack available to a C function */
#define LUA_MINSTACK 20
#define LUA_MINSTACK 20
/* predefined values in the registry */
#define LUA_RIDX_MAINTHREAD 1
@ -322,18 +322,18 @@ LUA_API void(lua_closeslot)(lua_State *L, int idx);
** ===============================================================
*/
#define lua_getextraspace(L) ((void *)((char *)(L)-LUA_EXTRASPACE))
#define lua_getextraspace(L) ((void *)((char *)(L)-LUA_EXTRASPACE))
#define lua_tonumber(L, i) lua_tonumberx(L, (i), NULL)
#define lua_tointeger(L, i) lua_tointegerx(L, (i), NULL)
#define lua_tonumber(L, i) lua_tonumberx(L, (i), NULL)
#define lua_tointeger(L, i) lua_tointegerx(L, (i), NULL)
#define lua_pop(L, n) lua_settop(L, -(n)-1)
#define lua_pop(L, n) lua_settop(L, -(n)-1)
#define lua_newtable(L) lua_createtable(L, 0, 0)
#define lua_newtable(L) lua_createtable(L, 0, 0)
#define lua_register(L, n, f) (lua_pushcfunction(L, (f)), lua_setglobal(L, (n)))
#define lua_register(L, n, f) (lua_pushcfunction(L, (f)), lua_setglobal(L, (n)))
#define lua_pushcfunction(L, f) lua_pushcclosure(L, (f), 0)
#define lua_pushcfunction(L, f) lua_pushcclosure(L, (f), 0)
#define lua_isfunction(L, n) (lua_type(L, (n)) == LUA_TFUNCTION)
#define lua_istable(L, n) (lua_type(L, (n)) == LUA_TTABLE)
@ -344,16 +344,16 @@ LUA_API void(lua_closeslot)(lua_State *L, int idx);
#define lua_isnone(L, n) (lua_type(L, (n)) == LUA_TNONE)
#define lua_isnoneornil(L, n) (lua_type(L, (n)) <= 0)
#define lua_pushliteral(L, s) lua_pushstring(L, "" s)
#define lua_pushliteral(L, s) lua_pushstring(L, "" s)
#define lua_pushglobaltable(L) \
((void)lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS))
#define lua_tostring(L, i) lua_tolstring(L, (i), NULL)
#define lua_tostring(L, i) lua_tolstring(L, (i), NULL)
#define lua_insert(L, idx) lua_rotate(L, (idx), 1)
#define lua_insert(L, idx) lua_rotate(L, (idx), 1)
#define lua_remove(L, idx) (lua_rotate(L, (idx), -1), lua_pop(L, 1))
#define lua_remove(L, idx) (lua_rotate(L, (idx), -1), lua_pop(L, 1))
#define lua_replace(L, idx) (lua_copy(L, -1, (idx)), lua_pop(L, 1))
@ -376,7 +376,7 @@ LUA_API void(lua_closeslot)(lua_State *L, int idx);
#define lua_getuservalue(L, idx) lua_getiuservalue(L, idx, 1)
#define lua_setuservalue(L, idx) lua_setiuservalue(L, idx, 1)
#define LUA_NUMTAGS LUA_NUMTYPES
#define LUA_NUMTAGS LUA_NUMTYPES
/* }============================================================== */
@ -389,19 +389,19 @@ LUA_API void(lua_closeslot)(lua_State *L, int idx);
/*
** Event codes
*/
#define LUA_HOOKCALL 0
#define LUA_HOOKRET 1
#define LUA_HOOKLINE 2
#define LUA_HOOKCOUNT 3
#define LUA_HOOKTAILCALL 4
#define LUA_HOOKCALL 0
#define LUA_HOOKRET 1
#define LUA_HOOKLINE 2
#define LUA_HOOKCOUNT 3
#define LUA_HOOKTAILCALL 4
/*
** Event masks
*/
#define LUA_MASKCALL (1 << LUA_HOOKCALL)
#define LUA_MASKRET (1 << LUA_HOOKRET)
#define LUA_MASKLINE (1 << LUA_HOOKLINE)
#define LUA_MASKCOUNT (1 << LUA_HOOKCOUNT)
#define LUA_MASKCALL (1 << LUA_HOOKCALL)
#define LUA_MASKRET (1 << LUA_HOOKRET)
#define LUA_MASKLINE (1 << LUA_HOOKLINE)
#define LUA_MASKCOUNT (1 << LUA_HOOKCOUNT)
typedef struct lua_Debug lua_Debug; /* activation record */

View file

@ -0,0 +1,9 @@
// lua.hpp
// Lua header files for C++
// <<extern "C">> not supplied automatically because Lua also compiles as C++
extern "C" {
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
}

View file

@ -12,10 +12,10 @@
#include "lzio.h"
/* data to catch conversion errors */
#define LUAC_DATA "\x19\x93\r\n\x1a\n"
#define LUAC_DATA "\x19\x93\r\n\x1a\n"
#define LUAC_INT 0x5678
#define LUAC_NUM cast_num(370.5)
#define LUAC_INT 0x5678
#define LUAC_NUM cast_num(370.5)
/*
** Encode major-minor version in one byte, one nibble for each
@ -23,7 +23,7 @@
#define MYINT(s) (s[0] - '0') /* assume one-digit numerals */
#define LUAC_VERSION (MYINT(LUA_VERSION_MAJOR) * 16 + MYINT(LUA_VERSION_MINOR))
#define LUAC_FORMAT 0 /* this is the official format */
#define LUAC_FORMAT 0 /* this is the official format */
/* load one chunk; from lundump.c */
LUAI_FUNC LClosure *luaU_undump(lua_State *L, ZIO *Z, const char *name);

View file

@ -58,7 +58,7 @@ typedef enum {
#define tointegerns(o, i) \
(l_likely(ttisinteger(o)) ? (*(i) = ivalue(o), 1) : luaV_tointegerns(o, i, LUA_FLOORN2I))
#define intop(op, v1, v2) l_castU2S(l_castS2U(v1) op l_castS2U(v2))
#define intop(op, v1, v2) l_castU2S(l_castS2U(v1) op l_castS2U(v2))
#define luaV_rawequalobj(t1, t2) luaV_equalobj(NULL, t1, t2)

View file

@ -25,9 +25,9 @@ typedef struct Mbuffer {
#define luaZ_initbuffer(L, buff) ((buff)->buffer = NULL, (buff)->buffsize = 0)
#define luaZ_buffer(buff) ((buff)->buffer)
#define luaZ_sizebuffer(buff) ((buff)->buffsize)
#define luaZ_bufflen(buff) ((buff)->n)
#define luaZ_buffer(buff) ((buff)->buffer)
#define luaZ_sizebuffer(buff) ((buff)->buffsize)
#define luaZ_bufflen(buff) ((buff)->n)
#define luaZ_buffremove(buff, i) ((buff)->n -= (i))
#define luaZ_resetbuffer(buff) ((buff)->n = 0)

View file

@ -41,10 +41,10 @@ const char lua_ident[] =
#define isvalid(L, o) (!ttisnil(o) || o != &G(L)->nilvalue)
/* test for pseudo index */
#define ispseudo(i) ((i) <= LUA_REGISTRYINDEX)
#define ispseudo(i) ((i) <= LUA_REGISTRYINDEX)
/* test for upvalue */
#define isupvalue(i) ((i) < LUA_REGISTRYINDEX)
#define isupvalue(i) ((i) < LUA_REGISTRYINDEX)
/*
** Convert an acceptable index to a pointer to its respective value.

View file

@ -75,9 +75,9 @@ static int pushglobalfuncname(lua_State *L, lua_Debug *ar)
lua_getfield(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE);
if (findfield(L, top + 1, 2)) {
const char *name = lua_tostring(L, -1);
if (strncmp(name, LUA_GNAME ".", 3) == 0) { /* name start with '_G.'? */
lua_pushstring(L, name + 3); /* push name without prefix */
lua_remove(L, -2); /* remove original name */
if (luaport_strncmp(name, LUA_GNAME ".", 3) == 0) { /* name start with '_G.'? */
lua_pushstring(L, name + 3); /* push name without prefix */
lua_remove(L, -2); /* remove original name */
}
lua_copy(L, -1, top + 1); /* copy name to proper place */
lua_settop(L, top + 1); /* remove table "loaded" and name copy */
@ -172,7 +172,7 @@ LUALIB_API int luaL_argerror(lua_State *L, int arg, const char *extramsg)
if (!lua_getstack(L, 0, &ar)) /* no stack frame? */
return luaL_error(L, "bad argument #%d (%s)", arg, extramsg);
lua_getinfo(L, "n", &ar);
if (strcmp(ar.namewhat, "method") == 0) {
if (luaport_strcmp(ar.namewhat, "method") == 0) {
arg--; /* do not count 'self' */
if (arg == 0) /* error is in the self argument itself? */
return luaL_error(L, "calling '%s' on bad self (%s)",
@ -238,22 +238,22 @@ LUALIB_API int luaL_error(lua_State *L, const char *fmt, ...)
LUALIB_API int luaL_fileresult(lua_State *L, int stat, const char *fname)
{
int en = errno; /* calls to Lua API may change this value */
int en = luaport_errno; /* calls to Lua API may change this value */
if (stat) {
lua_pushboolean(L, 1);
return 1;
} else {
luaL_pushfail(L);
if (fname)
lua_pushfstring(L, "%s: %s", fname, strerror(en));
lua_pushfstring(L, "%s: %s", fname, luaport_strerror(en));
else
lua_pushstring(L, strerror(en));
lua_pushstring(L, luaport_strerror(en));
lua_pushinteger(L, en);
return 3;
}
}
#if !defined(luaport_inspectstat) /* { */
#if !defined(l_inspectstat) /* { */
#if defined(LUA_USE_POSIX)
@ -262,17 +262,17 @@ LUALIB_API int luaL_fileresult(lua_State *L, int stat, const char *fname)
/*
** use appropriate macros to interpret 'pclose' return status
*/
#define luaport_inspectstat(stat, what) \
if (WIFEXITED(stat)) { \
stat = WEXITSTATUS(stat); \
} else if (WIFSIGNALED(stat)) { \
stat = WTERMSIG(stat); \
what = "signal"; \
#define l_inspectstat(stat, what) \
if (WIFEXITED(stat)) { \
stat = WEXITSTATUS(stat); \
} else if (WIFSIGNALED(stat)) { \
stat = WTERMSIG(stat); \
what = "signal"; \
}
#else
#define luaport_inspectstat(stat, what) /* no op */
#define l_inspectstat(stat, what) /* no op */
#endif
@ -280,12 +280,12 @@ LUALIB_API int luaL_fileresult(lua_State *L, int stat, const char *fname)
LUALIB_API int luaL_execresult(lua_State *L, int stat)
{
if (stat != 0 && errno != 0) /* error with an 'errno'? */
if (stat != 0 && luaport_errno != 0) /* error with an 'errno'? */
return luaL_fileresult(L, 0, NULL);
else {
const char *what = "exit"; /* type of termination */
luaport_inspectstat(stat, what); /* interpret result */
if (*what == 'e' && stat == 0) /* successful termination? */
const char *what = "exit"; /* type of termination */
l_inspectstat(stat, what); /* interpret result */
if (*what == 'e' && stat == 0) /* successful termination? */
lua_pushboolean(L, 1);
else
luaL_pushfail(L);
@ -359,7 +359,7 @@ LUALIB_API int luaL_checkoption(lua_State *L, int arg, const char *def,
luaL_checkstring(L, arg);
int i;
for (i = 0; lst[i]; i++)
if (strcmp(lst[i], name) == 0)
if (luaport_strcmp(lst[i], name) == 0)
return i;
return luaL_argerror(L, arg,
lua_pushfstring(L, "invalid option '%s'", name));
@ -407,7 +407,7 @@ LUALIB_API const char *luaL_optlstring(lua_State *L, int arg,
{
if (lua_isnoneornil(L, arg)) {
if (len)
*len = (def ? strlen(def) : 0);
*len = (def ? luaport_strlen(def) : 0);
return def;
} else
return luaL_checklstring(L, arg, len);
@ -579,7 +579,7 @@ LUALIB_API void luaL_addlstring(luaL_Buffer *B, const char *s, size_t l)
LUALIB_API void luaL_addstring(luaL_Buffer *B, const char *s)
{
luaL_addlstring(B, s, strlen(s));
luaL_addlstring(B, s, luaport_strlen(s));
}
LUALIB_API void luaL_pushresult(luaL_Buffer *B)
@ -697,7 +697,7 @@ LUALIB_API void luaL_unref(lua_State *L, int t, int ref)
typedef struct LoadF {
int n; /* number of pre-read characters */
LUAPORT_FILE *f; /* file being read */
FILE *f; /* file being read */
char buff[BUFSIZ]; /* area for reading file */
} LoadF;
@ -721,7 +721,7 @@ static const char *getF(lua_State *L, void *ud, size_t *size)
static int errfile(lua_State *L, const char *what, int fnameindex)
{
const char *serr = strerror(errno);
const char *serr = luaport_strerror(luaport_errno);
const char *filename = lua_tostring(L, fnameindex) + 1;
lua_pushfstring(L, "cannot %s %s: %s", what, filename, serr);
lua_remove(L, fnameindex);
@ -779,11 +779,10 @@ LUALIB_API int luaL_loadfilex(lua_State *L, const char *filename,
if (lf.f == NULL)
return errfile(L, "open", fnameindex);
}
if (skipcomment(&lf, &c)) /* read initial portion */
lf.buff[lf.n++] = '\n'; /* add line to correct line numbers */
if (c == LUA_SIGNATURE[0] && filename) { /* binary file? */
luaport_fclose(lf.f);
lf.f = luaport_fopen(filename, "rb"); /* reopen in binary mode */
if (skipcomment(&lf, &c)) /* read initial portion */
lf.buff[lf.n++] = '\n'; /* add line to correct line numbers */
if (c == LUA_SIGNATURE[0] && filename) { /* binary file? */
lf.f = luaport_freopen(filename, "rb", lf.f); /* reopen in binary mode */
if (lf.f == NULL)
return errfile(L, "reopen", fnameindex);
skipcomment(&lf, &c); /* re-read initial portion */
@ -829,7 +828,7 @@ LUALIB_API int luaL_loadbufferx(lua_State *L, const char *buff, size_t size,
LUALIB_API int luaL_loadstring(lua_State *L, const char *s)
{
return luaL_loadbuffer(L, s, strlen(s), s);
return luaL_loadbuffer(L, s, luaport_strlen(s), s);
}
/* }====================================================== */
@ -980,8 +979,8 @@ LUALIB_API void luaL_addgsub(luaL_Buffer *b, const char *s,
const char *p, const char *r)
{
const char *wild;
size_t l = strlen(p);
while ((wild = strstr(s, p)) != NULL) {
size_t l = luaport_strlen(p);
while ((wild = luaport_strstr(s, p)) != NULL) {
luaL_addlstring(b, s, wild - s); /* push prefix */
luaL_addstring(b, r); /* push replacement in place of pattern */
s = wild + l; /* continue after 'p' */
@ -1039,9 +1038,9 @@ static int checkcontrol(lua_State *L, const char *message, int tocont)
if (tocont || *(message++) != '@') /* not a control message? */
return 0;
else {
if (strcmp(message, "off") == 0)
if (luaport_strcmp(message, "off") == 0)
lua_setwarnf(L, warnfoff, L); /* turn warnings off */
else if (strcmp(message, "on") == 0)
else if (luaport_strcmp(message, "on") == 0)
lua_setwarnf(L, warnfon, L); /* turn warnings on */
return 1; /* it was a control message */
}

View file

@ -59,7 +59,7 @@ static const char *b_str2int(const char *s, int base, lua_Integer *pn)
{
lua_Unsigned n = 0;
int neg = 0;
s += strspn(s, SPACECHARS); /* skip initial spaces */
s += luaport_strspn(s, SPACECHARS); /* skip initial spaces */
if (*s == '-') {
s++;
neg = 1;
@ -75,7 +75,7 @@ static const char *b_str2int(const char *s, int base, lua_Integer *pn)
n = n * base + digit;
s++;
} while (isalnum((unsigned char)*s));
s += strspn(s, SPACECHARS); /* skip trailing spaces */
s += luaport_strspn(s, SPACECHARS); /* skip trailing spaces */
*pn = (lua_Integer)((neg) ? (0u - n) : n);
return s;
}

View file

@ -30,7 +30,7 @@
#include "lvm.h"
/* Maximum number of registers in a Lua function (must fit in 8 bits) */
#define MAXREGS 255
#define MAXREGS 255
#define hasjumps(e) ((e)->t != (e)->f)

View file

@ -165,7 +165,7 @@ static int db_getinfo(lua_State *L)
if (!lua_getinfo(L1, options, &ar))
return luaL_argerror(L, arg + 2, "invalid option");
lua_newtable(L); /* table to collect results */
if (strchr(options, 'S')) {
if (luaport_strchr(options, 'S')) {
lua_pushlstring(L, ar.source, ar.srclen);
lua_setfield(L, -2, "source");
settabss(L, "short_src", ar.short_src);
@ -173,26 +173,26 @@ static int db_getinfo(lua_State *L)
settabsi(L, "lastlinedefined", ar.lastlinedefined);
settabss(L, "what", ar.what);
}
if (strchr(options, 'l'))
if (luaport_strchr(options, 'l'))
settabsi(L, "currentline", ar.currentline);
if (strchr(options, 'u')) {
if (luaport_strchr(options, 'u')) {
settabsi(L, "nups", ar.nups);
settabsi(L, "nparams", ar.nparams);
settabsb(L, "isvararg", ar.isvararg);
}
if (strchr(options, 'n')) {
if (luaport_strchr(options, 'n')) {
settabss(L, "name", ar.name);
settabss(L, "namewhat", ar.namewhat);
}
if (strchr(options, 'r')) {
if (luaport_strchr(options, 'r')) {
settabsi(L, "ftransfer", ar.ftransfer);
settabsi(L, "ntransfer", ar.ntransfer);
}
if (strchr(options, 't'))
if (luaport_strchr(options, 't'))
settabsb(L, "istailcall", ar.istailcall);
if (strchr(options, 'L'))
if (luaport_strchr(options, 'L'))
treatstackoption(L, L1, "activelines");
if (strchr(options, 'f'))
if (luaport_strchr(options, 'f'))
treatstackoption(L, L1, "func");
return 1; /* return table */
}
@ -338,11 +338,11 @@ static void hookf(lua_State *L, lua_Debug *ar)
static int makemask(const char *smask, int count)
{
int mask = 0;
if (strchr(smask, 'c'))
if (luaport_strchr(smask, 'c'))
mask |= LUA_MASKCALL;
if (strchr(smask, 'r'))
if (luaport_strchr(smask, 'r'))
mask |= LUA_MASKRET;
if (strchr(smask, 'l'))
if (luaport_strchr(smask, 'l'))
mask |= LUA_MASKLINE;
if (count > 0)
mask |= LUA_MASKCOUNT;
@ -429,9 +429,9 @@ static int db_debug(lua_State *L)
char buffer[250];
lua_writestringerror("%s", "lua_debug> ");
if (luaport_fgets(buffer, sizeof(buffer), luaport_stdin) == NULL ||
strcmp(buffer, "cont\n") == 0)
luaport_strcmp(buffer, "cont\n") == 0)
return 0;
if (luaL_loadbuffer(L, buffer, strlen(buffer), "=(debug command)") ||
if (luaL_loadbuffer(L, buffer, luaport_strlen(buffer), "=(debug command)") ||
lua_pcall(L, 0, 0, 0))
lua_writestringerror("%s\n", luaL_tolstring(L, -1, NULL));
lua_settop(L, 0); /* remove eventual returns */

View file

@ -393,11 +393,11 @@ LUA_API int lua_getinfo(lua_State *L, const char *what, lua_Debug *ar)
}
cl = ttisclosure(func) ? clvalue(func) : NULL;
status = auxgetinfo(L, what, ar, cl, ci);
if (strchr(what, 'f')) {
if (luaport_strchr(what, 'f')) {
setobj2s(L, L->top, func);
api_incr_top(L);
}
if (strchr(what, 'L'))
if (luaport_strchr(what, 'L'))
collectvalidlines(L, cl);
lua_unlock(L);
return status;
@ -512,7 +512,7 @@ static const char *gxf(const Proto *p, int pc, Instruction i, int isup)
name = upvalname(p, t);
else
getobjname(p, pc, t, &name);
return (name && strcmp(name, LUA_ENV) == 0) ? "global" : "field";
return (name && luaport_strcmp(name, LUA_ENV) == 0) ? "global" : "field";
}
static const char *getobjname(const Proto *p, int lastpc, int reg,
@ -804,7 +804,7 @@ l_noret luaG_ordererror(lua_State *L, const TValue *p1, const TValue *p2)
{
const char *t1 = luaT_objtypename(L, p1);
const char *t2 = luaT_objtypename(L, p2);
if (strcmp(t1, t2) == 0)
if (luaport_strcmp(t1, t2) == 0)
luaG_runerror(L, "attempt to compare two %s values", t1);
else
luaG_runerror(L, "attempt to compare %s with %s", t1, t2);

View file

@ -74,10 +74,10 @@
#else /* }{ */
/* ISO C handling with long jumps */
#define LUAI_THROW(L, c) longjmp((c)->b, 1)
#define LUAI_TRY(L, c, a) \
if (setjmp((c)->b) == 0) { \
a \
#define LUAI_THROW(L, c) luaport_longjmp((c)->b, 1)
#define LUAI_TRY(L, c, a) \
if (luaport_setjmp((c)->b) == 0) { \
a \
}
#define luai_jmpbuf jmp_buf
@ -942,7 +942,7 @@ struct SParser { /* data to 'f_parser' */
static void checkmode(lua_State *L, const char *mode, const char *x)
{
if (mode && strchr(mode, x[0]) == NULL) {
if (mode && luaport_strchr(mode, x[0]) == NULL) {
luaO_pushfstring(L,
"attempt to load a %s chunk (mode is '%s')", x, mode);
luaD_throw(L, LUA_ERRSYNTAX);

View file

@ -31,7 +31,7 @@ typedef struct {
*/
#define dumpVector(D, v, n) dumpBlock(D, v, (n) * sizeof((v)[0]))
#define dumpLiteral(D, s) dumpBlock(D, s, sizeof(s) - sizeof(char))
#define dumpLiteral(D, s) dumpBlock(D, s, sizeof(s) - sizeof(char))
static void dumpBlock(DumpState *D, const void *b, size_t size)
{

View file

@ -30,12 +30,12 @@
** (Large enough to dissipate fixed overheads but small enough
** to allow small steps for the collector.)
*/
#define GCSWEEPMAX 100
#define GCSWEEPMAX 100
/*
** Maximum number of finalizers to call in each single step.
*/
#define GCFINMAX 10
#define GCFINMAX 10
/*
** Cost of calling one finalizer.
@ -46,19 +46,19 @@
** The equivalent, in bytes, of one unit of "work" (visiting a slot,
** sweeping an object, etc.)
*/
#define WORK2MEM sizeof(TValue)
#define WORK2MEM sizeof(TValue)
/*
** macro to adjust 'pause': 'pause' is actually used like
** 'pause / PAUSEADJ' (value chosen by tests)
*/
#define PAUSEADJ 100
#define PAUSEADJ 100
/* mask with all color bits */
#define maskcolors (bitmask(BLACKBIT) | WHITEBITS)
#define maskcolors (bitmask(BLACKBIT) | WHITEBITS)
/* mask with all GC bits */
#define maskgcbits (maskcolors | AGEBITS)
#define maskgcbits (maskcolors | AGEBITS)
/* macro to erase all color bits then set only the current white bit */
#define makewhite(g, x) \
@ -78,7 +78,7 @@
/*
** Protected access to objects in values
*/
#define gcvalueN(o) (iscollectable(o) ? gcvalue(o) : NULL)
#define gcvalueN(o) (iscollectable(o) ? gcvalue(o) : NULL)
#define markvalue(g, o) \
{ \
@ -547,8 +547,8 @@ static lu_mem traversetable(global_State *g, Table *h)
const TValue *mode = gfasttm(g, h->metatable, TM_MODE);
markobjectN(g, h->metatable);
if (mode && ttisstring(mode) && /* is there a weak mode? */
(cast_void(weakkey = strchr(svalue(mode), 'k')),
cast_void(weakvalue = strchr(svalue(mode), 'v')),
(cast_void(weakkey = luaport_strchr(svalue(mode), 'k')),
cast_void(weakvalue = luaport_strchr(svalue(mode), 'v')),
(weakkey || weakvalue))) { /* is really weak? */
if (!weakkey) /* strong keys? */
traverseweakvalue(g, h);

View file

@ -35,9 +35,9 @@
/* Check whether 'mode' matches '[rwa]%+?[L_MODEEXT]*' */
static int l_checkmode(const char *mode)
{
return (*mode != '\0' && strchr("rwa", *(mode++)) != NULL &&
(*mode != '+' || ((void)(++mode), 1)) && /* skip if char is '+' */
(strspn(mode, L_MODEEXT) == strlen(mode))); /* check extensions */
return (*mode != '\0' && luaport_strchr("rwa", *(mode++)) != NULL &&
(*mode != '+' || ((void)(++mode), 1)) && /* skip if char is '+' */
(luaport_strspn(mode, L_MODEEXT) == luaport_strlen(mode))); /* check extensions */
}
#endif
@ -73,7 +73,7 @@ static int l_checkmode(const char *mode)
#define l_popen(L, c, m) \
((void)c, (void)m, \
luaL_error(L, "'popen' not supported"), \
(LUAPORT_FILE *)0)
(FILE *)0)
#define l_pclose(L, file) ((void)L, (void)file, -1)
#endif /* } */
@ -146,7 +146,7 @@ typedef luaL_Stream LStream;
#define tolstream(L) ((LStream *)luaL_checkudata(L, 1, LUA_FILEHANDLE))
#define isclosed(p) ((p)->closef == NULL)
#define isclosed(p) ((p)->closef == NULL)
static int io_type(lua_State *L)
{
@ -162,7 +162,7 @@ static int io_type(lua_State *L)
return 1;
}
static int lf_tostring(lua_State *L)
static int f_tostring(lua_State *L)
{
LStream *p = tolstream(L);
if (isclosed(p))
@ -172,7 +172,7 @@ static int lf_tostring(lua_State *L)
return 1;
}
static LUAPORT_FILE *tofile(lua_State *L)
static FILE *tofile(lua_State *L)
{
LStream *p = tolstream(L);
if (l_unlikely(isclosed(p)))
@ -207,7 +207,7 @@ static int aux_close(lua_State *L)
return (*cf)(L); /* close it */
}
static int lf_close(lua_State *L)
static int f_close(lua_State *L)
{
tofile(L); /* make sure argument is an open stream */
return aux_close(L);
@ -217,10 +217,10 @@ static int io_close(lua_State *L)
{
if (lua_isnone(L, 1)) /* no argument? */
lua_getfield(L, LUA_REGISTRYINDEX, IO_OUTPUT); /* use default output */
return lf_close(L);
return f_close(L);
}
static int lf_gc(lua_State *L)
static int f_gc(lua_State *L)
{
LStream *p = tolstream(L);
if (!isclosed(p) && p->f != NULL)
@ -251,7 +251,7 @@ static void opencheck(lua_State *L, const char *fname, const char *mode)
LStream *p = newfile(L);
p->f = luaport_fopen(fname, mode);
if (l_unlikely(p->f == NULL))
luaL_error(L, "cannot open file '%s' (%s)", fname, strerror(errno));
luaL_error(L, "cannot open file '%s' (%s)", fname, luaport_strerror(luaport_errno));
}
static int io_open(lua_State *L)
@ -271,7 +271,7 @@ static int io_open(lua_State *L)
static int io_pclose(lua_State *L)
{
LStream *p = tolstream(L);
errno = 0;
luaport_errno = 0;
return luaL_execresult(L, l_pclose(L, p->f));
}
@ -293,7 +293,7 @@ static int io_tmpfile(lua_State *L)
return (p->f == NULL) ? luaL_fileresult(L, 0, NULL) : 1;
}
static LUAPORT_FILE *getiofile(lua_State *L, const char *findex)
static FILE *getiofile(lua_State *L, const char *findex)
{
LStream *p;
lua_getfield(L, LUA_REGISTRYINDEX, findex);
@ -358,7 +358,7 @@ static void aux_lines(lua_State *L, int toclose)
lua_pushcclosure(L, io_readline, 3 + n);
}
static int lf_lines(lua_State *L)
static int f_lines(lua_State *L)
{
tofile(L); /* check that it's a valid file handle */
aux_lines(L, 0);
@ -409,7 +409,7 @@ static int io_lines(lua_State *L)
/* auxiliary structure used by 'read_number' */
typedef struct {
LUAPORT_FILE *f; /* file being read */
FILE *f; /* file being read */
int c; /* current character (look ahead) */
int n; /* number of elements in buffer 'buff' */
char buff[L_MAXLENNUM + 1]; /* +1 for ending '\0' */
@ -457,7 +457,7 @@ static int readdigits(RN *rn, int hex)
** Then it calls 'lua_stringtonumber' to check whether the format is
** correct and to convert it to a Lua number.
*/
static int read_number(lua_State *L, LUAPORT_FILE *f)
static int read_number(lua_State *L, FILE *f)
{
RN rn;
int count = 0;
@ -496,19 +496,15 @@ static int read_number(lua_State *L, LUAPORT_FILE *f)
}
}
static int test_eof(lua_State *L, LUAPORT_FILE *f)
static int test_eof(lua_State *L, FILE *f)
{
int c = luaport_feof(f);
int c = luaport_getc(f);
luaport_ungetc(c, f); /* no-op when c == EOF */
lua_pushliteral(L, "");
return !c;
// int c = luaport_getc(f);
// luaport_ungetc(c, f); /* no-op when c == EOF */
// lua_pushliteral(L, "");
// return (c != EOF);
return (c != EOF);
}
static int read_line(lua_State *L, LUAPORT_FILE *f, int chop)
static int read_line(lua_State *L, FILE *f, int chop)
{
luaL_Buffer b;
int c;
@ -529,7 +525,7 @@ static int read_line(lua_State *L, LUAPORT_FILE *f, int chop)
return (c == '\n' || lua_rawlen(L, -1) > 0);
}
static void read_all(lua_State *L, LUAPORT_FILE *f)
static void read_all(lua_State *L, FILE *f)
{
size_t nr;
luaL_Buffer b;
@ -542,7 +538,7 @@ static void read_all(lua_State *L, LUAPORT_FILE *f)
luaL_pushresult(&b); /* close buffer */
}
static int read_chars(lua_State *L, LUAPORT_FILE *f, size_t n)
static int read_chars(lua_State *L, FILE *f, size_t n)
{
size_t nr; /* number of chars actually read */
char *p;
@ -555,7 +551,7 @@ static int read_chars(lua_State *L, LUAPORT_FILE *f, size_t n)
return (nr > 0); /* true iff read something */
}
static int g_read(lua_State *L, LUAPORT_FILE *f, int first)
static int g_read(lua_State *L, FILE *f, int first)
{
int nargs = lua_gettop(L) - 1;
int n, success;
@ -577,7 +573,6 @@ static int g_read(lua_State *L, LUAPORT_FILE *f, int first)
p++; /* skip optional '*' (for compatibility) */
switch (*p) {
case 'n': /* number */
return luaL_argerror(L, n, "specifier 'n' number not supported yet in this dft_platform build");
success = read_number(L, f);
break;
case 'l': /* line */
@ -610,7 +605,7 @@ static int io_read(lua_State *L)
return g_read(L, getiofile(L, IO_INPUT), 1);
}
static int lf_read(lua_State *L)
static int f_read(lua_State *L)
{
return g_read(L, tofile(L), 2);
}
@ -649,7 +644,7 @@ static int io_readline(lua_State *L)
/* }====================================================== */
static int g_write(lua_State *L, LUAPORT_FILE *f, int arg)
static int g_write(lua_State *L, FILE *f, int arg)
{
int nargs = lua_gettop(L) - arg;
int status = 1;
@ -664,7 +659,7 @@ static int g_write(lua_State *L, LUAPORT_FILE *f, int arg)
} else {
size_t l;
const char *s = luaL_checklstring(L, arg, &l);
status = status && (luaport_fwirte(s, sizeof(char), l, f) == l);
status = status && (luaport_fwrite(s, sizeof(char), l, f) == l);
}
}
if (l_likely(status))
@ -678,18 +673,18 @@ static int io_write(lua_State *L)
return g_write(L, getiofile(L, IO_OUTPUT), 1);
}
static int lf_write(lua_State *L)
static int f_write(lua_State *L)
{
LUAPORT_FILE *f = tofile(L);
FILE *f = tofile(L);
lua_pushvalue(L, 1); /* push file at the stack top (to be returned) */
return g_write(L, f, 2);
}
static int lf_seek(lua_State *L)
static int f_seek(lua_State *L)
{
static const int mode[] = { SEEK_SET, SEEK_CUR, SEEK_END };
static const char *const modenames[] = { "set", "cur", "end", NULL };
LUAPORT_FILE *f = tofile(L);
FILE *f = tofile(L);
int op = luaL_checkoption(L, 2, "cur", modenames);
lua_Integer p3 = luaL_optinteger(L, 3, 0);
l_seeknum offset = (l_seeknum)p3;
@ -704,11 +699,11 @@ static int lf_seek(lua_State *L)
}
}
static int lf_setvbuf(lua_State *L)
static int f_setvbuf(lua_State *L)
{
static const int mode[] = { _IONBF, _IOFBF, _IOLBF };
static const char *const modenames[] = { "no", "full", "line", NULL };
LUAPORT_FILE *f = tofile(L);
FILE *f = tofile(L);
int op = luaL_checkoption(L, 2, NULL, modenames);
lua_Integer sz = luaL_optinteger(L, 3, LUAL_BUFFERSIZE);
int res = luaport_setvbuf(f, NULL, mode[op], (size_t)sz);
@ -720,7 +715,7 @@ static int io_flush(lua_State *L)
return luaL_fileresult(L, luaport_fflush(getiofile(L, IO_OUTPUT)) == 0, NULL);
}
static int lf_flush(lua_State *L)
static int f_flush(lua_State *L)
{
return luaL_fileresult(L, luaport_fflush(tofile(L)) == 0, NULL);
}
@ -747,13 +742,13 @@ static const luaL_Reg iolib[] = {
** methods for file handles
*/
static const luaL_Reg meth[] = {
{ "read", lf_read },
{ "write", lf_write },
{ "lines", lf_lines },
{ "flush", lf_flush },
{ "seek", lf_seek },
{ "close", lf_close },
{ "setvbuf", lf_setvbuf },
{ "read", f_read },
{ "write", f_write },
{ "lines", f_lines },
{ "flush", f_flush },
{ "seek", f_seek },
{ "close", f_close },
{ "setvbuf", f_setvbuf },
{ NULL, NULL }
};
@ -762,9 +757,9 @@ static const luaL_Reg meth[] = {
*/
static const luaL_Reg metameth[] = {
{ "__index", NULL }, /* place holder */
{ "__gc", lf_gc },
{ "__close", lf_gc },
{ "__tostring", lf_tostring },
{ "__gc", f_gc },
{ "__close", f_gc },
{ "__tostring", f_tostring },
{ NULL, NULL }
};
@ -790,7 +785,7 @@ static int io_noclose(lua_State *L)
return 2;
}
static void createstdfile(lua_State *L, LUAPORT_FILE *f, const char *k,
static void createstdfile(lua_State *L, FILE *f, const char *k,
const char *fname)
{
LStream *p = newprefile(L);

View file

@ -26,7 +26,7 @@
#include "ltable.h"
#include "lzio.h"
#define next(ls) (ls->current = zgetc(ls->z))
#define next(ls) (ls->current = zgetc(ls->z))
#define currIsNewline(ls) (ls->current == '\n' || ls->current == '\r')

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