create project
This commit is contained in:
commit
56410482db
|
@ -0,0 +1,14 @@
|
||||||
|
#.gitignore
|
||||||
|
|
||||||
|
# Step-1, track all files in the current folder
|
||||||
|
!*
|
||||||
|
|
||||||
|
# Step-2, track specified files in the current folder
|
||||||
|
*
|
||||||
|
!*/
|
||||||
|
!.gitignore
|
||||||
|
!LICENSE
|
||||||
|
!*.md
|
||||||
|
|
||||||
|
# Step-3, untrack all in sub folders, which use their own .gitignore
|
||||||
|
*/*
|
|
@ -0,0 +1,201 @@
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright [yyyy] [name of copyright owner]
|
||||||
|
|
||||||
|
Licensed 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.
|
|
@ -0,0 +1,291 @@
|
||||||
|
22:05 2024/6/11
|
||||||
|
|
||||||
|
## 一、简介
|
||||||
|
|
||||||
|
> TraSH,一个基于 RISC-V 指令集的计算机系统
|
||||||
|
|
||||||
|
## 二、功能介绍
|
||||||
|
|
||||||
|
### 1. 特性
|
||||||
|
|
||||||
|
**TraSH 具有如下特性:**
|
||||||
|
|
||||||
|
- 完全采用 Verilog 进行编写
|
||||||
|
- 具有 5 级流水线,顺序执行,不支持分支预测(取指 IF、译指 ID、执行 EX、访存 MEM、写回 WB)
|
||||||
|
- 支持 RV32IMZicsr 指令集(ecall、ebreak、fence、fence.i、wfi 指令除外)
|
||||||
|
- 仅支持 M 模式
|
||||||
|
- 仅支持非向量中断
|
||||||
|
- 非 AMBA 总线,哈佛结构,支持 bootloader
|
||||||
|
- 支持 UART、TIMER、GPIO 等外设
|
||||||
|
- 支持 RT-Thread Nano 3.1.5
|
||||||
|
- 支持在多平台运行
|
||||||
|
|
||||||
|
**TraSH 可以在 Windows 和 Linux 平台运行:**
|
||||||
|
|
||||||
|
1. Windows 平台 (Win10)
|
||||||
|
- 支持 iverilog 仿真
|
||||||
|
- 支持 Gowin FPGA (TANG Nano 9K)
|
||||||
|
- 支持 XEMU 模拟器
|
||||||
|
|
||||||
|
2. Linux 平台 (CentOS)
|
||||||
|
- 支持 VCS 仿真
|
||||||
|
- 支持 XEMU 模拟器
|
||||||
|
|
||||||
|
### 2. 地址分配
|
||||||
|
|
||||||
|
编译的 .bin 可以在多个平台运行,但是由于平台的限制,需要对 rom 和 ram 的大小进行设置
|
||||||
|
|
||||||
|
原则上,除了 XEMU 外,其他平台请遵循 `rom=28K, ram=12K`
|
||||||
|
- vcs、iverilog、Gowin FPGA 均使用了相同的 IP,如需修改,需要重新生成 IP 进行替换
|
||||||
|
|
||||||
|
|起始地址 |结束地址 |大小 |外设 |支持|
|
||||||
|
|:-: |:-: |:-: |:-: |:-: |
|
||||||
|
|0x0000_0000|0x0fff_ffff|512K(Max 28K on non XEMU platform)|ROM |√ |
|
||||||
|
|0x1000_0000|0x1fff_ffff|512K(Max 28K on non XEMU platform)|RAM |√ |
|
||||||
|
|0x2000_0000|0x2fff_ffff|4K |TIMER1|√ |
|
||||||
|
|0x3000_0000|0x3fff_ffff|4K |UART1 |√ |
|
||||||
|
|0x4000_0000|0x4fff_ffff|4K |GPIO |√ |
|
||||||
|
|
||||||
|
*实际使用的空间大小详见 link.lds 文件*
|
||||||
|
|
||||||
|
## 三、环境搭建
|
||||||
|
|
||||||
|
### 1. Windows + iverilog
|
||||||
|
|
||||||
|
#### 1. 说明
|
||||||
|
|
||||||
|
- 内核及外设:`YuHeng 5-state RISC-V Core`
|
||||||
|
- 软件编译器:`gcc version 8.4.0 (T-HEAD RISCV Tools V1.10.5.1 B20210306)`
|
||||||
|
- 仿真环境:`iverilog + gtkwave`
|
||||||
|
|
||||||
|
*注意,当宏 `PRINT_STDIO_SIM` 被定义时,使用 `mscratchcswl` 寄存器来重定向 xprintf,需要编译器支持*
|
||||||
|
|
||||||
|
#### 2. 操作
|
||||||
|
|
||||||
|
修改仿真环境 iverilog 和 gtkwave 的路径(文件路径:`sim/config.mk`)
|
||||||
|
|
||||||
|
```
|
||||||
|
VCS = D:/iverilog/bin/iverilog.exe
|
||||||
|
SIM = D:/iverilog/bin/vvp.exe
|
||||||
|
WAV = D:/iverilog/gtkwave/bin/gtkwave.exe
|
||||||
|
```
|
||||||
|
|
||||||
|
修改测试程序编译工具的路径(文件路径:`sim/config.mk`)
|
||||||
|
|
||||||
|
```
|
||||||
|
EMBTOOLPATH = D:/EmbedCompiler/riscv64-elf-mingw-20210306
|
||||||
|
EMBTOOLPREFIX = ${EMBTOOLPATH}/bin/riscv64-unknown-elf
|
||||||
|
CC = ${EMBTOOLPREFIX}-gcc.exe
|
||||||
|
OBJDUMP = ${EMBTOOLPREFIX}-objdump.exe
|
||||||
|
OBJCOPY = ${EMBTOOLPREFIX}-objcopy.exe
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Windows + XEMU
|
||||||
|
|
||||||
|
#### 1. 说明
|
||||||
|
|
||||||
|
- 内核及外设:`YuHeng 5-state RISC-V Core`
|
||||||
|
- 软件编译器:`gcc version 8.4.0 (T-HEAD RISCV Tools V1.10.5.1 B20210306)`
|
||||||
|
- 仿真环境:`XEMU`
|
||||||
|
|
||||||
|
*注意,不能定义 `PRINT_STDIO_SIM`,即只支持使用 UART 来重定向 xprintf *
|
||||||
|
|
||||||
|
#### 2. 操作
|
||||||
|
|
||||||
|
下载并安装 `MinGW`,打开网页 `https://sourceforge.net/projects/mingw/files/`,下载 `mingw-get-setup.exe`
|
||||||
|
|
||||||
|
安装 gcc、g++、gdb 和 pthread
|
||||||
|
|
||||||
|
```
|
||||||
|
mingw-get install gcc
|
||||||
|
mingw-get install g++
|
||||||
|
mingw-get install gdb
|
||||||
|
mingw-get install pthreads
|
||||||
|
```
|
||||||
|
|
||||||
|
修改 Windows gcc 编译工具的路径(文件路径:`sim/xemu/Makefile`)
|
||||||
|
|
||||||
|
```
|
||||||
|
TARGET = .\xemu.exe
|
||||||
|
CC = D:\MinGW\bin\gcc.exe
|
||||||
|
PARAM =
|
||||||
|
LIB = -lpthread -lm
|
||||||
|
```
|
||||||
|
|
||||||
|
修改测试程序编译工具的路径(文件路径:`sim/config.mk`)
|
||||||
|
|
||||||
|
```
|
||||||
|
EMBTOOLPATH = D:/EmbedCompiler/riscv64-elf-mingw-20210306
|
||||||
|
EMBTOOLPREFIX = ${EMBTOOLPATH}/bin/riscv64-unknown-elf
|
||||||
|
CC = ${EMBTOOLPREFIX}-gcc.exe
|
||||||
|
OBJDUMP = ${EMBTOOLPREFIX}-objdump.exe
|
||||||
|
OBJCOPY = ${EMBTOOLPREFIX}-objcopy.exe
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Windows + Gowin FPGA
|
||||||
|
|
||||||
|
#### 1. 说明
|
||||||
|
|
||||||
|
- 内核及外设:`YuHeng 5-state RISC-V Core`
|
||||||
|
- 软件编译器:`gcc version 8.4.0 (T-HEAD RISCV Tools V1.10.5.1 B20210306)`
|
||||||
|
- 仿真环境:`GOWIN FPGA Designer Version 1.9.8.11 Education`
|
||||||
|
|
||||||
|
*注意,不能定义 `PRINT_STDIO_SIM`,即只支持使用 UART 来重定向 xprintf *
|
||||||
|
|
||||||
|
#### 2. 操作
|
||||||
|
|
||||||
|
安装 Gowin IDE
|
||||||
|
|
||||||
|
修改测试程序编译工具的路径(文件路径:`sim/config.mk`)
|
||||||
|
|
||||||
|
```
|
||||||
|
EMBTOOLPATH = D:/EmbedCompiler/riscv64-elf-mingw-20210306
|
||||||
|
EMBTOOLPREFIX = ${EMBTOOLPATH}/bin/riscv64-unknown-elf
|
||||||
|
CC = ${EMBTOOLPREFIX}-gcc.exe
|
||||||
|
OBJDUMP = ${EMBTOOLPREFIX}-objdump.exe
|
||||||
|
OBJCOPY = ${EMBTOOLPREFIX}-objcopy.exe
|
||||||
|
```
|
||||||
|
|
||||||
|
*注意,重新编译测试程序后,需要重新生成 IP*
|
||||||
|
|
||||||
|
### 4. Linux + VCS
|
||||||
|
|
||||||
|
#### 1. 说明
|
||||||
|
|
||||||
|
- 内核及外设:`YuHeng 5-state RISC-V Core`
|
||||||
|
- 软件编译器:`gcc version 8.4.0 (T-HEAD RISCV Tools V1.10.5.1 B20210307)`
|
||||||
|
- 仿真环境:`VCS + DVE/Veridi`
|
||||||
|
|
||||||
|
*注意,当宏 `PRINT_STDIO_SIM` 被定义时,使用 `mscratchcswl` 寄存器来重定向 xprintf,需要编译器支持*
|
||||||
|
|
||||||
|
#### 2. 操作
|
||||||
|
|
||||||
|
修改测试程序编译工具的路径(文件路径:`sim/config.mk`)
|
||||||
|
|
||||||
|
```
|
||||||
|
EMBTOOLPATH = /home/crazy/Tools/compiler/xuantie/v8.4.0/riscv64-elf-x86_64-20210307
|
||||||
|
EMBTOOLPREFIX = ${EMBTOOLPATH}/bin/riscv64-unknown-elf
|
||||||
|
CC = ${EMBTOOLPREFIX}-gcc
|
||||||
|
OBJDUMP = ${EMBTOOLPREFIX}-objdump
|
||||||
|
OBJCOPY = ${EMBTOOLPREFIX}-objcopy
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5. Linux + XEMU
|
||||||
|
|
||||||
|
#### 1. 说明
|
||||||
|
|
||||||
|
- 内核及外设:`YuHeng 5-state RISC-V Core`
|
||||||
|
- 软件编译器:`gcc version 8.4.0 (T-HEAD RISCV Tools V1.10.5.1 B20210307)`
|
||||||
|
- 仿真环境:`XEMU`
|
||||||
|
|
||||||
|
*注意,不能定义 `PRINT_STDIO_SIM`,即只支持使用 UART 来重定向 xprintf *
|
||||||
|
|
||||||
|
#### 2. 操作
|
||||||
|
|
||||||
|
安装 curses 库
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y libncurses-dev
|
||||||
|
```
|
||||||
|
|
||||||
|
修改测试程序编译工具的路径(文件路径:`sim/config.mk`)
|
||||||
|
|
||||||
|
```
|
||||||
|
EMBTOOLPATH = /home/crazy/Tools/compiler/xuantie/v8.4.0/riscv64-elf-x86_64-20210307
|
||||||
|
EMBTOOLPREFIX = ${EMBTOOLPATH}/bin/riscv64-unknown-elf
|
||||||
|
CC = ${EMBTOOLPREFIX}-gcc
|
||||||
|
OBJDUMP = ${EMBTOOLPREFIX}-objdump
|
||||||
|
OBJCOPY = ${EMBTOOLPREFIX}-objcopy
|
||||||
|
```
|
||||||
|
|
||||||
|
## 四、使用说明
|
||||||
|
|
||||||
|
*注意,以下操作不区分 Windows 和 Linux 平台*
|
||||||
|
|
||||||
|
### 1. 编译测试程序
|
||||||
|
|
||||||
|
1. 打开 Terminal
|
||||||
|
|
||||||
|
2. 进入 `sim/simple`
|
||||||
|
|
||||||
|
3. 执行 `make build`,编译测试程序
|
||||||
|
- 在 Windows 平台中,还会在工程的根目录下生成 .mi 文件,用于固化 Gowin FPGA 的 rom IP
|
||||||
|
|
||||||
|
### 2. 编译 RTL
|
||||||
|
|
||||||
|
*注意,仅在 vcs 和 iverilog 仿真时使用*
|
||||||
|
|
||||||
|
1. 打开 Terminal
|
||||||
|
|
||||||
|
2. 进入 `sim/simple`
|
||||||
|
|
||||||
|
3. 执行 `make compile`,编译 RTL
|
||||||
|
|
||||||
|
4. 执行 `make build`,编译测试程序
|
||||||
|
|
||||||
|
5. 执行 `make sim`,进行仿真
|
||||||
|
|
||||||
|
6. 执行 `make wave`,查看波形
|
||||||
|
|
||||||
|
此外,可以使用 `make run`,等价于 `make compile && make build && make sim`
|
||||||
|
|
||||||
|
### 3. 编译 XEMU 并运行
|
||||||
|
|
||||||
|
1. 打开 Terminal
|
||||||
|
|
||||||
|
2. 进入 `sim/simple`
|
||||||
|
|
||||||
|
3. 执行 `make xemu`,先编译 XEMU,然后编译测试程序并运行
|
||||||
|
|
||||||
|
*模拟器退出条件:1. 通过 UART1 发送字节序列 0x1b 0x04*
|
||||||
|
*模拟器退出条件:2. 键盘输入 Ctrl+b/B*
|
||||||
|
|
||||||
|
### 4. 使用 debugger
|
||||||
|
|
||||||
|
1. 进入 `scripts/debugger`
|
||||||
|
|
||||||
|
2. 运行 `debugger.py` 或 `debugger.exe`
|
||||||
|
- `debugger.exe` 通过 `pkgtool.bat` 脚本对 `debugger.py` 打包得到
|
||||||
|
|
||||||
|
debugger 支持的命令:
|
||||||
|
|
||||||
|
- `com`,扫描串口
|
||||||
|
- `com4`,打开串口(格式:115200 N 8 1)
|
||||||
|
|
||||||
|
```
|
||||||
|
This is a PuSH Terminal.
|
||||||
|
|
||||||
|
Help Menu:
|
||||||
|
----------------------------------------
|
||||||
|
~ - Switch mode.
|
||||||
|
q - Exit terminal.
|
||||||
|
r - Repeat last command.
|
||||||
|
help - (h) Show help menu.
|
||||||
|
cd - Switch to work path.
|
||||||
|
load - (ld) Load file.
|
||||||
|
download - (d) Download to target device.
|
||||||
|
go - (g) Control target device jump and run.
|
||||||
|
com - Scan valid serial port.
|
||||||
|
com* - Open target serial port.
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
*注意,debugger 需要配合 Gowin FPGA 使用*
|
||||||
|
|
||||||
|
## 五、项目引用
|
||||||
|
|
||||||
|
> RISC-V 内核: git clone https://gitee.com/dengchow/yuheng-riscv-soc.git
|
||||||
|
> XEMU 模拟器: git clone https://gitee.com/dengchow/xemu.git
|
||||||
|
|
||||||
|
## 六、修改日志
|
||||||
|
|
||||||
|
- v1.0
|
||||||
|
- 创建项目并集成测试(0:29 2024/3/10)
|
||||||
|
|
||||||
|
## 七、维护
|
||||||
|
|
||||||
|
如果有任何疑问或者建议,欢迎在下方评论
|
||||||
|
|
||||||
|
ATONEMAN
|
||||||
|
2024/6/11
|
|
@ -0,0 +1,13 @@
|
||||||
|
#.gitignore
|
||||||
|
|
||||||
|
# Step-1, track all files in the current folder
|
||||||
|
!*
|
||||||
|
|
||||||
|
# Step-2, track specified files in the current folder
|
||||||
|
*
|
||||||
|
!*/
|
||||||
|
!.gitignore
|
||||||
|
!*.gprj
|
||||||
|
|
||||||
|
# Step-3, untrack all in sub folders, which use their own .gitignore
|
||||||
|
*/*
|
|
@ -0,0 +1,34 @@
|
||||||
|
<?xml version="1" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE gowin-fpga-project>
|
||||||
|
<Project>
|
||||||
|
<Template>FPGA</Template>
|
||||||
|
<Version>5</Version>
|
||||||
|
<Device name="GW1NR-9C" pn="GW1NR-LV9QN88PC6/I5">gw1nr9c-004</Device>
|
||||||
|
<FileList>
|
||||||
|
<File path="src/ipdefs/gowin_dpb_32x8k/gowin_dpb_32x8k.v" type="file.verilog" enable="1"/>
|
||||||
|
<File path="src/ipdefs/gowin_dpb_8x4k/gowin_dpb_8x4k.v" type="file.verilog" enable="1"/>
|
||||||
|
<File path="src/ipdefs/gowin_rpll/gowin_rpll.v" type="file.verilog" enable="1"/>
|
||||||
|
<File path="src/rtl/core/pa_core_clint.v" type="file.verilog" enable="1"/>
|
||||||
|
<File path="src/rtl/core/pa_core_csr.v" type="file.verilog" enable="1"/>
|
||||||
|
<File path="src/rtl/core/pa_core_exu.v" type="file.verilog" enable="1"/>
|
||||||
|
<File path="src/rtl/core/pa_core_exu_div.v" type="file.verilog" enable="1"/>
|
||||||
|
<File path="src/rtl/core/pa_core_exu_mul.v" type="file.verilog" enable="1"/>
|
||||||
|
<File path="src/rtl/core/pa_core_idu.v" type="file.verilog" enable="1"/>
|
||||||
|
<File path="src/rtl/core/pa_core_mau.v" type="file.verilog" enable="1"/>
|
||||||
|
<File path="src/rtl/core/pa_core_pcgen.v" type="file.verilog" enable="1"/>
|
||||||
|
<File path="src/rtl/core/pa_core_rtu.v" type="file.verilog" enable="1"/>
|
||||||
|
<File path="src/rtl/core/pa_core_top.v" type="file.verilog" enable="1"/>
|
||||||
|
<File path="src/rtl/core/pa_core_xreg.v" type="file.verilog" enable="1"/>
|
||||||
|
<File path="src/rtl/pa_chip_param.v" type="file.verilog" enable="1"/>
|
||||||
|
<File path="src/rtl/pa_chip_top.v" type="file.verilog" enable="1"/>
|
||||||
|
<File path="src/rtl/perips/pa_perips_gpio.v" type="file.verilog" enable="1"/>
|
||||||
|
<File path="src/rtl/perips/pa_perips_tcm.v" type="file.verilog" enable="1"/>
|
||||||
|
<File path="src/rtl/perips/pa_perips_tcm2.v" type="file.verilog" enable="1"/>
|
||||||
|
<File path="src/rtl/perips/pa_perips_timer.v" type="file.verilog" enable="1"/>
|
||||||
|
<File path="src/rtl/perips/pa_perips_uart.v" type="file.verilog" enable="1"/>
|
||||||
|
<File path="src/rtl/soc/pa_soc_rbm.v" type="file.verilog" enable="1"/>
|
||||||
|
<File path="src/rtl/utils/pa_dff.v" type="file.verilog" enable="1"/>
|
||||||
|
<File path="src/fpga_project.cst" type="file.cst" enable="1"/>
|
||||||
|
<File path="src/fpga_project.sdc" type="file.sdc" enable="1"/>
|
||||||
|
</FileList>
|
||||||
|
</Project>
|
|
@ -0,0 +1,11 @@
|
||||||
|
#.gitignore
|
||||||
|
|
||||||
|
# Step-1, track all files in the current folder
|
||||||
|
!*
|
||||||
|
|
||||||
|
# Step-2, track specified files in the current folder
|
||||||
|
#*
|
||||||
|
#!*/
|
||||||
|
|
||||||
|
# Step-3, untrack all in sub folders, which use their own .gitignore
|
||||||
|
*/*
|
|
@ -0,0 +1,20 @@
|
||||||
|
+incdir+../../fpga_project/src/rtl
|
||||||
|
../../fpga_project/src/rtl/utils/pa_dff.v
|
||||||
|
../../fpga_project/src/rtl/core/pa_core_xreg.v
|
||||||
|
../../fpga_project/src/rtl/core/pa_core_csr.v
|
||||||
|
../../fpga_project/src/rtl/core/pa_core_pcgen.v
|
||||||
|
../../fpga_project/src/rtl/core/pa_core_idu.v
|
||||||
|
../../fpga_project/src/rtl/core/pa_core_exu_div.v
|
||||||
|
../../fpga_project/src/rtl/core/pa_core_exu_mul.v
|
||||||
|
../../fpga_project/src/rtl/core/pa_core_exu.v
|
||||||
|
../../fpga_project/src/rtl/core/pa_core_clint.v
|
||||||
|
../../fpga_project/src/rtl/core/pa_core_mau.v
|
||||||
|
../../fpga_project/src/rtl/core/pa_core_rtu.v
|
||||||
|
../../fpga_project/src/rtl/core/pa_core_top.v
|
||||||
|
../../fpga_project/src/rtl/perips/pa_perips_tcm.v
|
||||||
|
../../fpga_project/src/rtl/perips/pa_perips_tcm2.v
|
||||||
|
../../fpga_project/src/rtl/perips/pa_perips_timer.v
|
||||||
|
../../fpga_project/src/rtl/perips/pa_perips_uart.v
|
||||||
|
../../fpga_project/src/rtl/perips/pa_perips_gpio.v
|
||||||
|
../../fpga_project/src/rtl/soc/pa_soc_rbm.v
|
||||||
|
../../fpga_project/src/rtl/pa_chip_top.v
|
|
@ -0,0 +1,64 @@
|
||||||
|
//Copyright (C)2014-2023 Gowin Semiconductor Corporation.
|
||||||
|
//All rights reserved.
|
||||||
|
//File Title: Physical Constraints file
|
||||||
|
//GOWIN Version: 1.9.8.11 Education
|
||||||
|
//Part Number: GW1NR-LV9QN88PC6/I5
|
||||||
|
//Device: GW1NR-9
|
||||||
|
//Device Version: C
|
||||||
|
//Created Time: Sat 12 30 20:58:14 2023
|
||||||
|
|
||||||
|
IO_LOC "clk_i" 52;
|
||||||
|
IO_PORT "clk_i" IO_TYPE=LVCMOS33 PULL_MODE=UP BANK_VCCIO=3.3;
|
||||||
|
IO_LOC "rst_n_i" 4;
|
||||||
|
IO_PORT "rst_n_i" IO_TYPE=LVCMOS33 PULL_MODE=UP BANK_VCCIO=3.3;
|
||||||
|
|
||||||
|
IO_LOC "clk_o" 38;
|
||||||
|
IO_PORT "clk_o" IO_TYPE=LVCMOS33 PULL_MODE=UP DRIVE=12 OPEN_DRAIN=OFF BANK_VCCIO=3.3;
|
||||||
|
|
||||||
|
IO_LOC "gpio_PA15" 70;
|
||||||
|
IO_PORT "gpio_PA15" IO_TYPE=LVCMOS33 PULL_MODE=UP DRIVE=12 OPEN_DRAIN=OFF BANK_VCCIO=3.3;
|
||||||
|
|
||||||
|
IO_LOC "gpio_PA14" 71;
|
||||||
|
IO_PORT "gpio_PA14" IO_TYPE=LVCMOS33 PULL_MODE=UP BANK_VCCIO=3.3;
|
||||||
|
|
||||||
|
IO_LOC "gpio_PA13" 72;
|
||||||
|
IO_PORT "gpio_PA13" IO_TYPE=LVCMOS33 PULL_MODE=UP DRIVE=12 OPEN_DRAIN=OFF BANK_VCCIO=3.3;
|
||||||
|
|
||||||
|
IO_LOC "gpio_PA12" 73;
|
||||||
|
IO_PORT "gpio_PA12" IO_TYPE=LVCMOS33 PULL_MODE=UP DRIVE=12 OPEN_DRAIN=OFF BANK_VCCIO=3.3;
|
||||||
|
|
||||||
|
IO_LOC "gpio_PA11" 74;
|
||||||
|
IO_PORT "gpio_PA11" IO_TYPE=LVCMOS33 PULL_MODE=UP DRIVE=12 OPEN_DRAIN=OFF BANK_VCCIO=3.3;
|
||||||
|
|
||||||
|
IO_LOC "gpio_PA10" 75;
|
||||||
|
IO_PORT "gpio_PA10" IO_TYPE=LVCMOS33 PULL_MODE=UP BANK_VCCIO=3.3;
|
||||||
|
|
||||||
|
IO_LOC "gpio_PA9" 76;
|
||||||
|
IO_PORT "gpio_PA9" IO_TYPE=LVCMOS33 PULL_MODE=UP DRIVE=12 OPEN_DRAIN=OFF BANK_VCCIO=3.3;
|
||||||
|
|
||||||
|
IO_LOC "gpio_PA8" 77;
|
||||||
|
IO_PORT "gpio_PA8" IO_TYPE=LVCMOS33 PULL_MODE=NONE DRIVE=12 OPEN_DRAIN=ON BANK_VCCIO=3.3;
|
||||||
|
|
||||||
|
IO_LOC "gpio_PA7" 79;
|
||||||
|
IO_PORT "gpio_PA7" IO_TYPE=LVCMOS33 PULL_MODE=NONE DRIVE=12 OPEN_DRAIN=ON BANK_VCCIO=3.3;
|
||||||
|
|
||||||
|
IO_LOC "gpio_PA6" 80;
|
||||||
|
IO_PORT "gpio_PA6" IO_TYPE=LVCMOS33 PULL_MODE=NONE DRIVE=12 OPEN_DRAIN=ON BANK_VCCIO=3.3;
|
||||||
|
|
||||||
|
IO_LOC "gpio_PA5" 81;
|
||||||
|
IO_PORT "gpio_PA5" IO_TYPE=LVCMOS33 PULL_MODE=NONE DRIVE=12 OPEN_DRAIN=ON BANK_VCCIO=3.3;
|
||||||
|
|
||||||
|
IO_LOC "gpio_PA4" 82;
|
||||||
|
IO_PORT "gpio_PA4" IO_TYPE=LVCMOS33 PULL_MODE=NONE DRIVE=12 OPEN_DRAIN=ON BANK_VCCIO=3.3;
|
||||||
|
|
||||||
|
IO_LOC "gpio_PA3" 83;
|
||||||
|
IO_PORT "gpio_PA3" IO_TYPE=LVCMOS33 PULL_MODE=UP DRIVE=12 OPEN_DRAIN=OFF BANK_VCCIO=3.3;
|
||||||
|
|
||||||
|
IO_LOC "gpio_PA2" 84;
|
||||||
|
IO_PORT "gpio_PA2" IO_TYPE=LVCMOS33 PULL_MODE=NONE DRIVE=12 OPEN_DRAIN=ON BANK_VCCIO=3.3;
|
||||||
|
|
||||||
|
IO_LOC "gpio_PA1" 85;
|
||||||
|
IO_PORT "gpio_PA1" IO_TYPE=LVCMOS33 PULL_MODE=NONE DRIVE=12 OPEN_DRAIN=ON BANK_VCCIO=3.3;
|
||||||
|
|
||||||
|
IO_LOC "gpio_PA0" 86;
|
||||||
|
IO_PORT "gpio_PA0" IO_TYPE=LVCMOS33 PULL_MODE=NONE DRIVE=12 OPEN_DRAIN=ON BANK_VCCIO=3.3;
|
|
@ -0,0 +1,7 @@
|
||||||
|
//Copyright (C)2014-2024 GOWIN Semiconductor Corporation.
|
||||||
|
//All rights reserved.
|
||||||
|
//File Title: Timing Constraints file
|
||||||
|
//GOWIN Version: 1.9.8.11 Education
|
||||||
|
//Created Time: 2024-01-06 21:37:45
|
||||||
|
create_clock -name clk_i -period 37.037 -waveform {0 18.518} [get_ports {clk_i}]
|
||||||
|
create_clock -name clk_o -period 98.765 -waveform {0 49.383} [get_ports {clk_o}]
|
|
@ -0,0 +1,16 @@
|
||||||
|
#.gitignore
|
||||||
|
|
||||||
|
# Step-1, track all files in the current folder
|
||||||
|
!*
|
||||||
|
|
||||||
|
# Step-2, track specified files in the current folder
|
||||||
|
*
|
||||||
|
!*/
|
||||||
|
!.gitignore
|
||||||
|
!*.ipc
|
||||||
|
!*.v
|
||||||
|
|
||||||
|
*_tmp.v
|
||||||
|
|
||||||
|
# Step-3, untrack all in sub folders, which use their own .gitignore
|
||||||
|
#*/*
|
|
@ -0,0 +1,24 @@
|
||||||
|
[General]
|
||||||
|
ipc_version=4
|
||||||
|
file=gowin_dpb_32x8k
|
||||||
|
module=Gowin_DPB_32x8k
|
||||||
|
target_device=gw1nr9c-004
|
||||||
|
type=ram_dpb
|
||||||
|
version=1.0
|
||||||
|
|
||||||
|
[Config]
|
||||||
|
Area=true
|
||||||
|
BYTE_SIZE=0
|
||||||
|
DEPTH_A=8192
|
||||||
|
DEPTH_B=8192
|
||||||
|
LANG=0
|
||||||
|
READ_A=0
|
||||||
|
READ_B=0
|
||||||
|
RESET_MODE=true
|
||||||
|
Speed=false
|
||||||
|
WIDTH_A=32
|
||||||
|
WIDTH_B=32
|
||||||
|
WRITE_A=0
|
||||||
|
WRITE_B=0
|
||||||
|
DIMENSION_MATCH=65
|
||||||
|
MEM_FILE=E:\\0_Project\\rep_mygit\\TraSH\\riscv-bootloader.mi
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,22 @@
|
||||||
|
[General]
|
||||||
|
ipc_version=4
|
||||||
|
file=gowin_dpb_8x4k
|
||||||
|
module=Gowin_DPB_8x4k
|
||||||
|
target_device=gw1nr9c-004
|
||||||
|
type=ram_dpb
|
||||||
|
version=1.0
|
||||||
|
|
||||||
|
[Config]
|
||||||
|
Area=true
|
||||||
|
BYTE_SIZE=0
|
||||||
|
DEPTH_A=4096
|
||||||
|
DEPTH_B=4096
|
||||||
|
LANG=0
|
||||||
|
READ_A=0
|
||||||
|
READ_B=0
|
||||||
|
RESET_MODE=true
|
||||||
|
Speed=false
|
||||||
|
WIDTH_A=8
|
||||||
|
WIDTH_B=8
|
||||||
|
WRITE_A=0
|
||||||
|
WRITE_B=0
|
|
@ -0,0 +1,99 @@
|
||||||
|
//Copyright (C)2014-2023 Gowin Semiconductor Corporation.
|
||||||
|
//All rights reserved.
|
||||||
|
//File Title: IP file
|
||||||
|
//GOWIN Version: V1.9.8.11 Education
|
||||||
|
//Part Number: GW1NR-LV9QN88PC6/I5
|
||||||
|
//Device: GW1NR-9
|
||||||
|
//Device Version: C
|
||||||
|
//Created Time: Sat Jan 06 16:21:33 2024
|
||||||
|
|
||||||
|
module Gowin_DPB_8x4k (douta, doutb, clka, ocea, cea, reseta, wrea, clkb, oceb, ceb, resetb, wreb, ada, dina, adb, dinb);
|
||||||
|
|
||||||
|
output [7:0] douta;
|
||||||
|
output [7:0] doutb;
|
||||||
|
input clka;
|
||||||
|
input ocea;
|
||||||
|
input cea;
|
||||||
|
input reseta;
|
||||||
|
input wrea;
|
||||||
|
input clkb;
|
||||||
|
input oceb;
|
||||||
|
input ceb;
|
||||||
|
input resetb;
|
||||||
|
input wreb;
|
||||||
|
input [11:0] ada;
|
||||||
|
input [7:0] dina;
|
||||||
|
input [11:0] adb;
|
||||||
|
input [7:0] dinb;
|
||||||
|
|
||||||
|
wire [11:0] dpb_inst_0_douta_w;
|
||||||
|
wire [11:0] dpb_inst_0_doutb_w;
|
||||||
|
wire [11:0] dpb_inst_1_douta_w;
|
||||||
|
wire [11:0] dpb_inst_1_doutb_w;
|
||||||
|
wire gw_gnd;
|
||||||
|
|
||||||
|
assign gw_gnd = 1'b0;
|
||||||
|
|
||||||
|
DPB dpb_inst_0 (
|
||||||
|
.DOA({dpb_inst_0_douta_w[11:0],douta[3:0]}),
|
||||||
|
.DOB({dpb_inst_0_doutb_w[11:0],doutb[3:0]}),
|
||||||
|
.CLKA(clka),
|
||||||
|
.OCEA(ocea),
|
||||||
|
.CEA(cea),
|
||||||
|
.RESETA(reseta),
|
||||||
|
.WREA(wrea),
|
||||||
|
.CLKB(clkb),
|
||||||
|
.OCEB(oceb),
|
||||||
|
.CEB(ceb),
|
||||||
|
.RESETB(resetb),
|
||||||
|
.WREB(wreb),
|
||||||
|
.BLKSELA({gw_gnd,gw_gnd,gw_gnd}),
|
||||||
|
.BLKSELB({gw_gnd,gw_gnd,gw_gnd}),
|
||||||
|
.ADA({ada[11:0],gw_gnd,gw_gnd}),
|
||||||
|
.DIA({gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,dina[3:0]}),
|
||||||
|
.ADB({adb[11:0],gw_gnd,gw_gnd}),
|
||||||
|
.DIB({gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,dinb[3:0]})
|
||||||
|
);
|
||||||
|
|
||||||
|
defparam dpb_inst_0.READ_MODE0 = 1'b0;
|
||||||
|
defparam dpb_inst_0.READ_MODE1 = 1'b0;
|
||||||
|
defparam dpb_inst_0.WRITE_MODE0 = 2'b00;
|
||||||
|
defparam dpb_inst_0.WRITE_MODE1 = 2'b00;
|
||||||
|
defparam dpb_inst_0.BIT_WIDTH_0 = 4;
|
||||||
|
defparam dpb_inst_0.BIT_WIDTH_1 = 4;
|
||||||
|
defparam dpb_inst_0.BLK_SEL_0 = 3'b000;
|
||||||
|
defparam dpb_inst_0.BLK_SEL_1 = 3'b000;
|
||||||
|
defparam dpb_inst_0.RESET_MODE = "SYNC";
|
||||||
|
|
||||||
|
DPB dpb_inst_1 (
|
||||||
|
.DOA({dpb_inst_1_douta_w[11:0],douta[7:4]}),
|
||||||
|
.DOB({dpb_inst_1_doutb_w[11:0],doutb[7:4]}),
|
||||||
|
.CLKA(clka),
|
||||||
|
.OCEA(ocea),
|
||||||
|
.CEA(cea),
|
||||||
|
.RESETA(reseta),
|
||||||
|
.WREA(wrea),
|
||||||
|
.CLKB(clkb),
|
||||||
|
.OCEB(oceb),
|
||||||
|
.CEB(ceb),
|
||||||
|
.RESETB(resetb),
|
||||||
|
.WREB(wreb),
|
||||||
|
.BLKSELA({gw_gnd,gw_gnd,gw_gnd}),
|
||||||
|
.BLKSELB({gw_gnd,gw_gnd,gw_gnd}),
|
||||||
|
.ADA({ada[11:0],gw_gnd,gw_gnd}),
|
||||||
|
.DIA({gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,dina[7:4]}),
|
||||||
|
.ADB({adb[11:0],gw_gnd,gw_gnd}),
|
||||||
|
.DIB({gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,dinb[7:4]})
|
||||||
|
);
|
||||||
|
|
||||||
|
defparam dpb_inst_1.READ_MODE0 = 1'b0;
|
||||||
|
defparam dpb_inst_1.READ_MODE1 = 1'b0;
|
||||||
|
defparam dpb_inst_1.WRITE_MODE0 = 2'b00;
|
||||||
|
defparam dpb_inst_1.WRITE_MODE1 = 2'b00;
|
||||||
|
defparam dpb_inst_1.BIT_WIDTH_0 = 4;
|
||||||
|
defparam dpb_inst_1.BIT_WIDTH_1 = 4;
|
||||||
|
defparam dpb_inst_1.BLK_SEL_0 = 3'b000;
|
||||||
|
defparam dpb_inst_1.BLK_SEL_1 = 3'b000;
|
||||||
|
defparam dpb_inst_1.RESET_MODE = "SYNC";
|
||||||
|
|
||||||
|
endmodule //Gowin_DPB_8x4k
|
|
@ -0,0 +1,24 @@
|
||||||
|
[General]
|
||||||
|
ipc_version=4
|
||||||
|
file=gowin_rpll
|
||||||
|
module=Gowin_rPLL
|
||||||
|
target_device=gw1nr9c-004
|
||||||
|
type=clock_rpll
|
||||||
|
version=1.0
|
||||||
|
|
||||||
|
[Config]
|
||||||
|
CKLOUTD3=false
|
||||||
|
CLKFB_SOURCE=0
|
||||||
|
CLKIN_FREQ=27
|
||||||
|
CLKOUTD=false
|
||||||
|
CLKOUTP=false
|
||||||
|
CLKOUT_BYPASS=false
|
||||||
|
CLKOUT_DIVIDE_DYN=true
|
||||||
|
CLKOUT_FREQ=10.125
|
||||||
|
CLKOUT_TOLERANCE=0
|
||||||
|
DYNAMIC=false
|
||||||
|
LANG=0
|
||||||
|
LOCK_EN=true
|
||||||
|
MODE_GENERAL=true
|
||||||
|
PLL_PWD=false
|
||||||
|
RESET_PLL=true
|
|
@ -0,0 +1,65 @@
|
||||||
|
//Copyright (C)2014-2023 Gowin Semiconductor Corporation.
|
||||||
|
//All rights reserved.
|
||||||
|
//File Title: IP file
|
||||||
|
//GOWIN Version: V1.9.8.11 Education
|
||||||
|
//Part Number: GW1NR-LV9QN88PC6/I5
|
||||||
|
//Device: GW1NR-9
|
||||||
|
//Device Version: C
|
||||||
|
//Created Time: Sat Jan 06 21:34:57 2024
|
||||||
|
|
||||||
|
module Gowin_rPLL (clkout, lock, reset, clkin);
|
||||||
|
|
||||||
|
output clkout;
|
||||||
|
output lock;
|
||||||
|
input reset;
|
||||||
|
input clkin;
|
||||||
|
|
||||||
|
wire clkoutp_o;
|
||||||
|
wire clkoutd_o;
|
||||||
|
wire clkoutd3_o;
|
||||||
|
wire gw_gnd;
|
||||||
|
|
||||||
|
assign gw_gnd = 1'b0;
|
||||||
|
|
||||||
|
rPLL rpll_inst (
|
||||||
|
.CLKOUT(clkout),
|
||||||
|
.LOCK(lock),
|
||||||
|
.CLKOUTP(clkoutp_o),
|
||||||
|
.CLKOUTD(clkoutd_o),
|
||||||
|
.CLKOUTD3(clkoutd3_o),
|
||||||
|
.RESET(reset),
|
||||||
|
.RESET_P(gw_gnd),
|
||||||
|
.CLKIN(clkin),
|
||||||
|
.CLKFB(gw_gnd),
|
||||||
|
.FBDSEL({gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd}),
|
||||||
|
.IDSEL({gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd}),
|
||||||
|
.ODSEL({gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd}),
|
||||||
|
.PSDA({gw_gnd,gw_gnd,gw_gnd,gw_gnd}),
|
||||||
|
.DUTYDA({gw_gnd,gw_gnd,gw_gnd,gw_gnd}),
|
||||||
|
.FDLY({gw_gnd,gw_gnd,gw_gnd,gw_gnd})
|
||||||
|
);
|
||||||
|
|
||||||
|
defparam rpll_inst.FCLKIN = "27";
|
||||||
|
defparam rpll_inst.DYN_IDIV_SEL = "false";
|
||||||
|
defparam rpll_inst.IDIV_SEL = 7;
|
||||||
|
defparam rpll_inst.DYN_FBDIV_SEL = "false";
|
||||||
|
defparam rpll_inst.FBDIV_SEL = 2;
|
||||||
|
defparam rpll_inst.DYN_ODIV_SEL = "false";
|
||||||
|
defparam rpll_inst.ODIV_SEL = 48;
|
||||||
|
defparam rpll_inst.PSDA_SEL = "0000";
|
||||||
|
defparam rpll_inst.DYN_DA_EN = "false";
|
||||||
|
defparam rpll_inst.DUTYDA_SEL = "1000";
|
||||||
|
defparam rpll_inst.CLKOUT_FT_DIR = 1'b1;
|
||||||
|
defparam rpll_inst.CLKOUTP_FT_DIR = 1'b1;
|
||||||
|
defparam rpll_inst.CLKOUT_DLY_STEP = 0;
|
||||||
|
defparam rpll_inst.CLKOUTP_DLY_STEP = 0;
|
||||||
|
defparam rpll_inst.CLKFB_SEL = "internal";
|
||||||
|
defparam rpll_inst.CLKOUT_BYPASS = "false";
|
||||||
|
defparam rpll_inst.CLKOUTP_BYPASS = "false";
|
||||||
|
defparam rpll_inst.CLKOUTD_BYPASS = "false";
|
||||||
|
defparam rpll_inst.DYN_SDIV_SEL = 2;
|
||||||
|
defparam rpll_inst.CLKOUTD_SRC = "CLKOUT";
|
||||||
|
defparam rpll_inst.CLKOUTD3_SRC = "CLKOUT";
|
||||||
|
defparam rpll_inst.DEVICE = "GW1NR-9C";
|
||||||
|
|
||||||
|
endmodule //Gowin_rPLL
|
|
@ -0,0 +1,13 @@
|
||||||
|
#.gitignore
|
||||||
|
|
||||||
|
# Step-1, track all files in the current folder
|
||||||
|
!*
|
||||||
|
|
||||||
|
# Step-2, track specified files in the current folder
|
||||||
|
*
|
||||||
|
!*/
|
||||||
|
!.gitignore
|
||||||
|
!*.v
|
||||||
|
|
||||||
|
# Step-3, untrack all in sub folders, which use their own .gitignore
|
||||||
|
#*/*
|
|
@ -0,0 +1,302 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021, SERI Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2021-10-29 Lyons first version
|
||||||
|
* 2022-04-04 Lyons v2.0
|
||||||
|
* 2023-06-14 Lyons v3.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
`ifdef TESTBENCH_VCS
|
||||||
|
`include "pa_chip_param.v"
|
||||||
|
`else
|
||||||
|
`include "../pa_chip_param.v"
|
||||||
|
`endif
|
||||||
|
|
||||||
|
module pa_core_clint (
|
||||||
|
input wire clk_i,
|
||||||
|
input wire rst_n_i,
|
||||||
|
|
||||||
|
input wire inst_set_i, // indicate instruction set, [0], only support rv32i yet
|
||||||
|
input wire [2:0] inst_func_i, // indicate instruction func, [6:4], only 3-bits
|
||||||
|
|
||||||
|
input wire [`ADDR_BUS_WIDTH-1:0] pc_i,
|
||||||
|
input wire [`DATA_BUS_WIDTH-1:0] inst_i,
|
||||||
|
|
||||||
|
input wire [`DATA_BUS_WIDTH-1:0] csr_mtvec_i,
|
||||||
|
input wire [`DATA_BUS_WIDTH-1:0] csr_mepc_i,
|
||||||
|
input wire [`DATA_BUS_WIDTH-1:0] csr_mstatus_i,
|
||||||
|
|
||||||
|
input wire irq_i,
|
||||||
|
|
||||||
|
input wire jump_flag_i,
|
||||||
|
input wire hold_flag_i,
|
||||||
|
|
||||||
|
output wire [`CSR_BUS_WIDTH-1:0] csr_waddr_o,
|
||||||
|
output wire csr_waddr_vld_o,
|
||||||
|
output wire [`DATA_BUS_WIDTH-1:0] csr_wdata_o,
|
||||||
|
|
||||||
|
output wire hold_flag_o,
|
||||||
|
|
||||||
|
output wire jump_flag_o,
|
||||||
|
output wire [`DATA_BUS_WIDTH-1:0] jump_addr_o
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// value of 'int_state'
|
||||||
|
|
||||||
|
localparam INT_STATE_IDLE = 2'd0;
|
||||||
|
localparam INT_STATE_MCALL = 2'd1;
|
||||||
|
localparam INT_STATE_MRET = 2'd2;
|
||||||
|
|
||||||
|
// value of 'int_type'
|
||||||
|
|
||||||
|
localparam INT_TYPE_NONE = 2'b00;
|
||||||
|
localparam INT_TYPE_EXCRPTION = 2'b01;
|
||||||
|
localparam INT_TYPE_INTERRUPT = 2'b10;
|
||||||
|
localparam INT_TYPE_SOFTINT = 2'b11;
|
||||||
|
|
||||||
|
// value of 'csr_state'
|
||||||
|
|
||||||
|
localparam CSR_STATE_IDLE = 3'd0;
|
||||||
|
localparam CSR_STATE_WAIT = 3'd1;
|
||||||
|
localparam CSR_STATE_MEPC = 3'd2;
|
||||||
|
localparam CSR_STATE_MSTATUS = 3'd3;
|
||||||
|
localparam CSR_STATE_MCAUSE = 3'd4;
|
||||||
|
localparam CSR_STATE_MRET = 3'd5;
|
||||||
|
|
||||||
|
|
||||||
|
reg [1:0] int_state;
|
||||||
|
reg [1:0] int_type;
|
||||||
|
|
||||||
|
reg [2:0] csr_state;
|
||||||
|
|
||||||
|
wire inst_set_rvi;
|
||||||
|
|
||||||
|
assign inst_set_rvi = inst_set_i;
|
||||||
|
|
||||||
|
wire global_int_en;
|
||||||
|
wire global_int_si;
|
||||||
|
|
||||||
|
assign global_int_en = csr_mstatus_i[3]; // MIE
|
||||||
|
assign global_int_si = csr_mstatus_i[31]; // SINT
|
||||||
|
|
||||||
|
// 'op_xxx' is equal to zero when it is Non-ecall/ebreak/mret inst
|
||||||
|
|
||||||
|
wire op_ecall;
|
||||||
|
wire op_ebreak;
|
||||||
|
wire op_mret;
|
||||||
|
|
||||||
|
assign op_ecall = 0; //inst_set_rvi && inst_func_i[2]; // to inst_func_i[6]
|
||||||
|
assign op_ebreak = inst_set_rvi && inst_func_i[1]; // to inst_func_i[5]
|
||||||
|
assign op_mret = inst_set_rvi && inst_func_i[0]; // to inst_func_i[4]
|
||||||
|
|
||||||
|
wire [1:0] irq_1r;
|
||||||
|
pa_dff_rst_0 #(2) dff_irq_1r (clk_i, rst_n_i, `VALID, {irq_1r[0], irq_i}, irq_1r);
|
||||||
|
|
||||||
|
// 'irq_vld' is valid during the csr-handle cycle
|
||||||
|
|
||||||
|
wire irq_vld;
|
||||||
|
reg irq_vld_t;
|
||||||
|
|
||||||
|
always @ (posedge clk_i or negedge rst_n_i) begin
|
||||||
|
if (!rst_n_i) begin
|
||||||
|
irq_vld_t <= `INVALID;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
if (int_state == INT_STATE_IDLE) begin
|
||||||
|
irq_vld_t <= `INVALID;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
irq_vld_t <= irq_vld;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assign irq_vld = (irq_vld_t)
|
||||||
|
|| (~irq_1r[1] && irq_1r[0]); // posedge of irq_i
|
||||||
|
|
||||||
|
always @ (*) begin
|
||||||
|
if (!rst_n_i) begin
|
||||||
|
int_state <= INT_STATE_IDLE;
|
||||||
|
int_type <= INT_TYPE_NONE;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
if (op_mret) begin
|
||||||
|
int_state <= INT_STATE_MRET;
|
||||||
|
int_type <= INT_TYPE_EXCRPTION;
|
||||||
|
end
|
||||||
|
else if (op_ecall || op_ebreak) begin
|
||||||
|
int_state <= INT_STATE_MCALL;
|
||||||
|
int_type <= INT_TYPE_EXCRPTION;
|
||||||
|
end
|
||||||
|
else if (global_int_en && irq_vld) begin
|
||||||
|
int_state <= INT_STATE_MCALL;
|
||||||
|
int_type <= INT_TYPE_INTERRUPT;
|
||||||
|
end
|
||||||
|
else if (global_int_en && global_int_si) begin
|
||||||
|
int_state <= INT_STATE_MCALL;
|
||||||
|
int_type <= INT_TYPE_SOFTINT;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
int_state <= INT_STATE_IDLE;
|
||||||
|
int_type <= INT_TYPE_NONE;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
wire jump_addr_sel;
|
||||||
|
|
||||||
|
assign jump_addr_sel = ~(|inst_i[`DATA_BUS_WIDTH-1:0]);
|
||||||
|
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] inst_addr;
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] jump_addr;
|
||||||
|
|
||||||
|
assign inst_addr[`DATA_BUS_WIDTH-1:0] = pc_i[`DATA_BUS_WIDTH-1:0] + 32'hffff_fffc; // -4
|
||||||
|
assign jump_addr[`DATA_BUS_WIDTH-1:0] = pc_i[`DATA_BUS_WIDTH-1:0]; // -0
|
||||||
|
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] break_addr_soft;
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] break_addr_ext;
|
||||||
|
|
||||||
|
assign break_addr_soft[`DATA_BUS_WIDTH-1:0] = {32{int_type[0] & op_ecall }} & (jump_addr_sel ? jump_addr : inst_addr)
|
||||||
|
| {32{int_type[0] & op_ebreak }} & (jump_addr_sel ? jump_addr : inst_addr);
|
||||||
|
|
||||||
|
assign break_addr_ext[`DATA_BUS_WIDTH-1:0] = {32{int_type[1] }} & (jump_addr_sel ? jump_addr : inst_addr);
|
||||||
|
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] break_cause_soft;
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] break_cause_ext;
|
||||||
|
|
||||||
|
assign break_cause_soft[`DATA_BUS_WIDTH-1:0] = {32{int_type[0] & op_ecall }} & 32'd11
|
||||||
|
| {32{int_type[0] & op_ebreak }} & 32'd3;
|
||||||
|
|
||||||
|
assign break_cause_ext[`DATA_BUS_WIDTH-1:0] = {32{int_type[1] & ~int_type[0]}} & 32'h8000_0003
|
||||||
|
| {32{int_type[1] & int_type[0]}} & 32'h8000_0004;
|
||||||
|
|
||||||
|
always @ (posedge clk_i or negedge rst_n_i) begin
|
||||||
|
if (!rst_n_i) begin
|
||||||
|
csr_state <= CSR_STATE_IDLE;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
case (csr_state)
|
||||||
|
CSR_STATE_IDLE ,
|
||||||
|
CSR_STATE_WAIT : begin
|
||||||
|
case (int_state)
|
||||||
|
INT_STATE_MCALL : begin
|
||||||
|
if (jump_flag_i || hold_flag_i) begin
|
||||||
|
csr_state <= CSR_STATE_WAIT;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
csr_state <= CSR_STATE_MEPC;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
INT_STATE_MRET : begin
|
||||||
|
csr_state <= CSR_STATE_MRET;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
CSR_STATE_MEPC : csr_state <= (jump_flag_i ? CSR_STATE_MEPC : CSR_STATE_MSTATUS);
|
||||||
|
CSR_STATE_MSTATUS : csr_state <= CSR_STATE_MCAUSE;
|
||||||
|
CSR_STATE_MCAUSE : csr_state <= CSR_STATE_IDLE;
|
||||||
|
|
||||||
|
CSR_STATE_MRET : csr_state <= CSR_STATE_IDLE;
|
||||||
|
|
||||||
|
default : begin
|
||||||
|
csr_state <= CSR_STATE_IDLE;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] break_cause;
|
||||||
|
pa_dff_en_2 #(`DATA_BUS_WIDTH) dff_break_cause (clk_i, rst_n_i,
|
||||||
|
(int_state == INT_STATE_MCALL) && !jump_flag_i && !hold_flag_i,
|
||||||
|
(break_cause_soft | break_cause_ext), {`DATA_BUS_WIDTH{1'b0}},
|
||||||
|
break_cause);
|
||||||
|
|
||||||
|
reg [`CSR_BUS_WIDTH-1:0] csr_waddr;
|
||||||
|
reg csr_waddr_vld;
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] csr_wdata;
|
||||||
|
|
||||||
|
always @ (*) begin
|
||||||
|
case (csr_state)
|
||||||
|
CSR_STATE_MEPC : begin
|
||||||
|
csr_waddr <= {20'h0, `CSR_MEPC};
|
||||||
|
csr_waddr_vld <= `VALID;
|
||||||
|
csr_wdata <= break_addr_soft
|
||||||
|
| break_addr_ext;
|
||||||
|
end
|
||||||
|
|
||||||
|
CSR_STATE_MSTATUS : begin
|
||||||
|
csr_waddr <= {20'h0, `CSR_MSTATUS};
|
||||||
|
csr_waddr_vld <= `VALID;
|
||||||
|
csr_wdata <= {csr_mstatus_i[31:8], csr_mstatus_i[3], csr_mstatus_i[6:4], 1'b0, csr_mstatus_i[2:0]};
|
||||||
|
end
|
||||||
|
|
||||||
|
CSR_STATE_MCAUSE : begin
|
||||||
|
csr_waddr <= {20'h0, `CSR_MCAUSE};
|
||||||
|
csr_waddr_vld <= `VALID;
|
||||||
|
csr_wdata <= break_cause;
|
||||||
|
end
|
||||||
|
|
||||||
|
CSR_STATE_MRET : begin
|
||||||
|
csr_waddr <= {20'h0, `CSR_MSTATUS};
|
||||||
|
csr_waddr_vld <= `VALID;
|
||||||
|
csr_wdata <= {csr_mstatus_i[31:8], 1'b0, csr_mstatus_i[6:4], csr_mstatus_i[7], csr_mstatus_i[2:0]};
|
||||||
|
end
|
||||||
|
|
||||||
|
default : begin
|
||||||
|
csr_waddr <= `ZERO_WORD;
|
||||||
|
csr_waddr_vld <= `INVALID;
|
||||||
|
csr_wdata <= `ZERO_WORD;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] csr_mtvec;
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] csr_mepc;
|
||||||
|
|
||||||
|
assign csr_mtvec[`DATA_BUS_WIDTH-1:0] = (break_cause == 32'h8000_0004) ? (csr_mtvec_i[`DATA_BUS_WIDTH-1:0] + 32'h4)
|
||||||
|
: csr_mtvec_i[`DATA_BUS_WIDTH-1:0];
|
||||||
|
|
||||||
|
assign csr_mepc[`DATA_BUS_WIDTH-1:0] = csr_mepc_i[`DATA_BUS_WIDTH-1:0];
|
||||||
|
|
||||||
|
reg int_jump_flag;
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] int_jump_addr;
|
||||||
|
|
||||||
|
always @ (posedge clk_i or negedge rst_n_i) begin
|
||||||
|
if (!rst_n_i) begin
|
||||||
|
int_jump_flag <= `INVALID;
|
||||||
|
int_jump_addr <= `ZERO_WORD;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
case (csr_state)
|
||||||
|
CSR_STATE_MCAUSE : begin
|
||||||
|
int_jump_flag <= `VALID;
|
||||||
|
int_jump_addr <= csr_mtvec;
|
||||||
|
end
|
||||||
|
CSR_STATE_MRET : begin
|
||||||
|
int_jump_flag <= `VALID;
|
||||||
|
int_jump_addr <= csr_mepc;
|
||||||
|
end
|
||||||
|
default : begin
|
||||||
|
int_jump_flag <= `INVALID;
|
||||||
|
int_jump_addr <= `ZERO_WORD;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assign csr_waddr_o[`CSR_BUS_WIDTH-1:0] = csr_waddr[`CSR_BUS_WIDTH-1:0];
|
||||||
|
assign csr_waddr_vld_o = csr_waddr_vld;
|
||||||
|
assign csr_wdata_o[`DATA_BUS_WIDTH-1:0] = csr_wdata[`DATA_BUS_WIDTH-1:0];
|
||||||
|
|
||||||
|
assign hold_flag_o = (csr_state != CSR_STATE_IDLE);
|
||||||
|
|
||||||
|
assign jump_flag_o = int_jump_flag;
|
||||||
|
assign jump_addr_o[`DATA_BUS_WIDTH-1:0] = int_jump_addr[`DATA_BUS_WIDTH-1:0];
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,108 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021, SERI Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2021-10-29 Lyons first version
|
||||||
|
* 2022-04-04 Lyons v2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
`ifdef TESTBENCH_VCS
|
||||||
|
`include "pa_chip_param.v"
|
||||||
|
`else
|
||||||
|
`include "../pa_chip_param.v"
|
||||||
|
`endif
|
||||||
|
|
||||||
|
module pa_core_csr (
|
||||||
|
input wire clk_i,
|
||||||
|
input wire rst_n_i,
|
||||||
|
|
||||||
|
output wire [`DATA_BUS_WIDTH-1:0] csr_mtvec_o,
|
||||||
|
output wire [`DATA_BUS_WIDTH-1:0] csr_mepc_o,
|
||||||
|
output wire [`DATA_BUS_WIDTH-1:0] csr_mstatus_o,
|
||||||
|
|
||||||
|
input wire [`CSR_BUS_WIDTH-1:0] csr_raddr_i,
|
||||||
|
|
||||||
|
input wire [`CSR_BUS_WIDTH-1:0] csr_waddr_i,
|
||||||
|
input wire csr_waddr_vld_i,
|
||||||
|
|
||||||
|
input wire [`DATA_BUS_WIDTH-1:0] csr_wdata_i,
|
||||||
|
|
||||||
|
output wire [`DATA_BUS_WIDTH-1:0] csr_rdata_o
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] _mtvec; // Machine Trap Vector
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] _mepc; // Machine Exception PC
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] _mcause; // Machine Exception Cause
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] _mie; // Machine Interrupt Enable
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] _mip; // Machine Interrupt Pending
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] _mtval; // Machine Trap Value
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] _mscratch; // Machine Scratch
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] _mscratchcswl; // Machine Scratch
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] _mstatus; // Machine Status
|
||||||
|
reg [63:0] _cycle; // Machine Cycle
|
||||||
|
|
||||||
|
always @ (posedge clk_i or negedge rst_n_i) begin
|
||||||
|
if (!rst_n_i) begin
|
||||||
|
_cycle <= 64'h0;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
_cycle <= _cycle + 64'h1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always @ (posedge clk_i or negedge rst_n_i) begin
|
||||||
|
if (!rst_n_i) begin
|
||||||
|
_mtvec <= 32'h0;
|
||||||
|
_mepc <= 32'h0;
|
||||||
|
_mcause <= 32'h0;
|
||||||
|
_mie <= 32'h0;
|
||||||
|
_mip <= 32'h0;
|
||||||
|
_mtval <= 32'h0;
|
||||||
|
_mscratch <= 32'h0;
|
||||||
|
_mstatus <= 32'h0000_0060; // MPP=11
|
||||||
|
end
|
||||||
|
else if (csr_waddr_vld_i) begin
|
||||||
|
case (csr_waddr_i[11:0])
|
||||||
|
`CSR_MTVEC : _mtvec <= csr_wdata_i;
|
||||||
|
`CSR_MEPC : _mepc <= csr_wdata_i;
|
||||||
|
`CSR_MCAUSE : _mcause <= csr_wdata_i;
|
||||||
|
`CSR_MIE : _mie <= csr_wdata_i;
|
||||||
|
`CSR_MIP : _mip <= csr_wdata_i;
|
||||||
|
`CSR_MTVAL : _mtval <= csr_wdata_i;
|
||||||
|
`CSR_MSCRATCH : _mscratch <= csr_wdata_i;
|
||||||
|
`CSR_MSCRATCHCSWL : _mscratchcswl <= csr_wdata_i;
|
||||||
|
`CSR_MSTATUS : _mstatus <= csr_wdata_i;
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] _csr;
|
||||||
|
|
||||||
|
always @ (*) begin
|
||||||
|
_csr = `ZERO_WORD;
|
||||||
|
case (csr_raddr_i[11:0])
|
||||||
|
`CSR_MTVEC : _csr = _mtvec;
|
||||||
|
`CSR_MEPC : _csr = _mepc;
|
||||||
|
`CSR_MCAUSE : _csr = _mcause;
|
||||||
|
`CSR_MIE : _csr = _mie;
|
||||||
|
`CSR_MIP : _csr = _mip;
|
||||||
|
`CSR_MTVAL : _csr = _mtval;
|
||||||
|
`CSR_MSCRATCH : _csr = _mscratch;
|
||||||
|
`CSR_MSCRATCHCSWL : _csr = _mscratchcswl;
|
||||||
|
`CSR_MSTATUS : _csr = _mstatus;
|
||||||
|
`CSR_CYCLEH : _csr = _cycle[63:32];
|
||||||
|
`CSR_CYCLE : _csr = _cycle[31: 0];
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
assign csr_mtvec_o[`DATA_BUS_WIDTH-1:0] = _mtvec[`DATA_BUS_WIDTH-1:0];
|
||||||
|
assign csr_mepc_o[`DATA_BUS_WIDTH-1:0] = _mepc[`DATA_BUS_WIDTH-1:0];
|
||||||
|
assign csr_mstatus_o[`DATA_BUS_WIDTH-1:0] = _mstatus[`DATA_BUS_WIDTH-1:0];
|
||||||
|
|
||||||
|
assign csr_rdata_o[`DATA_BUS_WIDTH-1:0] = _csr[`DATA_BUS_WIDTH-1:0];
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,492 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021, SERI Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2021-10-29 Lyons first version
|
||||||
|
* 2022-04-04 Lyons v2.0
|
||||||
|
* 2023-06-14 Lyons v3.0, add comments
|
||||||
|
*/
|
||||||
|
|
||||||
|
`ifdef TESTBENCH_VCS
|
||||||
|
`include "pa_chip_param.v"
|
||||||
|
`else
|
||||||
|
`include "../pa_chip_param.v"
|
||||||
|
`endif
|
||||||
|
|
||||||
|
module pa_core_exu (
|
||||||
|
input wire clk_i,
|
||||||
|
input wire rst_n_i,
|
||||||
|
|
||||||
|
input wire [1:0] inst_set_i, // indicate instruction set, [1:0], only support rv32im yet
|
||||||
|
input wire [`INST_FUNC_WIDTH-1:0] inst_func_i,
|
||||||
|
|
||||||
|
input wire [`DATA_BUS_WIDTH-1:0] pc_i,
|
||||||
|
|
||||||
|
input wire [`DATA_BUS_WIDTH-1:0] reg1_rdata_i,
|
||||||
|
input wire [`DATA_BUS_WIDTH-1:0] reg2_rdata_i,
|
||||||
|
|
||||||
|
input wire [19:0] uimm_i, // immediate data, [19:0], only 20-bits
|
||||||
|
|
||||||
|
input wire [`REG_BUS_WIDTH-1:0] reg_waddr_i,
|
||||||
|
input wire reg_waddr_vld_i,
|
||||||
|
|
||||||
|
input wire [`DATA_BUS_WIDTH-1:0] csr_rdata_i,
|
||||||
|
|
||||||
|
output wire csr_waddr_vld_o,
|
||||||
|
output wire [`DATA_BUS_WIDTH-1:0] csr_wdata_o,
|
||||||
|
|
||||||
|
output wire mem_en_o,
|
||||||
|
|
||||||
|
output wire hold_flag_o,
|
||||||
|
|
||||||
|
output wire jump_flag_o,
|
||||||
|
output wire [`DATA_BUS_WIDTH-1:0] jump_addr_o,
|
||||||
|
|
||||||
|
output wire [`REG_BUS_WIDTH-1:0] reg_waddr_o,
|
||||||
|
output wire reg_waddr_vld_o,
|
||||||
|
|
||||||
|
output wire [`DATA_BUS_WIDTH-1:0] iresult_o,
|
||||||
|
output wire iresult_vld_o
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
wire inst_set_rvi;
|
||||||
|
wire inst_set_rvm;
|
||||||
|
|
||||||
|
assign inst_set_rvi = inst_set_i[0];
|
||||||
|
assign inst_set_rvm = inst_set_i[1];
|
||||||
|
|
||||||
|
wire subop_unsign;
|
||||||
|
wire subop_sign;
|
||||||
|
|
||||||
|
wire subop_immv;
|
||||||
|
wire subop_regv;
|
||||||
|
|
||||||
|
wire subop_eq;
|
||||||
|
wire subop_ne;
|
||||||
|
wire subop_lt;
|
||||||
|
wire subop_gt;
|
||||||
|
|
||||||
|
assign subop_unsign = inst_func_i[31];
|
||||||
|
assign subop_sign = !inst_func_i[31];
|
||||||
|
|
||||||
|
assign subop_immv = inst_func_i[30];
|
||||||
|
assign subop_regv = !inst_func_i[30];
|
||||||
|
|
||||||
|
assign subop_eq = inst_func_i[27];
|
||||||
|
assign subop_ne = inst_func_i[26];
|
||||||
|
assign subop_lt = inst_func_i[25];
|
||||||
|
assign subop_gt = inst_func_i[24];
|
||||||
|
|
||||||
|
wire op_add;
|
||||||
|
wire op_sub;
|
||||||
|
wire op_sll;
|
||||||
|
wire op_srl;
|
||||||
|
wire op_sra;
|
||||||
|
wire op_or;
|
||||||
|
wire op_and;
|
||||||
|
wire op_xor;
|
||||||
|
wire op_slt;
|
||||||
|
wire op_load;
|
||||||
|
wire op_store;
|
||||||
|
wire op_fence;
|
||||||
|
wire op_b;
|
||||||
|
wire op_jal;
|
||||||
|
wire op_jalr;
|
||||||
|
wire op_auipc;
|
||||||
|
wire op_lui;
|
||||||
|
wire op_ecall;
|
||||||
|
wire op_ebrea;
|
||||||
|
wire op_mret;
|
||||||
|
wire op_wfi;
|
||||||
|
wire op_csrrw;
|
||||||
|
wire op_csrrs;
|
||||||
|
wire op_csrrc;
|
||||||
|
|
||||||
|
wire op_mul;
|
||||||
|
wire op_div;
|
||||||
|
wire op_rem;
|
||||||
|
|
||||||
|
assign op_add = inst_set_rvi && inst_func_i[23];
|
||||||
|
assign op_sub = inst_set_rvi && inst_func_i[22];
|
||||||
|
assign op_sll = inst_set_rvi && inst_func_i[21];
|
||||||
|
assign op_srl = inst_set_rvi && inst_func_i[20];
|
||||||
|
assign op_sra = inst_set_rvi && inst_func_i[19];
|
||||||
|
assign op_or = inst_set_rvi && inst_func_i[18];
|
||||||
|
assign op_and = inst_set_rvi && inst_func_i[17];
|
||||||
|
assign op_xor = inst_set_rvi && inst_func_i[16];
|
||||||
|
assign op_slt = inst_set_rvi && inst_func_i[15];
|
||||||
|
assign op_load = inst_set_rvi && inst_func_i[14];
|
||||||
|
assign op_store = inst_set_rvi && inst_func_i[13];
|
||||||
|
assign op_fence = inst_set_rvi && inst_func_i[12];
|
||||||
|
assign op_b = inst_set_rvi && inst_func_i[11];
|
||||||
|
assign op_jal = inst_set_rvi && inst_func_i[10];
|
||||||
|
assign op_jalr = inst_set_rvi && inst_func_i[ 9];
|
||||||
|
assign op_auipc = inst_set_rvi && inst_func_i[ 8];
|
||||||
|
assign op_lui = inst_set_rvi && inst_func_i[ 7];
|
||||||
|
assign op_ecall = inst_set_rvi && inst_func_i[ 6];
|
||||||
|
assign op_ebrea = inst_set_rvi && inst_func_i[ 5];
|
||||||
|
assign op_mret = inst_set_rvi && inst_func_i[ 4];
|
||||||
|
assign op_wfi = inst_set_rvi && inst_func_i[ 3];
|
||||||
|
assign op_csrrw = inst_set_rvi && inst_func_i[ 2];
|
||||||
|
assign op_csrrs = inst_set_rvi && inst_func_i[ 1];
|
||||||
|
assign op_csrrc = inst_set_rvi && inst_func_i[ 0];
|
||||||
|
|
||||||
|
assign op_mul = inst_set_rvm && inst_func_i[23];
|
||||||
|
assign op_div = inst_set_rvm && inst_func_i[22];
|
||||||
|
assign op_rem = inst_set_rvm && inst_func_i[21];
|
||||||
|
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] inst_addr;
|
||||||
|
|
||||||
|
assign inst_addr[`DATA_BUS_WIDTH-1:0] = pc_i[`DATA_BUS_WIDTH-1:0] + 32'hffff_fff8; // -8, back 2-inst
|
||||||
|
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] op_uimm5_zero;
|
||||||
|
|
||||||
|
assign op_uimm5_zero = {{27{1'b0}}, uimm_i[4:0]};
|
||||||
|
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] op_uimm12_zero;
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] op_uimm12_sign;
|
||||||
|
|
||||||
|
assign op_uimm12_zero = {{20{1'b0}}, uimm_i[11:0]};
|
||||||
|
assign op_uimm12_sign = {{20{uimm_i[11]}}, uimm_i[11:0]};
|
||||||
|
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] op1_data_1;
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] op1_data_2;
|
||||||
|
|
||||||
|
assign op1_data_1 = {32{op_csrrw || op_csrrs || op_csrrc}}
|
||||||
|
& (subop_immv ? op_uimm5_zero
|
||||||
|
: reg1_rdata_i);
|
||||||
|
|
||||||
|
assign op1_data_2 = {32{!op_csrrw && !op_csrrs && !op_csrrc}}
|
||||||
|
& reg1_rdata_i;
|
||||||
|
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] op2_data_1;
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] op2_data_2;
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] op2_data_3;
|
||||||
|
|
||||||
|
assign op2_data_1 = {32{op_slt || op_load || op_store}}
|
||||||
|
& (subop_immv ? op_uimm12_sign
|
||||||
|
: reg2_rdata_i);
|
||||||
|
|
||||||
|
assign op2_data_2 = {32{op_csrrw || op_csrrs || op_csrrc}}
|
||||||
|
& `ZERO_WORD;
|
||||||
|
|
||||||
|
assign op2_data_3 = {32{!op_slt && !op_load && !op_store && !op_csrrw && !op_csrrs && !op_csrrc}}
|
||||||
|
& (subop_immv ? subop_unsign ? op_uimm12_zero
|
||||||
|
: op_uimm12_sign
|
||||||
|
: reg2_rdata_i);
|
||||||
|
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] op1_data;
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] op2_data;
|
||||||
|
|
||||||
|
assign op1_data = op1_data_1
|
||||||
|
| op1_data_2;
|
||||||
|
|
||||||
|
assign op2_data = op2_data_1
|
||||||
|
| op2_data_2
|
||||||
|
| op2_data_3;
|
||||||
|
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] iresult_add;
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] iresult_sub;
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] iresult_sll;
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] iresult_srl;
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] iresult_sra;
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] iresult_or;
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] iresult_and;
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] iresult_xor;
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] iresult_slt;
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] iresult_mem;
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] iresult_jalx;
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] iresult_auipc;
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] iresult_lui;
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] iresult_csrw;
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] iresult_csrs;
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] iresult_csrc;
|
||||||
|
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] result_pc_bxx;
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] result_pc_jalx;
|
||||||
|
|
||||||
|
assign iresult_add = op1_data + op2_data;
|
||||||
|
|
||||||
|
assign iresult_sub = op1_data + (~op2_data + 32'h1);
|
||||||
|
|
||||||
|
assign iresult_sll = op1_data << op2_data[4:0]; // mux circuit
|
||||||
|
|
||||||
|
assign iresult_srl = op1_data >> op2_data[4:0]; // mux circuit
|
||||||
|
|
||||||
|
assign iresult_sra = iresult_srl
|
||||||
|
| ~(32'hffff_ffff >> op2_data[4:0]) & {32{op1_data[31]}};
|
||||||
|
|
||||||
|
assign iresult_or = op1_data | op2_data;
|
||||||
|
|
||||||
|
assign iresult_and = op1_data & op2_data;
|
||||||
|
|
||||||
|
assign iresult_xor = op1_data ^ op2_data;
|
||||||
|
|
||||||
|
wire [`DATA_BUS_WIDTH:0] iresult_subs;
|
||||||
|
wire [`DATA_BUS_WIDTH:0] iresult_subu;
|
||||||
|
|
||||||
|
wire iresult_subs_zero;
|
||||||
|
wire iresult_subu_zero;
|
||||||
|
|
||||||
|
assign iresult_subs = {op1_data[31], op1_data[31:0]}
|
||||||
|
+ (~{op2_data[31], op2_data[31:0]} + 33'h1);
|
||||||
|
|
||||||
|
assign iresult_subu = {1'b0, op1_data[31:0]}
|
||||||
|
+ (~{1'b0, op2_data[31:0]} + 33'h1);
|
||||||
|
|
||||||
|
assign iresult_subs_zero = ~(|iresult_subs[32:0]);
|
||||||
|
assign iresult_subu_zero = ~(|iresult_subu[32:0]);
|
||||||
|
|
||||||
|
assign iresult_slt = subop_unsign ? ((iresult_subu[32] && !iresult_subu_zero) ? 32'h1 : 32'h0)
|
||||||
|
: ((iresult_subs[32] && !iresult_subs_zero) ? 32'h1 : 32'h0);
|
||||||
|
|
||||||
|
assign iresult_mem = op1_data + op2_data;
|
||||||
|
|
||||||
|
wire op1_eq_op2;
|
||||||
|
wire op1_ne_op2;
|
||||||
|
wire op1_lt_op2;
|
||||||
|
wire op1_ge_op2;
|
||||||
|
|
||||||
|
assign op1_eq_op2 = subop_eq && iresult_subs_zero;
|
||||||
|
assign op1_ne_op2 = subop_ne && !iresult_subs_zero;
|
||||||
|
assign op1_lt_op2 = subop_lt && iresult_subs[32];
|
||||||
|
assign op1_ge_op2 = subop_gt && !iresult_subs[32];
|
||||||
|
|
||||||
|
wire op1_ltu_op2;
|
||||||
|
wire op1_geu_op2;
|
||||||
|
|
||||||
|
assign op1_ltu_op2 = subop_lt && iresult_subu[32];
|
||||||
|
assign op1_geu_op2 = subop_gt && !iresult_subu[32];
|
||||||
|
|
||||||
|
wire bxx_valid;
|
||||||
|
|
||||||
|
assign bxx_valid = subop_sign && (op1_eq_op2 || op1_ne_op2 || op1_lt_op2 || op1_ge_op2)
|
||||||
|
|| subop_unsign && (op1_ltu_op2 || op1_geu_op2);
|
||||||
|
|
||||||
|
assign result_pc_bxx = inst_addr + {{19{uimm_i[11]}}, uimm_i[11:0], 1'b0};
|
||||||
|
|
||||||
|
assign result_pc_jalx = {32{op_jalr}} & ( (op1_data + {{20{uimm_i[11]}}, uimm_i[11:0]}) & 32'hffff_fffe )
|
||||||
|
| {32{op_jal }} & ( inst_addr + {{11{uimm_i[11]}}, uimm_i[19:0], 1'b0} );
|
||||||
|
|
||||||
|
assign iresult_jalx = inst_addr + 32'h4;
|
||||||
|
|
||||||
|
assign iresult_auipc = inst_addr + {uimm_i[19:0], 12'b0};
|
||||||
|
|
||||||
|
assign iresult_lui = {uimm_i[19:0], 12'b0};
|
||||||
|
|
||||||
|
assign iresult_csrw = op1_data;
|
||||||
|
assign iresult_csrs = csr_rdata_i | op1_data;
|
||||||
|
assign iresult_csrc = csr_rdata_i & ~op1_data;
|
||||||
|
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] iresult_i_final;
|
||||||
|
|
||||||
|
always @ (*) begin
|
||||||
|
iresult_i_final = `ZERO_WORD;
|
||||||
|
case (inst_func_i[`INST_FUNC_WIDTH-1:0] & 32'h00_ffffff)
|
||||||
|
`INST_FUNC_ADD : iresult_i_final = iresult_add;
|
||||||
|
`INST_FUNC_SUB : iresult_i_final = iresult_sub;
|
||||||
|
`INST_FUNC_SLL : iresult_i_final = iresult_sll;
|
||||||
|
`INST_FUNC_SRL : iresult_i_final = iresult_srl;
|
||||||
|
`INST_FUNC_SRA : iresult_i_final = iresult_sra;
|
||||||
|
`INST_FUNC_OR : iresult_i_final = iresult_or;
|
||||||
|
`INST_FUNC_AND : iresult_i_final = iresult_and;
|
||||||
|
`INST_FUNC_XOR : iresult_i_final = iresult_xor;
|
||||||
|
`INST_FUNC_SLT : iresult_i_final = iresult_slt;
|
||||||
|
|
||||||
|
`INST_FUNC_LOAD : iresult_i_final = iresult_mem;
|
||||||
|
`INST_FUNC_STORE : iresult_i_final = iresult_mem;
|
||||||
|
|
||||||
|
`INST_FUNC_FENCE : iresult_i_final = `ZERO_WORD; // not support yet
|
||||||
|
|
||||||
|
`INST_FUNC_B : iresult_i_final = `ZERO_WORD;
|
||||||
|
|
||||||
|
`INST_FUNC_JAL : iresult_i_final = iresult_jalx;
|
||||||
|
`INST_FUNC_JALR : iresult_i_final = iresult_jalx;
|
||||||
|
|
||||||
|
`INST_FUNC_AUIPC : iresult_i_final = iresult_auipc;
|
||||||
|
`INST_FUNC_LUI : iresult_i_final = iresult_lui;
|
||||||
|
|
||||||
|
`INST_FUNC_WFI : iresult_i_final = `ZERO_WORD; // not support yet
|
||||||
|
|
||||||
|
`INST_FUNC_CSRRW : iresult_i_final = csr_rdata_i;
|
||||||
|
`INST_FUNC_CSRRS : iresult_i_final = csr_rdata_i;
|
||||||
|
`INST_FUNC_CSRRC : iresult_i_final = csr_rdata_i;
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
reg iresult_i_vld;
|
||||||
|
|
||||||
|
always @ (*) begin
|
||||||
|
iresult_i_vld = `INVALID;
|
||||||
|
case (inst_func_i[`INST_FUNC_WIDTH-1:0] & 32'h00_ffffff)
|
||||||
|
`INST_FUNC_ADD : iresult_i_vld = `VALID;
|
||||||
|
`INST_FUNC_SUB : iresult_i_vld = `VALID;
|
||||||
|
`INST_FUNC_SLL : iresult_i_vld = `VALID;
|
||||||
|
`INST_FUNC_SRL : iresult_i_vld = `VALID;
|
||||||
|
`INST_FUNC_SRA : iresult_i_vld = `VALID;
|
||||||
|
`INST_FUNC_OR : iresult_i_vld = `VALID;
|
||||||
|
`INST_FUNC_AND : iresult_i_vld = `VALID;
|
||||||
|
`INST_FUNC_XOR : iresult_i_vld = `VALID;
|
||||||
|
`INST_FUNC_SLT : iresult_i_vld = `VALID;
|
||||||
|
|
||||||
|
`INST_FUNC_LOAD : iresult_i_vld = `VALID;
|
||||||
|
`INST_FUNC_STORE : iresult_i_vld = `VALID;
|
||||||
|
|
||||||
|
`INST_FUNC_FENCE : iresult_i_vld = `INVALID; // not support yet
|
||||||
|
|
||||||
|
`INST_FUNC_B : iresult_i_vld = `VALID;
|
||||||
|
|
||||||
|
`INST_FUNC_JAL : iresult_i_vld = `VALID;
|
||||||
|
`INST_FUNC_JALR : iresult_i_vld = `VALID;
|
||||||
|
|
||||||
|
`INST_FUNC_AUIPC : iresult_i_vld = `VALID;
|
||||||
|
`INST_FUNC_LUI : iresult_i_vld = `VALID;
|
||||||
|
|
||||||
|
`INST_FUNC_WFI : iresult_i_vld = `INVALID; //not support yet
|
||||||
|
|
||||||
|
`INST_FUNC_CSRRW : iresult_i_vld = `VALID;
|
||||||
|
`INST_FUNC_CSRRS : iresult_i_vld = `VALID;
|
||||||
|
`INST_FUNC_CSRRC : iresult_i_vld = `VALID;
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
// rv32m: mul process
|
||||||
|
|
||||||
|
wire subop_unsign_u1;
|
||||||
|
wire subop_unsign_u2;
|
||||||
|
|
||||||
|
wire subop_high;
|
||||||
|
wire subop_low;
|
||||||
|
|
||||||
|
assign subop_unsign_u1 = inst_func_i[31] & inst_func_i[28];
|
||||||
|
assign subop_unsign_u2 = inst_func_i[31] & inst_func_i[29];
|
||||||
|
|
||||||
|
assign subop_high = inst_func_i[30];
|
||||||
|
assign subop_low = !inst_func_i[30];
|
||||||
|
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] op1_mul_data;
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] op2_mul_data;
|
||||||
|
|
||||||
|
assign op1_mul_data = (~subop_unsign_u1 & reg1_rdata_i[31]) ? (~reg1_rdata_i + 32'b1)
|
||||||
|
: ( reg1_rdata_i);
|
||||||
|
|
||||||
|
assign op2_mul_data = (~subop_unsign_u2 & reg2_rdata_i[31]) ? (~reg2_rdata_i + 32'b1)
|
||||||
|
: ( reg2_rdata_i);
|
||||||
|
|
||||||
|
wire iresult_mul_sign;
|
||||||
|
|
||||||
|
assign iresult_mul_sign = (~subop_unsign_u1 & reg1_rdata_i[31])
|
||||||
|
^ (~subop_unsign_u2 & reg2_rdata_i[31]);
|
||||||
|
|
||||||
|
wire [63:0] iresult_mul;
|
||||||
|
|
||||||
|
pa_core_exu_mul u_pa_core_exu_mul (
|
||||||
|
.data1_i (op1_mul_data),
|
||||||
|
.data2_i (op2_mul_data),
|
||||||
|
|
||||||
|
.sign_i (iresult_mul_sign),
|
||||||
|
|
||||||
|
.data_o (iresult_mul)
|
||||||
|
);
|
||||||
|
|
||||||
|
// rv32m: div process
|
||||||
|
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] op1_div_data;
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] op2_div_data;
|
||||||
|
|
||||||
|
assign op1_div_data = op1_mul_data;
|
||||||
|
assign op2_div_data = op2_mul_data;
|
||||||
|
|
||||||
|
wire iresult_q_sign;
|
||||||
|
wire iresult_r_sign;
|
||||||
|
|
||||||
|
assign iresult_q_sign = iresult_mul_sign;
|
||||||
|
assign iresult_r_sign = (~subop_unsign_u1 & reg1_rdata_i[31]);
|
||||||
|
|
||||||
|
wire div_hold;
|
||||||
|
|
||||||
|
wire [`REG_BUS_WIDTH-1:0] div_reg_waddr;
|
||||||
|
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] iresult_div_rem;
|
||||||
|
wire iresult_div_rem_vld;
|
||||||
|
|
||||||
|
pa_core_exu_div u_pa_core_exu_div (
|
||||||
|
.clk_i (clk_i),
|
||||||
|
.rst_n_i (rst_n_i),
|
||||||
|
|
||||||
|
.data1_i (op1_div_data),
|
||||||
|
.data2_i (op2_div_data),
|
||||||
|
|
||||||
|
.reg_waddr_i (reg_waddr_i),
|
||||||
|
|
||||||
|
.op_div_i (op_div),
|
||||||
|
.op_rem_i (op_rem),
|
||||||
|
|
||||||
|
.q_sign_i (iresult_q_sign),
|
||||||
|
.r_sign_i (iresult_r_sign),
|
||||||
|
|
||||||
|
.hold_o (div_hold),
|
||||||
|
|
||||||
|
.reg_waddr_o (div_reg_waddr),
|
||||||
|
|
||||||
|
.data_o (iresult_div_rem),
|
||||||
|
.data_vld_o (iresult_div_rem_vld)
|
||||||
|
);
|
||||||
|
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] iresult_m_final;
|
||||||
|
|
||||||
|
always @ (*) begin
|
||||||
|
iresult_m_final = `ZERO_WORD;
|
||||||
|
case (inst_func_i[`INST_FUNC_WIDTH-1:0] & 32'h00_ffffff)
|
||||||
|
`INST_FUNC_MUL : iresult_m_final = {32{subop_high}} & iresult_mul[63:32]
|
||||||
|
| {32{subop_low }} & iresult_mul[31: 0];
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
reg iresult_m_vld;
|
||||||
|
|
||||||
|
always @ (*) begin
|
||||||
|
iresult_m_vld = `INVALID;
|
||||||
|
case (inst_func_i[`INST_FUNC_WIDTH-1:0] & 32'h00_ffffff)
|
||||||
|
`INST_FUNC_MUL : iresult_m_vld = `VALID;
|
||||||
|
`INST_FUNC_DIV : iresult_m_vld = `VALID;
|
||||||
|
`INST_FUNC_REM : iresult_m_vld = `VALID;
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
assign csr_waddr_vld_o = (op_csrrw || op_csrrs || op_csrrc);
|
||||||
|
|
||||||
|
assign csr_wdata_o[`DATA_BUS_WIDTH-1:0] = {32{op_csrrw}} & iresult_csrw
|
||||||
|
| {32{op_csrrs}} & iresult_csrs
|
||||||
|
| {32{op_csrrc}} & iresult_csrc;
|
||||||
|
|
||||||
|
assign mem_en_o = (op_load || op_store);
|
||||||
|
|
||||||
|
assign hold_flag_o = (op_store || op_load)
|
||||||
|
|| (op_div || op_rem || div_hold);
|
||||||
|
|
||||||
|
assign jump_flag_o = (op_b && bxx_valid)
|
||||||
|
|| (op_jal || op_jalr);
|
||||||
|
|
||||||
|
assign jump_addr_o = {32{op_b && bxx_valid}} & result_pc_bxx
|
||||||
|
| {32{op_jal || op_jalr}} & result_pc_jalx;
|
||||||
|
|
||||||
|
assign reg_waddr_o[`REG_BUS_WIDTH-1:0] = iresult_div_rem_vld ? div_reg_waddr[`REG_BUS_WIDTH-1:0]
|
||||||
|
: reg_waddr_i[`REG_BUS_WIDTH-1:0];
|
||||||
|
|
||||||
|
assign reg_waddr_vld_o = iresult_div_rem_vld ? 1'b1
|
||||||
|
: reg_waddr_vld_i;
|
||||||
|
|
||||||
|
assign iresult_o[`DATA_BUS_WIDTH-1:0] = {32{inst_set_rvi & iresult_i_vld}} & iresult_i_final[`DATA_BUS_WIDTH-1:0]
|
||||||
|
| {32{inst_set_rvm & iresult_m_vld}} & iresult_m_final[`DATA_BUS_WIDTH-1:0]
|
||||||
|
| {32{iresult_div_rem_vld }} & iresult_div_rem[`DATA_BUS_WIDTH-1:0];
|
||||||
|
|
||||||
|
assign iresult_vld_o = inst_set_rvi & iresult_i_vld
|
||||||
|
| inst_set_rvm & iresult_m_vld
|
||||||
|
| iresult_div_rem_vld;
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,193 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021, SERI Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2021-10-29 Lyons first version
|
||||||
|
* 2022-04-04 Lyons v2.0
|
||||||
|
* 2023-06-14 Lyons v3.0, add comments
|
||||||
|
*/
|
||||||
|
|
||||||
|
`ifdef TESTBENCH_VCS
|
||||||
|
`include "pa_chip_param.v"
|
||||||
|
`else
|
||||||
|
`include "../pa_chip_param.v"
|
||||||
|
`endif
|
||||||
|
|
||||||
|
module pa_core_exu_div (
|
||||||
|
input wire clk_i,
|
||||||
|
input wire rst_n_i,
|
||||||
|
|
||||||
|
input wire [`DATA_BUS_WIDTH-1:0] data1_i,
|
||||||
|
input wire [`DATA_BUS_WIDTH-1:0] data2_i,
|
||||||
|
|
||||||
|
input wire [`REG_BUS_WIDTH-1:0] reg_waddr_i,
|
||||||
|
|
||||||
|
input wire op_div_i,
|
||||||
|
input wire op_rem_i,
|
||||||
|
|
||||||
|
input wire q_sign_i,
|
||||||
|
input wire r_sign_i,
|
||||||
|
|
||||||
|
output wire hold_o,
|
||||||
|
|
||||||
|
output wire [`REG_BUS_WIDTH-1:0] reg_waddr_o,
|
||||||
|
|
||||||
|
output wire [31:0] data_o,
|
||||||
|
output wire data_vld_o
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
wire div_start;
|
||||||
|
|
||||||
|
assign div_start = (op_div_i || op_rem_i);
|
||||||
|
|
||||||
|
wire [31:0] data_dividend;
|
||||||
|
pa_dff_rst_0 #(32) dff_data_dividend (clk_i, rst_n_i, div_start, data1_i, data_dividend);
|
||||||
|
|
||||||
|
wire [31:0] data_divisor;
|
||||||
|
pa_dff_rst_0 #(32) dff_data_divisor (clk_i, rst_n_i, div_start, data2_i, data_divisor);
|
||||||
|
|
||||||
|
wire q_sign;
|
||||||
|
pa_dff_rst_0 #(1) dff_q_sign (clk_i, rst_n_i, div_start, q_sign_i, q_sign);
|
||||||
|
|
||||||
|
wire r_sign;
|
||||||
|
pa_dff_rst_0 #(1) dff_r_sign (clk_i, rst_n_i, div_start, r_sign_i, r_sign);
|
||||||
|
|
||||||
|
wire op;
|
||||||
|
pa_dff_rst_0 #(1) dff_op (clk_i, rst_n_i, div_start, op_div_i, op);
|
||||||
|
|
||||||
|
wire [`REG_BUS_WIDTH-1:0] reg_waddr;
|
||||||
|
pa_dff_rst_0 #(`REG_BUS_WIDTH) dff_reg_waddr (clk_i, rst_n_i, div_start, reg_waddr_i, reg_waddr);
|
||||||
|
|
||||||
|
wire [64:0] current_divisor_n; // [-y]
|
||||||
|
wire [64:0] current_divisor_p; // [ y]
|
||||||
|
|
||||||
|
assign current_divisor_n[64:0] = {1'b1, (~data_divisor[31:0] + 32'd1), 32'b0}; // [-y]
|
||||||
|
assign current_divisor_p[64:0] = {1'b0, data_divisor[31:0], 32'b0}; // [ y]
|
||||||
|
|
||||||
|
// 'divide_zero' is valid when 'data_divisor' is equal to zero
|
||||||
|
// 'divide_sel' is valid when 'data_divisor' is greater than 'data_dividend'
|
||||||
|
|
||||||
|
wire divide_zero;
|
||||||
|
wire divide_sel;
|
||||||
|
|
||||||
|
assign divide_zero = ~(|data_divisor[31:0]);
|
||||||
|
|
||||||
|
assign divide_sel = (data_divisor > data_dividend);
|
||||||
|
|
||||||
|
// division process
|
||||||
|
|
||||||
|
reg [5:0] div_cnt;
|
||||||
|
|
||||||
|
always @ (posedge clk_i or negedge rst_n_i) begin
|
||||||
|
if (!rst_n_i) begin
|
||||||
|
div_cnt <= 6'd33;
|
||||||
|
end
|
||||||
|
else if (div_start) begin
|
||||||
|
if (data2_i == 32'd0) begin
|
||||||
|
div_cnt <= 6'd32;
|
||||||
|
end
|
||||||
|
else if (data2_i > data1_i) begin
|
||||||
|
div_cnt <= 6'd32;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
div_cnt <= 6'd0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else if (div_cnt > 6'd32) begin
|
||||||
|
div_cnt <= div_cnt;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
div_cnt <= div_cnt + 6'd1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
wire sm_start;
|
||||||
|
wire sm_running;
|
||||||
|
wire sm_stop;
|
||||||
|
|
||||||
|
assign sm_start = (div_cnt == 6'd0);
|
||||||
|
assign sm_running = (div_cnt >= 6'd0) && (div_cnt <= 6'd32);
|
||||||
|
assign sm_stop = (div_cnt == 6'd32);
|
||||||
|
|
||||||
|
wire [64:0] rst_remainder;
|
||||||
|
|
||||||
|
wire [64:0] current_remainder;
|
||||||
|
reg [64:0] next_remainder;
|
||||||
|
|
||||||
|
always @ (posedge clk_i or negedge rst_n_i) begin
|
||||||
|
if (!rst_n_i) begin
|
||||||
|
next_remainder[64:0] <= 65'b0;
|
||||||
|
end
|
||||||
|
else if (sm_start) begin
|
||||||
|
next_remainder[64:0] <= {33'b0, data_dividend[31:0]};
|
||||||
|
end
|
||||||
|
else if (sm_stop) begin
|
||||||
|
next_remainder[64:0] <= next_remainder[64:0];
|
||||||
|
end
|
||||||
|
else if (sm_running) begin
|
||||||
|
next_remainder[64:0] <= rst_remainder[64:0];
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
next_remainder[64:0] <= 65'b0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assign current_remainder[64:0] = {next_remainder[63:0], 1'b0};
|
||||||
|
|
||||||
|
wire [64:0] rst_remainder_sub;
|
||||||
|
wire [64:0] rst_remainder_add;
|
||||||
|
|
||||||
|
assign rst_remainder_sub[64:0] = current_remainder[64:0]
|
||||||
|
+ current_divisor_n[64:0];
|
||||||
|
|
||||||
|
assign rst_remainder_add[64:0] = current_remainder[64:0]
|
||||||
|
+ current_divisor_p[64:0];
|
||||||
|
|
||||||
|
assign rst_remainder[64:1] = current_remainder[64] ? rst_remainder_add[64:1]
|
||||||
|
: rst_remainder_sub[64:1];
|
||||||
|
|
||||||
|
assign rst_remainder[0] = !rst_remainder[64];
|
||||||
|
|
||||||
|
wire [31:0] rst_qt;
|
||||||
|
wire [31:0] rst_rem;
|
||||||
|
|
||||||
|
assign rst_qt[31:0] = rst_remainder[31:0];
|
||||||
|
|
||||||
|
wire [64:0] rst_remainder_back;
|
||||||
|
|
||||||
|
assign rst_remainder_back[64:0] = rst_remainder[64:0]
|
||||||
|
+ current_divisor_p[64:0];
|
||||||
|
|
||||||
|
assign rst_rem[31:0] = rst_remainder[64] ? rst_remainder_back[63:32]
|
||||||
|
: rst_remainder[63:32];
|
||||||
|
|
||||||
|
wire [31:0] rst_qt_final_t;
|
||||||
|
wire [31:0] rst_rem_final_t;
|
||||||
|
|
||||||
|
assign rst_qt_final_t[31:0] = divide_zero ? 32'hffff_ffff
|
||||||
|
: (divide_sel ? 32'b0 : rst_qt[31:0]);
|
||||||
|
|
||||||
|
assign rst_rem_final_t[31:0] = divide_zero ? data_dividend[31:0]
|
||||||
|
: (divide_sel ? data_dividend[31:0] : rst_rem[31:0]);
|
||||||
|
|
||||||
|
wire [31:0] rst_qt_final;
|
||||||
|
wire [31:0] rst_rem_final;
|
||||||
|
|
||||||
|
assign rst_qt_final[31:0] = q_sign ? (~rst_qt_final_t[31:0] + 32'd1)
|
||||||
|
: rst_qt_final_t[31:0];
|
||||||
|
|
||||||
|
assign rst_rem_final[31:0] = r_sign ? (~rst_rem_final_t[31:0] + 32'd1)
|
||||||
|
: rst_rem_final_t[31:0];
|
||||||
|
|
||||||
|
assign hold_o = sm_running && !sm_stop;
|
||||||
|
|
||||||
|
assign reg_waddr_o[`REG_BUS_WIDTH-1:0] = {5{sm_stop}} & reg_waddr[`REG_BUS_WIDTH-1:0];
|
||||||
|
|
||||||
|
assign data_o[31:0] = {32{sm_stop}} & {op ? rst_qt_final[31:0] : rst_rem_final[31:0]};
|
||||||
|
assign data_vld_o = sm_stop;
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,45 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021, SERI Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2021-10-29 Lyons first version
|
||||||
|
* 2022-04-04 Lyons v2.0
|
||||||
|
* 2023-06-13 Lyons v3.0, add comments
|
||||||
|
*/
|
||||||
|
|
||||||
|
`ifdef TESTBENCH_VCS
|
||||||
|
`include "pa_chip_param.v"
|
||||||
|
`else
|
||||||
|
`include "../pa_chip_param.v"
|
||||||
|
`endif
|
||||||
|
|
||||||
|
module pa_core_exu_mul (
|
||||||
|
input wire [`DATA_BUS_WIDTH-1:0] data1_i,
|
||||||
|
input wire [`DATA_BUS_WIDTH-1:0] data2_i,
|
||||||
|
|
||||||
|
input wire sign_i,
|
||||||
|
|
||||||
|
output wire [63:0] data_o
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
wire [47:0] iresult_final_high;
|
||||||
|
wire [47:0] iresult_final_low;
|
||||||
|
|
||||||
|
// you should using multi ip here
|
||||||
|
|
||||||
|
assign iresult_final_high[47:0] = data1_i[31:0] * {16'b0, data2_i[31:16]};
|
||||||
|
assign iresult_final_low [47:0] = data1_i[31:0] * {16'b0, data2_i[15: 0]};
|
||||||
|
|
||||||
|
wire [63:0] iresult_final;
|
||||||
|
|
||||||
|
assign iresult_final[63:0] = {iresult_final_high[47:0], 16'b0}
|
||||||
|
+ {16'b0, iresult_final_low[47:0]};
|
||||||
|
|
||||||
|
assign data_o[63:0] = sign_i ? (~iresult_final[63:0] + 64'b1)
|
||||||
|
: ( iresult_final[63:0]);
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,411 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021, SERI Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2021-10-29 Lyons first version
|
||||||
|
* 2022-04-04 Lyons v2.0
|
||||||
|
* 2023-06-13 Lyons v3.0, add comments
|
||||||
|
*/
|
||||||
|
|
||||||
|
`ifdef TESTBENCH_VCS
|
||||||
|
`include "pa_chip_param.v"
|
||||||
|
`else
|
||||||
|
`include "../pa_chip_param.v"
|
||||||
|
`endif
|
||||||
|
|
||||||
|
module pa_core_idu (
|
||||||
|
input wire [`DATA_BUS_WIDTH-1:0] inst_data_i,
|
||||||
|
|
||||||
|
output wire [`INST_SET_WIDTH-1:0] inst_set_o,
|
||||||
|
output wire [`INST_TYPE_WIDTH-1:0] inst_type_o,
|
||||||
|
output wire [`INST_FUNC_WIDTH-1:0] inst_func_o,
|
||||||
|
|
||||||
|
output wire [`REG_BUS_WIDTH-1:0] reg1_raddr_o,
|
||||||
|
output wire [`REG_BUS_WIDTH-1:0] reg2_raddr_o,
|
||||||
|
|
||||||
|
output wire [`REG_BUS_WIDTH-1:0] reg_waddr_o,
|
||||||
|
output wire reg_waddr_vld_o,
|
||||||
|
|
||||||
|
output wire [`DATA_BUS_WIDTH-1:0] uimm_o,
|
||||||
|
output wire [`CSR_BUS_WIDTH-1:0] csr_o
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
wire [4:0] inst_rs3;
|
||||||
|
wire [6:0] inst_func7;
|
||||||
|
wire [4:0] inst_rs2;
|
||||||
|
wire [4:0] inst_rs1;
|
||||||
|
wire [2:0] inst_rm;
|
||||||
|
wire [2:0] inst_func3;
|
||||||
|
wire [4:0] inst_rd;
|
||||||
|
wire [6:0] inst_opcode;
|
||||||
|
|
||||||
|
assign inst_rs3[4:0] = inst_data_i[31:27];
|
||||||
|
assign inst_func7[6:0] = inst_data_i[31:25];
|
||||||
|
assign inst_rs2[4:0] = inst_data_i[24:20];
|
||||||
|
assign inst_rs1[4:0] = inst_data_i[19:15];
|
||||||
|
assign inst_rm[2:0] = inst_data_i[14:12];
|
||||||
|
assign inst_func3[2:0] = inst_data_i[14:12];
|
||||||
|
assign inst_rd[4:0] = inst_data_i[11: 7];
|
||||||
|
assign inst_opcode[6:0] = inst_data_i[ 6: 0];
|
||||||
|
|
||||||
|
wire [4:0] inst_uimm5;
|
||||||
|
|
||||||
|
assign inst_uimm5[4:0] = inst_data_i[19:15];
|
||||||
|
|
||||||
|
wire [11:0] inst_uimm12_b_type;
|
||||||
|
wire [11:0] inst_uimm12_i_type;
|
||||||
|
wire [11:0] inst_uimm12_s_type;
|
||||||
|
|
||||||
|
assign inst_uimm12_b_type[11:0] = {inst_data_i[31],
|
||||||
|
inst_data_i[7],
|
||||||
|
inst_data_i[30:25],
|
||||||
|
inst_data_i[11: 8]};
|
||||||
|
|
||||||
|
assign inst_uimm12_i_type[11:0] = {inst_data_i[31:20]};
|
||||||
|
|
||||||
|
assign inst_uimm12_s_type[11:0] = {inst_data_i[31:25],
|
||||||
|
inst_data_i[11: 7]};
|
||||||
|
|
||||||
|
wire [19:0] inst_uimm20_j_type;
|
||||||
|
wire [19:0] inst_uimm20_u_type;
|
||||||
|
|
||||||
|
assign inst_uimm20_j_type[19:0] = {inst_data_i[31],
|
||||||
|
inst_data_i[19:12],
|
||||||
|
inst_data_i[20],
|
||||||
|
inst_data_i[30:21]};
|
||||||
|
|
||||||
|
assign inst_uimm20_u_type[19:0] = {inst_data_i[31:12]};
|
||||||
|
|
||||||
|
wire inst_rs2_all0;
|
||||||
|
wire inst_rs1_all0;
|
||||||
|
wire inst_func3_all0;
|
||||||
|
wire inst_rd_all0;
|
||||||
|
|
||||||
|
assign inst_rs2_all0 = ~(|inst_rs2[4:0]);
|
||||||
|
assign inst_rs1_all0 = ~(|inst_rs1[4:0]);
|
||||||
|
assign inst_func3_all0 = ~(|inst_func3[2:0]);
|
||||||
|
assign inst_rd_all0 = ~(|inst_rd[4:0]);
|
||||||
|
|
||||||
|
wire inst_is_ecall;
|
||||||
|
wire inst_is_ebreak;
|
||||||
|
wire inst_is_mret;
|
||||||
|
wire inst_is_wfi;
|
||||||
|
wire inst_is_csrrx;
|
||||||
|
wire inst_is_csrri;
|
||||||
|
|
||||||
|
assign inst_is_ecall = (inst_data_i[31:20] == 12'h000) && inst_rs1_all0 && inst_func3_all0 && inst_rd_all0;
|
||||||
|
assign inst_is_ebreak = (inst_data_i[31:20] == 12'h001) && inst_rs1_all0 && inst_func3_all0 && inst_rd_all0;
|
||||||
|
assign inst_is_mret = (inst_data_i[31:20] == 12'h302) && inst_rs1_all0 && inst_func3_all0 && inst_rd_all0;
|
||||||
|
assign inst_is_wfi = (inst_data_i[31:20] == 12'h105) && inst_rs1_all0 && inst_func3_all0;
|
||||||
|
assign inst_is_csrrx = (~inst_func3[2]) && (~inst_func3_all0);
|
||||||
|
assign inst_is_csrri = ( inst_func3[2]) && (~inst_func3_all0);
|
||||||
|
|
||||||
|
// analyse, get 'inst_set' and 'inst_type'
|
||||||
|
// modify here when add new inst set or inst
|
||||||
|
|
||||||
|
reg [`INST_SET_WIDTH-1:0] inst_set;
|
||||||
|
reg [`INST_TYPE_WIDTH-1:0] inst_type;
|
||||||
|
|
||||||
|
always @ (*) begin
|
||||||
|
case (inst_opcode[6:0])
|
||||||
|
7'b0000011 , // lb/lh/lw/lbu/lhu
|
||||||
|
7'b1100111 , // jalr
|
||||||
|
7'b0010011 : begin // addi/slli/slti/sltiu/xori/srli/srai/ori/andi
|
||||||
|
inst_set[`INST_SET_WIDTH-1:0] = `INST_SET_RV32I;
|
||||||
|
inst_type[`INST_TYPE_WIDTH-1:0] = `INST_TYPE_I;
|
||||||
|
end
|
||||||
|
|
||||||
|
7'b0010111 , // auipc
|
||||||
|
7'b0110111 : begin // lui
|
||||||
|
inst_set[`INST_SET_WIDTH-1:0] = `INST_SET_RV32I;
|
||||||
|
inst_type[`INST_TYPE_WIDTH-1:0] = `INST_TYPE_U;
|
||||||
|
end
|
||||||
|
|
||||||
|
7'b0100011 : begin // sb/sh/sw
|
||||||
|
inst_set[`INST_SET_WIDTH-1:0] = `INST_SET_RV32I;
|
||||||
|
inst_type[`INST_TYPE_WIDTH-1:0] = `INST_TYPE_S;
|
||||||
|
end
|
||||||
|
|
||||||
|
7'b0110011 : begin // add/sub/sll/slt/sltu/xor/srl/sra/or/and
|
||||||
|
// mul/mulh/mulhsu/mulhu/div/divu/rem/remu
|
||||||
|
inst_set[`INST_SET_WIDTH-1:0] = inst_func7[0] ? `INST_SET_RV32M
|
||||||
|
: `INST_SET_RV32I;
|
||||||
|
inst_type[`INST_TYPE_WIDTH-1:0] = `INST_TYPE_R;
|
||||||
|
end
|
||||||
|
|
||||||
|
7'b1100011 : begin // beq/bne/blt/bge/bltu/bgeu
|
||||||
|
inst_set[`INST_SET_WIDTH-1:0] = `INST_SET_RV32I;
|
||||||
|
inst_type[`INST_TYPE_WIDTH-1:0] = `INST_TYPE_B;
|
||||||
|
end
|
||||||
|
|
||||||
|
7'b1101111 : begin // jal
|
||||||
|
inst_set[`INST_SET_WIDTH-1:0] = `INST_SET_RV32I;
|
||||||
|
inst_type[`INST_TYPE_WIDTH-1:0] = `INST_TYPE_J;
|
||||||
|
end
|
||||||
|
|
||||||
|
7'b1110011 : begin // ecall/ebreak/mret/wfi/csrrw/csrrs/csrrc/csrrwi/csrrsi/csrrci
|
||||||
|
inst_set[`INST_SET_WIDTH-1:0] = `INST_SET_RV32I;
|
||||||
|
inst_type[`INST_TYPE_WIDTH-1:0] = `INST_TYPE_CSR;
|
||||||
|
end
|
||||||
|
|
||||||
|
default : begin
|
||||||
|
inst_set[`INST_SET_WIDTH-1:0] = `INST_SET_NULL;
|
||||||
|
inst_type[`INST_TYPE_WIDTH-1:0] = `INST_TYPE_NULL;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] uimm;
|
||||||
|
reg [`CSR_BUS_WIDTH-1:0] csr;
|
||||||
|
|
||||||
|
always @ (*) begin
|
||||||
|
case (inst_type[6:0])
|
||||||
|
`INST_TYPE_R : begin
|
||||||
|
uimm = `ZERO_WORD;
|
||||||
|
csr = `CSR_NULL;
|
||||||
|
end
|
||||||
|
`INST_TYPE_I : begin
|
||||||
|
uimm = {20'b0, inst_uimm12_i_type[11:0]};
|
||||||
|
csr = `CSR_NULL;
|
||||||
|
end
|
||||||
|
`INST_TYPE_S : begin
|
||||||
|
uimm = {20'b0, inst_uimm12_s_type[11:0]};
|
||||||
|
csr = `CSR_NULL;
|
||||||
|
end
|
||||||
|
`INST_TYPE_B : begin
|
||||||
|
uimm = {20'b0, inst_uimm12_b_type[11:0]};
|
||||||
|
csr = `CSR_NULL;
|
||||||
|
end
|
||||||
|
`INST_TYPE_U : begin
|
||||||
|
uimm = {12'b0, inst_uimm20_u_type[19:0]};
|
||||||
|
csr = `CSR_NULL;
|
||||||
|
end
|
||||||
|
`INST_TYPE_J : begin
|
||||||
|
uimm = {12'b0, inst_uimm20_j_type[19:0]};
|
||||||
|
csr = `CSR_NULL;
|
||||||
|
end
|
||||||
|
`INST_TYPE_CSR : begin
|
||||||
|
uimm = inst_is_csrri ? {27'b0, inst_uimm5[4:0]} : `ZERO_WORD;
|
||||||
|
csr = {inst_func7[6:0], inst_rs2[4:0]};
|
||||||
|
end
|
||||||
|
default : begin
|
||||||
|
uimm = `ZERO_WORD;
|
||||||
|
csr = `CSR_NULL;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
// analyse, get 'inst_set' and 'inst_func'
|
||||||
|
// modify here when add new inst set or inst
|
||||||
|
|
||||||
|
reg [`INST_FUNC_WIDTH-1:0] inst_func;
|
||||||
|
|
||||||
|
always @ (*) begin
|
||||||
|
inst_func = `INST_FUNC_NULL;
|
||||||
|
case (inst_opcode[6:0])
|
||||||
|
7'b0000011 : begin
|
||||||
|
case (inst_func3[2:0])
|
||||||
|
`INST_LB : inst_func = `INST_FUNC_LOAD | `INST_FUNC_SUFFIX_IMM | `INST_FUNC_SUFFIX_BYTE;
|
||||||
|
`INST_LH : inst_func = `INST_FUNC_LOAD | `INST_FUNC_SUFFIX_IMM | `INST_FUNC_SUFFIX_HALF;
|
||||||
|
`INST_LW : inst_func = `INST_FUNC_LOAD | `INST_FUNC_SUFFIX_IMM;
|
||||||
|
`INST_LBU : inst_func = `INST_FUNC_LOAD | `INST_FUNC_SUFFIX_IMM | `INST_FUNC_SUFFIX_BYTE | `INST_FUNC_SUFFIX_UNSIGN;
|
||||||
|
`INST_LHU : inst_func = `INST_FUNC_LOAD | `INST_FUNC_SUFFIX_IMM | `INST_FUNC_SUFFIX_HALF | `INST_FUNC_SUFFIX_UNSIGN;
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
7'b0010011 : begin
|
||||||
|
case (inst_func3[2:0])
|
||||||
|
`INST_ADD : inst_func = `INST_FUNC_ADD | `INST_FUNC_SUFFIX_IMM;
|
||||||
|
`INST_SLL : inst_func = `INST_FUNC_SLL | `INST_FUNC_SUFFIX_IMM;
|
||||||
|
`INST_SLT : inst_func = `INST_FUNC_SLT | `INST_FUNC_SUFFIX_IMM;
|
||||||
|
`INST_SLTU : inst_func = `INST_FUNC_SLT | `INST_FUNC_SUFFIX_IMM | `INST_FUNC_SUFFIX_UNSIGN;
|
||||||
|
`INST_XOR : inst_func = `INST_FUNC_XOR | `INST_FUNC_SUFFIX_IMM;
|
||||||
|
`INST_SRL : inst_func = (inst_func7[5] ? `INST_FUNC_SRA : `INST_FUNC_SRL) | `INST_FUNC_SUFFIX_IMM;
|
||||||
|
`INST_OR : inst_func = `INST_FUNC_OR | `INST_FUNC_SUFFIX_IMM;
|
||||||
|
`INST_AND : inst_func = `INST_FUNC_AND | `INST_FUNC_SUFFIX_IMM;
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
7'b0010111 : begin
|
||||||
|
inst_func = `INST_FUNC_AUIPC;
|
||||||
|
end
|
||||||
|
|
||||||
|
7'b0100011 : begin
|
||||||
|
case (inst_func3[2:0])
|
||||||
|
`INST_SB : inst_func = `INST_FUNC_STORE | `INST_FUNC_SUFFIX_IMM | `INST_FUNC_SUFFIX_BYTE;
|
||||||
|
`INST_SH : inst_func = `INST_FUNC_STORE | `INST_FUNC_SUFFIX_IMM | `INST_FUNC_SUFFIX_HALF;
|
||||||
|
`INST_SW : inst_func = `INST_FUNC_STORE | `INST_FUNC_SUFFIX_IMM;
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
7'b0110011 : begin
|
||||||
|
if (inst_func7[0]) begin
|
||||||
|
case (inst_func3[2:0])
|
||||||
|
`INST_MUL : inst_func = `INST_FUNC_MUL;
|
||||||
|
`INST_MULH : inst_func = `INST_FUNC_MUL | `INST_FUNC_SUFFIX_HIGH;
|
||||||
|
`INST_MULHSU : inst_func = `INST_FUNC_MUL | `INST_FUNC_SUFFIX_U2 | `INST_FUNC_SUFFIX_HIGH;
|
||||||
|
`INST_MULHU : inst_func = `INST_FUNC_MUL | `INST_FUNC_SUFFIX_U1 | `INST_FUNC_SUFFIX_U2 | `INST_FUNC_SUFFIX_HIGH;
|
||||||
|
`INST_DIV : inst_func = `INST_FUNC_DIV;
|
||||||
|
`INST_DIVU : inst_func = `INST_FUNC_DIV | `INST_FUNC_SUFFIX_U1 | `INST_FUNC_SUFFIX_U2;
|
||||||
|
`INST_REM : inst_func = `INST_FUNC_REM;
|
||||||
|
`INST_REMU : inst_func = `INST_FUNC_REM | `INST_FUNC_SUFFIX_U1 | `INST_FUNC_SUFFIX_U2;
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
case (inst_func3[2:0])
|
||||||
|
`INST_ADD : inst_func = (inst_func7[5] ? `INST_FUNC_SUB : `INST_FUNC_ADD);
|
||||||
|
`INST_SLL : inst_func = `INST_FUNC_SLL;
|
||||||
|
`INST_SLT : inst_func = `INST_FUNC_SLT;
|
||||||
|
`INST_SLTU : inst_func = `INST_FUNC_SLT | `INST_FUNC_SUFFIX_UNSIGN;
|
||||||
|
`INST_XOR : inst_func = `INST_FUNC_XOR;
|
||||||
|
`INST_SRL : inst_func = (inst_func7[5] ? `INST_FUNC_SRA : `INST_FUNC_SRL);
|
||||||
|
`INST_OR : inst_func = `INST_FUNC_OR;
|
||||||
|
`INST_AND : inst_func = `INST_FUNC_AND;
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
7'b0110111 : begin
|
||||||
|
inst_func = `INST_FUNC_LUI | `INST_FUNC_SUFFIX_IMM;
|
||||||
|
end
|
||||||
|
|
||||||
|
7'b1100011 : begin
|
||||||
|
case (inst_func3[2:0])
|
||||||
|
`INST_BEQ : inst_func = `INST_FUNC_B | `INST_FUNC_SUFFIX_EQ;
|
||||||
|
`INST_BNE : inst_func = `INST_FUNC_B | `INST_FUNC_SUFFIX_NE;
|
||||||
|
`INST_BLT : inst_func = `INST_FUNC_B | `INST_FUNC_SUFFIX_LT;
|
||||||
|
`INST_BGE : inst_func = `INST_FUNC_B | `INST_FUNC_SUFFIX_GT | `INST_FUNC_SUFFIX_EQ;
|
||||||
|
`INST_BLTU : inst_func = `INST_FUNC_B | `INST_FUNC_SUFFIX_LT | `INST_FUNC_SUFFIX_UNSIGN;
|
||||||
|
`INST_BGEU : inst_func = `INST_FUNC_B | `INST_FUNC_SUFFIX_GT | `INST_FUNC_SUFFIX_EQ | `INST_FUNC_SUFFIX_UNSIGN;
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
7'b1101111 : begin
|
||||||
|
inst_func = `INST_FUNC_JAL;
|
||||||
|
end
|
||||||
|
|
||||||
|
7'b1100111 : begin
|
||||||
|
inst_func = `INST_FUNC_JALR;
|
||||||
|
end
|
||||||
|
|
||||||
|
7'b1110011 : begin
|
||||||
|
case (inst_func3[2:0])
|
||||||
|
`INST_ECALL : begin
|
||||||
|
case ({inst_is_ecall, inst_is_ebreak, inst_is_mret, inst_is_wfi})
|
||||||
|
4'b1000 : inst_func = `INST_FUNC_ECALL;
|
||||||
|
4'b0100 : inst_func = `INST_FUNC_EBREAK;
|
||||||
|
4'b0010 : inst_func = `INST_FUNC_MRET;
|
||||||
|
4'b0001 : inst_func = `INST_FUNC_WFI;
|
||||||
|
default : inst_func = `INST_FUNC_NULL;
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
`INST_CSRRW : inst_func = `INST_FUNC_CSRRW;
|
||||||
|
`INST_CSRRS : inst_func = `INST_FUNC_CSRRS;
|
||||||
|
`INST_CSRRC : inst_func = `INST_FUNC_CSRRC;
|
||||||
|
`INST_CSRRWI : inst_func = `INST_FUNC_CSRRW | `INST_FUNC_SUFFIX_IMM;
|
||||||
|
`INST_CSRRSI : inst_func = `INST_FUNC_CSRRS | `INST_FUNC_SUFFIX_IMM;
|
||||||
|
`INST_CSRRCI : inst_func = `INST_FUNC_CSRRC | `INST_FUNC_SUFFIX_IMM;
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
reg reg_raddr1_vld;
|
||||||
|
reg reg_raddr2_vld;
|
||||||
|
reg reg_waddr_vld;
|
||||||
|
reg imm_vld;
|
||||||
|
reg csr_vld;
|
||||||
|
|
||||||
|
always @ (*) begin
|
||||||
|
case (inst_type[6:0])
|
||||||
|
`INST_TYPE_R : begin
|
||||||
|
reg_raddr1_vld = `VALID;
|
||||||
|
reg_raddr2_vld = `VALID;
|
||||||
|
case (inst_set[`INST_SET_WIDTH-1:0])
|
||||||
|
`INST_SET_RV32I ,
|
||||||
|
`INST_SET_RV32M : begin
|
||||||
|
reg_waddr_vld = `VALID;
|
||||||
|
end
|
||||||
|
`INST_SET_RV32FD : begin
|
||||||
|
reg_waddr_vld = `INVALID;
|
||||||
|
end
|
||||||
|
default : begin
|
||||||
|
reg_waddr_vld = `INVALID;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
imm_vld = `INVALID;
|
||||||
|
csr_vld = `INVALID;
|
||||||
|
end
|
||||||
|
`INST_TYPE_I : begin
|
||||||
|
reg_raddr1_vld = `VALID;
|
||||||
|
reg_raddr2_vld = `INVALID;
|
||||||
|
reg_waddr_vld = `VALID;
|
||||||
|
imm_vld = `VALID;
|
||||||
|
csr_vld = `INVALID;
|
||||||
|
end
|
||||||
|
`INST_TYPE_S : begin
|
||||||
|
reg_raddr1_vld = `VALID;
|
||||||
|
reg_raddr2_vld = `VALID;
|
||||||
|
reg_waddr_vld = `INVALID;
|
||||||
|
imm_vld = `VALID;
|
||||||
|
csr_vld = `INVALID;
|
||||||
|
end
|
||||||
|
`INST_TYPE_B : begin
|
||||||
|
reg_raddr1_vld = `VALID;
|
||||||
|
reg_raddr2_vld = `VALID;
|
||||||
|
reg_waddr_vld = `INVALID;
|
||||||
|
imm_vld = `VALID;
|
||||||
|
csr_vld = `INVALID;
|
||||||
|
end
|
||||||
|
`INST_TYPE_U : begin
|
||||||
|
reg_raddr1_vld = `INVALID;
|
||||||
|
reg_raddr2_vld = `INVALID;
|
||||||
|
reg_waddr_vld = `VALID;
|
||||||
|
imm_vld = `VALID;
|
||||||
|
csr_vld = `INVALID;
|
||||||
|
end
|
||||||
|
`INST_TYPE_J : begin
|
||||||
|
reg_raddr1_vld = `INVALID;
|
||||||
|
reg_raddr2_vld = `INVALID;
|
||||||
|
reg_waddr_vld = `VALID;
|
||||||
|
imm_vld = `VALID;
|
||||||
|
csr_vld = `INVALID;
|
||||||
|
end
|
||||||
|
`INST_TYPE_CSR : begin
|
||||||
|
reg_raddr1_vld = inst_is_csrrx ? `VALID : `INVALID;
|
||||||
|
reg_raddr2_vld = `INVALID;
|
||||||
|
reg_waddr_vld = `VALID;
|
||||||
|
imm_vld = inst_is_csrri ? `VALID : `INVALID;
|
||||||
|
csr_vld = `VALID;
|
||||||
|
end
|
||||||
|
default : begin
|
||||||
|
reg_raddr1_vld = `INVALID;
|
||||||
|
reg_raddr2_vld = `INVALID;
|
||||||
|
reg_waddr_vld = `INVALID;
|
||||||
|
imm_vld = `INVALID;
|
||||||
|
csr_vld = `INVALID;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
assign inst_set_o[`INST_SET_WIDTH-1:0] = inst_set[`INST_SET_WIDTH-1:0];
|
||||||
|
assign inst_type_o[`INST_TYPE_WIDTH-1:0] = inst_type[`INST_TYPE_WIDTH-1:0];
|
||||||
|
assign inst_func_o[`INST_FUNC_WIDTH-1:0] = inst_func[`INST_FUNC_WIDTH-1:0];
|
||||||
|
|
||||||
|
// data keep zero while field is invalid
|
||||||
|
|
||||||
|
assign reg1_raddr_o[`REG_BUS_WIDTH-1:0] = {{`REG_BUS_WIDTH}{reg_raddr1_vld}} & inst_rs1[`REG_BUS_WIDTH-1:0];
|
||||||
|
assign reg2_raddr_o[`REG_BUS_WIDTH-1:0] = {{`REG_BUS_WIDTH}{reg_raddr2_vld}} & inst_rs2[`REG_BUS_WIDTH-1:0];
|
||||||
|
|
||||||
|
assign reg_waddr_o[`REG_BUS_WIDTH-1:0] = {{`REG_BUS_WIDTH}{reg_waddr_vld}} & inst_rd[`REG_BUS_WIDTH-1:0];
|
||||||
|
assign reg_waddr_vld_o = reg_waddr_vld;
|
||||||
|
|
||||||
|
assign uimm_o[`DATA_BUS_WIDTH-1:0] = {{`DATA_BUS_WIDTH}{imm_vld}} & uimm[`DATA_BUS_WIDTH-1:0];
|
||||||
|
assign csr_o[`CSR_BUS_WIDTH-1:0] = {{`CSR_BUS_WIDTH }{csr_vld}} & csr[`CSR_BUS_WIDTH-1:0];
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,122 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021, SERI Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2021-10-29 Lyons first version
|
||||||
|
* 2022-04-04 Lyons v2.0
|
||||||
|
* 2023-06-13 Lyons v3.0, add comments
|
||||||
|
*/
|
||||||
|
|
||||||
|
`ifdef TESTBENCH_VCS
|
||||||
|
`include "pa_chip_param.v"
|
||||||
|
`else
|
||||||
|
`include "../pa_chip_param.v"
|
||||||
|
`endif
|
||||||
|
|
||||||
|
module pa_core_mau (
|
||||||
|
input wire [4:0] inst_func_i, // indicate instruction func, [31,29:28,op_load,op_store]
|
||||||
|
|
||||||
|
input wire [1:0] mem_addr_i,
|
||||||
|
|
||||||
|
input wire [`DATA_BUS_WIDTH-1:0] mem_data_i,
|
||||||
|
input wire mem_data_vld_i,
|
||||||
|
|
||||||
|
output wire [`DATA_BUS_WIDTH-1:0] mem_data_o,
|
||||||
|
output wire mem_data_vld_o,
|
||||||
|
|
||||||
|
input wire [`DATA_BUS_WIDTH-1:0] rbm_data_i,
|
||||||
|
|
||||||
|
output wire [`DATA_BUS_WIDTH-1:0] rbm_data_o,
|
||||||
|
output wire [2:0] rbm_size_o
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
wire subop_sign;
|
||||||
|
|
||||||
|
wire subop_byte;
|
||||||
|
wire subop_half;
|
||||||
|
wire subop_word;
|
||||||
|
|
||||||
|
assign subop_sign = ~inst_func_i[4]; // to inst_func_i[31]
|
||||||
|
|
||||||
|
assign subop_byte = (inst_func_i[3:2] == 2'b01); // to inst_func_i[29:28]
|
||||||
|
assign subop_half = (inst_func_i[3:2] == 2'b10); // to inst_func_i[29:28]
|
||||||
|
assign subop_word = (inst_func_i[3:2] == 2'b00); // to inst_func_i[29:28]
|
||||||
|
|
||||||
|
wire op_load;
|
||||||
|
wire op_store;
|
||||||
|
|
||||||
|
assign op_load = inst_func_i[1]; // to inst_func_i[14]
|
||||||
|
assign op_store = inst_func_i[0]; // to inst_func_i[13]
|
||||||
|
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] mem_data;
|
||||||
|
|
||||||
|
// 'mem_data' is equal to zero when it is Non-memory-access inst
|
||||||
|
|
||||||
|
assign mem_data = {32{op_load }} & rbm_data_i
|
||||||
|
| {32{op_store}} & mem_data_i;
|
||||||
|
|
||||||
|
// memory byte access: lb/sb
|
||||||
|
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] mem_data_b0;
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] mem_data_b1;
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] mem_data_b2;
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] mem_data_b3;
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] mem_data_b;
|
||||||
|
|
||||||
|
assign mem_data_b0 = op_load ? {24'b0 | {24{subop_sign && mem_data[ 7]}}, mem_data[ 7: 0]}
|
||||||
|
: {mem_data[31:0]};
|
||||||
|
assign mem_data_b1 = op_load ? {24'b0 | {24{subop_sign && mem_data[15]}}, mem_data[15: 8]}
|
||||||
|
: {mem_data[23:0], 8'b0 };
|
||||||
|
assign mem_data_b2 = op_load ? {24'b0 | {24{subop_sign && mem_data[23]}}, mem_data[23:16]}
|
||||||
|
: {mem_data[15:0], 16'b0};
|
||||||
|
assign mem_data_b3 = op_load ? {24'b0 | {24{subop_sign && mem_data[31]}}, mem_data[31:24]}
|
||||||
|
: {mem_data[ 7:0], 24'b0};
|
||||||
|
|
||||||
|
assign mem_data_b = {32{mem_addr_i[1:0] == 2'b00}} & mem_data_b0
|
||||||
|
| {32{mem_addr_i[1:0] == 2'b01}} & mem_data_b1
|
||||||
|
| {32{mem_addr_i[1:0] == 2'b10}} & mem_data_b2
|
||||||
|
| {32{mem_addr_i[1:0] == 2'b11}} & mem_data_b3;
|
||||||
|
|
||||||
|
// memory half-word access: lh/sh
|
||||||
|
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] mem_data_h0;
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] mem_data_h1;
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] mem_data_h;
|
||||||
|
|
||||||
|
assign mem_data_h0 = op_load ? {16'b0 | {16{subop_sign && mem_data[15]}}, mem_data[15: 0]}
|
||||||
|
: {mem_data[31:0]};
|
||||||
|
assign mem_data_h1 = op_load ? {16'b0 | {16{subop_sign && mem_data[31]}}, mem_data[31:16]}
|
||||||
|
: {mem_data[15:0], 16'b0};
|
||||||
|
|
||||||
|
assign mem_data_h = {32{mem_addr_i[1] == 1'b0}} & mem_data_h0
|
||||||
|
| {32{mem_addr_i[1] == 1'b1}} & mem_data_h1;
|
||||||
|
|
||||||
|
// memory word access: lw/sw
|
||||||
|
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] mem_data_w;
|
||||||
|
|
||||||
|
assign mem_data_w = {mem_data[31:0]};
|
||||||
|
|
||||||
|
// 'mem_wdata' is equal to zero when it is Non-load inst
|
||||||
|
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] mem_wdata/* synthesis syn_keep=1 */;
|
||||||
|
|
||||||
|
assign mem_wdata = {32{subop_byte}} & mem_data_b
|
||||||
|
| {32{subop_half}} & mem_data_h
|
||||||
|
| {32{subop_word}} & mem_data_w;
|
||||||
|
|
||||||
|
// to exec unit, process data
|
||||||
|
|
||||||
|
assign mem_data_o[`DATA_BUS_WIDTH-1:0] = mem_wdata[`DATA_BUS_WIDTH-1:0];
|
||||||
|
assign mem_data_vld_o = op_load;
|
||||||
|
|
||||||
|
// to bus, store data
|
||||||
|
|
||||||
|
assign rbm_data_o[`DATA_BUS_WIDTH-1:0] = mem_wdata[`DATA_BUS_WIDTH-1:0];
|
||||||
|
assign rbm_size_o = {subop_word, subop_half, subop_byte};
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,61 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021, SERI Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2021-10-29 Lyons first version
|
||||||
|
* 2022-04-04 Lyons v2.0
|
||||||
|
* 2023-06-13 Lyons v3.0, add comments
|
||||||
|
*/
|
||||||
|
|
||||||
|
`ifdef TESTBENCH_VCS
|
||||||
|
`include "pa_chip_param.v"
|
||||||
|
`else
|
||||||
|
`include "../pa_chip_param.v"
|
||||||
|
`endif
|
||||||
|
|
||||||
|
module pa_core_pcgen (
|
||||||
|
input wire clk_i,
|
||||||
|
input wire rst_n_i,
|
||||||
|
|
||||||
|
input wire reset_flag_i,
|
||||||
|
|
||||||
|
input wire hold_flag_i,
|
||||||
|
|
||||||
|
input wire jump_flag_i,
|
||||||
|
input wire [`DATA_BUS_WIDTH-1:0] jump_addr_i,
|
||||||
|
|
||||||
|
output wire [`DATA_BUS_WIDTH-1:0] pc_o
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] _pc;
|
||||||
|
|
||||||
|
always @ (posedge clk_i or negedge rst_n_i) begin
|
||||||
|
if (!rst_n_i) begin
|
||||||
|
// hardware power-on reset
|
||||||
|
_pc[`DATA_BUS_WIDTH-1:0] <= `RESET_PC_ADDR;
|
||||||
|
end
|
||||||
|
else if (reset_flag_i) begin
|
||||||
|
// software reset
|
||||||
|
_pc[`DATA_BUS_WIDTH-1:0] <= `RESET_PC_ADDR;
|
||||||
|
end
|
||||||
|
else if (jump_flag_i) begin
|
||||||
|
// jump
|
||||||
|
_pc[`DATA_BUS_WIDTH-1:0] <= jump_addr_i[`DATA_BUS_WIDTH-1:0];
|
||||||
|
end
|
||||||
|
else if (hold_flag_i) begin
|
||||||
|
// cpu stall & hold
|
||||||
|
_pc[`DATA_BUS_WIDTH-1:0] <= _pc[`DATA_BUS_WIDTH-1:0];
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
// only support 32-bits instruction
|
||||||
|
_pc[`DATA_BUS_WIDTH-1:0] <= _pc[`DATA_BUS_WIDTH-1:0] + 32'h4;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assign pc_o[`DATA_BUS_WIDTH-1:0] = _pc[`DATA_BUS_WIDTH-1:0];
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,81 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021, SERI Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2021-10-29 Lyons first version
|
||||||
|
* 2022-04-04 Lyons v2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
`ifdef TESTBENCH_VCS
|
||||||
|
`include "pa_chip_param.v"
|
||||||
|
`else
|
||||||
|
`include "../pa_chip_param.v"
|
||||||
|
`endif
|
||||||
|
|
||||||
|
module pa_core_rtu (
|
||||||
|
input wire clk_i,
|
||||||
|
input wire rst_n_i,
|
||||||
|
|
||||||
|
input wire [`REG_BUS_WIDTH-1:0] reg1_raddr_i,
|
||||||
|
input wire [`REG_BUS_WIDTH-1:0] reg2_raddr_i,
|
||||||
|
|
||||||
|
input wire [`REG_BUS_WIDTH-1:0] reg_waddr_i,
|
||||||
|
input wire reg_waddr_vld_i,
|
||||||
|
|
||||||
|
input wire [`DATA_BUS_WIDTH-1:0] reg_wdata_i,
|
||||||
|
|
||||||
|
output wire [`DATA_BUS_WIDTH-1:0] reg1_rdata_o,
|
||||||
|
output wire [`DATA_BUS_WIDTH-1:0] reg2_rdata_o,
|
||||||
|
|
||||||
|
output wire [`DATA_BUS_WIDTH-1:0] csr_mtvec_o,
|
||||||
|
output wire [`DATA_BUS_WIDTH-1:0] csr_mepc_o,
|
||||||
|
output wire [`DATA_BUS_WIDTH-1:0] csr_mstatus_o,
|
||||||
|
|
||||||
|
input wire [`CSR_BUS_WIDTH-1:0] csr_raddr_i,
|
||||||
|
|
||||||
|
input wire [`CSR_BUS_WIDTH-1:0] csr_waddr_i,
|
||||||
|
input wire csr_waddr_vld_i,
|
||||||
|
|
||||||
|
input wire [`DATA_BUS_WIDTH-1:0] csr_wdata_i,
|
||||||
|
|
||||||
|
output wire [`DATA_BUS_WIDTH-1:0] csr_rdata_o
|
||||||
|
);
|
||||||
|
|
||||||
|
pa_core_csr u_pa_core_csr (
|
||||||
|
.clk_i (clk_i),
|
||||||
|
.rst_n_i (rst_n_i),
|
||||||
|
|
||||||
|
.csr_mtvec_o (csr_mtvec_o),
|
||||||
|
.csr_mepc_o (csr_mepc_o),
|
||||||
|
.csr_mstatus_o (csr_mstatus_o),
|
||||||
|
|
||||||
|
.csr_raddr_i (csr_raddr_i),
|
||||||
|
|
||||||
|
.csr_waddr_i (csr_waddr_i),
|
||||||
|
.csr_waddr_vld_i (csr_waddr_vld_i),
|
||||||
|
|
||||||
|
.csr_wdata_i (csr_wdata_i),
|
||||||
|
|
||||||
|
.csr_rdata_o (csr_rdata_o)
|
||||||
|
);
|
||||||
|
|
||||||
|
pa_core_xreg u_pa_core_xreg (
|
||||||
|
.clk_i (clk_i),
|
||||||
|
.rst_n_i (rst_n_i),
|
||||||
|
|
||||||
|
.reg1_raddr_i (reg1_raddr_i),
|
||||||
|
.reg2_raddr_i (reg2_raddr_i),
|
||||||
|
|
||||||
|
.reg_waddr_i (reg_waddr_i),
|
||||||
|
.reg_waddr_vld_i (reg_waddr_vld_i),
|
||||||
|
|
||||||
|
.reg_wdata_i (reg_wdata_i),
|
||||||
|
|
||||||
|
.reg1_rdata_o (reg1_rdata_o),
|
||||||
|
.reg2_rdata_o (reg2_rdata_o)
|
||||||
|
);
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,417 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021, SERI Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2021-10-29 Lyons first version
|
||||||
|
* 2022-04-04 Lyons v2.0
|
||||||
|
* 2023-06-10 Lyons v3.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
`ifdef TESTBENCH_VCS
|
||||||
|
`include "pa_chip_param.v"
|
||||||
|
`else
|
||||||
|
`include "../pa_chip_param.v"
|
||||||
|
`endif
|
||||||
|
|
||||||
|
module pa_core_top (
|
||||||
|
input wire clk_i,
|
||||||
|
input wire rst_n_i,
|
||||||
|
|
||||||
|
input wire irq_i,
|
||||||
|
|
||||||
|
output wire [`ADDR_BUS_WIDTH-1:0] ibus_addr_o,
|
||||||
|
input wire [`DATA_BUS_WIDTH-1:0] ibus_data_i,
|
||||||
|
|
||||||
|
output wire [`ADDR_BUS_WIDTH-1:0] dbus_addr_o,
|
||||||
|
output dbus_rd_o,
|
||||||
|
output dbus_we_o,
|
||||||
|
output wire [2:0] dbus_size_o,
|
||||||
|
output wire [`DATA_BUS_WIDTH-1:0] dbus_data_o,
|
||||||
|
input wire [`DATA_BUS_WIDTH-1:0] dbus_data_i
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
wire exu_hold_flag;
|
||||||
|
wire int_hold_flag;
|
||||||
|
|
||||||
|
wire hold_flag;
|
||||||
|
|
||||||
|
wire jump_flag;
|
||||||
|
wire [`ADDR_BUS_WIDTH-1:0] jump_addr;
|
||||||
|
|
||||||
|
wire idu_flush_flag;
|
||||||
|
wire exu_flush_flag;
|
||||||
|
|
||||||
|
|
||||||
|
wire hold_flag_1r;
|
||||||
|
pa_dff_rst_0 #(1) dff_hold_flag_1r (clk_i, rst_n_i, `VALID, hold_flag, hold_flag_1r);
|
||||||
|
|
||||||
|
wire jump_flag_1r;
|
||||||
|
pa_dff_rst_0 #(1) dff_jump_flag_1r (clk_i, rst_n_i, `VALID, jump_flag, jump_flag_1r);
|
||||||
|
|
||||||
|
// inst address generated from pcgen module
|
||||||
|
// inst data fetched after one clock
|
||||||
|
|
||||||
|
wire [`ADDR_BUS_WIDTH-1:0] inst_addr;
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] inst_data;
|
||||||
|
|
||||||
|
pa_core_pcgen u_pa_core_pcgen (
|
||||||
|
.clk_i (clk_i),
|
||||||
|
.rst_n_i (rst_n_i),
|
||||||
|
|
||||||
|
.reset_flag_i (`INVALID),
|
||||||
|
|
||||||
|
.hold_flag_i (hold_flag),
|
||||||
|
|
||||||
|
.jump_flag_i (jump_flag),
|
||||||
|
.jump_addr_i (jump_addr),
|
||||||
|
|
||||||
|
.pc_o (inst_addr)
|
||||||
|
);
|
||||||
|
|
||||||
|
// "ifu_inst_addr" work under IF state
|
||||||
|
|
||||||
|
wire [`ADDR_BUS_WIDTH-1:0] ifu_inst_addr;
|
||||||
|
|
||||||
|
assign ifu_inst_addr[`ADDR_BUS_WIDTH-1:0] = inst_addr[`ADDR_BUS_WIDTH-1:0];
|
||||||
|
|
||||||
|
// inst data fetched from tcm module by bus
|
||||||
|
|
||||||
|
assign ibus_addr_o[`ADDR_BUS_WIDTH-1:0] = ifu_inst_addr[`ADDR_BUS_WIDTH-1:0];
|
||||||
|
assign inst_data[`DATA_BUS_WIDTH-1:0] = ibus_data_i[`DATA_BUS_WIDTH-1:0];
|
||||||
|
|
||||||
|
// "idu_inst_data" work under ID state
|
||||||
|
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] idu_inst_data;
|
||||||
|
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] inst_data_1r;
|
||||||
|
pa_dff_en_2 #(`DATA_BUS_WIDTH) dff_inst_data_1r (clk_i, rst_n_i, idu_flush_flag, {`DATA_BUS_WIDTH{1'b0}}, idu_inst_data, inst_data_1r);
|
||||||
|
|
||||||
|
assign idu_inst_data[`DATA_BUS_WIDTH-1:0] = hold_flag_1r ? inst_data_1r[`DATA_BUS_WIDTH-1:0]
|
||||||
|
: inst_data[`DATA_BUS_WIDTH-1:0];
|
||||||
|
|
||||||
|
wire [`INST_SET_WIDTH-1:0] inst_set;
|
||||||
|
wire [`INST_TYPE_WIDTH-1:0] inst_type;
|
||||||
|
wire [`INST_FUNC_WIDTH-1:0] inst_func;
|
||||||
|
|
||||||
|
wire [`REG_BUS_WIDTH-1:0] reg1_raddr;
|
||||||
|
wire [`REG_BUS_WIDTH-1:0] reg2_raddr;
|
||||||
|
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] reg1_rdata;
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] reg2_rdata;
|
||||||
|
|
||||||
|
wire [`REG_BUS_WIDTH-1:0] reg_waddr;
|
||||||
|
wire reg_waddr_vld;
|
||||||
|
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] uimm_data;
|
||||||
|
|
||||||
|
wire [`CSR_BUS_WIDTH-1:0] csr_addr;
|
||||||
|
|
||||||
|
// ifu module only include comb logic, no timing logic
|
||||||
|
|
||||||
|
pa_core_idu u_pa_core_idu (
|
||||||
|
.inst_data_i (idu_inst_data),
|
||||||
|
|
||||||
|
.inst_set_o (inst_set),
|
||||||
|
.inst_type_o (inst_type),
|
||||||
|
.inst_func_o (inst_func),
|
||||||
|
|
||||||
|
.reg1_raddr_o (reg1_raddr),
|
||||||
|
.reg2_raddr_o (reg2_raddr),
|
||||||
|
|
||||||
|
.reg_waddr_o (reg_waddr),
|
||||||
|
.reg_waddr_vld_o (reg_waddr_vld),
|
||||||
|
|
||||||
|
.uimm_o (uimm_data),
|
||||||
|
.csr_o (csr_addr)
|
||||||
|
);
|
||||||
|
|
||||||
|
wire [`INST_SET_WIDTH-1:0] exu_inst_set;
|
||||||
|
pa_dff_en_2 #(`INST_SET_WIDTH) dff_exu_inst_set (clk_i, rst_n_i, exu_flush_flag, {`INST_SET_WIDTH{1'b0}}, inst_set, exu_inst_set);
|
||||||
|
|
||||||
|
wire [`INST_FUNC_WIDTH-1:0] exu_inst_func;
|
||||||
|
pa_dff_en_2 #(`INST_FUNC_WIDTH) dff_exu_inst_func (clk_i, rst_n_i, exu_flush_flag, {`INST_FUNC_WIDTH{1'b0}}, inst_func, exu_inst_func);
|
||||||
|
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] exu_reg1_rdata;
|
||||||
|
pa_dff_en_2 #(`DATA_BUS_WIDTH) dff_exu_reg1_rdata (clk_i, rst_n_i, exu_flush_flag, {`DATA_BUS_WIDTH{1'b0}}, reg1_rdata, exu_reg1_rdata);
|
||||||
|
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] exu_reg2_rdata;
|
||||||
|
pa_dff_en_2 #(`DATA_BUS_WIDTH) dff_exu_reg2_rdata (clk_i, rst_n_i, exu_flush_flag, {`DATA_BUS_WIDTH{1'b0}}, reg2_rdata, exu_reg2_rdata);
|
||||||
|
|
||||||
|
wire [`REG_BUS_WIDTH-1:0] exu_reg_waddr;
|
||||||
|
pa_dff_en_2 #(`REG_BUS_WIDTH) dff_exu_reg_waddr (clk_i, rst_n_i, exu_flush_flag, {`REG_BUS_WIDTH{1'b0}}, reg_waddr, exu_reg_waddr);
|
||||||
|
|
||||||
|
wire exu_reg_waddr_vld;
|
||||||
|
pa_dff_en_2 #(1) dff_exu_reg_waddr_vld (clk_i, rst_n_i, exu_flush_flag, 1'b0, reg_waddr_vld, exu_reg_waddr_vld);
|
||||||
|
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] exu_uimm_data;
|
||||||
|
pa_dff_en_2 #(`DATA_BUS_WIDTH) dff_exu_uimm_data (clk_i, rst_n_i, exu_flush_flag, {`DATA_BUS_WIDTH{1'b0}}, uimm_data, exu_uimm_data);
|
||||||
|
|
||||||
|
wire [`CSR_BUS_WIDTH-1:0] exu_csr_addr;
|
||||||
|
pa_dff_en_2 #(`CSR_BUS_WIDTH) dff_exu_csr_addr (clk_i, rst_n_i, exu_flush_flag, {`CSR_BUS_WIDTH{1'b0}}, csr_addr, exu_csr_addr);
|
||||||
|
|
||||||
|
// exu module generate "exu_hold_flag" signal if extend EX state
|
||||||
|
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] exu_csr_rdata;
|
||||||
|
|
||||||
|
wire exu_csr_waddr_vld;
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] exu_csr_wdata;
|
||||||
|
|
||||||
|
wire mem_en_flag;
|
||||||
|
|
||||||
|
wire exu_jump_flag;
|
||||||
|
wire [`ADDR_BUS_WIDTH-1:0] exu_jump_addr;
|
||||||
|
|
||||||
|
wire [`REG_BUS_WIDTH-1:0] reg_waddr_wb;
|
||||||
|
wire reg_waddr_wb_vld;
|
||||||
|
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] iresult;
|
||||||
|
wire iresult_vld;
|
||||||
|
|
||||||
|
pa_core_exu u_pa_core_exu (
|
||||||
|
.clk_i (clk_i),
|
||||||
|
.rst_n_i (rst_n_i),
|
||||||
|
|
||||||
|
.inst_set_i (exu_inst_set[1:0]),
|
||||||
|
.inst_func_i (exu_inst_func),
|
||||||
|
|
||||||
|
.pc_i (ifu_inst_addr),
|
||||||
|
|
||||||
|
.reg1_rdata_i (exu_reg1_rdata),
|
||||||
|
.reg2_rdata_i (exu_reg2_rdata),
|
||||||
|
|
||||||
|
.uimm_i (exu_uimm_data[19:0]),
|
||||||
|
|
||||||
|
.reg_waddr_i (exu_reg_waddr),
|
||||||
|
.reg_waddr_vld_i (exu_reg_waddr_vld),
|
||||||
|
|
||||||
|
.csr_rdata_i (exu_csr_rdata),
|
||||||
|
|
||||||
|
.csr_waddr_vld_o (exu_csr_waddr_vld),
|
||||||
|
.csr_wdata_o (exu_csr_wdata),
|
||||||
|
|
||||||
|
.mem_en_o (mem_en_flag),
|
||||||
|
|
||||||
|
.hold_flag_o (exu_hold_flag),
|
||||||
|
|
||||||
|
.jump_flag_o (exu_jump_flag),
|
||||||
|
.jump_addr_o (exu_jump_addr),
|
||||||
|
|
||||||
|
.reg_waddr_o (reg_waddr_wb),
|
||||||
|
.reg_waddr_vld_o (reg_waddr_wb_vld),
|
||||||
|
|
||||||
|
.iresult_o (iresult),
|
||||||
|
.iresult_vld_o (iresult_vld)
|
||||||
|
);
|
||||||
|
|
||||||
|
// clint module generate "int_hold_flag" signal if interrupt valid
|
||||||
|
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] csr_mtvec_data;
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] csr_mepc_data;
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] csr_mstatus_data;
|
||||||
|
|
||||||
|
wire [`CSR_BUS_WIDTH-1:0] int_csr_waddr;
|
||||||
|
wire int_csr_waddr_vld;
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] int_csr_wdata;
|
||||||
|
|
||||||
|
wire int_jump_flag;
|
||||||
|
wire [`ADDR_BUS_WIDTH-1:0] int_jump_addr;
|
||||||
|
|
||||||
|
pa_core_clint u_pa_core_clint (
|
||||||
|
.clk_i (clk_i),
|
||||||
|
.rst_n_i (rst_n_i),
|
||||||
|
|
||||||
|
.inst_set_i (exu_inst_set[0]),
|
||||||
|
.inst_func_i (exu_inst_func[6:4]),
|
||||||
|
|
||||||
|
.pc_i (ifu_inst_addr),
|
||||||
|
.inst_i (idu_inst_data),
|
||||||
|
|
||||||
|
.csr_mtvec_i (csr_mtvec_data),
|
||||||
|
.csr_mepc_i (csr_mepc_data),
|
||||||
|
.csr_mstatus_i (csr_mstatus_data),
|
||||||
|
|
||||||
|
.irq_i (irq_i),
|
||||||
|
|
||||||
|
.jump_flag_i (exu_jump_flag),
|
||||||
|
.hold_flag_i (exu_hold_flag),
|
||||||
|
|
||||||
|
.csr_waddr_o (int_csr_waddr),
|
||||||
|
.csr_waddr_vld_o (int_csr_waddr_vld),
|
||||||
|
.csr_wdata_o (int_csr_wdata),
|
||||||
|
|
||||||
|
.hold_flag_o (int_hold_flag),
|
||||||
|
|
||||||
|
.jump_flag_o (int_jump_flag),
|
||||||
|
.jump_addr_o (int_jump_addr)
|
||||||
|
);
|
||||||
|
|
||||||
|
assign hold_flag = exu_hold_flag
|
||||||
|
|| int_hold_flag;
|
||||||
|
|
||||||
|
assign jump_flag = exu_jump_flag
|
||||||
|
|| int_jump_flag;
|
||||||
|
|
||||||
|
assign jump_addr = exu_jump_flag ? exu_jump_addr
|
||||||
|
: int_jump_addr;
|
||||||
|
|
||||||
|
assign idu_flush_flag = (jump_flag)
|
||||||
|
|| (int_hold_flag);
|
||||||
|
|
||||||
|
assign exu_flush_flag = (jump_flag || jump_flag_1r)
|
||||||
|
|| (hold_flag);
|
||||||
|
|
||||||
|
wire [`CSR_BUS_WIDTH-1:0] csr_waddr;
|
||||||
|
wire csr_waddr_vld;
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] csr_wdata;
|
||||||
|
|
||||||
|
assign csr_waddr[`CSR_BUS_WIDTH-1:0] = exu_csr_addr[`CSR_BUS_WIDTH-1:0]
|
||||||
|
| int_csr_waddr[`CSR_BUS_WIDTH-1:0];
|
||||||
|
|
||||||
|
assign csr_waddr_vld = exu_csr_waddr_vld
|
||||||
|
| int_csr_waddr_vld;
|
||||||
|
|
||||||
|
assign csr_wdata[`DATA_BUS_WIDTH-1:0] = exu_csr_wdata[`DATA_BUS_WIDTH-1:0]
|
||||||
|
| int_csr_wdata[`DATA_BUS_WIDTH-1:0];
|
||||||
|
|
||||||
|
// mem store generate address in EX state, write under next clock
|
||||||
|
// mem load generate address in EX state, return data after next clock
|
||||||
|
|
||||||
|
wire mem_en_flag_1r;
|
||||||
|
pa_dff_rst_0 #(1) dff_mem_en_flag_1r (clk_i, rst_n_i, `VALID, mem_en_flag, mem_en_flag_1r);
|
||||||
|
|
||||||
|
wire [`ADDR_BUS_WIDTH-1:0] mem_addr;
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] mem_data;
|
||||||
|
wire [2:0] mem_size;
|
||||||
|
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] mem_wdata;
|
||||||
|
wire mem_wdata_vld;
|
||||||
|
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] mem_rdata;
|
||||||
|
wire mem_rdata_vld;
|
||||||
|
|
||||||
|
wire [`ADDR_BUS_WIDTH-1:0] mem_addr_1r;
|
||||||
|
pa_dff_rst_0 #(`ADDR_BUS_WIDTH) dff_mem_addr_1r (clk_i, rst_n_i, `VALID, mem_addr, mem_addr_1r);
|
||||||
|
|
||||||
|
assign mem_addr[`ADDR_BUS_WIDTH-1:0] = {{`ADDR_BUS_WIDTH}{mem_en_flag }} & iresult[`DATA_BUS_WIDTH-1:0]
|
||||||
|
| {{`ADDR_BUS_WIDTH}{mem_en_flag_1r}} & mem_addr_1r[`ADDR_BUS_WIDTH-1:0];
|
||||||
|
|
||||||
|
assign mem_wdata[`DATA_BUS_WIDTH-1:0] = {{`DATA_BUS_WIDTH}{mem_en_flag }} & exu_reg2_rdata[`DATA_BUS_WIDTH-1:0];
|
||||||
|
assign mem_wdata_vld = mem_en_flag;
|
||||||
|
|
||||||
|
wire subop_sign_1r;
|
||||||
|
pa_dff_rst_0 #(1) dff_subop_sign_1r (clk_i, rst_n_i, `VALID, exu_inst_func[31], subop_sign_1r);
|
||||||
|
|
||||||
|
wire [1:0] subop_size_1r;
|
||||||
|
pa_dff_rst_0 #(2) dff_subop_size_1r (clk_i, rst_n_i, `VALID, exu_inst_func[29:28], subop_size_1r);
|
||||||
|
|
||||||
|
wire op_load_1r;
|
||||||
|
pa_dff_rst_0 #(1) dff_op_load_1r (clk_i, rst_n_i, `VALID, exu_inst_func[14], op_load_1r);
|
||||||
|
|
||||||
|
wire subop_sign;
|
||||||
|
wire [1:0] subop_size;
|
||||||
|
wire op_load;
|
||||||
|
wire op_store;
|
||||||
|
|
||||||
|
assign subop_sign = exu_inst_func[31] || subop_sign_1r;
|
||||||
|
assign subop_size[1:0] = exu_inst_func[29:28] | subop_size_1r[1:0];
|
||||||
|
assign op_load = exu_inst_func[14] || op_load_1r;
|
||||||
|
assign op_store = exu_inst_func[13];
|
||||||
|
|
||||||
|
wire [4:0] mau_inst_func;
|
||||||
|
|
||||||
|
assign mau_inst_func[4:0] = {subop_sign, subop_size[1:0], op_load, op_store};
|
||||||
|
|
||||||
|
pa_core_mau u_pa_core_mau (
|
||||||
|
.inst_func_i (mau_inst_func),
|
||||||
|
|
||||||
|
.mem_addr_i (mem_addr[1:0]),
|
||||||
|
|
||||||
|
.mem_data_i (mem_wdata),
|
||||||
|
.mem_data_vld_i (mem_wdata_vld),
|
||||||
|
|
||||||
|
.mem_data_o (mem_rdata),
|
||||||
|
.mem_data_vld_o (mem_rdata_vld),
|
||||||
|
|
||||||
|
.rbm_data_i (dbus_data_i),
|
||||||
|
|
||||||
|
.rbm_data_o (mem_data),
|
||||||
|
.rbm_size_o (mem_size)
|
||||||
|
);
|
||||||
|
|
||||||
|
assign dbus_addr_o[`ADDR_BUS_WIDTH-1:0] = {32{mem_en_flag || mem_en_flag_1r}} & mem_addr[`ADDR_BUS_WIDTH-1:0];
|
||||||
|
assign dbus_data_o[`DATA_BUS_WIDTH-1:0] = {32{mem_en_flag}} & mem_data[`DATA_BUS_WIDTH-1:0];
|
||||||
|
assign dbus_size_o[2:0] = {3{mem_en_flag}} & mem_size[2:0];
|
||||||
|
assign dbus_rd_o = mem_en_flag & op_load;
|
||||||
|
assign dbus_we_o = mem_en_flag & op_store;
|
||||||
|
|
||||||
|
wire [`REG_BUS_WIDTH-1:0] mau_reg_addr;
|
||||||
|
pa_dff_rst_0 #(`REG_BUS_WIDTH) dff_mau_reg_addr (clk_i, rst_n_i, `VALID, reg_waddr_wb, mau_reg_addr);
|
||||||
|
|
||||||
|
wire mau_reg_addr_vld;
|
||||||
|
pa_dff_rst_0 #(1) dff_mau_reg_addr_vld (clk_i, rst_n_i, `VALID, reg_waddr_wb_vld, mau_reg_addr_vld);
|
||||||
|
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] mau_mem_data;
|
||||||
|
wire mau_mem_data_vld;
|
||||||
|
|
||||||
|
assign mau_mem_data[`DATA_BUS_WIDTH-1:0] = mem_rdata[`DATA_BUS_WIDTH-1:0];
|
||||||
|
assign mau_mem_data_vld = mem_rdata_vld;
|
||||||
|
|
||||||
|
// rtu module work under ID/WB state, include regfile and csrfile
|
||||||
|
|
||||||
|
wire [`REG_BUS_WIDTH-1:0] rtu_reg_waddr;
|
||||||
|
wire rtu_reg_waddr_vld;
|
||||||
|
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] rtu_reg_wdata;
|
||||||
|
|
||||||
|
wire [`CSR_BUS_WIDTH-1:0] rtu_csr_waddr;
|
||||||
|
wire rtu_csr_waddr_vld;
|
||||||
|
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] rtu_csr_wdata;
|
||||||
|
|
||||||
|
assign rtu_reg_waddr[`REG_BUS_WIDTH-1:0] = mau_mem_data_vld ? mau_reg_addr[`REG_BUS_WIDTH-1:0] // from memory
|
||||||
|
: reg_waddr_wb[`REG_BUS_WIDTH-1:0]; // from exu
|
||||||
|
assign rtu_reg_waddr_vld = mau_mem_data_vld ? (mau_reg_addr_vld && !mem_en_flag) // from memory
|
||||||
|
: reg_waddr_wb_vld; // from exu
|
||||||
|
|
||||||
|
assign rtu_reg_wdata[`DATA_BUS_WIDTH-1:0] = mau_mem_data_vld ? mau_mem_data[`DATA_BUS_WIDTH-1:0] // from memory, data
|
||||||
|
: iresult[`DATA_BUS_WIDTH-1:0]; // from exu, data
|
||||||
|
|
||||||
|
assign rtu_csr_waddr[`CSR_BUS_WIDTH-1:0] = csr_waddr[`CSR_BUS_WIDTH-1:0];
|
||||||
|
assign rtu_csr_waddr_vld = csr_waddr_vld;
|
||||||
|
|
||||||
|
assign rtu_csr_wdata[`DATA_BUS_WIDTH-1:0] = csr_wdata[`DATA_BUS_WIDTH-1:0];
|
||||||
|
|
||||||
|
pa_core_rtu u_pa_core_rtu (
|
||||||
|
.clk_i (clk_i),
|
||||||
|
.rst_n_i (rst_n_i),
|
||||||
|
|
||||||
|
.reg1_raddr_i (reg1_raddr),
|
||||||
|
.reg2_raddr_i (reg2_raddr),
|
||||||
|
|
||||||
|
.reg_waddr_i (rtu_reg_waddr),
|
||||||
|
.reg_waddr_vld_i (rtu_reg_waddr_vld),
|
||||||
|
|
||||||
|
.reg_wdata_i (rtu_reg_wdata),
|
||||||
|
|
||||||
|
.reg1_rdata_o (reg1_rdata),
|
||||||
|
.reg2_rdata_o (reg2_rdata),
|
||||||
|
|
||||||
|
.csr_mtvec_o (csr_mtvec_data),
|
||||||
|
.csr_mepc_o (csr_mepc_data),
|
||||||
|
.csr_mstatus_o (csr_mstatus_data),
|
||||||
|
|
||||||
|
.csr_raddr_i (exu_csr_addr),
|
||||||
|
|
||||||
|
.csr_waddr_i (rtu_csr_waddr),
|
||||||
|
.csr_waddr_vld_i (rtu_csr_waddr_vld),
|
||||||
|
|
||||||
|
.csr_wdata_i (rtu_csr_wdata),
|
||||||
|
|
||||||
|
.csr_rdata_o (exu_csr_rdata)
|
||||||
|
);
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,207 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021, SERI Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2021-10-29 Lyons first version
|
||||||
|
* 2022-04-04 Lyons v2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
`ifdef TESTBENCH_VCS
|
||||||
|
`include "pa_chip_param.v"
|
||||||
|
`else
|
||||||
|
`include "../pa_chip_param.v"
|
||||||
|
`endif
|
||||||
|
|
||||||
|
module pa_core_xreg (
|
||||||
|
input wire clk_i,
|
||||||
|
input wire rst_n_i,
|
||||||
|
|
||||||
|
input wire [`REG_BUS_WIDTH-1:0] reg1_raddr_i,
|
||||||
|
input wire [`REG_BUS_WIDTH-1:0] reg2_raddr_i,
|
||||||
|
|
||||||
|
input wire [`REG_BUS_WIDTH-1:0] reg_waddr_i,
|
||||||
|
input wire reg_waddr_vld_i,
|
||||||
|
|
||||||
|
input wire [`DATA_BUS_WIDTH-1:0] reg_wdata_i,
|
||||||
|
|
||||||
|
output wire [`DATA_BUS_WIDTH-1:0] reg1_rdata_o,
|
||||||
|
output wire [`DATA_BUS_WIDTH-1:0] reg2_rdata_o
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] _x0 = `ZERO_WORD;
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] _x1 = `ZERO_WORD;
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] _x2 = `ZERO_WORD;
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] _x3 = `ZERO_WORD;
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] _x4 = `ZERO_WORD;
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] _x5 = `ZERO_WORD;
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] _x6 = `ZERO_WORD;
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] _x7 = `ZERO_WORD;
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] _x8 = `ZERO_WORD;
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] _x9 = `ZERO_WORD;
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] _x10 = `ZERO_WORD;
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] _x11 = `ZERO_WORD;
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] _x12 = `ZERO_WORD;
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] _x13 = `ZERO_WORD;
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] _x14 = `ZERO_WORD;
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] _x15 = `ZERO_WORD;
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] _x16 = `ZERO_WORD;
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] _x17 = `ZERO_WORD;
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] _x18 = `ZERO_WORD;
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] _x19 = `ZERO_WORD;
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] _x20 = `ZERO_WORD;
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] _x21 = `ZERO_WORD;
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] _x22 = `ZERO_WORD;
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] _x23 = `ZERO_WORD;
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] _x24 = `ZERO_WORD;
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] _x25 = `ZERO_WORD;
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] _x26 = `ZERO_WORD;
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] _x27 = `ZERO_WORD;
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] _x28 = `ZERO_WORD;
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] _x29 = `ZERO_WORD;
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] _x30 = `ZERO_WORD;
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] _x31 = `ZERO_WORD;
|
||||||
|
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] _rs1;
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] _rs2;
|
||||||
|
|
||||||
|
always @ (posedge clk_i) begin
|
||||||
|
if (reg_waddr_vld_i) begin
|
||||||
|
case (reg_waddr_i[4:0])
|
||||||
|
5'h00 : _x0 <= `ZERO_WORD;
|
||||||
|
5'h01 : _x1 <= reg_wdata_i;
|
||||||
|
5'h02 : _x2 <= reg_wdata_i;
|
||||||
|
5'h03 : _x3 <= reg_wdata_i;
|
||||||
|
5'h04 : _x4 <= reg_wdata_i;
|
||||||
|
5'h05 : _x5 <= reg_wdata_i;
|
||||||
|
5'h06 : _x6 <= reg_wdata_i;
|
||||||
|
5'h07 : _x7 <= reg_wdata_i;
|
||||||
|
5'h08 : _x8 <= reg_wdata_i;
|
||||||
|
5'h09 : _x9 <= reg_wdata_i;
|
||||||
|
5'h0a : _x10 <= reg_wdata_i;
|
||||||
|
5'h0b : _x11 <= reg_wdata_i;
|
||||||
|
5'h0c : _x12 <= reg_wdata_i;
|
||||||
|
5'h0d : _x13 <= reg_wdata_i;
|
||||||
|
5'h0e : _x14 <= reg_wdata_i;
|
||||||
|
5'h0f : _x15 <= reg_wdata_i;
|
||||||
|
5'h10 : _x16 <= reg_wdata_i;
|
||||||
|
5'h11 : _x17 <= reg_wdata_i;
|
||||||
|
5'h12 : _x18 <= reg_wdata_i;
|
||||||
|
5'h13 : _x19 <= reg_wdata_i;
|
||||||
|
5'h14 : _x20 <= reg_wdata_i;
|
||||||
|
5'h15 : _x21 <= reg_wdata_i;
|
||||||
|
5'h16 : _x22 <= reg_wdata_i;
|
||||||
|
5'h17 : _x23 <= reg_wdata_i;
|
||||||
|
5'h18 : _x24 <= reg_wdata_i;
|
||||||
|
5'h19 : _x25 <= reg_wdata_i;
|
||||||
|
5'h1a : _x26 <= reg_wdata_i;
|
||||||
|
5'h1b : _x27 <= reg_wdata_i;
|
||||||
|
5'h1c : _x28 <= reg_wdata_i;
|
||||||
|
5'h1d : _x29 <= reg_wdata_i;
|
||||||
|
5'h1e : _x30 <= reg_wdata_i;
|
||||||
|
5'h1f : _x31 <= reg_wdata_i;
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always @ (*) begin
|
||||||
|
if (reg_waddr_vld_i && (reg1_raddr_i == reg_waddr_i)) begin
|
||||||
|
if (reg1_raddr_i == 5'h00) begin
|
||||||
|
_rs1 = `ZERO_WORD;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
_rs1 = reg_wdata_i;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
case (reg1_raddr_i[4:0])
|
||||||
|
5'h00 : _rs1 = _x0;
|
||||||
|
5'h01 : _rs1 = _x1;
|
||||||
|
5'h02 : _rs1 = _x2;
|
||||||
|
5'h03 : _rs1 = _x3;
|
||||||
|
5'h04 : _rs1 = _x4;
|
||||||
|
5'h05 : _rs1 = _x5;
|
||||||
|
5'h06 : _rs1 = _x6;
|
||||||
|
5'h07 : _rs1 = _x7;
|
||||||
|
5'h08 : _rs1 = _x8;
|
||||||
|
5'h09 : _rs1 = _x9;
|
||||||
|
5'h0a : _rs1 = _x10;
|
||||||
|
5'h0b : _rs1 = _x11;
|
||||||
|
5'h0c : _rs1 = _x12;
|
||||||
|
5'h0d : _rs1 = _x13;
|
||||||
|
5'h0e : _rs1 = _x14;
|
||||||
|
5'h0f : _rs1 = _x15;
|
||||||
|
5'h10 : _rs1 = _x16;
|
||||||
|
5'h11 : _rs1 = _x17;
|
||||||
|
5'h12 : _rs1 = _x18;
|
||||||
|
5'h13 : _rs1 = _x19;
|
||||||
|
5'h14 : _rs1 = _x20;
|
||||||
|
5'h15 : _rs1 = _x21;
|
||||||
|
5'h16 : _rs1 = _x22;
|
||||||
|
5'h17 : _rs1 = _x23;
|
||||||
|
5'h18 : _rs1 = _x24;
|
||||||
|
5'h19 : _rs1 = _x25;
|
||||||
|
5'h1a : _rs1 = _x26;
|
||||||
|
5'h1b : _rs1 = _x27;
|
||||||
|
5'h1c : _rs1 = _x28;
|
||||||
|
5'h1d : _rs1 = _x29;
|
||||||
|
5'h1e : _rs1 = _x30;
|
||||||
|
5'h1f : _rs1 = _x31;
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always @ (*) begin
|
||||||
|
if (reg_waddr_vld_i && (reg2_raddr_i == reg_waddr_i)) begin
|
||||||
|
if (reg2_raddr_i == 5'h00) begin
|
||||||
|
_rs2 = `ZERO_WORD;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
_rs2 = reg_wdata_i;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
case (reg2_raddr_i[4:0])
|
||||||
|
5'h00 : _rs2 = _x0;
|
||||||
|
5'h01 : _rs2 = _x1;
|
||||||
|
5'h02 : _rs2 = _x2;
|
||||||
|
5'h03 : _rs2 = _x3;
|
||||||
|
5'h04 : _rs2 = _x4;
|
||||||
|
5'h05 : _rs2 = _x5;
|
||||||
|
5'h06 : _rs2 = _x6;
|
||||||
|
5'h07 : _rs2 = _x7;
|
||||||
|
5'h08 : _rs2 = _x8;
|
||||||
|
5'h09 : _rs2 = _x9;
|
||||||
|
5'h0a : _rs2 = _x10;
|
||||||
|
5'h0b : _rs2 = _x11;
|
||||||
|
5'h0c : _rs2 = _x12;
|
||||||
|
5'h0d : _rs2 = _x13;
|
||||||
|
5'h0e : _rs2 = _x14;
|
||||||
|
5'h0f : _rs2 = _x15;
|
||||||
|
5'h10 : _rs2 = _x16;
|
||||||
|
5'h11 : _rs2 = _x17;
|
||||||
|
5'h12 : _rs2 = _x18;
|
||||||
|
5'h13 : _rs2 = _x19;
|
||||||
|
5'h14 : _rs2 = _x20;
|
||||||
|
5'h15 : _rs2 = _x21;
|
||||||
|
5'h16 : _rs2 = _x22;
|
||||||
|
5'h17 : _rs2 = _x23;
|
||||||
|
5'h18 : _rs2 = _x24;
|
||||||
|
5'h19 : _rs2 = _x25;
|
||||||
|
5'h1a : _rs2 = _x26;
|
||||||
|
5'h1b : _rs2 = _x27;
|
||||||
|
5'h1c : _rs2 = _x28;
|
||||||
|
5'h1d : _rs2 = _x29;
|
||||||
|
5'h1e : _rs2 = _x30;
|
||||||
|
5'h1f : _rs2 = _x31;
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assign reg1_rdata_o[`DATA_BUS_WIDTH-1:0] = _rs1[`DATA_BUS_WIDTH-1:0];
|
||||||
|
assign reg2_rdata_o[`DATA_BUS_WIDTH-1:0] = _rs2[`DATA_BUS_WIDTH-1:0];
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,183 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021, SERI Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2021-10-29 Lyons first version
|
||||||
|
* 2022-04-04 Lyons v2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
// memory model define(only choose one)
|
||||||
|
`ifdef TESTBENCH_VCS
|
||||||
|
`define MEMORY_MODEL_REG
|
||||||
|
`else
|
||||||
|
`define MEMORY_MODEL_BRAM
|
||||||
|
`endif
|
||||||
|
|
||||||
|
// xtal clock freq define(cpu clock may be divided)
|
||||||
|
`define XTAL_FREQ_HZ 32'd27_000_000
|
||||||
|
|
||||||
|
// core clock freq define
|
||||||
|
`define CORE_FREQ_HZ 32'd10_125_000
|
||||||
|
|
||||||
|
// uart baud rate define(fixed)
|
||||||
|
`define UART_BAUD 32'd115200
|
||||||
|
|
||||||
|
// memory size define(KByte)
|
||||||
|
`ifdef MEMORY_MODEL_REG
|
||||||
|
`define MEM_SIZE 32'd32
|
||||||
|
`endif
|
||||||
|
|
||||||
|
// bus width
|
||||||
|
`define ADDR_BUS_WIDTH 8'd32
|
||||||
|
`define DATA_BUS_WIDTH 8'd32
|
||||||
|
`define REG_BUS_WIDTH 8'd5
|
||||||
|
`define CSR_BUS_WIDTH 8'd12
|
||||||
|
|
||||||
|
// data width(bit)
|
||||||
|
`define INT_WIDTH 8'd32
|
||||||
|
|
||||||
|
// cpu reset pc address
|
||||||
|
`define RESET_PC_ADDR 32'h0000_0000
|
||||||
|
|
||||||
|
// instruct data define
|
||||||
|
`define INST_DATA_NOP 32'h0000_0000
|
||||||
|
|
||||||
|
// default data define
|
||||||
|
`define ZERO_WORD 32'h0000_0000
|
||||||
|
|
||||||
|
// valid signal value define
|
||||||
|
`define VALID 1'b1
|
||||||
|
`define INVALID 1'b0
|
||||||
|
|
||||||
|
// pin level define
|
||||||
|
`define LEVEL_HIGH 1'b1
|
||||||
|
`define LEVEL_LOW 1'b0
|
||||||
|
|
||||||
|
// csr register address define
|
||||||
|
`define CSR_NULL 12'h000
|
||||||
|
`define CSR_MTVEC 12'h305
|
||||||
|
`define CSR_MEPC 12'h341
|
||||||
|
`define CSR_MCAUSE 12'h342
|
||||||
|
`define CSR_MIE 12'h304
|
||||||
|
`define CSR_MIP 12'h344
|
||||||
|
`define CSR_MTVAL 12'h343
|
||||||
|
`define CSR_MSCRATCH 12'h340
|
||||||
|
`define CSR_MSCRATCHCSWL 12'h349
|
||||||
|
`define CSR_MSTATUS 12'h300
|
||||||
|
`define CSR_CYCLEH 12'hc80
|
||||||
|
`define CSR_CYCLE 12'hc00
|
||||||
|
|
||||||
|
// instruc define
|
||||||
|
`define INST_SET_WIDTH 8'd8
|
||||||
|
`define INST_SET_NULL 8'b0000_0000
|
||||||
|
`define INST_SET_RV32I 8'b0000_0001
|
||||||
|
`define INST_SET_RV32M 8'b0000_0010
|
||||||
|
`define INST_SET_RV32FD 8'b0000_0000
|
||||||
|
|
||||||
|
`define INST_TYPE_WIDTH 8'd8
|
||||||
|
`define INST_TYPE_NULL 8'b0000_0000
|
||||||
|
`define INST_TYPE_CSR 8'b0000_0001
|
||||||
|
`define INST_TYPE_R 8'b0000_0010
|
||||||
|
`define INST_TYPE_I 8'b0000_0100
|
||||||
|
`define INST_TYPE_S 8'b0000_1000
|
||||||
|
`define INST_TYPE_B 8'b0001_0000
|
||||||
|
`define INST_TYPE_U 8'b0010_0000
|
||||||
|
`define INST_TYPE_J 8'b0100_0000
|
||||||
|
|
||||||
|
`define INST_FUNC_WIDTH 8'd32
|
||||||
|
`define INST_FUNC_NULL 32'b0_0_00_0000_0000_0000_0000_0000_0000_0000
|
||||||
|
|
||||||
|
`define INST_FUNC_ADD 32'b0_0_00_0000_1000_0000_0000_0000_0000_0000
|
||||||
|
`define INST_FUNC_SUB 32'b0_0_00_0000_0100_0000_0000_0000_0000_0000
|
||||||
|
`define INST_FUNC_SLL 32'b0_0_00_0000_0010_0000_0000_0000_0000_0000
|
||||||
|
`define INST_FUNC_SRL 32'b0_0_00_0000_0001_0000_0000_0000_0000_0000
|
||||||
|
`define INST_FUNC_SRA 32'b0_0_00_0000_0000_1000_0000_0000_0000_0000
|
||||||
|
`define INST_FUNC_OR 32'b0_0_00_0000_0000_0100_0000_0000_0000_0000
|
||||||
|
`define INST_FUNC_AND 32'b0_0_00_0000_0000_0010_0000_0000_0000_0000
|
||||||
|
`define INST_FUNC_XOR 32'b0_0_00_0000_0000_0001_0000_0000_0000_0000
|
||||||
|
`define INST_FUNC_SLT 32'b0_0_00_0000_0000_0000_1000_0000_0000_0000
|
||||||
|
`define INST_FUNC_LOAD 32'b0_0_00_0000_0000_0000_0100_0000_0000_0000
|
||||||
|
`define INST_FUNC_STORE 32'b0_0_00_0000_0000_0000_0010_0000_0000_0000
|
||||||
|
`define INST_FUNC_FENCE 32'b0_0_00_0000_0000_0000_0001_0000_0000_0000
|
||||||
|
`define INST_FUNC_B 32'b0_0_00_0000_0000_0000_0000_1000_0000_0000
|
||||||
|
`define INST_FUNC_JAL 32'b0_0_00_0000_0000_0000_0000_0100_0000_0000
|
||||||
|
`define INST_FUNC_JALR 32'b0_0_00_0000_0000_0000_0000_0010_0000_0000
|
||||||
|
`define INST_FUNC_AUIPC 32'b0_0_00_0000_0000_0000_0000_0001_0000_0000
|
||||||
|
`define INST_FUNC_LUI 32'b0_0_00_0000_0000_0000_0000_0000_1000_0000
|
||||||
|
`define INST_FUNC_ECALL 32'b0_0_00_0000_0000_0000_0000_0000_0100_0000
|
||||||
|
`define INST_FUNC_EBREAK 32'b0_0_00_0000_0000_0000_0000_0000_0010_0000
|
||||||
|
`define INST_FUNC_MRET 32'b0_0_00_0000_0000_0000_0000_0000_0001_0000
|
||||||
|
`define INST_FUNC_WFI 32'b0_0_00_0000_0000_0000_0000_0000_0000_1000
|
||||||
|
`define INST_FUNC_CSRRW 32'b0_0_00_0000_0000_0000_0000_0000_0000_0100
|
||||||
|
`define INST_FUNC_CSRRS 32'b0_0_00_0000_0000_0000_0000_0000_0000_0010
|
||||||
|
`define INST_FUNC_CSRRC 32'b0_0_00_0000_0000_0000_0000_0000_0000_0001
|
||||||
|
|
||||||
|
`define INST_FUNC_MUL 32'b0_0_00_0000_1000_0000_0000_0000_0000_0000
|
||||||
|
`define INST_FUNC_DIV 32'b0_0_00_0000_0100_0000_0000_0000_0000_0000
|
||||||
|
`define INST_FUNC_REM 32'b0_0_00_0000_0010_0000_0000_0000_0000_0000
|
||||||
|
|
||||||
|
`define INST_FUNC_SUFFIX_UNSIGN 32'b1_0_00_0000_0000_0000_0000_0000_0000_0000
|
||||||
|
|
||||||
|
`define INST_FUNC_SUFFIX_IMM 32'b0_1_00_0000_0000_0000_0000_0000_0000_0000
|
||||||
|
|
||||||
|
`define INST_FUNC_SUFFIX_HIGH 32'b0_1_00_0000_0000_0000_0000_0000_0000_0000
|
||||||
|
|
||||||
|
`define INST_FUNC_SUFFIX_BYTE 32'b0_0_01_0000_0000_0000_0000_0000_0000_0000
|
||||||
|
`define INST_FUNC_SUFFIX_HALF 32'b0_0_10_0000_0000_0000_0000_0000_0000_0000
|
||||||
|
|
||||||
|
`define INST_FUNC_SUFFIX_U1 32'b1_0_01_0000_0000_0000_0000_0000_0000_0000
|
||||||
|
`define INST_FUNC_SUFFIX_U2 32'b1_0_10_0000_0000_0000_0000_0000_0000_0000
|
||||||
|
|
||||||
|
`define INST_FUNC_SUFFIX_EQ 32'b0_0_00_1000_0000_0000_0000_0000_0000_0000
|
||||||
|
`define INST_FUNC_SUFFIX_NE 32'b0_0_00_0100_0000_0000_0000_0000_0000_0000
|
||||||
|
`define INST_FUNC_SUFFIX_LT 32'b0_0_00_0010_0000_0000_0000_0000_0000_0000
|
||||||
|
`define INST_FUNC_SUFFIX_GT 32'b0_0_00_0001_0000_0000_0000_0000_0000_0000
|
||||||
|
|
||||||
|
`define INST_LB 3'b000
|
||||||
|
`define INST_LH 3'b001
|
||||||
|
`define INST_LW 3'b010
|
||||||
|
`define INST_LBU 3'b100
|
||||||
|
`define INST_LHU 3'b101
|
||||||
|
|
||||||
|
`define INST_FENCE 3'b000
|
||||||
|
`define INST_FENCEI 3'b001
|
||||||
|
|
||||||
|
`define INST_ADD 3'b000 // INST_SUB
|
||||||
|
`define INST_SLL 3'b001
|
||||||
|
`define INST_SLT 3'b010
|
||||||
|
`define INST_SLTU 3'b011
|
||||||
|
`define INST_XOR 3'b100
|
||||||
|
`define INST_SRL 3'b101 // INST_SRA
|
||||||
|
`define INST_OR 3'b110
|
||||||
|
`define INST_AND 3'b111
|
||||||
|
|
||||||
|
`define INST_SB 3'b000
|
||||||
|
`define INST_SH 3'b001
|
||||||
|
`define INST_SW 3'b010
|
||||||
|
|
||||||
|
`define INST_BEQ 3'b000
|
||||||
|
`define INST_BNE 3'b001
|
||||||
|
`define INST_BLT 3'b100
|
||||||
|
`define INST_BGE 3'b101
|
||||||
|
`define INST_BLTU 3'b110
|
||||||
|
`define INST_BGEU 3'b111
|
||||||
|
|
||||||
|
`define INST_ECALL 3'b000 // INST_EBREAK INST_EBREAK INST_MRET INST_WFI
|
||||||
|
`define INST_CSRRW 3'b001
|
||||||
|
`define INST_CSRRS 3'b010
|
||||||
|
`define INST_CSRRC 3'b011
|
||||||
|
`define INST_CSRRWI 3'b101
|
||||||
|
`define INST_CSRRSI 3'b110
|
||||||
|
`define INST_CSRRCI 3'b111
|
||||||
|
|
||||||
|
`define INST_MUL 3'b000
|
||||||
|
`define INST_MULH 3'b001
|
||||||
|
`define INST_MULHSU 3'b010
|
||||||
|
`define INST_MULHU 3'b011
|
||||||
|
`define INST_DIV 3'b100
|
||||||
|
`define INST_DIVU 3'b101
|
||||||
|
`define INST_REM 3'b110
|
||||||
|
`define INST_REMU 3'b111
|
|
@ -0,0 +1,246 @@
|
||||||
|
`timescale 1ns / 1ps
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021, SERI Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2021-10-29 Lyons first version
|
||||||
|
* 2022-04-04 Lyons v2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
`ifdef TESTBENCH_VCS
|
||||||
|
`include "pa_chip_param.v"
|
||||||
|
`else
|
||||||
|
`include "./pa_chip_param.v"
|
||||||
|
`endif
|
||||||
|
|
||||||
|
module pa_chip_top (
|
||||||
|
input wire clk_i,
|
||||||
|
input wire rst_n_i,
|
||||||
|
|
||||||
|
output wire clk_o,
|
||||||
|
|
||||||
|
inout wire gpio_PA0,
|
||||||
|
inout wire gpio_PA1,
|
||||||
|
inout wire gpio_PA2,
|
||||||
|
inout wire gpio_PA3,
|
||||||
|
inout wire gpio_PA4,
|
||||||
|
inout wire gpio_PA5,
|
||||||
|
inout wire gpio_PA6,
|
||||||
|
inout wire gpio_PA7,
|
||||||
|
inout wire gpio_PA8,
|
||||||
|
inout wire gpio_PA9,
|
||||||
|
inout wire gpio_PA10,
|
||||||
|
inout wire gpio_PA11,
|
||||||
|
inout wire gpio_PA12,
|
||||||
|
inout wire gpio_PA13,
|
||||||
|
input wire gpio_PA14,
|
||||||
|
output wire gpio_PA15
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
wire clk_out;
|
||||||
|
wire rst_out_n;
|
||||||
|
|
||||||
|
Gowin_rPLL _clock_0 (
|
||||||
|
.clkout(clk_out), //output clkout
|
||||||
|
.lock(rst_out_n), //output lock
|
||||||
|
.reset(~rst_n_i), //input reset
|
||||||
|
.clkin(clk_i) //input clkin
|
||||||
|
);
|
||||||
|
|
||||||
|
assign clk_o = clk_out;
|
||||||
|
|
||||||
|
|
||||||
|
wire [`ADDR_BUS_WIDTH-1:0] m0_addr;
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] m0_rdata;
|
||||||
|
|
||||||
|
wire [`ADDR_BUS_WIDTH-1:0] m1_addr;
|
||||||
|
wire m1_rd;
|
||||||
|
wire m1_we;
|
||||||
|
wire [2:0] m1_size;
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] m1_wdata;
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] m1_rdata;
|
||||||
|
|
||||||
|
wire s0_rd;
|
||||||
|
wire s0_we;
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] s0_data;
|
||||||
|
|
||||||
|
wire s1_rd;
|
||||||
|
wire s1_we;
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] s1_data;
|
||||||
|
|
||||||
|
wire s2_rd;
|
||||||
|
wire s2_we;
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] s2_data;
|
||||||
|
|
||||||
|
wire s3_rd;
|
||||||
|
wire s3_we;
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] s3_data;
|
||||||
|
|
||||||
|
wire s4_rd;
|
||||||
|
wire s4_we;
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] s4_data;
|
||||||
|
|
||||||
|
wire s5_rd;
|
||||||
|
wire s5_we;
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] s5_data;
|
||||||
|
|
||||||
|
wire s6_rd;
|
||||||
|
wire s6_we;
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] s6_data;
|
||||||
|
|
||||||
|
wire irq_flag;
|
||||||
|
|
||||||
|
pa_core_top u_pa_core_top (
|
||||||
|
.clk_i (clk_out),
|
||||||
|
.rst_n_i (rst_out_n),
|
||||||
|
|
||||||
|
.irq_i (irq_flag),
|
||||||
|
|
||||||
|
.ibus_addr_o (m0_addr),
|
||||||
|
.ibus_data_i (m0_rdata),
|
||||||
|
|
||||||
|
.dbus_addr_o (m1_addr),
|
||||||
|
.dbus_rd_o (m1_rd),
|
||||||
|
.dbus_we_o (m1_we),
|
||||||
|
.dbus_size_o (m1_size),
|
||||||
|
.dbus_data_o (m1_wdata),
|
||||||
|
.dbus_data_i (m1_rdata)
|
||||||
|
);
|
||||||
|
|
||||||
|
pa_soc_rbm u_pa_soc_rbm1 (
|
||||||
|
.m_addr_i (m1_addr),
|
||||||
|
.m_data_o (m1_rdata),
|
||||||
|
.m_we_i (m1_we),
|
||||||
|
.m_rd_i (m1_rd),
|
||||||
|
|
||||||
|
// 0x0000_0000 ~ 0x0fff_ffff
|
||||||
|
.s0_data_i (s0_data),
|
||||||
|
.s0_we_o (s0_we),
|
||||||
|
.s0_rd_o (s0_rd),
|
||||||
|
|
||||||
|
// 0x1000_0000 ~ 0x1fff_ffff
|
||||||
|
.s1_data_i (s1_data),
|
||||||
|
.s1_we_o (s1_we),
|
||||||
|
.s1_rd_o (s1_rd),
|
||||||
|
|
||||||
|
// 0x2000_0000 ~ 0x2fff_ffff
|
||||||
|
.s2_data_i (s2_data),
|
||||||
|
.s2_we_o (s2_we),
|
||||||
|
.s2_rd_o (s2_rd),
|
||||||
|
|
||||||
|
// 0x3000_0000 ~ 0x3fff_ffff
|
||||||
|
.s3_data_i (s3_data),
|
||||||
|
.s3_we_o (s3_we),
|
||||||
|
.s3_rd_o (s3_rd),
|
||||||
|
|
||||||
|
// 0x4000_0000 ~ 0x4fff_ffff
|
||||||
|
.s4_data_i (s4_data),
|
||||||
|
.s4_we_o (s4_we),
|
||||||
|
.s4_rd_o (s4_rd),
|
||||||
|
|
||||||
|
// 0x5000_0000 ~ 0x5fff_ffff
|
||||||
|
.s5_data_i (s5_data),
|
||||||
|
.s5_we_o (s5_we),
|
||||||
|
.s5_rd_o (s5_rd),
|
||||||
|
|
||||||
|
// 0x6000_0000 ~ 0x6fff_ffff
|
||||||
|
.s6_data_i (s6_data),
|
||||||
|
.s6_we_o (s6_we),
|
||||||
|
.s6_rd_o (s6_rd)
|
||||||
|
);
|
||||||
|
|
||||||
|
pa_perips_tcm2 u_pa_perips_rom (
|
||||||
|
.clk_i (clk_out),
|
||||||
|
.rst_n_i (rst_out_n),
|
||||||
|
|
||||||
|
.addr1_i (m1_addr),
|
||||||
|
.rd1_i (s0_rd),
|
||||||
|
.we1_i (s0_we),
|
||||||
|
.size1_i (m1_size),
|
||||||
|
.data1_i (m1_wdata),
|
||||||
|
.data1_o (s0_data),
|
||||||
|
|
||||||
|
.addr2_i (m0_addr),
|
||||||
|
.rd2_i (1'b1),
|
||||||
|
.data2_o (m0_rdata)
|
||||||
|
);
|
||||||
|
|
||||||
|
pa_perips_tcm u_pa_perips_ram (
|
||||||
|
.clk_i (clk_out),
|
||||||
|
.rst_n_i (rst_out_n),
|
||||||
|
|
||||||
|
.addr1_i (m1_addr),
|
||||||
|
.rd1_i (s1_rd),
|
||||||
|
.we1_i (s1_we),
|
||||||
|
.size1_i (m1_size),
|
||||||
|
.data1_i (m1_wdata),
|
||||||
|
.data1_o (s1_data),
|
||||||
|
|
||||||
|
.addr2_i (32'b0),
|
||||||
|
.rd2_i (1'b0),
|
||||||
|
.data2_o ()
|
||||||
|
);
|
||||||
|
|
||||||
|
pa_perips_timer u_pa_perips_timer1 (
|
||||||
|
.clk_i (clk_out),
|
||||||
|
.rst_n_i (rst_out_n),
|
||||||
|
|
||||||
|
.addr_i (m1_addr[7:0]),
|
||||||
|
.data_rd_i (s2_rd),
|
||||||
|
.data_we_i (s2_we),
|
||||||
|
.data_i (m1_wdata),
|
||||||
|
.data_o (s2_data),
|
||||||
|
|
||||||
|
.irq_o (irq_flag)
|
||||||
|
);
|
||||||
|
|
||||||
|
pa_perips_uart u_pa_perips_uart1 (
|
||||||
|
.clk_i (clk_out),
|
||||||
|
.rst_n_i (rst_out_n),
|
||||||
|
|
||||||
|
.addr_i (m1_addr[7:0]),
|
||||||
|
.data_rd_i (s3_rd),
|
||||||
|
.data_we_i (s3_we),
|
||||||
|
.data_i (m1_wdata),
|
||||||
|
.data_o (s3_data),
|
||||||
|
|
||||||
|
.pad_rxd (gpio_PA14),
|
||||||
|
.pad_txd (gpio_PA15)
|
||||||
|
);
|
||||||
|
|
||||||
|
pa_perips_gpio u_pa_perips_gpio1 (
|
||||||
|
.clk_i (clk_out),
|
||||||
|
.rst_n_i (rst_out_n),
|
||||||
|
|
||||||
|
.addr_i (m1_addr[7:0]),
|
||||||
|
.data_rd_i (s4_rd),
|
||||||
|
.data_we_i (s4_we),
|
||||||
|
.data_i (m1_wdata),
|
||||||
|
.data_o (s4_data),
|
||||||
|
|
||||||
|
.pad_PA0 (gpio_PA0),
|
||||||
|
.pad_PA1 (gpio_PA1),
|
||||||
|
.pad_PA2 (gpio_PA2),
|
||||||
|
.pad_PA3 (gpio_PA3),
|
||||||
|
.pad_PA4 (gpio_PA4),
|
||||||
|
.pad_PA5 (gpio_PA5),
|
||||||
|
.pad_PA6 (gpio_PA6),
|
||||||
|
.pad_PA7 (gpio_PA7),
|
||||||
|
.pad_PA8 (gpio_PA8),
|
||||||
|
.pad_PA9 (gpio_PA9),
|
||||||
|
.pad_PA10 (gpio_PA10),
|
||||||
|
.pad_PA11 (gpio_PA11),
|
||||||
|
.pad_PA12 (gpio_PA12),
|
||||||
|
.pad_PA13 (gpio_PA13),
|
||||||
|
.pad_PA14 (),
|
||||||
|
.pad_PA15 ()
|
||||||
|
);
|
||||||
|
|
||||||
|
assign s5_data[`DATA_BUS_WIDTH-1:0] = 32'b0;
|
||||||
|
assign s6_data[`DATA_BUS_WIDTH-1:0] = 32'b0;
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,233 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021, SERI Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2023-12-23 Lyons first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
`ifdef TESTBENCH_VCS
|
||||||
|
`include "pa_chip_param.v"
|
||||||
|
`else
|
||||||
|
`include "../pa_chip_param.v"
|
||||||
|
`endif
|
||||||
|
|
||||||
|
module pa_perips_gpio (
|
||||||
|
input wire clk_i,
|
||||||
|
input wire rst_n_i,
|
||||||
|
|
||||||
|
input wire [7:0] addr_i,
|
||||||
|
input wire data_rd_i,
|
||||||
|
input wire data_we_i,
|
||||||
|
input wire [`DATA_BUS_WIDTH-1:0] data_i,
|
||||||
|
output wire [`DATA_BUS_WIDTH-1:0] data_o,
|
||||||
|
|
||||||
|
inout wire pad_PA0,
|
||||||
|
inout wire pad_PA1,
|
||||||
|
inout wire pad_PA2,
|
||||||
|
inout wire pad_PA3,
|
||||||
|
inout wire pad_PA4,
|
||||||
|
inout wire pad_PA5,
|
||||||
|
inout wire pad_PA6,
|
||||||
|
inout wire pad_PA7,
|
||||||
|
inout wire pad_PA8,
|
||||||
|
inout wire pad_PA9,
|
||||||
|
inout wire pad_PA10,
|
||||||
|
inout wire pad_PA11,
|
||||||
|
inout wire pad_PA12,
|
||||||
|
inout wire pad_PA13,
|
||||||
|
inout wire pad_PA14,
|
||||||
|
inout wire pad_PA15
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
localparam GPIO_REG_CR = 8'h00;
|
||||||
|
localparam GPIO_REG_IN = 8'h04;
|
||||||
|
localparam GPIO_REG_OUT = 8'h08;
|
||||||
|
localparam GPIO_REG_RSVD = 8'h0c;
|
||||||
|
localparam GPIO_REG_OBIT = 8'h10;
|
||||||
|
|
||||||
|
|
||||||
|
// [15:0] : direction, 0:out, 1:in
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] _gpio_cr;
|
||||||
|
|
||||||
|
// [15:0] : input bit
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] _gpio_in;
|
||||||
|
|
||||||
|
// [15:0] : output bit
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] _gpio_out;
|
||||||
|
|
||||||
|
|
||||||
|
always @ (posedge clk_i or negedge rst_n_i) begin
|
||||||
|
if (!rst_n_i) begin
|
||||||
|
_gpio_cr <= 32'h0000_4400;
|
||||||
|
_gpio_out <= 32'h0000_fff7;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
if (data_we_i) begin
|
||||||
|
case (addr_i[7:0])
|
||||||
|
GPIO_REG_CR : _gpio_cr <= {16'b0, data_i[15:0]};
|
||||||
|
GPIO_REG_OUT : _gpio_out <= {16'b0, data_i[15:0]};
|
||||||
|
GPIO_REG_OBIT + 4*0 : _gpio_out[0 ] <= data_i[0];
|
||||||
|
GPIO_REG_OBIT + 4*1 : _gpio_out[1 ] <= data_i[0];
|
||||||
|
GPIO_REG_OBIT + 4*2 : _gpio_out[2 ] <= data_i[0];
|
||||||
|
GPIO_REG_OBIT + 4*3 : _gpio_out[3 ] <= data_i[0];
|
||||||
|
GPIO_REG_OBIT + 4*4 : _gpio_out[4 ] <= data_i[0];
|
||||||
|
GPIO_REG_OBIT + 4*5 : _gpio_out[5 ] <= data_i[0];
|
||||||
|
GPIO_REG_OBIT + 4*6 : _gpio_out[6 ] <= data_i[0];
|
||||||
|
GPIO_REG_OBIT + 4*7 : _gpio_out[7 ] <= data_i[0];
|
||||||
|
GPIO_REG_OBIT + 4*8 : _gpio_out[8 ] <= data_i[0];
|
||||||
|
GPIO_REG_OBIT + 4*9 : _gpio_out[9 ] <= data_i[0];
|
||||||
|
GPIO_REG_OBIT + 4*10 : _gpio_out[10] <= data_i[0];
|
||||||
|
GPIO_REG_OBIT + 4*11 : _gpio_out[11] <= data_i[0];
|
||||||
|
GPIO_REG_OBIT + 4*12 : _gpio_out[12] <= data_i[0];
|
||||||
|
GPIO_REG_OBIT + 4*13 : _gpio_out[13] <= data_i[0];
|
||||||
|
GPIO_REG_OBIT + 4*14 : _gpio_out[14] <= data_i[0];
|
||||||
|
GPIO_REG_OBIT + 4*15 : _gpio_out[15] <= data_i[0];
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] _data = `ZERO_WORD;
|
||||||
|
|
||||||
|
always @ (posedge clk_i) begin
|
||||||
|
if (data_rd_i) begin
|
||||||
|
case (addr_i[7:0])
|
||||||
|
GPIO_REG_CR : _data <= _gpio_cr;
|
||||||
|
GPIO_REG_IN : _data <= _gpio_in;
|
||||||
|
default : _data <= `ZERO_WORD;
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] pad_PIn;
|
||||||
|
|
||||||
|
IOBUF uut_0 (
|
||||||
|
.O (pad_PIn[0]),
|
||||||
|
.IO (pad_PA0),
|
||||||
|
.I (_gpio_out[0]),
|
||||||
|
.OEN (_gpio_cr[0])
|
||||||
|
);
|
||||||
|
|
||||||
|
IOBUF uut_1 (
|
||||||
|
.O (pad_PIn[1]),
|
||||||
|
.IO (pad_PA1),
|
||||||
|
.I (_gpio_out[1]),
|
||||||
|
.OEN (_gpio_cr[1])
|
||||||
|
);
|
||||||
|
|
||||||
|
IOBUF uut_2 (
|
||||||
|
.O (pad_PIn[2]),
|
||||||
|
.IO (pad_PA2),
|
||||||
|
.I (_gpio_out[2]),
|
||||||
|
.OEN (_gpio_cr[2])
|
||||||
|
);
|
||||||
|
|
||||||
|
IOBUF uut_3 (
|
||||||
|
.O (pad_PIn[3]),
|
||||||
|
.IO (pad_PA3),
|
||||||
|
.I (_gpio_out[3]),
|
||||||
|
.OEN (_gpio_cr[3])
|
||||||
|
);
|
||||||
|
|
||||||
|
IOBUF uut_4 (
|
||||||
|
.O (pad_PIn[4]),
|
||||||
|
.IO (pad_PA4),
|
||||||
|
.I (_gpio_out[4]),
|
||||||
|
.OEN (_gpio_cr[4])
|
||||||
|
);
|
||||||
|
|
||||||
|
IOBUF uut_5 (
|
||||||
|
.O (pad_PIn[5]),
|
||||||
|
.IO (pad_PA5),
|
||||||
|
.I (_gpio_out[5]),
|
||||||
|
.OEN (_gpio_cr[5])
|
||||||
|
);
|
||||||
|
|
||||||
|
IOBUF uut_6 (
|
||||||
|
.O (pad_PIn[6]),
|
||||||
|
.IO (pad_PA6),
|
||||||
|
.I (_gpio_out[6]),
|
||||||
|
.OEN (_gpio_cr[6])
|
||||||
|
);
|
||||||
|
|
||||||
|
IOBUF uut_7 (
|
||||||
|
.O (pad_PIn[7]),
|
||||||
|
.IO (pad_PA7),
|
||||||
|
.I (_gpio_out[7]),
|
||||||
|
.OEN (_gpio_cr[7])
|
||||||
|
);
|
||||||
|
|
||||||
|
IOBUF uut_8 (
|
||||||
|
.O (pad_PIn[8]),
|
||||||
|
.IO (pad_PA8),
|
||||||
|
.I (_gpio_out[8]),
|
||||||
|
.OEN (_gpio_cr[8])
|
||||||
|
);
|
||||||
|
|
||||||
|
IOBUF uut_9 (
|
||||||
|
.O (pad_PIn[9]),
|
||||||
|
.IO (pad_PA9),
|
||||||
|
.I (_gpio_out[9]),
|
||||||
|
.OEN (_gpio_cr[9])
|
||||||
|
);
|
||||||
|
|
||||||
|
IOBUF uut_10 (
|
||||||
|
.O (pad_PIn[10]),
|
||||||
|
.IO (pad_PA10),
|
||||||
|
.I (_gpio_out[10]),
|
||||||
|
.OEN (_gpio_cr[10])
|
||||||
|
);
|
||||||
|
|
||||||
|
IOBUF uut_11 (
|
||||||
|
.O (pad_PIn[11]),
|
||||||
|
.IO (pad_PA11),
|
||||||
|
.I (_gpio_out[11]),
|
||||||
|
.OEN (_gpio_cr[11])
|
||||||
|
);
|
||||||
|
|
||||||
|
IOBUF uut_12 (
|
||||||
|
.O (pad_PIn[12]),
|
||||||
|
.IO (pad_PA12),
|
||||||
|
.I (_gpio_out[12]),
|
||||||
|
.OEN (_gpio_cr[12])
|
||||||
|
);
|
||||||
|
|
||||||
|
IOBUF uut_13 (
|
||||||
|
.O (pad_PIn[13]),
|
||||||
|
.IO (pad_PA13),
|
||||||
|
.I (_gpio_out[13]),
|
||||||
|
.OEN (_gpio_cr[13])
|
||||||
|
);
|
||||||
|
|
||||||
|
// IOBUF uut_14 (
|
||||||
|
// .O (pad_PIn[14]),
|
||||||
|
// .IO (pad_PA14),
|
||||||
|
// .I (_gpio_out[14]),
|
||||||
|
// .OEN (_gpio_cr[14])
|
||||||
|
// );
|
||||||
|
|
||||||
|
// IOBUF uut_15 (
|
||||||
|
// .O (pad_PIn[15]),
|
||||||
|
// .IO (pad_PA15),
|
||||||
|
// .I (_gpio_out[15]),
|
||||||
|
// .OEN (_gpio_cr[15])
|
||||||
|
// );
|
||||||
|
|
||||||
|
assign pad_PIn[31:14] = 18'b0;
|
||||||
|
|
||||||
|
always @ (posedge clk_i) begin
|
||||||
|
if (!rst_n_i) begin
|
||||||
|
_gpio_in <= `ZERO_WORD;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
_gpio_in <= pad_PIn;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assign data_o[`DATA_BUS_WIDTH-1:0] = _data[`DATA_BUS_WIDTH-1:0];
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,142 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021, SERI Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2021-10-29 Lyons first version
|
||||||
|
* 2022-04-04 Lyons v2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
`ifdef TESTBENCH_VCS
|
||||||
|
`include "pa_chip_param.v"
|
||||||
|
`else
|
||||||
|
`include "../pa_chip_param.v"
|
||||||
|
`endif
|
||||||
|
|
||||||
|
module pa_perips_tcm (
|
||||||
|
input wire clk_i,
|
||||||
|
input wire rst_n_i,
|
||||||
|
|
||||||
|
input wire [`ADDR_BUS_WIDTH-1:0] addr1_i,
|
||||||
|
input wire rd1_i,
|
||||||
|
input wire we1_i,
|
||||||
|
input wire [2:0] size1_i,
|
||||||
|
input wire [`DATA_BUS_WIDTH-1:0] data1_i,
|
||||||
|
output wire [`DATA_BUS_WIDTH-1:0] data1_o,
|
||||||
|
|
||||||
|
input wire [`ADDR_BUS_WIDTH-1:0] addr2_i,
|
||||||
|
input wire rd2_i,
|
||||||
|
output wire [`DATA_BUS_WIDTH-1:0] data2_o
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
wire [`ADDR_BUS_WIDTH-1:0] index1;
|
||||||
|
wire [`ADDR_BUS_WIDTH-1:0] index2;
|
||||||
|
|
||||||
|
assign index1[`ADDR_BUS_WIDTH-1:0] = {2'b0, 4'b0, addr1_i[27:2]};
|
||||||
|
assign index2[`ADDR_BUS_WIDTH-1:0] = {2'b0, 4'b0, addr2_i[27:2]};
|
||||||
|
|
||||||
|
reg [3:0] addr_mask;
|
||||||
|
|
||||||
|
wire size_word;
|
||||||
|
wire size_half;
|
||||||
|
|
||||||
|
assign size_word = size1_i[2];
|
||||||
|
assign size_half = size1_i[1];
|
||||||
|
|
||||||
|
always @ (*) begin
|
||||||
|
case (addr1_i[1:0])
|
||||||
|
2'b00 : addr_mask[3:0] <= {size_word, size_word, (size_word || size_half), 1'b1};
|
||||||
|
2'b01 : addr_mask[3:0] <= {4'b0010};
|
||||||
|
2'b10 : addr_mask[3:0] <= {size_half, 3'b100};
|
||||||
|
2'b11 : addr_mask[3:0] <= {4'b1000};
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] _data1;
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] _data2;
|
||||||
|
|
||||||
|
Gowin_DPB_8x4k _ram_3 (
|
||||||
|
.douta(_data1[31:24]), //output [7:0] douta
|
||||||
|
.doutb(_data2[31:24]), //output [7:0] doutb
|
||||||
|
.clka(clk_i), //input clka
|
||||||
|
.ocea(`VALID), //input ocea
|
||||||
|
.cea(`VALID), //input cea
|
||||||
|
.reseta(~rst_n_i), //input reseta
|
||||||
|
.wrea(we1_i && addr_mask[3]), //input wrea
|
||||||
|
.clkb(clk_i), //input clkb
|
||||||
|
.oceb(`VALID), //input oceb
|
||||||
|
.ceb(`VALID), //input ceb
|
||||||
|
.resetb(~rst_n_i), //input resetb
|
||||||
|
.wreb(1'b0), //input wreb
|
||||||
|
.ada(addr1_i[13:2]), //input [11:0] ada
|
||||||
|
.dina(data1_i[31:24]), //input [7:0] dina
|
||||||
|
.adb(addr2_i[13:2]), //input [11:0] adb
|
||||||
|
.dinb(8'b0) //input [7:0] dinb
|
||||||
|
);
|
||||||
|
|
||||||
|
Gowin_DPB_8x4k _ram_2 (
|
||||||
|
.douta(_data1[23:16]), //output [7:0] douta
|
||||||
|
.doutb(_data2[23:16]), //output [7:0] doutb
|
||||||
|
.clka(clk_i), //input clka
|
||||||
|
.ocea(`VALID), //input ocea
|
||||||
|
.cea(`VALID), //input cea
|
||||||
|
.reseta(~rst_n_i), //input reseta
|
||||||
|
.wrea(we1_i && addr_mask[2]), //input wrea
|
||||||
|
.clkb(clk_i), //input clkb
|
||||||
|
.oceb(`VALID), //input oceb
|
||||||
|
.ceb(`VALID), //input ceb
|
||||||
|
.resetb(~rst_n_i), //input resetb
|
||||||
|
.wreb(1'b0), //input wreb
|
||||||
|
.ada(addr1_i[13:2]), //input [11:0] ada
|
||||||
|
.dina(data1_i[23:16]), //input [7:0] dina
|
||||||
|
.adb(addr2_i[13:2]), //input [11:0] adb
|
||||||
|
.dinb(8'b0) //input [7:0] dinb
|
||||||
|
);
|
||||||
|
|
||||||
|
Gowin_DPB_8x4k _ram_1 (
|
||||||
|
.douta(_data1[15:8]), //output [7:0] douta
|
||||||
|
.doutb(_data2[15:8]), //output [7:0] doutb
|
||||||
|
.clka(clk_i), //input clka
|
||||||
|
.ocea(`VALID), //input ocea
|
||||||
|
.cea(`VALID), //input cea
|
||||||
|
.reseta(~rst_n_i), //input reseta
|
||||||
|
.wrea(we1_i && addr_mask[1]), //input wrea
|
||||||
|
.clkb(clk_i), //input clkb
|
||||||
|
.oceb(`VALID), //input oceb
|
||||||
|
.ceb(`VALID), //input ceb
|
||||||
|
.resetb(~rst_n_i), //input resetb
|
||||||
|
.wreb(1'b0), //input wreb
|
||||||
|
.ada(addr1_i[13:2]), //input [11:0] ada
|
||||||
|
.dina(data1_i[15:8]), //input [7:0] dina
|
||||||
|
.adb(addr2_i[13:2]), //input [11:0] adb
|
||||||
|
.dinb(8'b0) //input [7:0] dinb
|
||||||
|
);
|
||||||
|
|
||||||
|
Gowin_DPB_8x4k _ram_0 (
|
||||||
|
.douta(_data1[7:0]), //output [7:0] douta
|
||||||
|
.doutb(_data2[7:0]), //output [7:0] doutb
|
||||||
|
.clka(clk_i), //input clka
|
||||||
|
.ocea(`VALID), //input ocea
|
||||||
|
.cea(`VALID), //input cea
|
||||||
|
.reseta(~rst_n_i), //input reseta
|
||||||
|
.wrea(we1_i && addr_mask[0]), //input wrea
|
||||||
|
.clkb(clk_i), //input clkb
|
||||||
|
.oceb(`VALID), //input oceb
|
||||||
|
.ceb(`VALID), //input ceb
|
||||||
|
.resetb(~rst_n_i), //input resetb
|
||||||
|
.wreb(1'b0), //input wreb
|
||||||
|
.ada(addr1_i[13:2]), //input [11:0] ada
|
||||||
|
.dina(data1_i[7:0]), //input [7:0] dina
|
||||||
|
.adb(addr2_i[13:2]), //input [11:0] adb
|
||||||
|
.dinb(8'b0) //input [7:0] dinb
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
assign data1_o[`DATA_BUS_WIDTH-1:0] = _data1[`DATA_BUS_WIDTH-1:0];
|
||||||
|
assign data2_o[`DATA_BUS_WIDTH-1:0] = _data2[`DATA_BUS_WIDTH-1:0];
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,100 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021, SERI Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2021-10-29 Lyons first version
|
||||||
|
* 2022-04-04 Lyons v2.0
|
||||||
|
* 2022-07-01 Lyons add pa_perips_tcm2 for rom
|
||||||
|
*/
|
||||||
|
|
||||||
|
`ifdef TESTBENCH_VCS
|
||||||
|
`include "pa_chip_param.v"
|
||||||
|
`else
|
||||||
|
`include "../pa_chip_param.v"
|
||||||
|
`endif
|
||||||
|
|
||||||
|
module pa_perips_tcm2 (
|
||||||
|
input wire clk_i,
|
||||||
|
input wire rst_n_i,
|
||||||
|
|
||||||
|
input wire [`ADDR_BUS_WIDTH-1:0] addr1_i,
|
||||||
|
input wire rd1_i,
|
||||||
|
input wire we1_i,
|
||||||
|
input wire [2:0] size1_i,
|
||||||
|
input wire [`DATA_BUS_WIDTH-1:0] data1_i,
|
||||||
|
output wire [`DATA_BUS_WIDTH-1:0] data1_o,
|
||||||
|
|
||||||
|
input wire [`ADDR_BUS_WIDTH-1:0] addr2_i,
|
||||||
|
input wire rd2_i,
|
||||||
|
output wire [`DATA_BUS_WIDTH-1:0] data2_o
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
`ifdef MEMORY_MODEL_REG
|
||||||
|
|
||||||
|
reg [7:0] _ram[0:`MEM_SIZE*1024-1];
|
||||||
|
|
||||||
|
wire [`ADDR_BUS_WIDTH-1:0] index1;
|
||||||
|
wire [`ADDR_BUS_WIDTH-1:0] index2;
|
||||||
|
|
||||||
|
assign index1[`ADDR_BUS_WIDTH-1:0] = {2'b0, 4'b0, addr1_i[27:2]};
|
||||||
|
assign index2[`ADDR_BUS_WIDTH-1:0] = {2'b0, 4'b0, addr2_i[27:2]};
|
||||||
|
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] _data1;
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] _data2;
|
||||||
|
|
||||||
|
always @ (posedge clk_i or negedge rst_n_i) begin
|
||||||
|
if (!rst_n_i) begin
|
||||||
|
_data1[`DATA_BUS_WIDTH-1:0] = `ZERO_WORD;
|
||||||
|
end
|
||||||
|
else if (rd1_i) begin
|
||||||
|
_data1[`DATA_BUS_WIDTH-1:0] = {_ram[index1*4+3], _ram[index1*4+2], _ram[index1*4+1], _ram[index1*4+0]};
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always @ (posedge clk_i or negedge rst_n_i) begin
|
||||||
|
if (!rst_n_i) begin
|
||||||
|
_data2[`DATA_BUS_WIDTH-1:0] = `ZERO_WORD;
|
||||||
|
end
|
||||||
|
else if (rd2_i) begin
|
||||||
|
_data2[`DATA_BUS_WIDTH-1:0] = {_ram[index2*4+3], _ram[index2*4+2], _ram[index2*4+1], _ram[index2*4+0]};
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
`endif // `ifdef MEMORY_MODEL_REG
|
||||||
|
|
||||||
|
|
||||||
|
`ifdef MEMORY_MODEL_BRAM
|
||||||
|
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] _data1;
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] _data2;
|
||||||
|
|
||||||
|
Gowin_DPB_32x8k _rom_0 (
|
||||||
|
.douta(_data1), //output [31:0] douta
|
||||||
|
.doutb(_data2), //output [31:0] doutb
|
||||||
|
.clka(clk_i), //input clka
|
||||||
|
.ocea(`VALID), //input ocea
|
||||||
|
.cea(`VALID), //input cea
|
||||||
|
.reseta(~rst_n_i), //input reseta
|
||||||
|
.wrea(we1_i), //input wrea
|
||||||
|
.clkb(clk_i), //input clkb
|
||||||
|
.oceb(`VALID), //input oceb
|
||||||
|
.ceb(`VALID), //input ceb
|
||||||
|
.resetb(~rst_n_i), //input resetb
|
||||||
|
.wreb(1'b0), //input wreb
|
||||||
|
.ada(addr1_i[14:2]), //input [12:0] ada
|
||||||
|
.dina(data1_i), //input [31:0] dina
|
||||||
|
.adb(addr2_i[14:2]), //input [12:0] adb
|
||||||
|
.dinb(32'b0) //input [31:0] dinb
|
||||||
|
);
|
||||||
|
|
||||||
|
`endif // `ifdef MEMORY_MODEL_BRAM
|
||||||
|
|
||||||
|
|
||||||
|
assign data1_o[`DATA_BUS_WIDTH-1:0] = _data1[`DATA_BUS_WIDTH-1:0];
|
||||||
|
assign data2_o[`DATA_BUS_WIDTH-1:0] = _data2[`DATA_BUS_WIDTH-1:0];
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,163 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021, SERI Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2021-10-29 Lyons first version
|
||||||
|
* 2022-04-04 Lyons v2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
`ifdef TESTBENCH_VCS
|
||||||
|
`include "pa_chip_param.v"
|
||||||
|
`else
|
||||||
|
`include "../pa_chip_param.v"
|
||||||
|
`endif
|
||||||
|
|
||||||
|
module pa_perips_timer (
|
||||||
|
input wire clk_i,
|
||||||
|
input wire rst_n_i,
|
||||||
|
|
||||||
|
input wire [7:0] addr_i,
|
||||||
|
input wire data_rd_i,
|
||||||
|
input wire data_we_i,
|
||||||
|
input wire [`DATA_BUS_WIDTH-1:0] data_i,
|
||||||
|
output wire [`DATA_BUS_WIDTH-1:0] data_o,
|
||||||
|
|
||||||
|
output wire irq_o
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
localparam TIMER_REG_CR = 8'h00;
|
||||||
|
localparam TIMER_REG_SR = 8'h04;
|
||||||
|
localparam TIMER_REG_PSC = 8'h08;
|
||||||
|
localparam TIMER_REG_LOAD = 8'h0c;
|
||||||
|
localparam TIMER_REG_COUNT = 8'h10;
|
||||||
|
|
||||||
|
|
||||||
|
// [0]: enbale
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] _timer_cr;
|
||||||
|
|
||||||
|
// [0]: timing-up flag
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] _timer_sr;
|
||||||
|
|
||||||
|
// [31:0] : prescale, need sub 1
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] _timer_psc;
|
||||||
|
|
||||||
|
// [31:0] : load value
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] _timer_load;
|
||||||
|
|
||||||
|
// [31:0] : count
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] _timer_count;
|
||||||
|
|
||||||
|
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] timer_clk_cnt;
|
||||||
|
|
||||||
|
wire timer_clk_timeup;
|
||||||
|
|
||||||
|
assign timer_clk_timeup = (timer_clk_cnt == _timer_psc[31:0]);
|
||||||
|
|
||||||
|
always @ (posedge clk_i or negedge rst_n_i) begin
|
||||||
|
if (!rst_n_i) begin
|
||||||
|
timer_clk_cnt <= `ZERO_WORD;
|
||||||
|
end
|
||||||
|
else if (_timer_cr[0]) begin
|
||||||
|
if (timer_clk_timeup) begin
|
||||||
|
timer_clk_cnt <= `ZERO_WORD;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
timer_clk_cnt <= timer_clk_cnt + 32'h1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
timer_clk_cnt <= `ZERO_WORD;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
reg timer_timeup;
|
||||||
|
|
||||||
|
always @ (posedge clk_i or negedge rst_n_i) begin
|
||||||
|
if (!rst_n_i) begin
|
||||||
|
timer_timeup <= 1'b0;
|
||||||
|
end
|
||||||
|
else if (_timer_cr[0]) begin
|
||||||
|
if (timer_timeup) begin
|
||||||
|
timer_timeup <= 1'b0;
|
||||||
|
end
|
||||||
|
else if (_timer_count == 32'h0) begin
|
||||||
|
timer_timeup <= 1'b1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
timer_timeup <= 1'b0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always @ (posedge clk_i or negedge rst_n_i) begin
|
||||||
|
if (!rst_n_i) begin
|
||||||
|
_timer_count <= `ZERO_WORD;
|
||||||
|
end
|
||||||
|
else if (_timer_cr[0]) begin
|
||||||
|
if (_timer_count == 32'h0) begin
|
||||||
|
_timer_count <= _timer_load; // re-load timer value
|
||||||
|
end
|
||||||
|
else if (timer_clk_timeup) begin
|
||||||
|
_timer_count <= _timer_count - 32'h1;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
_timer_count <= _timer_count;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
_timer_count <= `ZERO_WORD;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always @ (posedge clk_i or negedge rst_n_i) begin
|
||||||
|
if (!rst_n_i) begin
|
||||||
|
_timer_cr <= `ZERO_WORD;
|
||||||
|
_timer_sr <= `ZERO_WORD;
|
||||||
|
_timer_psc <= `ZERO_WORD;
|
||||||
|
_timer_load <= `ZERO_WORD;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
if (data_we_i) begin
|
||||||
|
case (addr_i[7:0])
|
||||||
|
TIMER_REG_CR : _timer_cr <= {data_i[31:0]};
|
||||||
|
TIMER_REG_SR : _timer_sr <= {data_i[31:1], (_timer_sr[0] & ~data_i[0])};
|
||||||
|
TIMER_REG_PSC : _timer_psc <= {data_i[31:0]};
|
||||||
|
TIMER_REG_LOAD : _timer_load <= {data_i[31:0]};
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
else if (_timer_sr[0]) begin
|
||||||
|
_timer_sr <= {data_i[31:1], 1'b0};
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
if (_timer_cr[0] && timer_timeup) begin
|
||||||
|
_timer_sr <= {data_i[31:1], 1'b1};
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] _data = `ZERO_WORD;
|
||||||
|
|
||||||
|
always @ (posedge clk_i) begin
|
||||||
|
if (data_rd_i) begin
|
||||||
|
case (addr_i[7:0])
|
||||||
|
TIMER_REG_CR : _data <= _timer_cr;
|
||||||
|
TIMER_REG_SR : _data <= _timer_sr;
|
||||||
|
TIMER_REG_PSC : _data <= _timer_psc;
|
||||||
|
TIMER_REG_LOAD : _data <= _timer_load;
|
||||||
|
TIMER_REG_COUNT : _data <= _timer_count;
|
||||||
|
default : _data <= `ZERO_WORD;
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assign data_o[`DATA_BUS_WIDTH-1:0] = _data[`DATA_BUS_WIDTH-1:0];
|
||||||
|
|
||||||
|
assign irq_o = _timer_sr[0];
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,285 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021, SERI Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2021-10-29 Lyons first version
|
||||||
|
* 2022-04-04 Lyons v2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
`ifdef TESTBENCH_VCS
|
||||||
|
`include "pa_chip_param.v"
|
||||||
|
`else
|
||||||
|
`include "../pa_chip_param.v"
|
||||||
|
`endif
|
||||||
|
|
||||||
|
module pa_perips_uart (
|
||||||
|
input wire clk_i,
|
||||||
|
input wire rst_n_i,
|
||||||
|
|
||||||
|
input wire [7:0] addr_i,
|
||||||
|
input wire data_rd_i,
|
||||||
|
input wire data_we_i,
|
||||||
|
input wire [`DATA_BUS_WIDTH-1:0] data_i,
|
||||||
|
output wire [`DATA_BUS_WIDTH-1:0] data_o,
|
||||||
|
|
||||||
|
input wire pad_rxd,
|
||||||
|
output wire pad_txd
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
localparam UART_REG_CR = 8'h00;
|
||||||
|
localparam UART_REG_SR = 8'h04;
|
||||||
|
localparam UART_REG_BAUD = 8'h08;
|
||||||
|
localparam UART_REG_RXD = 8'h0c;
|
||||||
|
localparam UART_REG_TXD = 8'h10;
|
||||||
|
|
||||||
|
localparam UART_STATE_IDLE = 2'b00;
|
||||||
|
localparam UART_STATE_START = 2'b01;
|
||||||
|
localparam UART_STATE_RUN = 2'b10;
|
||||||
|
localparam UART_STATE_END = 2'b11;
|
||||||
|
|
||||||
|
|
||||||
|
// [0]: tx enbale
|
||||||
|
// [1]: rx enbale
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] _uart_cr;
|
||||||
|
|
||||||
|
// [0]: tx flag
|
||||||
|
// [1]: rx flag
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] _uart_sr;
|
||||||
|
|
||||||
|
// [31:0] : baud
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] _uart_baud;
|
||||||
|
|
||||||
|
// [31:0] : rx data
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] _uart_rxd;
|
||||||
|
|
||||||
|
// [31:0] : tx data
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] _uart_txd;
|
||||||
|
|
||||||
|
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] uart_tx_clk_cycle;
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] uart_rx_clk_cycle;
|
||||||
|
wire [`DATA_BUS_WIDTH-1:0] uart_rx_clk_cycle_d2;
|
||||||
|
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] uart_tx_clk_cnt;
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] uart_rx_clk_cnt;
|
||||||
|
|
||||||
|
wire uart_tx_clk_timeup;
|
||||||
|
wire uart_rx_clk_timeup;
|
||||||
|
|
||||||
|
// stop=1 datah...datal start=0 10bit=1
|
||||||
|
|
||||||
|
reg [19:0] uart_tx_pipe;
|
||||||
|
reg [7:0] uart_rx_pipe;
|
||||||
|
|
||||||
|
reg [1:0] uart_tx_state;
|
||||||
|
reg [1:0] uart_rx_state;
|
||||||
|
|
||||||
|
assign uart_tx_clk_cycle[`DATA_BUS_WIDTH-1:0] = (`CORE_FREQ_HZ / `UART_BAUD);
|
||||||
|
assign uart_rx_clk_cycle[`DATA_BUS_WIDTH-1:0] = (`CORE_FREQ_HZ / `UART_BAUD);
|
||||||
|
assign uart_rx_clk_cycle_d2[`DATA_BUS_WIDTH-1:0] = (`CORE_FREQ_HZ / `UART_BAUD) / 2;
|
||||||
|
|
||||||
|
assign uart_tx_clk_timeup = (uart_tx_clk_cnt == uart_tx_clk_cycle[31:0]);
|
||||||
|
|
||||||
|
assign uart_rx_clk_timeup = (uart_rx_state[1:0] == UART_STATE_START) ? (uart_rx_clk_cnt == uart_rx_clk_cycle_d2[31:0])
|
||||||
|
: (uart_rx_clk_cnt == uart_rx_clk_cycle[31:0] );
|
||||||
|
|
||||||
|
// uart tx pipeline
|
||||||
|
|
||||||
|
always @ (posedge clk_i or negedge rst_n_i) begin
|
||||||
|
if (!rst_n_i) begin
|
||||||
|
uart_tx_clk_cnt <= `ZERO_WORD;
|
||||||
|
end
|
||||||
|
else if (uart_tx_state[1:0] == UART_STATE_IDLE) begin
|
||||||
|
uart_tx_clk_cnt <= `ZERO_WORD;
|
||||||
|
end
|
||||||
|
else if (uart_tx_clk_timeup) begin
|
||||||
|
uart_tx_clk_cnt <= `ZERO_WORD;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
uart_tx_clk_cnt <= uart_tx_clk_cnt + 32'h1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
reg uart_tx_start;
|
||||||
|
|
||||||
|
always @ (posedge clk_i or negedge rst_n_i) begin
|
||||||
|
if (!rst_n_i) begin
|
||||||
|
uart_tx_start <= `INVALID;
|
||||||
|
end
|
||||||
|
else if (_uart_cr[0] && (addr_i[7:0] == UART_REG_TXD) && data_we_i) begin
|
||||||
|
uart_tx_start <= `VALID;
|
||||||
|
end
|
||||||
|
else if (uart_tx_state[1:0] == UART_STATE_START) begin
|
||||||
|
uart_tx_start <= `INVALID;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always @ (posedge clk_i or negedge rst_n_i) begin
|
||||||
|
if (!rst_n_i) begin
|
||||||
|
uart_tx_state[1:0] <= UART_STATE_IDLE;
|
||||||
|
end
|
||||||
|
else if (uart_tx_start) begin
|
||||||
|
uart_tx_state[1:0] <= UART_STATE_START;
|
||||||
|
end
|
||||||
|
else if (uart_tx_clk_timeup) begin
|
||||||
|
if (uart_tx_state[1:0] == UART_STATE_START) begin
|
||||||
|
uart_tx_state[1:0] <= UART_STATE_RUN;
|
||||||
|
end
|
||||||
|
else if (uart_tx_state[1:0] == UART_STATE_RUN) begin
|
||||||
|
if (!uart_tx_pipe[0]) begin
|
||||||
|
uart_tx_state[1:0] <= UART_STATE_END;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else if (uart_tx_state[1:0] == UART_STATE_END) begin
|
||||||
|
uart_tx_state[1:0] <= UART_STATE_IDLE;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always @ (posedge clk_i or negedge rst_n_i) begin
|
||||||
|
if (!rst_n_i) begin
|
||||||
|
uart_tx_pipe[19:0] <= 20'hf_ffff;
|
||||||
|
end
|
||||||
|
else if (uart_tx_clk_timeup) begin
|
||||||
|
if (_uart_cr[0]) begin
|
||||||
|
case (uart_tx_state[1:0])
|
||||||
|
UART_STATE_IDLE : uart_tx_pipe[19:0] <= {20'hf_ffff};
|
||||||
|
UART_STATE_START : uart_tx_pipe[19:0] <= {1'b1, _uart_txd[7:0], 1'b0, 10'h3ff};
|
||||||
|
UART_STATE_RUN : uart_tx_pipe[19:0] <= {1'b1, uart_tx_pipe[19:1]};
|
||||||
|
UART_STATE_END : uart_tx_pipe[19:0] <= {20'hf_ffff};
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assign pad_txd = uart_tx_pipe[10];
|
||||||
|
|
||||||
|
// uart rx pipeline
|
||||||
|
|
||||||
|
always @ (posedge clk_i or negedge rst_n_i) begin
|
||||||
|
if (!rst_n_i) begin
|
||||||
|
uart_rx_clk_cnt <= `ZERO_WORD;
|
||||||
|
end
|
||||||
|
else if (uart_rx_state[1:0] == UART_STATE_IDLE) begin
|
||||||
|
uart_rx_clk_cnt <= `ZERO_WORD;
|
||||||
|
end
|
||||||
|
else if (uart_rx_clk_timeup) begin
|
||||||
|
uart_rx_clk_cnt <= `ZERO_WORD;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
uart_rx_clk_cnt <= uart_rx_clk_cnt + 32'h1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always @ (posedge clk_i or negedge rst_n_i) begin
|
||||||
|
if (!rst_n_i) begin
|
||||||
|
uart_rx_state[1:0] <= UART_STATE_IDLE;
|
||||||
|
end
|
||||||
|
else if (uart_rx_state[1:0] == UART_STATE_IDLE) begin
|
||||||
|
if (!pad_rxd) begin
|
||||||
|
uart_rx_state[1:0] <= UART_STATE_START;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else if (uart_rx_state[1:0] == UART_STATE_START) begin
|
||||||
|
if (!pad_rxd && uart_rx_clk_timeup) begin
|
||||||
|
uart_rx_state[1:0] <= UART_STATE_RUN;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else if (uart_rx_clk_timeup) begin
|
||||||
|
if (uart_rx_state[1:0] == UART_STATE_RUN) begin
|
||||||
|
if (!uart_rx_pipe[0]) begin
|
||||||
|
uart_rx_state[1:0] <= UART_STATE_END;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else if (uart_rx_state[1:0] == UART_STATE_END) begin
|
||||||
|
uart_rx_state[1:0] <= UART_STATE_IDLE;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always @ (posedge clk_i or negedge rst_n_i) begin
|
||||||
|
if (!rst_n_i) begin
|
||||||
|
uart_rx_pipe[7:0] <= 8'hff;
|
||||||
|
end
|
||||||
|
else if (_uart_cr[1]) begin
|
||||||
|
if (uart_rx_clk_timeup) begin
|
||||||
|
case (uart_rx_state[1:0])
|
||||||
|
UART_STATE_IDLE : uart_rx_pipe[7:0] <= {8'hff};
|
||||||
|
UART_STATE_START : uart_rx_pipe[7:0] <= {pad_rxd, uart_rx_pipe[7:1]};
|
||||||
|
UART_STATE_RUN : uart_rx_pipe[7:0] <= {pad_rxd, uart_rx_pipe[7:1]};
|
||||||
|
UART_STATE_END : uart_rx_pipe[7:0] <= {8'hff};
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
wire uart_tx_idle;
|
||||||
|
wire uart_rx_idle;
|
||||||
|
|
||||||
|
assign uart_tx_idle = (uart_tx_state[1:0] == UART_STATE_IDLE);
|
||||||
|
assign uart_rx_idle = (uart_rx_state[1:0] == UART_STATE_IDLE);
|
||||||
|
|
||||||
|
wire uart_tx_idle_1r;
|
||||||
|
pa_dff_rst_0 #(1) dff_uart_tx_idle_1r (clk_i, rst_n_i, `VALID, uart_tx_idle, uart_tx_idle_1r);
|
||||||
|
|
||||||
|
wire uart_rx_idle_1r;
|
||||||
|
pa_dff_rst_0 #(1) dff_uart_rx_idle_1r (clk_i, rst_n_i, `VALID, uart_rx_idle, uart_rx_idle_1r);
|
||||||
|
|
||||||
|
always @ (posedge clk_i or negedge rst_n_i) begin
|
||||||
|
if (!rst_n_i) begin
|
||||||
|
_uart_cr <= 32'h0000_0003; // enable uart rx/tx default
|
||||||
|
_uart_sr <= 32'h0000_0000;
|
||||||
|
_uart_baud <= `UART_BAUD; // read-only
|
||||||
|
_uart_rxd <= 32'hffff_ffff; // default high level
|
||||||
|
_uart_txd <= 32'hffff_ffff; // default high level
|
||||||
|
end
|
||||||
|
else if (_uart_cr[0] && (uart_tx_state[1:0] == UART_STATE_END)) begin
|
||||||
|
if (UART_REG_SR == addr_i[7:0]) begin
|
||||||
|
_uart_sr <= {data_i[31:2], (_uart_sr[1] & ~data_i[1]), 1'b1};
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
_uart_sr <= {_uart_sr[31:1], 1'b1};
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else if (_uart_cr[1] && (uart_rx_state[1:0] == UART_STATE_END)) begin
|
||||||
|
if (UART_REG_SR == addr_i[7:0]) begin
|
||||||
|
_uart_sr <= {data_i[31:2], 1'b1, (_uart_sr[0] & ~data_i[0])};
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
_uart_sr <= {_uart_sr[31:2], 1'b1, _uart_sr[0]};
|
||||||
|
end
|
||||||
|
_uart_rxd <= {24'b0, uart_rx_pipe[7:0]};
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
if (data_we_i) begin
|
||||||
|
case (addr_i[7:0])
|
||||||
|
UART_REG_CR : _uart_cr <= {data_i[31:0]};
|
||||||
|
UART_REG_SR : _uart_sr <= {data_i[31:2], (_uart_sr[1] & ~data_i[1]), (_uart_sr[0] & ~data_i[0])};
|
||||||
|
UART_REG_TXD : _uart_txd <= {24'b0, data_i[7:0]};
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
reg [`DATA_BUS_WIDTH-1:0] _data = `ZERO_WORD;
|
||||||
|
|
||||||
|
always @ (posedge clk_i) begin
|
||||||
|
if (data_rd_i) begin
|
||||||
|
case (addr_i[7:0])
|
||||||
|
UART_REG_CR : _data <= {_uart_cr[31:0]};
|
||||||
|
UART_REG_SR : _data <= {_uart_sr[31:2], (uart_rx_idle_1r & _uart_sr[1]), (uart_tx_idle_1r & _uart_sr[0])};
|
||||||
|
UART_REG_BAUD : _data <= {_uart_baud[31:0]};
|
||||||
|
UART_REG_RXD : _data <= {24'b0, _uart_rxd[7:0]};
|
||||||
|
UART_REG_TXD : _data <= {24'b0, _uart_txd[7:0]};
|
||||||
|
default : _data <= {32'h0000_0000};
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assign data_o[`DATA_BUS_WIDTH-1:0] = _data[`DATA_BUS_WIDTH-1:0];
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,114 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021, SERI Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2021-10-29 Lyons first version
|
||||||
|
* 2022-04-04 Lyons v2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
`ifdef TESTBENCH_VCS
|
||||||
|
`include "pa_chip_param.v"
|
||||||
|
`else
|
||||||
|
`include "../pa_chip_param.v"
|
||||||
|
`endif
|
||||||
|
|
||||||
|
module pa_soc_rbm (
|
||||||
|
input wire [`ADDR_BUS_WIDTH-1:0] m_addr_i,
|
||||||
|
output reg [`DATA_BUS_WIDTH-1:0] m_data_o,
|
||||||
|
input wire m_we_i,
|
||||||
|
input wire m_rd_i,
|
||||||
|
|
||||||
|
input wire [`DATA_BUS_WIDTH-1:0] s0_data_i,
|
||||||
|
output reg s0_we_o,
|
||||||
|
output reg s0_rd_o,
|
||||||
|
|
||||||
|
input wire [`DATA_BUS_WIDTH-1:0] s1_data_i,
|
||||||
|
output reg s1_we_o,
|
||||||
|
output reg s1_rd_o,
|
||||||
|
|
||||||
|
input wire [`DATA_BUS_WIDTH-1:0] s2_data_i,
|
||||||
|
output reg s2_we_o,
|
||||||
|
output reg s2_rd_o,
|
||||||
|
|
||||||
|
input wire [`DATA_BUS_WIDTH-1:0] s3_data_i,
|
||||||
|
output reg s3_we_o,
|
||||||
|
output reg s3_rd_o,
|
||||||
|
|
||||||
|
input wire [`DATA_BUS_WIDTH-1:0] s4_data_i,
|
||||||
|
output reg s4_we_o,
|
||||||
|
output reg s4_rd_o,
|
||||||
|
|
||||||
|
input wire [`DATA_BUS_WIDTH-1:0] s5_data_i,
|
||||||
|
output reg s5_we_o,
|
||||||
|
output reg s5_rd_o,
|
||||||
|
|
||||||
|
input wire [`DATA_BUS_WIDTH-1:0] s6_data_i,
|
||||||
|
output reg s6_we_o,
|
||||||
|
output reg s6_rd_o
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
localparam SLAVE_0_ADDR = 4'b0000; // rom 0x0000_0000 ~ 0x0fff_ffff
|
||||||
|
localparam SLAVE_1_ADDR = 4'b0001; // ram 0x1000_0000 ~ 0x1fff_ffff
|
||||||
|
localparam SLAVE_2_ADDR = 4'b0010; // timer 0x2000_0000 ~ 0x2fff_ffff
|
||||||
|
localparam SLAVE_3_ADDR = 4'b0011; // uart 0x3000_0000 ~ 0x3fff_ffff
|
||||||
|
localparam SLAVE_4_ADDR = 4'b0100; // i2c 0x4000_0000 ~ 0x4fff_ffff
|
||||||
|
localparam SLAVE_5_ADDR = 4'b0101; // spi 0x5000_0000 ~ 0x5fff_ffff
|
||||||
|
localparam SLAVE_6_ADDR = 4'b0110; // lcd 0x6000_0000 ~ 0x6fff_ffff
|
||||||
|
|
||||||
|
|
||||||
|
always @ (*) begin
|
||||||
|
case (m_addr_i[31:28])
|
||||||
|
SLAVE_0_ADDR : m_data_o[`DATA_BUS_WIDTH-1:0] = s0_data_i[`DATA_BUS_WIDTH-1:0];
|
||||||
|
SLAVE_1_ADDR : m_data_o[`DATA_BUS_WIDTH-1:0] = s1_data_i[`DATA_BUS_WIDTH-1:0];
|
||||||
|
SLAVE_2_ADDR : m_data_o[`DATA_BUS_WIDTH-1:0] = s2_data_i[`DATA_BUS_WIDTH-1:0];
|
||||||
|
SLAVE_3_ADDR : m_data_o[`DATA_BUS_WIDTH-1:0] = s3_data_i[`DATA_BUS_WIDTH-1:0];
|
||||||
|
SLAVE_4_ADDR : m_data_o[`DATA_BUS_WIDTH-1:0] = s4_data_i[`DATA_BUS_WIDTH-1:0];
|
||||||
|
SLAVE_5_ADDR : m_data_o[`DATA_BUS_WIDTH-1:0] = s5_data_i[`DATA_BUS_WIDTH-1:0];
|
||||||
|
SLAVE_6_ADDR : m_data_o[`DATA_BUS_WIDTH-1:0] = s6_data_i[`DATA_BUS_WIDTH-1:0];
|
||||||
|
default : m_data_o[`DATA_BUS_WIDTH-1:0] = `ZERO_WORD;
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
always @ (*) begin
|
||||||
|
s0_we_o = `INVALID;
|
||||||
|
s1_we_o = `INVALID;
|
||||||
|
s2_we_o = `INVALID;
|
||||||
|
s3_we_o = `INVALID;
|
||||||
|
s4_we_o = `INVALID;
|
||||||
|
s5_we_o = `INVALID;
|
||||||
|
s6_we_o = `INVALID;
|
||||||
|
case (m_addr_i[31:28])
|
||||||
|
SLAVE_0_ADDR : s0_we_o = m_we_i;
|
||||||
|
SLAVE_1_ADDR : s1_we_o = m_we_i;
|
||||||
|
SLAVE_2_ADDR : s2_we_o = m_we_i;
|
||||||
|
SLAVE_3_ADDR : s3_we_o = m_we_i;
|
||||||
|
SLAVE_4_ADDR : s4_we_o = m_we_i;
|
||||||
|
SLAVE_5_ADDR : s5_we_o = m_we_i;
|
||||||
|
SLAVE_6_ADDR : s6_we_o = m_we_i;
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
always @ (*) begin
|
||||||
|
s0_rd_o = `INVALID;
|
||||||
|
s1_rd_o = `INVALID;
|
||||||
|
s2_rd_o = `INVALID;
|
||||||
|
s3_rd_o = `INVALID;
|
||||||
|
s4_rd_o = `INVALID;
|
||||||
|
s5_rd_o = `INVALID;
|
||||||
|
s6_rd_o = `INVALID;
|
||||||
|
case (m_addr_i[31:28])
|
||||||
|
SLAVE_0_ADDR : s0_rd_o = m_rd_i;
|
||||||
|
SLAVE_1_ADDR : s1_rd_o = m_rd_i;
|
||||||
|
SLAVE_2_ADDR : s2_rd_o = m_rd_i;
|
||||||
|
SLAVE_3_ADDR : s3_rd_o = m_rd_i;
|
||||||
|
SLAVE_4_ADDR : s4_rd_o = m_rd_i;
|
||||||
|
SLAVE_5_ADDR : s5_rd_o = m_rd_i;
|
||||||
|
SLAVE_6_ADDR : s6_rd_o = m_rd_i;
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,153 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021, SERI Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2023-06-05 Lyons first version
|
||||||
|
* 2023-06-13 Lyons add comments
|
||||||
|
*/
|
||||||
|
|
||||||
|
`ifdef TESTBENCH_VCS
|
||||||
|
`include "pa_chip_param.v"
|
||||||
|
`else
|
||||||
|
`include "../pa_chip_param.v"
|
||||||
|
`endif
|
||||||
|
|
||||||
|
// dff, set 'def_val' when 'reset' is valid, update when 'enable' is valid
|
||||||
|
|
||||||
|
module pa_dff_rst_def #(
|
||||||
|
parameter DW = 32
|
||||||
|
)(
|
||||||
|
input wire clk_i,
|
||||||
|
input wire rst_n_i,
|
||||||
|
|
||||||
|
input wire [DW-1:0] def_val,
|
||||||
|
|
||||||
|
input wire en,
|
||||||
|
input wire [DW-1:0] din,
|
||||||
|
|
||||||
|
output wire [DW-1:0] qout
|
||||||
|
);
|
||||||
|
|
||||||
|
reg [DW-1:0] qout_r;
|
||||||
|
|
||||||
|
always @ (posedge clk_i or negedge rst_n_i) begin
|
||||||
|
if (!rst_n_i) begin
|
||||||
|
qout_r[DW-1:0] <= def_val[DW-1:0];
|
||||||
|
end
|
||||||
|
else if (en) begin
|
||||||
|
qout_r[DW-1:0] <= din[DW-1:0];
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
qout_r[DW-1:0] <= qout_r[DW-1:0];
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assign qout[DW-1:0] = qout_r[DW-1:0];
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
|
||||||
|
// dff, set '0' when 'reset' is valid, update when 'enable' is valid
|
||||||
|
|
||||||
|
module pa_dff_rst_0 #(
|
||||||
|
parameter DW = 32
|
||||||
|
)(
|
||||||
|
input wire clk_i,
|
||||||
|
input wire rst_n_i,
|
||||||
|
|
||||||
|
input wire en,
|
||||||
|
input wire [DW-1:0] din,
|
||||||
|
|
||||||
|
output wire [DW-1:0] qout
|
||||||
|
);
|
||||||
|
|
||||||
|
pa_dff_rst_def #(DW) _dff (clk_i, rst_n_i, {DW{1'b0}}, en, din, qout);
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
|
||||||
|
// dff, set '1' when 'reset' is valid, update when 'enable' is valid
|
||||||
|
|
||||||
|
module pa_dff_rst_1 #(
|
||||||
|
parameter DW = 32
|
||||||
|
)(
|
||||||
|
input wire clk_i,
|
||||||
|
input wire rst_n_i,
|
||||||
|
|
||||||
|
input wire en,
|
||||||
|
input wire [DW-1:0] din,
|
||||||
|
|
||||||
|
output wire [DW-1:0] qout
|
||||||
|
);
|
||||||
|
|
||||||
|
pa_dff_rst_def #(DW) _dff (clk_i, rst_n_i, {DW{1'b1}}, en, din, qout);
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
|
||||||
|
// dff, update when 'enable' is valid, lock when it is invalid
|
||||||
|
module pa_dff_en_l #(
|
||||||
|
parameter DW = 32
|
||||||
|
)(
|
||||||
|
input wire clk_i,
|
||||||
|
input wire rst_n_i,
|
||||||
|
|
||||||
|
input wire en,
|
||||||
|
input wire [DW-1:0] din,
|
||||||
|
|
||||||
|
output wire [DW-1:0] qout
|
||||||
|
);
|
||||||
|
|
||||||
|
reg [DW-1:0] qout_r;
|
||||||
|
|
||||||
|
always @ (posedge clk_i or negedge rst_n_i) begin
|
||||||
|
if (!rst_n_i) begin
|
||||||
|
qout_r[DW-1:0] <= 0;
|
||||||
|
end
|
||||||
|
else if (en) begin
|
||||||
|
qout_r[DW-1:0] <= din[DW-1:0];
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
qout_r[DW-1:0] <= qout_r[DW-1:0];
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assign qout[DW-1:0] = qout_r[DW-1:0];
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
|
||||||
|
// dff, update when 'enable' is valid
|
||||||
|
module pa_dff_en_2 #(
|
||||||
|
parameter DW = 32
|
||||||
|
)(
|
||||||
|
input wire clk_i,
|
||||||
|
input wire rst_n_i,
|
||||||
|
|
||||||
|
input wire en,
|
||||||
|
input wire [DW-1:0] din1,
|
||||||
|
input wire [DW-1:0] din2,
|
||||||
|
|
||||||
|
output wire [DW-1:0] qout
|
||||||
|
);
|
||||||
|
|
||||||
|
reg [DW-1:0] qout_r;
|
||||||
|
|
||||||
|
always @ (posedge clk_i or negedge rst_n_i) begin
|
||||||
|
if (!rst_n_i) begin
|
||||||
|
qout_r[DW-1:0] <= 0;
|
||||||
|
end
|
||||||
|
else if (en) begin
|
||||||
|
qout_r[DW-1:0] <= din1[DW-1:0];
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
qout_r[DW-1:0] <= din2[DW-1:0];
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assign qout[DW-1:0] = qout_r[DW-1:0];
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,14 @@
|
||||||
|
#.gitignore
|
||||||
|
|
||||||
|
# Step-1, track all files in the current folder
|
||||||
|
!*
|
||||||
|
|
||||||
|
# Step-2, track specified files in the current folder
|
||||||
|
*
|
||||||
|
!*/
|
||||||
|
!.gitignore
|
||||||
|
!*.SchDoc
|
||||||
|
!*.PcbDoc
|
||||||
|
|
||||||
|
# Step-3, untrack all in sub folders, which use their own .gitignore
|
||||||
|
*/*
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,13 @@
|
||||||
|
#.gitignore
|
||||||
|
|
||||||
|
# Step-1, track all files in the current folder
|
||||||
|
!*
|
||||||
|
|
||||||
|
# Step-2, track specified files in the current folder
|
||||||
|
*
|
||||||
|
!*/
|
||||||
|
!.gitignore
|
||||||
|
!*.exe
|
||||||
|
|
||||||
|
# Step-3, untrack all in sub folders, which use their own .gitignore
|
||||||
|
*/*
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,16 @@
|
||||||
|
#.gitignore
|
||||||
|
|
||||||
|
# Step-1, track all files in the current folder
|
||||||
|
!*
|
||||||
|
|
||||||
|
# Step-2, track specified files in the current folder
|
||||||
|
*
|
||||||
|
!*/
|
||||||
|
!.gitignore
|
||||||
|
!*.py
|
||||||
|
!*.ico
|
||||||
|
!*.bat
|
||||||
|
!*.exe
|
||||||
|
|
||||||
|
# Step-3, untrack all in sub folders, which use their own .gitignore
|
||||||
|
*/*
|
Binary file not shown.
|
@ -0,0 +1,486 @@
|
||||||
|
#coding=utf-8
|
||||||
|
|
||||||
|
# Name: debugger
|
||||||
|
# Date: 12:26 2024/1/8
|
||||||
|
# Note:
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import glob
|
||||||
|
import time
|
||||||
|
import msvcrt
|
||||||
|
import queue
|
||||||
|
import threading
|
||||||
|
|
||||||
|
import winreg
|
||||||
|
import win32api
|
||||||
|
import win32gui
|
||||||
|
from win32con import WM_INPUTLANGCHANGEREQUEST
|
||||||
|
|
||||||
|
import mysys
|
||||||
|
import myserial
|
||||||
|
import myconvert
|
||||||
|
|
||||||
|
## size of shell cmd buffer
|
||||||
|
|
||||||
|
SHELL_CMD_SIZE = 128
|
||||||
|
|
||||||
|
## size of download package
|
||||||
|
|
||||||
|
DOWNLOAD_PKG_SIZE = 64
|
||||||
|
|
||||||
|
## number of serial ports while scan
|
||||||
|
|
||||||
|
SERIAL_PORT_NUM = 30
|
||||||
|
|
||||||
|
## baudrate of serial port
|
||||||
|
|
||||||
|
SERIAL_BAUDRATE = 115200
|
||||||
|
|
||||||
|
## valid value of 'shell_stat'
|
||||||
|
|
||||||
|
STAT_WAIT_SPEC_KEY = 0
|
||||||
|
STAT_WAIT_FUNC_KEY = 1
|
||||||
|
|
||||||
|
## valid value of 'shell_mode'
|
||||||
|
|
||||||
|
MODE_MAX = 2
|
||||||
|
|
||||||
|
MODE_NORMAL = 0
|
||||||
|
MODE_CONTROL = 1
|
||||||
|
|
||||||
|
'''
|
||||||
|
debugger.py
|
||||||
|
'''
|
||||||
|
|
||||||
|
welcome_info = """This is a PuSH Terminal.
|
||||||
|
Type 'help' for more information.
|
||||||
|
"""
|
||||||
|
|
||||||
|
help_info = """Command:
|
||||||
|
----------------------------------------
|
||||||
|
~ - Switch mode.
|
||||||
|
quit - (q) Quit terminal.
|
||||||
|
repeat - (r) Repeat last command.
|
||||||
|
help - (h) Show help menu.
|
||||||
|
cd - Switch to work path.
|
||||||
|
load - (ld) Load file.
|
||||||
|
download - (d) Download to target device.
|
||||||
|
go - (g) Control target device jump and run.
|
||||||
|
com - Scan valid serial port.
|
||||||
|
com* - Open target serial port.
|
||||||
|
"""
|
||||||
|
|
||||||
|
example_info = """Example:
|
||||||
|
----------------------------------------
|
||||||
|
1. download & run
|
||||||
|
1) switch to control mode
|
||||||
|
2) ld > com > com* > [hardware reset] > [ESC] > d
|
||||||
|
2. go without download
|
||||||
|
1) switch to control mode
|
||||||
|
2) [hardware reset] > g
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class GlobalParam:
|
||||||
|
exitFlag = False
|
||||||
|
|
||||||
|
workPath = None
|
||||||
|
|
||||||
|
binFile = None
|
||||||
|
binData = None
|
||||||
|
binSize = 0
|
||||||
|
|
||||||
|
workQueue = None
|
||||||
|
queueLock = None
|
||||||
|
|
||||||
|
currentSerial = None
|
||||||
|
lastSerial = None
|
||||||
|
|
||||||
|
threadInput = None
|
||||||
|
threadOutput = None
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.workQueue = queue.Queue(SHELL_CMD_SIZE)
|
||||||
|
self.queueLock = threading.Lock()
|
||||||
|
|
||||||
|
def serial_check(self):
|
||||||
|
if self.currentSerial != None or self.lastSerial != None:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def get_desktop_path(self):
|
||||||
|
key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, r'Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders')
|
||||||
|
return winreg.QueryValueEx(key, 'Desktop')[0]
|
||||||
|
|
||||||
|
def get_work_path(self):
|
||||||
|
return r'..\..'
|
||||||
|
|
||||||
|
def cleanup(self):
|
||||||
|
while self.serial_check():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class NewThread (threading.Thread):
|
||||||
|
def __init__(self, *args, **keywords):
|
||||||
|
threading.Thread.__init__(self, *args, **keywords)
|
||||||
|
self.killed = False
|
||||||
|
|
||||||
|
def start(self):
|
||||||
|
self.__run_backup = self.run
|
||||||
|
self.run = self.__run
|
||||||
|
threading.Thread.start(self)
|
||||||
|
|
||||||
|
def __run(self):
|
||||||
|
sys.settrace(self.globaltrace)
|
||||||
|
self.__run_backup()
|
||||||
|
self.run = self.__run_backup
|
||||||
|
|
||||||
|
def globaltrace(self, frame, event, arg):
|
||||||
|
if event == 'call':
|
||||||
|
return self.localtrace
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
def localtrace(self, frame, event, arg):
|
||||||
|
if self.killed:
|
||||||
|
if event == 'line':
|
||||||
|
raise SystemExit()
|
||||||
|
return self.localtrace
|
||||||
|
|
||||||
|
def kill(self):
|
||||||
|
self.killed = True
|
||||||
|
|
||||||
|
class Shell:
|
||||||
|
shell_trig = False
|
||||||
|
shell_mode = MODE_CONTROL
|
||||||
|
shell_stat = STAT_WAIT_SPEC_KEY
|
||||||
|
shell_line = None
|
||||||
|
shell_line_curpos = 0
|
||||||
|
|
||||||
|
def __init__(self, cmdsize):
|
||||||
|
self.shell_line = [0]*cmdsize
|
||||||
|
|
||||||
|
def output(self, ser, ch, redirect=True):
|
||||||
|
## handle control key
|
||||||
|
if self.shell_stat == STAT_WAIT_SPEC_KEY and ch == 0xe0:
|
||||||
|
self.shell_stat = STAT_WAIT_FUNC_KEY
|
||||||
|
return
|
||||||
|
elif self.shell_stat == STAT_WAIT_FUNC_KEY:
|
||||||
|
self.shell_stat = STAT_WAIT_SPEC_KEY
|
||||||
|
return
|
||||||
|
|
||||||
|
## handle tab key
|
||||||
|
if ch == ord('\t'):
|
||||||
|
return
|
||||||
|
## handle backspace key
|
||||||
|
elif ch == 0x08 or ch == 0x7f:
|
||||||
|
if self.shell_line_curpos == 0:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
self.shell_line_curpos = self.shell_line_curpos - 1
|
||||||
|
self.shell_line[self.shell_line_curpos] = 0
|
||||||
|
_xputs(ser, "\b \b")
|
||||||
|
return
|
||||||
|
## handle enter key
|
||||||
|
elif ch == ord('\r'):
|
||||||
|
if redirect:
|
||||||
|
_xputs(ser, "\n")
|
||||||
|
return
|
||||||
|
|
||||||
|
## handle normal character
|
||||||
|
self.shell_line[self.shell_line_curpos] = ch
|
||||||
|
_xputs(ser, chr(ch))
|
||||||
|
|
||||||
|
## handle overwrite
|
||||||
|
self.shell_line_curpos = self.shell_line_curpos + 1
|
||||||
|
if self.shell_line_curpos >= SHELL_CMD_SIZE:
|
||||||
|
self.shell_line_curpos = 0
|
||||||
|
|
||||||
|
|
||||||
|
def _is_equal(v1, v2):
|
||||||
|
rslt = False
|
||||||
|
if type(v2) != type(list()):
|
||||||
|
rslt = mysys._is_equal(v1, v2)
|
||||||
|
else:
|
||||||
|
for v in v2:
|
||||||
|
if mysys._is_equal(v1, v):
|
||||||
|
rslt = True
|
||||||
|
break
|
||||||
|
return rslt
|
||||||
|
|
||||||
|
def _xputs(ser, info):
|
||||||
|
if ser == None:
|
||||||
|
mysys._xputs(info)
|
||||||
|
else:
|
||||||
|
for ch in info:
|
||||||
|
myserial.WriteData(ser, myconvert.ToHexStr([ord(ch),]))
|
||||||
|
|
||||||
|
def _tostr(data):
|
||||||
|
return "".join(chr(i) for i in data).lower()
|
||||||
|
|
||||||
|
|
||||||
|
def serial_thread(port):
|
||||||
|
global globalParam
|
||||||
|
|
||||||
|
ser = myserial.OpenPort(port, baud_rate=SERIAL_BAUDRATE)
|
||||||
|
globalParam.currentSerial = ser
|
||||||
|
globalParam.lastSerial = ser
|
||||||
|
|
||||||
|
shell = Shell(SHELL_CMD_SIZE)
|
||||||
|
|
||||||
|
try:
|
||||||
|
while not globalParam.exitFlag:
|
||||||
|
(state, length, data) = myserial.ReadData(ser)
|
||||||
|
if not state:
|
||||||
|
break
|
||||||
|
if length > 0:
|
||||||
|
for ch in data:
|
||||||
|
shell.output(None, ch, False)
|
||||||
|
else:
|
||||||
|
time.sleep(0.02)
|
||||||
|
finally:
|
||||||
|
myserial.ClosePort(ser)
|
||||||
|
globalParam.currentSerial = None
|
||||||
|
globalParam.lastSerial = None
|
||||||
|
|
||||||
|
def input_thread():
|
||||||
|
global globalParam
|
||||||
|
|
||||||
|
while not globalParam.exitFlag:
|
||||||
|
if msvcrt.kbhit():
|
||||||
|
globalParam.queueLock.acquire()
|
||||||
|
if not globalParam.workQueue.full():
|
||||||
|
globalParam.workQueue.put( msvcrt.getch() )
|
||||||
|
globalParam.queueLock.release()
|
||||||
|
time.sleep(0.02)
|
||||||
|
|
||||||
|
def output_thread():
|
||||||
|
global globalParam
|
||||||
|
|
||||||
|
## searh serial ports but not show them
|
||||||
|
serial_ports = myserial.SearchPort(SERIAL_PORT_NUM)
|
||||||
|
|
||||||
|
## only one serial thread is allowed to be created
|
||||||
|
tserial = None
|
||||||
|
|
||||||
|
## save the last command
|
||||||
|
last_cmd_line = "help"
|
||||||
|
|
||||||
|
## create shell and work on control mode
|
||||||
|
shell = Shell(SHELL_CMD_SIZE)
|
||||||
|
_xputs(None, ":")
|
||||||
|
|
||||||
|
while not globalParam.exitFlag:
|
||||||
|
## try to get one character
|
||||||
|
if not shell.shell_trig:
|
||||||
|
globalParam.queueLock.acquire()
|
||||||
|
ch = -1
|
||||||
|
if not globalParam.workQueue.empty():
|
||||||
|
ch = int.from_bytes(globalParam.workQueue.get(), byteorder='big')
|
||||||
|
globalParam.queueLock.release()
|
||||||
|
|
||||||
|
if ch < 0:
|
||||||
|
time.sleep(0.02)
|
||||||
|
continue
|
||||||
|
|
||||||
|
## handle esc key
|
||||||
|
if shell.shell_trig or ch == 0x1b:
|
||||||
|
shell.shell_trig = False
|
||||||
|
shell.shell_line_curpos = 0
|
||||||
|
shell.shell_mode = (shell.shell_mode + 1) % MODE_MAX
|
||||||
|
if shell.shell_mode == MODE_NORMAL:
|
||||||
|
_xputs(None, "enter normal mode ...\n")
|
||||||
|
if globalParam.serial_check():
|
||||||
|
_xputs(None, "serial port is alive.\n")
|
||||||
|
globalParam.currentSerial = globalParam.lastSerial
|
||||||
|
if shell.shell_mode == MODE_CONTROL:
|
||||||
|
_xputs(None, ":")
|
||||||
|
globalParam.currentSerial = None
|
||||||
|
continue
|
||||||
|
|
||||||
|
if shell.shell_mode == MODE_CONTROL:
|
||||||
|
if ch == ord('\r') or ch == ord('\n'):
|
||||||
|
cmd_line = _tostr(shell.shell_line[:shell.shell_line_curpos])
|
||||||
|
shell.shell_line_curpos = 0
|
||||||
|
## USER COMMAND PARSE AND EXECUTE BEGIN
|
||||||
|
if _is_equal(cmd_line, ['quit', 'q']):
|
||||||
|
_xputs(None, "\n")
|
||||||
|
if globalParam.serial_check():
|
||||||
|
tserial.kill()
|
||||||
|
tserial.join()
|
||||||
|
globalParam.exitFlag = True
|
||||||
|
continue
|
||||||
|
|
||||||
|
if _is_equal(cmd_line, ['repeat', 'r']):
|
||||||
|
_xputs(None, ":" + last_cmd_line)
|
||||||
|
cmd_line = last_cmd_line
|
||||||
|
|
||||||
|
last_cmd_line = cmd_line
|
||||||
|
_xputs(None, "\n")
|
||||||
|
|
||||||
|
if _is_equal(cmd_line, ['help', 'h']):
|
||||||
|
_xputs(None, help_info + "\n")
|
||||||
|
_xputs(None, example_info + "\n")
|
||||||
|
pass
|
||||||
|
|
||||||
|
if _is_equal(cmd_line.split(' ')[0], 'cd'):
|
||||||
|
globalParam.workPath = globalParam.get_desktop_path()
|
||||||
|
flist = glob.glob(globalParam.workPath + '\\*.bin')
|
||||||
|
_xputs(None, "work path: " + globalParam.workPath + "\n")
|
||||||
|
_xputs(None, "find {0} valid file: ".format(len(flist)) + "\n")
|
||||||
|
for file in flist:
|
||||||
|
_xputs(None, file.split('\\')[-1] + "\n")
|
||||||
|
_xputs(None, "\n")
|
||||||
|
pass
|
||||||
|
|
||||||
|
if _is_equal(cmd_line.split(' ')[0], ['load', 'ld']): ## 'load [xxx.bin]'
|
||||||
|
params = cmd_line.split(' ')
|
||||||
|
file = None
|
||||||
|
if len(params) > 1:
|
||||||
|
if len(params[1].split('.')) > 1:
|
||||||
|
file = params[1]
|
||||||
|
else:
|
||||||
|
file = params[1].split('.')[0] + '.bin'
|
||||||
|
else:
|
||||||
|
flist = glob.glob(globalParam.workPath + '\\*.bin')
|
||||||
|
if len(flist) > 0:
|
||||||
|
file = flist[0].split('\\')[-1]
|
||||||
|
if file != None:
|
||||||
|
_xputs(None, "open file: " + file + "\n")
|
||||||
|
try:
|
||||||
|
globalParam.binFile = globalParam.workPath + '\\' + file
|
||||||
|
with open(globalParam.binFile, 'rb') as fd:
|
||||||
|
globalParam.binData = fd.read()
|
||||||
|
globalParam.binSize = len(globalParam.binData)
|
||||||
|
_xputs(None, "read {0} bytes.".format(globalParam.binSize) + "\n")
|
||||||
|
except:
|
||||||
|
_xputs(None, "open failed." + "\n")
|
||||||
|
else:
|
||||||
|
_xputs(None, "invalid param." + "\n")
|
||||||
|
_xputs(None, "\n")
|
||||||
|
pass
|
||||||
|
|
||||||
|
if _is_equal(cmd_line.split(' ')[0], ['download', 'd']): ## 'download [com*]'
|
||||||
|
params = cmd_line.split(' ')
|
||||||
|
ser = None
|
||||||
|
if len(params) > 1:
|
||||||
|
ser = myserial.OpenPort(params[1], baud_rate=SERIAL_BAUDRATE)
|
||||||
|
needClose = True
|
||||||
|
else:
|
||||||
|
if globalParam.serial_check():
|
||||||
|
ser = globalParam.lastSerial
|
||||||
|
needClose = False
|
||||||
|
if globalParam.binSize > 0:
|
||||||
|
pkgs = 0
|
||||||
|
if ser != None:
|
||||||
|
bindata = globalParam.binData
|
||||||
|
while True:
|
||||||
|
pkgs = pkgs + 1
|
||||||
|
if len(bindata) >= DOWNLOAD_PKG_SIZE:
|
||||||
|
data = bindata[:DOWNLOAD_PKG_SIZE]
|
||||||
|
bindata = bindata[DOWNLOAD_PKG_SIZE:]
|
||||||
|
data = b'\xa5' + data + b'\x5a'
|
||||||
|
myserial.WriteData(ser, data)
|
||||||
|
_xputs(None, ".")
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
data = b'\xa5' + bindata + b'\x00'*(DOWNLOAD_PKG_SIZE-len(bindata)) + b'\x5a'
|
||||||
|
myserial.WriteData(ser, data)
|
||||||
|
_xputs(None, ".")
|
||||||
|
break
|
||||||
|
data = b'\xa6' + b'\x01' + b'\x00'*(DOWNLOAD_PKG_SIZE-1) + b'\x6a'
|
||||||
|
myserial.WriteData(ser, data)
|
||||||
|
_xputs(None, "." + "\n")
|
||||||
|
_xputs(None, "send {0} pkgs, pkg size {1}.".format(pkgs, DOWNLOAD_PKG_SIZE) + "\n")
|
||||||
|
if needClose:
|
||||||
|
myserial.ClosePort(ser)
|
||||||
|
shell.shell_trig = True
|
||||||
|
else:
|
||||||
|
_xputs(None, "invalid param." + "\n")
|
||||||
|
else:
|
||||||
|
_xputs(None, "please load bin file first." + "\n")
|
||||||
|
_xputs(None, "\n")
|
||||||
|
pass
|
||||||
|
|
||||||
|
if _is_equal(cmd_line.split(' ')[0], ['go', 'g']): ## 'go [com*]'
|
||||||
|
params = cmd_line.split(' ')
|
||||||
|
ser = None
|
||||||
|
if len(params) > 1:
|
||||||
|
ser = myserial.OpenPort(params[1], baud_rate=SERIAL_BAUDRATE)
|
||||||
|
needClose = True
|
||||||
|
else:
|
||||||
|
if globalParam.serial_check():
|
||||||
|
ser = globalParam.lastSerial
|
||||||
|
needClose = False
|
||||||
|
if ser != None:
|
||||||
|
data = b'\xa6' + b'\x02' + b'\x00'*(DOWNLOAD_PKG_SIZE-1) + b'\x6a'
|
||||||
|
myserial.WriteData(ser, data)
|
||||||
|
_xputs(None, "." + "\n")
|
||||||
|
_xputs(None, "send {0} pkgs, pkg size {1}.".format(1, DOWNLOAD_PKG_SIZE) + "\n")
|
||||||
|
if needClose:
|
||||||
|
myserial.ClosePort(ser)
|
||||||
|
shell.shell_trig = True
|
||||||
|
else:
|
||||||
|
_xputs(None, "invalid param." + "\n")
|
||||||
|
_xputs(None, "\n")
|
||||||
|
pass
|
||||||
|
|
||||||
|
if _is_equal(cmd_line, 'com'):
|
||||||
|
serial_ports = myserial.SearchPort(SERIAL_PORT_NUM)
|
||||||
|
_xputs(None, "valid port: " + str(serial_ports).replace('[','').replace(']','').replace('\'','') + "\n")
|
||||||
|
_xputs(None, "\n")
|
||||||
|
pass
|
||||||
|
|
||||||
|
if serial_ports != None: ## 'com*'
|
||||||
|
for i in range(len(serial_ports)):
|
||||||
|
if _is_equal(cmd_line, serial_ports[i]): # e.g. _is_equal(cmd_line, 'com20')
|
||||||
|
if globalParam.serial_check():
|
||||||
|
tserial.kill()
|
||||||
|
tserial.join()
|
||||||
|
tserial = NewThread(target=serial_thread, args=(serial_ports[i],))
|
||||||
|
tserial.start()
|
||||||
|
while not globalParam.serial_check():
|
||||||
|
pass
|
||||||
|
shell.shell_trig = True
|
||||||
|
pass
|
||||||
|
|
||||||
|
if shell.shell_trig:
|
||||||
|
continue
|
||||||
|
|
||||||
|
_xputs(None, ":")
|
||||||
|
## USER COMMAND PARSE AND EXECUTE END
|
||||||
|
continue
|
||||||
|
|
||||||
|
if shell.shell_mode == MODE_CONTROL or shell.shell_mode == MODE_NORMAL:
|
||||||
|
shell.output(globalParam.currentSerial, ch, True)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
global globalParam
|
||||||
|
globalParam = GlobalParam()
|
||||||
|
|
||||||
|
mysys.env_init(lang='EN', cls=True, curs=False)
|
||||||
|
|
||||||
|
print(welcome_info, end="\n")
|
||||||
|
|
||||||
|
globalParam.workPath = globalParam.get_work_path()
|
||||||
|
|
||||||
|
globalParam.threadInput = NewThread(target=input_thread)
|
||||||
|
globalParam.threadOutput = NewThread(target=output_thread)
|
||||||
|
|
||||||
|
globalParam.threadInput.start()
|
||||||
|
globalParam.threadOutput.start()
|
||||||
|
|
||||||
|
globalParam.threadInput.join()
|
||||||
|
globalParam.threadOutput.join()
|
||||||
|
|
||||||
|
globalParam.cleanup()
|
||||||
|
|
||||||
|
timeout = 0
|
||||||
|
print("Exit After %d Second ..." % timeout, end="\n")
|
||||||
|
time.sleep(timeout)
|
||||||
|
|
||||||
|
mysys.env_init(lang='ZH', cls=False, curs=True)
|
||||||
|
|
||||||
|
print("Exit.", end="\n")
|
Binary file not shown.
After Width: | Height: | Size: 4.2 KiB |
|
@ -0,0 +1,49 @@
|
||||||
|
#-*-coding: utf-8 -*-
|
||||||
|
|
||||||
|
def InsertBlock(hex_str):
|
||||||
|
if type(hex_str) != type("12"):
|
||||||
|
print("hex_str is not 'str' type!")
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
if len(hex_str)%2 != 0:
|
||||||
|
hex_str += '0'
|
||||||
|
print("add '0' at end,amended: ", end="")
|
||||||
|
print(hex_str)
|
||||||
|
hex_str_len = len(hex_str)
|
||||||
|
# print(hex_str_len)
|
||||||
|
hex_str_list = ["".join(hex_str[2*i:2*i+2]) for i in range(hex_str_len//2)]
|
||||||
|
# print(hex_str_list)
|
||||||
|
return " ".join(hex_str_list)
|
||||||
|
|
||||||
|
def ToHexStr(data):
|
||||||
|
if type(data) == type([1,]):
|
||||||
|
bytes_data = ToBytes(data)
|
||||||
|
return bytes_data.hex()
|
||||||
|
elif type(data) == type(b'\x00'):
|
||||||
|
return data.hex()
|
||||||
|
else:
|
||||||
|
print("only 'list' or 'bytes' is valid!")
|
||||||
|
return None
|
||||||
|
|
||||||
|
def ToIntList(data):
|
||||||
|
if type(data) == type('12'):
|
||||||
|
bytes_data = ToBytes(data)
|
||||||
|
return list(bytes_data)
|
||||||
|
elif type(data) == type(b'\x00'):
|
||||||
|
return list(data)
|
||||||
|
else:
|
||||||
|
print("only 'str' or 'bytes' is valid!")
|
||||||
|
return None
|
||||||
|
|
||||||
|
def ToBytes(data):
|
||||||
|
if type(data) == type('12'):
|
||||||
|
if len(data)%2 != 0:
|
||||||
|
data += '0'
|
||||||
|
print("add '0' at end,amended: ", end="")
|
||||||
|
print(data)
|
||||||
|
return bytes().fromhex(data)
|
||||||
|
elif type(data) == type([1,]):
|
||||||
|
return bytes(data)
|
||||||
|
else:
|
||||||
|
print("only 'str' or 'list' is valid!")
|
||||||
|
return None
|
|
@ -0,0 +1,57 @@
|
||||||
|
#-*-coding: utf-8 -*-
|
||||||
|
|
||||||
|
import time
|
||||||
|
import serial
|
||||||
|
|
||||||
|
import myconvert
|
||||||
|
|
||||||
|
def SearchPort(num=20):
|
||||||
|
port_list = []
|
||||||
|
for idx in range(num):
|
||||||
|
name = 'COM' + str(idx)
|
||||||
|
try:
|
||||||
|
ser = serial.Serial(name)
|
||||||
|
ser.open
|
||||||
|
if ser.is_open:
|
||||||
|
port_list.append(name)
|
||||||
|
ser.close
|
||||||
|
except serial.serialutil.SerialException:
|
||||||
|
pass
|
||||||
|
return port_list
|
||||||
|
|
||||||
|
def OpenPort(port, baud_rate=9600, parity=serial.PARITY_NONE):
|
||||||
|
try:
|
||||||
|
ser = serial.Serial(port, baud_rate, parity=parity) # 8-data bits/1-stop bits
|
||||||
|
print("%s is opened, baudrate is %d." %(port, baud_rate), end="\n")
|
||||||
|
return ser
|
||||||
|
except:
|
||||||
|
return None
|
||||||
|
|
||||||
|
def ClosePort(ser):
|
||||||
|
try:
|
||||||
|
if ser.is_open:
|
||||||
|
print("%s is closed." %(ser.name), end="\n")
|
||||||
|
ser.close()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def ReadData(ser):
|
||||||
|
try:
|
||||||
|
if ser.is_open:
|
||||||
|
raw_data = ser.read(ser.in_waiting)
|
||||||
|
if len(raw_data) != 0:
|
||||||
|
return (True, len(raw_data), myconvert.ToIntList(raw_data))
|
||||||
|
else:
|
||||||
|
return (True, 0, None)
|
||||||
|
except:
|
||||||
|
return (False, 0, None)
|
||||||
|
|
||||||
|
def WriteData(ser, data):
|
||||||
|
try:
|
||||||
|
if ser.is_open:
|
||||||
|
if type(data) != type(b'\x00'):
|
||||||
|
data = myconvert.ToBytes(data)
|
||||||
|
ser.write(data)
|
||||||
|
time.sleep(1 / ser.baudrate * len(data) * 10)
|
||||||
|
except:
|
||||||
|
return None
|
|
@ -0,0 +1,70 @@
|
||||||
|
#-*-coding: utf-8 -*-
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
import win32api
|
||||||
|
import win32gui
|
||||||
|
from win32con import WM_INPUTLANGCHANGEREQUEST
|
||||||
|
|
||||||
|
def _is_equal(v1, v2):
|
||||||
|
## ignore case
|
||||||
|
|
||||||
|
if len(v1) != len(v2):
|
||||||
|
return 0
|
||||||
|
|
||||||
|
s1 = v1.lower()
|
||||||
|
s2 = v2.lower()
|
||||||
|
|
||||||
|
if s1 == s2:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def _is_equal2(v1, v2):
|
||||||
|
## ignore case
|
||||||
|
|
||||||
|
if len(v1) != len(v1):
|
||||||
|
return 0
|
||||||
|
|
||||||
|
s1 = "".join(chr(i) for i in v1).lower()
|
||||||
|
s2 = v2.lower()
|
||||||
|
|
||||||
|
if s1 == s2:
|
||||||
|
return 1
|
||||||
|
else:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
def _xputs(ch):
|
||||||
|
print(ch, end="")
|
||||||
|
sys.stdout.flush()
|
||||||
|
|
||||||
|
def change_language(lang="EN"):
|
||||||
|
LANG = {
|
||||||
|
"ZH": 0x0804,
|
||||||
|
"EN": 0x0409
|
||||||
|
}
|
||||||
|
hwnd = win32gui.GetForegroundWindow()
|
||||||
|
language = LANG[lang]
|
||||||
|
result = win32api.SendMessage(
|
||||||
|
hwnd,
|
||||||
|
WM_INPUTLANGCHANGEREQUEST,
|
||||||
|
0,
|
||||||
|
language
|
||||||
|
)
|
||||||
|
if not result:
|
||||||
|
return True
|
||||||
|
|
||||||
|
def env_init(lang="EN", cls=True, curs=True):
|
||||||
|
if curs:
|
||||||
|
os.system('echo -e "\033[?25h" 1>NUL')
|
||||||
|
else:
|
||||||
|
os.system('echo -e "\033[?25l"')
|
||||||
|
|
||||||
|
if cls:
|
||||||
|
os.system('cls')
|
||||||
|
|
||||||
|
change_language(lang)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
env_init("EN", False)
|
|
@ -0,0 +1,11 @@
|
||||||
|
@echo off
|
||||||
|
|
||||||
|
chcp 65001
|
||||||
|
|
||||||
|
rd build /S /Q
|
||||||
|
rd dist /S /Q
|
||||||
|
rd __pycache__ /S /Q
|
||||||
|
|
||||||
|
del *.spec /S
|
||||||
|
|
||||||
|
timeout /t 2
|
|
@ -0,0 +1,15 @@
|
||||||
|
@echo off
|
||||||
|
|
||||||
|
chcp 65001
|
||||||
|
|
||||||
|
rd build /S /Q
|
||||||
|
rd dist /S /Q
|
||||||
|
rd __pycache__ /S /Q
|
||||||
|
|
||||||
|
del *.spec /S
|
||||||
|
del *.exe /S
|
||||||
|
|
||||||
|
pyinstaller -F -i icon.ico debugger.py
|
||||||
|
cp dist/*.exe .
|
||||||
|
|
||||||
|
timeout /t 2
|
|
@ -0,0 +1,19 @@
|
||||||
|
#.gitignore
|
||||||
|
|
||||||
|
# Step-1, track all files in the current folder
|
||||||
|
!*
|
||||||
|
|
||||||
|
# Step-2, track specified files in the current folder
|
||||||
|
*
|
||||||
|
!*/
|
||||||
|
!.gitignore
|
||||||
|
!*.mk
|
||||||
|
!Makefile
|
||||||
|
!*.lds
|
||||||
|
!*.h
|
||||||
|
!*.c
|
||||||
|
!*.s
|
||||||
|
!*.S
|
||||||
|
|
||||||
|
# Step-3, untrack all in sub folders, which use their own .gitignore
|
||||||
|
#*/*
|
|
@ -0,0 +1,91 @@
|
||||||
|
#/*
|
||||||
|
# * Copyright {c} 2020-2021, SERI Development Team
|
||||||
|
# *
|
||||||
|
# * SPDX-License-Identifier: Apache-2.0
|
||||||
|
# *
|
||||||
|
# * Change Logs:
|
||||||
|
# * Date Author Notes
|
||||||
|
# * 2022-04-04 Lyons first version
|
||||||
|
# */
|
||||||
|
|
||||||
|
COLORS = "\033[32m"
|
||||||
|
COLORE = "\033[0m"
|
||||||
|
|
||||||
|
.PHONY: help
|
||||||
|
help:
|
||||||
|
@echo "help - help menu "
|
||||||
|
@echo "build - compile c/asm file "
|
||||||
|
@echo "compile - compile rtl file "
|
||||||
|
@echo "sim - simulate "
|
||||||
|
@echo "run - compile and simulate "
|
||||||
|
@echo "wave - open wave "
|
||||||
|
@echo "xemu - compile and run on xemu (linux platform) "
|
||||||
|
|
||||||
|
.PHONY: build
|
||||||
|
build:
|
||||||
|
@echo -e ${COLORS}[INFO] compile c/asm file ...${COLORE}
|
||||||
|
${Q}${CC} ${INCLUDES} ${INCFILES} ${CFLAGS} ${LDFLAGS} ${LDLIBS} ${ASMFILES} ${CFILES} -o ${TARGET}.elf
|
||||||
|
@echo -e ${COLORS}[INFO] create dump file ...${COLORE}
|
||||||
|
${Q}${OBJDUMP} -D -S ${TARGET}.elf > ${TARGET}.dump
|
||||||
|
@echo -e ${COLORS}[INFO] create image file ...${COLORE}
|
||||||
|
${Q}${OBJCOPY} -S -O binary ${TARGET}.elf ${TARGET}.bin
|
||||||
|
${Q}${OBJCOPY} -S -O verilog ${TARGET}.elf image.pat
|
||||||
|
ifneq ($(shell uname), Linux)
|
||||||
|
${Q}${PROJPATH}/scripts/bin2mi.exe ${TARGET}.bin
|
||||||
|
${Q}${CP} rom.mi ${PROJPATH}/riscv-bootloader.mi
|
||||||
|
endif
|
||||||
|
@echo -e ${COLORS}[INFO] execute done${COLORE}
|
||||||
|
|
||||||
|
.PHONY: compile
|
||||||
|
compile:
|
||||||
|
@echo -e ${COLORS}[INFO] compile design file ...${COLORE}
|
||||||
|
ifneq ($(shell uname), Linux)
|
||||||
|
${Q}${VCS} -g2012 -o wave.vvp ${ALLDEFINE} -f ${PROJPATH}/fpga_project/src//design.f ${TBFILES}
|
||||||
|
else
|
||||||
|
${Q}${VCS} -Mupdate -sverilog +v2k -debug_pp -timescale="1ns/100ps" ${ALLDEFINE} \
|
||||||
|
-f ${PROJPATH}/fpga_project/src//design.f ${TBFILES} \
|
||||||
|
-l compile.log
|
||||||
|
endif
|
||||||
|
@echo -e ${COLORS}[INFO] execute done${COLORE}
|
||||||
|
|
||||||
|
.PHONY: sim
|
||||||
|
sim:
|
||||||
|
@echo -e ${COLORS}[INFO] simulate ...${COLORE}
|
||||||
|
ifneq ($(shell uname), Linux)
|
||||||
|
${Q}${SIM} -n wave.vvp -lxt2
|
||||||
|
else
|
||||||
|
${Q}${SIM} -l sim.log
|
||||||
|
endif
|
||||||
|
@echo -e ${COLORS}[INFO] execute done${COLORE}
|
||||||
|
|
||||||
|
.PHONY: run
|
||||||
|
run: build compile sim
|
||||||
|
|
||||||
|
.PHONY: wave
|
||||||
|
wave:
|
||||||
|
@echo -e ${COLORS}[INFO] open wave ...${COLORE}
|
||||||
|
ifneq ($(shell uname), Linux)
|
||||||
|
${Q}${WAV} wave.vcd &
|
||||||
|
else
|
||||||
|
${Q}${WAV} -full64 -vpd wave.vpd &
|
||||||
|
endif
|
||||||
|
@echo -e ${COLORS}[INFO] execute done${COLORE}
|
||||||
|
|
||||||
|
.PHONY: xemu
|
||||||
|
xemu:
|
||||||
|
@echo -e ${COLORS}[INFO] compile xemu ...${COLORE}
|
||||||
|
${Q}make -C ${WORKPATH}/../xemu build
|
||||||
|
@echo -e ${COLORS}[INFO] simulate ...${COLORE}
|
||||||
|
ifneq ($(shell uname), Linux)
|
||||||
|
${Q}${WORKPATH}/../xemu/xemu.exe ${TARGET}.bin
|
||||||
|
else
|
||||||
|
${Q}${WORKPATH}/../xemu/xemu ${TARGET}.bin
|
||||||
|
endif
|
||||||
|
@echo -e ${COLORS}[INFO] execute done${COLORE}
|
||||||
|
|
||||||
|
.PHONY: clean
|
||||||
|
clean:
|
||||||
|
@echo -e ${COLORS}[INFO] clean project ...${COLORE}
|
||||||
|
@make -C ${WORKPATH}/../xemu clean
|
||||||
|
@ls | grep -vE "Makefile|driver|rtthread-nano|*\.lds$$|*\.c$$|*\.h$$" | xargs -i rm -rf {}
|
||||||
|
@echo -e ${COLORS}[INFO] execute done${COLORE}
|
|
@ -0,0 +1,86 @@
|
||||||
|
#/*
|
||||||
|
# * Copyright {c} 2020-2021, SERI Development Team
|
||||||
|
# *
|
||||||
|
# * SPDX-License-Identifier: Apache-2.0
|
||||||
|
# *
|
||||||
|
# * Change Logs:
|
||||||
|
# * Date Author Notes
|
||||||
|
# * 2022-04-04 Lyons first version
|
||||||
|
# */
|
||||||
|
|
||||||
|
# Note:
|
||||||
|
# 1. if work on Windows, you can use iverilog, Gowin FPGA or XEMU to simulate
|
||||||
|
# 2. if work on Linux, you can use VCS or XEMU to simulate
|
||||||
|
|
||||||
|
ifeq ($(shell uname), Linux)
|
||||||
|
EMBTOOLPATH = /home/crazy/Tools/compiler/xuantie/v8.4.0/riscv64-elf-x86_64-20210307
|
||||||
|
EMBTOOLPREFIX = ${EMBTOOLPATH}/bin/riscv64-unknown-elf
|
||||||
|
CC = ${EMBTOOLPREFIX}-gcc
|
||||||
|
OBJDUMP = ${EMBTOOLPREFIX}-objdump
|
||||||
|
OBJCOPY = ${EMBTOOLPREFIX}-objcopy
|
||||||
|
else
|
||||||
|
EMBTOOLPATH = D:/EmbedCompiler/riscv64-elf-mingw-20210306
|
||||||
|
EMBTOOLPREFIX = ${EMBTOOLPATH}/bin/riscv64-unknown-elf
|
||||||
|
CC = ${EMBTOOLPREFIX}-gcc.exe
|
||||||
|
OBJDUMP = ${EMBTOOLPREFIX}-objdump.exe
|
||||||
|
OBJCOPY = ${EMBTOOLPREFIX}-objcopy.exe
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(shell uname), Linux)
|
||||||
|
VCS = vcs
|
||||||
|
SIM = ./simv
|
||||||
|
WAV = dve
|
||||||
|
else
|
||||||
|
VCS = D:/iverilog/bin/iverilog.exe
|
||||||
|
SIM = D:/iverilog/bin/vvp.exe
|
||||||
|
WAV = D:/iverilog/gtkwave/bin/gtkwave.exe
|
||||||
|
endif
|
||||||
|
|
||||||
|
RM = rm -f
|
||||||
|
CP = cp
|
||||||
|
MV = mv
|
||||||
|
|
||||||
|
# for vcs tools
|
||||||
|
ifeq ($(shell uname), Linux)
|
||||||
|
ALLDEFINE = +define+DUMP_VPD
|
||||||
|
ALLDEFINE += +define+TESTBENCH_VCS
|
||||||
|
else
|
||||||
|
ALLDEFINE = -DDUMP_VCD
|
||||||
|
ALLDEFINE += -DTESTBENCH_VCS
|
||||||
|
endif
|
||||||
|
|
||||||
|
TBFILES = ${PROJPATH}/tb/prim_sim.v \
|
||||||
|
${PROJPATH}/fpga_project/src/ipdefs/gowin_rpll/gowin_rpll.v \
|
||||||
|
${PROJPATH}/fpga_project/src/ipdefs/gowin_dpb_8x4k/gowin_dpb_8x4k.v \
|
||||||
|
${PROJPATH}/fpga_project/src/ipdefs/gowin_dpb_32x8k/gowin_dpb_32x8k.v \
|
||||||
|
${PROJPATH}/tb/core_data_monitor_tb.v \
|
||||||
|
${PROJPATH}/tb/core_uart_monitor_tb.v \
|
||||||
|
${PROJPATH}/tb/core_tb.v
|
||||||
|
|
||||||
|
# for c/asm tools
|
||||||
|
INCLUDES =
|
||||||
|
|
||||||
|
INCFILES = -I${PROJPATH}/sim/libs \
|
||||||
|
-I${PROJPATH}/sim/libs/_sdk \
|
||||||
|
-I${PROJPATH}/sim/libs/_sdk/systick \
|
||||||
|
-I${PROJPATH}/sim/libs/_sdk/gpio \
|
||||||
|
-I${PROJPATH}/sim/libs/_sdk/timer \
|
||||||
|
-I${PROJPATH}/sim/libs/_sdk/uart \
|
||||||
|
-I${PROJPATH}/sim/libs/_utilities
|
||||||
|
|
||||||
|
CFLAGS = -march=rv32im -mabi=ilp32 -mcmodel=medlow
|
||||||
|
|
||||||
|
LDFLAGS = -Wl,-Map,${TARGET}.map,-warn-common \
|
||||||
|
-Wl,--gc-sections \
|
||||||
|
-Wl,--no-relax \
|
||||||
|
-nostartfiles
|
||||||
|
|
||||||
|
LDLIBS = -lm -lc -lgcc
|
||||||
|
|
||||||
|
ASMFILES = ${PROJPATH}/sim/libs/_startup/start.S \
|
||||||
|
${PROJPATH}/sim/libs/_startup/trap.S
|
||||||
|
|
||||||
|
CFILES = ${PROJPATH}/sim/libs/_sdk/systick/*.c \
|
||||||
|
${PROJPATH}/sim/libs/_sdk/timer/*.c \
|
||||||
|
${PROJPATH}/sim/libs/_sdk/uart/*.c \
|
||||||
|
${PROJPATH}/sim/libs/_utilities/*.c
|
|
@ -0,0 +1,68 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021, SERI Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2021-10-29 Lyons first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __DEF_H__
|
||||||
|
#define __DEF_H__
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define CPU_FREQ_HZ (10125000)
|
||||||
|
#define CPU_FREQ_KHZ (CPU_FREQ_HZ / 1000)
|
||||||
|
#define CPU_FREQ_MHZ (CPU_FREQ_HZ / 1000000)
|
||||||
|
|
||||||
|
#define LCD_X_SIZE (240)
|
||||||
|
#define LCD_Y_SIZE (135)
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
#define __I volatile /*!< Defines 'read only' permissions */
|
||||||
|
#else
|
||||||
|
#define __I volatile const /*!< Defines 'read only' permissions */
|
||||||
|
#endif
|
||||||
|
#define __O volatile /*!< Defines 'write only' permissions */
|
||||||
|
#define __IO volatile /*!< Defines 'read / write' permissions */
|
||||||
|
|
||||||
|
#ifndef UNUSED
|
||||||
|
#define UNUSED(X) ((void)X)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define CLEAR_ARRAY(ins,data) memset((uint8_t*)ins,data,sizeof(ins))
|
||||||
|
#define CLEAR_STRUCT(ins,data) memset((uint8_t*)ins,data,sizeof(ins))
|
||||||
|
|
||||||
|
#define GET_ARRAY_NUM(ins) ((uint32_t)(sizeof(ins)/sizeof(ins[0])))
|
||||||
|
#define GET_STRUCT_SIZE(ins) ((uint32_t)(sizeof(ins)))
|
||||||
|
|
||||||
|
#define GET_WORD_BYTE0(w) ((uint8_t)((w) & 0xFF))
|
||||||
|
#define GET_WORD_BYTE1(w) ((uint8_t)((w>>8) & 0xFF))
|
||||||
|
|
||||||
|
#define GET_DWORD_BYTE0(d) GET_WORD_BYTE0(d)
|
||||||
|
#define GET_DWORD_BYTE1(d) GET_WORD_BYTE1(d)
|
||||||
|
#define GET_DWORD_BYTE2(d) ((uint8_t)(((d)>>16) & 0xFF))
|
||||||
|
#define GET_DWORD_BYTE3(d) ((uint8_t)(((d)>>24) & 0xFF))
|
||||||
|
|
||||||
|
#define BUILD_WORD(a,b) ((uint16_t)(((a)<<8 ) | (b)))
|
||||||
|
#define BUILD_DWORD(a,b,c,d) ((uint32_t)(((a)<<24) | ((b)<<16) | ((c)<<8) | (d)))
|
||||||
|
|
||||||
|
#define _internal_ro static const
|
||||||
|
#define _internal_rw static
|
||||||
|
#define _internal_zi static
|
||||||
|
|
||||||
|
#define read_csr(reg) ({ unsigned long __tmp; \
|
||||||
|
asm volatile ("csrr %0, " #reg : "=r"(__tmp)); \
|
||||||
|
__tmp; })
|
||||||
|
|
||||||
|
#define write_csr(reg, val) ({ \
|
||||||
|
if (__builtin_constant_p(val) && (unsigned long)(val) < 32) \
|
||||||
|
asm volatile ("csrw " #reg ", %0" :: "i"(val)); \
|
||||||
|
else \
|
||||||
|
asm volatile ("csrw " #reg ", %0" :: "r"(val)); })
|
||||||
|
|
||||||
|
#include "__simulation.h"
|
||||||
|
|
||||||
|
#endif //#ifndef __DEF_H__
|
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021, SERI Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2021-10-29 Lyons first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __SIMULATION_H__
|
||||||
|
#define __SIMULATION_H__
|
||||||
|
|
||||||
|
#include "uart.h"
|
||||||
|
|
||||||
|
#define _csr_putc(val) write_csr(mscratchcswl, val)
|
||||||
|
#define _uart_putc(val) uart_send_wait(UART1, val)
|
||||||
|
|
||||||
|
#ifdef PRINT_STDIO_SIM
|
||||||
|
#define simulation(data) \
|
||||||
|
do { \
|
||||||
|
_csr_putc( (1<<31)|0x1b ); _csr_putc(0); \
|
||||||
|
_csr_putc( (1<<31)|data ); _csr_putc(0); \
|
||||||
|
} while (0);
|
||||||
|
#else
|
||||||
|
#define simulation(data) \
|
||||||
|
do { \
|
||||||
|
_uart_putc(0x1b); \
|
||||||
|
_uart_putc(data); \
|
||||||
|
} while (0);
|
||||||
|
#endif // #ifdef PRINT_STDIO_SIM
|
||||||
|
|
||||||
|
#endif //#ifndef __SIMULATION_H__
|
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021, SERI Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2023-12-23 Lyons first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __GPIO_H__
|
||||||
|
#define __GPIO_H__
|
||||||
|
|
||||||
|
#include "__def.h"
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
__IO uint32_t cr;
|
||||||
|
__IO uint32_t in;
|
||||||
|
__IO uint32_t out;
|
||||||
|
uint32_t rsvd;
|
||||||
|
__O uint32_t obit[16];
|
||||||
|
} GPIO_Type;
|
||||||
|
|
||||||
|
#define GPIO_BASE (0x40000000)
|
||||||
|
|
||||||
|
#define GPIO1 ((GPIO_Type*)(GPIO_BASE))
|
||||||
|
|
||||||
|
#define POut(n,v) do { \
|
||||||
|
GPIO1->obit[n] = v; \
|
||||||
|
} while (0);
|
||||||
|
|
||||||
|
#define LCD_BK_OFF POut(3,0)
|
||||||
|
#define LCD_BK_ON POut(3,1)
|
||||||
|
|
||||||
|
#define LCD_CS0_EN POut(5,0)
|
||||||
|
#define LCD_CS0_DIS POut(5,1)
|
||||||
|
|
||||||
|
#define LCD_RST_L POut(7,0)
|
||||||
|
#define LCD_RST_H POut(7,1)
|
||||||
|
|
||||||
|
#define LCD_DC_L POut(8,0)
|
||||||
|
#define LCD_DC_H POut(8,1)
|
||||||
|
|
||||||
|
#define LCD_SCL_L POut(9,0)
|
||||||
|
#define LCD_SCL_H POut(9,1)
|
||||||
|
|
||||||
|
#define LCD_SDA_L POut(11,0)
|
||||||
|
#define LCD_SDA_H POut(11,1)
|
||||||
|
|
||||||
|
#endif //#ifndef __UART_H__
|
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021, SERI Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2021-11-08 Lyons first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "systick.h"
|
||||||
|
|
||||||
|
uint64_t get_cycle_value(void)
|
||||||
|
{
|
||||||
|
uint64_t cycle;
|
||||||
|
|
||||||
|
cycle = read_csr(cycle);
|
||||||
|
cycle += (uint64_t)(read_csr(cycleh)) << 32;
|
||||||
|
|
||||||
|
return cycle;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t get_cyclel_value(void)
|
||||||
|
{
|
||||||
|
return read_csr(cycle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void delay_us(uint32_t us)
|
||||||
|
{
|
||||||
|
uint64_t start;
|
||||||
|
uint64_t end;
|
||||||
|
|
||||||
|
if (0 == us) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
start = get_cycle_value();
|
||||||
|
end = start + (us * CPU_FREQ_KHZ) / 1000;
|
||||||
|
|
||||||
|
while (get_cycle_value() < end);
|
||||||
|
}
|
||||||
|
|
||||||
|
void delay_ms(uint32_t ms)
|
||||||
|
{
|
||||||
|
if (0 == ms) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (ms--) {
|
||||||
|
delay_us(1000);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021, SERI Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2021-11-08 Lyons first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __SYSTICK_H__
|
||||||
|
#define __SYSTICK_H__
|
||||||
|
|
||||||
|
#include "__def.h"
|
||||||
|
|
||||||
|
uint64_t get_cycle_value(void);
|
||||||
|
uint32_t get_cyclel_value(void);
|
||||||
|
|
||||||
|
void delay_us();
|
||||||
|
void delay_ms();
|
||||||
|
|
||||||
|
#endif //#ifndef __SYSTICK_H__
|
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021, SERI Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2021-10-29 Lyons first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "timer.h"
|
||||||
|
|
||||||
|
void timer_init(TIM_Type *tim, uint32_t psc, uint32_t value)
|
||||||
|
{
|
||||||
|
tim->cr &= ~TIM_CR_EN; //close first
|
||||||
|
|
||||||
|
tim->sr |= TIM_SR_CLR_TUF;
|
||||||
|
|
||||||
|
tim->psc = (0 == psc) ? 0 : (psc-1);
|
||||||
|
tim->load = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void timer_control(TIM_Type *tim, uint8_t en)
|
||||||
|
{
|
||||||
|
uint32_t dummy;
|
||||||
|
|
||||||
|
dummy = tim->cr;
|
||||||
|
|
||||||
|
if (TIM_EN == en)
|
||||||
|
{
|
||||||
|
dummy |= TIM_CR_EN;
|
||||||
|
} else {
|
||||||
|
dummy &= ~TIM_CR_EN;
|
||||||
|
}
|
||||||
|
|
||||||
|
tim->cr = dummy;
|
||||||
|
}
|
||||||
|
|
||||||
|
void timer_clearflag(TIM_Type *tim, uint32_t flag)
|
||||||
|
{
|
||||||
|
tim->sr = flag;
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021, SERI Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2021-10-29 Lyons first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __TIMER_H__
|
||||||
|
#define __TIMER_H__
|
||||||
|
|
||||||
|
#include "__def.h"
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
__IO uint32_t cr;
|
||||||
|
__IO uint32_t sr;
|
||||||
|
__IO uint32_t psc;
|
||||||
|
__O uint32_t load;
|
||||||
|
__I uint32_t count;
|
||||||
|
} TIM_Type;
|
||||||
|
|
||||||
|
#define TIM_BASE (0x20000000)
|
||||||
|
|
||||||
|
#define TIM1 ((TIM_Type*)(TIM_BASE))
|
||||||
|
|
||||||
|
// [0]: enbale
|
||||||
|
#define TIM_CR_EN (uint32_t)(1 << 0)
|
||||||
|
|
||||||
|
// [0]: timing-up flag
|
||||||
|
#define TIM_SR_FLAG_TUF (uint32_t)(1 << 0)
|
||||||
|
|
||||||
|
#define TIM_SR_CLR_TUF (uint32_t)(1 << 0) //write "1" clear
|
||||||
|
|
||||||
|
#define TIM_EN (uint8_t)0x1
|
||||||
|
#define TIM_DIS (uint8_t)0x0
|
||||||
|
|
||||||
|
void timer_init(TIM_Type *tim, uint32_t psc, uint32_t value);
|
||||||
|
|
||||||
|
void timer_control(TIM_Type *tim, uint8_t en);
|
||||||
|
void timer_clearflag(TIM_Type *tim, uint32_t flag);
|
||||||
|
|
||||||
|
#endif //#ifndef __TIMER_H__
|
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021, SERI Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2021-10-29 Lyons first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "uart.h"
|
||||||
|
|
||||||
|
void uart_send(UART_Type *uart, uint8_t data)
|
||||||
|
{
|
||||||
|
uart->sr = UART_SR_CLR_TXE;
|
||||||
|
uart->txd = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void uart_send_wait(UART_Type *uart, uint8_t data)
|
||||||
|
{
|
||||||
|
uart->txd = data;
|
||||||
|
while ( !(uart->sr & UART_SR_FLAG_TXE) );
|
||||||
|
uart->sr = UART_SR_CLR_TXE;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t uart_read(UART_Type *uart)
|
||||||
|
{
|
||||||
|
uint8_t dummy;
|
||||||
|
|
||||||
|
if (uart->sr & UART_SR_FLAG_RXNE)
|
||||||
|
{
|
||||||
|
dummy = uart->rxd;
|
||||||
|
uart->sr = UART_SR_CLR_RXNE;
|
||||||
|
} else {
|
||||||
|
dummy = 0xFF; //0xFF is -1
|
||||||
|
}
|
||||||
|
|
||||||
|
return dummy;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t uart_read_wait(UART_Type *uart)
|
||||||
|
{
|
||||||
|
uint8_t dummy;
|
||||||
|
|
||||||
|
while ( !(uart->sr & UART_SR_FLAG_RXNE) );
|
||||||
|
|
||||||
|
dummy = uart->rxd;
|
||||||
|
uart->sr = UART_SR_CLR_RXNE;
|
||||||
|
|
||||||
|
return dummy;
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021, SERI Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2021-10-29 Lyons first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __UART_H__
|
||||||
|
#define __UART_H__
|
||||||
|
|
||||||
|
#include "__def.h"
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
__IO uint32_t cr;
|
||||||
|
__IO uint32_t sr;
|
||||||
|
__I uint32_t baud;
|
||||||
|
__I uint32_t rxd;
|
||||||
|
__IO uint32_t txd;
|
||||||
|
} UART_Type;
|
||||||
|
|
||||||
|
#define UART_BASE (0x30000000)
|
||||||
|
|
||||||
|
#define UART1 ((UART_Type*)(UART_BASE))
|
||||||
|
#define UART2 ((UART_Type*)(UART_BASE + 0x10000000))
|
||||||
|
#define UART3 ((UART_Type*)(UART_BASE + 0x20000000))
|
||||||
|
|
||||||
|
// [0]: tx enbale
|
||||||
|
// [1]: rx enbale
|
||||||
|
#define UART_CR_TX_EN (uint32_t)(1 << 0)
|
||||||
|
#define UART_CR_RX_EN (uint32_t)(1 << 1)
|
||||||
|
|
||||||
|
// [0]: tx flag
|
||||||
|
// [1]: rx flag
|
||||||
|
#define UART_SR_FLAG_TXE (uint32_t)(1 << 0)
|
||||||
|
#define UART_SR_FLAG_RXNE (uint32_t)(1 << 1)
|
||||||
|
|
||||||
|
#define UART_SR_CLR_TXE (uint32_t)(1 << 0) //write "1" clear
|
||||||
|
#define UART_SR_CLR_RXNE (uint32_t)(1 << 1)
|
||||||
|
|
||||||
|
void uart_send(UART_Type *uart, uint8_t data);
|
||||||
|
void uart_send_wait(UART_Type *uart, uint8_t data);
|
||||||
|
|
||||||
|
uint8_t uart_read(UART_Type *uart);
|
||||||
|
uint8_t uart_read_wait(UART_Type *uart);
|
||||||
|
|
||||||
|
#endif //#ifndef __UART_H__
|
|
@ -0,0 +1,56 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021, SERI Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2021-10-29 Lyons first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
.section .init
|
||||||
|
|
||||||
|
.globl _start
|
||||||
|
.type _start,@function
|
||||||
|
|
||||||
|
_start:
|
||||||
|
.option push
|
||||||
|
.option pop
|
||||||
|
la gp, __stack_top
|
||||||
|
addi sp, gp, -1024
|
||||||
|
|
||||||
|
la a0, __bss_start
|
||||||
|
la a1, __bss_end
|
||||||
|
bgeu a0, a1, _bss_init_end
|
||||||
|
_bss_init_begin:
|
||||||
|
sw zero, 0(a0)
|
||||||
|
addi a0, a0, 4
|
||||||
|
bltu a0, a1, _bss_init_begin
|
||||||
|
_bss_init_end:
|
||||||
|
|
||||||
|
la a0, __data_lma
|
||||||
|
la a1, __data_start
|
||||||
|
la a2, __data_end
|
||||||
|
bgeu a1, a2, _data_init_end
|
||||||
|
_data_init_begin:
|
||||||
|
lw t0, 0(a0)
|
||||||
|
sw t0, 0(a1)
|
||||||
|
addi a0, a0, 4
|
||||||
|
addi a1, a1, 4
|
||||||
|
bltu a1, a2, _data_init_begin
|
||||||
|
_data_init_end:
|
||||||
|
|
||||||
|
call init
|
||||||
|
call entry
|
||||||
|
|
||||||
|
loop:
|
||||||
|
j loop
|
||||||
|
|
||||||
|
.weak init
|
||||||
|
init:
|
||||||
|
ret
|
||||||
|
|
||||||
|
.weak entry
|
||||||
|
entry:
|
||||||
|
call main
|
||||||
|
ret
|
|
@ -0,0 +1,179 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021, SERI Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2021-10-29 Lyons first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
.section .text
|
||||||
|
|
||||||
|
.global interrupt_enable
|
||||||
|
.align 2
|
||||||
|
interrupt_disable:
|
||||||
|
csrrci a0, mstatus, 8
|
||||||
|
ret
|
||||||
|
|
||||||
|
.global interrupt_disable
|
||||||
|
.align 2
|
||||||
|
interrupt_enable:
|
||||||
|
csrw mstatus, a0
|
||||||
|
ret
|
||||||
|
|
||||||
|
/* Macro for saving task context */
|
||||||
|
.macro save_context
|
||||||
|
addi sp, sp, -32*4
|
||||||
|
|
||||||
|
sw x1, 1*4(sp)
|
||||||
|
|
||||||
|
csrr x1, mepc
|
||||||
|
sw x1, 0*4(sp)
|
||||||
|
|
||||||
|
li x1, 0x0088
|
||||||
|
sw x1, 2*4(sp)
|
||||||
|
|
||||||
|
sw x4, 4*4(sp)
|
||||||
|
sw x5, 5*4(sp)
|
||||||
|
sw x6, 6*4(sp)
|
||||||
|
sw x7, 7*4(sp)
|
||||||
|
sw x8, 8*4(sp)
|
||||||
|
sw x9, 9*4(sp)
|
||||||
|
sw x10, 10*4(sp)
|
||||||
|
sw x11, 11*4(sp)
|
||||||
|
sw x12, 12*4(sp)
|
||||||
|
sw x13, 13*4(sp)
|
||||||
|
sw x14, 14*4(sp)
|
||||||
|
sw x15, 15*4(sp)
|
||||||
|
sw x16, 16*4(sp)
|
||||||
|
sw x17, 17*4(sp)
|
||||||
|
sw x18, 18*4(sp)
|
||||||
|
sw x19, 19*4(sp)
|
||||||
|
sw x20, 20*4(sp)
|
||||||
|
sw x21, 21*4(sp)
|
||||||
|
sw x22, 22*4(sp)
|
||||||
|
sw x23, 23*4(sp)
|
||||||
|
sw x24, 24*4(sp)
|
||||||
|
sw x25, 25*4(sp)
|
||||||
|
sw x26, 26*4(sp)
|
||||||
|
sw x27, 27*4(sp)
|
||||||
|
sw x28, 28*4(sp)
|
||||||
|
sw x29, 29*4(sp)
|
||||||
|
sw x30, 30*4(sp)
|
||||||
|
sw x31, 31*4(sp)
|
||||||
|
.endm
|
||||||
|
|
||||||
|
/* Macro for restoring task context */
|
||||||
|
.macro restore_context
|
||||||
|
lw x1, 0*4(sp)
|
||||||
|
csrw mepc, x1
|
||||||
|
|
||||||
|
lw x1, 1*4(sp)
|
||||||
|
|
||||||
|
li t0, 0x1800
|
||||||
|
csrw mstatus, t0
|
||||||
|
lw t0, 2*4(sp)
|
||||||
|
csrs mstatus, t0
|
||||||
|
|
||||||
|
lw x4, 4*4(sp)
|
||||||
|
lw x5, 5*4(sp)
|
||||||
|
lw x6, 6*4(sp)
|
||||||
|
lw x7, 7*4(sp)
|
||||||
|
lw x8, 8*4(sp)
|
||||||
|
lw x9, 9*4(sp)
|
||||||
|
lw x10, 10*4(sp)
|
||||||
|
lw x11, 11*4(sp)
|
||||||
|
lw x12, 12*4(sp)
|
||||||
|
lw x13, 13*4(sp)
|
||||||
|
lw x14, 14*4(sp)
|
||||||
|
lw x15, 15*4(sp)
|
||||||
|
lw x16, 16*4(sp)
|
||||||
|
lw x17, 17*4(sp)
|
||||||
|
lw x18, 18*4(sp)
|
||||||
|
lw x19, 19*4(sp)
|
||||||
|
lw x20, 20*4(sp)
|
||||||
|
lw x21, 21*4(sp)
|
||||||
|
lw x22, 22*4(sp)
|
||||||
|
lw x23, 23*4(sp)
|
||||||
|
lw x24, 24*4(sp)
|
||||||
|
lw x25, 25*4(sp)
|
||||||
|
lw x26, 26*4(sp)
|
||||||
|
lw x27, 27*4(sp)
|
||||||
|
lw x28, 28*4(sp)
|
||||||
|
lw x29, 29*4(sp)
|
||||||
|
lw x30, 30*4(sp)
|
||||||
|
lw x31, 31*4(sp)
|
||||||
|
|
||||||
|
addi sp, sp, 32*4
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.global trap_entry
|
||||||
|
.align 2
|
||||||
|
trap_entry:
|
||||||
|
j vector_handler
|
||||||
|
|
||||||
|
vector_handler:
|
||||||
|
_save:
|
||||||
|
save_context
|
||||||
|
|
||||||
|
#ifdef OS_ENABLE_RT_THREAD
|
||||||
|
la t0, rt_interrupt_nest
|
||||||
|
li t1, 1
|
||||||
|
sb t1, 0(t0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
csrr a0, mcause
|
||||||
|
csrr a1, mepc
|
||||||
|
|
||||||
|
srli t0, a0, 31
|
||||||
|
beq t0, a0, _is_exception
|
||||||
|
|
||||||
|
csrw mscratch, sp
|
||||||
|
mv sp, gp
|
||||||
|
|
||||||
|
call trap_handler
|
||||||
|
|
||||||
|
csrr sp, mscratch
|
||||||
|
|
||||||
|
j _is_interrupt
|
||||||
|
|
||||||
|
_is_exception:
|
||||||
|
addi a1, a1, 4
|
||||||
|
csrw mepc, a1
|
||||||
|
|
||||||
|
_is_interrupt:
|
||||||
|
|
||||||
|
#ifdef OS_ENABLE_RT_THREAD
|
||||||
|
la s0, rt_thread_switch_interrupt_flag
|
||||||
|
lw s2, 0(s0)
|
||||||
|
beqz s2, _restore
|
||||||
|
sw zero, 0(s0)
|
||||||
|
|
||||||
|
la s0, rt_interrupt_from_thread
|
||||||
|
lw s1, 0(s0)
|
||||||
|
sw sp, 0(s1)
|
||||||
|
|
||||||
|
la s0, rt_interrupt_to_thread
|
||||||
|
lw s1, 0(s0)
|
||||||
|
lw sp, 0(s1)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
_restore:
|
||||||
|
#ifdef OS_ENABLE_RT_THREAD
|
||||||
|
la t0, rt_interrupt_nest
|
||||||
|
sb zero, 0(t0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
restore_context
|
||||||
|
|
||||||
|
mret
|
||||||
|
|
||||||
|
_nop_list:
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
|
||||||
|
.weak trap_handler
|
||||||
|
trap_handler:
|
||||||
|
ret
|
|
@ -0,0 +1,165 @@
|
||||||
|
/*------------------------------------------------------------------------/
|
||||||
|
/ Universal string handler for user console interface
|
||||||
|
/-------------------------------------------------------------------------/
|
||||||
|
/
|
||||||
|
/ Copyright (C) 2011, ChaN, all right reserved.
|
||||||
|
/
|
||||||
|
/ * This software is a free software and there is NO WARRANTY.
|
||||||
|
/ * No restriction on use. You can use, modify and redistribute it for
|
||||||
|
/ personal, non-profit or commercial products UNDER YOUR RESPONSIBILITY.
|
||||||
|
/ * Redistributions of source code must retain the above copyright notice.
|
||||||
|
/
|
||||||
|
/-------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#include "__def.h"
|
||||||
|
|
||||||
|
#include "uart.h"
|
||||||
|
#include "xprintf.h"
|
||||||
|
|
||||||
|
/*----------------------------------------------*/
|
||||||
|
/* Put a character */
|
||||||
|
/*----------------------------------------------*/
|
||||||
|
|
||||||
|
void xputc (char c)
|
||||||
|
{
|
||||||
|
if ('\n' == c)
|
||||||
|
{
|
||||||
|
#ifdef PRINT_STDIO_SIM
|
||||||
|
_csr_putc( (1<<31)|(uint8_t)'\r' ); _csr_putc(0);
|
||||||
|
#else
|
||||||
|
_uart_putc( (uint8_t)'\r' );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef PRINT_STDIO_SIM
|
||||||
|
_csr_putc( (1<<31)|(uint8_t)c ); _csr_putc(0);
|
||||||
|
#else
|
||||||
|
_uart_putc( (uint8_t)c );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*----------------------------------------------*/
|
||||||
|
/* Put a null-terminated string */
|
||||||
|
/*----------------------------------------------*/
|
||||||
|
|
||||||
|
void xputs ( /* Put a string to the default device */
|
||||||
|
const char* str /* Pointer to the string */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
while (*str)
|
||||||
|
xputc(*str++);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*----------------------------------------------*/
|
||||||
|
/* Formatted string output */
|
||||||
|
/*----------------------------------------------*/
|
||||||
|
/* xprintf("%d", 1234); "1234"
|
||||||
|
xprintf("%6d,%3d%%", -200, 5); " -200, 5%"
|
||||||
|
xprintf("%-6u", 100); "100 "
|
||||||
|
xprintf("%ld", 12345678L); "12345678"
|
||||||
|
xprintf("%04x", 0xA3); "00a3"
|
||||||
|
xprintf("%08LX", 0x123ABC); "00123ABC"
|
||||||
|
xprintf("%016b", 0x550F); "0101010100001111"
|
||||||
|
xprintf("%s", "String"); "String"
|
||||||
|
xprintf("%-4s", "abc"); "abc "
|
||||||
|
xprintf("%4s", "abc"); " abc"
|
||||||
|
xprintf("%c", 'a'); "a"
|
||||||
|
xprintf("%f", 10.0); <xprintf lacks floating point support>
|
||||||
|
*/
|
||||||
|
|
||||||
|
static
|
||||||
|
void xvprintf (
|
||||||
|
const char* fmt, /* Pointer to the format string */
|
||||||
|
va_list arp /* Pointer to arguments */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
unsigned int r, i, j, w, f;
|
||||||
|
unsigned long v;
|
||||||
|
char s[16], c, d, *p;
|
||||||
|
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
c = *fmt++; /* Get a char */
|
||||||
|
if (!c) break; /* End of format? */
|
||||||
|
if (c != '%') { /* Pass through it if not a % sequense */
|
||||||
|
xputc(c); continue;
|
||||||
|
}
|
||||||
|
f = 0;
|
||||||
|
c = *fmt++; /* Get first char of the sequense */
|
||||||
|
if (c == '0') { /* Flag: '0' padded */
|
||||||
|
f = 1; c = *fmt++;
|
||||||
|
} else {
|
||||||
|
if (c == '-') { /* Flag: left justified */
|
||||||
|
f = 2; c = *fmt++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (w = 0; c >= '0' && c <= '9'; c = *fmt++) /* Minimum width */
|
||||||
|
w = w * 10 + c - '0';
|
||||||
|
if (c == 'l' || c == 'L') { /* Prefix: Size is long int */
|
||||||
|
f |= 4; c = *fmt++;
|
||||||
|
}
|
||||||
|
if (!c) break; /* End of format? */
|
||||||
|
d = c;
|
||||||
|
if (d >= 'a') d -= 0x20;
|
||||||
|
switch (d) { /* Type is... */
|
||||||
|
case 'S' : /* String */
|
||||||
|
p = va_arg(arp, char*);
|
||||||
|
for (j = 0; p[j]; j++) ;
|
||||||
|
while (!(f & 2) && j++ < w) xputc(' ');
|
||||||
|
xputs(p);
|
||||||
|
while (j++ < w) xputc(' ');
|
||||||
|
continue;
|
||||||
|
case 'C' : /* Character */
|
||||||
|
xputc((char)va_arg(arp, int)); continue;
|
||||||
|
case 'B' : /* Binary */
|
||||||
|
r = 2; break;
|
||||||
|
case 'O' : /* Octal */
|
||||||
|
r = 8; break;
|
||||||
|
case 'D' : /* Signed decimal */
|
||||||
|
case 'U' : /* Unsigned decimal */
|
||||||
|
r = 10; break;
|
||||||
|
case 'X' : /* Hexdecimal */
|
||||||
|
r = 16; break;
|
||||||
|
default: /* Unknown type (passthrough) */
|
||||||
|
xputc(c); continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get an argument and put it in numeral */
|
||||||
|
v = (f & 4) ? va_arg(arp, long) : ((d == 'D') ? (long)va_arg(arp, int) : (long)va_arg(arp, unsigned int));
|
||||||
|
if (d == 'D' && (v & 0x80000000)) {
|
||||||
|
v = 0 - v;
|
||||||
|
f |= 8;
|
||||||
|
}
|
||||||
|
i = 0;
|
||||||
|
do {
|
||||||
|
if (2 == r) {d = (char)(v & 0x00000001); v >>= 1;}
|
||||||
|
else if (8 == r) {d = (char)(v & 0x00000007); v >>= 3;}
|
||||||
|
else if (10 == r) {d = (char)(v % r); v /= r;}
|
||||||
|
else if (16 == r) {d = (char)(v & 0x0000000f); v >>= 4;}
|
||||||
|
else {d = 0; v = 0;}
|
||||||
|
if (d > 9) d += (c == 'x') ? 0x27 : 0x07;
|
||||||
|
s[i++] = d + '0';
|
||||||
|
} while (v && i < sizeof(s));
|
||||||
|
if (f & 8) s[i++] = '-';
|
||||||
|
j = i; d = (f & 1) ? '0' : ' ';
|
||||||
|
while (!(f & 2) && j++ < w) xputc(d);
|
||||||
|
do xputc(s[--i]); while(i);
|
||||||
|
while (j++ < w) xputc(' ');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void xprintf ( /* Put a formatted string to the default device */
|
||||||
|
const char* fmt, /* Pointer to the format string */
|
||||||
|
... /* Optional arguments */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
va_list arp;
|
||||||
|
|
||||||
|
va_start(arp, fmt);
|
||||||
|
xvprintf(fmt, arp);
|
||||||
|
va_end(arp);
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
/*------------------------------------------------------------------------/
|
||||||
|
/ Universal string handler for user console interface
|
||||||
|
/-------------------------------------------------------------------------/
|
||||||
|
/
|
||||||
|
/ Copyright (C) 2011, ChaN, all right reserved.
|
||||||
|
/
|
||||||
|
/ * This software is a free software and there is NO WARRANTY.
|
||||||
|
/ * No restriction on use. You can use, modify and redistribute it for
|
||||||
|
/ personal, non-profit or commercial products UNDER YOUR RESPONSIBILITY.
|
||||||
|
/ * Redistributions of source code must retain the above copyright notice.
|
||||||
|
/
|
||||||
|
/-------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef _XPRINTF_H_
|
||||||
|
#define _XPRINTF_H_
|
||||||
|
|
||||||
|
void xputc (char c);
|
||||||
|
void xputs (const char* str);
|
||||||
|
void xprintf (const char* fmt, ...);
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,22 @@
|
||||||
|
#.gitignore
|
||||||
|
|
||||||
|
# Step-1, track all files in the current folder
|
||||||
|
!*
|
||||||
|
|
||||||
|
# Step-2, track specified files in the current folder
|
||||||
|
*
|
||||||
|
!*/
|
||||||
|
!.gitignore
|
||||||
|
!*.mk
|
||||||
|
!Makefile
|
||||||
|
!*.lds
|
||||||
|
!*.h
|
||||||
|
!*.c
|
||||||
|
!*.s
|
||||||
|
!*.S
|
||||||
|
|
||||||
|
# Step-3, untrack all in sub folders, which use their own .gitignore
|
||||||
|
*/*
|
||||||
|
!driver/*
|
||||||
|
!rtthread-nano/*
|
||||||
|
|
|
@ -0,0 +1,74 @@
|
||||||
|
#/*
|
||||||
|
# * Copyright {c} 2020-2021, SERI Development Team
|
||||||
|
# *
|
||||||
|
# * SPDX-License-Identifier: Apache-2.0
|
||||||
|
# *
|
||||||
|
# * Change Logs:
|
||||||
|
# * Date Author Notes
|
||||||
|
# * 2022-03-27 Lyons first version
|
||||||
|
# */
|
||||||
|
|
||||||
|
TARGET = riscv
|
||||||
|
|
||||||
|
Q = @
|
||||||
|
|
||||||
|
PROJPATH = ../..
|
||||||
|
WORKPATH = .
|
||||||
|
|
||||||
|
include ../config.mk
|
||||||
|
|
||||||
|
INCLUDES += -I.
|
||||||
|
|
||||||
|
INCFILES += -I${WORKPATH}/rtthread-nano/bsp \
|
||||||
|
-I${WORKPATH}/rtthread-nano/components/finsh \
|
||||||
|
-I${WORKPATH}/rtthread-nano/include \
|
||||||
|
-I${WORKPATH}/rtthread-nano/include/libc \
|
||||||
|
-I${WORKPATH}/libs/_kernel/libcpu/risc-v/common
|
||||||
|
|
||||||
|
INCFILES += -I${WORKPATH}/driver
|
||||||
|
|
||||||
|
CFLAGS += -O0 -ffunction-sections -fdata-sections
|
||||||
|
# CFLAGS += -g
|
||||||
|
CFLAGS += -Wno-pointer-to-int-cast -Wno-int-to-pointer-cast
|
||||||
|
CFLAGS += -DOS_ENABLE_RT_THREAD
|
||||||
|
# CFLAGS += -DPRINT_STDIO_SIM
|
||||||
|
CFLAGS += -DSIMULATION_PRINT_VERSION
|
||||||
|
# CFLAGS += -DSIMULATION_PRINT_THREAD_SWITCH
|
||||||
|
|
||||||
|
LDFLAGS += -T${WORKPATH}/link.lds
|
||||||
|
|
||||||
|
LDLIBS +=
|
||||||
|
|
||||||
|
ASMFILES += ${WORKPATH}/rtthread-nano/libcpu/risc-v/common/context_gcc.S
|
||||||
|
|
||||||
|
CFILES += ${WORKPATH}/rtthread-nano/bsp/board.c \
|
||||||
|
${WORKPATH}/rtthread-nano/components/device/device.c \
|
||||||
|
${WORKPATH}/rtthread-nano/components/finsh/cmd.c \
|
||||||
|
${WORKPATH}/rtthread-nano/components/finsh/finsh_port.c \
|
||||||
|
${WORKPATH}/rtthread-nano/components/finsh/msh.c \
|
||||||
|
${WORKPATH}/rtthread-nano/components/finsh/shell.c \
|
||||||
|
${WORKPATH}/rtthread-nano/libcpu/risc-v/common/cpuport.c \
|
||||||
|
${WORKPATH}/rtthread-nano/src/clock.c \
|
||||||
|
${WORKPATH}/rtthread-nano/src/components.c \
|
||||||
|
${WORKPATH}/rtthread-nano/src/cpu.c \
|
||||||
|
${WORKPATH}/rtthread-nano/src/idle.c \
|
||||||
|
${WORKPATH}/rtthread-nano/src/ipc.c \
|
||||||
|
${WORKPATH}/rtthread-nano/src/irq.c \
|
||||||
|
${WORKPATH}/rtthread-nano/src/kservice.c \
|
||||||
|
${WORKPATH}/rtthread-nano/src/mem.c \
|
||||||
|
${WORKPATH}/rtthread-nano/src/memheap.c \
|
||||||
|
${WORKPATH}/rtthread-nano/src/mempool.c \
|
||||||
|
${WORKPATH}/rtthread-nano/src/object.c \
|
||||||
|
${WORKPATH}/rtthread-nano/src/scheduler.c \
|
||||||
|
${WORKPATH}/rtthread-nano/src/slab.c \
|
||||||
|
${WORKPATH}/rtthread-nano/src/thread.c \
|
||||||
|
${WORKPATH}/rtthread-nano/src/timer.c
|
||||||
|
|
||||||
|
CFILES += ${WORKPATH}/driver/Driver_tftspi.c \
|
||||||
|
${WORKPATH}/driver/Task_tft.c
|
||||||
|
|
||||||
|
CFILES += ${WORKPATH}/init.c \
|
||||||
|
${WORKPATH}/interrupt.c \
|
||||||
|
${WORKPATH}/main.c
|
||||||
|
|
||||||
|
include ../build.mk
|
|
@ -0,0 +1,629 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* TFT 1.14寸显示屏驱动文件,目前使用SPI
|
||||||
|
*
|
||||||
|
* 版本修订:
|
||||||
|
* 修改时间 版本号 修改内容
|
||||||
|
* 2022-12-07 v1.0 开始构建本文件;
|
||||||
|
*
|
||||||
|
* Create :2016年09月09日
|
||||||
|
* Update :2022年12月07日
|
||||||
|
* Author :dengchow
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
***/
|
||||||
|
|
||||||
|
#include "Driver_tftspi.h"
|
||||||
|
|
||||||
|
#define LCD_MODE 2
|
||||||
|
// 0 // 竖屏
|
||||||
|
// 1
|
||||||
|
// 2 // 横屏
|
||||||
|
// 3
|
||||||
|
|
||||||
|
uint16_t POINT_COLOR = 0x0000;//画笔颜色
|
||||||
|
uint16_t BACK_COLOR = 0xFFFF;//背景色
|
||||||
|
|
||||||
|
_TFTCmdTypeStruct TFTCmd;//管理LCD重要参数
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief :模拟SPI发送数据
|
||||||
|
* @note :--
|
||||||
|
* @param :dat,待发送的数据
|
||||||
|
* @return :void
|
||||||
|
*
|
||||||
|
* @data :2023/01/21
|
||||||
|
* @design :
|
||||||
|
**/
|
||||||
|
static void _spi_write_data(uint8_t dat)
|
||||||
|
{
|
||||||
|
#ifdef LCD_SPI_SOFT
|
||||||
|
for (uint8_t i=0; i<8; i++)
|
||||||
|
{
|
||||||
|
LCD_SCL_L;
|
||||||
|
if (dat & 0x80) {
|
||||||
|
LCD_SDA_H;
|
||||||
|
} else {
|
||||||
|
LCD_SDA_L;
|
||||||
|
}
|
||||||
|
LCD_SCL_H;
|
||||||
|
dat <<= 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief :写寄存器地址
|
||||||
|
* @note :--
|
||||||
|
* @param :reg, 寄存器地址
|
||||||
|
* @return :void
|
||||||
|
*
|
||||||
|
* @data :2017/03/04
|
||||||
|
* @design :
|
||||||
|
**/
|
||||||
|
void TFT_WR_REG(uint16_t reg)
|
||||||
|
{
|
||||||
|
TFT_DC_CMD();
|
||||||
|
_spi_write_data(reg);
|
||||||
|
|
||||||
|
TFT_DC_DATA();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief :写数据
|
||||||
|
* @note :--使用此函数前先调用TFT_WR_REG(),即写寄存器函数!
|
||||||
|
* @param :dat, 要写入的值
|
||||||
|
* @return :void
|
||||||
|
*
|
||||||
|
* @data :2017/03/04
|
||||||
|
* @design :
|
||||||
|
**/
|
||||||
|
void TFT_WR_DATA8(uint8_t dat)
|
||||||
|
{
|
||||||
|
_spi_write_data(dat);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TFT_WR_DATA(uint16_t dat)
|
||||||
|
{
|
||||||
|
_spi_write_data(dat>>8);
|
||||||
|
_spi_write_data(dat);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief :读数据
|
||||||
|
* @note :--读数据前先写寄存器地址!
|
||||||
|
* @param :void
|
||||||
|
* @return :uint16_t, 读到的值
|
||||||
|
*
|
||||||
|
* @data :2017/03/04
|
||||||
|
* @design :
|
||||||
|
**/
|
||||||
|
uint16_t TFT_RD_DATA(void)
|
||||||
|
{
|
||||||
|
return BACK_COLOR; // NO USED!
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief :选择lcd设备
|
||||||
|
* @note :--
|
||||||
|
* @param :idx, lcd序号
|
||||||
|
en, 1选中/0未选中
|
||||||
|
* @return :void
|
||||||
|
*
|
||||||
|
* @data :2017/03/04
|
||||||
|
* @design :
|
||||||
|
**/
|
||||||
|
void TFT_Select(uint8_t idx, uint8_t en)
|
||||||
|
{
|
||||||
|
if (0 == en)
|
||||||
|
{
|
||||||
|
switch (idx)
|
||||||
|
{
|
||||||
|
case 0: LCD_CS0_DIS; break;
|
||||||
|
|
||||||
|
default: {
|
||||||
|
LCD_CS0_DIS;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
switch (idx)
|
||||||
|
{
|
||||||
|
case 0: LCD_CS0_EN; break;
|
||||||
|
|
||||||
|
default: {
|
||||||
|
LCD_CS0_EN;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief :向寄存器写数据
|
||||||
|
* @note :--
|
||||||
|
* @param :reg, 寄存器地址
|
||||||
|
dat, 要写入的值
|
||||||
|
* @return :void
|
||||||
|
*
|
||||||
|
* @data :2017/03/04
|
||||||
|
* @design :
|
||||||
|
**/
|
||||||
|
void TFT_WriteReg(uint16_t reg, uint16_t dat)
|
||||||
|
{
|
||||||
|
TFT_WR_REG(reg);
|
||||||
|
TFT_WR_DATA(dat);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief :从寄存器读数据
|
||||||
|
* @note :--
|
||||||
|
* @param :Reg, 寄存器地址
|
||||||
|
* @return :uint16_t, 读到的数据
|
||||||
|
*
|
||||||
|
* @data :2017/03/04
|
||||||
|
* @design :
|
||||||
|
**/
|
||||||
|
uint16_t TFT_ReadReg(uint16_t reg)
|
||||||
|
{
|
||||||
|
return 0xFFFF; // NO USED!
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief :开始写GRAM
|
||||||
|
* @note :--
|
||||||
|
* @param :void
|
||||||
|
* @return :void
|
||||||
|
*
|
||||||
|
* @data :2017/03/04
|
||||||
|
* @design :
|
||||||
|
**/
|
||||||
|
void TFT_StartWriteRAM(void)
|
||||||
|
{
|
||||||
|
TFT_WR_REG(0x2C);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief :写GRAM
|
||||||
|
* @note :--
|
||||||
|
* @param :color, 颜色值
|
||||||
|
* @return :void
|
||||||
|
*
|
||||||
|
* @data :2017/03/04
|
||||||
|
* @design :
|
||||||
|
**/
|
||||||
|
void TFT_WriteRAM(uint16_t color)
|
||||||
|
{
|
||||||
|
TFT_WR_DATA(color);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief :tft开启显示
|
||||||
|
* @note :
|
||||||
|
* @param :void
|
||||||
|
* @return :void
|
||||||
|
*
|
||||||
|
* @data :2017/03/04
|
||||||
|
* @design :
|
||||||
|
**/
|
||||||
|
void TFT_DisplayOn(void)
|
||||||
|
{
|
||||||
|
// NO USED!
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief :tft关闭显示
|
||||||
|
* @note :--
|
||||||
|
* @param :void
|
||||||
|
* @return :void
|
||||||
|
*
|
||||||
|
* @data :2017/03/04
|
||||||
|
* @design :
|
||||||
|
**/
|
||||||
|
void TFT_DisplayOff(void)
|
||||||
|
{
|
||||||
|
// NO USED!
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief :设置光标位置
|
||||||
|
* @note :--
|
||||||
|
* @param :X1, 横坐标(0~TFTCmd.width)
|
||||||
|
Y1, 纵坐标(0~TFTCmd.height)
|
||||||
|
X2, 横坐标(0~TFTCmd.width)
|
||||||
|
Y3, 纵坐标(0~TFTCmd.height)
|
||||||
|
* @return :void
|
||||||
|
*
|
||||||
|
* @data :2017/03/04
|
||||||
|
* @design :
|
||||||
|
**/
|
||||||
|
void TFT_SetCursor(uint16_t X1, uint16_t Y1, uint16_t X2, uint16_t Y2)
|
||||||
|
{
|
||||||
|
#if (LCD_MODE == 0)
|
||||||
|
const uint16_t _k_x_base = 52;
|
||||||
|
const uint16_t _k_y_base = 40;
|
||||||
|
#endif
|
||||||
|
#if (LCD_MODE == 1)
|
||||||
|
const uint16_t _k_x_base = 53;
|
||||||
|
const uint16_t _k_y_base = 40;
|
||||||
|
#endif
|
||||||
|
#if (LCD_MODE == 2)
|
||||||
|
const uint16_t _k_x_base = 40;
|
||||||
|
const uint16_t _k_y_base = 53;
|
||||||
|
#endif
|
||||||
|
#if (LCD_MODE == 3)
|
||||||
|
const uint16_t _k_x_base = 40;
|
||||||
|
const uint16_t _k_y_base = 52;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
TFT_WR_REG(0x2A); //列地址设置
|
||||||
|
TFT_WR_DATA(X1+_k_x_base);
|
||||||
|
TFT_WR_DATA(X2+_k_x_base);
|
||||||
|
|
||||||
|
TFT_WR_REG(0x2B); //行地址设置
|
||||||
|
TFT_WR_DATA(Y1+_k_y_base);
|
||||||
|
TFT_WR_DATA(Y2+_k_y_base);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief :设置tft的自动扫描方向
|
||||||
|
* @note :--ILI9341的其他函数可能会受到此函数设置的影响,所以,一般设置为L2R_U2D!
|
||||||
|
--针对ILI9341进行修改,修复无法横屏的bug!
|
||||||
|
--设置ILI9341默认为RGB格式!
|
||||||
|
* @param :direct, 扫描方向(_TFTScanDir枚举类型中定义!)
|
||||||
|
* @return :void
|
||||||
|
*
|
||||||
|
* @data :2018/01/24
|
||||||
|
* @design :
|
||||||
|
**/
|
||||||
|
void TFT_SetScanDir(_TFTScanDir direct)
|
||||||
|
{
|
||||||
|
// NO USED!
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief :设置tft显示方向
|
||||||
|
* @note :--
|
||||||
|
* @param :direct, 显示方向(_TFTDispDir枚举类型定义!)
|
||||||
|
* @return :void
|
||||||
|
*
|
||||||
|
* @data :2017/03/04
|
||||||
|
* @design :
|
||||||
|
**/
|
||||||
|
void TFT_SetDisplayDir(_TFTDispDir direct)
|
||||||
|
{
|
||||||
|
if(direct == DISP_PORTRAIT)//竖屏
|
||||||
|
{
|
||||||
|
TFTCmd.dir = DISP_PORTRAIT;
|
||||||
|
TFTCmd.width = CFG_LCD_Y_SIZE;
|
||||||
|
TFTCmd.height = CFG_LCD_X_SIZE;
|
||||||
|
}else{//横屏
|
||||||
|
TFTCmd.dir = DISP_HORIZON;
|
||||||
|
TFTCmd.width = CFG_LCD_X_SIZE;
|
||||||
|
TFTCmd.height = CFG_LCD_Y_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
TFTCmd.wramcmd = 0; // NO USED!
|
||||||
|
TFTCmd.setxcmd = 0; // NO USED!
|
||||||
|
TFTCmd.setycmd = 0; // NO USED!
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief :设置tft窗口大小
|
||||||
|
* @note :--窗体大小,width*height!
|
||||||
|
* @param :XS , 窗口起始横坐标
|
||||||
|
YS , 窗口起始纵坐标
|
||||||
|
width , 窗口宽度,必须大于0!
|
||||||
|
height, 窗口高度,必须大于0!
|
||||||
|
* @return :void
|
||||||
|
*
|
||||||
|
* @data :2017/03/04
|
||||||
|
* @design :
|
||||||
|
**/
|
||||||
|
void TFT_SetWindowSize(uint16_t XS, uint16_t YS, uint16_t width, uint16_t height)
|
||||||
|
{
|
||||||
|
// NO USED!
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief :tft初始化设置
|
||||||
|
* @note :--
|
||||||
|
* @param :void
|
||||||
|
* @return :void
|
||||||
|
*
|
||||||
|
* @data :2017/03/04
|
||||||
|
* @design :
|
||||||
|
**/
|
||||||
|
void TFT_InitConfig(void)
|
||||||
|
{
|
||||||
|
TFT_BACK_LED_CLOSE();
|
||||||
|
|
||||||
|
TFT_Select(0xff, 1); // SELECT ALL DEVICE!
|
||||||
|
|
||||||
|
TFT_RST_HIGH();
|
||||||
|
delay_ms(1);
|
||||||
|
TFT_RST_LOW();
|
||||||
|
delay_ms(10);
|
||||||
|
TFT_RST_HIGH();
|
||||||
|
delay_ms(120);
|
||||||
|
|
||||||
|
TFT_WR_REG(0x36);
|
||||||
|
#if (LCD_MODE == 0)
|
||||||
|
TFT_WR_DATA8(0x00);
|
||||||
|
#endif
|
||||||
|
#if (LCD_MODE == 1)
|
||||||
|
TFT_WR_DATA8(0xC0);
|
||||||
|
#endif
|
||||||
|
#if (LCD_MODE == 2)
|
||||||
|
TFT_WR_DATA8(0x70);
|
||||||
|
#endif
|
||||||
|
#if (LCD_MODE == 3)
|
||||||
|
TFT_WR_DATA8(0xA0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
TFT_WR_REG(0x3A);
|
||||||
|
TFT_WR_DATA8(0x05);
|
||||||
|
|
||||||
|
TFT_WR_REG(0xB2);
|
||||||
|
TFT_WR_DATA8(0x0C);
|
||||||
|
TFT_WR_DATA8(0x0C);
|
||||||
|
TFT_WR_DATA8(0x00);
|
||||||
|
TFT_WR_DATA8(0x33);
|
||||||
|
TFT_WR_DATA8(0x33);
|
||||||
|
|
||||||
|
TFT_WR_REG(0xB7);
|
||||||
|
TFT_WR_DATA8(0x35);
|
||||||
|
|
||||||
|
TFT_WR_REG(0xBB);
|
||||||
|
TFT_WR_DATA8(0x19);
|
||||||
|
|
||||||
|
TFT_WR_REG(0xC0);
|
||||||
|
TFT_WR_DATA8(0x2C);
|
||||||
|
|
||||||
|
TFT_WR_REG(0xC2);
|
||||||
|
TFT_WR_DATA8(0x01);
|
||||||
|
|
||||||
|
TFT_WR_REG(0xC3);
|
||||||
|
TFT_WR_DATA8(0x12);
|
||||||
|
|
||||||
|
TFT_WR_REG(0xC4);
|
||||||
|
TFT_WR_DATA8(0x20);
|
||||||
|
|
||||||
|
TFT_WR_REG(0xC6);
|
||||||
|
TFT_WR_DATA8(0x0F);
|
||||||
|
|
||||||
|
TFT_WR_REG(0xD0);
|
||||||
|
TFT_WR_DATA8(0xA4);
|
||||||
|
TFT_WR_DATA8(0xA1);
|
||||||
|
|
||||||
|
TFT_WR_REG(0xE0);
|
||||||
|
TFT_WR_DATA8(0xD0);
|
||||||
|
TFT_WR_DATA8(0x04);
|
||||||
|
TFT_WR_DATA8(0x0D);
|
||||||
|
TFT_WR_DATA8(0x11);
|
||||||
|
TFT_WR_DATA8(0x13);
|
||||||
|
TFT_WR_DATA8(0x2B);
|
||||||
|
TFT_WR_DATA8(0x3F);
|
||||||
|
TFT_WR_DATA8(0x54);
|
||||||
|
TFT_WR_DATA8(0x4C);
|
||||||
|
TFT_WR_DATA8(0x18);
|
||||||
|
TFT_WR_DATA8(0x0D);
|
||||||
|
TFT_WR_DATA8(0x0B);
|
||||||
|
TFT_WR_DATA8(0x1F);
|
||||||
|
TFT_WR_DATA8(0x23);
|
||||||
|
|
||||||
|
TFT_WR_REG(0xE1);
|
||||||
|
TFT_WR_DATA8(0xD0);
|
||||||
|
TFT_WR_DATA8(0x04);
|
||||||
|
TFT_WR_DATA8(0x0C);
|
||||||
|
TFT_WR_DATA8(0x11);
|
||||||
|
TFT_WR_DATA8(0x13);
|
||||||
|
TFT_WR_DATA8(0x2C);
|
||||||
|
TFT_WR_DATA8(0x3F);
|
||||||
|
TFT_WR_DATA8(0x44);
|
||||||
|
TFT_WR_DATA8(0x51);
|
||||||
|
TFT_WR_DATA8(0x2F);
|
||||||
|
TFT_WR_DATA8(0x1F);
|
||||||
|
TFT_WR_DATA8(0x1F);
|
||||||
|
TFT_WR_DATA8(0x20);
|
||||||
|
TFT_WR_DATA8(0x23);
|
||||||
|
|
||||||
|
TFT_WR_REG(0x21);
|
||||||
|
|
||||||
|
TFT_SetDisplayDir(DISP_HORIZON);
|
||||||
|
TFT_SetWindowSize(0, 0, TFTCmd.width, TFTCmd.height);
|
||||||
|
|
||||||
|
TFT_WR_REG(0x11);
|
||||||
|
delay_ms(120);
|
||||||
|
|
||||||
|
TFT_WR_REG(0x29);
|
||||||
|
TFT_WR_REG(0x2C);
|
||||||
|
|
||||||
|
TFT_ClearScreen(WHITE);
|
||||||
|
|
||||||
|
TFT_Select(0xff, 0); // UNSELECT ALL DEVICE!
|
||||||
|
|
||||||
|
TFT_BACK_LED_OPEN();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief :tft清屏
|
||||||
|
* @note :--以特定的颜色填充整块屏幕!
|
||||||
|
* @param :color, 要清屏的填充色
|
||||||
|
* @return :void
|
||||||
|
*
|
||||||
|
* @data :2017/03/04
|
||||||
|
* @design :
|
||||||
|
**/
|
||||||
|
void TFT_ClearScreen(uint16_t color)
|
||||||
|
{
|
||||||
|
TFT_FillSingleColor(0, 0, TFTCmd.width, TFTCmd.height, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief :特殊延时
|
||||||
|
* @note :--当mdk -O1时间优化时需要设置,一般不涉及!
|
||||||
|
* @param :t, 特殊延时
|
||||||
|
* @return :void
|
||||||
|
*
|
||||||
|
* @data :2017/03/04
|
||||||
|
* @design :
|
||||||
|
**/
|
||||||
|
//static void opt_delay(uint32_t t)
|
||||||
|
//{
|
||||||
|
// while(t--);
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief :tft读点
|
||||||
|
* @note :--
|
||||||
|
* @param :X, 横坐标(0~TFTCmd.width)
|
||||||
|
Y, 纵坐标(0~TFTCmd.height)
|
||||||
|
* @return :uint16_t, RGB格式的颜色值
|
||||||
|
*
|
||||||
|
* @data :2017/03/04
|
||||||
|
* @design :
|
||||||
|
**/
|
||||||
|
uint16_t TFT_ReadPoint(uint16_t X, uint16_t Y)
|
||||||
|
{
|
||||||
|
return BACK_COLOR; // NO USED!
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief :tft画点
|
||||||
|
* @note :--
|
||||||
|
* @param :X , 横坐标(0~TFTCmd.width)
|
||||||
|
Y , 纵坐标(0~TFTCmd.height)
|
||||||
|
color, 颜色(取自调色板定义的颜色或者其他颜色!)
|
||||||
|
* @return :void
|
||||||
|
*
|
||||||
|
* @data :2017/03/04
|
||||||
|
* @design :
|
||||||
|
**/
|
||||||
|
void TFT_DrawPoint(uint16_t X, uint16_t Y, uint16_t color)
|
||||||
|
{
|
||||||
|
if ((X >= TFTCmd.width) || (Y >= TFTCmd.height))
|
||||||
|
return;
|
||||||
|
|
||||||
|
TFT_SetCursor(X, Y, X, Y);
|
||||||
|
TFT_StartWriteRAM();
|
||||||
|
TFT_WR_DATA(color);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief :tft快速画点
|
||||||
|
* @note :--本函数需要Driver_tft.c支持!
|
||||||
|
* @param :X , 横坐标(0~TFTCmd.width)
|
||||||
|
Y , 纵坐标(0~TFTCmd.height)
|
||||||
|
color, 颜色
|
||||||
|
* @return :void
|
||||||
|
*
|
||||||
|
* @data :2017/03/04
|
||||||
|
* @design :
|
||||||
|
**/
|
||||||
|
void TFT_FastDrawPoint(uint16_t X, uint16_t Y, uint16_t color)
|
||||||
|
{
|
||||||
|
TFT_DrawPoint(X, Y, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief :在指定区域内填充单个颜色
|
||||||
|
* @note :--填充矩形区域,大小为:(XE-XS)*(YE-YS)
|
||||||
|
* @param :XS , 起点横坐标
|
||||||
|
YS , 起点纵坐标
|
||||||
|
XE , 终点横坐标
|
||||||
|
YE , 终点纵坐标
|
||||||
|
Color, 要填充的颜色
|
||||||
|
* @return :void
|
||||||
|
*
|
||||||
|
* @data :2017/03/04
|
||||||
|
* @design :
|
||||||
|
**/
|
||||||
|
void TFT_FillSingleColor(uint16_t XS, uint16_t YS, uint16_t XE, uint16_t YE, uint16_t color)
|
||||||
|
{
|
||||||
|
uint16_t height, width;
|
||||||
|
|
||||||
|
width = XE - XS;
|
||||||
|
height = YE - YS;
|
||||||
|
|
||||||
|
TFT_SetCursor(XS, YS, XE-1, YE-1);
|
||||||
|
TFT_StartWriteRAM();
|
||||||
|
|
||||||
|
for (uint16_t i=0; i<width*height; i++ ) {
|
||||||
|
TFT_WR_DATA(color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief :在指定区域内填充指定颜色块
|
||||||
|
* @note :--填充矩形区域,大小为:(XE-XS)*(YE-YS)
|
||||||
|
* @param :XS , 起点横坐标
|
||||||
|
YS , 起点纵坐标
|
||||||
|
XE , 终点横坐标
|
||||||
|
YE , 终点纵坐标
|
||||||
|
*color, 要填充的颜色
|
||||||
|
* @return :void
|
||||||
|
*
|
||||||
|
* @data :2017/03/04
|
||||||
|
* @design :
|
||||||
|
**/
|
||||||
|
void TFT_FillBlockColor(uint16_t XS, uint16_t YS, uint16_t XE, uint16_t YE, uint16_t *color)
|
||||||
|
{
|
||||||
|
uint16_t height, width;
|
||||||
|
|
||||||
|
width = XE - XS;
|
||||||
|
height = YE - YS;
|
||||||
|
|
||||||
|
TFT_SetCursor(XS, YS, XE-1, YE-1);
|
||||||
|
TFT_StartWriteRAM();
|
||||||
|
|
||||||
|
for (uint16_t i=0; i<width*height; i++ ) {
|
||||||
|
TFT_WR_DATA(color[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ******************** Copyright (C), 2017-2017, TYUT TSS-plan by SERI.LJI ******************** */
|
|
@ -0,0 +1,149 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* TFT 1.14寸显示屏驱动文件,目前使用SPI
|
||||||
|
*
|
||||||
|
* 版本修订:
|
||||||
|
* 修改时间 版本号 修改内容
|
||||||
|
* 2022-12-07 v1.0 开始构建本文件;
|
||||||
|
*
|
||||||
|
* Create :2016年09月09日
|
||||||
|
* Update :2022年12月07日
|
||||||
|
* Author :dengchow
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
***/
|
||||||
|
|
||||||
|
#ifndef __TFT_SPI_H__
|
||||||
|
#define __TFT_SPI_H__
|
||||||
|
|
||||||
|
/*Needed Library Define*/
|
||||||
|
#include "__def.h"
|
||||||
|
#include "systick.h"
|
||||||
|
#include "gpio.h"
|
||||||
|
|
||||||
|
#define LCD_SPI_SOFT
|
||||||
|
|
||||||
|
#define CFG_LCD_X_SIZE LCD_X_SIZE
|
||||||
|
#define CFG_LCD_Y_SIZE LCD_Y_SIZE
|
||||||
|
|
||||||
|
/*Param Define*/
|
||||||
|
///扫描方向枚举
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
SCAN_L2R_U2D = (uint8_t)0, //从左到右,从上到下
|
||||||
|
SCAN_L2R_D2U = (uint8_t)1, //从左到右,从下到上
|
||||||
|
SCAN_R2L_U2D = (uint8_t)2, //从右到左,从上到下
|
||||||
|
SCAN_R2L_D2U = (uint8_t)3, //从右到左,从下到上
|
||||||
|
SCAN_U2D_L2R = (uint8_t)4, //从上到下,从左到右
|
||||||
|
SCAN_U2D_R2L = (uint8_t)5, //从上到下,从右到左
|
||||||
|
SCAN_D2U_L2R = (uint8_t)6, //从下到上,从左到右
|
||||||
|
SCAN_D2U_R2L = (uint8_t)7, //从下到上,从右到左
|
||||||
|
}_TFTScanDir;
|
||||||
|
|
||||||
|
///显示方向枚举
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
DISP_HORIZON = (uint8_t)0, //横向显示
|
||||||
|
DISP_PORTRAIT = (uint8_t)1, //纵向显示
|
||||||
|
}_TFTDispDir;
|
||||||
|
|
||||||
|
///tft控制参数集
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint16_t id; //ID
|
||||||
|
|
||||||
|
uint16_t width; //宽度
|
||||||
|
uint16_t height; //高度
|
||||||
|
|
||||||
|
uint16_t wramcmd; //开始写gram指令
|
||||||
|
uint16_t setxcmd; //设置x坐标指令
|
||||||
|
uint16_t setycmd; //设置y坐标指令
|
||||||
|
_TFTDispDir dir; //显示方向
|
||||||
|
}_TFTCmdTypeStruct;
|
||||||
|
|
||||||
|
extern _TFTCmdTypeStruct TFTCmd;//管理LCD重要参数
|
||||||
|
extern uint16_t POINT_COLOR;//默认黑色
|
||||||
|
extern uint16_t BACK_COLOR; //背景颜色,默认为白色
|
||||||
|
|
||||||
|
///复位控制
|
||||||
|
#define TFT_RST_PORT ;
|
||||||
|
#define TFT_RST_PIN ;
|
||||||
|
#define TFT_RST_HIGH() LCD_RST_H;
|
||||||
|
#define TFT_RST_LOW() LCD_RST_L;
|
||||||
|
|
||||||
|
///数据&命令控制
|
||||||
|
#define TFT_DC_PORT ;
|
||||||
|
#define TFT_DC_PIN ;
|
||||||
|
#define TFT_DC_DATA() LCD_DC_H;
|
||||||
|
#define TFT_DC_CMD() LCD_DC_L;
|
||||||
|
|
||||||
|
///背光灯控制
|
||||||
|
#define TFT_BACK_LED_PORT ;
|
||||||
|
#define TFT_BACK_LED_PIN ;
|
||||||
|
#define TFT_BACK_LED_OPEN() LCD_BK_ON;
|
||||||
|
#define TFT_BACK_LED_CLOSE() LCD_BK_OFF;
|
||||||
|
|
||||||
|
///扫描方向定义
|
||||||
|
#define DFT_SCAN_DIR SCAN_L2R_U2D //SCAN_D2U_L2R
|
||||||
|
|
||||||
|
///设置tft显示模式(若定义则为BGR,否则为RGB!)
|
||||||
|
#define TFT_BGR_MODE
|
||||||
|
|
||||||
|
///颜色板,RGB模式下色彩值
|
||||||
|
#define WHITE 0xFFFF // 1.白色
|
||||||
|
#define BLACK 0x0000 // 2.黑色
|
||||||
|
#define RED 0x001F // 3.红色
|
||||||
|
#define BRED 0XF81F // 4.紫色(水晶葡萄色)
|
||||||
|
#define GRED 0XFFE0 // 5.青色
|
||||||
|
#define YELLOW 0X07FF // 6.黄色
|
||||||
|
#define BLUE 0xF800 // 7.蓝色
|
||||||
|
#define MAGENTA 0xF81F // 8.洋红色(偏紫偏粉色)
|
||||||
|
#define GREEN 0x07E0 // 9.绿色
|
||||||
|
#define CYAN 0x7FFF //10.淡黄色
|
||||||
|
#define BBLUE 0XBC40 //11.浅蓝色
|
||||||
|
#define GRAY 0X8430 //12.灰色
|
||||||
|
#define BROWN 0X01CF //13.棕色
|
||||||
|
#define LLGBROWN 0X7D7C //14.浅浅灰棕色(浅皮肤色)
|
||||||
|
#define LGBROWN 0X5458 //15.浅灰棕色
|
||||||
|
#define LRED 0X841F //16.浅红色(果肉色)
|
||||||
|
#define LGRAY 0XC618 //17.浅灰色
|
||||||
|
#define LGGREEN 0XA651 //18.浅灰绿色(保护眼色)
|
||||||
|
#define LBROWN 0X2B12 //19.浅棕色
|
||||||
|
|
||||||
|
#define tobgr(d) TFT_RGB2BGR(d)
|
||||||
|
#define torgb(d) TFT_BGR2RGB(d)
|
||||||
|
|
||||||
|
/*Function Define*/
|
||||||
|
///tft底层寄存器相关操作
|
||||||
|
void TFT_WR_REG(uint16_t reg);//写寄存器地址
|
||||||
|
void TFT_WR_DATA(uint16_t dat);//写数据
|
||||||
|
uint16_t TFT_RD_DATA(void);//读数据
|
||||||
|
|
||||||
|
void TFT_Select(uint8_t idx, uint8_t en);//选择lcd设备
|
||||||
|
void TFT_WriteReg(uint16_t reg, uint16_t dat);//向寄存器写数据
|
||||||
|
uint16_t TFT_ReadReg(uint16_t reg);//从寄存器读数据
|
||||||
|
void TFT_StartWriteRAM(void);//开始写GRAM
|
||||||
|
void TFT_WriteRAM(uint16_t color);//写GRAM
|
||||||
|
|
||||||
|
void TFT_DisplayOn(void);//tft开启显示
|
||||||
|
void TFT_DisplayOff(void);//tft关闭显示
|
||||||
|
|
||||||
|
void TFT_SetCursor(uint16_t X1, uint16_t Y1, uint16_t X2, uint16_t Y2);//设置光标位置
|
||||||
|
void TFT_SetScanDir(_TFTScanDir direct);//设置tft自动扫描方向
|
||||||
|
void TFT_SetDisplayDir(_TFTDispDir direct);//设置tft显示方向
|
||||||
|
void TFT_SetWindowSize(uint16_t XS, uint16_t YS, uint16_t width, uint16_t height);//设置tft窗口大小
|
||||||
|
|
||||||
|
///初始化相关操作
|
||||||
|
void TFT_InitConfig(void);//tft初始化设置
|
||||||
|
void TFT_ClearScreen(uint16_t color);//tft清屏
|
||||||
|
|
||||||
|
uint16_t TFT_ReadPoint(uint16_t X, uint16_t Y);//读取个某点的颜色值
|
||||||
|
void TFT_DrawPoint(uint16_t X, uint16_t Y, uint16_t color);//画点
|
||||||
|
void TFT_FastDrawPoint(uint16_t X, uint16_t Y, uint16_t color);//快速画点
|
||||||
|
void TFT_FillSingleColor(uint16_t XS, uint16_t YS, uint16_t XE, uint16_t YE, uint16_t color);//在指定区域内填充单个颜色
|
||||||
|
void TFT_FillBlockColor(uint16_t XS, uint16_t YS, uint16_t XE, uint16_t YE, uint16_t *color);//在指定区域内填充颜色块
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* ******************** Copyright (C), 2017-2017, TYUT TSS-plan by SERI.LJI ******************** */
|
|
@ -0,0 +1,355 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* 320*240 TFT 显示屏字库编码(3.2吋显示屏)
|
||||||
|
*
|
||||||
|
* 文件说明:tft常用ASCII表(偏移量32!);
|
||||||
|
* 取模软件:PC2LCD2002;
|
||||||
|
* 取模方式:阴码 + 逐列式 + 顺向 + C51格式;
|
||||||
|
* 当前支持:12*12、16*16和24*24(可根据需要自行添加);
|
||||||
|
* 需要注意:(size/8+((size%8)?1:0))*(size/2);
|
||||||
|
* 其中size是字库生成时的点阵大小(12/16/24/...);
|
||||||
|
*
|
||||||
|
* 本例程不做任何商业用途,只可作为学习使用(在前人的工作基础上改进!);
|
||||||
|
* 免责声明:本例程对原版代码修改较大,并添加自己需要的功能,已做适应性修改!
|
||||||
|
* 感谢论坛网友的帮助支持:www.opencdv.com
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Create :2016年09月09日
|
||||||
|
* Update :2017年10月15日
|
||||||
|
* Author :dengchow
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
***/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __TASK_TFT_FONT_H__
|
||||||
|
#define __TASK_TFT_FONT_H__
|
||||||
|
|
||||||
|
#define _USE_FONT1608
|
||||||
|
//#define _USE_FONT2412
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 12*12 -- ASCII字符集点阵
|
||||||
|
*/
|
||||||
|
const unsigned char asc_tft_1206[95][12]=
|
||||||
|
{
|
||||||
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*" ",0*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x3F,0x40,0x00,0x00,0x00,0x00,0x00,0x00},/*"!",1*/
|
||||||
|
{0x00,0x00,0x30,0x00,0x40,0x00,0x30,0x00,0x40,0x00,0x00,0x00},/*""",2*/
|
||||||
|
{0x09,0x00,0x0B,0xC0,0x3D,0x00,0x0B,0xC0,0x3D,0x00,0x09,0x00},/*"#",3*/
|
||||||
|
{0x18,0xC0,0x24,0x40,0x7F,0xE0,0x22,0x40,0x31,0x80,0x00,0x00},/*"$",4*/
|
||||||
|
{0x18,0x00,0x24,0xC0,0x1B,0x00,0x0D,0x80,0x32,0x40,0x01,0x80},/*"%",5*/
|
||||||
|
{0x03,0x80,0x1C,0x40,0x27,0x40,0x1C,0x80,0x07,0x40,0x00,0x40},/*"&",6*/
|
||||||
|
{0x10,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"'",7*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x80,0x20,0x40,0x40,0x20},/*"(",8*/
|
||||||
|
{0x00,0x00,0x40,0x20,0x20,0x40,0x1F,0x80,0x00,0x00,0x00,0x00},/*")",9*/
|
||||||
|
{0x09,0x00,0x06,0x00,0x1F,0x80,0x06,0x00,0x09,0x00,0x00,0x00},/*"*",10*/
|
||||||
|
{0x04,0x00,0x04,0x00,0x3F,0x80,0x04,0x00,0x04,0x00,0x00,0x00},/*"+",11*/
|
||||||
|
{0x00,0x10,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*",",12*/
|
||||||
|
{0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x00,0x00},/*"-",13*/
|
||||||
|
{0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*".",14*/
|
||||||
|
{0x00,0x20,0x01,0xC0,0x06,0x00,0x38,0x00,0x40,0x00,0x00,0x00},/*"/",15*/
|
||||||
|
{0x1F,0x80,0x20,0x40,0x20,0x40,0x20,0x40,0x1F,0x80,0x00,0x00},/*"0",16*/
|
||||||
|
{0x00,0x00,0x10,0x40,0x3F,0xC0,0x00,0x40,0x00,0x00,0x00,0x00},/*"1",17*/
|
||||||
|
{0x18,0xC0,0x21,0x40,0x22,0x40,0x24,0x40,0x18,0x40,0x00,0x00},/*"2",18*/
|
||||||
|
{0x10,0x80,0x20,0x40,0x24,0x40,0x24,0x40,0x1B,0x80,0x00,0x00},/*"3",19*/
|
||||||
|
{0x02,0x00,0x0D,0x00,0x11,0x00,0x3F,0xC0,0x01,0x40,0x00,0x00},/*"4",20*/
|
||||||
|
{0x3C,0x80,0x24,0x40,0x24,0x40,0x24,0x40,0x23,0x80,0x00,0x00},/*"5",21*/
|
||||||
|
{0x1F,0x80,0x24,0x40,0x24,0x40,0x34,0x40,0x03,0x80,0x00,0x00},/*"6",22*/
|
||||||
|
{0x30,0x00,0x20,0x00,0x27,0xC0,0x38,0x00,0x20,0x00,0x00,0x00},/*"7",23*/
|
||||||
|
{0x1B,0x80,0x24,0x40,0x24,0x40,0x24,0x40,0x1B,0x80,0x00,0x00},/*"8",24*/
|
||||||
|
{0x1C,0x00,0x22,0xC0,0x22,0x40,0x22,0x40,0x1F,0x80,0x00,0x00},/*"9",25*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x08,0x40,0x00,0x00,0x00,0x00,0x00,0x00},/*":",26*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00},/*";",27*/
|
||||||
|
{0x00,0x00,0x04,0x00,0x0A,0x00,0x11,0x00,0x20,0x80,0x40,0x40},/*"<",28*/
|
||||||
|
{0x09,0x00,0x09,0x00,0x09,0x00,0x09,0x00,0x09,0x00,0x00,0x00},/*"=",29*/
|
||||||
|
{0x00,0x00,0x40,0x40,0x20,0x80,0x11,0x00,0x0A,0x00,0x04,0x00},/*">",30*/
|
||||||
|
{0x18,0x00,0x20,0x00,0x23,0x40,0x24,0x00,0x18,0x00,0x00,0x00},/*"?",31*/
|
||||||
|
{0x1F,0x80,0x20,0x40,0x27,0x40,0x29,0x40,0x1F,0x40,0x00,0x00},/*"@",32*/
|
||||||
|
{0x00,0x40,0x07,0xC0,0x39,0x00,0x0F,0x00,0x01,0xC0,0x00,0x40},/*"A",33*/
|
||||||
|
{0x20,0x40,0x3F,0xC0,0x24,0x40,0x24,0x40,0x1B,0x80,0x00,0x00},/*"B",34*/
|
||||||
|
{0x1F,0x80,0x20,0x40,0x20,0x40,0x20,0x40,0x30,0x80,0x00,0x00},/*"C",35*/
|
||||||
|
{0x20,0x40,0x3F,0xC0,0x20,0x40,0x20,0x40,0x1F,0x80,0x00,0x00},/*"D",36*/
|
||||||
|
{0x20,0x40,0x3F,0xC0,0x24,0x40,0x2E,0x40,0x30,0xC0,0x00,0x00},/*"E",37*/
|
||||||
|
{0x20,0x40,0x3F,0xC0,0x24,0x40,0x2E,0x00,0x30,0x00,0x00,0x00},/*"F",38*/
|
||||||
|
{0x0F,0x00,0x10,0x80,0x20,0x40,0x22,0x40,0x33,0x80,0x02,0x00},/*"G",39*/
|
||||||
|
{0x20,0x40,0x3F,0xC0,0x04,0x00,0x04,0x00,0x3F,0xC0,0x20,0x40},/*"H",40*/
|
||||||
|
{0x20,0x40,0x20,0x40,0x3F,0xC0,0x20,0x40,0x20,0x40,0x00,0x00},/*"I",41*/
|
||||||
|
{0x00,0x60,0x20,0x20,0x20,0x20,0x3F,0xC0,0x20,0x00,0x20,0x00},/*"J",42*/
|
||||||
|
{0x20,0x40,0x3F,0xC0,0x24,0x40,0x0B,0x00,0x30,0xC0,0x20,0x40},/*"K",43*/
|
||||||
|
{0x20,0x40,0x3F,0xC0,0x20,0x40,0x00,0x40,0x00,0x40,0x00,0xC0},/*"L",44*/
|
||||||
|
{0x3F,0xC0,0x3C,0x00,0x03,0xC0,0x3C,0x00,0x3F,0xC0,0x00,0x00},/*"M",45*/
|
||||||
|
{0x20,0x40,0x3F,0xC0,0x0C,0x40,0x23,0x00,0x3F,0xC0,0x20,0x00},/*"N",46*/
|
||||||
|
{0x1F,0x80,0x20,0x40,0x20,0x40,0x20,0x40,0x1F,0x80,0x00,0x00},/*"O",47*/
|
||||||
|
{0x20,0x40,0x3F,0xC0,0x24,0x40,0x24,0x00,0x18,0x00,0x00,0x00},/*"P",48*/
|
||||||
|
{0x1F,0x80,0x21,0x40,0x21,0x40,0x20,0xE0,0x1F,0xA0,0x00,0x00},/*"Q",49*/
|
||||||
|
{0x20,0x40,0x3F,0xC0,0x24,0x40,0x26,0x00,0x19,0xC0,0x00,0x40},/*"R",50*/
|
||||||
|
{0x18,0xC0,0x24,0x40,0x24,0x40,0x22,0x40,0x31,0x80,0x00,0x00},/*"S",51*/
|
||||||
|
{0x30,0x00,0x20,0x40,0x3F,0xC0,0x20,0x40,0x30,0x00,0x00,0x00},/*"T",52*/
|
||||||
|
{0x20,0x00,0x3F,0x80,0x00,0x40,0x00,0x40,0x3F,0x80,0x20,0x00},/*"U",53*/
|
||||||
|
{0x20,0x00,0x3E,0x00,0x01,0xC0,0x07,0x00,0x38,0x00,0x20,0x00},/*"V",54*/
|
||||||
|
{0x38,0x00,0x07,0xC0,0x3C,0x00,0x07,0xC0,0x38,0x00,0x00,0x00},/*"W",55*/
|
||||||
|
{0x20,0x40,0x39,0xC0,0x06,0x00,0x39,0xC0,0x20,0x40,0x00,0x00},/*"X",56*/
|
||||||
|
{0x20,0x00,0x38,0x40,0x07,0xC0,0x38,0x40,0x20,0x00,0x00,0x00},/*"Y",57*/
|
||||||
|
{0x30,0x40,0x21,0xC0,0x26,0x40,0x38,0x40,0x20,0xC0,0x00,0x00},/*"Z",58*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x7F,0xE0,0x40,0x20,0x40,0x20,0x00,0x00},/*"[",59*/
|
||||||
|
{0x00,0x00,0x70,0x00,0x0C,0x00,0x03,0x80,0x00,0x40,0x00,0x00},/*"\",60*/
|
||||||
|
{0x00,0x00,0x40,0x20,0x40,0x20,0x7F,0xE0,0x00,0x00,0x00,0x00},/*"]",61*/
|
||||||
|
{0x00,0x00,0x20,0x00,0x40,0x00,0x20,0x00,0x00,0x00,0x00,0x00},/*"^",62*/
|
||||||
|
{0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10},/*"_",63*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"`",64*/
|
||||||
|
{0x00,0x00,0x02,0x80,0x05,0x40,0x05,0x40,0x03,0xC0,0x00,0x40},/*"a",65*/
|
||||||
|
{0x20,0x00,0x3F,0xC0,0x04,0x40,0x04,0x40,0x03,0x80,0x00,0x00},/*"b",66*/
|
||||||
|
{0x00,0x00,0x03,0x80,0x04,0x40,0x04,0x40,0x06,0x40,0x00,0x00},/*"c",67*/
|
||||||
|
{0x00,0x00,0x03,0x80,0x04,0x40,0x24,0x40,0x3F,0xC0,0x00,0x40},/*"d",68*/
|
||||||
|
{0x00,0x00,0x03,0x80,0x05,0x40,0x05,0x40,0x03,0x40,0x00,0x00},/*"e",69*/
|
||||||
|
{0x00,0x00,0x04,0x40,0x1F,0xC0,0x24,0x40,0x24,0x40,0x20,0x00},/*"f",70*/
|
||||||
|
{0x00,0x00,0x02,0xE0,0x05,0x50,0x05,0x50,0x06,0x50,0x04,0x20},/*"g",71*/
|
||||||
|
{0x20,0x40,0x3F,0xC0,0x04,0x40,0x04,0x00,0x03,0xC0,0x00,0x40},/*"h",72*/
|
||||||
|
{0x00,0x00,0x04,0x40,0x27,0xC0,0x00,0x40,0x00,0x00,0x00,0x00},/*"i",73*/
|
||||||
|
{0x00,0x10,0x00,0x10,0x04,0x10,0x27,0xE0,0x00,0x00,0x00,0x00},/*"j",74*/
|
||||||
|
{0x20,0x40,0x3F,0xC0,0x01,0x40,0x07,0x00,0x04,0xC0,0x04,0x40},/*"k",75*/
|
||||||
|
{0x20,0x40,0x20,0x40,0x3F,0xC0,0x00,0x40,0x00,0x40,0x00,0x00},/*"l",76*/
|
||||||
|
{0x07,0xC0,0x04,0x00,0x07,0xC0,0x04,0x00,0x03,0xC0,0x00,0x00},/*"m",77*/
|
||||||
|
{0x04,0x40,0x07,0xC0,0x04,0x40,0x04,0x00,0x03,0xC0,0x00,0x40},/*"n",78*/
|
||||||
|
{0x00,0x00,0x03,0x80,0x04,0x40,0x04,0x40,0x03,0x80,0x00,0x00},/*"o",79*/
|
||||||
|
{0x04,0x10,0x07,0xF0,0x04,0x50,0x04,0x40,0x03,0x80,0x00,0x00},/*"p",80*/
|
||||||
|
{0x00,0x00,0x03,0x80,0x04,0x40,0x04,0x50,0x07,0xF0,0x00,0x10},/*"q",81*/
|
||||||
|
{0x04,0x40,0x07,0xC0,0x02,0x40,0x04,0x00,0x04,0x00,0x00,0x00},/*"r",82*/
|
||||||
|
{0x00,0x00,0x06,0x40,0x05,0x40,0x05,0x40,0x04,0xC0,0x00,0x00},/*"s",83*/
|
||||||
|
{0x00,0x00,0x04,0x00,0x1F,0x80,0x04,0x40,0x00,0x40,0x00,0x00},/*"t",84*/
|
||||||
|
{0x04,0x00,0x07,0x80,0x00,0x40,0x04,0x40,0x07,0xC0,0x00,0x40},/*"u",85*/
|
||||||
|
{0x04,0x00,0x07,0x00,0x04,0xC0,0x01,0x80,0x06,0x00,0x04,0x00},/*"v",86*/
|
||||||
|
{0x06,0x00,0x01,0xC0,0x07,0x00,0x01,0xC0,0x06,0x00,0x00,0x00},/*"w",87*/
|
||||||
|
{0x04,0x40,0x06,0xC0,0x01,0x00,0x06,0xC0,0x04,0x40,0x00,0x00},/*"x",88*/
|
||||||
|
{0x04,0x10,0x07,0x10,0x04,0xE0,0x01,0x80,0x06,0x00,0x04,0x00},/*"y",89*/
|
||||||
|
{0x00,0x00,0x04,0x40,0x05,0xC0,0x06,0x40,0x04,0x40,0x00,0x00},/*"z",90*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x04,0x00,0x7B,0xE0,0x40,0x20,0x00,0x00},/*"{",91*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xF0,0x00,0x00,0x00,0x00},/*"|",92*/
|
||||||
|
{0x00,0x00,0x40,0x20,0x7B,0xE0,0x04,0x00,0x00,0x00,0x00,0x00},/*"}",93*/
|
||||||
|
{0x40,0x00,0x80,0x00,0x40,0x00,0x20,0x00,0x20,0x00,0x40,0x00},/*"~",94*/
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 16*16 -- ASCII字符集点阵
|
||||||
|
*/
|
||||||
|
#ifdef _USE_FONT1608
|
||||||
|
const unsigned char asc_tft_1608[95][16]=
|
||||||
|
{
|
||||||
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*" ",0*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0xCC,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00},/*"!",1*/
|
||||||
|
{0x00,0x00,0x08,0x00,0x30,0x00,0x60,0x00,0x08,0x00,0x30,0x00,0x60,0x00,0x00,0x00},/*""",2*/
|
||||||
|
{0x02,0x20,0x03,0xFC,0x1E,0x20,0x02,0x20,0x03,0xFC,0x1E,0x20,0x02,0x20,0x00,0x00},/*"#",3*/
|
||||||
|
{0x00,0x00,0x0E,0x18,0x11,0x04,0x3F,0xFF,0x10,0x84,0x0C,0x78,0x00,0x00,0x00,0x00},/*"$",4*/
|
||||||
|
{0x0F,0x00,0x10,0x84,0x0F,0x38,0x00,0xC0,0x07,0x78,0x18,0x84,0x00,0x78,0x00,0x00},/*"%",5*/
|
||||||
|
{0x00,0x78,0x0F,0x84,0x10,0xC4,0x11,0x24,0x0E,0x98,0x00,0xE4,0x00,0x84,0x00,0x08},/*"&",6*/
|
||||||
|
{0x08,0x00,0x68,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"'",7*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xE0,0x18,0x18,0x20,0x04,0x40,0x02,0x00,0x00},/*"(",8*/
|
||||||
|
{0x00,0x00,0x40,0x02,0x20,0x04,0x18,0x18,0x07,0xE0,0x00,0x00,0x00,0x00,0x00,0x00},/*")",9*/
|
||||||
|
{0x02,0x40,0x02,0x40,0x01,0x80,0x0F,0xF0,0x01,0x80,0x02,0x40,0x02,0x40,0x00,0x00},/*"*",10*/
|
||||||
|
{0x00,0x80,0x00,0x80,0x00,0x80,0x0F,0xF8,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x00},/*"+",11*/
|
||||||
|
{0x00,0x01,0x00,0x0D,0x00,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*",",12*/
|
||||||
|
{0x00,0x00,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80},/*"-",13*/
|
||||||
|
{0x00,0x00,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*".",14*/
|
||||||
|
{0x00,0x00,0x00,0x06,0x00,0x18,0x00,0x60,0x01,0x80,0x06,0x00,0x18,0x00,0x20,0x00},/*"/",15*/
|
||||||
|
{0x00,0x00,0x07,0xF0,0x08,0x08,0x10,0x04,0x10,0x04,0x08,0x08,0x07,0xF0,0x00,0x00},/*"0",16*/
|
||||||
|
{0x00,0x00,0x08,0x04,0x08,0x04,0x1F,0xFC,0x00,0x04,0x00,0x04,0x00,0x00,0x00,0x00},/*"1",17*/
|
||||||
|
{0x00,0x00,0x0E,0x0C,0x10,0x14,0x10,0x24,0x10,0x44,0x11,0x84,0x0E,0x0C,0x00,0x00},/*"2",18*/
|
||||||
|
{0x00,0x00,0x0C,0x18,0x10,0x04,0x11,0x04,0x11,0x04,0x12,0x88,0x0C,0x70,0x00,0x00},/*"3",19*/
|
||||||
|
{0x00,0x00,0x00,0xE0,0x03,0x20,0x04,0x24,0x08,0x24,0x1F,0xFC,0x00,0x24,0x00,0x00},/*"4",20*/
|
||||||
|
{0x00,0x00,0x1F,0x98,0x10,0x84,0x11,0x04,0x11,0x04,0x10,0x88,0x10,0x70,0x00,0x00},/*"5",21*/
|
||||||
|
{0x00,0x00,0x07,0xF0,0x08,0x88,0x11,0x04,0x11,0x04,0x18,0x88,0x00,0x70,0x00,0x00},/*"6",22*/
|
||||||
|
{0x00,0x00,0x1C,0x00,0x10,0x00,0x10,0xFC,0x13,0x00,0x1C,0x00,0x10,0x00,0x00,0x00},/*"7",23*/
|
||||||
|
{0x00,0x00,0x0E,0x38,0x11,0x44,0x10,0x84,0x10,0x84,0x11,0x44,0x0E,0x38,0x00,0x00},/*"8",24*/
|
||||||
|
{0x00,0x00,0x07,0x00,0x08,0x8C,0x10,0x44,0x10,0x44,0x08,0x88,0x07,0xF0,0x00,0x00},/*"9",25*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x0C,0x03,0x0C,0x00,0x00,0x00,0x00,0x00,0x00},/*":",26*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*";",27*/
|
||||||
|
{0x00,0x00,0x00,0x80,0x01,0x40,0x02,0x20,0x04,0x10,0x08,0x08,0x10,0x04,0x00,0x00},/*"<",28*/
|
||||||
|
{0x02,0x20,0x02,0x20,0x02,0x20,0x02,0x20,0x02,0x20,0x02,0x20,0x02,0x20,0x00,0x00},/*"=",29*/
|
||||||
|
{0x00,0x00,0x10,0x04,0x08,0x08,0x04,0x10,0x02,0x20,0x01,0x40,0x00,0x80,0x00,0x00},/*">",30*/
|
||||||
|
{0x00,0x00,0x0E,0x00,0x12,0x00,0x10,0x0C,0x10,0x6C,0x10,0x80,0x0F,0x00,0x00,0x00},/*"?",31*/
|
||||||
|
{0x03,0xE0,0x0C,0x18,0x13,0xE4,0x14,0x24,0x17,0xC4,0x08,0x28,0x07,0xD0,0x00,0x00},/*"@",32*/
|
||||||
|
{0x00,0x04,0x00,0x3C,0x03,0xC4,0x1C,0x40,0x07,0x40,0x00,0xE4,0x00,0x1C,0x00,0x04},/*"A",33*/
|
||||||
|
{0x10,0x04,0x1F,0xFC,0x11,0x04,0x11,0x04,0x11,0x04,0x0E,0x88,0x00,0x70,0x00,0x00},/*"B",34*/
|
||||||
|
{0x03,0xE0,0x0C,0x18,0x10,0x04,0x10,0x04,0x10,0x04,0x10,0x08,0x1C,0x10,0x00,0x00},/*"C",35*/
|
||||||
|
{0x10,0x04,0x1F,0xFC,0x10,0x04,0x10,0x04,0x10,0x04,0x08,0x08,0x07,0xF0,0x00,0x00},/*"D",36*/
|
||||||
|
{0x10,0x04,0x1F,0xFC,0x11,0x04,0x11,0x04,0x17,0xC4,0x10,0x04,0x08,0x18,0x00,0x00},/*"E",37*/
|
||||||
|
{0x10,0x04,0x1F,0xFC,0x11,0x04,0x11,0x00,0x17,0xC0,0x10,0x00,0x08,0x00,0x00,0x00},/*"F",38*/
|
||||||
|
{0x03,0xE0,0x0C,0x18,0x10,0x04,0x10,0x04,0x10,0x44,0x1C,0x78,0x00,0x40,0x00,0x00},/*"G",39*/
|
||||||
|
{0x10,0x04,0x1F,0xFC,0x10,0x84,0x00,0x80,0x00,0x80,0x10,0x84,0x1F,0xFC,0x10,0x04},/*"H",40*/
|
||||||
|
{0x00,0x00,0x10,0x04,0x10,0x04,0x1F,0xFC,0x10,0x04,0x10,0x04,0x00,0x00,0x00,0x00},/*"I",41*/
|
||||||
|
{0x00,0x03,0x00,0x01,0x10,0x01,0x10,0x01,0x1F,0xFE,0x10,0x00,0x10,0x00,0x00,0x00},/*"J",42*/
|
||||||
|
{0x10,0x04,0x1F,0xFC,0x11,0x04,0x03,0x80,0x14,0x64,0x18,0x1C,0x10,0x04,0x00,0x00},/*"K",43*/
|
||||||
|
{0x10,0x04,0x1F,0xFC,0x10,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x0C,0x00,0x00},/*"L",44*/
|
||||||
|
{0x10,0x04,0x1F,0xFC,0x1F,0x00,0x00,0xFC,0x1F,0x00,0x1F,0xFC,0x10,0x04,0x00,0x00},/*"M",45*/
|
||||||
|
{0x10,0x04,0x1F,0xFC,0x0C,0x04,0x03,0x00,0x00,0xE0,0x10,0x18,0x1F,0xFC,0x10,0x00},/*"N",46*/
|
||||||
|
{0x07,0xF0,0x08,0x08,0x10,0x04,0x10,0x04,0x10,0x04,0x08,0x08,0x07,0xF0,0x00,0x00},/*"O",47*/
|
||||||
|
{0x10,0x04,0x1F,0xFC,0x10,0x84,0x10,0x80,0x10,0x80,0x10,0x80,0x0F,0x00,0x00,0x00},/*"P",48*/
|
||||||
|
{0x07,0xF0,0x08,0x18,0x10,0x24,0x10,0x24,0x10,0x1C,0x08,0x0A,0x07,0xF2,0x00,0x00},/*"Q",49*/
|
||||||
|
{0x10,0x04,0x1F,0xFC,0x11,0x04,0x11,0x00,0x11,0xC0,0x11,0x30,0x0E,0x0C,0x00,0x04},/*"R",50*/
|
||||||
|
{0x00,0x00,0x0E,0x1C,0x11,0x04,0x10,0x84,0x10,0x84,0x10,0x44,0x1C,0x38,0x00,0x00},/*"S",51*/
|
||||||
|
{0x18,0x00,0x10,0x00,0x10,0x04,0x1F,0xFC,0x10,0x04,0x10,0x00,0x18,0x00,0x00,0x00},/*"T",52*/
|
||||||
|
{0x10,0x00,0x1F,0xF8,0x10,0x04,0x00,0x04,0x00,0x04,0x10,0x04,0x1F,0xF8,0x10,0x00},/*"U",53*/
|
||||||
|
{0x10,0x00,0x1E,0x00,0x11,0xE0,0x00,0x1C,0x00,0x70,0x13,0x80,0x1C,0x00,0x10,0x00},/*"V",54*/
|
||||||
|
{0x1F,0xC0,0x10,0x3C,0x00,0xE0,0x1F,0x00,0x00,0xE0,0x10,0x3C,0x1F,0xC0,0x00,0x00},/*"W",55*/
|
||||||
|
{0x10,0x04,0x18,0x0C,0x16,0x34,0x01,0xC0,0x01,0xC0,0x16,0x34,0x18,0x0C,0x10,0x04},/*"X",56*/
|
||||||
|
{0x10,0x00,0x1C,0x00,0x13,0x04,0x00,0xFC,0x13,0x04,0x1C,0x00,0x10,0x00,0x00,0x00},/*"Y",57*/
|
||||||
|
{0x08,0x04,0x10,0x1C,0x10,0x64,0x10,0x84,0x13,0x04,0x1C,0x04,0x10,0x18,0x00,0x00},/*"Z",58*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0xFE,0x40,0x02,0x40,0x02,0x40,0x02,0x00,0x00},/*"[",59*/
|
||||||
|
{0x00,0x00,0x30,0x00,0x0C,0x00,0x03,0x80,0x00,0x60,0x00,0x1C,0x00,0x03,0x00,0x00},/*"\",60*/
|
||||||
|
{0x00,0x00,0x40,0x02,0x40,0x02,0x40,0x02,0x7F,0xFE,0x00,0x00,0x00,0x00,0x00,0x00},/*"]",61*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x20,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x20,0x00,0x00,0x00},/*"^",62*/
|
||||||
|
{0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01},/*"_",63*/
|
||||||
|
{0x00,0x00,0x40,0x00,0x40,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"`",64*/
|
||||||
|
{0x00,0x00,0x00,0x98,0x01,0x24,0x01,0x44,0x01,0x44,0x01,0x44,0x00,0xFC,0x00,0x04},/*"a",65*/
|
||||||
|
{0x10,0x00,0x1F,0xFC,0x00,0x88,0x01,0x04,0x01,0x04,0x00,0x88,0x00,0x70,0x00,0x00},/*"b",66*/
|
||||||
|
{0x00,0x00,0x00,0x70,0x00,0x88,0x01,0x04,0x01,0x04,0x01,0x04,0x00,0x88,0x00,0x00},/*"c",67*/
|
||||||
|
{0x00,0x00,0x00,0x70,0x00,0x88,0x01,0x04,0x01,0x04,0x11,0x08,0x1F,0xFC,0x00,0x04},/*"d",68*/
|
||||||
|
{0x00,0x00,0x00,0xF8,0x01,0x44,0x01,0x44,0x01,0x44,0x01,0x44,0x00,0xC8,0x00,0x00},/*"e",69*/
|
||||||
|
{0x00,0x00,0x01,0x04,0x01,0x04,0x0F,0xFC,0x11,0x04,0x11,0x04,0x11,0x00,0x18,0x00},/*"f",70*/
|
||||||
|
{0x00,0x00,0x00,0xD6,0x01,0x29,0x01,0x29,0x01,0x29,0x01,0xC9,0x01,0x06,0x00,0x00},/*"g",71*/
|
||||||
|
{0x10,0x04,0x1F,0xFC,0x00,0x84,0x01,0x00,0x01,0x00,0x01,0x04,0x00,0xFC,0x00,0x04},/*"h",72*/
|
||||||
|
{0x00,0x00,0x01,0x04,0x19,0x04,0x19,0xFC,0x00,0x04,0x00,0x04,0x00,0x00,0x00,0x00},/*"i",73*/
|
||||||
|
{0x00,0x00,0x00,0x03,0x00,0x01,0x01,0x01,0x19,0x01,0x19,0xFE,0x00,0x00,0x00,0x00},/*"j",74*/
|
||||||
|
{0x10,0x04,0x1F,0xFC,0x00,0x24,0x00,0x40,0x01,0xB4,0x01,0x0C,0x01,0x04,0x00,0x00},/*"k",75*/
|
||||||
|
{0x00,0x00,0x10,0x04,0x10,0x04,0x1F,0xFC,0x00,0x04,0x00,0x04,0x00,0x00,0x00,0x00},/*"l",76*/
|
||||||
|
{0x01,0x04,0x01,0xFC,0x01,0x04,0x01,0x00,0x01,0xFC,0x01,0x04,0x01,0x00,0x00,0xFC},/*"m",77*/
|
||||||
|
{0x01,0x04,0x01,0xFC,0x00,0x84,0x01,0x00,0x01,0x00,0x01,0x04,0x00,0xFC,0x00,0x04},/*"n",78*/
|
||||||
|
{0x00,0x00,0x00,0xF8,0x01,0x04,0x01,0x04,0x01,0x04,0x01,0x04,0x00,0xF8,0x00,0x00},/*"o",79*/
|
||||||
|
{0x01,0x01,0x01,0xFF,0x00,0x85,0x01,0x04,0x01,0x04,0x00,0x88,0x00,0x70,0x00,0x00},/*"p",80*/
|
||||||
|
{0x00,0x00,0x00,0x70,0x00,0x88,0x01,0x04,0x01,0x04,0x01,0x05,0x01,0xFF,0x00,0x01},/*"q",81*/
|
||||||
|
{0x01,0x04,0x01,0x04,0x01,0xFC,0x00,0x84,0x01,0x04,0x01,0x00,0x01,0x80,0x00,0x00},/*"r",82*/
|
||||||
|
{0x00,0x00,0x00,0xCC,0x01,0x24,0x01,0x24,0x01,0x24,0x01,0x24,0x01,0x98,0x00,0x00},/*"s",83*/
|
||||||
|
{0x00,0x00,0x01,0x00,0x01,0x00,0x07,0xF8,0x01,0x04,0x01,0x04,0x00,0x00,0x00,0x00},/*"t",84*/
|
||||||
|
{0x01,0x00,0x01,0xF8,0x00,0x04,0x00,0x04,0x00,0x04,0x01,0x08,0x01,0xFC,0x00,0x04},/*"u",85*/
|
||||||
|
{0x01,0x00,0x01,0x80,0x01,0x70,0x00,0x0C,0x00,0x10,0x01,0x60,0x01,0x80,0x01,0x00},/*"v",86*/
|
||||||
|
{0x01,0xF0,0x01,0x0C,0x00,0x30,0x01,0xC0,0x00,0x30,0x01,0x0C,0x01,0xF0,0x01,0x00},/*"w",87*/
|
||||||
|
{0x00,0x00,0x01,0x04,0x01,0x8C,0x00,0x74,0x01,0x70,0x01,0x8C,0x01,0x04,0x00,0x00},/*"x",88*/
|
||||||
|
{0x01,0x01,0x01,0x81,0x01,0x71,0x00,0x0E,0x00,0x18,0x01,0x60,0x01,0x80,0x01,0x00},/*"y",89*/
|
||||||
|
{0x00,0x00,0x01,0x84,0x01,0x0C,0x01,0x34,0x01,0x44,0x01,0x84,0x01,0x0C,0x00,0x00},/*"z",90*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x3E,0xFC,0x40,0x02,0x40,0x02},/*"{",91*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00},/*"|",92*/
|
||||||
|
{0x00,0x00,0x40,0x02,0x40,0x02,0x3E,0xFC,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"}",93*/
|
||||||
|
{0x00,0x00,0x60,0x00,0x80,0x00,0x80,0x00,0x40,0x00,0x40,0x00,0x20,0x00,0x20,0x00},/*"~",94*/
|
||||||
|
};
|
||||||
|
#endif //#ifdef _USE_FONT1608
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 24*24 -- ASICII字符集点阵
|
||||||
|
*/
|
||||||
|
#ifdef _USE_FONT2412
|
||||||
|
const unsigned char asc_tft_2412[95][36]=
|
||||||
|
{
|
||||||
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*" ",0*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x80,0x38,0x0F,0xFE,0x38,0x0F,0x80,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"!",1*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x06,0x00,0x00,0x0C,0x00,0x00,0x38,0x00,0x00,0x31,0x00,0x00,0x06,0x00,0x00,0x0C,0x00,0x00,0x38,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00},/*""",2*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x61,0x80,0x00,0x67,0xF8,0x07,0xF9,0x80,0x00,0x61,0x80,0x00,0x61,0x80,0x00,0x61,0x80,0x00,0x61,0x80,0x00,0x67,0xF8,0x07,0xF9,0x80,0x00,0x61,0x80,0x00,0x00,0x00},/*"#",3*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xC0,0xE0,0x03,0xE0,0xF0,0x06,0x30,0x08,0x04,0x18,0x08,0x1F,0xFF,0xFE,0x04,0x0E,0x08,0x07,0x87,0xF0,0x03,0x81,0xE0,0x00,0x00,0x00,0x00,0x00,0x00},/*"$",4*/
|
||||||
|
{0x01,0xF0,0x00,0x06,0x0C,0x00,0x04,0x04,0x08,0x06,0x0C,0x70,0x01,0xF9,0xC0,0x00,0x0E,0x00,0x00,0x3B,0xE0,0x00,0xEC,0x18,0x07,0x08,0x08,0x04,0x0C,0x18,0x00,0x03,0xE0,0x00,0x00,0x00},/*"%",5*/
|
||||||
|
{0x00,0x01,0xE0,0x00,0x07,0xF0,0x03,0xF8,0x18,0x04,0x1C,0x08,0x04,0x17,0x08,0x07,0xE1,0xD0,0x03,0xC0,0xE0,0x00,0x23,0xB0,0x00,0x3C,0x08,0x00,0x20,0x08,0x00,0x00,0x10,0x00,0x00,0x00},/*"&",6*/
|
||||||
|
{0x00,0x00,0x00,0x01,0x00,0x00,0x31,0x00,0x00,0x32,0x00,0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"'",7*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x01,0xFF,0xC0,0x07,0x80,0xF0,0x0C,0x00,0x18,0x10,0x00,0x04,0x20,0x00,0x02,0x00,0x00,0x00},/*"(",8*/
|
||||||
|
{0x00,0x00,0x00,0x20,0x00,0x02,0x10,0x00,0x04,0x0C,0x00,0x18,0x07,0x80,0xF0,0x01,0xFF,0xC0,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*")",9*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x42,0x00,0x00,0x66,0x00,0x00,0x66,0x00,0x00,0x3C,0x00,0x00,0x18,0x00,0x03,0xFF,0xC0,0x00,0x18,0x00,0x00,0x3C,0x00,0x00,0x66,0x00,0x00,0x66,0x00,0x00,0x42,0x00},/*"*",10*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x01,0xFF,0xC0,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00},/*"+",11*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x31,0x00,0x00,0x32,0x00,0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*",",12*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x00,0x00},/*"-",13*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*".",14*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x1C,0x00,0x00,0x70,0x00,0x01,0x80,0x00,0x0E,0x00,0x00,0x38,0x00,0x00,0xC0,0x00,0x07,0x00,0x00,0x1C,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00},/*"/",15*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x7F,0x80,0x01,0xFF,0xE0,0x03,0x80,0x70,0x06,0x00,0x18,0x04,0x00,0x08,0x04,0x00,0x08,0x06,0x00,0x18,0x03,0x80,0x70,0x01,0xFF,0xE0,0x00,0x7F,0x80,0x00,0x00,0x00},/*"0",16*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x08,0x01,0x00,0x08,0x01,0x00,0x08,0x03,0xFF,0xF8,0x07,0xFF,0xF8,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00},/*"1",17*/
|
||||||
|
{0x00,0x00,0x00,0x01,0xC0,0x38,0x02,0xC0,0x58,0x04,0x00,0x98,0x04,0x01,0x18,0x04,0x02,0x18,0x04,0x04,0x18,0x06,0x1C,0x18,0x03,0xF8,0x18,0x01,0xE0,0xF8,0x00,0x00,0x00,0x00,0x00,0x00},/*"2",18*/
|
||||||
|
{0x00,0x00,0x00,0x01,0xC0,0xE0,0x03,0xC0,0xF0,0x04,0x00,0x08,0x04,0x08,0x08,0x04,0x08,0x08,0x06,0x18,0x08,0x03,0xF4,0x18,0x01,0xE7,0xF0,0x00,0x01,0xE0,0x00,0x00,0x00,0x00,0x00,0x00},/*"3",19*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x0D,0x00,0x00,0x11,0x00,0x00,0x61,0x00,0x00,0x81,0x08,0x03,0x01,0x08,0x07,0xFF,0xF8,0x0F,0xFF,0xF8,0x00,0x01,0x08,0x00,0x01,0x08,0x00,0x00,0x00},/*"4",20*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x00,0xE0,0x07,0xFC,0xD0,0x06,0x08,0x08,0x06,0x10,0x08,0x06,0x10,0x08,0x06,0x10,0x08,0x06,0x18,0x38,0x06,0x0F,0xF0,0x06,0x07,0xC0,0x00,0x00,0x00,0x00,0x00,0x00},/*"5",21*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x3F,0x80,0x01,0xFF,0xE0,0x03,0x84,0x30,0x02,0x08,0x18,0x04,0x10,0x08,0x04,0x10,0x08,0x04,0x10,0x08,0x07,0x18,0x10,0x03,0x0F,0xF0,0x00,0x07,0xC0,0x00,0x00,0x00},/*"6",22*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xC0,0x00,0x07,0x00,0x00,0x06,0x00,0x00,0x06,0x00,0xF8,0x06,0x07,0xF8,0x06,0x18,0x00,0x06,0xE0,0x00,0x07,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00},/*"7",23*/
|
||||||
|
{0x00,0x00,0x00,0x01,0xE1,0xE0,0x03,0xF7,0xF0,0x06,0x34,0x10,0x04,0x18,0x08,0x04,0x18,0x08,0x04,0x0C,0x08,0x04,0x0C,0x08,0x06,0x16,0x18,0x03,0xF3,0xF0,0x01,0xC1,0xE0,0x00,0x00,0x00},/*"8",24*/
|
||||||
|
{0x00,0x00,0x00,0x00,0xF8,0x00,0x03,0xFC,0x30,0x03,0x06,0x38,0x04,0x02,0x08,0x04,0x02,0x08,0x04,0x02,0x08,0x04,0x04,0x10,0x03,0x08,0xF0,0x01,0xFF,0xC0,0x00,0x7F,0x00,0x00,0x00,0x00},/*"9",25*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x38,0x00,0x70,0x38,0x00,0x70,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*":",26*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x1A,0x00,0x30,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*";",27*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x14,0x00,0x00,0x22,0x00,0x00,0x41,0x00,0x00,0x80,0x80,0x01,0x00,0x40,0x02,0x00,0x20,0x04,0x00,0x10,0x08,0x00,0x08,0x00,0x00,0x00},/*"<",28*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x21,0x00,0x00,0x21,0x00,0x00,0x21,0x00,0x00,0x21,0x00,0x00,0x21,0x00,0x00,0x21,0x00,0x00,0x21,0x00,0x00,0x21,0x00,0x00,0x21,0x00,0x00,0x21,0x00,0x00,0x00,0x00},/*"=",29*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x04,0x00,0x10,0x02,0x00,0x20,0x01,0x00,0x40,0x00,0x80,0x80,0x00,0x41,0x00,0x00,0x22,0x00,0x00,0x14,0x00,0x00,0x08,0x00,0x00,0x00,0x00},/*">",30*/
|
||||||
|
{0x00,0x00,0x00,0x03,0xC0,0x00,0x04,0xC0,0x00,0x04,0x00,0x00,0x08,0x00,0x38,0x08,0x0F,0x38,0x08,0x08,0x38,0x08,0x10,0x00,0x0C,0x30,0x00,0x07,0xE0,0x00,0x03,0xC0,0x00,0x00,0x00,0x00},/*"?",31*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x3F,0x80,0x00,0xFF,0xE0,0x03,0x80,0x70,0x02,0x0F,0x10,0x06,0x70,0x88,0x04,0xC0,0x88,0x04,0x83,0x08,0x04,0x7F,0x88,0x02,0xC0,0x90,0x03,0x01,0x20,0x00,0xFE,0x40},/*"@",32*/
|
||||||
|
{0x00,0x00,0x08,0x00,0x00,0x18,0x00,0x01,0xF8,0x00,0x3E,0x08,0x01,0xC2,0x00,0x07,0x02,0x00,0x07,0xE2,0x00,0x00,0xFE,0x00,0x00,0x1F,0xC8,0x00,0x01,0xF8,0x00,0x00,0x38,0x00,0x00,0x08},/*"A",33*/
|
||||||
|
{0x04,0x00,0x08,0x07,0xFF,0xF8,0x07,0xFF,0xF8,0x04,0x08,0x08,0x04,0x08,0x08,0x04,0x08,0x08,0x04,0x08,0x08,0x06,0x18,0x08,0x03,0xF4,0x18,0x01,0xE7,0xF0,0x00,0x01,0xE0,0x00,0x00,0x00},/*"B",34*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x3F,0x80,0x01,0xFF,0xE0,0x03,0x80,0x70,0x02,0x00,0x18,0x04,0x00,0x08,0x04,0x00,0x08,0x04,0x00,0x08,0x04,0x00,0x10,0x06,0x00,0x20,0x07,0x80,0xC0,0x00,0x00,0x00},/*"C",35*/
|
||||||
|
{0x04,0x00,0x08,0x07,0xFF,0xF8,0x07,0xFF,0xF8,0x04,0x00,0x08,0x04,0x00,0x08,0x04,0x00,0x08,0x04,0x00,0x18,0x02,0x00,0x10,0x03,0x80,0x70,0x01,0xFF,0xE0,0x00,0x7F,0x80,0x00,0x00,0x00},/*"D",36*/
|
||||||
|
{0x04,0x00,0x08,0x07,0xFF,0xF8,0x07,0xFF,0xF8,0x04,0x08,0x08,0x04,0x08,0x08,0x04,0x08,0x08,0x04,0x08,0x08,0x04,0x3E,0x08,0x04,0x00,0x08,0x06,0x00,0x18,0x01,0x00,0x60,0x00,0x00,0x00},/*"E",37*/
|
||||||
|
{0x04,0x00,0x08,0x07,0xFF,0xF8,0x07,0xFF,0xF8,0x04,0x08,0x08,0x04,0x08,0x00,0x04,0x08,0x00,0x04,0x08,0x00,0x04,0x3E,0x00,0x06,0x00,0x00,0x06,0x00,0x00,0x01,0x80,0x00,0x00,0x00,0x00},/*"F",38*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x3F,0x80,0x01,0xFF,0xE0,0x03,0x80,0x70,0x06,0x00,0x18,0x04,0x00,0x08,0x04,0x02,0x08,0x04,0x02,0x08,0x02,0x03,0xF0,0x07,0x83,0xF0,0x00,0x02,0x00,0x00,0x02,0x00},/*"G",39*/
|
||||||
|
{0x04,0x00,0x08,0x07,0xFF,0xF8,0x07,0xFF,0xF8,0x04,0x08,0x08,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x04,0x08,0x08,0x07,0xFF,0xF8,0x07,0xFF,0xF8,0x04,0x00,0x08},/*"H",40*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x08,0x04,0x00,0x08,0x04,0x00,0x08,0x07,0xFF,0xF8,0x07,0xFF,0xF8,0x04,0x00,0x08,0x04,0x00,0x08,0x04,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00},/*"I",41*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x07,0x00,0x00,0x01,0x04,0x00,0x01,0x04,0x00,0x01,0x04,0x00,0x03,0x07,0xFF,0xFE,0x07,0xFF,0xFC,0x04,0x00,0x00,0x04,0x00,0x00,0x04,0x00,0x00},/*"J",42*/
|
||||||
|
{0x04,0x00,0x08,0x07,0xFF,0xF8,0x07,0xFF,0xF8,0x04,0x0C,0x08,0x00,0x18,0x00,0x00,0x3E,0x00,0x04,0xC7,0x80,0x05,0x03,0xC8,0x06,0x00,0xF8,0x04,0x00,0x38,0x04,0x00,0x18,0x00,0x00,0x08},/*"K",43*/
|
||||||
|
{0x04,0x00,0x08,0x07,0xFF,0xF8,0x07,0xFF,0xF8,0x04,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x18,0x00,0x00,0x60,0x00,0x00,0x00},/*"L",44*/
|
||||||
|
{0x04,0x00,0x08,0x07,0xFF,0xF8,0x07,0x80,0x08,0x07,0xFC,0x00,0x00,0x7F,0xC0,0x00,0x03,0xF8,0x00,0x07,0xC0,0x00,0x78,0x00,0x07,0x80,0x08,0x07,0xFF,0xF8,0x07,0xFF,0xF8,0x04,0x00,0x08},/*"M",45*/
|
||||||
|
{0x04,0x00,0x08,0x07,0xFF,0xF8,0x07,0x00,0x08,0x03,0xC0,0x00,0x00,0xE0,0x00,0x00,0x38,0x00,0x00,0x1E,0x00,0x00,0x07,0x00,0x00,0x01,0xC0,0x04,0x00,0xF0,0x07,0xFF,0xF8,0x04,0x00,0x00},/*"N",46*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x7F,0x80,0x01,0xFF,0xE0,0x03,0x80,0x70,0x06,0x00,0x18,0x04,0x00,0x08,0x04,0x00,0x08,0x06,0x00,0x18,0x03,0x00,0x30,0x01,0xFF,0xE0,0x00,0x7F,0x80,0x00,0x00,0x00},/*"O",47*/
|
||||||
|
{0x04,0x00,0x08,0x07,0xFF,0xF8,0x07,0xFF,0xF8,0x04,0x04,0x08,0x04,0x04,0x00,0x04,0x04,0x00,0x04,0x04,0x00,0x04,0x04,0x00,0x06,0x0C,0x00,0x03,0xF8,0x00,0x01,0xF0,0x00,0x00,0x00,0x00},/*"P",48*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x7F,0x80,0x01,0xFF,0xE0,0x03,0x80,0x70,0x06,0x00,0x88,0x04,0x00,0x88,0x04,0x00,0xC8,0x06,0x00,0x3C,0x03,0x00,0x3E,0x01,0xFF,0xE6,0x00,0x7F,0x84,0x00,0x00,0x00},/*"Q",49*/
|
||||||
|
{0x04,0x00,0x08,0x07,0xFF,0xF8,0x07,0xFF,0xF8,0x04,0x08,0x08,0x04,0x08,0x00,0x04,0x0C,0x00,0x04,0x0F,0x00,0x04,0x0B,0xC0,0x06,0x10,0xF0,0x03,0xF0,0x38,0x01,0xE0,0x08,0x00,0x00,0x08},/*"R",50*/
|
||||||
|
{0x00,0x00,0x00,0x01,0xE0,0xF8,0x03,0xF0,0x30,0x06,0x30,0x10,0x04,0x18,0x08,0x04,0x18,0x08,0x04,0x0C,0x08,0x04,0x0C,0x08,0x02,0x06,0x18,0x02,0x07,0xF0,0x07,0x81,0xE0,0x00,0x00,0x00},/*"S",51*/
|
||||||
|
{0x01,0x80,0x00,0x06,0x00,0x00,0x04,0x00,0x00,0x04,0x00,0x00,0x04,0x00,0x08,0x07,0xFF,0xF8,0x07,0xFF,0xF8,0x04,0x00,0x08,0x04,0x00,0x00,0x04,0x00,0x00,0x06,0x00,0x00,0x01,0x80,0x00},/*"T",52*/
|
||||||
|
{0x04,0x00,0x00,0x07,0xFF,0xE0,0x07,0xFF,0xF0,0x04,0x00,0x18,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x04,0x00,0x10,0x07,0xFF,0xE0,0x04,0x00,0x00},/*"U",53*/
|
||||||
|
{0x04,0x00,0x00,0x06,0x00,0x00,0x07,0xE0,0x00,0x07,0xFE,0x00,0x04,0x1F,0xE0,0x00,0x01,0xF8,0x00,0x00,0x38,0x00,0x01,0xE0,0x04,0x3E,0x00,0x07,0xC0,0x00,0x06,0x00,0x00,0x04,0x00,0x00},/*"V",54*/
|
||||||
|
{0x04,0x00,0x00,0x07,0xE0,0x00,0x07,0xFF,0xC0,0x04,0x1F,0xF8,0x00,0x07,0xC0,0x07,0xF8,0x00,0x07,0xFF,0x80,0x04,0x3F,0xF8,0x00,0x07,0xC0,0x04,0xF8,0x00,0x07,0x00,0x00,0x04,0x00,0x00},/*"W",55*/
|
||||||
|
{0x00,0x00,0x00,0x04,0x00,0x08,0x06,0x00,0x18,0x07,0xC0,0x78,0x05,0xF1,0xC8,0x00,0x3E,0x00,0x00,0x1F,0x80,0x04,0x63,0xE8,0x07,0x80,0xF8,0x06,0x00,0x18,0x04,0x00,0x08,0x00,0x00,0x00},/*"X",56*/
|
||||||
|
{0x04,0x00,0x00,0x06,0x00,0x00,0x07,0x80,0x00,0x07,0xE0,0x08,0x04,0x7C,0x08,0x00,0x1F,0xF8,0x00,0x07,0xF8,0x00,0x18,0x08,0x04,0xE0,0x08,0x07,0x00,0x00,0x06,0x00,0x00,0x04,0x00,0x00},/*"Y",57*/
|
||||||
|
{0x00,0x00,0x00,0x01,0x00,0x08,0x06,0x00,0x38,0x04,0x00,0xF8,0x04,0x03,0xE8,0x04,0x0F,0x08,0x04,0x7C,0x08,0x05,0xF0,0x08,0x07,0xC0,0x08,0x07,0x00,0x18,0x04,0x00,0x60,0x00,0x00,0x00},/*"Z",58*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0xFF,0xFE,0x20,0x00,0x02,0x20,0x00,0x02,0x20,0x00,0x02,0x20,0x00,0x02,0x20,0x00,0x02,0x00,0x00,0x00},/*"[",59*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x07,0x00,0x00,0x00,0xC0,0x00,0x00,0x38,0x00,0x00,0x06,0x00,0x00,0x01,0xC0,0x00,0x00,0x30,0x00,0x00,0x0E,0x00,0x00,0x01,0x00,0x00,0x00},/*"\",60*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x02,0x20,0x00,0x02,0x20,0x00,0x02,0x20,0x00,0x02,0x20,0x00,0x02,0x3F,0xFF,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"]",61*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x10,0x00,0x00,0x30,0x00,0x00,0x20,0x00,0x00,0x30,0x00,0x00,0x10,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"^",62*/
|
||||||
|
{0x00,0x00,0x01,0x00,0x00,0x01,0x00,0x00,0x01,0x00,0x00,0x01,0x00,0x00,0x01,0x00,0x00,0x01,0x00,0x00,0x01,0x00,0x00,0x01,0x00,0x00,0x01,0x00,0x00,0x01,0x00,0x00,0x01,0x00,0x00,0x01},/*"_",63*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x20,0x00,0x00,0x10,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"`",64*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0x19,0xF8,0x00,0x1B,0x18,0x00,0x22,0x08,0x00,0x26,0x08,0x00,0x24,0x08,0x00,0x24,0x10,0x00,0x3F,0xF8,0x00,0x1F,0xF8,0x00,0x00,0x08,0x00,0x00,0x18},/*"a",65*/
|
||||||
|
{0x00,0x00,0x00,0x04,0x00,0x00,0x07,0xFF,0xF8,0x0F,0xFF,0xF0,0x00,0x18,0x18,0x00,0x10,0x08,0x00,0x20,0x08,0x00,0x20,0x08,0x00,0x30,0x18,0x00,0x1F,0xF0,0x00,0x0F,0xC0,0x00,0x00,0x00},/*"b",66*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x07,0xC0,0x00,0x1F,0xF0,0x00,0x18,0x30,0x00,0x20,0x08,0x00,0x20,0x08,0x00,0x20,0x08,0x00,0x3C,0x08,0x00,0x1C,0x10,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00},/*"c",67*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x07,0xC0,0x00,0x1F,0xF0,0x00,0x38,0x18,0x00,0x20,0x08,0x00,0x20,0x08,0x00,0x20,0x08,0x04,0x10,0x10,0x07,0xFF,0xF8,0x0F,0xFF,0xF0,0x00,0x00,0x10,0x00,0x00,0x00},/*"d",68*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xC0,0x00,0x1F,0xF0,0x00,0x12,0x30,0x00,0x22,0x18,0x00,0x22,0x08,0x00,0x22,0x08,0x00,0x32,0x08,0x00,0x1E,0x10,0x00,0x0E,0x20,0x00,0x00,0x00},/*"e",69*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x20,0x08,0x00,0x20,0x08,0x01,0xFF,0xF8,0x03,0xFF,0xF8,0x06,0x20,0x08,0x04,0x20,0x08,0x04,0x20,0x08,0x07,0x20,0x00,0x03,0x00,0x00,0x00,0x00,0x00},/*"f",70*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x0E,0x6E,0x00,0x1F,0xF3,0x00,0x31,0xB1,0x00,0x20,0xB1,0x00,0x20,0xB1,0x00,0x31,0x91,0x00,0x1F,0x13,0x00,0x2E,0x1E,0x00,0x20,0x0E,0x00,0x30,0x00},/*"g",71*/
|
||||||
|
{0x00,0x00,0x00,0x04,0x00,0x08,0x07,0xFF,0xF8,0x0F,0xFF,0xF8,0x00,0x10,0x08,0x00,0x20,0x00,0x00,0x20,0x00,0x00,0x20,0x08,0x00,0x3F,0xF8,0x00,0x1F,0xF8,0x00,0x00,0x08,0x00,0x00,0x00},/*"h",72*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x08,0x00,0x20,0x08,0x00,0x20,0x08,0x06,0x3F,0xF8,0x06,0x3F,0xF8,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00},/*"i",73*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x03,0x00,0x20,0x01,0x00,0x20,0x01,0x00,0x20,0x03,0x06,0x3F,0xFE,0x06,0x3F,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"j",74*/
|
||||||
|
{0x00,0x00,0x00,0x04,0x00,0x08,0x07,0xFF,0xF8,0x0F,0xFF,0xF8,0x00,0x01,0x88,0x00,0x03,0x00,0x00,0x2F,0xC0,0x00,0x38,0xF8,0x00,0x20,0x38,0x00,0x20,0x08,0x00,0x00,0x08,0x00,0x00,0x00},/*"k",75*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x08,0x04,0x00,0x08,0x04,0x00,0x08,0x07,0xFF,0xF8,0x0F,0xFF,0xF8,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00},/*"l",76*/
|
||||||
|
{0x00,0x20,0x08,0x00,0x3F,0xF8,0x00,0x3F,0xF8,0x00,0x10,0x08,0x00,0x20,0x00,0x00,0x3F,0xF8,0x00,0x3F,0xF8,0x00,0x10,0x08,0x00,0x20,0x00,0x00,0x3F,0xF8,0x00,0x3F,0xF8,0x00,0x00,0x08},/*"m",77*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x20,0x08,0x00,0x3F,0xF8,0x00,0x3F,0xF8,0x00,0x10,0x08,0x00,0x10,0x00,0x00,0x20,0x00,0x00,0x20,0x08,0x00,0x3F,0xF8,0x00,0x1F,0xF8,0x00,0x00,0x08,0x00,0x00,0x00},/*"n",78*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x07,0xC0,0x00,0x0F,0xF0,0x00,0x18,0x30,0x00,0x30,0x08,0x00,0x20,0x08,0x00,0x20,0x08,0x00,0x30,0x08,0x00,0x18,0x30,0x00,0x0F,0xF0,0x00,0x07,0xC0,0x00,0x00,0x00},/*"o",79*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x20,0x01,0x00,0x3F,0xFF,0x00,0x3F,0xFF,0x00,0x10,0x11,0x00,0x20,0x09,0x00,0x20,0x08,0x00,0x20,0x08,0x00,0x30,0x38,0x00,0x1F,0xF0,0x00,0x0F,0xC0,0x00,0x00,0x00},/*"p",80*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x07,0xC0,0x00,0x1F,0xF0,0x00,0x38,0x18,0x00,0x20,0x08,0x00,0x20,0x08,0x00,0x20,0x09,0x00,0x10,0x11,0x00,0x1F,0xFF,0x00,0x3F,0xFF,0x00,0x00,0x01,0x00,0x00,0x00},/*"q",81*/
|
||||||
|
{0x00,0x20,0x08,0x00,0x20,0x08,0x00,0x20,0x08,0x00,0x3F,0xF8,0x00,0x3F,0xF8,0x00,0x08,0x08,0x00,0x10,0x08,0x00,0x20,0x08,0x00,0x20,0x00,0x00,0x30,0x00,0x00,0x30,0x00,0x00,0x00,0x00},/*"r",82*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x78,0x00,0x1E,0x18,0x00,0x33,0x08,0x00,0x23,0x08,0x00,0x21,0x08,0x00,0x21,0x88,0x00,0x21,0x98,0x00,0x30,0xF0,0x00,0x38,0x60,0x00,0x00,0x00},/*"s",83*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x20,0x00,0x00,0x20,0x00,0x00,0xFF,0xF0,0x03,0xFF,0xF8,0x00,0x20,0x08,0x00,0x20,0x08,0x00,0x20,0x08,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00},/*"t",84*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x3F,0xF0,0x00,0x7F,0xF8,0x00,0x00,0x18,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x20,0x10,0x00,0x3F,0xF8,0x00,0x7F,0xF0,0x00,0x00,0x10,0x00,0x00,0x00},/*"u",85*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x30,0x00,0x00,0x3C,0x00,0x00,0x3F,0x80,0x00,0x23,0xF0,0x00,0x00,0x78,0x00,0x00,0x70,0x00,0x23,0x80,0x00,0x3C,0x00,0x00,0x30,0x00,0x00,0x20,0x00},/*"v",86*/
|
||||||
|
{0x00,0x20,0x00,0x00,0x3C,0x00,0x00,0x3F,0xE0,0x00,0x23,0xF8,0x00,0x00,0xE0,0x00,0x27,0x00,0x00,0x3E,0x00,0x00,0x3F,0xE0,0x00,0x21,0xF8,0x00,0x01,0xE0,0x00,0x3E,0x00,0x00,0x20,0x00},/*"w",87*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x20,0x08,0x00,0x20,0x08,0x00,0x38,0x38,0x00,0x3E,0x68,0x00,0x27,0x80,0x00,0x03,0xC8,0x00,0x2C,0xF8,0x00,0x38,0x38,0x00,0x20,0x18,0x00,0x20,0x08,0x00,0x00,0x00},/*"x",88*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x30,0x03,0x00,0x3C,0x01,0x00,0x3F,0x83,0x00,0x23,0xEC,0x00,0x00,0x70,0x00,0x23,0x80,0x00,0x3C,0x00,0x00,0x20,0x00,0x00,0x20,0x00,0x00,0x00,0x00},/*"y",89*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x08,0x00,0x20,0x38,0x00,0x20,0xF8,0x00,0x23,0xE8,0x00,0x2F,0x88,0x00,0x3E,0x08,0x00,0x38,0x08,0x00,0x20,0x18,0x00,0x00,0x70,0x00,0x00,0x00},/*"z",90*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x14,0x00,0x1F,0xF7,0xFC,0x30,0x00,0x06,0x20,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00},/*"{",91*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"|",92*/
|
||||||
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x02,0x30,0x00,0x06,0x1F,0xF7,0xFC,0x00,0x14,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"}",93*/
|
||||||
|
{0x00,0x00,0x00,0x18,0x00,0x00,0x60,0x00,0x00,0x40,0x00,0x00,0x40,0x00,0x00,0x20,0x00,0x00,0x10,0x00,0x00,0x08,0x00,0x00,0x04,0x00,0x00,0x04,0x00,0x00,0x0C,0x00,0x00,0x10,0x00,0x00},/*"~",94*/
|
||||||
|
};
|
||||||
|
#endif //#ifdef _USE_FONT2412
|
||||||
|
|
||||||
|
#endif //#ifndef __TASK_TFT_FONT_H__
|
||||||
|
|
||||||
|
/* ******************** Copyright (C), 2017-2017, TYUT TSS-plan by SERI.LJI ******************** */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,167 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* TFT 3.2寸显示屏驱动文件,目前使用FSMC(stm32f407系列可用,其他暂不支持!)
|
||||||
|
*
|
||||||
|
* 功能说明:
|
||||||
|
* 1.包含基本的显示、画点、画线功能及基本的数字显示;
|
||||||
|
* 2.包含中点画圆算法和改进中点画圆算法;
|
||||||
|
* 3.包含中点画椭圆算法;
|
||||||
|
* 4.显示字符的函数可返回当前目标所占空间的状态(坐标范围和颜色状态等!);
|
||||||
|
* 5.TFT的算法和OLED算法不同,TFT是按点写入,OLED按字节,因此TFT不存在覆盖!
|
||||||
|
* 6.区域操作的时间很长,有视觉可分辨延时,原因是对数组操作耗时太长!
|
||||||
|
*
|
||||||
|
* 使用注意:
|
||||||
|
* 1.本文件是不使用emWin等成熟移植方案的测试版本;
|
||||||
|
* 2.本文件并不独立,部分函数依赖硬件,目前是FSMC版本!
|
||||||
|
* 3.本程序为GUI界面服务,除学习外不得作为他用!同时欢迎不断补充功能!
|
||||||
|
*
|
||||||
|
* 版本修订:
|
||||||
|
* 修改时间 版本号 修改内容
|
||||||
|
* 2017-01-01 v1.0 移植oled程序,构建本文件;
|
||||||
|
* 2017-01-02 v2.0 增加中点画圆算法和改进中点画圆算法;
|
||||||
|
* 2017-01-02 v2.1 增加中点画椭圆算法和改进中点画椭圆算法;
|
||||||
|
* 2017-03-05 v3.0 添加区域移屏、翻转、颜色替换、颜色对调操作函数;
|
||||||
|
* 2017-03-05 v3.1 添加了操作的全局控制开关量;
|
||||||
|
* 2018-01-023 v4.0 重构文件,对部分函数进行优化,部分函数名修改!
|
||||||
|
* 2021-03-28 v5.0 添加gd32f407
|
||||||
|
*
|
||||||
|
* 程序出处:
|
||||||
|
* Copyright (C), 2017-2017, TYUT TSS-plan by SERI.LJI
|
||||||
|
* All rights reserved
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Create :2017年01月01日
|
||||||
|
* Update :2018年01月23日
|
||||||
|
* Author :dengchow
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
***/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __TASK_TFT_H__
|
||||||
|
#define __TASK_TFT_H__
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*Task_tft.h Needed Library Define*/
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*Task_tft.h Command Define*/
|
||||||
|
#define TFT_MAX_LENGTH_OF_DEC (10) //最大显示十进制位数
|
||||||
|
|
||||||
|
#define TFT_SWAP_TEMP_COLOR BLACK //颜色对调时临时替换颜色
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*Task_tft.h Param Define*/
|
||||||
|
///*移屏函数方向参数枚举*/
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
TFT_DIRECT_UP = (uint8_t)1,
|
||||||
|
TFT_DIRECT_DOWN = (uint8_t)2,
|
||||||
|
TFT_DIRECT_LEFT = (uint8_t)3,
|
||||||
|
TFT_DIRECT_RIGHT = (uint8_t)4,
|
||||||
|
}_TFTScrollDirect;
|
||||||
|
|
||||||
|
///*翻转函数方向参数枚举*/
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
TFT_TURN_L2R = (uint8_t)1,
|
||||||
|
TFT_TURN_U2D = (uint8_t)2,
|
||||||
|
}_TFTTurnDirect;
|
||||||
|
|
||||||
|
///*区域对齐函数参数枚举*/
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
TFT_ALIGN_H_CENTER = (uint8_t)0, //对齐方式,水平方向居中对齐(垂直水平分组按奇偶分!)
|
||||||
|
TFT_ALIGN_H_LEFT = (uint8_t)2, //对齐方式,水平方向居左对齐
|
||||||
|
TFT_ALIGN_H_RIGHT = (uint8_t)4, //对齐方式,水平方向居右对齐
|
||||||
|
|
||||||
|
TFT_ALIGN_V_CENTER = (uint8_t)1, //对齐方式,垂直方向居中对齐
|
||||||
|
TFT_ALIGN_V_TOP = (uint8_t)3, //对齐方式,垂直方向居上对齐
|
||||||
|
TFT_ALIGN_V_BOTTOM = (uint8_t)5, //对齐方式,垂直方向居下对齐
|
||||||
|
}_TFTAlignMode;
|
||||||
|
|
||||||
|
///TFT显示状态句柄:
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint16_t FC; //前景板颜色(画笔)
|
||||||
|
uint16_t BC; //背景板颜色(背景)
|
||||||
|
|
||||||
|
uint16_t XS; //起始坐标
|
||||||
|
uint16_t YS; //
|
||||||
|
uint16_t XE; //终止坐标
|
||||||
|
uint16_t YE; //
|
||||||
|
|
||||||
|
uint16_t Num; //若显示字符串,这里统计字符个数!
|
||||||
|
uint8_t FontSize; //字体
|
||||||
|
}_TFTDisplayStyleStruct;
|
||||||
|
|
||||||
|
///TFT区域对齐集合:
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint16_t X; //对齐后左上角横坐标
|
||||||
|
uint16_t Y; //对齐后左上角纵坐标
|
||||||
|
}_TFTAlignStruct;
|
||||||
|
|
||||||
|
extern _TFTDisplayStyleStruct DefaultStyle;//默认风格:白底黑字,1206字体
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*Task_tft.h Function Define*/
|
||||||
|
uint16_t TFT_BGR2RGB(uint16_t BGR);//BGR转化为RGB
|
||||||
|
uint16_t TFT_RGB2BGR(uint16_t RGB);//RGB转化为BGR
|
||||||
|
uint16_t TFT_MakeColor(uint8_t R, uint8_t G, uint8_t B);//调色函数(输入RGB三色值,输出TFT的颜色值)
|
||||||
|
void TFT_GetColor(uint16_t Color, uint8_t *R, uint8_t *G, uint8_t *B);//提色函数(输入TFT的颜色值,输出RGB三色值)
|
||||||
|
|
||||||
|
///图形系列函数:
|
||||||
|
void TFT_DrawBlock(uint16_t XS, uint16_t YS, uint16_t XE, uint16_t YE, uint16_t color);//画矩形框
|
||||||
|
void TFT_DrawRect(uint16_t XS, uint16_t YS, uint16_t width, uint16_t height, uint16_t BlockC, uint16_t FillC);//画矩形(填充矩形)
|
||||||
|
void TFT_DrawLine(uint16_t XS, uint16_t YS, uint16_t XE, uint16_t YE, uint16_t color);//画实线
|
||||||
|
void TFT_DrawDottedLine(uint16_t XS, uint16_t YS, uint16_t XE, uint16_t YE, uint16_t color);//画虚线
|
||||||
|
void TFT_DrawCircle(uint16_t XC, uint16_t YC, uint16_t R, uint16_t color);//画圆
|
||||||
|
void TFT_DrawCircle2(uint16_t XC, uint16_t YC, uint16_t R, uint16_t color);//改进画圆
|
||||||
|
void TFT_DrawEllipse(uint16_t XC, uint16_t YC, uint16_t A, uint16_t B, uint16_t color);//画椭圆
|
||||||
|
void TFT_DrawPIC16(uint16_t XS, uint16_t YS, uint16_t width, uint16_t height, uint8_t *PIC);//画16位bmp格式图片
|
||||||
|
|
||||||
|
|
||||||
|
///Display系列函数:
|
||||||
|
_TFTDisplayStyleStruct TFT_DisplayCHAR(uint16_t X, uint16_t Y, _TFTDisplayStyleStruct *style, char CHAR);//显示字符
|
||||||
|
_TFTDisplayStyleStruct TFT_DisplaySTR(uint16_t X, uint16_t Y, _TFTDisplayStyleStruct *style, char *STR);//显示字符串
|
||||||
|
_TFTDisplayStyleStruct TFT_DisplayHEX(uint16_t X, uint16_t Y, _TFTDisplayStyleStruct *style, uint16_t HEX);//显示转化后的16进制数字
|
||||||
|
_TFTDisplayStyleStruct TFT_DisplayINT(uint16_t X, uint16_t Y, _TFTDisplayStyleStruct *style, int32_t INT);//显示有符号的十进制数字
|
||||||
|
_TFTDisplayStyleStruct TFT_DisplayFLOAT(uint16_t X, uint16_t Y, _TFTDisplayStyleStruct *style, float FLOAT, uint8_t accu);//显示可变精度小数
|
||||||
|
|
||||||
|
|
||||||
|
///区域相关系列函数:
|
||||||
|
void TFT_Move(_TFTDisplayStyleStruct *area, _TFTScrollDirect direct, uint8_t loop);//移屏操作
|
||||||
|
void TFT_Turn(_TFTDisplayStyleStruct *area, _TFTTurnDirect direct);//翻转操作
|
||||||
|
uint8_t TFT_ColorChange(_TFTDisplayStyleStruct *area, uint16_t src, uint16_t tgt);//颜色替换操作
|
||||||
|
void TFT_ColorSwap(_TFTDisplayStyleStruct *area);//颜色对调操作
|
||||||
|
|
||||||
|
|
||||||
|
///显示状态设置系列函数:
|
||||||
|
void TFT_StyleStructInit(_TFTDisplayStyleStruct *style);//对创建的结构体进行初始化
|
||||||
|
void TFT_SetColorFont(uint16_t penColor, uint16_t backColor, uint8_t fontSize, _TFTDisplayStyleStruct *style);//设置前后板颜色、字体大小
|
||||||
|
void TFT_SetPosition(uint16_t XS, uint16_t YS, uint16_t XE, uint16_t YE, _TFTDisplayStyleStruct *style);//设置显示的坐标
|
||||||
|
_TFTAlignStruct TFT_Align(_TFTDisplayStyleStruct *area, _TFTAlignMode align);//区域对齐操作
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* ******************** Copyright (C), 2017-2017, TYUT TSS-plan by SERI.LJI ******************** */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021, SERI Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2021-10-29 Lyons first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "__def.h"
|
||||||
|
|
||||||
|
#include "uart.h"
|
||||||
|
#include "timer.h"
|
||||||
|
|
||||||
|
#include "rtconfig.h"
|
||||||
|
|
||||||
|
extern void trap_entry();
|
||||||
|
|
||||||
|
void init(void)
|
||||||
|
{
|
||||||
|
write_csr(mtvec, &trap_entry);
|
||||||
|
write_csr(mstatus, 0x00001800);
|
||||||
|
|
||||||
|
write_csr(mtval, 0);
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021, SERI Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2021-10-29 Lyons first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "__def.h"
|
||||||
|
#include "xprintf.h"
|
||||||
|
|
||||||
|
extern void timer1_handler(void);
|
||||||
|
extern void soft_handler(void);
|
||||||
|
|
||||||
|
void trap_handler(uint32_t irqno, uint32_t epc)
|
||||||
|
{
|
||||||
|
if (0x80000003 == irqno)
|
||||||
|
{
|
||||||
|
timer1_handler();
|
||||||
|
} else {
|
||||||
|
xprintf("irqno: %08x\n", irqno);
|
||||||
|
xprintf("break: %08x\n", epc);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,79 @@
|
||||||
|
OUTPUT_ARCH( "riscv" )
|
||||||
|
ENTRY(_start)
|
||||||
|
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
rom (rx) : ORIGIN = 0x00000000, LENGTH = 28K
|
||||||
|
ram (rwx) : ORIGIN = 0x10000000, LENGTH = 12K
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
.init :
|
||||||
|
{
|
||||||
|
KEEP (*(SORT_NONE(.init)))
|
||||||
|
} >rom
|
||||||
|
|
||||||
|
.text :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
__fsymtab_start = .;
|
||||||
|
KEEP(*(FSymTab))
|
||||||
|
__fsymtab_end = .;
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
__vsymtab_start = .;
|
||||||
|
KEEP(*(VSymTab))
|
||||||
|
__vsymtab_end = .;
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
*(.text.unlikely .text.unlikely.*)
|
||||||
|
*(.text.startup .text.startup.*)
|
||||||
|
*(.text .text.*)
|
||||||
|
*(.gnu.linkonce.t.*)
|
||||||
|
} >rom
|
||||||
|
|
||||||
|
.data :
|
||||||
|
{
|
||||||
|
__data_lma = LOADADDR(.data);
|
||||||
|
__data_start = .;
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
__rt_init_start = .;
|
||||||
|
KEEP(*(SORT(.rti_fn*)))
|
||||||
|
__rt_init_end = .;
|
||||||
|
|
||||||
|
*(.rdata)
|
||||||
|
*(.rodata .rodata.*)
|
||||||
|
*(.gnu.linkonce.r.*)
|
||||||
|
*(.data .data.*)
|
||||||
|
*(.gnu.linkonce.d.*)
|
||||||
|
*(.sdata .sdata.*)
|
||||||
|
*(.sdata*)
|
||||||
|
*(.gnu.linkonce.s.*)
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
__data_end = .;
|
||||||
|
} >ram AT>rom
|
||||||
|
|
||||||
|
.bss :
|
||||||
|
{
|
||||||
|
__bss_start = .;
|
||||||
|
|
||||||
|
*(.sbss .sbss.*)
|
||||||
|
*(.gnu.linkonce.sb.*)
|
||||||
|
*(.bss .bss.*)
|
||||||
|
*(.gnu.linkonce.b.*)
|
||||||
|
*(COMMON)
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
__bss_end = .;
|
||||||
|
__end = .;
|
||||||
|
} >ram
|
||||||
|
|
||||||
|
.stack ORIGIN(ram) + LENGTH(ram):
|
||||||
|
{
|
||||||
|
__stack_top = .;
|
||||||
|
} >ram
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,91 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021, SERI Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2021-10-29 Lyons first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "__def.h"
|
||||||
|
#include "systick.h"
|
||||||
|
#include "gpio.h"
|
||||||
|
#include "timer.h"
|
||||||
|
#include "uart.h"
|
||||||
|
#include "xprintf.h"
|
||||||
|
|
||||||
|
#include "rtthread.h"
|
||||||
|
|
||||||
|
// #define TEST_UART
|
||||||
|
// #define TEST_LCD
|
||||||
|
|
||||||
|
#ifdef TEST_LCD
|
||||||
|
#include "Driver_tftspi.h"
|
||||||
|
#include "Task_tft.h"
|
||||||
|
#endif // #ifdef TEST_LCD
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
#ifdef TEST_UART
|
||||||
|
int sum;
|
||||||
|
int mul;
|
||||||
|
int div;
|
||||||
|
|
||||||
|
sum = 0;
|
||||||
|
for (int i = 1; i <= 100; i++) {
|
||||||
|
sum += i;
|
||||||
|
}
|
||||||
|
xprintf("add: 1+2+..+100 = %5d, expect: %5d\n", sum, 5050);
|
||||||
|
|
||||||
|
sum = 0;
|
||||||
|
for (int i = 1; i <= 100; i++) {
|
||||||
|
sum -= i;
|
||||||
|
}
|
||||||
|
xprintf("sub: -1-2-..-100 = %5d, expect: %5d\n", sum, -5050);
|
||||||
|
|
||||||
|
mul = 1;
|
||||||
|
for (int i = 1; i <= 8; i++) {
|
||||||
|
mul *= i;
|
||||||
|
}
|
||||||
|
xprintf("mul: 1*2*..*8 = %5d, expect: %5d\n", mul, 40320);
|
||||||
|
|
||||||
|
div = 19960214;
|
||||||
|
for (int i = 1; i <= 8; i++) {
|
||||||
|
div /= i;
|
||||||
|
}
|
||||||
|
xprintf("div: %d, expect: %d\n", div, 495);
|
||||||
|
#endif // #ifdef TEST_UART
|
||||||
|
|
||||||
|
#ifdef TEST_LCD
|
||||||
|
TFT_InitConfig();
|
||||||
|
|
||||||
|
TFT_Select(0xff, 1);
|
||||||
|
TFT_DisplaySTR(0, 0, &DefaultStyle, "Hello, World!");
|
||||||
|
|
||||||
|
TFT_Select(0xff, 0);
|
||||||
|
#endif // #ifdef TEST_LCD
|
||||||
|
|
||||||
|
timer_init(TIM1, CPU_FREQ_MHZ-1, (1000/RT_TICK_PER_SECOND)*1000); // tick = 1ms
|
||||||
|
timer_control(TIM1, TIM_EN);
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
POut(0,1);
|
||||||
|
rt_thread_mdelay(500);
|
||||||
|
POut(0,0);
|
||||||
|
rt_thread_mdelay(500);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void timer1_handler(void)
|
||||||
|
{
|
||||||
|
rt_enter_critical();
|
||||||
|
|
||||||
|
extern void rt_os_tick_callback(void);
|
||||||
|
rt_os_tick_callback();
|
||||||
|
|
||||||
|
rt_exit_critical();
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
*.pyc
|
||||||
|
*.map
|
||||||
|
*.dblite
|
||||||
|
*.elf
|
||||||
|
*.bin
|
||||||
|
*.hex
|
||||||
|
*.axf
|
||||||
|
*.exe
|
||||||
|
*.pdb
|
||||||
|
*.idb
|
||||||
|
*.ilk
|
||||||
|
*.old
|
||||||
|
build
|
||||||
|
Debug
|
||||||
|
documentation/html
|
||||||
|
*~
|
||||||
|
*.o
|
||||||
|
*.obj
|
||||||
|
*.bak
|
||||||
|
*.dep
|
||||||
|
*.lib
|
||||||
|
*.a
|
||||||
|
*.i
|
||||||
|
*.d
|
||||||
|
tools/kconfig-frontends/kconfig-mconf
|
||||||
|
packages
|
||||||
|
cconfig.h
|
||||||
|
GPUCache
|
||||||
|
|
||||||
|
#cscope files
|
||||||
|
cscope.*
|
||||||
|
ncscope.*
|
||||||
|
|
||||||
|
#ctag files
|
||||||
|
tags
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
Kernel Design & Implementation
|
||||||
|
- Bernard Xiong <bernard.xiong@gmail.com>
|
||||||
|
|
||||||
|
LwIP 1.3.0/1.3.1/1.3.2/1.4.0
|
||||||
|
- Porting
|
||||||
|
Qiu Yi
|
||||||
|
Mbbill
|
||||||
|
- Testing
|
||||||
|
Bernard Xiong
|
||||||
|
|
||||||
|
Filesystem
|
||||||
|
- Porting and Add Virtual Filesystem
|
||||||
|
- Testing
|
||||||
|
Qiu Yi
|
||||||
|
prife
|
||||||
|
|
||||||
|
RTGUI
|
||||||
|
- Design and Implemenation
|
||||||
|
Bernard Xiong
|
||||||
|
Grissiom
|
||||||
|
|
||||||
|
BSP
|
||||||
|
Bernard Xiong
|
||||||
|
- ATMEL AT91SAM7S64 & AT91SAM7X256 Porting
|
||||||
|
- STM32 Porting
|
||||||
|
- S3C4510 Porting
|
||||||
|
|
||||||
|
Mbbill
|
||||||
|
- ATMEL AT91SAM7X256
|
||||||
|
|
||||||
|
Xulong Cao
|
||||||
|
- QEMU/x86
|
||||||
|
|
||||||
|
Aozima
|
||||||
|
- LPC 2148 Porting
|
||||||
|
- STM32 Porting
|
||||||
|
|
||||||
|
Jing Lee
|
||||||
|
- LPC 2478 Porting
|
||||||
|
|
||||||
|
Qiu Yi
|
||||||
|
- S3C2410 & S3C2440 Porting
|
||||||
|
- TI LM3S
|
||||||
|
|
||||||
|
others...
|
|
@ -0,0 +1,201 @@
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright [yyyy] [name of copyright owner]
|
||||||
|
|
||||||
|
Licensed 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.
|
|
@ -0,0 +1,69 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2019, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2021-05-24 the first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <rthw.h>
|
||||||
|
#include <rtthread.h>
|
||||||
|
|
||||||
|
#if defined(RT_USING_USER_MAIN) && defined(RT_USING_HEAP)
|
||||||
|
/*
|
||||||
|
* Please modify RT_HEAP_SIZE if you enable RT_USING_HEAP
|
||||||
|
* the RT_HEAP_SIZE max value = (sram size - ZI size), 1024 means 1024 bytes
|
||||||
|
*/
|
||||||
|
#ifndef RT_HEAP_SIZE
|
||||||
|
#define RT_HEAP_SIZE (15*1024)
|
||||||
|
#endif
|
||||||
|
static rt_uint8_t rt_heap[RT_HEAP_SIZE];
|
||||||
|
|
||||||
|
RT_WEAK void *rt_heap_begin_get(void)
|
||||||
|
{
|
||||||
|
return rt_heap;
|
||||||
|
}
|
||||||
|
|
||||||
|
RT_WEAK void *rt_heap_end_get(void)
|
||||||
|
{
|
||||||
|
return rt_heap + RT_HEAP_SIZE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void rt_os_tick_callback(void)
|
||||||
|
{
|
||||||
|
rt_tick_increase();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will initial your board.
|
||||||
|
*/
|
||||||
|
void rt_hw_board_init(void)
|
||||||
|
{
|
||||||
|
#ifdef RT_USING_COMPONENTS_INIT
|
||||||
|
rt_components_board_init();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(RT_USING_USER_MAIN) && defined(RT_USING_HEAP)
|
||||||
|
rt_system_heap_init(rt_heap_begin_get(), rt_heap_end_get());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef RT_USING_CONSOLE
|
||||||
|
|
||||||
|
static int uart_init(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
INIT_BOARD_EXPORT(uart_init);
|
||||||
|
|
||||||
|
void rt_hw_console_output(const char *str)
|
||||||
|
{
|
||||||
|
extern void xputs(const char* str);
|
||||||
|
xputs(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
/* RT-Thread config file */
|
||||||
|
|
||||||
|
#ifndef __RTTHREAD_CFG_H__
|
||||||
|
#define __RTTHREAD_CFG_H__
|
||||||
|
|
||||||
|
#define RT_DEBUG_INIT 0
|
||||||
|
|
||||||
|
#define RT_THREAD_PRIORITY_MAX 8
|
||||||
|
#define RT_TICK_PER_SECOND 100
|
||||||
|
#define RT_ALIGN_SIZE 4
|
||||||
|
#define RT_NAME_MAX 8
|
||||||
|
|
||||||
|
#define RT_USING_COMPONENTS_INIT
|
||||||
|
|
||||||
|
#define RT_USING_USER_MAIN
|
||||||
|
#define RT_MAIN_THREAD_STACK_SIZE 1024
|
||||||
|
|
||||||
|
#define IDLE_THREAD_STACK_SIZE 1024
|
||||||
|
|
||||||
|
#define RT_USING_TIMER_SOFT 0
|
||||||
|
#if RT_USING_TIMER_SOFT == 0
|
||||||
|
#undef RT_USING_TIMER_SOFT
|
||||||
|
#endif
|
||||||
|
#define RT_TIMER_THREAD_PRIO 4
|
||||||
|
#define RT_TIMER_THREAD_STACK_SIZE 1024
|
||||||
|
|
||||||
|
#define RT_USING_SEMAPHORE
|
||||||
|
// #define RT_USING_MUTEX
|
||||||
|
// #define RT_USING_EVENT
|
||||||
|
#define RT_USING_MAILBOX
|
||||||
|
|
||||||
|
// #define RT_USING_HEAP
|
||||||
|
|
||||||
|
#if defined(RT_USING_HEAP)
|
||||||
|
#define RT_HEAP_SIZE (8*1024)
|
||||||
|
#define RT_USING_SMALL_MEM
|
||||||
|
#else
|
||||||
|
#define RT_HEAP_SIZE (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define RT_USING_CONSOLE
|
||||||
|
#define RT_CONSOLEBUF_SIZE 256
|
||||||
|
|
||||||
|
#define RT_USING_FINSH
|
||||||
|
|
||||||
|
#if defined(RT_USING_FINSH)
|
||||||
|
#define FINSH_USING_MSH
|
||||||
|
#define FINSH_USING_MSH_ONLY
|
||||||
|
|
||||||
|
#define __FINSH_THREAD_PRIORITY 5
|
||||||
|
#define FINSH_THREAD_PRIORITY (RT_THREAD_PRIORITY_MAX / 8 * __FINSH_THREAD_PRIORITY + 1)
|
||||||
|
|
||||||
|
#define FINSH_THREAD_STACK_SIZE (2*1024)
|
||||||
|
|
||||||
|
#define FINSH_HISTORY_LINES 1
|
||||||
|
|
||||||
|
#define FINSH_USING_SYMTAB
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,437 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2007-01-21 Bernard the first version
|
||||||
|
* 2010-05-04 Bernard add rt_device_init implementation
|
||||||
|
* 2012-10-20 Bernard add device check in register function,
|
||||||
|
* provided by Rob <rdent@iinet.net.au>
|
||||||
|
* 2012-12-25 Bernard return RT_EOK if the device interface not exist.
|
||||||
|
* 2013-07-09 Grissiom add ref_count support
|
||||||
|
* 2016-04-02 Bernard fix the open_flag initialization issue.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <rtthread.h>
|
||||||
|
#if defined(RT_USING_POSIX)
|
||||||
|
#include <rtdevice.h> /* for wqueue_init */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef RT_USING_DEVICE
|
||||||
|
|
||||||
|
#ifdef RT_USING_DEVICE_OPS
|
||||||
|
#define device_init (dev->ops->init)
|
||||||
|
#define device_open (dev->ops->open)
|
||||||
|
#define device_close (dev->ops->close)
|
||||||
|
#define device_read (dev->ops->read)
|
||||||
|
#define device_write (dev->ops->write)
|
||||||
|
#define device_control (dev->ops->control)
|
||||||
|
#else
|
||||||
|
#define device_init (dev->init)
|
||||||
|
#define device_open (dev->open)
|
||||||
|
#define device_close (dev->close)
|
||||||
|
#define device_read (dev->read)
|
||||||
|
#define device_write (dev->write)
|
||||||
|
#define device_control (dev->control)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function registers a device driver with specified name.
|
||||||
|
*
|
||||||
|
* @param dev the pointer of device driver structure
|
||||||
|
* @param name the device driver's name
|
||||||
|
* @param flags the capabilities flag of device
|
||||||
|
*
|
||||||
|
* @return the error code, RT_EOK on initialization successfully.
|
||||||
|
*/
|
||||||
|
rt_err_t rt_device_register(rt_device_t dev,
|
||||||
|
const char *name,
|
||||||
|
rt_uint16_t flags)
|
||||||
|
{
|
||||||
|
if (dev == RT_NULL)
|
||||||
|
return -RT_ERROR;
|
||||||
|
|
||||||
|
if (rt_device_find(name) != RT_NULL)
|
||||||
|
return -RT_ERROR;
|
||||||
|
|
||||||
|
rt_object_init(&(dev->parent), RT_Object_Class_Device, name);
|
||||||
|
dev->flag = flags;
|
||||||
|
dev->ref_count = 0;
|
||||||
|
dev->open_flag = 0;
|
||||||
|
|
||||||
|
#if defined(RT_USING_POSIX)
|
||||||
|
dev->fops = RT_NULL;
|
||||||
|
rt_wqueue_init(&(dev->wait_queue));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function removes a previously registered device driver
|
||||||
|
*
|
||||||
|
* @param dev the pointer of device driver structure
|
||||||
|
*
|
||||||
|
* @return the error code, RT_EOK on successfully.
|
||||||
|
*/
|
||||||
|
rt_err_t rt_device_unregister(rt_device_t dev)
|
||||||
|
{
|
||||||
|
RT_ASSERT(dev != RT_NULL);
|
||||||
|
RT_ASSERT(rt_object_get_type(&dev->parent) == RT_Object_Class_Device);
|
||||||
|
RT_ASSERT(rt_object_is_systemobject(&dev->parent));
|
||||||
|
|
||||||
|
rt_object_detach(&(dev->parent));
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function initializes all registered device driver
|
||||||
|
*
|
||||||
|
* @return the error code, RT_EOK on successfully.
|
||||||
|
*
|
||||||
|
* @deprecated since 1.2.x, this function is not needed because the initialization
|
||||||
|
* of a device is performed when application opens it.
|
||||||
|
*/
|
||||||
|
rt_err_t rt_device_init_all(void)
|
||||||
|
{
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function finds a device driver by specified name.
|
||||||
|
*
|
||||||
|
* @param name the device driver's name
|
||||||
|
*
|
||||||
|
* @return the registered device driver on successful, or RT_NULL on failure.
|
||||||
|
*/
|
||||||
|
rt_device_t rt_device_find(const char *name)
|
||||||
|
{
|
||||||
|
return (rt_device_t)rt_object_find(name, RT_Object_Class_Device);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef RT_USING_HEAP
|
||||||
|
/**
|
||||||
|
* This function creates a device object with user data size.
|
||||||
|
*
|
||||||
|
* @param type, the kind type of this device object.
|
||||||
|
* @param attach_size, the size of user data.
|
||||||
|
*
|
||||||
|
* @return the allocated device object, or RT_NULL when failed.
|
||||||
|
*/
|
||||||
|
rt_device_t rt_device_create(int type, int attach_size)
|
||||||
|
{
|
||||||
|
int size;
|
||||||
|
rt_device_t device;
|
||||||
|
|
||||||
|
size = RT_ALIGN(sizeof(struct rt_device), RT_ALIGN_SIZE);
|
||||||
|
attach_size = RT_ALIGN(attach_size, RT_ALIGN_SIZE);
|
||||||
|
/* use the total size */
|
||||||
|
size += attach_size;
|
||||||
|
|
||||||
|
device = (rt_device_t)rt_malloc(size);
|
||||||
|
if (device)
|
||||||
|
{
|
||||||
|
rt_memset(device, 0x0, sizeof(struct rt_device));
|
||||||
|
device->type = (enum rt_device_class_type)type;
|
||||||
|
}
|
||||||
|
|
||||||
|
return device;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function destroy the specific device object.
|
||||||
|
*
|
||||||
|
* @param dev, the specific device object.
|
||||||
|
*/
|
||||||
|
void rt_device_destroy(rt_device_t dev)
|
||||||
|
{
|
||||||
|
RT_ASSERT(dev != RT_NULL);
|
||||||
|
RT_ASSERT(rt_object_get_type(&dev->parent) == RT_Object_Class_Device);
|
||||||
|
RT_ASSERT(rt_object_is_systemobject(&dev->parent) == RT_FALSE);
|
||||||
|
|
||||||
|
rt_object_detach(&(dev->parent));
|
||||||
|
|
||||||
|
/* release this device object */
|
||||||
|
rt_free(dev);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will initialize the specified device
|
||||||
|
*
|
||||||
|
* @param dev the pointer of device driver structure
|
||||||
|
*
|
||||||
|
* @return the result
|
||||||
|
*/
|
||||||
|
rt_err_t rt_device_init(rt_device_t dev)
|
||||||
|
{
|
||||||
|
rt_err_t result = RT_EOK;
|
||||||
|
|
||||||
|
RT_ASSERT(dev != RT_NULL);
|
||||||
|
|
||||||
|
/* get device_init handler */
|
||||||
|
if (device_init != RT_NULL)
|
||||||
|
{
|
||||||
|
if (!(dev->flag & RT_DEVICE_FLAG_ACTIVATED))
|
||||||
|
{
|
||||||
|
result = device_init(dev);
|
||||||
|
if (result != RT_EOK)
|
||||||
|
{
|
||||||
|
rt_kprintf("To initialize device:%s failed. The error code is %d\n",
|
||||||
|
dev->parent.name, result);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dev->flag |= RT_DEVICE_FLAG_ACTIVATED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will open a device
|
||||||
|
*
|
||||||
|
* @param dev the pointer of device driver structure
|
||||||
|
* @param oflag the flags for device open
|
||||||
|
*
|
||||||
|
* @return the result
|
||||||
|
*/
|
||||||
|
rt_err_t rt_device_open(rt_device_t dev, rt_uint16_t oflag)
|
||||||
|
{
|
||||||
|
rt_err_t result = RT_EOK;
|
||||||
|
|
||||||
|
RT_ASSERT(dev != RT_NULL);
|
||||||
|
RT_ASSERT(rt_object_get_type(&dev->parent) == RT_Object_Class_Device);
|
||||||
|
|
||||||
|
/* if device is not initialized, initialize it. */
|
||||||
|
if (!(dev->flag & RT_DEVICE_FLAG_ACTIVATED))
|
||||||
|
{
|
||||||
|
if (device_init != RT_NULL)
|
||||||
|
{
|
||||||
|
result = device_init(dev);
|
||||||
|
if (result != RT_EOK)
|
||||||
|
{
|
||||||
|
rt_kprintf("To initialize device:%s failed. The error code is %d\n",
|
||||||
|
dev->parent.name, result);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dev->flag |= RT_DEVICE_FLAG_ACTIVATED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* device is a stand alone device and opened */
|
||||||
|
if ((dev->flag & RT_DEVICE_FLAG_STANDALONE) &&
|
||||||
|
(dev->open_flag & RT_DEVICE_OFLAG_OPEN))
|
||||||
|
{
|
||||||
|
return -RT_EBUSY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* call device_open interface */
|
||||||
|
if (device_open != RT_NULL)
|
||||||
|
{
|
||||||
|
result = device_open(dev, oflag);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* set open flag */
|
||||||
|
dev->open_flag = (oflag & RT_DEVICE_OFLAG_MASK);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set open flag */
|
||||||
|
if (result == RT_EOK || result == -RT_ENOSYS)
|
||||||
|
{
|
||||||
|
dev->open_flag |= RT_DEVICE_OFLAG_OPEN;
|
||||||
|
|
||||||
|
dev->ref_count++;
|
||||||
|
/* don't let bad things happen silently. If you are bitten by this assert,
|
||||||
|
* please set the ref_count to a bigger type. */
|
||||||
|
RT_ASSERT(dev->ref_count != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will close a device
|
||||||
|
*
|
||||||
|
* @param dev the pointer of device driver structure
|
||||||
|
*
|
||||||
|
* @return the result
|
||||||
|
*/
|
||||||
|
rt_err_t rt_device_close(rt_device_t dev)
|
||||||
|
{
|
||||||
|
rt_err_t result = RT_EOK;
|
||||||
|
|
||||||
|
RT_ASSERT(dev != RT_NULL);
|
||||||
|
RT_ASSERT(rt_object_get_type(&dev->parent) == RT_Object_Class_Device);
|
||||||
|
|
||||||
|
if (dev->ref_count == 0)
|
||||||
|
return -RT_ERROR;
|
||||||
|
|
||||||
|
dev->ref_count--;
|
||||||
|
|
||||||
|
if (dev->ref_count != 0)
|
||||||
|
return RT_EOK;
|
||||||
|
|
||||||
|
/* call device_close interface */
|
||||||
|
if (device_close != RT_NULL)
|
||||||
|
{
|
||||||
|
result = device_close(dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set open flag */
|
||||||
|
if (result == RT_EOK || result == -RT_ENOSYS)
|
||||||
|
dev->open_flag = RT_DEVICE_OFLAG_CLOSE;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will read some data from a device.
|
||||||
|
*
|
||||||
|
* @param dev the pointer of device driver structure
|
||||||
|
* @param pos the position of reading
|
||||||
|
* @param buffer the data buffer to save read data
|
||||||
|
* @param size the size of buffer
|
||||||
|
*
|
||||||
|
* @return the actually read size on successful, otherwise negative returned.
|
||||||
|
*
|
||||||
|
* @note since 0.4.0, the unit of size/pos is a block for block device.
|
||||||
|
*/
|
||||||
|
rt_size_t rt_device_read(rt_device_t dev,
|
||||||
|
rt_off_t pos,
|
||||||
|
void *buffer,
|
||||||
|
rt_size_t size)
|
||||||
|
{
|
||||||
|
RT_ASSERT(dev != RT_NULL);
|
||||||
|
RT_ASSERT(rt_object_get_type(&dev->parent) == RT_Object_Class_Device);
|
||||||
|
|
||||||
|
if (dev->ref_count == 0)
|
||||||
|
{
|
||||||
|
rt_set_errno(-RT_ERROR);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* call device_read interface */
|
||||||
|
if (device_read != RT_NULL)
|
||||||
|
{
|
||||||
|
return device_read(dev, pos, buffer, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set error code */
|
||||||
|
rt_set_errno(-RT_ENOSYS);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will write some data to a device.
|
||||||
|
*
|
||||||
|
* @param dev the pointer of device driver structure
|
||||||
|
* @param pos the position of written
|
||||||
|
* @param buffer the data buffer to be written to device
|
||||||
|
* @param size the size of buffer
|
||||||
|
*
|
||||||
|
* @return the actually written size on successful, otherwise negative returned.
|
||||||
|
*
|
||||||
|
* @note since 0.4.0, the unit of size/pos is a block for block device.
|
||||||
|
*/
|
||||||
|
rt_size_t rt_device_write(rt_device_t dev,
|
||||||
|
rt_off_t pos,
|
||||||
|
const void *buffer,
|
||||||
|
rt_size_t size)
|
||||||
|
{
|
||||||
|
RT_ASSERT(dev != RT_NULL);
|
||||||
|
RT_ASSERT(rt_object_get_type(&dev->parent) == RT_Object_Class_Device);
|
||||||
|
|
||||||
|
if (dev->ref_count == 0)
|
||||||
|
{
|
||||||
|
rt_set_errno(-RT_ERROR);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* call device_write interface */
|
||||||
|
if (device_write != RT_NULL)
|
||||||
|
{
|
||||||
|
return device_write(dev, pos, buffer, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set error code */
|
||||||
|
rt_set_errno(-RT_ENOSYS);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will perform a variety of control functions on devices.
|
||||||
|
*
|
||||||
|
* @param dev the pointer of device driver structure
|
||||||
|
* @param cmd the command sent to device
|
||||||
|
* @param arg the argument of command
|
||||||
|
*
|
||||||
|
* @return the result
|
||||||
|
*/
|
||||||
|
rt_err_t rt_device_control(rt_device_t dev, int cmd, void *arg)
|
||||||
|
{
|
||||||
|
RT_ASSERT(dev != RT_NULL);
|
||||||
|
RT_ASSERT(rt_object_get_type(&dev->parent) == RT_Object_Class_Device);
|
||||||
|
|
||||||
|
/* call device_write interface */
|
||||||
|
if (device_control != RT_NULL)
|
||||||
|
{
|
||||||
|
return device_control(dev, cmd, arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
return -RT_ENOSYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will set the reception indication callback function. This callback function
|
||||||
|
* is invoked when this device receives data.
|
||||||
|
*
|
||||||
|
* @param dev the pointer of device driver structure
|
||||||
|
* @param rx_ind the indication callback function
|
||||||
|
*
|
||||||
|
* @return RT_EOK
|
||||||
|
*/
|
||||||
|
rt_err_t
|
||||||
|
rt_device_set_rx_indicate(rt_device_t dev,
|
||||||
|
rt_err_t (*rx_ind)(rt_device_t dev, rt_size_t size))
|
||||||
|
{
|
||||||
|
RT_ASSERT(dev != RT_NULL);
|
||||||
|
RT_ASSERT(rt_object_get_type(&dev->parent) == RT_Object_Class_Device);
|
||||||
|
|
||||||
|
dev->rx_indicate = rx_ind;
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will set the indication callback function when device has
|
||||||
|
* written data to physical hardware.
|
||||||
|
*
|
||||||
|
* @param dev the pointer of device driver structure
|
||||||
|
* @param tx_done the indication callback function
|
||||||
|
*
|
||||||
|
* @return RT_EOK
|
||||||
|
*/
|
||||||
|
rt_err_t
|
||||||
|
rt_device_set_tx_complete(rt_device_t dev,
|
||||||
|
rt_err_t (*tx_done)(rt_device_t dev, void *buffer))
|
||||||
|
{
|
||||||
|
RT_ASSERT(dev != RT_NULL);
|
||||||
|
RT_ASSERT(rt_object_get_type(&dev->parent) == RT_Object_Class_Device);
|
||||||
|
|
||||||
|
dev->tx_complete = tx_done;
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,249 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2010-03-22 Bernard first version
|
||||||
|
*/
|
||||||
|
#ifndef __FINSH_H__
|
||||||
|
#define __FINSH_H__
|
||||||
|
|
||||||
|
#include <rtthread.h>
|
||||||
|
#include "finsh_api.h"
|
||||||
|
|
||||||
|
/* -- the beginning of option -- */
|
||||||
|
#define FINSH_NAME_MAX 16 /* max length of identifier */
|
||||||
|
#define FINSH_NODE_MAX 16 /* max number of node */
|
||||||
|
|
||||||
|
#define FINSH_HEAP_MAX 128 /* max length of heap */
|
||||||
|
#define FINSH_STRING_MAX 128 /* max length of string */
|
||||||
|
#define FINSH_VARIABLE_MAX 8 /* max number of variable */
|
||||||
|
|
||||||
|
#define FINSH_STACK_MAX 64 /* max stack size */
|
||||||
|
#define FINSH_TEXT_MAX 128 /* max text segment size */
|
||||||
|
|
||||||
|
#define HEAP_ALIGNMENT 4 /* heap alignment */
|
||||||
|
|
||||||
|
#define FINSH_GET16(x) (*(x)) | (*((x)+1) << 8)
|
||||||
|
#define FINSH_GET32(x) (rt_uint32_t)(*(x)) | ((rt_uint32_t)*((x)+1) << 8) | \
|
||||||
|
((rt_uint32_t)*((x)+2) << 16) | ((rt_uint32_t)*((x)+3) << 24)
|
||||||
|
|
||||||
|
#define FINSH_SET16(x, v) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
*(x) = (v) & 0x00ff; \
|
||||||
|
(*((x)+1)) = (v) >> 8; \
|
||||||
|
} while ( 0 )
|
||||||
|
|
||||||
|
#define FINSH_SET32(x, v) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
*(x) = (rt_uint32_t)(v) & 0x000000ff; \
|
||||||
|
(*((x)+1)) = ((rt_uint32_t)(v) >> 8) & 0x000000ff; \
|
||||||
|
(*((x)+2)) = ((rt_uint32_t)(v) >> 16) & 0x000000ff; \
|
||||||
|
(*((x)+3)) = ((rt_uint32_t)(v) >> 24); \
|
||||||
|
} while ( 0 )
|
||||||
|
|
||||||
|
/* -- the end of option -- */
|
||||||
|
|
||||||
|
/* std header file */
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define FINSH_VERSION_MAJOR 1
|
||||||
|
#define FINSH_VERSION_MINOR 0
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @addtogroup finsh
|
||||||
|
*/
|
||||||
|
/*@{*/
|
||||||
|
#define FINSH_ERROR_OK 0 /**< No error */
|
||||||
|
#define FINSH_ERROR_INVALID_TOKEN 1 /**< Invalid token */
|
||||||
|
#define FINSH_ERROR_EXPECT_TYPE 2 /**< Expect a type */
|
||||||
|
#define FINSH_ERROR_UNKNOWN_TYPE 3 /**< Unknown type */
|
||||||
|
#define FINSH_ERROR_VARIABLE_EXIST 4 /**< Variable exist */
|
||||||
|
#define FINSH_ERROR_EXPECT_OPERATOR 5 /**< Expect a operator */
|
||||||
|
#define FINSH_ERROR_MEMORY_FULL 6 /**< Memory full */
|
||||||
|
#define FINSH_ERROR_UNKNOWN_OP 7 /**< Unknown operator */
|
||||||
|
#define FINSH_ERROR_UNKNOWN_NODE 8 /**< Unknown node */
|
||||||
|
#define FINSH_ERROR_EXPECT_CHAR 9 /**< Expect a character */
|
||||||
|
#define FINSH_ERROR_UNEXPECT_END 10 /**< Unexpect end */
|
||||||
|
#define FINSH_ERROR_UNKNOWN_TOKEN 11 /**< Unknown token */
|
||||||
|
#define FINSH_ERROR_NO_FLOAT 12 /**< Float not supported */
|
||||||
|
#define FINSH_ERROR_UNKNOWN_SYMBOL 13 /**< Unknown symbol */
|
||||||
|
#define FINSH_ERROR_NULL_NODE 14 /**< Null node */
|
||||||
|
/*@}*/
|
||||||
|
|
||||||
|
/* system call item */
|
||||||
|
struct finsh_syscall_item
|
||||||
|
{
|
||||||
|
struct finsh_syscall_item* next; /* next item */
|
||||||
|
struct finsh_syscall syscall; /* syscall */
|
||||||
|
};
|
||||||
|
extern struct finsh_syscall_item *global_syscall_list;
|
||||||
|
|
||||||
|
/* system variable table */
|
||||||
|
struct finsh_sysvar
|
||||||
|
{
|
||||||
|
const char* name; /* the name of variable */
|
||||||
|
#if defined(FINSH_USING_DESCRIPTION) && defined(FINSH_USING_SYMTAB)
|
||||||
|
const char* desc; /* description of system variable */
|
||||||
|
#endif
|
||||||
|
uint8_t type; /* the type of variable */
|
||||||
|
void* var ; /* the address of variable */
|
||||||
|
};
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) || (defined(__GNUC__) && defined(__x86_64__))
|
||||||
|
struct finsh_syscall* finsh_syscall_next(struct finsh_syscall* call);
|
||||||
|
struct finsh_sysvar* finsh_sysvar_next(struct finsh_sysvar* call);
|
||||||
|
#define FINSH_NEXT_SYSCALL(index) index=finsh_syscall_next(index)
|
||||||
|
#define FINSH_NEXT_SYSVAR(index) index=finsh_sysvar_next(index)
|
||||||
|
#else
|
||||||
|
#define FINSH_NEXT_SYSCALL(index) index++
|
||||||
|
#define FINSH_NEXT_SYSVAR(index) index++
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* system variable item */
|
||||||
|
struct finsh_sysvar_item
|
||||||
|
{
|
||||||
|
struct finsh_sysvar_item *next; /* next item */
|
||||||
|
struct finsh_sysvar sysvar; /* system variable */
|
||||||
|
};
|
||||||
|
extern struct finsh_sysvar *_sysvar_table_begin, *_sysvar_table_end;
|
||||||
|
extern struct finsh_sysvar_item* global_sysvar_list;
|
||||||
|
|
||||||
|
/* find out system variable, which should be implemented in user program */
|
||||||
|
struct finsh_sysvar* finsh_sysvar_lookup(const char* name);
|
||||||
|
|
||||||
|
|
||||||
|
struct finsh_token
|
||||||
|
{
|
||||||
|
char eof;
|
||||||
|
char replay;
|
||||||
|
|
||||||
|
int position;
|
||||||
|
uint8_t current_token;
|
||||||
|
|
||||||
|
union {
|
||||||
|
char char_value;
|
||||||
|
int int_value;
|
||||||
|
long long_value;
|
||||||
|
} value;
|
||||||
|
uint8_t string[FINSH_STRING_MAX];
|
||||||
|
|
||||||
|
uint8_t* line;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define FINSH_IDTYPE_VAR 0x01
|
||||||
|
#define FINSH_IDTYPE_SYSVAR 0x02
|
||||||
|
#define FINSH_IDTYPE_SYSCALL 0x04
|
||||||
|
#define FINSH_IDTYPE_ADDRESS 0x08
|
||||||
|
struct finsh_node
|
||||||
|
{
|
||||||
|
uint8_t node_type; /* node node_type */
|
||||||
|
uint8_t data_type; /* node data node_type */
|
||||||
|
uint8_t idtype; /* id node information */
|
||||||
|
|
||||||
|
union { /* value node */
|
||||||
|
char char_value;
|
||||||
|
short short_value;
|
||||||
|
int int_value;
|
||||||
|
long long_value;
|
||||||
|
void* ptr;
|
||||||
|
} value;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
/* point to variable identifier or function identifier */
|
||||||
|
struct finsh_var *var;
|
||||||
|
struct finsh_sysvar *sysvar;
|
||||||
|
struct finsh_syscall*syscall;
|
||||||
|
}id;
|
||||||
|
|
||||||
|
/* sibling and child node */
|
||||||
|
struct finsh_node *sibling, *child;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct finsh_parser
|
||||||
|
{
|
||||||
|
uint8_t* parser_string;
|
||||||
|
|
||||||
|
struct finsh_token token;
|
||||||
|
struct finsh_node* root;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup finsh
|
||||||
|
*
|
||||||
|
* The basic data type in finsh shell
|
||||||
|
*/
|
||||||
|
enum finsh_type {
|
||||||
|
finsh_type_unknown = 0, /**< unknown data type */
|
||||||
|
finsh_type_void, /**< void */
|
||||||
|
finsh_type_voidp, /**< void pointer */
|
||||||
|
finsh_type_char, /**< char */
|
||||||
|
finsh_type_uchar, /**< unsigned char */
|
||||||
|
finsh_type_charp, /**< char pointer */
|
||||||
|
finsh_type_short, /**< short */
|
||||||
|
finsh_type_ushort, /**< unsigned short */
|
||||||
|
finsh_type_shortp, /**< short pointer */
|
||||||
|
finsh_type_int, /**< int */
|
||||||
|
finsh_type_uint, /**< unsigned int */
|
||||||
|
finsh_type_intp, /**< int pointer */
|
||||||
|
finsh_type_long, /**< long */
|
||||||
|
finsh_type_ulong, /**< unsigned long */
|
||||||
|
finsh_type_longp /**< long pointer */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* init finsh environment */
|
||||||
|
int finsh_init(struct finsh_parser* parser);
|
||||||
|
/* flush finsh node, text segment */
|
||||||
|
int finsh_flush(struct finsh_parser* parser);
|
||||||
|
/* reset all of finsh */
|
||||||
|
int finsh_reset(struct finsh_parser* parser);
|
||||||
|
#ifdef RT_USING_DEVICE
|
||||||
|
void finsh_set_device(const char* device_name);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* run finsh parser to generate abstract synatx tree */
|
||||||
|
void finsh_parser_run (struct finsh_parser* parser, const unsigned char* string);
|
||||||
|
/* run compiler to compile abstract syntax tree */
|
||||||
|
int finsh_compiler_run(struct finsh_node* node);
|
||||||
|
/* run finsh virtual machine */
|
||||||
|
void finsh_vm_run(void);
|
||||||
|
|
||||||
|
/* get variable value */
|
||||||
|
struct finsh_var* finsh_var_lookup(const char* name);
|
||||||
|
/* get bottom value of stack */
|
||||||
|
long finsh_stack_bottom(void);
|
||||||
|
|
||||||
|
/* get error number of finsh */
|
||||||
|
uint8_t finsh_errno(void);
|
||||||
|
/* get error string */
|
||||||
|
const char* finsh_error_string(uint8_t type);
|
||||||
|
|
||||||
|
#ifdef RT_USING_HEAP
|
||||||
|
/**
|
||||||
|
* @ingroup finsh
|
||||||
|
*
|
||||||
|
* This function appends a system call to finsh runtime environment
|
||||||
|
* @param name the name of system call
|
||||||
|
* @param func the function pointer of system call
|
||||||
|
*/
|
||||||
|
void finsh_syscall_append(const char* name, syscall_func func);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup finsh
|
||||||
|
*
|
||||||
|
* This function appends a system variable to finsh runtime environment
|
||||||
|
* @param name the name of system variable
|
||||||
|
* @param type the data type of system variable
|
||||||
|
* @param addr the address of system variable
|
||||||
|
*/
|
||||||
|
void finsh_sysvar_append(const char* name, uint8_t type, void* addr);
|
||||||
|
#endif
|
||||||
|
#endif
|
|
@ -0,0 +1,220 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2010-03-22 Bernard first version
|
||||||
|
*/
|
||||||
|
#ifndef FINSH_API_H__
|
||||||
|
#define FINSH_API_H__
|
||||||
|
|
||||||
|
#include "finsh_config.h"
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#pragma section("FSymTab$f",read)
|
||||||
|
#pragma section("VSymTab",read)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef long (*syscall_func)(void);
|
||||||
|
|
||||||
|
/* system call table */
|
||||||
|
struct finsh_syscall
|
||||||
|
{
|
||||||
|
const char* name; /* the name of system call */
|
||||||
|
#if defined(FINSH_USING_DESCRIPTION) && defined(FINSH_USING_SYMTAB)
|
||||||
|
const char* desc; /* description of system call */
|
||||||
|
#endif
|
||||||
|
syscall_func func; /* the function address of system call */
|
||||||
|
};
|
||||||
|
extern struct finsh_syscall *_syscall_table_begin, *_syscall_table_end;
|
||||||
|
|
||||||
|
/* find out system call, which should be implemented in user program */
|
||||||
|
struct finsh_syscall* finsh_syscall_lookup(const char* name);
|
||||||
|
|
||||||
|
#ifdef FINSH_USING_SYMTAB
|
||||||
|
|
||||||
|
#ifdef __TI_COMPILER_VERSION__
|
||||||
|
#define __TI_FINSH_EXPORT_FUNCTION(f) PRAGMA(DATA_SECTION(f,"FSymTab"))
|
||||||
|
#define __TI_FINSH_EXPORT_VAR(v) PRAGMA(DATA_SECTION(v,"VSymTab"))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef FINSH_USING_DESCRIPTION
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#define FINSH_FUNCTION_EXPORT_CMD(name, cmd, desc) \
|
||||||
|
const char __fsym_##cmd##_name[] = #cmd; \
|
||||||
|
const char __fsym_##cmd##_desc[] = #desc; \
|
||||||
|
__declspec(allocate("FSymTab$f")) \
|
||||||
|
const struct finsh_syscall __fsym_##cmd = \
|
||||||
|
{ \
|
||||||
|
__fsym_##cmd##_name, \
|
||||||
|
__fsym_##cmd##_desc, \
|
||||||
|
(syscall_func)&name \
|
||||||
|
};
|
||||||
|
#pragma comment(linker, "/merge:FSymTab=mytext")
|
||||||
|
|
||||||
|
#define FINSH_VAR_EXPORT(name, type, desc) \
|
||||||
|
const char __vsym_##name##_name[] = #name; \
|
||||||
|
const char __vsym_##name##_desc[] = #desc; \
|
||||||
|
__declspec(allocate("VSymTab")) \
|
||||||
|
const struct finsh_sysvar __vsym_##name = \
|
||||||
|
{ \
|
||||||
|
__vsym_##name##_name, \
|
||||||
|
__vsym_##name##_desc, \
|
||||||
|
type, \
|
||||||
|
(void*)&name \
|
||||||
|
};
|
||||||
|
|
||||||
|
#elif defined(__TI_COMPILER_VERSION__)
|
||||||
|
#define FINSH_FUNCTION_EXPORT_CMD(name, cmd, desc) \
|
||||||
|
__TI_FINSH_EXPORT_FUNCTION(__fsym_##cmd); \
|
||||||
|
const char __fsym_##cmd##_name[] = #cmd; \
|
||||||
|
const char __fsym_##cmd##_desc[] = #desc; \
|
||||||
|
const struct finsh_syscall __fsym_##cmd = \
|
||||||
|
{ \
|
||||||
|
__fsym_##cmd##_name, \
|
||||||
|
__fsym_##cmd##_desc, \
|
||||||
|
(syscall_func)&name \
|
||||||
|
};
|
||||||
|
|
||||||
|
#define FINSH_VAR_EXPORT(name, type, desc) \
|
||||||
|
__TI_FINSH_EXPORT_VAR(__vsym_##name); \
|
||||||
|
const char __vsym_##name##_name[] = #name; \
|
||||||
|
const char __vsym_##name##_desc[] = #desc; \
|
||||||
|
const struct finsh_sysvar __vsym_##name = \
|
||||||
|
{ \
|
||||||
|
__vsym_##name##_name, \
|
||||||
|
__vsym_##name##_desc, \
|
||||||
|
type, \
|
||||||
|
(void*)&name \
|
||||||
|
};
|
||||||
|
|
||||||
|
#else
|
||||||
|
#define FINSH_FUNCTION_EXPORT_CMD(name, cmd, desc) \
|
||||||
|
const char __fsym_##cmd##_name[] SECTION(".rodata.name") = #cmd; \
|
||||||
|
const char __fsym_##cmd##_desc[] SECTION(".rodata.name") = #desc; \
|
||||||
|
RT_USED const struct finsh_syscall __fsym_##cmd SECTION("FSymTab")= \
|
||||||
|
{ \
|
||||||
|
__fsym_##cmd##_name, \
|
||||||
|
__fsym_##cmd##_desc, \
|
||||||
|
(syscall_func)&name \
|
||||||
|
};
|
||||||
|
|
||||||
|
#define FINSH_VAR_EXPORT(name, type, desc) \
|
||||||
|
const char __vsym_##name##_name[] SECTION(".rodata.name") = #name; \
|
||||||
|
const char __vsym_##name##_desc[] SECTION(".rodata.name") = #desc; \
|
||||||
|
RT_USED const struct finsh_sysvar __vsym_##name SECTION("VSymTab")= \
|
||||||
|
{ \
|
||||||
|
__vsym_##name##_name, \
|
||||||
|
__vsym_##name##_desc, \
|
||||||
|
type, \
|
||||||
|
(void*)&name \
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#define FINSH_FUNCTION_EXPORT_CMD(name, cmd, desc) \
|
||||||
|
const char __fsym_##cmd##_name[] = #cmd; \
|
||||||
|
__declspec(allocate("FSymTab$f")) \
|
||||||
|
const struct finsh_syscall __fsym_##cmd = \
|
||||||
|
{ \
|
||||||
|
__fsym_##cmd##_name, \
|
||||||
|
(syscall_func)&name \
|
||||||
|
};
|
||||||
|
#pragma comment(linker, "/merge:FSymTab=mytext")
|
||||||
|
|
||||||
|
#define FINSH_VAR_EXPORT(name, type, desc) \
|
||||||
|
const char __vsym_##name##_name[] = #name; \
|
||||||
|
__declspec(allocate("VSymTab")) const struct finsh_sysvar __vsym_##name = \
|
||||||
|
{ \
|
||||||
|
__vsym_##name##_name, \
|
||||||
|
type, \
|
||||||
|
(void*)&name \
|
||||||
|
};
|
||||||
|
|
||||||
|
#elif defined(__TI_COMPILER_VERSION__)
|
||||||
|
#define FINSH_FUNCTION_EXPORT_CMD(name, cmd, desc) \
|
||||||
|
__TI_FINSH_EXPORT_FUNCTION(__fsym_##cmd); \
|
||||||
|
const char __fsym_##cmd##_name[] = #cmd; \
|
||||||
|
const struct finsh_syscall __fsym_##cmd = \
|
||||||
|
{ \
|
||||||
|
__fsym_##cmd##_name, \
|
||||||
|
(syscall_func)&name \
|
||||||
|
};
|
||||||
|
|
||||||
|
#define FINSH_VAR_EXPORT(name, type, desc) \
|
||||||
|
__TI_FINSH_EXPORT_VAR(__vsym_##name); \
|
||||||
|
const char __vsym_##name##_name[] = #name; \
|
||||||
|
const struct finsh_sysvar __vsym_##name = \
|
||||||
|
{ \
|
||||||
|
__vsym_##name##_name, \
|
||||||
|
type, \
|
||||||
|
(void*)&name \
|
||||||
|
};
|
||||||
|
|
||||||
|
#else
|
||||||
|
#define FINSH_FUNCTION_EXPORT_CMD(name, cmd, desc) \
|
||||||
|
const char __fsym_##cmd##_name[] = #cmd; \
|
||||||
|
RT_USED const struct finsh_syscall __fsym_##cmd SECTION("FSymTab")= \
|
||||||
|
{ \
|
||||||
|
__fsym_##cmd##_name, \
|
||||||
|
(syscall_func)&name \
|
||||||
|
};
|
||||||
|
|
||||||
|
#define FINSH_VAR_EXPORT(name, type, desc) \
|
||||||
|
const char __vsym_##name##_name[] = #name; \
|
||||||
|
RT_USED const struct finsh_sysvar __vsym_##name SECTION("VSymTab")= \
|
||||||
|
{ \
|
||||||
|
__vsym_##name##_name, \
|
||||||
|
type, \
|
||||||
|
(void*)&name \
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#endif /* end of FINSH_USING_DESCRIPTION */
|
||||||
|
#endif /* end of FINSH_USING_SYMTAB */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup finsh
|
||||||
|
*
|
||||||
|
* This macro exports a system function to finsh shell.
|
||||||
|
*
|
||||||
|
* @param name the name of function.
|
||||||
|
* @param desc the description of function, which will show in help.
|
||||||
|
*/
|
||||||
|
#define FINSH_FUNCTION_EXPORT(name, desc) \
|
||||||
|
FINSH_FUNCTION_EXPORT_CMD(name, name, desc)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup finsh
|
||||||
|
*
|
||||||
|
* This macro exports a system function with an alias name to finsh shell.
|
||||||
|
*
|
||||||
|
* @param name the name of function.
|
||||||
|
* @param alias the alias name of function.
|
||||||
|
* @param desc the description of function, which will show in help.
|
||||||
|
*/
|
||||||
|
#define FINSH_FUNCTION_EXPORT_ALIAS(name, alias, desc) \
|
||||||
|
FINSH_FUNCTION_EXPORT_CMD(name, alias, desc)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup finsh
|
||||||
|
*
|
||||||
|
* This macro exports a command to module shell.
|
||||||
|
*
|
||||||
|
* @param command the name of command.
|
||||||
|
* @param desc the description of command, which will show in help.
|
||||||
|
*/
|
||||||
|
#ifdef FINSH_USING_MSH
|
||||||
|
#define MSH_CMD_EXPORT(command, desc) \
|
||||||
|
FINSH_FUNCTION_EXPORT_CMD(command, __cmd_##command, desc)
|
||||||
|
#define MSH_CMD_EXPORT_ALIAS(command, alias, desc) \
|
||||||
|
FINSH_FUNCTION_EXPORT_ALIAS(command, __cmd_##alias, desc)
|
||||||
|
#else
|
||||||
|
#define MSH_CMD_EXPORT(command, desc)
|
||||||
|
#define MSH_CMD_EXPORT_ALIAS(command, alias, desc)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,7 @@
|
||||||
|
/* FinSH config file */
|
||||||
|
|
||||||
|
#ifndef __MSH_CFG_H__
|
||||||
|
#define __MSH_CFG_H__
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <rthw.h>
|
||||||
|
#include <rtconfig.h>
|
||||||
|
|
||||||
|
#ifndef RT_USING_FINSH
|
||||||
|
#error Please uncomment the line <#include "finsh_config.h"> in the rtconfig.h
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef RT_USING_FINSH
|
||||||
|
|
||||||
|
#include "uart.h"
|
||||||
|
|
||||||
|
RT_WEAK char rt_hw_console_getchar(void)
|
||||||
|
{
|
||||||
|
rt_uint8_t ch;
|
||||||
|
|
||||||
|
extern uint8_t uart_read_wait(UART_Type *uart);
|
||||||
|
ch = uart_read_wait(UART1);
|
||||||
|
|
||||||
|
return ch;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* RT_USING_FINSH */
|
||||||
|
|
|
@ -0,0 +1,648 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2013-03-30 Bernard the first verion for finsh
|
||||||
|
* 2014-01-03 Bernard msh can execute module.
|
||||||
|
* 2017-07-19 Aubr.Cool limit argc to RT_FINSH_ARG_MAX
|
||||||
|
*/
|
||||||
|
#include <rtthread.h>
|
||||||
|
#include <finsh_config.h>
|
||||||
|
|
||||||
|
#ifdef FINSH_USING_MSH
|
||||||
|
|
||||||
|
#include "msh.h"
|
||||||
|
#include <finsh.h>
|
||||||
|
#include <shell.h>
|
||||||
|
|
||||||
|
#ifdef RT_USING_DFS
|
||||||
|
#include <dfs_posix.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef RT_USING_MODULE
|
||||||
|
#include <dlmodule.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef FINSH_ARG_MAX
|
||||||
|
#define FINSH_ARG_MAX 8
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef int (*cmd_function_t)(int argc, char **argv);
|
||||||
|
|
||||||
|
#ifdef FINSH_USING_MSH
|
||||||
|
#ifdef FINSH_USING_MSH_ONLY
|
||||||
|
rt_bool_t msh_is_used(void)
|
||||||
|
{
|
||||||
|
return RT_TRUE;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#ifdef FINSH_USING_MSH_DEFAULT
|
||||||
|
static rt_bool_t __msh_state = RT_TRUE;
|
||||||
|
#else
|
||||||
|
static rt_bool_t __msh_state = RT_FALSE;
|
||||||
|
#endif
|
||||||
|
rt_bool_t msh_is_used(void)
|
||||||
|
{
|
||||||
|
return __msh_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int msh_exit(int argc, char **argv)
|
||||||
|
{
|
||||||
|
/* return to finsh shell mode */
|
||||||
|
__msh_state = RT_FALSE;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
FINSH_FUNCTION_EXPORT_ALIAS(msh_exit, __cmd_exit, return to RT-Thread shell mode.);
|
||||||
|
|
||||||
|
static int msh_enter(void)
|
||||||
|
{
|
||||||
|
/* enter module shell mode */
|
||||||
|
__msh_state = RT_TRUE;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
FINSH_FUNCTION_EXPORT_ALIAS(msh_enter, msh, use module shell);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int msh_help(int argc, char **argv)
|
||||||
|
{
|
||||||
|
rt_kprintf("RT-Thread shell commands:\n");
|
||||||
|
{
|
||||||
|
struct finsh_syscall *index;
|
||||||
|
|
||||||
|
for (index = _syscall_table_begin;
|
||||||
|
index < _syscall_table_end;
|
||||||
|
FINSH_NEXT_SYSCALL(index))
|
||||||
|
{
|
||||||
|
if (strncmp(index->name, "__cmd_", 6) != 0) continue;
|
||||||
|
#if defined(FINSH_USING_DESCRIPTION) && defined(FINSH_USING_SYMTAB)
|
||||||
|
rt_kprintf("%-16s - %s\n", &index->name[6], index->desc);
|
||||||
|
#else
|
||||||
|
rt_kprintf("%s ", &index->name[6]);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rt_kprintf("\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
FINSH_FUNCTION_EXPORT_ALIAS(msh_help, __cmd_help, RT-Thread shell help.);
|
||||||
|
|
||||||
|
int cmd_ps(int argc, char **argv)
|
||||||
|
{
|
||||||
|
extern long list_thread(void);
|
||||||
|
extern int list_module(void);
|
||||||
|
|
||||||
|
#ifdef RT_USING_MODULE
|
||||||
|
if ((argc == 2) && (strcmp(argv[1], "-m") == 0))
|
||||||
|
list_module();
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
list_thread();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
FINSH_FUNCTION_EXPORT_ALIAS(cmd_ps, __cmd_ps, List threads in the system.);
|
||||||
|
|
||||||
|
#ifdef RT_USING_HEAP
|
||||||
|
int cmd_free(int argc, char **argv)
|
||||||
|
{
|
||||||
|
extern void list_mem(void);
|
||||||
|
extern void list_memheap(void);
|
||||||
|
|
||||||
|
#ifdef RT_USING_MEMHEAP_AS_HEAP
|
||||||
|
list_memheap();
|
||||||
|
#else
|
||||||
|
list_mem();
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
FINSH_FUNCTION_EXPORT_ALIAS(cmd_free, __cmd_free, Show the memory usage in the system.);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int msh_split(char *cmd, rt_size_t length, char *argv[FINSH_ARG_MAX])
|
||||||
|
{
|
||||||
|
char *ptr;
|
||||||
|
rt_size_t position;
|
||||||
|
rt_size_t argc;
|
||||||
|
rt_size_t i;
|
||||||
|
|
||||||
|
ptr = cmd;
|
||||||
|
position = 0; argc = 0;
|
||||||
|
|
||||||
|
while (position < length)
|
||||||
|
{
|
||||||
|
/* strip bank and tab */
|
||||||
|
while ((*ptr == ' ' || *ptr == '\t') && position < length)
|
||||||
|
{
|
||||||
|
*ptr = '\0';
|
||||||
|
ptr ++; position ++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(argc >= FINSH_ARG_MAX)
|
||||||
|
{
|
||||||
|
rt_kprintf("Too many args ! We only Use:\n");
|
||||||
|
for(i = 0; i < argc; i++)
|
||||||
|
{
|
||||||
|
rt_kprintf("%s ", argv[i]);
|
||||||
|
}
|
||||||
|
rt_kprintf("\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (position >= length) break;
|
||||||
|
|
||||||
|
/* handle string */
|
||||||
|
if (*ptr == '"')
|
||||||
|
{
|
||||||
|
ptr ++; position ++;
|
||||||
|
argv[argc] = ptr; argc ++;
|
||||||
|
|
||||||
|
/* skip this string */
|
||||||
|
while (*ptr != '"' && position < length)
|
||||||
|
{
|
||||||
|
if (*ptr == '\\')
|
||||||
|
{
|
||||||
|
if (*(ptr + 1) == '"')
|
||||||
|
{
|
||||||
|
ptr ++; position ++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ptr ++; position ++;
|
||||||
|
}
|
||||||
|
if (position >= length) break;
|
||||||
|
|
||||||
|
/* skip '"' */
|
||||||
|
*ptr = '\0'; ptr ++; position ++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
argv[argc] = ptr;
|
||||||
|
argc ++;
|
||||||
|
while ((*ptr != ' ' && *ptr != '\t') && position < length)
|
||||||
|
{
|
||||||
|
ptr ++; position ++;
|
||||||
|
}
|
||||||
|
if (position >= length) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return argc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cmd_function_t msh_get_cmd(char *cmd, int size)
|
||||||
|
{
|
||||||
|
struct finsh_syscall *index;
|
||||||
|
cmd_function_t cmd_func = RT_NULL;
|
||||||
|
|
||||||
|
for (index = _syscall_table_begin;
|
||||||
|
index < _syscall_table_end;
|
||||||
|
FINSH_NEXT_SYSCALL(index))
|
||||||
|
{
|
||||||
|
if (strncmp(index->name, "__cmd_", 6) != 0) continue;
|
||||||
|
|
||||||
|
if (strncmp(&index->name[6], cmd, size) == 0 &&
|
||||||
|
index->name[6 + size] == '\0')
|
||||||
|
{
|
||||||
|
cmd_func = (cmd_function_t)index->func;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return cmd_func;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(RT_USING_MODULE) && defined(RT_USING_DFS)
|
||||||
|
/* Return 0 on module executed. Other value indicate error.
|
||||||
|
*/
|
||||||
|
int msh_exec_module(const char *cmd_line, int size)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
int fd = -1;
|
||||||
|
char *pg_name;
|
||||||
|
int length, cmd_length = 0;
|
||||||
|
|
||||||
|
if (size == 0)
|
||||||
|
return -RT_ERROR;
|
||||||
|
/* get the length of command0 */
|
||||||
|
while ((cmd_line[cmd_length] != ' ' && cmd_line[cmd_length] != '\t') && cmd_length < size)
|
||||||
|
cmd_length ++;
|
||||||
|
|
||||||
|
/* get name length */
|
||||||
|
length = cmd_length + 32;
|
||||||
|
|
||||||
|
/* allocate program name memory */
|
||||||
|
pg_name = (char *) rt_malloc(length);
|
||||||
|
if (pg_name == RT_NULL)
|
||||||
|
return -RT_ENOMEM;
|
||||||
|
|
||||||
|
/* copy command0 */
|
||||||
|
memcpy(pg_name, cmd_line, cmd_length);
|
||||||
|
pg_name[cmd_length] = '\0';
|
||||||
|
|
||||||
|
if (strstr(pg_name, ".mo") != RT_NULL || strstr(pg_name, ".MO") != RT_NULL)
|
||||||
|
{
|
||||||
|
/* try to open program */
|
||||||
|
fd = open(pg_name, O_RDONLY, 0);
|
||||||
|
|
||||||
|
/* search in /bin path */
|
||||||
|
if (fd < 0)
|
||||||
|
{
|
||||||
|
rt_snprintf(pg_name, length - 1, "/bin/%.*s", cmd_length, cmd_line);
|
||||||
|
fd = open(pg_name, O_RDONLY, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* add .mo and open program */
|
||||||
|
|
||||||
|
/* try to open program */
|
||||||
|
strcat(pg_name, ".mo");
|
||||||
|
fd = open(pg_name, O_RDONLY, 0);
|
||||||
|
|
||||||
|
/* search in /bin path */
|
||||||
|
if (fd < 0)
|
||||||
|
{
|
||||||
|
rt_snprintf(pg_name, length - 1, "/bin/%.*s.mo", cmd_length, cmd_line);
|
||||||
|
fd = open(pg_name, O_RDONLY, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fd >= 0)
|
||||||
|
{
|
||||||
|
/* found program */
|
||||||
|
close(fd);
|
||||||
|
dlmodule_exec(pg_name, cmd_line, size);
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
rt_free(pg_name);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int system(const char *command)
|
||||||
|
{
|
||||||
|
int ret = -RT_ENOMEM;
|
||||||
|
char *cmd = rt_strdup(command);
|
||||||
|
|
||||||
|
if (cmd)
|
||||||
|
{
|
||||||
|
ret = msh_exec(cmd, rt_strlen(cmd));
|
||||||
|
rt_free(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int _msh_exec_cmd(char *cmd, rt_size_t length, int *retp)
|
||||||
|
{
|
||||||
|
int argc;
|
||||||
|
rt_size_t cmd0_size = 0;
|
||||||
|
cmd_function_t cmd_func;
|
||||||
|
char *argv[FINSH_ARG_MAX];
|
||||||
|
|
||||||
|
RT_ASSERT(cmd);
|
||||||
|
RT_ASSERT(retp);
|
||||||
|
|
||||||
|
/* find the size of first command */
|
||||||
|
while ((cmd[cmd0_size] != ' ' && cmd[cmd0_size] != '\t') && cmd0_size < length)
|
||||||
|
cmd0_size ++;
|
||||||
|
if (cmd0_size == 0)
|
||||||
|
return -RT_ERROR;
|
||||||
|
|
||||||
|
cmd_func = msh_get_cmd(cmd, cmd0_size);
|
||||||
|
if (cmd_func == RT_NULL)
|
||||||
|
return -RT_ERROR;
|
||||||
|
|
||||||
|
/* split arguments */
|
||||||
|
memset(argv, 0x00, sizeof(argv));
|
||||||
|
argc = msh_split(cmd, length, argv);
|
||||||
|
if (argc == 0)
|
||||||
|
return -RT_ERROR;
|
||||||
|
|
||||||
|
/* exec this command */
|
||||||
|
*retp = cmd_func(argc, argv);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(RT_USING_LWP) && defined(RT_USING_DFS)
|
||||||
|
static int _msh_exec_lwp(char *cmd, rt_size_t length)
|
||||||
|
{
|
||||||
|
int argc;
|
||||||
|
int cmd0_size = 0;
|
||||||
|
char *argv[FINSH_ARG_MAX];
|
||||||
|
int fd = -1;
|
||||||
|
char *pg_name;
|
||||||
|
|
||||||
|
extern int exec(char*, int, char**);
|
||||||
|
|
||||||
|
/* find the size of first command */
|
||||||
|
while ((cmd[cmd0_size] != ' ' && cmd[cmd0_size] != '\t') && cmd0_size < length)
|
||||||
|
cmd0_size ++;
|
||||||
|
if (cmd0_size == 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* split arguments */
|
||||||
|
rt_memset(argv, 0x00, sizeof(argv));
|
||||||
|
argc = msh_split(cmd, length, argv);
|
||||||
|
if (argc == 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
pg_name = argv[0];
|
||||||
|
/* try to open program */
|
||||||
|
fd = open(pg_name, O_RDONLY, 0);
|
||||||
|
|
||||||
|
if (fd < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* found program */
|
||||||
|
close(fd);
|
||||||
|
exec(pg_name, argc, argv);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int msh_exec(char *cmd, rt_size_t length)
|
||||||
|
{
|
||||||
|
int cmd_ret;
|
||||||
|
|
||||||
|
/* strim the beginning of command */
|
||||||
|
while ((length > 0) && (*cmd == ' ' || *cmd == '\t'))
|
||||||
|
{
|
||||||
|
cmd++;
|
||||||
|
length--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (length == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Exec sequence:
|
||||||
|
* 1. built-in command
|
||||||
|
* 2. module(if enabled)
|
||||||
|
*/
|
||||||
|
if (_msh_exec_cmd(cmd, length, &cmd_ret) == 0)
|
||||||
|
{
|
||||||
|
return cmd_ret;
|
||||||
|
}
|
||||||
|
#ifdef RT_USING_DFS
|
||||||
|
#ifdef DFS_USING_WORKDIR
|
||||||
|
if (msh_exec_script(cmd, length) == 0)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef RT_USING_MODULE
|
||||||
|
if (msh_exec_module(cmd, length) == 0)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef RT_USING_LWP
|
||||||
|
if (_msh_exec_lwp(cmd, length) == 0)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* truncate the cmd at the first space. */
|
||||||
|
{
|
||||||
|
char *tcmd;
|
||||||
|
tcmd = cmd;
|
||||||
|
while (*tcmd != ' ' && *tcmd != '\0')
|
||||||
|
{
|
||||||
|
tcmd++;
|
||||||
|
}
|
||||||
|
*tcmd = '\0';
|
||||||
|
}
|
||||||
|
rt_kprintf("%s: command not found.\n", cmd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int str_common(const char *str1, const char *str2)
|
||||||
|
{
|
||||||
|
const char *str = str1;
|
||||||
|
|
||||||
|
while ((*str != 0) && (*str2 != 0) && (*str == *str2))
|
||||||
|
{
|
||||||
|
str ++;
|
||||||
|
str2 ++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (str - str1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef RT_USING_DFS
|
||||||
|
void msh_auto_complete_path(char *path)
|
||||||
|
{
|
||||||
|
DIR *dir = RT_NULL;
|
||||||
|
struct dirent *dirent = RT_NULL;
|
||||||
|
char *full_path, *ptr, *index;
|
||||||
|
|
||||||
|
if (!path)
|
||||||
|
return;
|
||||||
|
|
||||||
|
full_path = (char *)rt_malloc(256);
|
||||||
|
if (full_path == RT_NULL) return; /* out of memory */
|
||||||
|
|
||||||
|
if (*path != '/')
|
||||||
|
{
|
||||||
|
getcwd(full_path, 256);
|
||||||
|
if (full_path[rt_strlen(full_path) - 1] != '/')
|
||||||
|
strcat(full_path, "/");
|
||||||
|
}
|
||||||
|
else *full_path = '\0';
|
||||||
|
|
||||||
|
index = RT_NULL;
|
||||||
|
ptr = path;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
if (*ptr == '/') index = ptr + 1;
|
||||||
|
if (!*ptr) break;
|
||||||
|
|
||||||
|
ptr ++;
|
||||||
|
}
|
||||||
|
if (index == RT_NULL) index = path;
|
||||||
|
|
||||||
|
if (index != RT_NULL)
|
||||||
|
{
|
||||||
|
char *dest = index;
|
||||||
|
|
||||||
|
/* fill the parent path */
|
||||||
|
ptr = full_path;
|
||||||
|
while (*ptr) ptr ++;
|
||||||
|
|
||||||
|
for (index = path; index != dest;)
|
||||||
|
*ptr++ = *index++;
|
||||||
|
*ptr = '\0';
|
||||||
|
|
||||||
|
dir = opendir(full_path);
|
||||||
|
if (dir == RT_NULL) /* open directory failed! */
|
||||||
|
{
|
||||||
|
rt_free(full_path);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* restore the index position */
|
||||||
|
index = dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* auto complete the file or directory name */
|
||||||
|
if (*index == '\0') /* display all of files and directories */
|
||||||
|
{
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
dirent = readdir(dir);
|
||||||
|
if (dirent == RT_NULL) break;
|
||||||
|
|
||||||
|
rt_kprintf("%s\n", dirent->d_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rt_size_t length, min_length;
|
||||||
|
|
||||||
|
min_length = 0;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
dirent = readdir(dir);
|
||||||
|
if (dirent == RT_NULL) break;
|
||||||
|
|
||||||
|
/* matched the prefix string */
|
||||||
|
if (strncmp(index, dirent->d_name, rt_strlen(index)) == 0)
|
||||||
|
{
|
||||||
|
if (min_length == 0)
|
||||||
|
{
|
||||||
|
min_length = rt_strlen(dirent->d_name);
|
||||||
|
/* save dirent name */
|
||||||
|
strcpy(full_path, dirent->d_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
length = str_common(dirent->d_name, full_path);
|
||||||
|
|
||||||
|
if (length < min_length)
|
||||||
|
{
|
||||||
|
min_length = length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (min_length)
|
||||||
|
{
|
||||||
|
if (min_length < rt_strlen(full_path))
|
||||||
|
{
|
||||||
|
/* list the candidate */
|
||||||
|
rewinddir(dir);
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
dirent = readdir(dir);
|
||||||
|
if (dirent == RT_NULL) break;
|
||||||
|
|
||||||
|
if (strncmp(index, dirent->d_name, rt_strlen(index)) == 0)
|
||||||
|
rt_kprintf("%s\n", dirent->d_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
length = index - path;
|
||||||
|
memcpy(index, full_path, min_length);
|
||||||
|
path[length + min_length] = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
closedir(dir);
|
||||||
|
rt_free(full_path);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void msh_auto_complete(char *prefix)
|
||||||
|
{
|
||||||
|
int length, min_length;
|
||||||
|
const char *name_ptr, *cmd_name;
|
||||||
|
struct finsh_syscall *index;
|
||||||
|
|
||||||
|
min_length = 0;
|
||||||
|
name_ptr = RT_NULL;
|
||||||
|
|
||||||
|
if (*prefix == '\0')
|
||||||
|
{
|
||||||
|
msh_help(0, RT_NULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef RT_USING_DFS
|
||||||
|
/* check whether a spare in the command */
|
||||||
|
{
|
||||||
|
char *ptr;
|
||||||
|
|
||||||
|
ptr = prefix + rt_strlen(prefix);
|
||||||
|
while (ptr != prefix)
|
||||||
|
{
|
||||||
|
if (*ptr == ' ')
|
||||||
|
{
|
||||||
|
msh_auto_complete_path(ptr + 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ptr --;
|
||||||
|
}
|
||||||
|
#ifdef RT_USING_MODULE
|
||||||
|
/* There is a chance that the user want to run the module directly. So
|
||||||
|
* try to complete the file names. If the completed path is not a
|
||||||
|
* module, the system won't crash anyway. */
|
||||||
|
if (ptr == prefix)
|
||||||
|
{
|
||||||
|
msh_auto_complete_path(ptr);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* checks in internal command */
|
||||||
|
{
|
||||||
|
for (index = _syscall_table_begin; index < _syscall_table_end; FINSH_NEXT_SYSCALL(index))
|
||||||
|
{
|
||||||
|
/* skip finsh shell function */
|
||||||
|
if (strncmp(index->name, "__cmd_", 6) != 0) continue;
|
||||||
|
|
||||||
|
cmd_name = (const char *) &index->name[6];
|
||||||
|
if (strncmp(prefix, cmd_name, strlen(prefix)) == 0)
|
||||||
|
{
|
||||||
|
if (min_length == 0)
|
||||||
|
{
|
||||||
|
/* set name_ptr */
|
||||||
|
name_ptr = cmd_name;
|
||||||
|
/* set initial length */
|
||||||
|
min_length = strlen(name_ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
length = str_common(name_ptr, cmd_name);
|
||||||
|
if (length < min_length)
|
||||||
|
min_length = length;
|
||||||
|
|
||||||
|
rt_kprintf("%s\n", cmd_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* auto complete string */
|
||||||
|
if (name_ptr != NULL)
|
||||||
|
{
|
||||||
|
rt_strncpy(prefix, name_ptr, min_length);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* FINSH_USING_MSH */
|
|
@ -0,0 +1,23 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2013-03-30 Bernard the first verion for FinSH
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __M_SHELL__
|
||||||
|
#define __M_SHELL__
|
||||||
|
|
||||||
|
#include <rtthread.h>
|
||||||
|
|
||||||
|
rt_bool_t msh_is_used(void);
|
||||||
|
int msh_exec(char *cmd, rt_size_t length);
|
||||||
|
void msh_auto_complete(char *prefix);
|
||||||
|
|
||||||
|
int msh_exec_module(const char *cmd_line, int size);
|
||||||
|
int msh_exec_script(const char *cmd_line, int size);
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,904 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2006-04-30 Bernard the first version for FinSH
|
||||||
|
* 2006-05-08 Bernard change finsh thread stack to 2048
|
||||||
|
* 2006-06-03 Bernard add support for skyeye
|
||||||
|
* 2006-09-24 Bernard remove the code related with hardware
|
||||||
|
* 2010-01-18 Bernard fix down then up key bug.
|
||||||
|
* 2010-03-19 Bernard fix backspace issue and fix device read in shell.
|
||||||
|
* 2010-04-01 Bernard add prompt output when start and remove the empty history
|
||||||
|
* 2011-02-23 Bernard fix variable section end issue of finsh shell
|
||||||
|
* initialization when use GNU GCC compiler.
|
||||||
|
* 2016-11-26 armink add password authentication
|
||||||
|
* 2018-07-02 aozima add custome prompt support.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <rthw.h>
|
||||||
|
#include <finsh_config.h>
|
||||||
|
|
||||||
|
#ifdef RT_USING_FINSH
|
||||||
|
|
||||||
|
#include "finsh.h"
|
||||||
|
#include "shell.h"
|
||||||
|
|
||||||
|
#ifdef FINSH_USING_MSH
|
||||||
|
#include "msh.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <stdio.h> /* for putchar */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* finsh thread */
|
||||||
|
#ifndef RT_USING_HEAP
|
||||||
|
static struct rt_thread finsh_thread;
|
||||||
|
ALIGN(RT_ALIGN_SIZE)
|
||||||
|
static char finsh_thread_stack[FINSH_THREAD_STACK_SIZE];
|
||||||
|
struct finsh_shell _shell;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* finsh symtab */
|
||||||
|
#ifdef FINSH_USING_SYMTAB
|
||||||
|
struct finsh_syscall *_syscall_table_begin = NULL;
|
||||||
|
struct finsh_syscall *_syscall_table_end = NULL;
|
||||||
|
struct finsh_sysvar *_sysvar_table_begin = NULL;
|
||||||
|
struct finsh_sysvar *_sysvar_table_end = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct finsh_shell *shell;
|
||||||
|
static char *finsh_prompt_custom = RT_NULL;
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) || (defined(__GNUC__) && defined(__x86_64__))
|
||||||
|
struct finsh_syscall* finsh_syscall_next(struct finsh_syscall* call)
|
||||||
|
{
|
||||||
|
unsigned int *ptr;
|
||||||
|
ptr = (unsigned int*) (call + 1);
|
||||||
|
while ((*ptr == 0) && ((unsigned int*)ptr < (unsigned int*) _syscall_table_end))
|
||||||
|
ptr ++;
|
||||||
|
|
||||||
|
return (struct finsh_syscall*)ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct finsh_sysvar* finsh_sysvar_next(struct finsh_sysvar* call)
|
||||||
|
{
|
||||||
|
unsigned int *ptr;
|
||||||
|
ptr = (unsigned int*) (call + 1);
|
||||||
|
while ((*ptr == 0) && ((unsigned int*)ptr < (unsigned int*) _sysvar_table_end))
|
||||||
|
ptr ++;
|
||||||
|
|
||||||
|
return (struct finsh_sysvar*)ptr;
|
||||||
|
}
|
||||||
|
#endif /* defined(_MSC_VER) || (defined(__GNUC__) && defined(__x86_64__)) */
|
||||||
|
|
||||||
|
#ifdef RT_USING_HEAP
|
||||||
|
int finsh_set_prompt(const char * prompt)
|
||||||
|
{
|
||||||
|
if(finsh_prompt_custom)
|
||||||
|
{
|
||||||
|
rt_free(finsh_prompt_custom);
|
||||||
|
finsh_prompt_custom = RT_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* strdup */
|
||||||
|
if(prompt)
|
||||||
|
{
|
||||||
|
finsh_prompt_custom = (char *)rt_malloc(strlen(prompt)+1);
|
||||||
|
if(finsh_prompt_custom)
|
||||||
|
{
|
||||||
|
strcpy(finsh_prompt_custom, prompt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif /* RT_USING_HEAP */
|
||||||
|
|
||||||
|
#if defined(RT_USING_DFS)
|
||||||
|
#include <dfs_posix.h>
|
||||||
|
#endif /* RT_USING_DFS */
|
||||||
|
|
||||||
|
const char *finsh_get_prompt()
|
||||||
|
{
|
||||||
|
#define _MSH_PROMPT "msh "
|
||||||
|
#define _PROMPT "finsh "
|
||||||
|
static char finsh_prompt[RT_CONSOLEBUF_SIZE + 1] = {0};
|
||||||
|
|
||||||
|
/* check prompt mode */
|
||||||
|
if (!shell->prompt_mode)
|
||||||
|
{
|
||||||
|
finsh_prompt[0] = '\0';
|
||||||
|
return finsh_prompt;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(finsh_prompt_custom)
|
||||||
|
{
|
||||||
|
strncpy(finsh_prompt, finsh_prompt_custom, sizeof(finsh_prompt)-1);
|
||||||
|
return finsh_prompt;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef FINSH_USING_MSH
|
||||||
|
if (msh_is_used()) strcpy(finsh_prompt, _MSH_PROMPT);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
strcpy(finsh_prompt, _PROMPT);
|
||||||
|
|
||||||
|
#if defined(RT_USING_DFS) && defined(DFS_USING_WORKDIR)
|
||||||
|
/* get current working directory */
|
||||||
|
getcwd(&finsh_prompt[rt_strlen(finsh_prompt)], RT_CONSOLEBUF_SIZE - rt_strlen(finsh_prompt));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
strcat(finsh_prompt, ">");
|
||||||
|
|
||||||
|
return finsh_prompt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup finsh
|
||||||
|
*
|
||||||
|
* This function get the prompt mode of finsh shell.
|
||||||
|
*
|
||||||
|
* @return prompt the prompt mode, 0 disable prompt mode, other values enable prompt mode.
|
||||||
|
*/
|
||||||
|
rt_uint32_t finsh_get_prompt_mode(void)
|
||||||
|
{
|
||||||
|
RT_ASSERT(shell != RT_NULL);
|
||||||
|
return shell->prompt_mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup finsh
|
||||||
|
*
|
||||||
|
* This function set the prompt mode of finsh shell.
|
||||||
|
*
|
||||||
|
* The parameter 0 disable prompt mode, other values enable prompt mode.
|
||||||
|
*
|
||||||
|
* @param prompt the prompt mode
|
||||||
|
*/
|
||||||
|
void finsh_set_prompt_mode(rt_uint32_t prompt_mode)
|
||||||
|
{
|
||||||
|
RT_ASSERT(shell != RT_NULL);
|
||||||
|
shell->prompt_mode = prompt_mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int finsh_getchar(void)
|
||||||
|
{
|
||||||
|
#ifdef RT_USING_DEVICE
|
||||||
|
#ifdef RT_USING_POSIX
|
||||||
|
return getchar();
|
||||||
|
#else
|
||||||
|
char ch = 0;
|
||||||
|
|
||||||
|
RT_ASSERT(shell != RT_NULL);
|
||||||
|
|
||||||
|
if(shell->device)
|
||||||
|
{
|
||||||
|
while (rt_device_read(shell->device, -1, &ch, 1) != 1)
|
||||||
|
rt_sem_take(&shell->rx_sem, RT_WAITING_FOREVER);
|
||||||
|
|
||||||
|
return (int)ch;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
extern char rt_hw_console_getchar(void);
|
||||||
|
return rt_hw_console_getchar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(RT_USING_POSIX) && defined(RT_USING_DEVICE)
|
||||||
|
static rt_err_t finsh_rx_ind(rt_device_t dev, rt_size_t size)
|
||||||
|
{
|
||||||
|
RT_ASSERT(shell != RT_NULL);
|
||||||
|
|
||||||
|
/* release semaphore to let finsh thread rx data */
|
||||||
|
rt_sem_release(&shell->rx_sem);
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup finsh
|
||||||
|
*
|
||||||
|
* This function sets the input device of finsh shell.
|
||||||
|
*
|
||||||
|
* @param device_name the name of new input device.
|
||||||
|
*/
|
||||||
|
void finsh_set_device(const char *device_name)
|
||||||
|
{
|
||||||
|
rt_device_t dev = RT_NULL;
|
||||||
|
|
||||||
|
RT_ASSERT(shell != RT_NULL);
|
||||||
|
dev = rt_device_find(device_name);
|
||||||
|
if (dev == RT_NULL)
|
||||||
|
{
|
||||||
|
rt_kprintf("finsh: can not find device: %s\n", device_name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check whether it's a same device */
|
||||||
|
if (dev == shell->device) return;
|
||||||
|
/* open this device and set the new device in finsh shell */
|
||||||
|
if (rt_device_open(dev, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_INT_RX | \
|
||||||
|
RT_DEVICE_FLAG_STREAM) == RT_EOK)
|
||||||
|
{
|
||||||
|
if (shell->device != RT_NULL)
|
||||||
|
{
|
||||||
|
/* close old finsh device */
|
||||||
|
rt_device_close(shell->device);
|
||||||
|
rt_device_set_rx_indicate(shell->device, RT_NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* clear line buffer before switch to new device */
|
||||||
|
memset(shell->line, 0, sizeof(shell->line));
|
||||||
|
shell->line_curpos = shell->line_position = 0;
|
||||||
|
|
||||||
|
shell->device = dev;
|
||||||
|
rt_device_set_rx_indicate(dev, finsh_rx_ind);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup finsh
|
||||||
|
*
|
||||||
|
* This function returns current finsh shell input device.
|
||||||
|
*
|
||||||
|
* @return the finsh shell input device name is returned.
|
||||||
|
*/
|
||||||
|
const char *finsh_get_device()
|
||||||
|
{
|
||||||
|
RT_ASSERT(shell != RT_NULL);
|
||||||
|
return shell->device->parent.name;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup finsh
|
||||||
|
*
|
||||||
|
* This function set the echo mode of finsh shell.
|
||||||
|
*
|
||||||
|
* FINSH_OPTION_ECHO=0x01 is echo mode, other values are none-echo mode.
|
||||||
|
*
|
||||||
|
* @param echo the echo mode
|
||||||
|
*/
|
||||||
|
void finsh_set_echo(rt_uint32_t echo)
|
||||||
|
{
|
||||||
|
RT_ASSERT(shell != RT_NULL);
|
||||||
|
shell->echo_mode = (rt_uint8_t)echo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup finsh
|
||||||
|
*
|
||||||
|
* This function gets the echo mode of finsh shell.
|
||||||
|
*
|
||||||
|
* @return the echo mode
|
||||||
|
*/
|
||||||
|
rt_uint32_t finsh_get_echo()
|
||||||
|
{
|
||||||
|
RT_ASSERT(shell != RT_NULL);
|
||||||
|
|
||||||
|
return shell->echo_mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef FINSH_USING_AUTH
|
||||||
|
/**
|
||||||
|
* set a new password for finsh
|
||||||
|
*
|
||||||
|
* @param password new password
|
||||||
|
*
|
||||||
|
* @return result, RT_EOK on OK, -RT_ERROR on the new password length is less than
|
||||||
|
* FINSH_PASSWORD_MIN or greater than FINSH_PASSWORD_MAX
|
||||||
|
*/
|
||||||
|
rt_err_t finsh_set_password(const char *password) {
|
||||||
|
rt_ubase_t level;
|
||||||
|
rt_size_t pw_len = rt_strlen(password);
|
||||||
|
|
||||||
|
if (pw_len < FINSH_PASSWORD_MIN || pw_len > FINSH_PASSWORD_MAX)
|
||||||
|
return -RT_ERROR;
|
||||||
|
|
||||||
|
level = rt_hw_interrupt_disable();
|
||||||
|
rt_strncpy(shell->password, password, FINSH_PASSWORD_MAX);
|
||||||
|
rt_hw_interrupt_enable(level);
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the finsh password
|
||||||
|
*
|
||||||
|
* @return password
|
||||||
|
*/
|
||||||
|
const char *finsh_get_password(void)
|
||||||
|
{
|
||||||
|
return shell->password;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void finsh_wait_auth(void)
|
||||||
|
{
|
||||||
|
int ch;
|
||||||
|
rt_bool_t input_finish = RT_FALSE;
|
||||||
|
char password[FINSH_PASSWORD_MAX] = { 0 };
|
||||||
|
rt_size_t cur_pos = 0;
|
||||||
|
/* password not set */
|
||||||
|
if (rt_strlen(finsh_get_password()) == 0) return;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
rt_kprintf("Password for login: ");
|
||||||
|
while (!input_finish)
|
||||||
|
{
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
/* read one character from device */
|
||||||
|
ch = finsh_getchar();
|
||||||
|
if (ch < 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ch >= ' ' && ch <= '~' && cur_pos < FINSH_PASSWORD_MAX)
|
||||||
|
{
|
||||||
|
/* change the printable characters to '*' */
|
||||||
|
rt_kprintf("*");
|
||||||
|
password[cur_pos++] = ch;
|
||||||
|
}
|
||||||
|
else if (ch == '\b' && cur_pos > 0)
|
||||||
|
{
|
||||||
|
/* backspace */
|
||||||
|
cur_pos--;
|
||||||
|
password[cur_pos] = '\0';
|
||||||
|
rt_kprintf("\b \b");
|
||||||
|
}
|
||||||
|
else if (ch == '\r' || ch == '\n')
|
||||||
|
{
|
||||||
|
rt_kprintf("\n");
|
||||||
|
input_finish = RT_TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!rt_strncmp(shell->password, password, FINSH_PASSWORD_MAX)) return;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* authentication failed, delay 2S for retry */
|
||||||
|
rt_thread_delay(2 * RT_TICK_PER_SECOND);
|
||||||
|
rt_kprintf("Sorry, try again.\n");
|
||||||
|
cur_pos = 0;
|
||||||
|
input_finish = RT_FALSE;
|
||||||
|
rt_memset(password, '\0', FINSH_PASSWORD_MAX);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* FINSH_USING_AUTH */
|
||||||
|
|
||||||
|
static void shell_auto_complete(char *prefix)
|
||||||
|
{
|
||||||
|
|
||||||
|
rt_kprintf("\n");
|
||||||
|
#ifdef FINSH_USING_MSH
|
||||||
|
if (msh_is_used() == RT_TRUE)
|
||||||
|
{
|
||||||
|
msh_auto_complete(prefix);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
#ifndef FINSH_USING_MSH_ONLY
|
||||||
|
extern void list_prefix(char * prefix);
|
||||||
|
list_prefix(prefix);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
rt_kprintf("%s%s", FINSH_PROMPT, prefix);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef FINSH_USING_MSH_ONLY
|
||||||
|
void finsh_run_line(struct finsh_parser *parser, const char *line)
|
||||||
|
{
|
||||||
|
const char *err_str;
|
||||||
|
|
||||||
|
if(shell->echo_mode)
|
||||||
|
rt_kprintf("\n");
|
||||||
|
finsh_parser_run(parser, (unsigned char *)line);
|
||||||
|
|
||||||
|
/* compile node root */
|
||||||
|
if (finsh_errno() == 0)
|
||||||
|
{
|
||||||
|
finsh_compiler_run(parser->root);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
err_str = finsh_error_string(finsh_errno());
|
||||||
|
rt_kprintf("%s\n", err_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* run virtual machine */
|
||||||
|
if (finsh_errno() == 0)
|
||||||
|
{
|
||||||
|
char ch;
|
||||||
|
finsh_vm_run();
|
||||||
|
|
||||||
|
ch = (unsigned char)finsh_stack_bottom();
|
||||||
|
if (ch > 0x20 && ch < 0x7e)
|
||||||
|
{
|
||||||
|
rt_kprintf("\t'%c', %d, 0x%08x\n",
|
||||||
|
(unsigned char)finsh_stack_bottom(),
|
||||||
|
(unsigned int)finsh_stack_bottom(),
|
||||||
|
(unsigned int)finsh_stack_bottom());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rt_kprintf("\t%d, 0x%08x\n",
|
||||||
|
(unsigned int)finsh_stack_bottom(),
|
||||||
|
(unsigned int)finsh_stack_bottom());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
finsh_flush(parser);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef FINSH_USING_HISTORY
|
||||||
|
static rt_bool_t shell_handle_history(struct finsh_shell *shell)
|
||||||
|
{
|
||||||
|
#if defined(_WIN32)
|
||||||
|
int i;
|
||||||
|
rt_kprintf("\r");
|
||||||
|
|
||||||
|
for (i = 0; i <= 60; i++)
|
||||||
|
putchar(' ');
|
||||||
|
rt_kprintf("\r");
|
||||||
|
|
||||||
|
#else
|
||||||
|
rt_kprintf("\033[2K\r");
|
||||||
|
#endif
|
||||||
|
rt_kprintf("%s%s", FINSH_PROMPT, shell->line);
|
||||||
|
return RT_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void shell_push_history(struct finsh_shell *shell)
|
||||||
|
{
|
||||||
|
if (shell->line_position != 0)
|
||||||
|
{
|
||||||
|
/* push history */
|
||||||
|
if (shell->history_count >= FINSH_HISTORY_LINES)
|
||||||
|
{
|
||||||
|
/* if current cmd is same as last cmd, don't push */
|
||||||
|
if (memcmp(&shell->cmd_history[FINSH_HISTORY_LINES - 1], shell->line, FINSH_CMD_SIZE))
|
||||||
|
{
|
||||||
|
/* move history */
|
||||||
|
int index;
|
||||||
|
for (index = 0; index < FINSH_HISTORY_LINES - 1; index ++)
|
||||||
|
{
|
||||||
|
memcpy(&shell->cmd_history[index][0],
|
||||||
|
&shell->cmd_history[index + 1][0], FINSH_CMD_SIZE);
|
||||||
|
}
|
||||||
|
memset(&shell->cmd_history[index][0], 0, FINSH_CMD_SIZE);
|
||||||
|
memcpy(&shell->cmd_history[index][0], shell->line, shell->line_position);
|
||||||
|
|
||||||
|
/* it's the maximum history */
|
||||||
|
shell->history_count = FINSH_HISTORY_LINES;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* if current cmd is same as last cmd, don't push */
|
||||||
|
if (shell->history_count == 0 || memcmp(&shell->cmd_history[shell->history_count - 1], shell->line, FINSH_CMD_SIZE))
|
||||||
|
{
|
||||||
|
shell->current_history = shell->history_count;
|
||||||
|
memset(&shell->cmd_history[shell->history_count][0], 0, FINSH_CMD_SIZE);
|
||||||
|
memcpy(&shell->cmd_history[shell->history_count][0], shell->line, shell->line_position);
|
||||||
|
|
||||||
|
/* increase count and set current history position */
|
||||||
|
shell->history_count ++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
shell->current_history = shell->history_count;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void finsh_thread_entry(void *parameter)
|
||||||
|
{
|
||||||
|
int ch;
|
||||||
|
|
||||||
|
/* normal is echo mode */
|
||||||
|
#ifndef FINSH_ECHO_DISABLE_DEFAULT
|
||||||
|
shell->echo_mode = 1;
|
||||||
|
#else
|
||||||
|
shell->echo_mode = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef FINSH_USING_MSH_ONLY
|
||||||
|
finsh_init(&shell->parser);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(RT_USING_POSIX) && defined(RT_USING_DEVICE)
|
||||||
|
/* set console device as shell device */
|
||||||
|
if (shell->device == RT_NULL)
|
||||||
|
{
|
||||||
|
rt_device_t console = rt_console_get_device();
|
||||||
|
if (console)
|
||||||
|
{
|
||||||
|
finsh_set_device(console->parent.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef FINSH_USING_AUTH
|
||||||
|
/* set the default password when the password isn't setting */
|
||||||
|
if (rt_strlen(finsh_get_password()) == 0)
|
||||||
|
{
|
||||||
|
if (finsh_set_password(FINSH_DEFAULT_PASSWORD) != RT_EOK)
|
||||||
|
{
|
||||||
|
rt_kprintf("Finsh password set failed.\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* waiting authenticate success */
|
||||||
|
finsh_wait_auth();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
rt_kprintf(FINSH_PROMPT);
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
ch = finsh_getchar();
|
||||||
|
if (ch < 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* handle control key
|
||||||
|
* up key : 0x1b 0x5b 0x41
|
||||||
|
* down key: 0x1b 0x5b 0x42
|
||||||
|
* right key:0x1b 0x5b 0x43
|
||||||
|
* left key: 0x1b 0x5b 0x44
|
||||||
|
*/
|
||||||
|
if (ch == 0x1b)
|
||||||
|
{
|
||||||
|
shell->stat = WAIT_SPEC_KEY;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (shell->stat == WAIT_SPEC_KEY)
|
||||||
|
{
|
||||||
|
if (ch == 0x5b)
|
||||||
|
{
|
||||||
|
shell->stat = WAIT_FUNC_KEY;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
shell->stat = WAIT_NORMAL;
|
||||||
|
}
|
||||||
|
else if (shell->stat == WAIT_FUNC_KEY)
|
||||||
|
{
|
||||||
|
shell->stat = WAIT_NORMAL;
|
||||||
|
|
||||||
|
if (ch == 0x41) /* up key */
|
||||||
|
{
|
||||||
|
#ifdef FINSH_USING_HISTORY
|
||||||
|
/* prev history */
|
||||||
|
if (shell->current_history > 0)
|
||||||
|
shell->current_history --;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
shell->current_history = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* copy the history command */
|
||||||
|
memcpy(shell->line, &shell->cmd_history[shell->current_history][0],
|
||||||
|
FINSH_CMD_SIZE);
|
||||||
|
shell->line_curpos = shell->line_position = strlen(shell->line);
|
||||||
|
shell_handle_history(shell);
|
||||||
|
#endif
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (ch == 0x42) /* down key */
|
||||||
|
{
|
||||||
|
#ifdef FINSH_USING_HISTORY
|
||||||
|
/* next history */
|
||||||
|
if (shell->current_history < shell->history_count - 1)
|
||||||
|
shell->current_history ++;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* set to the end of history */
|
||||||
|
if (shell->history_count != 0)
|
||||||
|
shell->current_history = shell->history_count - 1;
|
||||||
|
else
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(shell->line, &shell->cmd_history[shell->current_history][0],
|
||||||
|
FINSH_CMD_SIZE);
|
||||||
|
shell->line_curpos = shell->line_position = strlen(shell->line);
|
||||||
|
shell_handle_history(shell);
|
||||||
|
#endif
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (ch == 0x44) /* left key */
|
||||||
|
{
|
||||||
|
if (shell->line_curpos)
|
||||||
|
{
|
||||||
|
rt_kprintf("\b");
|
||||||
|
shell->line_curpos --;
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (ch == 0x43) /* right key */
|
||||||
|
{
|
||||||
|
if (shell->line_curpos < shell->line_position)
|
||||||
|
{
|
||||||
|
rt_kprintf("%c", shell->line[shell->line_curpos]);
|
||||||
|
shell->line_curpos ++;
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* received null or error */
|
||||||
|
if (ch == '\0' || ch == 0xFF) continue;
|
||||||
|
/* handle tab key */
|
||||||
|
else if (ch == '\t')
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
/* move the cursor to the beginning of line */
|
||||||
|
for (i = 0; i < shell->line_curpos; i++)
|
||||||
|
rt_kprintf("\b");
|
||||||
|
|
||||||
|
/* auto complete */
|
||||||
|
shell_auto_complete(&shell->line[0]);
|
||||||
|
/* re-calculate position */
|
||||||
|
shell->line_curpos = shell->line_position = strlen(shell->line);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* handle backspace key */
|
||||||
|
else if (ch == 0x7f || ch == 0x08)
|
||||||
|
{
|
||||||
|
/* note that shell->line_curpos >= 0 */
|
||||||
|
if (shell->line_curpos == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
shell->line_position--;
|
||||||
|
shell->line_curpos--;
|
||||||
|
|
||||||
|
if (shell->line_position > shell->line_curpos)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
rt_memmove(&shell->line[shell->line_curpos],
|
||||||
|
&shell->line[shell->line_curpos + 1],
|
||||||
|
shell->line_position - shell->line_curpos);
|
||||||
|
shell->line[shell->line_position] = 0;
|
||||||
|
|
||||||
|
rt_kprintf("\b%s \b", &shell->line[shell->line_curpos]);
|
||||||
|
|
||||||
|
/* move the cursor to the origin position */
|
||||||
|
for (i = shell->line_curpos; i <= shell->line_position; i++)
|
||||||
|
rt_kprintf("\b");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rt_kprintf("\b \b");
|
||||||
|
shell->line[shell->line_position] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* handle end of line, break */
|
||||||
|
if (ch == '\r' || ch == '\n')
|
||||||
|
{
|
||||||
|
#ifdef FINSH_USING_HISTORY
|
||||||
|
shell_push_history(shell);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef FINSH_USING_MSH
|
||||||
|
if (msh_is_used() == RT_TRUE)
|
||||||
|
{
|
||||||
|
if (shell->echo_mode)
|
||||||
|
rt_kprintf("\n");
|
||||||
|
msh_exec(shell->line, shell->line_position);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
#ifndef FINSH_USING_MSH_ONLY
|
||||||
|
/* add ';' and run the command line */
|
||||||
|
shell->line[shell->line_position] = ';';
|
||||||
|
|
||||||
|
if (shell->line_position != 0) finsh_run_line(&shell->parser, shell->line);
|
||||||
|
else
|
||||||
|
if (shell->echo_mode) rt_kprintf("\n");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
rt_kprintf(FINSH_PROMPT);
|
||||||
|
memset(shell->line, 0, sizeof(shell->line));
|
||||||
|
shell->line_curpos = shell->line_position = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* it's a large line, discard it */
|
||||||
|
if (shell->line_position >= FINSH_CMD_SIZE)
|
||||||
|
shell->line_position = 0;
|
||||||
|
|
||||||
|
/* normal character */
|
||||||
|
if (shell->line_curpos < shell->line_position)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
rt_memmove(&shell->line[shell->line_curpos + 1],
|
||||||
|
&shell->line[shell->line_curpos],
|
||||||
|
shell->line_position - shell->line_curpos);
|
||||||
|
shell->line[shell->line_curpos] = ch;
|
||||||
|
if (shell->echo_mode)
|
||||||
|
rt_kprintf("%s", &shell->line[shell->line_curpos]);
|
||||||
|
|
||||||
|
/* move the cursor to new position */
|
||||||
|
for (i = shell->line_curpos; i < shell->line_position; i++)
|
||||||
|
rt_kprintf("\b");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
shell->line[shell->line_position] = ch;
|
||||||
|
if (shell->echo_mode)
|
||||||
|
rt_kprintf("%c", ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
ch = 0;
|
||||||
|
shell->line_position ++;
|
||||||
|
shell->line_curpos++;
|
||||||
|
if (shell->line_position >= FINSH_CMD_SIZE)
|
||||||
|
{
|
||||||
|
/* clear command line */
|
||||||
|
shell->line_position = 0;
|
||||||
|
shell->line_curpos = 0;
|
||||||
|
}
|
||||||
|
} /* end of device read */
|
||||||
|
}
|
||||||
|
|
||||||
|
void finsh_system_function_init(const void *begin, const void *end)
|
||||||
|
{
|
||||||
|
_syscall_table_begin = (struct finsh_syscall *) begin;
|
||||||
|
_syscall_table_end = (struct finsh_syscall *) end;
|
||||||
|
}
|
||||||
|
|
||||||
|
void finsh_system_var_init(const void *begin, const void *end)
|
||||||
|
{
|
||||||
|
_sysvar_table_begin = (struct finsh_sysvar *) begin;
|
||||||
|
_sysvar_table_end = (struct finsh_sysvar *) end;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(__ICCARM__) || defined(__ICCRX__) /* for IAR compiler */
|
||||||
|
#ifdef FINSH_USING_SYMTAB
|
||||||
|
#pragma section="FSymTab"
|
||||||
|
#pragma section="VSymTab"
|
||||||
|
#endif
|
||||||
|
#elif defined(__ADSPBLACKFIN__) /* for VisaulDSP++ Compiler*/
|
||||||
|
#ifdef FINSH_USING_SYMTAB
|
||||||
|
extern "asm" int __fsymtab_start;
|
||||||
|
extern "asm" int __fsymtab_end;
|
||||||
|
extern "asm" int __vsymtab_start;
|
||||||
|
extern "asm" int __vsymtab_end;
|
||||||
|
#endif
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
#pragma section("FSymTab$a", read)
|
||||||
|
const char __fsym_begin_name[] = "__start";
|
||||||
|
const char __fsym_begin_desc[] = "begin of finsh";
|
||||||
|
__declspec(allocate("FSymTab$a")) const struct finsh_syscall __fsym_begin =
|
||||||
|
{
|
||||||
|
__fsym_begin_name,
|
||||||
|
__fsym_begin_desc,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
#pragma section("FSymTab$z", read)
|
||||||
|
const char __fsym_end_name[] = "__end";
|
||||||
|
const char __fsym_end_desc[] = "end of finsh";
|
||||||
|
__declspec(allocate("FSymTab$z")) const struct finsh_syscall __fsym_end =
|
||||||
|
{
|
||||||
|
__fsym_end_name,
|
||||||
|
__fsym_end_desc,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @ingroup finsh
|
||||||
|
*
|
||||||
|
* This function will initialize finsh shell
|
||||||
|
*/
|
||||||
|
int finsh_system_init(void)
|
||||||
|
{
|
||||||
|
rt_err_t result = RT_EOK;
|
||||||
|
rt_thread_t tid;
|
||||||
|
|
||||||
|
#ifdef FINSH_USING_SYMTAB
|
||||||
|
#if defined(__CC_ARM) || defined(__CLANG_ARM) /* ARM C Compiler */
|
||||||
|
extern const int FSymTab$$Base;
|
||||||
|
extern const int FSymTab$$Limit;
|
||||||
|
extern const int VSymTab$$Base;
|
||||||
|
extern const int VSymTab$$Limit;
|
||||||
|
finsh_system_function_init(&FSymTab$$Base, &FSymTab$$Limit);
|
||||||
|
#ifndef FINSH_USING_MSH_ONLY
|
||||||
|
finsh_system_var_init(&VSymTab$$Base, &VSymTab$$Limit);
|
||||||
|
#endif
|
||||||
|
#elif defined (__ICCARM__) || defined(__ICCRX__) /* for IAR Compiler */
|
||||||
|
finsh_system_function_init(__section_begin("FSymTab"),
|
||||||
|
__section_end("FSymTab"));
|
||||||
|
finsh_system_var_init(__section_begin("VSymTab"),
|
||||||
|
__section_end("VSymTab"));
|
||||||
|
#elif defined (__GNUC__) || defined(__TI_COMPILER_VERSION__)
|
||||||
|
/* GNU GCC Compiler and TI CCS */
|
||||||
|
extern const int __fsymtab_start;
|
||||||
|
extern const int __fsymtab_end;
|
||||||
|
extern const int __vsymtab_start;
|
||||||
|
extern const int __vsymtab_end;
|
||||||
|
finsh_system_function_init(&__fsymtab_start, &__fsymtab_end);
|
||||||
|
finsh_system_var_init(&__vsymtab_start, &__vsymtab_end);
|
||||||
|
#elif defined(__ADSPBLACKFIN__) /* for VisualDSP++ Compiler */
|
||||||
|
finsh_system_function_init(&__fsymtab_start, &__fsymtab_end);
|
||||||
|
finsh_system_var_init(&__vsymtab_start, &__vsymtab_end);
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
unsigned int *ptr_begin, *ptr_end;
|
||||||
|
|
||||||
|
if(shell)
|
||||||
|
{
|
||||||
|
rt_kprintf("finsh shell already init.\n");
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
ptr_begin = (unsigned int *)&__fsym_begin;
|
||||||
|
ptr_begin += (sizeof(struct finsh_syscall) / sizeof(unsigned int));
|
||||||
|
while (*ptr_begin == 0) ptr_begin ++;
|
||||||
|
|
||||||
|
ptr_end = (unsigned int *) &__fsym_end;
|
||||||
|
ptr_end --;
|
||||||
|
while (*ptr_end == 0) ptr_end --;
|
||||||
|
|
||||||
|
finsh_system_function_init(ptr_begin, ptr_end);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef RT_USING_HEAP
|
||||||
|
/* create or set shell structure */
|
||||||
|
shell = (struct finsh_shell *)rt_calloc(1, sizeof(struct finsh_shell));
|
||||||
|
if (shell == RT_NULL)
|
||||||
|
{
|
||||||
|
rt_kprintf("no memory for shell\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
tid = rt_thread_create(FINSH_THREAD_NAME,
|
||||||
|
finsh_thread_entry, RT_NULL,
|
||||||
|
FINSH_THREAD_STACK_SIZE, FINSH_THREAD_PRIORITY, 10);
|
||||||
|
#else
|
||||||
|
shell = &_shell;
|
||||||
|
tid = &finsh_thread;
|
||||||
|
result = rt_thread_init(&finsh_thread,
|
||||||
|
FINSH_THREAD_NAME,
|
||||||
|
finsh_thread_entry, RT_NULL,
|
||||||
|
&finsh_thread_stack[0], sizeof(finsh_thread_stack),
|
||||||
|
FINSH_THREAD_PRIORITY, 10);
|
||||||
|
#endif /* RT_USING_HEAP */
|
||||||
|
|
||||||
|
rt_sem_init(&(shell->rx_sem), "shrx", 0, 0);
|
||||||
|
finsh_set_prompt_mode(1);
|
||||||
|
|
||||||
|
if (tid != NULL && result == RT_EOK)
|
||||||
|
rt_thread_startup(tid);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
INIT_APP_EXPORT(finsh_system_init);
|
||||||
|
|
||||||
|
#endif /* RT_USING_FINSH */
|
||||||
|
|
|
@ -0,0 +1,110 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2011-06-02 Bernard Add finsh_get_prompt function declaration
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __SHELL_H__
|
||||||
|
#define __SHELL_H__
|
||||||
|
|
||||||
|
#include <rtthread.h>
|
||||||
|
#include "finsh.h"
|
||||||
|
|
||||||
|
#ifndef FINSH_THREAD_PRIORITY
|
||||||
|
#define FINSH_THREAD_PRIORITY 20
|
||||||
|
#endif
|
||||||
|
#ifndef FINSH_THREAD_STACK_SIZE
|
||||||
|
#define FINSH_THREAD_STACK_SIZE 2048
|
||||||
|
#endif
|
||||||
|
#ifndef FINSH_CMD_SIZE
|
||||||
|
#define FINSH_CMD_SIZE 80
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define FINSH_OPTION_ECHO 0x01
|
||||||
|
|
||||||
|
#define FINSH_PROMPT finsh_get_prompt()
|
||||||
|
const char* finsh_get_prompt(void);
|
||||||
|
int finsh_set_prompt(const char * prompt);
|
||||||
|
|
||||||
|
#ifdef FINSH_USING_HISTORY
|
||||||
|
#ifndef FINSH_HISTORY_LINES
|
||||||
|
#define FINSH_HISTORY_LINES 5
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef FINSH_USING_AUTH
|
||||||
|
#ifndef FINSH_PASSWORD_MAX
|
||||||
|
#define FINSH_PASSWORD_MAX RT_NAME_MAX
|
||||||
|
#endif
|
||||||
|
#ifndef FINSH_PASSWORD_MIN
|
||||||
|
#define FINSH_PASSWORD_MIN 6
|
||||||
|
#endif
|
||||||
|
#ifndef FINSH_DEFAULT_PASSWORD
|
||||||
|
#define FINSH_DEFAULT_PASSWORD "rtthread"
|
||||||
|
#endif
|
||||||
|
#endif /* FINSH_USING_AUTH */
|
||||||
|
|
||||||
|
#ifndef FINSH_THREAD_NAME
|
||||||
|
#define FINSH_THREAD_NAME "tshell"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
enum input_stat
|
||||||
|
{
|
||||||
|
WAIT_NORMAL,
|
||||||
|
WAIT_SPEC_KEY,
|
||||||
|
WAIT_FUNC_KEY,
|
||||||
|
};
|
||||||
|
struct finsh_shell
|
||||||
|
{
|
||||||
|
struct rt_semaphore rx_sem;
|
||||||
|
|
||||||
|
enum input_stat stat;
|
||||||
|
|
||||||
|
rt_uint8_t echo_mode:1;
|
||||||
|
rt_uint8_t prompt_mode: 1;
|
||||||
|
|
||||||
|
#ifdef FINSH_USING_HISTORY
|
||||||
|
rt_uint16_t current_history;
|
||||||
|
rt_uint16_t history_count;
|
||||||
|
|
||||||
|
char cmd_history[FINSH_HISTORY_LINES][FINSH_CMD_SIZE];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef FINSH_USING_MSH_ONLY
|
||||||
|
struct finsh_parser parser;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
char line[FINSH_CMD_SIZE];
|
||||||
|
rt_uint16_t line_position;
|
||||||
|
rt_uint16_t line_curpos;
|
||||||
|
|
||||||
|
#if !defined(RT_USING_POSIX) && defined(RT_USING_DEVICE)
|
||||||
|
rt_device_t device;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef FINSH_USING_AUTH
|
||||||
|
char password[FINSH_PASSWORD_MAX];
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
void finsh_set_echo(rt_uint32_t echo);
|
||||||
|
rt_uint32_t finsh_get_echo(void);
|
||||||
|
|
||||||
|
int finsh_system_init(void);
|
||||||
|
void finsh_set_device(const char* device_name);
|
||||||
|
const char* finsh_get_device(void);
|
||||||
|
|
||||||
|
rt_uint32_t finsh_get_prompt_mode(void);
|
||||||
|
void finsh_set_prompt_mode(rt_uint32_t prompt_mode);
|
||||||
|
|
||||||
|
#ifdef FINSH_USING_AUTH
|
||||||
|
rt_err_t finsh_set_password(const char *password);
|
||||||
|
const char *finsh_get_password(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LIBC_DIRENT_H__
|
||||||
|
#define LIBC_DIRENT_H__
|
||||||
|
|
||||||
|
#define DT_UNKNOWN 0x00
|
||||||
|
#define DT_REG 0x01
|
||||||
|
#define DT_DIR 0x02
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,206 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2016-11-12 Bernard The first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LIBC_ERRNO_H__
|
||||||
|
#define LIBC_ERRNO_H__
|
||||||
|
|
||||||
|
#include <rtconfig.h>
|
||||||
|
|
||||||
|
#if defined(RT_USING_NEWLIB) || defined(_WIN32)
|
||||||
|
/* use errno.h file in toolchains */
|
||||||
|
#include <errno.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__CC_ARM)
|
||||||
|
/*
|
||||||
|
defined in armcc/errno.h
|
||||||
|
|
||||||
|
#define EDOM 1
|
||||||
|
#define ERANGE 2
|
||||||
|
#define EILSEQ 4
|
||||||
|
#define ESIGNUM 3
|
||||||
|
#define EINVAL 5
|
||||||
|
#define ENOMEM 6
|
||||||
|
*/
|
||||||
|
#define ERROR_BASE_NO 7
|
||||||
|
|
||||||
|
#elif defined(__IAR_SYSTEMS_ICC__)
|
||||||
|
/* defined in iar/errno.h
|
||||||
|
#define EDOM 33
|
||||||
|
#define ERANGE 34
|
||||||
|
#define EFPOS 35
|
||||||
|
#define EILSEQ 36
|
||||||
|
*/
|
||||||
|
#define ERROR_BASE_NO 36
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define ERROR_BASE_NO 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(RT_USING_NEWLIB) && !defined(_WIN32)
|
||||||
|
|
||||||
|
#define EPERM (ERROR_BASE_NO + 1)
|
||||||
|
#define ENOENT (ERROR_BASE_NO + 2)
|
||||||
|
#define ESRCH (ERROR_BASE_NO + 3)
|
||||||
|
#define EINTR (ERROR_BASE_NO + 4)
|
||||||
|
#define EIO (ERROR_BASE_NO + 5)
|
||||||
|
#define ENXIO (ERROR_BASE_NO + 6)
|
||||||
|
#define E2BIG (ERROR_BASE_NO + 7)
|
||||||
|
#define ENOEXEC (ERROR_BASE_NO + 8)
|
||||||
|
#define EBADF (ERROR_BASE_NO + 9)
|
||||||
|
#define ECHILD (ERROR_BASE_NO + 10)
|
||||||
|
#define EAGAIN (ERROR_BASE_NO + 11)
|
||||||
|
|
||||||
|
#ifndef ENOMEM
|
||||||
|
#define ENOMEM (ERROR_BASE_NO + 12)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define EACCES (ERROR_BASE_NO + 13)
|
||||||
|
#define EFAULT (ERROR_BASE_NO + 14)
|
||||||
|
#define ENOTBLK (ERROR_BASE_NO + 15)
|
||||||
|
#define EBUSY (ERROR_BASE_NO + 16)
|
||||||
|
#define EEXIST (ERROR_BASE_NO + 17)
|
||||||
|
#define EXDEV (ERROR_BASE_NO + 18)
|
||||||
|
#define ENODEV (ERROR_BASE_NO + 19)
|
||||||
|
#define ENOTDIR (ERROR_BASE_NO + 20)
|
||||||
|
#define EISDIR (ERROR_BASE_NO + 21)
|
||||||
|
|
||||||
|
#ifndef EINVAL
|
||||||
|
#define EINVAL (ERROR_BASE_NO + 22)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ENFILE (ERROR_BASE_NO + 23)
|
||||||
|
#define EMFILE (ERROR_BASE_NO + 24)
|
||||||
|
#define ENOTTY (ERROR_BASE_NO + 25)
|
||||||
|
#define ETXTBSY (ERROR_BASE_NO + 26)
|
||||||
|
#define EFBIG (ERROR_BASE_NO + 27)
|
||||||
|
#define ENOSPC (ERROR_BASE_NO + 28)
|
||||||
|
#define ESPIPE (ERROR_BASE_NO + 29)
|
||||||
|
#define EROFS (ERROR_BASE_NO + 30)
|
||||||
|
#define EMLINK (ERROR_BASE_NO + 31)
|
||||||
|
#define EPIPE (ERROR_BASE_NO + 32)
|
||||||
|
|
||||||
|
#ifndef EDOM
|
||||||
|
#define EDOM (ERROR_BASE_NO + 33)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ERANGE
|
||||||
|
#define ERANGE (ERROR_BASE_NO + 34)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define EDEADLK (ERROR_BASE_NO + 35)
|
||||||
|
#define ENAMETOOLONG (ERROR_BASE_NO + 36)
|
||||||
|
#define ENOLCK (ERROR_BASE_NO + 37)
|
||||||
|
#define ENOSYS (ERROR_BASE_NO + 38)
|
||||||
|
#define ENOTEMPTY (ERROR_BASE_NO + 39)
|
||||||
|
#define ELOOP (ERROR_BASE_NO + 40)
|
||||||
|
#define EWOULDBLOCK EAGAIN
|
||||||
|
#define ENOMSG (ERROR_BASE_NO + 42)
|
||||||
|
#define EIDRM (ERROR_BASE_NO + 43)
|
||||||
|
#define ECHRNG (ERROR_BASE_NO + 44)
|
||||||
|
#define EL2NSYNC (ERROR_BASE_NO + 45)
|
||||||
|
#define EL3HLT (ERROR_BASE_NO + 46)
|
||||||
|
#define EL3RST (ERROR_BASE_NO + 47)
|
||||||
|
#define ELNRNG (ERROR_BASE_NO + 48)
|
||||||
|
#define EUNATCH (ERROR_BASE_NO + 49)
|
||||||
|
#define ENOCSI (ERROR_BASE_NO + 50)
|
||||||
|
#define EL2HLT (ERROR_BASE_NO + 51)
|
||||||
|
#define EBADE (ERROR_BASE_NO + 52)
|
||||||
|
#define EBADR (ERROR_BASE_NO + 53)
|
||||||
|
#define EXFULL (ERROR_BASE_NO + 54)
|
||||||
|
#define ENOANO (ERROR_BASE_NO + 55)
|
||||||
|
#define EBADRQC (ERROR_BASE_NO + 56)
|
||||||
|
#define EBADSLT (ERROR_BASE_NO + 57)
|
||||||
|
#define EDEADLOCK EDEADLK
|
||||||
|
#define EBFONT (ERROR_BASE_NO + 59)
|
||||||
|
#define ENOSTR (ERROR_BASE_NO + 60)
|
||||||
|
#define ENODATA (ERROR_BASE_NO + 61)
|
||||||
|
#define ETIME (ERROR_BASE_NO + 62)
|
||||||
|
#define ENOSR (ERROR_BASE_NO + 63)
|
||||||
|
#define ENONET (ERROR_BASE_NO + 64)
|
||||||
|
#define ENOPKG (ERROR_BASE_NO + 65)
|
||||||
|
#define EREMOTE (ERROR_BASE_NO + 66)
|
||||||
|
#define ENOLINK (ERROR_BASE_NO + 67)
|
||||||
|
#define EADV (ERROR_BASE_NO + 68)
|
||||||
|
#define ESRMNT (ERROR_BASE_NO + 69)
|
||||||
|
#define ECOMM (ERROR_BASE_NO + 70)
|
||||||
|
#define EPROTO (ERROR_BASE_NO + 71)
|
||||||
|
#define EMULTIHOP (ERROR_BASE_NO + 72)
|
||||||
|
#define EDOTDOT (ERROR_BASE_NO + 73)
|
||||||
|
#define EBADMSG (ERROR_BASE_NO + 74)
|
||||||
|
#define EOVERFLOW (ERROR_BASE_NO + 75)
|
||||||
|
#define ENOTUNIQ (ERROR_BASE_NO + 76)
|
||||||
|
#define EBADFD (ERROR_BASE_NO + 77)
|
||||||
|
#define EREMCHG (ERROR_BASE_NO + 78)
|
||||||
|
#define ELIBACC (ERROR_BASE_NO + 79)
|
||||||
|
#define ELIBBAD (ERROR_BASE_NO + 80)
|
||||||
|
#define ELIBSCN (ERROR_BASE_NO + 81)
|
||||||
|
#define ELIBMAX (ERROR_BASE_NO + 82)
|
||||||
|
#define ELIBEXEC (ERROR_BASE_NO + 83)
|
||||||
|
|
||||||
|
#ifndef EILSEQ
|
||||||
|
#define EILSEQ (ERROR_BASE_NO + 84)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ERESTART (ERROR_BASE_NO + 85)
|
||||||
|
#define ESTRPIPE (ERROR_BASE_NO + 86)
|
||||||
|
#define EUSERS (ERROR_BASE_NO + 87)
|
||||||
|
#define ENOTSOCK (ERROR_BASE_NO + 88)
|
||||||
|
#define EDESTADDRREQ (ERROR_BASE_NO + 89)
|
||||||
|
#define EMSGSIZE (ERROR_BASE_NO + 90)
|
||||||
|
#define EPROTOTYPE (ERROR_BASE_NO + 91)
|
||||||
|
#define ENOPROTOOPT (ERROR_BASE_NO + 92)
|
||||||
|
#define EPROTONOSUPPORT (ERROR_BASE_NO + 93)
|
||||||
|
#define ESOCKTNOSUPPORT (ERROR_BASE_NO + 94)
|
||||||
|
#define EOPNOTSUPP (ERROR_BASE_NO + 95)
|
||||||
|
#define ENOTSUP EOPNOTSUPP
|
||||||
|
#define EPFNOSUPPORT (ERROR_BASE_NO + 96)
|
||||||
|
#define EAFNOSUPPORT (ERROR_BASE_NO + 97)
|
||||||
|
#define EADDRINUSE (ERROR_BASE_NO + 98)
|
||||||
|
#define EADDRNOTAVAIL (ERROR_BASE_NO + 99)
|
||||||
|
#define ENETDOWN (ERROR_BASE_NO + 100)
|
||||||
|
#define ENETUNREACH (ERROR_BASE_NO + 101)
|
||||||
|
#define ENETRESET (ERROR_BASE_NO + 102)
|
||||||
|
#define ECONNABORTED (ERROR_BASE_NO + 103)
|
||||||
|
#define ECONNRESET (ERROR_BASE_NO + 104)
|
||||||
|
#define ENOBUFS (ERROR_BASE_NO + 105)
|
||||||
|
#define EISCONN (ERROR_BASE_NO + 106)
|
||||||
|
#define ENOTCONN (ERROR_BASE_NO + 107)
|
||||||
|
#define ESHUTDOWN (ERROR_BASE_NO + 108)
|
||||||
|
#define ETOOMANYREFS (ERROR_BASE_NO + 109)
|
||||||
|
#define ETIMEDOUT (ERROR_BASE_NO + 110)
|
||||||
|
#define ECONNREFUSED (ERROR_BASE_NO + 111)
|
||||||
|
#define EHOSTDOWN (ERROR_BASE_NO + 112)
|
||||||
|
#define EHOSTUNREACH (ERROR_BASE_NO + 113)
|
||||||
|
#define EALREADY (ERROR_BASE_NO + 114)
|
||||||
|
#define EINPROGRESS (ERROR_BASE_NO + 115)
|
||||||
|
#define ESTALE (ERROR_BASE_NO + 116)
|
||||||
|
#define EUCLEAN (ERROR_BASE_NO + 117)
|
||||||
|
#define ENOTNAM (ERROR_BASE_NO + 118)
|
||||||
|
#define ENAVAIL (ERROR_BASE_NO + 119)
|
||||||
|
#define EISNAM (ERROR_BASE_NO + 120)
|
||||||
|
#define EREMOTEIO (ERROR_BASE_NO + 121)
|
||||||
|
#define EDQUOT (ERROR_BASE_NO + 122)
|
||||||
|
#define ENOMEDIUM (ERROR_BASE_NO + 123)
|
||||||
|
#define EMEDIUMTYPE (ERROR_BASE_NO + 124)
|
||||||
|
#define ECANCELED (ERROR_BASE_NO + 125)
|
||||||
|
#define ENOKEY (ERROR_BASE_NO + 126)
|
||||||
|
#define EKEYEXPIRED (ERROR_BASE_NO + 127)
|
||||||
|
#define EKEYREVOKED (ERROR_BASE_NO + 128)
|
||||||
|
#define EKEYREJECTED (ERROR_BASE_NO + 129)
|
||||||
|
#define EOWNERDEAD (ERROR_BASE_NO + 130)
|
||||||
|
#define ENOTRECOVERABLE (ERROR_BASE_NO + 131)
|
||||||
|
#define ERFKILL (ERROR_BASE_NO + 132)
|
||||||
|
#define EHWPOISON (ERROR_BASE_NO + 133)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,102 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* File : libc_fcntl.h
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2018-02-07 Bernard Add O_DIRECTORY definition in NEWLIB mode.
|
||||||
|
* 2018-02-09 Bernard Add O_BINARY definition
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LIBC_FCNTL_H__
|
||||||
|
#define LIBC_FCNTL_H__
|
||||||
|
|
||||||
|
#if defined(RT_USING_NEWLIB) || defined(_WIN32)
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#ifndef O_NONBLOCK
|
||||||
|
#define O_NONBLOCK 0x4000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
#define O_ACCMODE (_O_RDONLY | _O_WRONLY | _O_RDWR)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef F_GETFL
|
||||||
|
#define F_GETFL 3
|
||||||
|
#endif
|
||||||
|
#ifndef F_SETFL
|
||||||
|
#define F_SETFL 4
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef O_DIRECTORY
|
||||||
|
#define O_DIRECTORY 0x200000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef O_BINARY
|
||||||
|
#ifdef _O_BINARY
|
||||||
|
#define O_BINARY _O_BINARY
|
||||||
|
#else
|
||||||
|
#define O_BINARY 0
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#else
|
||||||
|
#define O_RDONLY 00
|
||||||
|
#define O_WRONLY 01
|
||||||
|
#define O_RDWR 02
|
||||||
|
|
||||||
|
#define O_CREAT 0100
|
||||||
|
#define O_EXCL 0200
|
||||||
|
#define O_NOCTTY 0400
|
||||||
|
#define O_TRUNC 01000
|
||||||
|
#define O_APPEND 02000
|
||||||
|
#define O_NONBLOCK 04000
|
||||||
|
#define O_DSYNC 010000
|
||||||
|
#define O_SYNC 04010000
|
||||||
|
#define O_RSYNC 04010000
|
||||||
|
#define O_BINARY 0100000
|
||||||
|
#define O_DIRECTORY 0200000
|
||||||
|
#define O_NOFOLLOW 0400000
|
||||||
|
#define O_CLOEXEC 02000000
|
||||||
|
|
||||||
|
#define O_ASYNC 020000
|
||||||
|
#define O_DIRECT 040000
|
||||||
|
#define O_LARGEFILE 0100000
|
||||||
|
#define O_NOATIME 01000000
|
||||||
|
#define O_PATH 010000000
|
||||||
|
#define O_TMPFILE 020200000
|
||||||
|
#define O_NDELAY O_NONBLOCK
|
||||||
|
|
||||||
|
#define O_SEARCH O_PATH
|
||||||
|
#define O_EXEC O_PATH
|
||||||
|
|
||||||
|
#define O_ACCMODE (03|O_SEARCH)
|
||||||
|
|
||||||
|
#define F_DUPFD 0
|
||||||
|
#define F_GETFD 1
|
||||||
|
#define F_SETFD 2
|
||||||
|
#define F_GETFL 3
|
||||||
|
#define F_SETFL 4
|
||||||
|
|
||||||
|
#define F_SETOWN 8
|
||||||
|
#define F_GETOWN 9
|
||||||
|
#define F_SETSIG 10
|
||||||
|
#define F_GETSIG 11
|
||||||
|
|
||||||
|
#define F_GETLK 12
|
||||||
|
#define F_SETLK 13
|
||||||
|
#define F_SETLKW 14
|
||||||
|
|
||||||
|
#define F_SETOWN_EX 15
|
||||||
|
#define F_GETOWN_EX 16
|
||||||
|
|
||||||
|
#define F_GETOWNER_UIDS 17
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,64 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* File : libc_errno.h
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2017-10-30 Bernard The first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LIBC_FDSET_H__
|
||||||
|
#define LIBC_FDSET_H__
|
||||||
|
|
||||||
|
#include <rtconfig.h>
|
||||||
|
|
||||||
|
#if defined(RT_USING_NEWLIB) || defined(_WIN32)
|
||||||
|
#include <sys/types.h>
|
||||||
|
#if defined(HAVE_SYS_SELECT_H)
|
||||||
|
#include <sys/select.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#ifdef SAL_USING_POSIX
|
||||||
|
|
||||||
|
#ifdef FD_SETSIZE
|
||||||
|
#undef FD_SETSIZE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define FD_SETSIZE DFS_FD_MAX
|
||||||
|
#endif
|
||||||
|
|
||||||
|
# ifndef FD_SETSIZE
|
||||||
|
# define FD_SETSIZE 32
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# define NBBY 8 /* number of bits in a byte */
|
||||||
|
|
||||||
|
typedef long fd_mask;
|
||||||
|
# define NFDBITS (sizeof (fd_mask) * NBBY) /* bits per mask */
|
||||||
|
# ifndef howmany
|
||||||
|
# define howmany(x,y) (((x)+((y)-1))/(y))
|
||||||
|
# endif
|
||||||
|
|
||||||
|
/* We use a macro for fd_set so that including Sockets.h afterwards
|
||||||
|
can work. */
|
||||||
|
typedef struct _types_fd_set {
|
||||||
|
fd_mask fds_bits[howmany(FD_SETSIZE, NFDBITS)];
|
||||||
|
} _types_fd_set;
|
||||||
|
|
||||||
|
#define fd_set _types_fd_set
|
||||||
|
|
||||||
|
# define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1L << ((n) % NFDBITS)))
|
||||||
|
# define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1L << ((n) % NFDBITS)))
|
||||||
|
# define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1L << ((n) % NFDBITS)))
|
||||||
|
# define FD_ZERO(p) memset((void*)(p), 0, sizeof(*(p)))
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,234 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* File : libc_ioctl.h
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2017-01-21 Bernard the first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LIBC_IOCTL_H__
|
||||||
|
#define LIBC_IOCTL_H__
|
||||||
|
|
||||||
|
#define _IOC(a,b,c,d) ( ((a)<<30) | ((b)<<8) | (c) | ((d)<<16) )
|
||||||
|
#define _IOC_NONE 0U
|
||||||
|
#define _IOC_WRITE 1U
|
||||||
|
#define _IOC_READ 2U
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
#define _IO(a,b) _IOC(_IOC_NONE,(a),(b),0)
|
||||||
|
#define _IOW(a,b,c) _IOC(_IOC_WRITE,(a),(b),sizeof(c))
|
||||||
|
#define _IOR(a,b,c) _IOC(_IOC_READ,(a),(b),sizeof(c))
|
||||||
|
#define _IOWR(a,b,c) _IOC(_IOC_READ|_IOC_WRITE,(a),(b),sizeof(c))
|
||||||
|
|
||||||
|
#define FIONREAD _IOR('f', 127, int) /* get # bytes to read */
|
||||||
|
#define FIONBIO _IOW('f', 126, int) /* set/clear non-blocking i/o */
|
||||||
|
#define FIONWRITE _IOR('f', 121, int) /* get # bytes outstanding
|
||||||
|
* in send queue. */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define TCGETS 0x5401
|
||||||
|
#define TCSETS 0x5402
|
||||||
|
#define TCSETSW 0x5403
|
||||||
|
#define TCSETSF 0x5404
|
||||||
|
#define TCGETA 0x5405
|
||||||
|
#define TCSETA 0x5406
|
||||||
|
#define TCSETAW 0x5407
|
||||||
|
#define TCSETAF 0x5408
|
||||||
|
#define TCSBRK 0x5409
|
||||||
|
#define TCXONC 0x540A
|
||||||
|
#define TCFLSH 0x540B
|
||||||
|
#define TIOCEXCL 0x540C
|
||||||
|
#define TIOCNXCL 0x540D
|
||||||
|
#define TIOCSCTTY 0x540E
|
||||||
|
#define TIOCGPGRP 0x540F
|
||||||
|
#define TIOCSPGRP 0x5410
|
||||||
|
#define TIOCOUTQ 0x5411
|
||||||
|
#define TIOCSTI 0x5412
|
||||||
|
#define TIOCGWINSZ 0x5413
|
||||||
|
#define TIOCSWINSZ 0x5414
|
||||||
|
#define TIOCMGET 0x5415
|
||||||
|
#define TIOCMBIS 0x5416
|
||||||
|
#define TIOCMBIC 0x5417
|
||||||
|
#define TIOCMSET 0x5418
|
||||||
|
#define TIOCGSOFTCAR 0x5419
|
||||||
|
#define TIOCSSOFTCAR 0x541A
|
||||||
|
// #define FIONREAD 0x541B
|
||||||
|
#define TIOCINQ FIONREAD
|
||||||
|
#define TIOCLINUX 0x541C
|
||||||
|
#define TIOCCONS 0x541D
|
||||||
|
#define TIOCGSERIAL 0x541E
|
||||||
|
#define TIOCSSERIAL 0x541F
|
||||||
|
#define TIOCPKT 0x5420
|
||||||
|
// #define FIONBIO 0x5421
|
||||||
|
#define TIOCNOTTY 0x5422
|
||||||
|
#define TIOCSETD 0x5423
|
||||||
|
#define TIOCGETD 0x5424
|
||||||
|
#define TCSBRKP 0x5425
|
||||||
|
#define TIOCSBRK 0x5427
|
||||||
|
#define TIOCCBRK 0x5428
|
||||||
|
#define TIOCGSID 0x5429
|
||||||
|
#define TIOCGRS485 0x542E
|
||||||
|
#define TIOCSRS485 0x542F
|
||||||
|
#define TIOCGPTN 0x80045430
|
||||||
|
#define TIOCSPTLCK 0x40045431
|
||||||
|
#define TIOCGDEV 0x80045432
|
||||||
|
#define TCGETX 0x5432
|
||||||
|
#define TCSETX 0x5433
|
||||||
|
#define TCSETXF 0x5434
|
||||||
|
#define TCSETXW 0x5435
|
||||||
|
#define TIOCSIG 0x40045436
|
||||||
|
#define TIOCVHANGUP 0x5437
|
||||||
|
#define TIOCGPKT 0x80045438
|
||||||
|
#define TIOCGPTLCK 0x80045439
|
||||||
|
#define TIOCGEXCL 0x80045440
|
||||||
|
|
||||||
|
#define FIONCLEX 0x5450
|
||||||
|
#define FIOCLEX 0x5451
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
#define FIOASYNC 0x5452
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define TIOCSERCONFIG 0x5453
|
||||||
|
#define TIOCSERGWILD 0x5454
|
||||||
|
#define TIOCSERSWILD 0x5455
|
||||||
|
#define TIOCGLCKTRMIOS 0x5456
|
||||||
|
#define TIOCSLCKTRMIOS 0x5457
|
||||||
|
#define TIOCSERGSTRUCT 0x5458
|
||||||
|
#define TIOCSERGETLSR 0x5459
|
||||||
|
#define TIOCSERGETMULTI 0x545A
|
||||||
|
#define TIOCSERSETMULTI 0x545B
|
||||||
|
|
||||||
|
#define TIOCMIWAIT 0x545C
|
||||||
|
#define TIOCGICOUNT 0x545D
|
||||||
|
#define FIOQSIZE 0x5460
|
||||||
|
|
||||||
|
#define TIOCPKT_DATA 0
|
||||||
|
#define TIOCPKT_FLUSHREAD 1
|
||||||
|
#define TIOCPKT_FLUSHWRITE 2
|
||||||
|
#define TIOCPKT_STOP 4
|
||||||
|
#define TIOCPKT_START 8
|
||||||
|
#define TIOCPKT_NOSTOP 16
|
||||||
|
#define TIOCPKT_DOSTOP 32
|
||||||
|
#define TIOCPKT_IOCTL 64
|
||||||
|
|
||||||
|
#define TIOCSER_TEMT 0x01
|
||||||
|
|
||||||
|
struct winsize {
|
||||||
|
unsigned short ws_row;
|
||||||
|
unsigned short ws_col;
|
||||||
|
unsigned short ws_xpixel;
|
||||||
|
unsigned short ws_ypixel;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define TIOCM_LE 0x001
|
||||||
|
#define TIOCM_DTR 0x002
|
||||||
|
#define TIOCM_RTS 0x004
|
||||||
|
#define TIOCM_ST 0x008
|
||||||
|
#define TIOCM_SR 0x010
|
||||||
|
#define TIOCM_CTS 0x020
|
||||||
|
#define TIOCM_CAR 0x040
|
||||||
|
#define TIOCM_RNG 0x080
|
||||||
|
#define TIOCM_DSR 0x100
|
||||||
|
#define TIOCM_CD TIOCM_CAR
|
||||||
|
#define TIOCM_RI TIOCM_RNG
|
||||||
|
#define TIOCM_OUT1 0x2000
|
||||||
|
#define TIOCM_OUT2 0x4000
|
||||||
|
#define TIOCM_LOOP 0x8000
|
||||||
|
|
||||||
|
#define N_TTY 0
|
||||||
|
#define N_SLIP 1
|
||||||
|
#define N_MOUSE 2
|
||||||
|
#define N_PPP 3
|
||||||
|
#define N_STRIP 4
|
||||||
|
#define N_AX25 5
|
||||||
|
#define N_X25 6
|
||||||
|
#define N_6PACK 7
|
||||||
|
#define N_MASC 8
|
||||||
|
#define N_R3964 9
|
||||||
|
#define N_PROFIBUS_FDL 10
|
||||||
|
#define N_IRDA 11
|
||||||
|
#define N_SMSBLOCK 12
|
||||||
|
#define N_HDLC 13
|
||||||
|
#define N_SYNC_PPP 14
|
||||||
|
#define N_HCI 15
|
||||||
|
|
||||||
|
#define FIOSETOWN 0x8901
|
||||||
|
#define SIOCSPGRP 0x8902
|
||||||
|
#define FIOGETOWN 0x8903
|
||||||
|
#define SIOCGPGRP 0x8904
|
||||||
|
// #define SIOCATMARK 0x8905
|
||||||
|
#define SIOCGSTAMP 0x8906
|
||||||
|
#define SIOCGSTAMPNS 0x8907
|
||||||
|
|
||||||
|
#define SIOCADDRT 0x890B
|
||||||
|
#define SIOCDELRT 0x890C
|
||||||
|
#define SIOCRTMSG 0x890D
|
||||||
|
|
||||||
|
#define SIOCGIFNAME 0x8910
|
||||||
|
#define SIOCSIFLINK 0x8911
|
||||||
|
#define SIOCGIFCONF 0x8912
|
||||||
|
#define SIOCGIFFLAGS 0x8913
|
||||||
|
#define SIOCSIFFLAGS 0x8914
|
||||||
|
#define SIOCGIFADDR 0x8915
|
||||||
|
#define SIOCSIFADDR 0x8916
|
||||||
|
#define SIOCGIFDSTADDR 0x8917
|
||||||
|
#define SIOCSIFDSTADDR 0x8918
|
||||||
|
#define SIOCGIFBRDADDR 0x8919
|
||||||
|
#define SIOCSIFBRDADDR 0x891a
|
||||||
|
#define SIOCGIFNETMASK 0x891b
|
||||||
|
#define SIOCSIFNETMASK 0x891c
|
||||||
|
#define SIOCGIFMETRIC 0x891d
|
||||||
|
#define SIOCSIFMETRIC 0x891e
|
||||||
|
#define SIOCGIFMEM 0x891f
|
||||||
|
#define SIOCSIFMEM 0x8920
|
||||||
|
#define SIOCGIFMTU 0x8921
|
||||||
|
#define SIOCSIFMTU 0x8922
|
||||||
|
#define SIOCSIFNAME 0x8923
|
||||||
|
#define SIOCSIFHWADDR 0x8924
|
||||||
|
#define SIOCGIFENCAP 0x8925
|
||||||
|
#define SIOCSIFENCAP 0x8926
|
||||||
|
#define SIOCGIFHWADDR 0x8927
|
||||||
|
#define SIOCGIFSLAVE 0x8929
|
||||||
|
#define SIOCSIFSLAVE 0x8930
|
||||||
|
#define SIOCADDMULTI 0x8931
|
||||||
|
#define SIOCDELMULTI 0x8932
|
||||||
|
#define SIOCGIFINDEX 0x8933
|
||||||
|
#define SIOGIFINDEX SIOCGIFINDEX
|
||||||
|
#define SIOCSIFPFLAGS 0x8934
|
||||||
|
#define SIOCGIFPFLAGS 0x8935
|
||||||
|
#define SIOCDIFADDR 0x8936
|
||||||
|
#define SIOCSIFHWBROADCAST 0x8937
|
||||||
|
#define SIOCGIFCOUNT 0x8938
|
||||||
|
|
||||||
|
#define SIOCGIFBR 0x8940
|
||||||
|
#define SIOCSIFBR 0x8941
|
||||||
|
|
||||||
|
#define SIOCGIFTXQLEN 0x8942
|
||||||
|
#define SIOCSIFTXQLEN 0x8943
|
||||||
|
|
||||||
|
#define SIOCDARP 0x8953
|
||||||
|
#define SIOCGARP 0x8954
|
||||||
|
#define SIOCSARP 0x8955
|
||||||
|
|
||||||
|
#define SIOCDRARP 0x8960
|
||||||
|
#define SIOCGRARP 0x8961
|
||||||
|
#define SIOCSRARP 0x8962
|
||||||
|
|
||||||
|
#define SIOCGIFMAP 0x8970
|
||||||
|
#define SIOCSIFMAP 0x8971
|
||||||
|
|
||||||
|
#define SIOCADDDLCI 0x8980
|
||||||
|
#define SIOCDELDLCI 0x8981
|
||||||
|
|
||||||
|
#define SIOCDEVPRIVATE 0x89F0
|
||||||
|
#define SIOCPROTOPRIVATE 0x89E0
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue