[sync] sync code from internal

This commit is contained in:
jzlv 2023-02-24 21:33:12 +08:00
parent 810354065e
commit 6a4d89bfeb
285 changed files with 33056 additions and 27903 deletions

BIN
BouffaloSDK.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 194 KiB

148
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
*/
```
Bouffalolab Developer Forum: [https://bbs.bouffalolab.com/](https://bbs.bouffalolab.com/)

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
*/
```
博流开发者交流论坛: [https://bbs.bouffalolab.com/](https://bbs.bouffalolab.com/)

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,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,13 +41,15 @@ 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);
void ili9341_spi_draw_picture_blocking(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, ili9341_spi_color_t *picture);
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
#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,13 +41,15 @@ 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);
void st7789v_spi_draw_picture_blocking(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, st7789v_spi_color_t *picture);
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,13 +41,15 @@ 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);
void st7796_spi_draw_picture_blocking(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, st7796_spi_color_t *picture);
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)
@ -43,4 +45,6 @@ sdk_library_add_sources(lhal/llib_mtimer.c)
sdk_library_add_sources(lhal/llib_gpio.c)
sdk_add_include_directories(lhal)
sdk_add_compile_definitions(-DCONFIG_LUA_LHAL)
endif()
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')

View File

@ -332,7 +332,7 @@ static Rand64 nextrand(Rand64 *state)
#define shift64_FIG (64 - FIGS)
/* to scale to [0, 1), multiply by scaleFIG = 2^(-FIGS) */
#define scaleFIG (l_mathop(0.5) / ((Rand64)1 << (FIGS - 1)))
#define scaleFIG (l_mathop(0.5) / ((Rand64)1 << (FIGS - 1)))
static lua_Number I2d(Rand64 x)
{
@ -343,7 +343,7 @@ static lua_Number I2d(Rand64 x)
#define I2UInt(x) ((lua_Unsigned)trim64(x))
/* convert a 'lua_Unsigned' to a 'Rand64' */
#define Int2I(x) ((Rand64)(x))
#define Int2I(x) ((Rand64)(x))
#else /* no 'Rand64' }{ */

View File

@ -45,7 +45,7 @@
#endif
/* prefix for open functions in C libraries */
#define LUA_POF "luaopen_"
#define LUA_POF "luaopen_"
/* separator for open functions in C libraries */
#define LUA_OFSEP "_"
@ -56,7 +56,7 @@
*/
static const char *const CLIBS = "_CLIBS";
#define LIB_FAIL "open"
#define LIB_FAIL "open"
#define setprogdir(L) ((void)0)
@ -164,7 +164,7 @@ static void setprogdir(lua_State *L)
char *lb;
DWORD nsize = sizeof(buff) / sizeof(char);
DWORD n = GetModuleFileNameA(NULL, buff, nsize); /* get exec. name */
if (n == 0 || n == nsize || (lb = strrchr(buff, '\\')) == NULL)
if (n == 0 || n == nsize || (lb = luaport_strrchr(buff, '\\')) == NULL)
luaL_error(L, "unable to get ModuleFileName");
else {
*lb = '\0'; /* cut name on the last '\\' to get the path */
@ -218,7 +218,7 @@ static lua_CFunction lsys_sym(lua_State *L, void *lib, const char *sym)
#undef LIB_FAIL
#define LIB_FAIL "absent"
#define DLMSG "dynamic libraries not enabled; check your Lua installation"
#define DLMSG "dynamic libraries not enabled; check your Lua installation"
static void lsys_unloadlib(void *lib)
{
@ -284,14 +284,14 @@ static void setpath(lua_State *L, const char *fieldname,
const char *dftmark;
const char *nver = lua_pushfstring(L, "%s%s", envname, LUA_VERSUFFIX);
const char *path = luaport_getenv(nver); /* try versioned name */
if (path == NULL) /* no versioned environment variable? */
if (path == NULL) /* no versioned environment variable? */
path = luaport_getenv(envname); /* try unversioned name */
if (path == NULL || noenv(L)) /* no environment variable? */
lua_pushstring(L, dft); /* use default */
else if ((dftmark = strstr(path, LUA_PATH_SEP LUA_PATH_SEP)) == NULL)
if (path == NULL || noenv(L)) /* no environment variable? */
lua_pushstring(L, dft); /* use default */
else if ((dftmark = luaport_strstr(path, LUA_PATH_SEP LUA_PATH_SEP)) == NULL)
lua_pushstring(L, path); /* nothing to change */
else { /* path contains a ";;": insert default path in its place */
size_t len = strlen(path);
size_t len = luaport_strlen(path);
luaL_Buffer b;
luaL_buffinit(L, &b);
if (path < dftmark) { /* is there a prefix before ';;'? */
@ -413,7 +413,7 @@ static int ll_loadlib(lua_State *L)
static int readable(const char *filename)
{
LUAPORT_FILE *f = luaport_fopen(filename, "r"); /* try to open file */
FILE *f = luaport_fopen(filename, "r"); /* try to open file */
if (f == NULL)
return 0; /* open failed */
luaport_fclose(f);
@ -435,11 +435,11 @@ static const char *getnextfilename(char **path, char *end)
*name = *LUA_PATH_SEP; /* restore separator */
name++; /* skip it */
}
sep = strchr(name, *LUA_PATH_SEP); /* find next separator */
if (sep == NULL) /* separator not found? */
sep = end; /* name goes until the end */
*sep = '\0'; /* finish file name */
*path = sep; /* will start next search from here */
sep = luaport_strchr(name, *LUA_PATH_SEP); /* find next separator */
if (sep == NULL) /* separator not found? */
sep = end; /* name goes until the end */
*sep = '\0'; /* finish file name */
*path = sep; /* will start next search from here */
return name;
}
@ -469,7 +469,7 @@ static const char *searchpath(lua_State *L, const char *name,
char *endpathname; /* its end */
const char *filename;
/* separator is non-empty and appears in 'name'? */
if (*sep != '\0' && strchr(name, *sep) != NULL)
if (*sep != '\0' && luaport_strchr(name, *sep) != NULL)
name = luaL_gsub(L, name, sep, dirsep); /* replace it by 'dirsep' */
luaL_buffinit(L, &buff);
/* add path to the buffer, replacing marks ('?') with the file name */
@ -546,7 +546,7 @@ static int loadfunc(lua_State *L, const char *filename, const char *modname)
const char *openfunc;
const char *mark;
modname = luaL_gsub(L, modname, ".", LUA_OFSEP);
mark = strchr(modname, *LUA_IGMARK);
mark = luaport_strchr(modname, *LUA_IGMARK);
if (mark) {
int stat;
openfunc = lua_pushlstring(L, modname, mark - modname);
@ -573,7 +573,7 @@ static int searcher_Croot(lua_State *L)
{
const char *filename;
const char *name = luaL_checkstring(L, 1);
const char *p = strchr(name, '.');
const char *p = luaport_strchr(name, '.');
int stat;
if (p == NULL)
return 0; /* is root */

View File

@ -295,17 +295,17 @@ static const char *l_str2dloc(const char *s, lua_Number *result, int mode)
static const char *l_str2d(const char *s, lua_Number *result)
{
const char *endptr;
const char *pmode = strpbrk(s, ".xXnN"); /* look for special chars */
const char *pmode = luaport_strpbrk(s, ".xXnN"); /* look for special chars */
int mode = pmode ? ltolower(cast_uchar(*pmode)) : 0;
if (mode == 'n') /* reject 'inf' and 'nan' */
return NULL;
endptr = l_str2dloc(s, result, mode); /* try to convert */
if (endptr == NULL) { /* failed? may be a different locale */
char buff[L_MAXLENNUM + 1];
const char *pdot = strchr(s, '.');
if (pdot == NULL || strlen(s) > L_MAXLENNUM)
const char *pdot = luaport_strchr(s, '.');
if (pdot == NULL || luaport_strlen(s) > L_MAXLENNUM)
return NULL; /* string too long or no dot; fail */
strcpy(buff, s); /* copy string to buffer */
luaport_strcpy(buff, s); /* copy string to buffer */
buff[pdot - s] = lua_getlocaledecpoint(); /* correct decimal point */
endptr = l_str2dloc(buff, result, mode); /* try again */
if (endptr != NULL)
@ -404,7 +404,7 @@ static int tostringbuff(TValue *obj, char *buff)
len = lua_integer2str(buff, MAXNUMBER2STR, ivalue(obj));
else {
len = lua_number2str(buff, MAXNUMBER2STR, fltvalue(obj));
if (buff[strspn(buff, "-0123456789")] == '\0') { /* looks like an int? */
if (buff[luaport_strspn(buff, "-0123456789")] == '\0') { /* looks like an int? */
buff[len++] = lua_getlocaledecpoint();
buff[len++] = '0'; /* adds '.0' to result */
}
@ -513,14 +513,14 @@ const char *luaO_pushvfstring(lua_State *L, const char *fmt, va_list argp)
const char *e; /* points to next '%' */
buff.pushed = buff.blen = 0;
buff.L = L;
while ((e = strchr(fmt, '%')) != NULL) {
while ((e = luaport_strchr(fmt, '%')) != NULL) {
addstr2buff(&buff, fmt, e - fmt); /* add 'fmt' up to '%' */
switch (*(e + 1)) { /* conversion specifier */
case 's': { /* zero-terminated string */
const char *s = va_arg(argp, char *);
if (s == NULL)
s = "(null)";
addstr2buff(&buff, s, strlen(s));
addstr2buff(&buff, s, luaport_strlen(s));
break;
}
case 'c': { /* an 'int' as a character */
@ -571,8 +571,8 @@ const char *luaO_pushvfstring(lua_State *L, const char *fmt, va_list argp)
}
fmt = e + 2; /* skip '%' and the specifier */
}
addstr2buff(&buff, fmt, strlen(fmt)); /* rest of 'fmt' */
clearbuff(&buff); /* empty buffer into the stack */
addstr2buff(&buff, fmt, luaport_strlen(fmt)); /* rest of 'fmt' */
clearbuff(&buff); /* empty buffer into the stack */
lua_assert(buff.pushed == 1);
return svalue(s2v(L->top - 1));
}
@ -589,9 +589,9 @@ const char *luaO_pushfstring(lua_State *L, const char *fmt, ...)
/* }================================================================== */
#define RETS "..."
#define PRE "[string \""
#define POS "\"]"
#define RETS "..."
#define PRE "[string \""
#define POS "\"]"
#define addstr(a, b, l) (luaport_memcpy(a, b, (l) * sizeof(char)), a += (l))
@ -613,12 +613,12 @@ void luaO_chunkid(char *out, const char *source, size_t srclen)
bufflen -= LL(RETS);
luaport_memcpy(out, source + 1 + srclen - bufflen, bufflen * sizeof(char));
}
} else { /* string; format as [string "source"] */
const char *nl = strchr(source, '\n'); /* find first new line (if any) */
addstr(out, PRE, LL(PRE)); /* add prefix */
bufflen -= LL(PRE RETS POS) + 1; /* save space for prefix+suffix+'\0' */
if (srclen < bufflen && nl == NULL) { /* small one-line source? */
addstr(out, source, srclen); /* keep it */
} else { /* string; format as [string "source"] */
const char *nl = luaport_strchr(source, '\n'); /* find first new line (if any) */
addstr(out, PRE, LL(PRE)); /* add prefix */
bufflen -= LL(PRE RETS POS) + 1; /* save space for prefix+suffix+'\0' */
if (srclen < bufflen && nl == NULL) { /* small one-line source? */
addstr(out, source, srclen); /* keep it */
} else {
if (nl != NULL)
srclen = nl - source; /* stop at first newline */

View File

@ -90,8 +90,8 @@
#else /* }{ */
/* ISO C definitions */
#define l_gmtime(t, r) ((void)(r)->tm_sec, gmtime(t))
#define l_localtime(t, r) ((void)(r)->tm_sec, localtime(t))
#define l_gmtime(t, r) ((void)(r)->tm_sec, luaport_gmtime(t))
#define l_localtime(t, r) ((void)(r)->tm_sec, luaport_localtime(t))
#endif /* } */
@ -118,21 +118,21 @@
#define LUA_TMPNAMTEMPLATE "/tmp/lua_XXXXXX"
#endif
#define lua_tmpnam(b, e) \
{ \
strcpy(b, LUA_TMPNAMTEMPLATE); \
e = mkstemp(b); \
if (e != -1) \
close(e); \
e = (e == -1); \
#define lua_tmpnam(b, e) \
{ \
luaport_strcpy(b, LUA_TMPNAMTEMPLATE); \
e = mkstemp(b); \
if (e != -1) \
close(e); \
e = (e == -1); \
}
#else /* }{ */
/* ISO C definitions */
#define LUA_TMPNAMBUFSIZE L_tmpnam
#define lua_tmpnam(b, e) \
{ \
#define lua_tmpnam(b, e) \
{ \
e = (luaport_tmpnam(b) == NULL); \
}
@ -145,7 +145,7 @@ static int os_execute(lua_State *L)
{
const char *cmd = luaL_optstring(L, 1, NULL);
int stat;
errno = 0;
luaport_errno = 0;
stat = luaport_system(cmd);
if (cmd != NULL)
return luaL_execresult(L, stat);
@ -277,9 +277,9 @@ static const char *checkoption(lua_State *L, const char *conv,
const char *option = LUA_STRFTIMEOPTIONS;
int oplen = 1; /* length of options being checked */
for (; *option != '\0' && oplen <= convlen; option += oplen) {
if (*option == '|') /* next block? */
oplen++; /* will check options with next length (+1) */
else if (memcmp(conv, option, oplen) == 0) { /* match? */
if (*option == '|') /* next block? */
oplen++; /* will check options with next length (+1) */
else if (luaport_memcmp(conv, option, oplen) == 0) { /* match? */
luaport_memcpy(buff, conv, oplen); /* copy valid option to buffer */
buff[oplen] = '\0';
return conv + oplen; /* return next item */
@ -290,11 +290,11 @@ static const char *checkoption(lua_State *L, const char *conv,
return conv; /* to avoid warnings */
}
static time_t l_checktime(lua_State *L, int arg)
static luaport_time_t l_checktime(lua_State *L, int arg)
{
l_timet t = l_gettime(L, arg);
luaL_argcheck(L, (time_t)t == t, arg, "time out-of-bounds");
return (time_t)t;
luaL_argcheck(L, (luaport_time_t)t == t, arg, "time out-of-bounds");
return (luaport_time_t)t;
}
/* maximum size for an individual 'strftime' item */
@ -304,7 +304,7 @@ static int os_date(lua_State *L)
{
size_t slen;
const char *s = luaL_optlstring(L, 1, "%c", &slen);
time_t t = luaL_opt(L, l_checktime, 2, luaport_time(NULL));
luaport_time_t t = luaL_opt(L, l_checktime, 2, luaport_time(NULL));
const char *se = s + slen; /* 's' end */
struct tm tmr, *stm;
if (*s == '!') { /* UTC? */
@ -315,7 +315,7 @@ static int os_date(lua_State *L)
if (stm == NULL) /* invalid date? */
return luaL_error(L,
"date result cannot be represented in this installation");
if (strcmp(s, "*t") == 0) {
if (luaport_strcmp(s, "*t") == 0) {
lua_createtable(L, 0, 9); /* 9 = number of fields */
setallfields(L, stm);
} else {
@ -331,7 +331,7 @@ static int os_date(lua_State *L)
char *buff = luaL_prepbuffsize(&b, SIZETIMEFMT);
s++; /* skip '%' */
s = checkoption(L, s, se - s, cc + 1); /* copy specifier to 'cc' */
reslen = strftime(buff, SIZETIMEFMT, cc, stm);
reslen = luaport_strftime(buff, SIZETIMEFMT, cc, stm);
luaL_addsize(&b, reslen);
}
}
@ -342,9 +342,9 @@ static int os_date(lua_State *L)
static int os_time(lua_State *L)
{
time_t t;
if (lua_isnoneornil(L, 1)) /* called without args? */
t = luaport_time(NULL); /* get current time */
luaport_time_t t;
if (lua_isnoneornil(L, 1)) /* called without args? */
t = luaport_time(NULL); /* get current time */
else {
struct tm ts;
luaL_checktype(L, 1, LUA_TTABLE);
@ -356,21 +356,22 @@ static int os_time(lua_State *L)
ts.tm_min = getfield(L, "min", 0, 0);
ts.tm_sec = getfield(L, "sec", 0, 0);
ts.tm_isdst = getboolfield(L, "isdst");
t = mktime(&ts);
t = luaport_mktime(&ts);
setallfields(L, &ts); /* update fields with normalized values */
}
if (t != (time_t)(l_timet)t || t == (time_t)(-1))
return luaL_error(L,
"time result cannot be represented in this installation");
// if (t != (luaport_time_t)(l_timet)t || t == (luaport_time_t)(-1))
// return luaL_error(L,
// "time result cannot be represented in this installation");
l_pushtime(L, t);
return 1;
}
static int os_difftime(lua_State *L)
{
time_t t1 = l_checktime(L, 1);
time_t t2 = l_checktime(L, 2);
lua_pushnumber(L, (lua_Number)difftime(t1, t2));
luaport_time_t t1 = l_checktime(L, 1);
luaport_time_t t2 = l_checktime(L, 2);
lua_pushnumber(L, (lua_Number)luaport_difftime(t1, t2));
return 1;
}
@ -384,7 +385,7 @@ static int os_setlocale(lua_State *L)
"numeric", "time", NULL };
const char *l = luaL_optstring(L, 1, NULL);
int op = luaL_checkoption(L, 2, "all", catnames);
lua_pushstring(L, setlocale(cat[op], l));
lua_pushstring(L, luaport_setlocale(cat[op], l));
return 1;
}

View File

@ -29,13 +29,13 @@
/* maximum number of local variables per function (must be smaller
than 250, due to the bytecode format) */
#define MAXVARS 200
#define MAXVARS 200
#define hasmultret(k) ((k) == VCALL || (k) == VVARARG)
/* because all strings are unified by the scanner, the parser
can use pointer equality for string equality */
#define eqstr(a, b) ((a) == (b))
#define eqstr(a, b) ((a) == (b))
/*
** nodes for block list (list of active blocks)
@ -1679,9 +1679,8 @@ static void test_then_block(LexState *ls, int *escapelist)
luaX_next(ls); /* skip 'break' */
enterblock(fs, &bl, 0); /* must enter block before 'goto' */
newgotoentry(ls, luaS_newliteral(ls->L, "break"), line, v.t);
while (testnext(ls, ';')) {
} /* skip semicolons */
if (block_follow(ls, 0)) { /* jump is the entire block? */
while (testnext(ls, ';')) {} /* skip semicolons */
if (block_follow(ls, 0)) { /* jump is the entire block? */
leaveblock(fs);
return; /* and that is it */
} else /* must skip over 'then' part if condition is false */
@ -1731,9 +1730,9 @@ static int getlocalattribute(LexState *ls)
if (testnext(ls, '<')) {
const char *attr = getstr(str_checkname(ls));
checknext(ls, '>');
if (strcmp(attr, "const") == 0)
if (luaport_strcmp(attr, "const") == 0)
return RDKCONST; /* read-only variable */
else if (strcmp(attr, "close") == 0)
else if (luaport_strcmp(attr, "close") == 0)
return RDKTOCLOSE; /* to-be-closed variable */
else
luaK_semerror(ls,

View File

@ -42,7 +42,7 @@ typedef struct LG {
global_State g;
} LG;
#define fromstate(L) (cast(LX *, cast(lu_byte *, (L)) - offsetof(LX, l)))
#define fromstate(L) (cast(LX *, cast(lu_byte *, (L)) - luaport_offsetof(LX, l)))
/*
** A macro to create a "random" seed when a state is created;
@ -57,11 +57,11 @@ typedef struct LG {
** Rely on Address Space Layout Randomization (if present) and
** current time.
*/
#define addbuff(b, p, e) \
{ \
size_t t = cast_sizet(e); \
#define addbuff(b, p, e) \
{ \
size_t t = cast_sizet(e); \
luaport_memcpy(b + p, &t, sizeof(t)); \
p += sizeof(t); \
p += sizeof(t); \
}
static unsigned int luai_makeseed(lua_State *L)
@ -305,7 +305,7 @@ LUA_API lua_State *lua_newthread(lua_State *L)
resethookcount(L1);
/* initialize L1 extra space */
luaport_memcpy(lua_getextraspace(L1), lua_getextraspace(g->mainthread),
LUA_EXTRASPACE);
LUA_EXTRASPACE);
luai_userstatethread(L, L1);
stack_init(L1, L); /* init stack */
lua_unlock(L);

View File

@ -32,9 +32,9 @@ int luaS_eqlngstr(TString *a, TString *b)
{
size_t len = a->u.lnglen;
lua_assert(a->tt == LUA_VLNGSTR && b->tt == LUA_VLNGSTR);
return (a == b) || /* same instance or... */
((len == b->u.lnglen) && /* equal length and ... */
(memcmp(getstr(a), getstr(b), len) == 0)); /* equal contents */
return (a == b) || /* same instance or... */
((len == b->u.lnglen) && /* equal length and ... */
(luaport_memcmp(getstr(a), getstr(b), len) == 0)); /* equal contents */
}
unsigned int luaS_hash(const char *str, size_t l, unsigned int seed)
@ -189,7 +189,7 @@ static TString *internshrstr(lua_State *L, const char *str, size_t l)
TString **list = &tb->hash[lmod(h, tb->size)];
lua_assert(str != NULL); /* otherwise 'memcmp'/'memcpy' are undefined */
for (ts = *list; ts != NULL; ts = ts->u.hnext) {
if (l == ts->shrlen && (memcmp(str, getstr(ts), l * sizeof(char)) == 0)) {
if (l == ts->shrlen && (luaport_memcmp(str, getstr(ts), l * sizeof(char)) == 0)) {
/* found! */
if (isdead(g, ts)) /* dead (but not collected yet)? */
changewhite(ts); /* resurrect it */
@ -239,14 +239,14 @@ TString *luaS_new(lua_State *L, const char *str)
int j;
TString **p = G(L)->strcache[i];
for (j = 0; j < STRCACHE_M; j++) {
if (strcmp(str, getstr(p[j])) == 0) /* hit? */
return p[j]; /* that is it */
if (luaport_strcmp(str, getstr(p[j])) == 0) /* hit? */
return p[j]; /* that is it */
}
/* normal route */
for (j = STRCACHE_M - 1; j > 0; j--)
p[j] = p[j - 1]; /* move out last element */
/* new element is first in the list */
p[0] = luaS_newlstr(L, str, strlen(str));
p[0] = luaS_newlstr(L, str, luaport_strlen(str));
return p[0];
}

View File

@ -34,7 +34,7 @@
#endif
/* macro to 'unsign' a character */
#define uchar(c) ((unsigned char)(c))
#define uchar(c) ((unsigned char)(c))
/*
** Some sizes are better limited to fit in 'int', but must also fit in
@ -591,7 +591,7 @@ static const char *match_capture(MatchState *ms, const char *s, int l)
l = check_capture(ms, l);
len = ms->capture[l].len;
if ((size_t)(ms->src_end - s) >= len &&
memcmp(ms->capture[l].init, s, len) == 0)
luaport_memcmp(ms->capture[l].init, s, len) == 0)
return s + len;
else
return NULL;
@ -725,9 +725,9 @@ static const char *lmemfind(const char *s1, size_t l1,
const char *init; /* to search for a '*s2' inside 's1' */
l2--; /* 1st char will be checked by 'memchr' */
l1 = l1 - l2; /* 's2' cannot be found after that */
while (l1 > 0 && (init = (const char *)memchr(s1, *s2, l1)) != NULL) {
while (l1 > 0 && (init = (const char *)luaport_memchr(s1, *s2, l1)) != NULL) {
init++; /* 1st char is already checked */
if (memcmp(init, s2 + 1, l2) == 0)
if (luaport_memcmp(init, s2 + 1, l2) == 0)
return init - 1;
else { /* correct 'l1' and 's1' to try again */
l1 -= init - s1;
@ -792,9 +792,9 @@ static int nospecials(const char *p, size_t l)
{
size_t upto = 0;
do {
if (strpbrk(p + upto, SPECIALS))
return 0; /* pattern has a special character */
upto += strlen(p + upto) + 1; /* may have more after \0 */
if (luaport_strpbrk(p + upto, SPECIALS))
return 0; /* pattern has a special character */
upto += luaport_strlen(p + upto) + 1; /* may have more after \0 */
} while (upto <= l);
return 1; /* no special chars found */
}
@ -920,7 +920,7 @@ static void add_s(MatchState *ms, luaL_Buffer *b, const char *s,
lua_State *L = ms->L;
const char *news = lua_tolstring(L, 3, &l);
const char *p;
while ((p = (char *)memchr(news, L_ESC, l)) != NULL) {
while ((p = (char *)luaport_memchr(news, L_ESC, l)) != NULL) {
luaL_addlstring(b, news, p - news);
p++; /* skip ESC */
if (*p == L_ESC) /* '%%' */
@ -1049,7 +1049,7 @@ static int str_gsub(lua_State *L)
** to nibble boundaries by making what is left after that first digit a
** multiple of 4.
*/
#define L_NBFD ((l_floatatt(MANT_DIG) - 1) % 4 + 1)
#define L_NBFD ((l_floatatt(MANT_DIG) - 1) % 4 + 1)
/*
** Add integer part of 'x' to buffer and return new 'x'
@ -1125,7 +1125,7 @@ static int lua_number2strx(lua_State *L, char *buff, int sz,
** worst case are floats: they may need 99 significant digits, plus
** '0x', '-', '.', 'e+XXXX', and '\0'. Adding some extra, 120.
*/
#define MAX_ITEM 120
#define MAX_ITEM 120
/* valid flags in a format specification */
#if !defined(L_FMTFLAGSF)
@ -1195,9 +1195,9 @@ static int quotefloat(lua_State *L, char *buff, lua_Number n)
int nb = lua_number2strx(L, buff, MAX_ITEM,
"%" LUA_NUMBER_FRMLEN "a", n);
/* ensures that 'buff' string uses a dot as the radix character */
if (memchr(buff, '.', nb) == NULL) { /* no dot? */
char point = lua_getlocaledecpoint(); /* try locale point */
char *ppoint = (char *)memchr(buff, point, nb);
if (luaport_memchr(buff, '.', nb) == NULL) { /* no dot? */
char point = lua_getlocaledecpoint(); /* try locale point */
char *ppoint = (char *)luaport_memchr(buff, point, nb);
if (ppoint)
*ppoint = '.'; /* change it to a dot */
}
@ -1219,11 +1219,9 @@ static void addliteral(lua_State *L, luaL_Buffer *b, int arg)
case LUA_TNUMBER: {
char *buff = luaL_prepbuffsize(b, MAX_ITEM);
int nb;
if (!lua_isinteger(L, arg)) { /* float? */
luaL_error(L, "specifier '%%q' not supported yet in this dft_platform build");
return;
if (!lua_isinteger(L, arg)) /* float? */
nb = quotefloat(L, buff, lua_tonumber(L, arg));
} else { /* integers */
else { /* integers */
lua_Integer n = lua_tointeger(L, arg);
const char *format = (n == LUA_MININTEGER) /* corner case? */
?
@ -1266,10 +1264,10 @@ static const char *get2digits(const char *s)
static void checkformat(lua_State *L, const char *form, const char *flags,
int precision)
{
const char *spec = form + 1; /* skip '%' */
spec += strspn(spec, flags); /* skip flags */
if (*spec != '0') { /* a width cannot start with '0' */
spec = get2digits(spec); /* skip width */
const char *spec = form + 1; /* skip '%' */
spec += luaport_strspn(spec, flags); /* skip flags */
if (*spec != '0') { /* a width cannot start with '0' */
spec = get2digits(spec); /* skip width */
if (*spec == '.' && precision) {
spec++;
spec = get2digits(spec); /* skip precision */
@ -1287,7 +1285,7 @@ static const char *getformat(lua_State *L, const char *strfrmt,
char *form)
{
/* spans flags, width, and precision ('0' is included as a flag) */
size_t len = strspn(strfrmt, L_FMTFLAGSF "123456789.");
size_t len = luaport_strspn(strfrmt, L_FMTFLAGSF "123456789.");
len++; /* adds following character (should be the specifier) */
/* still needs space for '%', '\0', plus a length modifier */
if (len >= MAX_FORMAT - 10)
@ -1303,10 +1301,10 @@ static const char *getformat(lua_State *L, const char *strfrmt,
*/
static void addlenmod(char *form, const char *lenmod)
{
size_t l = strlen(form);
size_t lm = strlen(lenmod);
size_t l = luaport_strlen(form);
size_t lm = luaport_strlen(lenmod);
char spec = form[l - 1];
strcpy(form + l - 1, lenmod);
luaport_strcpy(form + l - 1, lenmod);
form[l + lm - 1] = spec;
form[l + lm] = '\0';
}
@ -1360,7 +1358,6 @@ static int str_format(lua_State *L)
}
case 'a':
case 'A':
return luaL_error(L, "specifier '%%a' or '%%A' not supported yet in this dft_platform build");
checkformat(L, form, L_FMTFLAGSF, 1);
addlenmod(form, LUA_NUMBER_FRMLEN);
nb = lua_number2strx(L, buff, maxitem, form,
@ -1383,9 +1380,9 @@ static int str_format(lua_State *L)
case 'p': {
const void *p = lua_topointer(L, arg);
checkformat(L, form, L_FMTFLAGSC, 0);
if (p == NULL) { /* avoid calling 'printf' with argument NULL */
p = "(null)"; /* result */
form[strlen(form) - 1] = 's'; /* format it as a string */
if (p == NULL) { /* avoid calling 'printf' with argument NULL */
p = "(null)"; /* result */
form[luaport_strlen(form) - 1] = 's'; /* format it as a string */
}
nb = l_sprintf(buff, maxitem, form, p);
break;
@ -1402,9 +1399,9 @@ static int str_format(lua_State *L)
if (form[2] == '\0') /* no modifiers? */
luaL_addvalue(&b); /* keep entire string */
else {
luaL_argcheck(L, l == strlen(s), arg, "string contains zeros");
luaL_argcheck(L, l == luaport_strlen(s), arg, "string contains zeros");
checkformat(L, form, L_FMTFLAGSC, 1);
if (strchr(form, '.') == NULL && l >= 100) {
if (luaport_strchr(form, '.') == NULL && l >= 100) {
/* no precision and string is too long to be formatted */
luaL_addvalue(&b); /* keep entire string */
} else { /* format the string into 'buff' */
@ -1443,13 +1440,13 @@ static int str_format(lua_State *L)
#define MAXINTSIZE 16
/* number of bits in a character */
#define NB CHAR_BIT
#define NB CHAR_BIT
/* mask for one character (NB 1's) */
#define MC ((1 << NB) - 1)
#define MC ((1 << NB) - 1)
/* size of a lua_Integer */
#define SZINT ((int)sizeof(lua_Integer))
#define SZINT ((int)sizeof(lua_Integer))
/* dummy union to get native endianness */
static const union {
@ -1612,7 +1609,7 @@ static KOption getoption(Header *h, const char **fmt, int *size)
h->islittle = nativeendian.little;
break;
case '!': {
const int maxalign = offsetof(struct cD, u);
const int maxalign = luaport_offsetof(struct cD, u);
h->maxalign = getnumlimit(h, fmt, maxalign);
break;
}
@ -1773,7 +1770,7 @@ static int str_pack(lua_State *L)
case Kzstr: { /* zero-terminated string */
size_t len;
const char *s = luaL_checklstring(L, arg, &len);
luaL_argcheck(L, strlen(s) == len, arg, "string contains zeros");
luaL_argcheck(L, luaport_strlen(s) == len, arg, "string contains zeros");
luaL_addlstring(&b, s, len);
luaL_addchar(&b, '\0'); /* add zero at the end */
totalsize += len + 1;
@ -1901,7 +1898,7 @@ static int str_unpack(lua_State *L)
break;
}
case Kzstr: {
size_t len = strlen(data + pos);
size_t len = luaport_strlen(data + pos);
luaL_argcheck(L, pos + len < ld, 2,
"unfinished string for format 'z'");
lua_pushlstring(L, data + pos, len);

View File

@ -41,46 +41,46 @@
** MAXABITS is the largest integer such that MAXASIZE fits in an
** unsigned int.
*/
#define MAXABITS cast_int(sizeof(int) * CHAR_BIT - 1)
#define MAXABITS cast_int(sizeof(int) * CHAR_BIT - 1)
/*
** MAXASIZE is the maximum size of the array part. It is the minimum
** between 2^MAXABITS and the maximum size that, measured in bytes,
** fits in a 'size_t'.
*/
#define MAXASIZE luaM_limitN(1u << MAXABITS, TValue)
#define MAXASIZE luaM_limitN(1u << MAXABITS, TValue)
/*
** MAXHBITS is the largest integer such that 2^MAXHBITS fits in a
** signed int.
*/
#define MAXHBITS (MAXABITS - 1)
#define MAXHBITS (MAXABITS - 1)
/*
** MAXHSIZE is the maximum size of the hash part. It is the minimum
** between 2^MAXHBITS and the maximum size such that, measured in bytes,
** it fits in a 'size_t'.
*/
#define MAXHSIZE luaM_limitN(1u << MAXHBITS, Node)
#define MAXHSIZE luaM_limitN(1u << MAXHBITS, Node)
/*
** When the original hash value is good, hashing by a power of 2
** avoids the cost of '%'.
*/
#define hashpow2(t, n) (gnode(t, lmod((n), sizenode(t))))
#define hashpow2(t, n) (gnode(t, lmod((n), sizenode(t))))
/*
** for other types, it is better to avoid modulo by power of 2, as
** they can have many 2 factors.
*/
#define hashmod(t, n) (gnode(t, ((n) % ((sizenode(t) - 1) | 1))))
#define hashmod(t, n) (gnode(t, ((n) % ((sizenode(t) - 1) | 1))))
#define hashstr(t, str) hashpow2(t, (str)->hash)
#define hashboolean(t, p) hashpow2(t, p)
#define hashpointer(t, p) hashmod(t, point2uint(p))
#define dummynode (&dummynode_)
#define dummynode (&dummynode_)
static const Node dummynode_ = {
{ { NULL }, LUA_VEMPTY, /* value's value and type */

View File

@ -22,10 +22,10 @@
** Operations that an object must define to mimic a table
** (some functions only need some of them)
*/
#define TAB_R 1 /* read */
#define TAB_W 2 /* write */
#define TAB_L 4 /* length */
#define TAB_RW (TAB_R | TAB_W) /* read/write */
#define TAB_R 1 /* read */
#define TAB_W 2 /* write */
#define TAB_L 4 /* length */
#define TAB_RW (TAB_R | TAB_W) /* read/write */
#define aux_getn(L, n, w) (checktab(L, n, (w) | TAB_L), luaL_len(L, n))
@ -238,7 +238,7 @@ typedef unsigned int IdxT;
static unsigned int l_randomizePivot(void)
{
clock_t c = luaport_clock();
time_t t = luaport_time(NULL);
luaport_time_t t = luaport_time(NULL);
unsigned int buff[sof(c) + sof(t)];
unsigned int i, rnd = 0;
luaport_memcpy(buff, &c, sof(c) * sizeof(unsigned int));

View File

@ -267,9 +267,9 @@ static void loadFunction(LoadState *S, Proto *f, TString *psource)
static void checkliteral(LoadState *S, const char *s, const char *msg)
{
char buff[sizeof(LUA_SIGNATURE) + sizeof(LUAC_DATA)]; /* larger than both */
size_t len = strlen(s);
size_t len = luaport_strlen(s);
loadVector(S, buff, len);
if (memcmp(s, buff, len) != 0)
if (luaport_memcmp(s, buff, len) != 0)
error(S, msg);
}

View File

@ -21,7 +21,7 @@
#define MAXUNICODE 0x10FFFFu
#define MAXUTF 0x7FFFFFFFu
#define MAXUTF 0x7FFFFFFFu
/*
** Integer type for decoded UTF-8 values; MAXUTF needs 31 bits.

View File

@ -51,7 +51,7 @@
*/
/* number of bits in the mantissa of a float */
#define NBM (l_floatatt(MANT_DIG))
#define NBM (l_floatatt(MANT_DIG))
/*
** Check whether some integers may not fit in a float, testing whether
@ -63,7 +63,7 @@
#if ((((LUA_MAXINTEGER >> (NBM / 4)) >> (NBM / 4)) >> (NBM / 4)) >> (NBM - (3 * (NBM / 4)))) > 0
/* limit for integers that fit in a float */
#define MAXINTFITSF ((lua_Unsigned)1 << NBM)
#define MAXINTFITSF ((lua_Unsigned)1 << NBM)
/* check whether 'i' is in the interval [-MAXINTFITSF, MAXINTFITSF] */
#define l_intfitsf(i) ((MAXINTFITSF + l_castS2U(i)) <= (2 * MAXINTFITSF))
@ -367,11 +367,11 @@ static int l_strcmp(const TString *ls, const TString *rs)
const char *r = getstr(rs);
size_t lr = tsslen(rs);
for (;;) { /* for each segment */
int temp = strcoll(l, r);
int temp = luaport_strcoll(l, r);
if (temp != 0) /* not equal? */
return temp; /* done */
else { /* strings are equal up to a '\0' */
size_t len = strlen(l); /* index of first '\0' in both strings */
size_t len = luaport_strlen(l); /* index of first '\0' in both strings */
if (len == lr) /* 'rs' is finished? */
return (len == ll) ? 0 : 1; /* check 'ls' */
else if (len == ll) /* 'ls' is finished? */
@ -762,7 +762,7 @@ lua_Number luaV_modf(lua_State *L, lua_Number m, lua_Number n)
}
/* number of bits in an integer */
#define NBITS cast_int(sizeof(lua_Integer) * CHAR_BIT)
#define NBITS cast_int(sizeof(lua_Integer) * CHAR_BIT)
/*
** Shift left operation. (Shift right just negates 'y'.)
@ -898,10 +898,10 @@ void luaV_finishOp(lua_State *L)
#define l_bor(a, b) intop(|, a, b)
#define l_bxor(a, b) intop(^, a, b)
#define l_lti(a, b) (a < b)
#define l_lei(a, b) (a <= b)
#define l_gti(a, b) (a > b)
#define l_gei(a, b) (a >= b)
#define l_lti(a, b) (a < b)
#define l_lei(a, b) (a <= b)
#define l_gti(a, b) (a > b)
#define l_gei(a, b) (a >= b)
/*
** Arithmetic operations with immediate operands. 'iop' is the integer
@ -1076,14 +1076,14 @@ void luaV_finishOp(lua_State *L)
** some macros for common tasks in 'luaV_execute'
*/
#define RA(i) (base + GETARG_A(i))
#define RB(i) (base + GETARG_B(i))
#define vRB(i) s2v(RB(i))
#define KB(i) (k + GETARG_B(i))
#define RC(i) (base + GETARG_C(i))
#define vRC(i) s2v(RC(i))
#define KC(i) (k + GETARG_C(i))
#define RKC(i) ((TESTARG_k(i)) ? k + GETARG_C(i) : s2v(base + GETARG_C(i)))
#define RA(i) (base + GETARG_A(i))
#define RB(i) (base + GETARG_B(i))
#define vRB(i) s2v(RB(i))
#define KB(i) (k + GETARG_B(i))
#define RC(i) (base + GETARG_C(i))
#define vRC(i) s2v(RC(i))
#define KC(i) (k + GETARG_C(i))
#define RKC(i) ((TESTARG_k(i)) ? k + GETARG_C(i) : s2v(base + GETARG_C(i)))
#define updatetrap(ci) (trap = ci->u.l.trap)
@ -1128,7 +1128,7 @@ void luaV_finishOp(lua_State *L)
/*
** Correct global 'pc'.
*/
#define savepc(L) (ci->u.l.savedpc = pc)
#define savepc(L) (ci->u.l.savedpc = pc)
/*
** Whenever code can raise errors, the global 'pc' and the global
@ -1140,10 +1140,10 @@ void luaV_finishOp(lua_State *L)
** Protect code that, in general, can raise errors, reallocate the
** stack, and change the hooks.
*/
#define Protect(exp) (savestate(L, ci), (exp), updatetrap(ci))
#define Protect(exp) (savestate(L, ci), (exp), updatetrap(ci))
/* special version that does not change the top */
#define ProtectNT(exp) (savepc(L), (exp), updatetrap(ci))
#define ProtectNT(exp) (savepc(L), (exp), updatetrap(ci))
/*
** Protect code that can only raise errors. (That is, it cannot change
@ -1207,7 +1207,7 @@ returning: /* trap already set */
vmfetch();
#if 0
/* low-level line tracing for debugging Lua */
printf("line: %d\n", luaG_getfuncline(cl->p, pcRel(pc, cl->p)));
luaport_printf("line: %d\n", luaG_getfuncline(cl->p, pcRel(pc, cl->p)));
#endif
lua_assert(base == ci->func + 1);
lua_assert(base <= L->top && L->top < L->stack_last);

View File

@ -0,0 +1,754 @@
/*
** $Id: luaconf.h $
** Configuration file for Lua
** See Copyright Notice in lua.h
*/
#ifndef luaconf_h
#define luaconf_h
#include <limits.h>
#include <stddef.h>
#include "luaport.h"
/*
** ===================================================================
** General Configuration File for Lua
**
** Some definitions here can be changed externally, through the compiler
** (e.g., with '-D' options): They are commented out or protected
** by '#if !defined' guards. However, several other definitions
** should be changed directly here, either because they affect the
** Lua ABI (by making the changes here, you ensure that all software
** connected to Lua, such as C libraries, will be compiled with the same
** configuration); or because they are seldom changed.
**
** Search for "@@" to find all configurable definitions.
** ===================================================================
*/
/*
** {====================================================================
** System Configuration: macros to adapt (if needed) Lua to some
** particular platform, for instance restricting it to C89.
** =====================================================================
*/
/*
@@ LUA_USE_C89 controls the use of non-ISO-C89 features.
** Define it if you want Lua to avoid the use of a few C99 features
** or Windows-specific features on Windows.
*/
/* #define LUA_USE_C89 */
/*
** By default, Lua on Windows use (some) specific Windows features
*/
#if !defined(LUA_USE_C89) && defined(_WIN32) && !defined(_WIN32_WCE)
#define LUA_USE_WINDOWS /* enable goodies for regular Windows */
#endif
#if defined(LUA_USE_WINDOWS)
// #define LUA_DL_DLL /* enable support for DLL */
#define LUA_USE_C89 /* broadly, Windows is C89 */
#endif
#if defined(LUA_USE_LINUX)
// #define LUA_USE_POSIX
// #define LUA_USE_DLOPEN /* needs an extra library: -ldl */
#endif
#if defined(LUA_USE_MACOSX)
// #define LUA_USE_POSIX
// #define LUA_USE_DLOPEN /* MacOS does not need -ldl */
#endif
#if defined(LUA_USE_MCU)
// #define LUA_USE_POSIX
#endif
/*
@@ LUAI_IS32INT is true iff 'int' has (at least) 32 bits.
*/
#define LUAI_IS32INT ((UINT_MAX >> 30) >= 3)
/* }================================================================== */
/*
** {==================================================================
** Configuration for Number types. These options should not be
** set externally, because any other code connected to Lua must
** use the same configuration.
** ===================================================================
*/
/*
@@ LUA_INT_TYPE defines the type for Lua integers.
@@ LUA_FLOAT_TYPE defines the type for Lua floats.
** Lua should work fine with any mix of these options supported
** by your C compiler. The usual configurations are 64-bit integers
** and 'double' (the default), 32-bit integers and 'float' (for
** restricted platforms), and 'long'/'double' (for C compilers not
** compliant with C99, which may not have support for 'long long').
*/
/* predefined options for LUA_INT_TYPE */
#define LUA_INT_INT 1
#define LUA_INT_LONG 2
#define LUA_INT_LONGLONG 3
/* predefined options for LUA_FLOAT_TYPE */
#define LUA_FLOAT_FLOAT 1
#define LUA_FLOAT_DOUBLE 2
#define LUA_FLOAT_LONGDOUBLE 3
/* Default configuration ('long long' and 'double', for 64-bit Lua) */
#define LUA_INT_DEFAULT LUA_INT_LONGLONG
#define LUA_FLOAT_DEFAULT LUA_FLOAT_FLOAT
/*
@@ LUA_32BITS enables Lua with 32-bit integers and 32-bit floats.
*/
#define LUA_32BITS 0
/*
@@ LUA_C89_NUMBERS ensures that Lua uses the largest types available for
** C89 ('long' and 'double'); Windows always has '__int64', so it does
** not need to use this case.
*/
#if defined(LUA_USE_C89) && !defined(LUA_USE_WINDOWS)
#define LUA_C89_NUMBERS 1
#else
#define LUA_C89_NUMBERS 0
#endif
#if LUA_32BITS /* { */
/*
** 32-bit integers and 'float'
*/
#if LUAI_IS32INT /* use 'int' if big enough */
#define LUA_INT_TYPE LUA_INT_INT
#else /* otherwise use 'long' */
#define LUA_INT_TYPE LUA_INT_LONG
#endif
#define LUA_FLOAT_TYPE LUA_FLOAT_FLOAT
#elif LUA_C89_NUMBERS /* }{ */
/*
** largest types available for C89 ('long' and 'double')
*/
#define LUA_INT_TYPE LUA_INT_LONG
#define LUA_FLOAT_TYPE LUA_FLOAT_DOUBLE
#else /* }{ */
/* use defaults */
#define LUA_INT_TYPE LUA_INT_DEFAULT
#define LUA_FLOAT_TYPE LUA_FLOAT_DEFAULT
#endif /* } */
/* }================================================================== */
/*
** {==================================================================
** Configuration for Paths.
** ===================================================================
*/
/*
** LUA_PATH_SEP is the character that separates templates in a path.
** LUA_PATH_MARK is the string that marks the substitution points in a
** template.
** LUA_EXEC_DIR in a Windows path is replaced by the executable's
** directory.
*/
#define LUA_PATH_SEP ";"
#define LUA_PATH_MARK "?"
#define LUA_EXEC_DIR "!"
/*
@@ LUA_PATH_DEFAULT is the default path that Lua uses to look for
** Lua libraries.
@@ LUA_CPATH_DEFAULT is the default path that Lua uses to look for
** C libraries.
** CHANGE them if your machine has a non-conventional directory
** hierarchy or if you want to install your libraries in
** non-conventional directories.
*/
#define LUA_VDIR LUA_VERSION_MAJOR "." LUA_VERSION_MINOR
#if defined(_WIN32) /* { */
/*
** In Windows, any exclamation mark ('!') in the path is replaced by the
** path of the directory of the executable file of the current process.
*/
#define LUA_LDIR "!\\lua\\"
#define LUA_CDIR "!\\"
#define LUA_SHRDIR "!\\..\\share\\lua\\" LUA_VDIR "\\"
#if !defined(LUA_PATH_DEFAULT)
#define LUA_PATH_DEFAULT \
LUA_LDIR "?.lua;" LUA_LDIR "?\\init.lua;" LUA_CDIR "?.lua;" LUA_CDIR "?\\init.lua;" LUA_SHRDIR "?.lua;" LUA_SHRDIR "?\\init.lua;" \
".\\?.lua;" \
".\\?\\init.lua"
#endif
#if !defined(LUA_CPATH_DEFAULT)
#define LUA_CPATH_DEFAULT \
LUA_CDIR "?.dll;" LUA_CDIR "..\\lib\\lua\\" LUA_VDIR "\\?.dll;" LUA_CDIR "loadall.dll;" \
".\\?.dll"
#endif
#elif defined(LUA_USE_MCU) /* }{ */
#define LUA_ROOT "/sd/"
#define LUA_LDIR LUA_ROOT "share/lua/" LUA_VDIR "/"
#define LUA_CDIR LUA_ROOT "lib/lua/" LUA_VDIR "/"
#if !defined(LUA_PATH_DEFAULT)
#define LUA_PATH_DEFAULT \
LUA_LDIR "?.lua;" LUA_LDIR "?/init.lua;" LUA_CDIR "?.lua;" LUA_CDIR "?/init.lua;" \
"./?.lua;" \
"./?/init.lua"
#endif
#if !defined(LUA_CPATH_DEFAULT)
#define LUA_CPATH_DEFAULT \
LUA_CDIR "?.so;" LUA_CDIR "loadall.so;" \
"./?.so"
#endif
#else /* }{ */
#define LUA_ROOT "/usr/local/"
#define LUA_LDIR LUA_ROOT "share/lua/" LUA_VDIR "/"
#define LUA_CDIR LUA_ROOT "lib/lua/" LUA_VDIR "/"
#if !defined(LUA_PATH_DEFAULT)
#define LUA_PATH_DEFAULT \
LUA_LDIR "?.lua;" LUA_LDIR "?/init.lua;" LUA_CDIR "?.lua;" LUA_CDIR "?/init.lua;" \
"./?.lua;" \
"./?/init.lua"
#endif
#if !defined(LUA_CPATH_DEFAULT)
#define LUA_CPATH_DEFAULT \
LUA_CDIR "?.so;" LUA_CDIR "loadall.so;" \
"./?.so"
#endif
#endif /* } */
/*
@@ LUA_DIRSEP is the directory separator (for submodules).
** CHANGE it if your machine does not use "/" as the directory separator
** and is not Windows. (On Windows Lua automatically uses "\".)
*/
#if !defined(LUA_DIRSEP)
#if defined(_WIN32)
#define LUA_DIRSEP "\\"
#else
#define LUA_DIRSEP "/"
#endif
#endif
/* }================================================================== */
/*
** {==================================================================
** Marks for exported symbols in the C code
** ===================================================================
*/
/*
@@ LUA_API is a mark for all core API functions.
@@ LUALIB_API is a mark for all auxiliary library functions.
@@ LUAMOD_API is a mark for all standard library opening functions.
** CHANGE them if you need to define those functions in some special way.
** For instance, if you want to create one Windows DLL with the core and
** the libraries, you may want to use the following definition (define
** LUA_BUILD_AS_DLL to get it).
*/
#if defined(LUA_BUILD_AS_DLL) /* { */
#if defined(LUA_CORE) || defined(LUA_LIB) /* { */
#define LUA_API __declspec(dllexport)
#else /* }{ */
#define LUA_API __declspec(dllimport)
#endif /* } */
#else /* }{ */
#define LUA_API extern
#endif /* } */
/*
** More often than not the libs go together with the core.
*/
#define LUALIB_API LUA_API
#define LUAMOD_API LUA_API
/*
@@ LUAI_FUNC is a mark for all extern functions that are not to be
** exported to outside modules.
@@ LUAI_DDEF and LUAI_DDEC are marks for all extern (const) variables,
** none of which to be exported to outside modules (LUAI_DDEF for
** definitions and LUAI_DDEC for declarations).
** CHANGE them if you need to mark them in some special way. Elf/gcc
** (versions 3.2 and later) mark them as "hidden" to optimize access
** when Lua is compiled as a shared library. Not all elf targets support
** this attribute. Unfortunately, gcc does not offer a way to check
** whether the target offers that support, and those without support
** give a warning about it. To avoid these warnings, change to the
** default definition.
*/
#if defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 302) && \
defined(__ELF__) /* { */
#define LUAI_FUNC __attribute__((visibility("internal"))) extern
#else /* }{ */
#define LUAI_FUNC extern
#endif /* } */
#define LUAI_DDEC(dec) LUAI_FUNC dec
#define LUAI_DDEF /* empty */
/* }================================================================== */
/*
** {==================================================================
** Compatibility with previous versions
** ===================================================================
*/
/*
@@ LUA_COMPAT_5_3 controls other macros for compatibility with Lua 5.3.
** You can define it to get all options, or change specific options
** to fit your specific needs.
*/
#if defined(LUA_COMPAT_5_3) /* { */
/*
@@ LUA_COMPAT_MATHLIB controls the presence of several deprecated
** functions in the mathematical library.
** (These functions were already officially removed in 5.3;
** nevertheless they are still available here.)
*/
#define LUA_COMPAT_MATHLIB
/*
@@ LUA_COMPAT_APIINTCASTS controls the presence of macros for
** manipulating other integer types (lua_pushunsigned, lua_tounsigned,
** luaL_checkint, luaL_checklong, etc.)
** (These macros were also officially removed in 5.3, but they are still
** available here.)
*/
#define LUA_COMPAT_APIINTCASTS
/*
@@ LUA_COMPAT_LT_LE controls the emulation of the '__le' metamethod
** using '__lt'.
*/
#define LUA_COMPAT_LT_LE
/*
@@ The following macros supply trivial compatibility for some
** changes in the API. The macros themselves document how to
** change your code to avoid using them.
** (Once more, these macros were officially removed in 5.3, but they are
** still available here.)
*/
#define lua_strlen(L, i) lua_rawlen(L, (i))
#define lua_objlen(L, i) lua_rawlen(L, (i))
#define lua_equal(L, idx1, idx2) lua_compare(L, (idx1), (idx2), LUA_OPEQ)
#define lua_lessthan(L, idx1, idx2) lua_compare(L, (idx1), (idx2), LUA_OPLT)
#endif /* } */
/* }================================================================== */
/*
** {==================================================================
** Configuration for Numbers (low-level part).
** Change these definitions if no predefined LUA_FLOAT_* / LUA_INT_*
** satisfy your needs.
** ===================================================================
*/
/*
@@ LUAI_UACNUMBER is the result of a 'default argument promotion'
@@ over a floating number.
@@ l_floatatt(x) corrects float attribute 'x' to the proper float type
** by prefixing it with one of FLT/DBL/LDBL.
@@ LUA_NUMBER_FRMLEN is the length modifier for writing floats.
@@ LUA_NUMBER_FMT is the format for writing floats.
@@ lua_number2str converts a float to a string.
@@ l_mathop allows the addition of an 'l' or 'f' to all math operations.
@@ l_floor takes the floor of a float.
@@ lua_str2number converts a decimal numeral to a number.
*/
/* The following definitions are good for most cases here */
#define l_floor(x) (l_mathop(floor)(x))
#define lua_number2str(s, sz, n) \
l_sprintf((s), sz, LUA_NUMBER_FMT, (LUAI_UACNUMBER)(n))
/*
@@ lua_numbertointeger converts a float number with an integral value
** to an integer, or returns 0 if float is not within the range of
** a lua_Integer. (The range comparisons are tricky because of
** rounding. The tests here assume a two-complement representation,
** where MININTEGER always has an exact representation as a float;
** MAXINTEGER may not have one, and therefore its conversion to float
** may have an ill-defined value.)
*/
#define lua_numbertointeger(n, p) \
((n) >= (LUA_NUMBER)(LUA_MININTEGER) && \
(n) < -(LUA_NUMBER)(LUA_MININTEGER) && \
(*(p) = (LUA_INTEGER)(n), 1))
/* now the variable definitions */
#if LUA_FLOAT_TYPE == LUA_FLOAT_FLOAT /* { single float */
#define LUA_NUMBER float
#define l_floatatt(n) (FLT_##n)
#define LUAI_UACNUMBER double
#define LUA_NUMBER_FRMLEN ""
#define LUA_NUMBER_FMT "%.7g"
#define l_mathop(op) op##f
#define lua_str2number(s, p) luaport_strtof((s), (p))
#elif LUA_FLOAT_TYPE == LUA_FLOAT_LONGDOUBLE /* }{ long double */
#define LUA_NUMBER long double
#define l_floatatt(n) (LDBL_##n)
#define LUAI_UACNUMBER long double
#define LUA_NUMBER_FRMLEN "L"
#define LUA_NUMBER_FMT "%.19Lg"
#define l_mathop(op) op##l
#define lua_str2number(s, p) strtold((s), (p))
#elif LUA_FLOAT_TYPE == LUA_FLOAT_DOUBLE /* }{ double */
#define LUA_NUMBER double
#define l_floatatt(n) (DBL_##n)
#define LUAI_UACNUMBER double
#define LUA_NUMBER_FRMLEN ""
#define LUA_NUMBER_FMT "%.14g"
#define l_mathop(op) op
#define lua_str2number(s, p) luaport_strtod((s), (p))
#else /* }{ */
#error "numeric float type not defined"
#endif /* } */
/*
@@ LUA_UNSIGNED is the unsigned version of LUA_INTEGER.
@@ LUAI_UACINT is the result of a 'default argument promotion'
@@ over a LUA_INTEGER.
@@ LUA_INTEGER_FRMLEN is the length modifier for reading/writing integers.
@@ LUA_INTEGER_FMT is the format for writing integers.
@@ LUA_MAXINTEGER is the maximum value for a LUA_INTEGER.
@@ LUA_MININTEGER is the minimum value for a LUA_INTEGER.
@@ LUA_MAXUNSIGNED is the maximum value for a LUA_UNSIGNED.
@@ lua_integer2str converts an integer to a string.
*/
/* The following definitions are good for most cases here */
#define LUA_INTEGER_FMT "%" LUA_INTEGER_FRMLEN "d"
#define LUAI_UACINT LUA_INTEGER
#define lua_integer2str(s, sz, n) \
l_sprintf((s), sz, LUA_INTEGER_FMT, (LUAI_UACINT)(n))
/*
** use LUAI_UACINT here to avoid problems with promotions (which
** can turn a comparison between unsigneds into a signed comparison)
*/
#define LUA_UNSIGNED unsigned LUAI_UACINT
/* now the variable definitions */
#if LUA_INT_TYPE == LUA_INT_INT /* { int */
#define LUA_INTEGER int
#define LUA_INTEGER_FRMLEN ""
#define LUA_MAXINTEGER INT_MAX
#define LUA_MININTEGER INT_MIN
#define LUA_MAXUNSIGNED UINT_MAX
#elif LUA_INT_TYPE == LUA_INT_LONG /* }{ long */
#define LUA_INTEGER long
#define LUA_INTEGER_FRMLEN "l"
#define LUA_MAXINTEGER LONG_MAX
#define LUA_MININTEGER LONG_MIN
#define LUA_MAXUNSIGNED ULONG_MAX
#elif LUA_INT_TYPE == LUA_INT_LONGLONG /* }{ long long */
/* use presence of macro LLONG_MAX as proxy for C99 compliance */
#if defined(LLONG_MAX) /* { */
/* use ISO C99 stuff */
#define LUA_INTEGER long long
#define LUA_INTEGER_FRMLEN "ll"
#define LUA_MAXINTEGER LLONG_MAX
#define LUA_MININTEGER LLONG_MIN
#define LUA_MAXUNSIGNED ULLONG_MAX
#elif defined(LUA_USE_WINDOWS) /* }{ */
/* in Windows, can use specific Windows types */
#define LUA_INTEGER __int64
#define LUA_INTEGER_FRMLEN "I64"
#define LUA_MAXINTEGER _I64_MAX
#define LUA_MININTEGER _I64_MIN
#define LUA_MAXUNSIGNED _UI64_MAX
#else /* }{ */
#error "Compiler does not support 'long long'. Use option '-DLUA_32BITS' \
or '-DLUA_C89_NUMBERS' (see file 'luaconf.h' for details)"
#endif /* } */
#else /* }{ */
#error "numeric integer type not defined"
#endif /* } */
/* }================================================================== */
/*
** {==================================================================
** Dependencies with C99 and other C details
** ===================================================================
*/
/*
@@ l_sprintf is equivalent to 'snprintf' or 'sprintf' in C89.
** (All uses in Lua have only one format item.)
*/
#if !defined(LUA_USE_C89)
#define l_sprintf(s, sz, f, i) luaport_snprintf(s, sz, f, i)
#else
#define l_sprintf(s, sz, f, i) ((void)(sz), luaport_sprintf(s, f, i))
#endif
/*
@@ lua_strx2number converts a hexadecimal numeral to a number.
** In C99, 'strtod' does that conversion. Otherwise, you can
** leave 'lua_strx2number' undefined and Lua will provide its own
** implementation.
*/
#if !defined(LUA_USE_C89)
#define lua_strx2number(s, p) lua_str2number(s, p)
#endif
/*
@@ lua_pointer2str converts a pointer to a readable string in a
** non-specified way.
*/
#define lua_pointer2str(buff, sz, p) l_sprintf(buff, sz, "%p", p)
/*
@@ lua_number2strx converts a float to a hexadecimal numeral.
** In C99, 'sprintf' (with format specifiers '%a'/'%A') does that.
** Otherwise, you can leave 'lua_number2strx' undefined and Lua will
** provide its own implementation.
*/
#if !defined(LUA_USE_C89)
#define lua_number2strx(L, b, sz, f, n) \
((void)L, l_sprintf(b, sz, f, (LUAI_UACNUMBER)(n)))
#endif
/*
** 'strtof' and 'opf' variants for math functions are not valid in
** C89. Otherwise, the macro 'HUGE_VALF' is a good proxy for testing the
** availability of these variants. ('math.h' is already included in
** all files that use these macros.)
*/
#if defined(LUA_USE_C89) || (defined(HUGE_VAL) && !defined(HUGE_VALF))
#undef l_mathop /* variants not available */
#undef lua_str2number
#define l_mathop(op) (lua_Number) op /* no variant */
#define lua_str2number(s, p) ((lua_Number)luaport_strtod((s), (p)))
#endif
/*
@@ LUA_KCONTEXT is the type of the context ('ctx') for continuation
** functions. It must be a numerical type; Lua will use 'intptr_t' if
** available, otherwise it will use 'ptrdiff_t' (the nearest thing to
** 'intptr_t' in C89)
*/
#define LUA_KCONTEXT ptrdiff_t
#if !defined(LUA_USE_C89) && defined(__STDC_VERSION__) && \
__STDC_VERSION__ >= 199901L
#include <stdint.h>
#if defined(INTPTR_MAX) /* even in C99 this type is optional */
#undef LUA_KCONTEXT
#define LUA_KCONTEXT intptr_t
#endif
#endif
/*
@@ lua_getlocaledecpoint gets the locale "radix character" (decimal point).
** Change that if you do not want to use C locales. (Code using this
** macro must include the header 'locale.h'.)
*/
#if !defined(lua_getlocaledecpoint)
#define lua_getlocaledecpoint() (luaport_localeconv()->decimal_point[0])
#endif
/*
** macros to improve jump prediction, used mostly for error handling
** and debug facilities. (Some macros in the Lua API use these macros.
** Define LUA_NOBUILTIN if you do not want '__builtin_expect' in your
** code.)
*/
#if !defined(luai_likely)
#if defined(__GNUC__) && !defined(LUA_NOBUILTIN)
#define luai_likely(x) (__builtin_expect(((x) != 0), 1))
#define luai_unlikely(x) (__builtin_expect(((x) != 0), 0))
#else
#define luai_likely(x) (x)
#define luai_unlikely(x) (x)
#endif
#endif
#if defined(LUA_CORE) || defined(LUA_LIB)
/* shorter names for Lua's own use */
#define l_likely(x) luai_likely(x)
#define l_unlikely(x) luai_unlikely(x)
#endif
/* }================================================================== */
/*
** {==================================================================
** Language Variations
** =====================================================================
*/
/*
@@ LUA_NOCVTN2S/LUA_NOCVTS2N control how Lua performs some
** coercions. Define LUA_NOCVTN2S to turn off automatic coercion from
** numbers to strings. Define LUA_NOCVTS2N to turn off automatic
** coercion from strings to numbers.
*/
/* #define LUA_NOCVTN2S */
/* #define LUA_NOCVTS2N */
/*
@@ LUA_USE_APICHECK turns on several consistency checks on the C API.
** Define it as a help when debugging C code.
*/
#if defined(LUA_USE_APICHECK)
#include <assert.h>
#define luai_apicheck(l, e) luaport_assert(e)
#endif
/* }================================================================== */
/*
** {==================================================================
** Macros that affect the API and must be stable (that is, must be the
** same when you compile Lua and when you compile code that links to
** Lua).
** =====================================================================
*/
/*
@@ LUAI_MAXSTACK limits the size of the Lua stack.
** CHANGE it if you need a different limit. This limit is arbitrary;
** its only purpose is to stop Lua from consuming unlimited stack
** space (and to reserve some numbers for pseudo-indices).
** (It must fit into max(size_t)/32.)
*/
#if LUAI_IS32INT
#define LUAI_MAXSTACK 1000000
#else
#define LUAI_MAXSTACK 15000
#endif
/*
@@ LUA_EXTRASPACE defines the size of a raw memory area associated with
** a Lua state with very fast access.
** CHANGE it if you need a different size.
*/
#define LUA_EXTRASPACE (sizeof(void *))
/*
@@ LUA_IDSIZE gives the maximum size for the description of the source
@@ of a function in debug information.
** CHANGE it if you want a different size.
*/
#define LUA_IDSIZE 60
/*
@@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system.
*/
#define LUAL_BUFFERSIZE ((int)(16 * sizeof(void *) * sizeof(lua_Number)))
/*
@@ LUAI_MAXALIGN defines fields that, when used in a union, ensure
** maximum alignment for the other items in that union.
*/
#define LUAI_MAXALIGN \
lua_Number n; \
double u; \
void *s; \
lua_Integer i; \
long l
/* }================================================================== */
/* =================================================================== */
/*
** Local configuration. You can use this space to add your redefinitions
** without modifying the main part of the file.
*/
#endif

View File

@ -0,0 +1,98 @@
/*
** $Id: luaport.h $
** Lua Port
** See Copyright Notice in lua.h
*/
#ifndef luaport_h
#define luaport_h
#define LUA_USE_MCU
#define LUA_USE_APICHECK
// #define LUAI_ASSERT
#include <assert.h>
#define luaport_assert assert
#include <stdarg.h>
#define luaport_offsetof offsetof
#include <stdio.h>
#define luaport_stdin stdin
#define luaport_stdout stdout
#define luaport_stderr stderr
#define luaport_tmpfile tmpfile
#define luaport_tmpnam tmpnam
#define luaport_fclose fclose
#define luaport_fflush fflush
#define luaport_freopen freopen
#define luaport_setvbuf setvbuf
#define luaport_fprintf fprintf
#define luaport_printf printf
#define luaport_fgets fgets
#define luaport_fputs fputs
#define luaport_getc getc
#define luaport_ungetc ungetc
#define luaport_fread fread
#define luaport_fwrite fwrite
#define luaport_fseek fseek
#define luaport_ftell ftell
#define luaport_clearerr clearerr
#define luaport_feof feof
#define luaport_ferror ferror
#define luaport_fopen fopen
#define luaport_sprintf sprintf
#define luaport_remove remove
#define luaport_rename rename
#define luaport_snprintf snprintf
#include <string.h>
#define luaport_memchr memchr
#define luaport_memcmp memcmp
#define luaport_memcpy memcpy
#define luaport_strchr strchr
#define luaport_strcmp strcmp
#define luaport_strcoll strcoll
#define luaport_strcpy strcpy
#define luaport_strerror strerror
#define luaport_strlen strlen
#define luaport_strncmp strncmp
#define luaport_strpbrk strpbrk
#define luaport_strrchr strrchr
#define luaport_strspn strspn
#define luaport_strstr strstr
#include <errno.h>
#define luaport_errno errno
#include <stdlib.h>
#define luaport_abort abort
#define luaport_exit exit
#define luaport_free free
#define luaport_getenv getenv
#define luaport_realloc realloc
#define luaport_strtod strtod
#define luaport_strtof strtof
#define luaport_system system
#include <setjmp.h>
#define luaport_longjmp longjmp
#define luaport_setjmp setjmp
#include <locale.h>
#define luaport_setlocale setlocale
#define luaport_localeconv localeconv
#include <time.h>
#define luaport_time_t long long
#define luaport_clock clock
#define luaport_difftime difftime
#define luaport_mktime mktime
#define luaport_time time
#define luaport_gmtime gmtime
#define luaport_localtime localtime
#define luaport_strftime strftime
#define luaport_signal(sig,func) NULL
#endif

View File

@ -0,0 +1,698 @@
/*
** $Id: lua.c $
** Lua stand-alone interpreter
** See Copyright Notice in lua.h
*/
#define lua_c
#include "lprefix.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// #include <signal.h>
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
#if !defined(LUA_PROGNAME)
#define LUA_PROGNAME "lua"
#endif
#if !defined(LUA_INIT_VAR)
#define LUA_INIT_VAR "LUA_INIT"
#endif
#define LUA_INITVARVERSION LUA_INIT_VAR LUA_VERSUFFIX
static lua_State *globalL = NULL;
static const char *progname = LUA_PROGNAME;
#if defined(LUA_USE_POSIX) /* { */
/*
** Use 'sigaction' when available.
*/
static void
setsignal(int sig, void (*handler)(int))
{
struct sigaction sa;
sa.sa_handler = handler;
sa.sa_flags = 0;
sigemptyset(&sa.sa_mask); /* do not mask any signal */
sigaction(sig, &sa, NULL);
}
#else /* }{ */
#define setsignal luaport_signal
#endif /* } */
/*
** Hook set by signal function to stop the interpreter.
*/
static void
lstop(lua_State *L, lua_Debug *ar)
{
(void)ar; /* unused arg. */
lua_sethook(L, NULL, 0, 0); /* reset hook */
luaL_error(L, "interrupted!");
}
/*
** Function to be called at a C signal. Because a C signal cannot
** just change a Lua state (as there is no proper synchronization),
** this function only sets a hook that, when called, will stop the
** interpreter.
*/
static void
laction(int i)
{
int flag = LUA_MASKCALL | LUA_MASKRET | LUA_MASKLINE | LUA_MASKCOUNT;
setsignal(i, SIG_DFL); /* if another SIGINT happens, terminate process */
lua_sethook(globalL, lstop, flag, 1);
}
static void
print_usage(const char *badoption)
{
lua_writestringerror("%s: ", progname);
if (badoption[1] == 'e' || badoption[1] == 'l')
lua_writestringerror("'%s' needs argument\n", badoption);
else
lua_writestringerror("unrecognized option '%s'\n", badoption);
lua_writestringerror(
"usage: %s [options] [script [args]]\n"
"Available options are:\n"
" -e stat execute string 'stat'\n"
" -i enter interactive mode after executing 'script'\n"
" -l mod require library 'mod' into global 'mod'\n"
" -l g=mod require library 'mod' into global 'g'\n"
" -v show version information\n"
" -E ignore environment variables\n"
" -W turn warnings on\n"
" -- stop handling options\n"
" - stop handling options and execute stdin\n",
progname);
}
/*
** Prints an error message, adding the program name in front of it
** (if present)
*/
static void
l_message(const char *pname, const char *msg)
{
if (pname)
lua_writestringerror("%s: ", pname);
lua_writestringerror("%s\n", msg);
}
/*
** Check whether 'status' is not OK and, if so, prints the error
** message on the top of the stack. It assumes that the error object
** is a string, as it was either generated by Lua or by 'msghandler'.
*/
static int
report(lua_State *L, int status)
{
if (status != LUA_OK) {
const char *msg = lua_tostring(L, -1);
l_message(progname, msg);
lua_pop(L, 1); /* remove message */
}
return status;
}
/*
** Message handler used to run all chunks
*/
static int
msghandler(lua_State *L)
{
const char *msg = lua_tostring(L, 1);
if (msg == NULL) { /* is error object not a string? */
if (luaL_callmeta(L, 1, "__tostring") && /* does it have a metamethod */
lua_type(L, -1) == LUA_TSTRING) /* that produces a string? */
return 1; /* that is the message */
else
msg = lua_pushfstring(L, "(error object is a %s value)", luaL_typename(L, 1));
}
luaL_traceback(L, L, msg, 1); /* append a standard traceback */
return 1; /* return the traceback */
}
/*
** Interface to 'lua_pcall', which sets appropriate message function
** and C-signal handler. Used to run all chunks.
*/
static int
docall(lua_State *L, int narg, int nres)
{
int status;
int base = lua_gettop(L) - narg; /* function index */
lua_pushcfunction(L, msghandler); /* push message handler */
lua_insert(L, base); /* put it under function and args */
globalL = L; /* to be available to 'laction' */
setsignal(SIGINT, laction); /* set C-signal handler */
status = lua_pcall(L, narg, nres, base);
setsignal(SIGINT, SIG_DFL); /* reset C-signal handler */
lua_remove(L, base); /* remove message handler from the stack */
return status;
}
static void
print_version(void)
{
lua_writestring(LUA_COPYRIGHT, luaport_strlen(LUA_COPYRIGHT));
lua_writeline();
}
/*
** Create the 'arg' table, which stores all arguments from the
** command line ('argv'). It should be aligned so that, at index 0,
** it has 'argv[script]', which is the script name. The arguments
** to the script (everything after 'script') go to positive indices;
** other arguments (before the script name) go to negative indices.
** If there is no script name, assume interpreter's name as base.
*/
static void
createargtable(lua_State *L, char **argv, int argc, int script)
{
int i, narg;
if (script == argc)
script = 0; /* no script name? */
narg = argc - (script + 1); /* number of positive indices */
lua_createtable(L, narg, script + 1);
for (i = 0; i < argc; i++) {
lua_pushstring(L, argv[i]);
lua_rawseti(L, -2, i - script);
}
lua_setglobal(L, "arg");
}
static int
dochunk(lua_State *L, int status)
{
if (status == LUA_OK)
status = docall(L, 0, 0);
return report(L, status);
}
static int
dofile(lua_State *L, const char *name)
{
return dochunk(L, luaL_loadfile(L, name));
}
static int
dostring(lua_State *L, const char *s, const char *name)
{
return dochunk(L, luaL_loadbuffer(L, s, luaport_strlen(s), name));
}
/*
** Receives 'globname[=modname]' and runs 'globname = require(modname)'.
*/
static int
dolibrary(lua_State *L, char *globname)
{
int status;
char *modname = luaport_strchr(globname, '=');
if (modname == NULL) /* no explicit name? */
modname = globname; /* module name is equal to global name */
else {
*modname = '\0'; /* global name ends here */
modname++; /* module name starts after the '=' */
}
lua_getglobal(L, "require");
lua_pushstring(L, modname);
status = docall(L, 1, 1); /* call 'require(modname)' */
if (status == LUA_OK)
lua_setglobal(L, globname); /* globname = require(modname) */
return report(L, status);
}
/*
** Push on the stack the contents of table 'arg' from 1 to #arg
*/
static int
pushargs(lua_State *L)
{
int i, n;
if (lua_getglobal(L, "arg") != LUA_TTABLE)
luaL_error(L, "'arg' is not a table");
n = (int)luaL_len(L, -1);
luaL_checkstack(L, n + 3, "too many arguments to script");
for (i = 1; i <= n; i++)
lua_rawgeti(L, -i, i);
lua_remove(L, -i); /* remove table from the stack */
return n;
}
static int
handle_script(lua_State *L, char **argv)
{
int status;
const char *fname = argv[0];
if (luaport_strcmp(fname, "-") == 0 && luaport_strcmp(argv[-1], "--") != 0)
fname = NULL; /* stdin */
status = luaL_loadfile(L, fname);
if (status == LUA_OK) {
int n = pushargs(L); /* push arguments to script */
status = docall(L, n, LUA_MULTRET);
}
return report(L, status);
}
/* bits of various argument indicators in 'args' */
#define has_error 1 /* bad option */
#define has_i 2 /* -i */
#define has_v 4 /* -v */
#define has_e 8 /* -e */
#define has_E 16 /* -E */
/*
** Traverses all arguments from 'argv', returning a mask with those
** needed before running any Lua code (or an error code if it finds
** any invalid argument). 'first' returns the first not-handled argument
** (either the script name or a bad argument in case of error).
*/
static int
collectargs(char **argv, int *first)
{
int args = 0;
int i;
for (i = 1; argv[i] != NULL; i++) {
*first = i;
if (argv[i][0] != '-') /* not an option? */
return args; /* stop handling options */
switch (argv[i][1]) { /* else check option */
case '-': /* '--' */
if (argv[i][2] != '\0') /* extra characters after '--'? */
return has_error; /* invalid option */
*first = i + 1;
return args;
case '\0': /* '-' */
return args; /* script "name" is '-' */
case 'E':
if (argv[i][2] != '\0') /* extra characters? */
return has_error; /* invalid option */
args |= has_E;
break;
case 'W':
if (argv[i][2] != '\0') /* extra characters? */
return has_error; /* invalid option */
break;
case 'i':
args |= has_i; /* (-i implies -v) */ /* FALLTHROUGH */
case 'v':
if (argv[i][2] != '\0') /* extra characters? */
return has_error; /* invalid option */
args |= has_v;
break;
case 'e':
args |= has_e; /* FALLTHROUGH */
case 'l': /* both options need an argument */
if (argv[i][2] == '\0') { /* no concatenated argument? */
i++; /* try next 'argv' */
if (argv[i] == NULL || argv[i][0] == '-')
return has_error; /* no next argument or it is another option */
}
break;
default: /* invalid option */
return has_error;
}
}
*first = i; /* no script name */
return args;
}
/*
** Processes options 'e' and 'l', which involve running Lua code, and
** 'W', which also affects the state.
** Returns 0 if some code raises an error.
*/
static int
runargs(lua_State *L, char **argv, int n)
{
int i;
for (i = 1; i < n; i++) {
int option = argv[i][1];
lua_assert(argv[i][0] == '-'); /* already checked */
switch (option) {
case 'e':
case 'l': {
int status;
char *extra = argv[i] + 2; /* both options need an argument */
if (*extra == '\0')
extra = argv[++i];
lua_assert(extra != NULL);
status = (option == 'e') ? dostring(L, extra, "=(command line)") : dolibrary(L, extra);
if (status != LUA_OK)
return 0;
break;
}
case 'W':
lua_warning(L, "@on", 0); /* warnings on */
break;
}
}
return 1;
}
static int
handle_luainit(lua_State *L)
{
const char *name = "=" LUA_INITVARVERSION;
const char *init = luaport_getenv(name + 1);
if (init == NULL) {
name = "=" LUA_INIT_VAR;
init = luaport_getenv(name + 1); /* try alternative name */
}
if (init == NULL)
return LUA_OK;
else if (init[0] == '@')
return dofile(L, init + 1);
else
return dostring(L, init, name);
}
/*
** {==================================================================
** Read-Eval-Print Loop (REPL)
** ===================================================================
*/
#if !defined(LUA_PROMPT)
#define LUA_PROMPT "> "
#define LUA_PROMPT2 ">> "
#endif
#if !defined(LUA_MAXINPUT)
#define LUA_MAXINPUT 512
#endif
/*
** lua_stdin_is_tty detects whether the standard input is a 'tty' (that
** is, whether we're running lua interactively).
*/
#if !defined(lua_stdin_is_tty) /* { */
#if defined(LUA_USE_POSIX) /* { */
#include <unistd.h>
#define lua_stdin_is_tty() isatty(0)
#elif defined(LUA_USE_WINDOWS) /* }{ */
#include <io.h>
#include <windows.h>
#define lua_stdin_is_tty() _isatty(_fileno(stdin))
#else /* }{ */
/* ISO C definition */
#define lua_stdin_is_tty() 1 /* assume stdin is a tty */
#endif /* } */
#endif /* } */
/*
** lua_readline defines how to show a prompt and then read a line from
** the standard input.
** lua_saveline defines how to "save" a read line in a "history".
** lua_freeline defines how to free a line read by lua_readline.
*/
#if !defined(lua_readline) /* { */
#if defined(LUA_USE_READLINE) /* { */
#include <readline/readline.h>
#include <readline/history.h>
#define lua_initreadline(L) ((void)L, rl_readline_name = "lua")
#define lua_readline(L, b, p) ((void)L, ((b) = readline(p)) != NULL)
#define lua_saveline(L, line) ((void)L, add_history(line))
#define lua_freeline(L, b) ((void)L, free(b))
#else /* }{ */
#define lua_initreadline(L) ((void)L)
#define lua_readline(L, b, p) \
((void)L, luaport_fputs(p, luaport_stdout), luaport_fflush(luaport_stdout), /* show prompt */ \
luaport_fgets(b, LUA_MAXINPUT, luaport_stdin) != NULL) /* get line */
#define lua_saveline(L, line) \
{ \
(void)L; \
(void)line; \
}
#define lua_freeline(L, b) \
{ \
(void)L; \
(void)b; \
}
#endif /* } */
#endif /* } */
/*
** Return the string to be used as a prompt by the interpreter. Leave
** the string (or nil, if using the default value) on the stack, to keep
** it anchored.
*/
static const char *
get_prompt(lua_State *L, int firstline)
{
if (lua_getglobal(L, firstline ? "_PROMPT" : "_PROMPT2") == LUA_TNIL)
return (firstline ? LUA_PROMPT : LUA_PROMPT2); /* use the default */
else { /* apply 'tostring' over the value */
const char *p = luaL_tolstring(L, -1, NULL);
lua_remove(L, -2); /* remove original value */
return p;
}
}
/* mark in error messages for incomplete statements */
#define EOFMARK "<eof>"
#define marklen (sizeof(EOFMARK) / sizeof(char) - 1)
/*
** Check whether 'status' signals a syntax error and the error
** message at the top of the stack ends with the above mark for
** incomplete statements.
*/
static int
incomplete(lua_State *L, int status)
{
if (status == LUA_ERRSYNTAX) {
size_t lmsg;
const char *msg = lua_tolstring(L, -1, &lmsg);
if (lmsg >= marklen && luaport_strcmp(msg + lmsg - marklen, EOFMARK) == 0) {
lua_pop(L, 1);
return 1;
}
}
return 0; /* else... */
}
/*
** Prompt the user, read a line, and push it into the Lua stack.
*/
static int
pushline(lua_State *L, int firstline)
{
char buffer[LUA_MAXINPUT];
char *b = buffer;
size_t l;
const char *prmt = get_prompt(L, firstline);
int readstatus = lua_readline(L, b, prmt);
if (readstatus == 0)
return 0; /* no input (prompt will be popped by caller) */
lua_pop(L, 1); /* remove prompt */
l = luaport_strlen(b);
if (l > 0 && b[l - 1] == '\n') /* line ends with newline? */
b[--l] = '\0'; /* remove it */
if (firstline && b[0] == '=') /* for compatibility with 5.2, ... */
lua_pushfstring(L, "return %s", b + 1); /* change '=' to 'return' */
else
lua_pushlstring(L, b, l);
lua_freeline(L, b);
return 1;
}
/*
** Try to compile line on the stack as 'return <line>;'; on return, stack
** has either compiled chunk or original line (if compilation failed).
*/
static int
addreturn(lua_State *L)
{
const char *line = lua_tostring(L, -1); /* original line */
const char *retline = lua_pushfstring(L, "return %s;", line);
int status = luaL_loadbuffer(L, retline, luaport_strlen(retline), "=stdin");
if (status == LUA_OK) {
lua_remove(L, -2); /* remove modified line */
if (line[0] != '\0') /* non empty? */
lua_saveline(L, line); /* keep history */
} else
lua_pop(L, 2); /* pop result from 'luaL_loadbuffer' and modified line */
return status;
}
/*
** Read multiple lines until a complete Lua statement
*/
static int
multiline(lua_State *L)
{
for (;;) { /* repeat until gets a complete statement */
size_t len;
const char *line = lua_tolstring(L, 1, &len); /* get what it has */
int status = luaL_loadbuffer(L, line, len, "=stdin"); /* try it */
if (!incomplete(L, status) || !pushline(L, 0)) {
lua_saveline(L, line); /* keep history */
return status; /* cannot or should not try to add continuation line */
}
lua_pushliteral(L, "\n"); /* add newline... */
lua_insert(L, -2); /* ...between the two lines */
lua_concat(L, 3); /* join them */
}
}
/*
** Read a line and try to load (compile) it first as an expression (by
** adding "return " in front of it) and second as a statement. Return
** the final status of load/call with the resulting function (if any)
** in the top of the stack.
*/
static int
loadline(lua_State *L)
{
int status;
lua_settop(L, 0);
if (!pushline(L, 1))
return -1; /* no input */
if ((status = addreturn(L)) != LUA_OK) /* 'return ...' did not work? */
status = multiline(L); /* try as command, maybe with continuation lines */
lua_remove(L, 1); /* remove line from the stack */
lua_assert(lua_gettop(L) == 1);
return status;
}
/*
** Prints (calling the Lua 'print' function) any values on the stack
*/
static void
l_print(lua_State *L)
{
int n = lua_gettop(L);
if (n > 0) { /* any result to be printed? */
luaL_checkstack(L, LUA_MINSTACK, "too many results to print");
lua_getglobal(L, "print");
lua_insert(L, 1);
if (lua_pcall(L, n, 0, 0) != LUA_OK)
l_message(progname, lua_pushfstring(L, "error calling 'print' (%s)", lua_tostring(L, -1)));
}
}
/*
** Do the REPL: repeatedly read (load) a line, evaluate (call) it, and
** print any results.
*/
static void
doREPL(lua_State *L)
{
int status;
const char *oldprogname = progname;
progname = NULL; /* no 'progname' on errors in interactive mode */
lua_initreadline(L);
while ((status = loadline(L)) != -1) {
if (status == LUA_OK)
status = docall(L, 0, LUA_MULTRET);
if (status == LUA_OK)
l_print(L);
else
report(L, status);
}
lua_settop(L, 0); /* clear stack */
lua_writeline();
progname = oldprogname;
}
/* }================================================================== */
/*
** Main body of stand-alone interpreter (to be called in protected mode).
** Reads the options and handles them all.
*/
static int
pmain(lua_State *L)
{
int argc = (int)lua_tointeger(L, 1);
char **argv = (char **)lua_touserdata(L, 2);
int script;
int args = collectargs(argv, &script);
luaL_checkversion(L); /* check that interpreter has correct version */
if (argv[0] && argv[0][0])
progname = argv[0];
if (args == has_error) { /* bad arg? */
print_usage(argv[script]); /* 'script' has index of bad arg. */
return 0;
}
if (args & has_v) /* option '-v'? */
print_version();
if (args & has_E) { /* option '-E'? */
lua_pushboolean(L, 1); /* signal for libraries to ignore env. vars. */
lua_setfield(L, LUA_REGISTRYINDEX, "LUA_NOENV");
}
luaL_openlibs(L); /* open standard libraries */
createargtable(L, argv, argc, script); /* create table 'arg' */
lua_gc(L, LUA_GCGEN, 0, 0); /* GC in generational mode */
if (!(args & has_E)) { /* no option '-E'? */
if (handle_luainit(L) != LUA_OK) /* run LUA_INIT */
return 0; /* error running LUA_INIT */
}
if (!runargs(L, argv, script)) /* execute arguments -e and -l */
return 0; /* something failed */
if (script < argc && /* execute main script (if there is one) */
handle_script(L, argv + script) != LUA_OK)
return 0;
if (args & has_i) /* -i option? */
doREPL(L); /* do read-eval-print loop */
else if (script == argc && !(args & (has_e | has_v))) { /* no arguments? */
if (lua_stdin_is_tty()) { /* running in interactive mode? */
print_version();
doREPL(L); /* do read-eval-print loop */
} else
dofile(L, NULL); /* executes stdin as a file */
}
lua_pushboolean(L, 1); /* signal no errors */
return 1;
}
int lua_main(int argc, char **argv)
{
int status, result;
lua_State *L = luaL_newstate(); /* create state */
if (L == NULL) {
l_message(argv[0], "cannot create state: not enough memory");
return EXIT_FAILURE;
}
lua_pushcfunction(L, &pmain); /* to call 'pmain' in protected mode */
lua_pushinteger(L, argc); /* 1st argument */
lua_pushlightuserdata(L, argv); /* 2nd argument */
status = lua_pcall(L, 2, 1, 0); /* do the call */
result = lua_toboolean(L, -1); /* get result */
report(L, status);
lua_close(L);
return (result && status == LUA_OK) ? EXIT_SUCCESS : EXIT_FAILURE;
}

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