mirror of
https://github.com/bouffalolab/bouffalo_sdk.git
synced 2025-05-08 19:07:22 +08:00
[sync] sync code from internal
This commit is contained in:
parent
810354065e
commit
6a4d89bfeb
BIN
BouffaloSDK.png
Normal file
BIN
BouffaloSDK.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 194 KiB |
148
README.md
148
README.md
@ -1,26 +1,30 @@
|
||||
[](LICENSE)
|
||||
[]()
|
||||
|
||||
[中文版](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.0(hal + 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).
|
||||

|
||||
|
||||
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/)
|
146
README_zh.md
146
README_zh.md
@ -1,26 +1,30 @@
|
||||
[](LICENSE)
|
||||
[]()
|
||||
|
||||
[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)。
|
||||

|
||||
|
||||
注意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** 并通过串口进行固件的烧录。
|
||||
需要注意,如果使用的是 linux,linux 由于权限问题会拒绝访问串口设备,所以,为了方便后续使用,将你自己的用户名添加到 `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/)
|
@ -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()
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
528
bsp/common/lcd/lcd_conf.h
Normal 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
|
376
bsp/common/lcd/spi/bl_spi_hard_4.c
Normal file
376
bsp/common/lcd/spi/bl_spi_hard_4.c
Normal 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
|
38
bsp/common/lcd/spi/bl_spi_hard_4.h
Normal file
38
bsp/common/lcd/spi/bl_spi_hard_4.h
Normal 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
|
@ -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 *)¶m, 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
|
||||
|
@ -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
|
@ -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 *)¶m, 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,Blocking,Using 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
|
@ -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
|
||||
|
@ -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 *)¶m, 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
|
||||
|
@ -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
|
@ -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 *)¶m, 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
|
||||
|
@ -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
|
@ -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;
|
||||
|
@ -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 {
|
||||
|
@ -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()
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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()
|
@ -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;
|
||||
|
@ -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****************************/
|
||||
|
||||
/*---------------------------------------*/
|
||||
|
@ -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
@ -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
|
||||
}
|
||||
|
@ -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 ---*/
|
||||
|
@ -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
33
components/fs/fatfs/port/fatfs_diskio_register.h
Normal file
33
components/fs/fatfs/port/fatfs_diskio_register.h
Normal 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
|
@ -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
|
@ -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)
|
||||
|
33
components/libc/newlib/CMakeLists.txt
Normal file
33
components/libc/newlib/CMakeLists.txt
Normal 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()
|
9
components/libc/newlib/README.md
Normal file
9
components/libc/newlib/README.md
Normal 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 |
|
561
components/libc/newlib/port_file_fatfs.c
Normal file
561
components/libc/newlib/port_file_fatfs.c
Normal 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;
|
||||
}
|
229
components/libc/newlib/port_file_nosys.c
Normal file
229
components/libc/newlib/port_file_nosys.c
Normal 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;
|
||||
}
|
53
components/libc/newlib/port_init_fini.c
Normal file
53
components/libc/newlib/port_init_fini.c
Normal 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();
|
||||
}
|
122
components/libc/newlib/port_memory.c
Normal file
122
components/libc/newlib/port_memory.c
Normal 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);
|
||||
}
|
106
components/libc/newlib/port_time.c
Normal file
106
components/libc/newlib/port_time.c
Normal 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);
|
||||
}
|
383
components/libc/newlib/port_tty.c
Normal file
383
components/libc/newlib/port_tty.c
Normal 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;
|
||||
}
|
||||
}
|
538
components/libc/newlib/syscalls.c
Normal file
538
components/libc/newlib/syscalls.c
Normal 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
|
||||
----------------------------------------------------------------------------*/
|
||||
|
||||
|
144
components/libc/newlib/syscalls_nosys.c
Normal file
144
components/libc/newlib/syscalls_nosys.c
Normal 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
25
components/libc/sprintf.c
Normal 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;
|
||||
}
|
@ -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
@ -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
20
components/libc/vsprintf.c
Normal file
20
components/libc/vsprintf.c
Normal 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);
|
||||
}
|
@ -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)
|
||||
|
@ -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)
|
@ -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
|
||||
|
@ -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)))
|
||||
|
@ -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);
|
||||
|
@ -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 /* } */
|
||||
|
||||
|
@ -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
|
||||
|
@ -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) \
|
||||
|
@ -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);
|
||||
|
@ -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))) ? \
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
#define vmdispatch(x) goto *disptab[x];
|
||||
|
||||
#define vmcase(l) L_##l:
|
||||
#define vmcase(l) L_##l:
|
||||
|
||||
#define vmbreak \
|
||||
vmfetch(); \
|
||||
|
@ -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))
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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];)
|
||||
|
||||
|
@ -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 */
|
||||
|
||||
|
9
components/runtime/lua/core/inc/lua.hpp
Normal file
9
components/runtime/lua/core/inc/lua.hpp
Normal 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"
|
||||
}
|
@ -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);
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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.
|
||||
|
@ -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 */
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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')
|
||||
|
||||
|
@ -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' }{ */
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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];
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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));
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,7 @@
|
||||
|
||||
#define MAXUNICODE 0x10FFFFu
|
||||
|
||||
#define MAXUTF 0x7FFFFFFFu
|
||||
#define MAXUTF 0x7FFFFFFFu
|
||||
|
||||
/*
|
||||
** Integer type for decoded UTF-8 values; MAXUTF needs 31 bits.
|
||||
|
@ -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);
|
||||
|
754
components/runtime/lua/port/inc/luaconf.h
Normal file
754
components/runtime/lua/port/inc/luaconf.h
Normal 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
|
98
components/runtime/lua/port/inc/luaport.h
Normal file
98
components/runtime/lua/port/inc/luaport.h
Normal 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
|
698
components/runtime/lua/start/lua.c
Normal file
698
components/runtime/lua/start/lua.c
Normal 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
Loading…
x
Reference in New Issue
Block a user