Compare commits

..

49 Commits

Author SHA1 Message Date
Copilot
30e1e5e9dc Reorganize Group names in build system for clarity and IDE integration #10923 2025-11-16 11:40:53 +08:00
Chuan
ae2a5758bc bsp: k230: add spi driver
Requirement: The BSP for the k230 platform in the RT-Thread repository does not yet have an spi driver.

Solution: Provide spi driver for the k230 platform in the RT-Thread repository.

- Supports SPI0(OSPI) controller with 1/2/4/8 data lines.
- Supports SPI1(QSPI0) and SPI2(QSPI1) controllers with 1/2/4 data lines.
- Implements DMA-based transfers for OSPI, QSPI, and DSPI modes.
- Falls back to standard IRQ-driven transfers for legacy SPI mode (single line).
- Updates documentation in bsp/README.md

Signed-off-by: ChuanN-sudo <fjchuanil@gmail.com>
2025-11-16 11:37:32 +08:00
Chuan
ee20484759 docs(utest):Add standardized documentation for Drivers Core Test
Signed-off-by: ChuanN-sudo <fjchuanil@gmail.com>
2025-11-16 10:28:46 +08:00
ibvqeibob
4e41e700f0 doxygen: add comments for lwp shared memory APIs
Add Doxygen-style comments for the lwp shared memory public APIs
in components/lwp/lwp_shm.c and the related control structure.
This change is documentation-only and does not modify any runtime
behavior or logic.

Signed-off-by: ibvqeibob <2601187225@qq.com>
2025-11-15 14:20:36 +08:00
CYFS
327006cb88 [docs][utest]:Add standardized utest documentation block for serialv2_tc 2025-11-15 14:18:44 +08:00
CYFS
92377190ba [docs][utest]:Add standardized utest documentation block for slab_tc 2025-11-14 23:32:08 +08:00
CYFS
b53293863d [docs][utest]:Add standardized utest documentation block for object_tc 2025-11-14 12:44:52 +08:00
CYFS
6a5489f947 [docs][utest]:Add standardized utest documentation block for mem_tc 2025-11-14 12:43:09 +08:00
CYFS
832fe803df [docs][utest]:Add standardized utest documentation block for memheap_tc 2025-11-14 12:43:09 +08:00
MuChenger
8286196d9f [bsp/xuantie][fix] 修正Bsp Kconfig配置 2025-11-13 18:44:24 +08:00
Ze-Hou
ec5e72c59a feature: utest: add standardized utest documentation to thread_tc
Signed-off-by: Ze-Hou <yingkezhou@qq.com>
2025-11-13 18:42:13 +08:00
Ze-Hou
538e5ff6d5 feature: utest: add standardized utest documentation to hooklist_tc
Signed-off-by: Ze-Hou <yingkezhou@qq.com>
2025-11-13 16:23:15 +08:00
wdfk-prog
ddfe2cd61c feat[spi]: enable interrupt-safe operations using spinlocks 2025-11-13 15:41:41 +08:00
wdfk-prog
ec27e09df8 feat:[stm32][can]: enhance control logic and refactor sendmsg 2025-11-13 15:31:05 +08:00
wdfk-prog
f56875fff5 fix[components]: 修复日志输出的gcc编译警告 2025-11-13 15:16:49 +08:00
rcitach
9150317539 Fixed PWM assertion error caused by using DM 2025-11-13 11:11:59 +08:00
westcity-YOLO
32d2cf17c7 clang format ignore migration 2025-11-13 10:33:25 +08:00
R b b666
0d78fa460e [BSP][Documentation] Add comprehensive BSP driver support summary table (#10925)
* List of RT-Thread BSP Support Additions.
2025-11-13 09:55:13 +08:00
Yonggang Luo
a81023b88d [components/ktime]: Remove unused rt_ktime_cputimer_getstep
Can use rt_ktime_cputimer_getfrq() / RT_TICK_PER_SECOND instead.
2025-11-12 12:59:29 +08:00
Copilot
e525c38cb8 [libcpu][cortex-a] Refactor FPU stack initialization for maintainability (#10919)
* Initial plan

* [libcpu][cortex-a] Improve FPU stack initialization implementation

Co-authored-by: BernardXiong <1241087+BernardXiong@users.noreply.github.com>

* [libcpu][cortex-a] Replace FPU init loop with rt_memset

Co-authored-by: BernardXiong <1241087+BernardXiong@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: BernardXiong <1241087+BernardXiong@users.noreply.github.com>
2025-11-12 04:34:34 +08:00
Teng mengchen
284081fe4c [utest]: [signal]: Add Standardized function comment blocks. (#10914)
* [utest]: [signal]:Standardized function comment blocks have been added.

Added comments to the utest for the signal module, including: test purpose,
usage scenarios, dependency configurations, expected outcomes, and expected
behaviors.

Signed-off-by: Mengchen Teng <teng_mengchen@163.com>

* [utest]: [signal]:Correct issues including grammatical errors, spelling mistakes, and ambiguities in function names.

Fixed the issue of grammatical errors in words; changed the variable 'recive_sig' to 'receive_sig'.
Originally, rt_signal_unmask_test was testing the masking function of rt_signal_mask, while
rt_signal_mask_test was verifying whether signals could be sent correctly during unmasking——the
function names were exactly opposite to their functions. Now the two function names have been swapped,
and the corresponding comments have also been updated accordingly.After modification, it has been
verified that the signal-related utests can be executed correctly.

Signed-off-by: Mengchen Teng <teng_mengchen@163.com>

---------

Signed-off-by: Mengchen Teng <teng_mengchen@163.com>
2025-11-11 21:46:19 +08:00
Dailingxiang1
11a2f7eac6 bsp: add stm32f407-micu support
Update bsp/stm32/stm32f407-micu/rtconfig.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

Update bsp/stm32/stm32f407-micu/rtconfig.h

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

Update bsp/stm32/stm32f407-micu/project.uvproj

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

Update bsp/stm32/stm32f407-micu/project.uvproj

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

Update bsp/stm32/stm32f407-micu/board/board.h

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

add ci

Delete bsp/stm32/stm32f407-micu/project.uvgui.dlx

	modified:   MAINTAINERS
	deleted:    bsp/stm32/stm32f407-micu/figures/board.png.png
	deleted:    bsp/stm32/stm32f407-micu/project.uvopt
	modified:   bsp/stm32/stm32f407-micu/project.uvoptx
	modified:   bsp/stm32/stm32f407-micu/project.uvprojx
2025-11-11 12:35:33 +08:00
lhxj
d80c211075 docs(utest): Add standardized documentation for core.irq (irq_tc.c) (#10913)
* docs(utest): Add standardized documentation for core.irq (irq_tc.c)

Most test cases in `src/utest` lack standardized functional
documentation, as tracked in issue #10895. This leads to high
maintenance costs, difficulty for new contributors, and inefficient
code reviews.

Solution:
This patch adds the full, standardized documentation block to
`src/utest/irq_tc.c`, following the approved template.

The documentation details:
- Test Objectives and tested APIs
- Test Scenarios (for `irq_test` and `interrupt_test`)
- Verification Metrics (the `uassert` criteria)
- Dependencies (Kconfig options and hardware)
- Test Execution command and Expected Results

This makes the test case's purpose and behavior immediately clear
to future maintainers and reviewers.

Relates to #10895

Signed-off-by: lhxj <2743257167@qq.com>

* Update src/utest/irq_tc.c

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Signed-off-by: lhxj <2743257167@qq.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-10 21:49:05 +08:00
rbb666
5119fc5433 update:rtthread version number to v5.3.0 2025-11-10 16:56:22 +08:00
Rbb666
596f0a8c37 action:Fixed assertion failure when running utest/messagequeue_tc multiple times. 2025-11-10 11:25:56 +08:00
wdfk-prog
44cf90a4ef fix(can): Resolve potential race condition in message transmission
Setting the send status flag `sndchange` after calling the can->ops->sendmsg function
could lead to a race condition if a transmission timeout occurs, resulting in incorrect state handling.
This patch moves the operation of setting the `sndchange` flag to before the call to can->ops->sendmsg.
This ensures that the mailbox's status is correctly marked as "sending" before the hardware begins transmission,
making the driver's state management more robust and reliable, especially in handling exceptions like timeouts.

Additionally, new macros for CAN filter modes have been added in dev_can.h.
2025-11-08 11:52:25 +08:00
Rbb666
2c9257831e utest:Fix signal info node leak in signal_tc when running multiple times. 2025-11-08 10:41:55 +08:00
RyanCW
6e184553d1 [bsp][gd32] 串口 tx buf应该可以设置为0 (#10908) 2025-11-08 10:39:25 +08:00
CYFS
cbe9f5d82c fix:stm32 can build error (#10909) 2025-11-08 10:38:42 +08:00
ChengyangMa
5b87ac609e [libc][syscall] add detailed function comments for memory management 2025-11-07 20:52:08 -05:00
Liu Changjie
8153fe5fd9 [libc][syscalls] 新手PR任务_增加文件操作相关函数的文档注释 2025-11-07 20:50:13 -05:00
Copilot
c631b39317 [Components] Remove vbus component and realview-a8-vmm libcpu (#10863)
* Initial plan

* Remove vbus component and related code

Co-authored-by: BernardXiong <1241087+BernardXiong@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: BernardXiong <1241087+BernardXiong@users.noreply.github.com>
2025-11-07 17:03:05 +08:00
Pcb-yun
96a125ca41 [bsp] [stm32] 添加鹿小班STM32H723开发板的BSP (#10842)
* [bsp] [stm32] 添加鹿小班STM32H723开发板的BSP

* fix(bsp): 修正链接脚本中的拼写错误并启用环境变量配置

修复链接脚本中'excetion'拼写错误为'execution'
启用rtconfig.py中的环境变量配置选项

* fix(bsp): 重新添加开发板IAR、GCC链接脚本

链接脚本中包含了所有寄存器,除flash与主sarm外其余寄存器已注释

* refactor(bsp): 移除冗余的SOC_STM32H723ZGT6配置选项
2025-11-07 17:01:51 +08:00
thomax2
2e1cf8d981 utilize the clang-format-ignore mechanism in bsp/nxp 2025-11-07 17:00:33 +08:00
wdfk-prog
95f7287313 fix:[dfs]ls在文件名太长时打印出来的文件名与大小连接在一起,无法区分 2025-11-07 16:59:23 +08:00
Copilot
d39a439603 [klibc] 将函数签名与标准 libc 对齐以修复类型冲突 #10890 2025-11-07 15:48:51 +08:00
wdfk-prog
4ee00eba9b feat[ulog]: 增加 Kconfig 选项以控制 Finsh/MSH 命令 2025-11-07 11:16:46 +08:00
CYFS
934c8195f4 [serialv2]:Fixed the issue where the serialv2 terminal did not have the enable stream mode 2025-11-07 09:52:55 +08:00
RyanCW
97f316f5d0 [bsp][gd32][serial_v2] 增加GD32F5支持 (#10840)
[bsp][gd32][serial_v2] 增加 GD32F5 支持
2025-11-07 09:28:59 +08:00
wdfk-prog
55306ad133 fix(finsh): Correct stack usage display format in list_thread command 2025-11-06 19:50:17 +08:00
lhxj
e3640ffc3d fix(doc): Exclude 'src/utest/perf/README.md' from Doxygen build (RT-Thread#10888)
Problem description:
The file 'src/utest/perf/README.md' was incorrectly appearing as a root-level page in the Doxygen documentation output.

Problem analysis:
This file was unintentionally included by the Doxygen build process following commit 7499790. It is an internal README for performance tests and is not intended to be part of the generated documentation.

Solution:
The issue is resolved by explicitly excluding this file from the build. The path '../src/utest/perf/README.md' has been added to the EXCLUDE list in both 'documentation/Doxyfile.1.9.1' and 'documentation/Doxyfile.1.9.8'.

This issue was originally introduced by the following commit:
Commit: 7499790
Title: utest: core: move perf testcase from example to src

Signed-off-by: lhxj <2743257167@qq.com>
2025-11-06 10:43:28 +08:00
kurisaw
fa6f86eda3 [ci]: disable the post-ci-status enabling option for regarding the relevant CI 2025-11-04 11:16:13 +08:00
Yuqiang Wang
925eab78df [ci]: disable auto-run status ci 2025-11-04 08:22:42 +08:00
CYFS
e458c0df7e Add a token to fix the 403 error 2025-11-02 16:31:46 +08:00
Yucai Liu
c91a7f46f5 [libcpu/arm/cortex-m33]: Fix incorrect CPU architecture in GCC context switch
The context_gcc.S file was incorrectly marked as cortex-m4 in both the
doxygen comment and .cpu directive, while the IAR and KEIL versions
correctly specify cortex-m33. This file uses ARMv8-M specific features
(PSPLIM register, TrustZone support) that are not available in Cortex-M4.

Changes:
- Update doxygen group from cortex-m4 to cortex-m33
- Change .cpu directive from cortex-m4 to cortex-m33
2025-11-02 16:23:31 +08:00
CYFS
d3ba09a0d7 [log]Update V5.2.2 Released Changelog. 2025-10-31 16:36:32 +08:00
Yuqiang Wang
ba509f92c2 [ci]: Introduce a regular inspection mechanism for abnormal CI reports (#10852) 2025-10-30 09:19:36 +08:00
Ze-Hou
666fa243f2 feature: k230: Add other existing drivers to the ci.attachconfig.yml file (#10869)
Resolve issue #10857

Signed-off-by: Ze-Hou <yingkezhou@qq.com>
2025-10-30 06:20:37 +08:00
Copilot
a10922b01b [Feature] Add automated CI results comment to pull requests (#10856)
* Initial plan

* Add CI results comment workflow

Co-authored-by: supperthomas <60349489+supperthomas@users.noreply.github.com>

* Improve CI results comment formatting and PR detection

Co-authored-by: supperthomas <60349489+supperthomas@users.noreply.github.com>

* Add documentation for CI results comment feature

Co-authored-by: supperthomas <60349489+supperthomas@users.noreply.github.com>

* Add ToolsCI and pkgs_test to monitored workflows

Co-authored-by: supperthomas <60349489+supperthomas@users.noreply.github.com>

* Add immediate CI status comment via direct workflow integration

Co-authored-by: supperthomas <60349489+supperthomas@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: supperthomas <60349489+supperthomas@users.noreply.github.com>
2025-10-30 06:18:47 +08:00
430 changed files with 33607 additions and 5948 deletions

View File

@@ -160,6 +160,7 @@
"stm32/stm32f407-atk-explorer",
"stm32/stm32f407-robomaster-c",
"stm32/stm32f407-st-discovery",
"stm32/stm32f407-micu",
"stm32/stm32f410-st-nucleo",
"stm32/stm32f411-st-nucleo",
"stm32/stm32f411-atk-nano",
@@ -195,6 +196,7 @@
"stm32/stm32h563-st-nucleo",
"stm32/stm32h503-st-nucleo",
"stm32/stm32h723-st-nucleo",
"stm32/stm32h723-lxb-disco",
"stm32/stm32h730-esphosted-evb",
"stm32/stm32h743-armfly-v7",
"stm32/stm32h743-atk-apollo",

139
.github/workflows/README_CI_RESULTS.md vendored Normal file
View File

@@ -0,0 +1,139 @@
# CI Results Comment Workflow
## Overview / 概述
This feature automatically posts CI test results as comments on Pull Requests, making it easier for contributors and reviewers to see the status of all CI checks at a glance.
此功能自动将 CI 测试结果作为评论发布到 Pull Request 中,使贡献者和审阅者更容易一目了然地看到所有 CI 检查的状态。
## Implementation / 实现方式
The feature uses **two complementary approaches** to ensure CI results are always visible:
该功能使用**两种互补方法**来确保 CI 结果始终可见:
### 1. Direct Workflow Integration (Immediate) / 直接工作流集成(立即生效)
Each main CI workflow includes a `post-ci-status` job that:
每个主要 CI 工作流都包含一个 `post-ci-status` 作业,它:
- ✅ Works immediately on PR branches (no merge required) / 立即在 PR 分支上生效(无需合并)
- 📝 Updates a single comment with workflow status / 使用工作流状态更新单个评论
- 🔄 Runs after each workflow completes / 在每个工作流完成后运行
**Modified Workflows:**
- `bsp_buildings.yml`
- `static_code_analysis.yml`
- `format_check.yml`
- `utest_auto_run.yml`
### 2. Workflow Run Trigger (After Merge) / 工作流运行触发器(合并后)
The `ci_results_comment.yml` workflow:
`ci_results_comment.yml` 工作流:
- ⏰ Triggers when CI workflows complete / 在 CI 工作流完成时触发
- 📊 Provides comprehensive summary of all workflows / 提供所有工作流的全面摘要
- 🔍 Shows detailed job-level information / 显示详细的作业级信息
- ⚠️ **Only works after merged to master** / **仅在合并到 master 后才有效**
## Features / 功能特性
1. **Automatic Updates / 自动更新**: The comment is automatically created when CI workflows complete and updated as new workflows finish.
/ 当 CI 工作流完成时自动创建评论,并在新工作流完成时更新。
2. **Comprehensive Summary / 全面总结**: Shows the status of all major CI workflows including:
/ 显示所有主要 CI 工作流的状态,包括:
- RT-Thread BSP Static Build Check / BSP 静态构建检查
- Static code analysis / 静态代码分析
- Check File Format and License / 文件格式和许可证检查
- utest_auto_run / 单元测试自动运行
3. **Status Indicators / 状态指示器**:
- ✅ Success / 成功
- ❌ Failure / 失败
- 🟠 Queued / 排队中
- 🟡 In Progress / 进行中
- ⏭️ Skipped / 已跳过
4. **Detailed Information / 详细信息**: Expandable sections show individual job results within each workflow.
/ 可展开的部分显示每个工作流中的各个作业结果。
## How It Works / 工作原理
1. The workflow is triggered when any of the monitored CI workflows complete.
/ 当任何受监控的 CI 工作流完成时,将触发此工作流。
2. It collects the status of all workflows and jobs for the associated Pull Request.
/ 它收集关联 Pull Request 的所有工作流和作业的状态。
3. A formatted comment is posted (or updated if one already exists) with the current CI status.
/ 发布(或更新已存在的)格式化评论,显示当前 CI 状态。
## Comment Format / 评论格式
The comment includes:
评论包括:
- **Overall Summary / 总体摘要**: Quick statistics showing count of passed, failed, queued, in-progress, and skipped workflows.
/ 快速统计数据,显示通过、失败、排队、进行中和跳过的工作流数量。
- **Detailed Results / 详细结果**: Collapsible sections for each workflow with links to individual jobs.
/ 每个工作流的可折叠部分,包含指向各个作业的链接。
## Benefits / 优势
1. **Visibility / 可见性**: Contributors can immediately see which CI checks have passed or failed without navigating to the Actions tab.
/ 贡献者无需导航到 Actions 选项卡即可立即查看哪些 CI 检查通过或失败。
2. **Efficiency / 效率**: Reviewers can quickly assess the CI status before reviewing the code.
/ 审阅者可以在审查代码之前快速评估 CI 状态。
3. **Transparency / 透明度**: All stakeholders have a clear view of the PR's CI status.
/ 所有利益相关者都可以清楚地了解 PR 的 CI 状态。
## Permissions Required / 所需权限
The workflow requires the following permissions:
工作流需要以下权限:
- `pull-requests: write` - To create and update comments / 创建和更新评论
- `issues: write` - To post comments on PR issues / 在 PR 问题上发布评论
- `actions: read` - To read workflow run status / 读取工作流运行状态
- `checks: read` - To read check run status / 读取检查运行状态
## Configuration / 配置
The workflow monitors the following workflows by default:
工作流默认监控以下工作流:
```yaml
workflows:
- "RT-Thread BSP Static Build Check"
- "Static code analysis"
- "Check File Format and License"
- "utest_auto_run"
```
To add more workflows to monitor, edit the `.github/workflows/ci_results_comment.yml` file and add workflow names to the `workflows` list.
要监控更多工作流,请编辑 `.github/workflows/ci_results_comment.yml` 文件并将工作流名称添加到 `workflows` 列表中。
## Troubleshooting / 故障排除
### Comment not appearing / 评论未出现
1. Ensure the workflow has the required permissions / 确保工作流具有所需权限
2. Check that the PR is from a branch in the repository (not a fork) / 检查 PR 是否来自存储库中的分支(而非分支)
3. Verify the workflow is enabled in the repository settings / 验证工作流在存储库设置中已启用
### Comment not updating / 评论未更新
1. The comment updates when a monitored workflow completes / 当受监控的工作流完成时,评论会更新
2. Check the Actions tab to see if the workflow is running / 检查 Actions 选项卡以查看工作流是否正在运行
3. Look for errors in the workflow logs / 在工作流日志中查找错误
## Contributing / 贡献
Contributions to improve this workflow are welcome! Please follow the standard contribution process outlined in the CONTRIBUTING.md file.
欢迎改进此工作流的贡献!请遵循 CONTRIBUTING.md 文件中概述的标准贡献流程。

View File

@@ -13,9 +13,6 @@ name: RT-Thread BSP Static Build Check
# Controls when the action will run. Triggers the workflow on push or pull request
# events but only for the RT-Thread organization master branch
on:
# Runs at 16:00 UTC (BeiJing 00:00) every day
schedule:
- cron: '0 16 * * *'
push:
branches:
- master
@@ -46,6 +43,12 @@ on:
types:
- online-pkgs-static-building-trigger-event
workflow_dispatch:
inputs:
trigger_type:
description: '触发类型'
required: false
default: 'manual'
type: string
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
@@ -288,4 +291,17 @@ jobs:
uses: actions/upload-artifact@main
with:
name: 00_all_bsp_output_${{ github.sha }}
path: output/
path: output/
# # Post CI status to PR comment
# post-ci-status:
# needs: build
# if: always() && github.event_name == 'pull_request' && github.repository_owner == 'RT-Thread'
# uses: ./.github/workflows/post_ci_status.yml
# with:
# workflow_name: "RT-Thread BSP Static Build Check"
# workflow_status: ${{ needs.build.result }}
# pr_number: ${{ github.event.pull_request.number }}
# permissions:
# pull-requests: write
# issues: write

303
.github/workflows/ci_results_comment.yml vendored Normal file
View File

@@ -0,0 +1,303 @@
#
# Copyright (c) 2025, RT-Thread Development Team
#
# SPDX-License-Identifier: Apache-2.0
#
# Change Logs:
# Date Author Notes
# 2025-10-27 GitHub Copilot Post CI results to PR comments
name: CI Results Comment
# on:
# workflow_run:
# workflows:
# - "RT-Thread BSP Static Build Check"
# - "Static code analysis"
# - "Check File Format and License"
# - "utest_auto_run"
# - "ToolsCI"
# - "pkgs_test"
# types:
# - completed
permissions:
pull-requests: write
issues: write
actions: read
checks: read
jobs:
comment-ci-results:
runs-on: ubuntu-22.04
if: github.event.workflow_run.event == 'pull_request' && github.repository_owner == 'RT-Thread'
steps:
- name: Get PR number
id: get-pr
uses: actions/github-script@v7
with:
script: |
// Get PR number from workflow_run
const prNumber = context.payload.workflow_run.pull_requests[0]?.number;
if (!prNumber) {
console.log('No PR found in workflow_run');
// Fallback: search for PR by branch
const pulls = await github.rest.pulls.list({
owner: context.repo.owner,
repo: context.repo.repo,
state: 'open',
head: `${context.repo.owner}:${context.payload.workflow_run.head_branch}`
});
if (pulls.data.length === 0) {
console.log('No open PR found for this branch');
return null;
}
const pr = pulls.data[0];
console.log(`Found PR #${pr.number}`);
return pr.number;
}
console.log(`Found PR #${prNumber}`);
return prNumber;
- name: Get workflow run details
if: steps.get-pr.outputs.result != 'null'
id: workflow-details
uses: actions/github-script@v7
with:
script: |
const prNumber = ${{ steps.get-pr.outputs.result }};
if (!prNumber) {
return { success: false, message: 'No PR found' };
}
// Get all workflow runs for this PR
const workflowRuns = await github.rest.actions.listWorkflowRunsForRepo({
owner: context.repo.owner,
repo: context.repo.repo,
event: 'pull_request',
per_page: 100
});
// Filter runs for this specific PR
const prRuns = workflowRuns.data.workflow_runs.filter(run => {
return run.pull_requests.some(pr => pr.number === prNumber);
});
// Get the latest run for each workflow
const workflowMap = new Map();
for (const run of prRuns) {
const existing = workflowMap.get(run.name);
if (!existing || new Date(run.created_at) > new Date(existing.created_at)) {
workflowMap.set(run.name, run);
}
}
// Prepare results summary
const results = [];
for (const [name, run] of workflowMap) {
let status = '🟡';
let statusText = 'In Progress';
if (run.status === 'completed') {
if (run.conclusion === 'success') {
status = '✅';
statusText = 'Success';
} else if (run.conclusion === 'failure') {
status = '❌';
statusText = 'Failure';
} else if (run.conclusion === 'cancelled') {
status = '⏭️';
statusText = 'Cancelled';
} else if (run.conclusion === 'skipped') {
status = '⏭️';
statusText = 'Skipped';
}
} else if (run.status === 'queued') {
status = '🟠';
statusText = 'Queued';
}
results.push({
name: name,
status: status,
statusText: statusText,
url: run.html_url,
conclusion: run.conclusion,
runId: run.id
});
}
return {
success: true,
results: results,
prNumber: prNumber
};
- name: Get job details
if: steps.get-pr.outputs.result != 'null'
id: job-details
uses: actions/github-script@v7
with:
script: |
const workflowDetails = ${{ steps.workflow-details.outputs.result }};
if (!workflowDetails || !workflowDetails.success) {
return { jobs: [] };
}
const allJobs = [];
for (const result of workflowDetails.results) {
try {
const jobs = await github.rest.actions.listJobsForWorkflowRun({
owner: context.repo.owner,
repo: context.repo.repo,
run_id: result.runId,
per_page: 100
});
for (const job of jobs.data.jobs) {
let jobStatus = '⌛';
if (job.status === 'completed') {
if (job.conclusion === 'success') {
jobStatus = '✅';
} else if (job.conclusion === 'failure') {
jobStatus = '❌';
} else if (job.conclusion === 'skipped') {
jobStatus = '⏭️';
}
} else if (job.status === 'in_progress') {
jobStatus = '🔄';
} else if (job.status === 'queued') {
jobStatus = '🟠';
}
allJobs.push({
workflow: result.name,
name: job.name,
status: jobStatus,
conclusion: job.conclusion || job.status,
url: job.html_url
});
}
} catch (error) {
console.log(`Error getting jobs for workflow ${result.name}: ${error.message}`);
}
}
return { jobs: allJobs };
- name: Post or update comment
if: steps.get-pr.outputs.result != 'null'
uses: actions/github-script@v7
with:
script: |
const prNumber = ${{ steps.get-pr.outputs.result }};
const workflowDetails = ${{ steps.workflow-details.outputs.result }};
const jobDetails = ${{ steps.job-details.outputs.result }};
if (!workflowDetails || !workflowDetails.success) {
console.log('No workflow details available');
return;
}
// Prepare comment body
const now = new Date();
const timestamp = now.toISOString();
const results = workflowDetails.results;
const jobs = jobDetails.jobs || [];
let commentBody = '<!-- CI Results Comment -->\n';
commentBody += '## 🤖 CI Test Results\n\n';
commentBody += `**Last Updated:** ${timestamp}\n\n`;
commentBody += '### Test Spec & Results:\n\n';
commentBody += '✅ Success | ❌ Failure | 🟠 Queued | 🟡 Progress | ⏭️ Skipped | ⚠️ Quarantine\n\n';
// Group jobs by workflow
const jobsByWorkflow = new Map();
for (const job of jobs) {
if (!jobsByWorkflow.has(job.workflow)) {
jobsByWorkflow.set(job.workflow, []);
}
jobsByWorkflow.get(job.workflow).push(job);
}
// Calculate overall statistics
let totalSuccess = 0;
let totalFailure = 0;
let totalQueued = 0;
let totalProgress = 0;
let totalSkipped = 0;
for (const result of results) {
if (result.conclusion === 'success') totalSuccess++;
else if (result.conclusion === 'failure') totalFailure++;
else if (result.statusText === 'Queued') totalQueued++;
else if (result.statusText === 'In Progress') totalProgress++;
else if (result.conclusion === 'skipped' || result.conclusion === 'cancelled') totalSkipped++;
}
// Summary line
commentBody += '#### Overall Summary\n\n';
commentBody += `- ✅ **Success:** ${totalSuccess}\n`;
commentBody += `- ❌ **Failure:** ${totalFailure}\n`;
commentBody += `- 🟠 **Queued:** ${totalQueued}\n`;
commentBody += `- 🟡 **In Progress:** ${totalProgress}\n`;
commentBody += `- ⏭️ **Skipped:** ${totalSkipped}\n\n`;
commentBody += '---\n\n';
commentBody += '### Detailed Results\n\n';
// Build detailed results
for (const result of results) {
commentBody += `<details>\n`;
commentBody += `<summary>${result.status} <strong>${result.name}</strong> - ${result.statusText}</summary>\n\n`;
commentBody += `**Workflow:** [${result.name}](${result.url})\n\n`;
// Show jobs for this workflow
const workflowJobs = jobsByWorkflow.get(result.name) || [];
if (workflowJobs.length > 0) {
commentBody += '**Jobs:**\n\n';
for (const job of workflowJobs) {
commentBody += `- ${job.status} [${job.name}](${job.url})\n`;
}
}
commentBody += '\n</details>\n\n';
}
commentBody += '\n---\n';
commentBody += '*🤖 This comment is automatically generated and updated by the CI system.*\n';
// Check if comment already exists
const comments = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber
});
const existingComment = comments.data.find(comment =>
comment.user.login === 'github-actions[bot]' &&
comment.body.includes('<!-- CI Results Comment -->')
);
if (existingComment) {
// Update existing comment
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: existingComment.id,
body: commentBody
});
console.log(`Updated comment ${existingComment.id} on PR #${prNumber}`);
} else {
// Create new comment
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
body: commentBody
});
console.log(`Created new comment on PR #${prNumber}`);
}

View File

@@ -29,4 +29,17 @@ jobs:
shell: bash
run: |
pip install click chardet PyYaml
python tools/ci/file_check.py check 'https://github.com/RT-Thread/rt-thread' 'master'
python tools/ci/file_check.py check 'https://github.com/RT-Thread/rt-thread' 'master'
# # Post CI status to PR comment
# post-ci-status:
# needs: scancode_job
# if: always() && github.event_name == 'pull_request' && github.repository_owner == 'RT-Thread'
# uses: ./.github/workflows/post_ci_status.yml
# with:
# workflow_name: "Check File Format and License"
# workflow_status: ${{ needs.scancode_job.result }}
# pr_number: ${{ github.event.pull_request.number }}
# permissions:
# pull-requests: write
# issues: write

110
.github/workflows/post_ci_status.yml vendored Normal file
View File

@@ -0,0 +1,110 @@
#
# Copyright (c) 2025, RT-Thread Development Team
#
# SPDX-License-Identifier: Apache-2.0
#
# Change Logs:
# Date Author Notes
# 2025-10-27 GitHub Copilot Reusable workflow to post CI status
name: Post CI Status Comment
# on:
# workflow_call:
# inputs:
# workflow_name:
# description: 'Name of the workflow'
# required: true
# type: string
# workflow_status:
# description: 'Status of the workflow (success/failure)'
# required: true
# type: string
# pr_number:
# description: 'Pull request number'
# required: true
# type: number
permissions:
pull-requests: write
issues: write
jobs:
post-comment:
runs-on: ubuntu-22.04
if: github.repository_owner == 'RT-Thread'
steps:
- name: Post or update CI status comment
uses: actions/github-script@v7
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
script: |
const prNumber = ${{ inputs.pr_number }};
const workflowName = '${{ inputs.workflow_name }}';
const workflowStatus = '${{ inputs.workflow_status }}';
// Status emoji mapping
const statusEmoji = workflowStatus === 'success' ? '✅' : '❌';
const timestamp = new Date().toISOString();
// Try to find existing comment
const comments = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber
});
const botComment = comments.data.find(comment =>
comment.user.login === 'github-actions[bot]' &&
comment.body.includes('<!-- CI Status Comment -->')
);
// Get all workflow runs for this PR to build comprehensive status
let allStatuses = {};
if (botComment) {
// Parse existing statuses from comment
const statusRegex = /- (✅|❌|🟡) \*\*(.+?)\*\*/g;
let match;
while ((match = statusRegex.exec(botComment.body)) !== null) {
allStatuses[match[2]] = match[1];
}
}
// Update current workflow status
allStatuses[workflowName] = statusEmoji;
// Build comment body
let commentBody = '<!-- CI Status Comment -->\n';
commentBody += '## 🤖 CI Test Results\n\n';
commentBody += `**Last Updated:** ${timestamp}\n\n`;
commentBody += '### Workflow Status:\n\n';
for (const [name, emoji] of Object.entries(allStatuses)) {
commentBody += `- ${emoji} **${name}**\n`;
}
commentBody += '\n---\n';
commentBody += '✅ Success | ❌ Failure | 🟡 In Progress\n\n';
commentBody += '*This comment is automatically updated as CI workflows complete.*\n';
if (botComment) {
// Update existing comment
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: botComment.id,
body: commentBody
});
console.log(`Updated comment ${botComment.id} on PR #${prNumber}`);
} else {
// Create new comment
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
body: commentBody
});
console.log(`Created new comment on PR #${prNumber}`);
}

View File

@@ -0,0 +1,200 @@
name: Weekly CI Scheduler
on:
# Runs at 08:00 Beijing time every day
schedule:
- cron: '0 0 * * *'
workflow_dispatch:
inputs:
debug:
description: 'Debug mode'
required: false
default: 'false'
env:
TARGET_WORKFLOWS: '["RT-Thread BSP Static Build Check", "utest_auto_run"]'
DISCUSSION_CATEGORY: "Github Action Exception Reports"
jobs:
trigger-and-monitor:
name: Trigger and Monitor CIs
runs-on: ubuntu-latest
outputs:
failed_workflows: ${{ steps.collect-results.outputs.failed_workflows }}
total_workflows: ${{ steps.collect-results.outputs.total_workflows }}
has_results: ${{ steps.collect-results.outputs.has_results }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install Python dependencies
run: |
python -m pip install --upgrade pip
pip install requests
- name: Record start time
id: start-time
run: |
echo "start_time=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_OUTPUT
echo "Start time: $(date -u +'%Y-%m-%dT%H:%M:%SZ')"
- name: Trigger CI workflows directly
id: trigger-ci
run: |
python tools/ci/scheduled-ci-trigger/trigger_workflows_direct.py
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TARGET_WORKFLOWS: ${{ env.TARGET_WORKFLOWS }}
- name: Wait for workflows to appear
id: wait-for-workflows
run: |
echo "Waiting for workflows to appear in API..."
python tools/ci/scheduled-ci-trigger/wait_for_workflows.py "${{ steps.start-time.outputs.start_time }}"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TARGET_WORKFLOWS: ${{ env.TARGET_WORKFLOWS }}
- name: Monitor CI workflows
id: monitor-ci
run: |
python tools/ci/scheduled-ci-trigger/monitor_workflows.py "${{ steps.start-time.outputs.start_time }}"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TARGET_WORKFLOWS: ${{ env.TARGET_WORKFLOWS }}
- name: Collect monitoring results
id: collect-results
run: |
echo "Checking for monitoring results..."
if [ -f "monitoring_results.json" ]; then
echo "monitoring_results.json found"
FAILED_COUNT=$(python -c "import json; data=json.load(open('monitoring_results.json')); print(len([w for w in data if w.get('conclusion') == 'failure']))")
TOTAL_COUNT=$(python -c "import json; data=json.load(open('monitoring_results.json')); print(len(data))")
echo "failed_workflows=$FAILED_COUNT" >> $GITHUB_OUTPUT
echo "total_workflows=$TOTAL_COUNT" >> $GITHUB_OUTPUT
echo "has_results=true" >> $GITHUB_OUTPUT
echo "Results: $FAILED_COUNT failed out of $TOTAL_COUNT total"
else
echo "monitoring_results.json not found"
echo "failed_workflows=0" >> $GITHUB_OUTPUT
echo "total_workflows=0" >> $GITHUB_OUTPUT
echo "has_results=false" >> $GITHUB_OUTPUT
fi
- name: Generate detailed report
if: steps.collect-results.outputs.has_results == 'true' && steps.collect-results.outputs.failed_workflows != '0'
id: generate-report
run: |
echo "Generating detailed report..."
python tools/ci/scheduled-ci-trigger/generate_report.py
echo "Report generation completed"
- name: Upload report artifact
if: steps.collect-results.outputs.has_results == 'true' && steps.collect-results.outputs.failed_workflows != '0'
uses: actions/upload-artifact@v4
with:
name: ci-failure-report
path: |
monitoring_results.json
failure_details.md
retention-days: 7
create-discussion:
name: Create Discussion Report
needs: trigger-and-monitor
if: needs.trigger-and-monitor.outputs.has_results == 'true' && needs.trigger-and-monitor.outputs.failed_workflows != '0'
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Download report artifact
uses: actions/download-artifact@v4
with:
name: ci-failure-report
- name: Create Discussion
uses: actions/github-script@v6
env:
DISCUSSION_CATEGORY: ${{ env.DISCUSSION_CATEGORY }}
with:
script: |
const fs = require('fs');
const reportPath = './failure_details.md';
let reportContent = fs.readFileSync(reportPath, 'utf8');
// 提取日期从第一行: # YYYYMMDD_ci_integration-failed-report
const lines = reportContent.split('\n');
const firstLine = lines[0].trim();
const dateMatch = firstLine.match(/# (\d{8})_ci_integration-failed-report/);
if (!dateMatch) {
console.error('Failed to extract date from first line:', firstLine);
process.exit(1);
}
const dateString = dateMatch[1];
const discussionTitle = `${dateString}_ci_integration-failed-report`;
// === 关键修复:移除第一行(用于提取的隐藏行) ===
reportContent = lines.slice(1).join('\n').trim();
// 获取仓库ID和分类ID
const getRepoQuery = `
query($owner: String!, $repo: String!) {
repository(owner: $owner, name: $repo) {
id
discussionCategories(first: 20) {
nodes {
id
name
}
}
}
}
`;
const repoData = await github.graphql(getRepoQuery, {
owner: context.repo.owner,
repo: context.repo.repo
});
const repositoryId = repoData.repository.id;
const categories = repoData.repository.discussionCategories.nodes;
const targetCategory = categories.find(cat => cat.name === process.env.DISCUSSION_CATEGORY);
if (!targetCategory) {
console.error('Category not found:', process.env.DISCUSSION_CATEGORY);
process.exit(1);
}
const createDiscussionMutation = `
mutation($repositoryId: ID!, $categoryId: ID!, $title: String!, $body: String!) {
createDiscussion(input: {
repositoryId: $repositoryId
categoryId: $categoryId
title: $title
body: $body
}) {
discussion {
id
title
url
}
}
}
`;
const result = await github.graphql(createDiscussionMutation, {
repositoryId: repositoryId,
categoryId: targetCategory.id,
title: discussionTitle,
body: reportContent // 使用清理后的内容(无第一行)
});
console.log('Discussion created successfully:', result.createDiscussion.discussion.url);

View File

@@ -54,4 +54,17 @@ jobs:
sudo make install FILESDIR=/usr/local/share/Cppcheck
cppcheck --version
cd ..
python tools/ci/cpp_check.py check
python tools/ci/cpp_check.py check
# # Post CI status to PR comment
# post-ci-status:
# needs: scancode_job
# if: always() && github.event_name == 'pull_request' && github.repository_owner == 'RT-Thread'
# uses: ./.github/workflows/post_ci_status.yml
# with:
# workflow_name: "Static code analysis"
# workflow_status: ${{ needs.scancode_job.result }}
# pr_number: ${{ github.event.pull_request.number }}
# permissions:
# pull-requests: write
# issues: write

View File

@@ -18,6 +18,13 @@ on:
- documentation/**
- '**/README.md'
- '**/README_zh.md'
workflow_dispatch:
inputs:
trigger_type:
description: '触发类型'
required: false
default: 'manual'
type: string
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
@@ -297,4 +304,16 @@ jobs:
echo "=========================================================================================="
break
fi
done
done
# # Post CI status to PR comment
# post-ci-status:
# needs: test
# if: always() && github.event_name == 'pull_request' && github.repository_owner == 'RT-Thread'
# uses: ./.github/workflows/post_ci_status.yml
# with:
# workflow_name: "utest_auto_run"
# workflow_status: ${{ needs.test.result }}
# pr_number: ${{ github.event.pull_request.number }}
# permissions:
# pull-requests: write
# issues: write

View File

@@ -147,6 +147,10 @@ tag: bsp_stm32f429-atk-apollo
path: bsp/stm32/stm32f429-atk-apollo
owners: lizhen9880(lizhen9880)<lizhen9880@126.com>
tag: bsp_stm32f407-micu
path: bsp/stm32/stm32f407-micu
owners: DaiLingxiang(Dailingxiang1)<3070269033@qq.com>
tag: bsp_stm32h723-st-nucleo
path: bsp/stm32/stm32h723-st-nucleo
owners: 下里巴人(hywing)<hywing.sir@qq.com>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,9 @@
# files format check exclude path, please follow the instructions below to modify;
# If you need to exclude an entire folder, add the folder path in dir_path;
# If you need to exclude a file, add the path to the file in file_path.
# 从 .ignore_format.yml 迁移的规则
/v85xx*/Libraries/CMSIS/
/v85xx*/Libraries/VangoV85xx*_standard_peripheral/

View File

@@ -28,6 +28,5 @@ extern int __bss_end;
#define HEAP_END (void*)(0x20000000 + 0xA0000)
void rt_hw_board_init(void);
int rt_vbus_do_init(void);
#endif

View File

@@ -34,55 +34,63 @@ menu "On-chip Peripheral Drivers"
config BSP_UART0_RX_USING_DMA
bool "Enable UART0 RX DMA"
depends on BSP_USING_UART0
select RT_SERIAL_USING_DMA
depends on BSP_USING_UART0 && RT_USING_SERIAL_V2 && RT_SERIAL_USING_DMA
default n
config BSP_UART0_TX_USING_DMA
bool "Enable UART0 TX DMA"
depends on BSP_USING_UART0
select RT_SERIAL_USING_DMA
depends on BSP_USING_UART0 && RT_USING_SERIAL_V2 && RT_SERIAL_USING_DMA
default n
config BSP_UART0_DMA_PING_BUFSIZE
int "Set UART0 RX DMA ping-pong buffer size"
range 16 65535
depends on BSP_USING_UART0 && RT_USING_SERIAL_V2 && BSP_UART0_RX_USING_DMA
default 64
config BSP_UART0_RX_BUFSIZE
int "Set UART0 RX buffer size"
range 64 65535
depends on BSP_USING_UART0 && RT_USING_SERIAL_V2
default 64
default 128
config BSP_UART0_TX_BUFSIZE
int "Set UART0 TX buffer size"
range 0 65535
depends on BSP_USING_UART0 && RT_USING_SERIAL_V2
default 0
default 128
config BSP_USING_UART1
bool "Enable UART1"
default n
default y
config BSP_UART1_RX_USING_DMA
bool "Enable UART1 RX DMA"
depends on BSP_USING_UART1
select RT_SERIAL_USING_DMA
depends on BSP_USING_UART1 && RT_USING_SERIAL_V2 && RT_SERIAL_USING_DMA
default n
config BSP_UART1_TX_USING_DMA
bool "Enable UART1 TX DMA"
depends on BSP_USING_UART1
select RT_SERIAL_USING_DMA
depends on BSP_USING_UART1 && RT_USING_SERIAL_V2 && RT_SERIAL_USING_DMA
default n
config BSP_UART1_DMA_PING_BUFSIZE
int "Set UART1 RX DMA ping-pong buffer size"
range 16 65535
depends on BSP_USING_UART1 && RT_USING_SERIAL_V2 && BSP_UART1_RX_USING_DMA
default 64
config BSP_UART1_RX_BUFSIZE
int "Set UART1 RX buffer size"
range 64 65535
depends on BSP_USING_UART1 && RT_USING_SERIAL_V2
default 64
default 128
config BSP_UART1_TX_BUFSIZE
int "Set UART1 TX buffer size"
range 0 65535
depends on BSP_USING_UART1 && RT_USING_SERIAL_V2
default 0
default 128
config BSP_USING_UART2
bool "Enable UART2"
@@ -90,27 +98,31 @@ menu "On-chip Peripheral Drivers"
config BSP_UART2_RX_USING_DMA
bool "Enable UART2 RX DMA"
depends on BSP_USING_UART2
select RT_SERIAL_USING_DMA
depends on BSP_USING_UART2 && RT_USING_SERIAL_V2 && RT_SERIAL_USING_DMA
default n
config BSP_UART2_TX_USING_DMA
bool "Enable UART2 TX DMA"
depends on BSP_USING_UART2
select RT_SERIAL_USING_DMA
depends on BSP_USING_UART2 && RT_USING_SERIAL_V2 && RT_SERIAL_USING_DMA
default n
config BSP_UART2_DMA_PING_BUFSIZE
int "Set UART2 RX DMA ping-pong buffer size"
range 16 65535
depends on BSP_USING_UART2 && RT_USING_SERIAL_V2 && BSP_UART2_RX_USING_DMA
default 64
config BSP_UART2_RX_BUFSIZE
int "Set UART2 RX buffer size"
range 64 65535
depends on BSP_USING_UART2 && RT_USING_SERIAL_V2
default 64
default 128
config BSP_UART2_TX_BUFSIZE
int "Set UART2 TX buffer size"
range 0 65535
depends on BSP_USING_UART2 && RT_USING_SERIAL_V2
default 0
default 128
config BSP_USING_UART3
bool "Enable UART3"
@@ -118,27 +130,31 @@ menu "On-chip Peripheral Drivers"
config BSP_UART3_RX_USING_DMA
bool "Enable UART3 RX DMA"
depends on BSP_USING_UART3
select RT_SERIAL_USING_DMA
depends on BSP_USING_UART3 && RT_USING_SERIAL_V2 && RT_SERIAL_USING_DMA
default n
config BSP_UART3_TX_USING_DMA
bool "Enable UART3 TX DMA"
depends on BSP_USING_UART3
select RT_SERIAL_USING_DMA
depends on BSP_USING_UART3 && RT_USING_SERIAL_V2 && RT_SERIAL_USING_DMA
default n
config BSP_UART3_DMA_PING_BUFSIZE
int "Set UART3 RX DMA ping-pong buffer size"
range 16 65535
depends on BSP_USING_UART3 && RT_USING_SERIAL_V2 && BSP_UART3_RX_USING_DMA
default 64
config BSP_UART3_RX_BUFSIZE
int "Set UART3 RX buffer size"
range 64 65535
depends on BSP_USING_UART3 && RT_USING_SERIAL_V2
default 64
default 128
config BSP_UART3_TX_BUFSIZE
int "Set UART3 TX buffer size"
range 0 65535
depends on BSP_USING_UART3 && RT_USING_SERIAL_V2
default 0
default 128
config BSP_USING_UART4
bool "Enable UART4"
@@ -146,27 +162,31 @@ menu "On-chip Peripheral Drivers"
config BSP_UART4_RX_USING_DMA
bool "Enable UART4 RX DMA"
depends on BSP_USING_UART4
select RT_SERIAL_USING_DMA
depends on BSP_USING_UART4 && RT_USING_SERIAL_V2 && RT_SERIAL_USING_DMA
default n
config BSP_UART4_TX_USING_DMA
bool "Enable UART4 TX DMA"
depends on BSP_USING_UART4
select RT_SERIAL_USING_DMA
depends on BSP_USING_UART4 && RT_USING_SERIAL_V2 && RT_SERIAL_USING_DMA
default n
config BSP_UART4_DMA_PING_BUFSIZE
int "Set UART4 RX DMA ping-pong buffer size"
range 16 65535
depends on BSP_USING_UART4 && RT_USING_SERIAL_V2 && BSP_UART4_RX_USING_DMA
default 64
config BSP_UART4_RX_BUFSIZE
int "Set UART4 RX buffer size"
range 64 65535
depends on BSP_USING_UART4 && RT_USING_SERIAL_V2
default 64
default 128
config BSP_UART4_TX_BUFSIZE
int "Set UART4 TX buffer size"
range 0 65535
depends on BSP_USING_UART4 && RT_USING_SERIAL_V2
default 0
default 128
config BSP_USING_UART5
bool "Enable UART5"
@@ -174,27 +194,31 @@ menu "On-chip Peripheral Drivers"
config BSP_UART5_RX_USING_DMA
bool "Enable UART5 RX DMA"
depends on BSP_USING_UART5
select RT_SERIAL_USING_DMA
depends on BSP_USING_UART5 && RT_USING_SERIAL_V2 && RT_SERIAL_USING_DMA
default n
config BSP_UART5_TX_USING_DMA
bool "Enable UART5 TX DMA"
depends on BSP_USING_UART5
select RT_SERIAL_USING_DMA
depends on BSP_USING_UART5 && RT_USING_SERIAL_V2 && RT_SERIAL_USING_DMA
default n
config BSP_UART5_DMA_PING_BUFSIZE
int "Set UART5 RX DMA ping-pong buffer size"
range 16 65535
depends on BSP_USING_UART5 && RT_USING_SERIAL_V2 && BSP_UART5_RX_USING_DMA
default 64
config BSP_UART5_RX_BUFSIZE
int "Set UART5 RX buffer size"
range 64 65535
depends on BSP_USING_UART5 && RT_USING_SERIAL_V2
default 64
default 128
config BSP_UART5_TX_BUFSIZE
int "Set UART5 TX buffer size"
range 0 65535
depends on BSP_USING_UART5 && RT_USING_SERIAL_V2
default 0
default 128
config BSP_USING_UART6
bool "Enable UART6"
@@ -202,55 +226,63 @@ menu "On-chip Peripheral Drivers"
config BSP_UART6_RX_USING_DMA
bool "Enable UART6 RX DMA"
depends on BSP_USING_UART6
select RT_SERIAL_USING_DMA
depends on BSP_USING_UART6 && RT_USING_SERIAL_V2 && RT_SERIAL_USING_DMA
default n
config BSP_UART6_TX_USING_DMA
bool "Enable UART6 TX DMA"
depends on BSP_USING_UART6
select RT_SERIAL_USING_DMA
depends on BSP_USING_UART6 && RT_USING_SERIAL_V2 && RT_SERIAL_USING_DMA
default n
config BSP_UART6_DMA_PING_BUFSIZE
int "Set UART6 RX DMA ping-pong buffer size"
range 16 65535
depends on BSP_USING_UART6 && RT_USING_SERIAL_V2 && BSP_UART6_RX_USING_DMA
default 64
config BSP_UART6_RX_BUFSIZE
int "Set UART6 RX buffer size"
range 64 65535
depends on BSP_USING_UART6 && RT_USING_SERIAL_V2
default 64
default 128
config BSP_UART6_TX_BUFSIZE
int "Set UART6 TX buffer size"
range 0 65535
depends on BSP_USING_UART6 && RT_USING_SERIAL_V2
default 0
default 128
config BSP_USING_UART7
config BSP_USING_UART7
bool "Enable UART7"
default n
config BSP_UART7_RX_USING_DMA
bool "Enable UART7 RX DMA"
depends on BSP_USING_UART7
select RT_SERIAL_USING_DMA
depends on BSP_USING_UART7 && RT_USING_SERIAL_V2 && RT_SERIAL_USING_DMA
default n
config BSP_UART7_TX_USING_DMA
bool "Enable UART7 TX DMA"
depends on BSP_USING_UART7
select RT_SERIAL_USING_DMA
depends on BSP_USING_UART7 && RT_USING_SERIAL_V2 && RT_SERIAL_USING_DMA
default n
config BSP_UART7_DMA_PING_BUFSIZE
int "Set UART7 RX DMA ping-pong buffer size"
range 16 65535
depends on BSP_USING_UART7 && RT_USING_SERIAL_V2 && BSP_UART7_RX_USING_DMA
default 64
config BSP_UART7_RX_BUFSIZE
int "Set UART7 RX buffer size"
range 64 65535
depends on BSP_USING_UART7 && RT_USING_SERIAL_V2
default 64
default 128
config BSP_UART7_TX_BUFSIZE
int "Set UART7 TX buffer size"
range 0 65535
depends on BSP_USING_UART7 && RT_USING_SERIAL_V2
default 0
default 128
endif
menuconfig BSP_USING_SPI

View File

@@ -263,7 +263,6 @@ static void dma_recv_isr (struct rt_serial_device *serial)
RT_ASSERT(serial != RT_NULL);
uart = rt_container_of(serial, struct gd32_uart, serial);
recv_len = 0;
level = rt_hw_interrupt_disable();
#if defined SOC_SERIES_GD32E23x
counter = dma_transfer_number_get(uart->dma.rx.channel);
@@ -297,21 +296,14 @@ static void usart_isr (struct rt_serial_device *serial)
if (usart_interrupt_flag_get(uart->periph, USART_INT_FLAG_RBNE) != RESET)
{
struct rt_serial_rx_fifo *rx_fifo;
rx_fifo = (struct rt_serial_rx_fifo *) serial->serial_rx;
RT_ASSERT(rx_fifo != RT_NULL);
char chr = usart_data_receive(uart->periph);
rt_hw_serial_control_isr(serial, RT_HW_SERIAL_CTRL_PUTC, &chr);
rt_uint8_t chr = usart_data_receive(uart->periph);
rt_hw_serial_control_isr(serial, RT_HW_SERIAL_CTRL_PUTC, (void *)&chr);
rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
/* Clear RXNE interrupt flag */
usart_interrupt_flag_clear(uart->periph, USART_INT_FLAG_RBNE);
}
else if (usart_interrupt_flag_get(uart->periph, USART_INT_FLAG_TBE) != RESET)
{
rt_uint8_t put_char = 0;
if (rt_hw_serial_control_isr(serial, RT_HW_SERIAL_CTRL_GETC, &put_char) == RT_EOK)
if (rt_hw_serial_control_isr(serial, RT_HW_SERIAL_CTRL_GETC, (void *)&put_char) == RT_EOK)
{
usart_data_transmit(uart->periph, put_char);
}
@@ -320,7 +312,6 @@ static void usart_isr (struct rt_serial_device *serial)
usart_interrupt_disable(uart->periph, USART_INT_TBE);
usart_interrupt_enable(uart->periph, USART_INT_TC);
}
usart_interrupt_flag_clear(uart->periph, USART_INT_FLAG_TBE);
}
else if (usart_interrupt_flag_get(uart->periph, USART_INT_FLAG_TC) != RESET)
{
@@ -334,10 +325,9 @@ static void usart_isr (struct rt_serial_device *serial)
#ifdef RT_SERIAL_USING_DMA
else if (usart_interrupt_flag_get(uart->periph, USART_INT_FLAG_IDLE) != RESET)
{
volatile uint8_t data = (uint8_t)usart_data_receive(uart->periph);
volatile uint8_t idle_clear_dummy = (uint8_t)usart_data_receive(uart->periph);
RT_UNUSED(idle_clear_dummy);
dma_recv_isr(serial);
usart_interrupt_flag_clear(uart->periph, USART_INT_FLAG_IDLE);
}
#endif
@@ -595,8 +585,8 @@ void UART7_IRQHandler (void)
}
#endif /* BSP_USING_UART7 */
#if define SOC_SERIES_GD32E23x
#if define BSP_UART0_RX_USING_DMA || define BSP_UART0_TX_USING_DMA
#if defined SOC_SERIES_GD32E23x
#if defined BSP_UART0_RX_USING_DMA || defined BSP_UART0_TX_USING_DMA
void DMA_Channel1_2_IRQHandler(void)
{
/* enter interrupt */
@@ -906,6 +896,9 @@ static void _uart_dma_receive (struct gd32_uart *uart, rt_uint8_t *buffer, rt_ui
dma_interrupt_enable(uart->dma.rx.channel, DMA_CHXCTL_HTFIE);
dma_interrupt_enable(uart->dma.rx.channel, DMA_CHXCTL_FTFIE);
/* enable circular mode */
dma_circulation_enable(uart->dma.rx.channel);
/* enable dma channel */
dma_channel_enable(uart->dma.rx.channel);
@@ -953,7 +946,11 @@ static void _uart_dma_receive (struct gd32_uart *uart, rt_uint8_t *buffer, rt_ui
usart_interrupt_enable(uart->periph, USART_INT_IDLE);
/* enable dma receive */
#if defined SOC_SERIES_GD32F5xx
usart_dma_receive_config(uart->periph, USART_DENR_ENABLE);
#else
usart_dma_receive_config(uart->periph, USART_RECEIVE_DMA_ENABLE);
#endif
#endif
}
@@ -972,7 +969,11 @@ static void _uart_dma_transmit (struct gd32_uart *uart, rt_uint8_t *buffer, rt_u
DMA_CHCNT(uart->dma.tx.periph, uart->dma.tx.channel) = size;
/* enable dma transmit */
#if defined SOC_SERIES_GD32F5xx
usart_dma_transmit_config(uart->periph, USART_DENT_ENABLE);
#else
usart_dma_transmit_config(uart->periph, USART_TRANSMIT_DMA_ENABLE);
#endif
/* enable dma channel */
dma_channel_enable(uart->dma.tx.periph, uart->dma.tx.channel);
@@ -1057,7 +1058,7 @@ static void gd32_dma_config (struct rt_serial_device *serial, rt_ubase_t flag)
if (flag == RT_DEVICE_FLAG_DMA_RX)
{
rt_uint8_t *ptr = NULL;
rt_hw_serial_control_isr(serial, RT_HW_SERIAL_CTRL_GET_DMA_PING_BUF, &ptr);
rt_hw_serial_control_isr(serial, RT_HW_SERIAL_CTRL_GET_DMA_PING_BUF, (void *)&ptr);
/* start dma transfer */
_uart_dma_receive(uart, ptr, serial->config.dma_ping_bufsz);

View File

@@ -32,12 +32,12 @@ struct gd32_uart
rcu_periph_enum tx_gpio_clk;
rcu_periph_enum rx_gpio_clk;
uint32_t tx_port;
#if defined SOC_SERIES_GD32F4xx || defined SOC_SERIES_GD32E23x
#if defined SOC_SERIES_GD32F4xx || defined SOC_SERIES_GD32E23x || defined SOC_SERIES_GD32F5xx
uint16_t tx_af;
#endif
uint16_t tx_pin;
uint32_t rx_port;
#if defined SOC_SERIES_GD32F4xx || defined SOC_SERIES_GD32E23x
#if defined SOC_SERIES_GD32F4xx || defined SOC_SERIES_GD32E23x || defined SOC_SERIES_GD32F5xx
uint16_t rx_af;
#endif
uint16_t rx_pin;

View File

@@ -1,9 +1,54 @@
scons.args: &scons
scons_arg:
- '--strict'
devices.spi:
<<: *scons
kconfig:
- CONFIG_RT_USING_SPI=y
- CONFIG_BSP_USING_SPI=y
- CONFIG_BSP_USING_SPI0=y
devices.i2c:
<<: *scons
kconfig:
- CONFIG_RT_USING_I2C=y
- CONFIG_BSP_USING_I2C=y
- CONFIG_BSP_USING_I2C0=y
devices.adc:
<<: *scons
kconfig:
- CONFIG_RT_USING_ADC=y
- CONFIG_BSP_USING_ADC=y
devices.hwtimer:
<<: *scons
kconfig:
- CONFIG_RT_USING_HWTIMER=y
- CONFIG_BSP_USING_TIMERS=y
- CONFIG_BSP_USING_TIMER0=y
devices.pdma:
<<: *scons
kconfig:
- CONFIG_RT_USING_PDMA=y
- CONFIG_BSP_USING_PDMA=y
- CONFIG_BSP_USING_PDMA_CHANNEL0=y
devices.pwm:
<<: *scons
kconfig:
- CONFIG_RT_USING_PWM=y
- CONFIG_BSP_USING_PWM=y
- CONFIG_BSP_USING_PWM0=y
devices.rtc:
<<: *scons
kconfig:
- CONFIG_RT_USING_RTC=y
- CONFIG_BSP_USING_RTC=y
devices.ts:
<<: *scons
kconfig:
- CONFIG_RT_USING_TS=y
- CONFIG_BSP_USING_TS=y
devices.wdt:
<<: *scons
kconfig:
- CONFIG_RT_USING_WDT=y
- CONFIG_BSP_USING_WDT=y
- CONFIG_BSP_USING_WDT0=y

View File

@@ -534,8 +534,6 @@ CONFIG_RT_USING_ADT_REF=y
# CONFIG_RT_USING_RT_LINK is not set
# end of Utilities
# CONFIG_RT_USING_VBUS is not set
#
# Memory management
#
@@ -943,6 +941,7 @@ CONFIG_RT_USING_VDSO=y
# CONFIG_PKG_USING_R_RHEALSTONE is not set
# CONFIG_PKG_USING_HEARTBEAT is not set
# CONFIG_PKG_USING_MICRO_ROS_RTTHREAD_PACKAGE is not set
# CONFIG_PKG_USING_CHERRYECAT is not set
# end of system packages
#
@@ -1100,6 +1099,12 @@ CONFIG_RT_USING_VDSO=y
# CONFIG_PKG_USING_GD32_ARM_CMSIS_DRIVER is not set
# CONFIG_PKG_USING_GD32_ARM_SERIES_DRIVER is not set
# end of GD32 Drivers
#
# HPMicro SDK
#
# CONFIG_PKG_USING_HPM_SDK is not set
# end of HPMicro SDK
# end of HAL & SDK Drivers
#
@@ -1619,6 +1624,7 @@ CONFIG_PKG_ZLIB_VER="latest"
#
# Drivers Configuration
#
# CONFIG_BSP_USING_SPI is not set
# CONFIG_BSP_USING_I2C is not set
# CONFIG_BSP_USING_RTC is not set
# CONFIG_BSP_USING_ADC is not set

View File

@@ -1,4 +1,31 @@
menu "Drivers Configuration"
menuconfig BSP_USING_SPI
bool "Enable SPI"
select RT_USING_SPI
select RT_USING_QSPI
default n
if BSP_USING_SPI
config BSP_USING_SPI0
bool "Enable SPI0"
help
Support 1, 2, 4 and 8 lines, Max clock frequency is 200 Mhz.
default n
config BSP_USING_SPI1
bool "Enable SPI1"
help
Support 1, 2, and 4 lines, Max clock frequency is 100 Mhz.
default n
config BSP_USING_SPI2
bool "Enable SPI2"
help
Support 1, 2, and 4 lines, Max clock frequency is 100 Mhz.
default n
endif
menuconfig BSP_USING_I2C
bool "Enable I2C"
select RT_USING_I2C

View File

@@ -0,0 +1,11 @@
# RT-Thread building script for SPI component
from building import *
cwd = GetCurrentDir()
src = Glob('*.c')
CPPPATH = [cwd]
group = DefineGroup('SPI', src, depend = ['BSP_USING_SPI'], CPPPATH = CPPPATH)
Return('group')

View File

@@ -0,0 +1,734 @@
/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Copyright (c) 2006-2025 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <rtthread.h>
#include <rtdevice.h>
#include "drv_spi.h"
#include <drivers/dev_spi.h>
#include <string.h>
#include "drv_gpio.h"
#include "riscv_io.h"
#include "board.h"
#include "ioremap.h"
#include "sysctl_rst.h"
#include "sysctl_clk.h"
#include "cache.h"
#define DBG_TAG "spi"
#include <rtdbg.h>
struct k230_spi_dev
{
struct rt_spi_bus dev;
void *base;
const char *name;
const char *event_name;
rt_ubase_t pa_base;
rt_uint32_t size;
rt_uint8_t idx;
rt_uint8_t rdse;
rt_uint8_t rdsd;
rt_uint8_t max_line;
rt_uint32_t max_hz;
struct rt_event event;
void *send_buf;
void *recv_buf;
rt_size_t send_length;
rt_size_t recv_length;
rt_uint8_t cell_size;
int vector;
};
static rt_err_t k230_spi_configure(struct rt_spi_device *device, struct rt_spi_configuration *configuration)
{
RT_ASSERT(device != RT_NULL);
RT_ASSERT(configuration != RT_NULL);
struct k230_spi_dev *qspi_bus = (struct k230_spi_dev *)device->bus;
k230_spi_reg_t *qspi_reg = (k230_spi_reg_t *)qspi_bus->base;
struct rt_qspi_device *dev = (struct rt_qspi_device *)device;
struct rt_qspi_configuration *qspi_cfg = &dev->config;
struct rt_spi_configuration *qspi_cfg_parent = &dev->config.parent;
rt_uint8_t dfs, mode, spi_ff;
rt_uint32_t max_hz, qspi_clk;
if (qspi_cfg->qspi_dl_width > qspi_bus->max_line || qspi_cfg->qspi_dl_width == 0)
{
return -RT_EINVAL;
}
if (qspi_cfg_parent->data_width < 4 || qspi_cfg_parent->data_width > 32)
{
return -RT_EINVAL;
}
/* Check if the clock frequency exceeds the hardware limits */
max_hz = qspi_cfg_parent->max_hz;
if (max_hz > qspi_bus->max_hz)
{
max_hz = qspi_bus->max_hz;
}
/* Get QSPI Controller Clock Frequency */
if (qspi_bus->idx == 0)
{
qspi_clk = sysctl_clk_get_leaf_freq(SYSCTL_CLK_SSI0);
}
else if (qspi_bus->idx == 1)
{
qspi_clk = sysctl_clk_get_leaf_freq(SYSCTL_CLK_SSI1);
}
else if (qspi_bus->idx == 2)
{
qspi_clk = sysctl_clk_get_leaf_freq(SYSCTL_CLK_SSI2);
}
else
{
return -RT_EINVAL;
}
/* Set SPI_FRF to config SPI mode*/
if (qspi_cfg->qspi_dl_width == 1)
{
spi_ff = SPI_FRF_STD_SPI;
}
else if (qspi_cfg->qspi_dl_width == 2)
{
spi_ff = SPI_FRF_DUAL_SPI;
}
else if (qspi_cfg->qspi_dl_width == 4)
{
spi_ff = SPI_FRF_QUAD_SPI;
}
else if (qspi_cfg->qspi_dl_width == 8)
{
spi_ff = SPI_FRF_OCT_SPI;
}
else
{
return -RT_EINVAL;
}
/*
* dfs: Data Frame Size, Write dfs into bits 8-9 of the register ctrlr0
* mode: SPI mode(CPOL and CPHA)Write mode into bits 0-4 of the register ctrlr0
*/
mode = qspi_cfg_parent->mode & RT_SPI_MODE_3;
dfs = qspi_cfg_parent->data_width - 1;
qspi_reg->ssienr = 0;
qspi_reg->ser = 0;
qspi_reg->baudr = qspi_clk / max_hz;
qspi_reg->rx_sample_delay = qspi_bus->rdse << 16 | qspi_bus->rdsd;
qspi_reg->axiawlen = SSIC_AXI_BLW << 8;
qspi_reg->axiarlen = SSIC_AXI_BLW << 8;
qspi_reg->ctrlr0 = (dfs) | (mode << 8) | (spi_ff << 22);
return RT_EOK;
}
static rt_ssize_t k230_spi_xfer(struct rt_spi_device *device, struct rt_spi_message *message)
{
struct k230_spi_dev *qspi_bus = (struct k230_spi_dev *)device->bus;
k230_spi_reg_t *qspi_reg = (k230_spi_reg_t *)qspi_bus->base;
struct rt_qspi_device *dev = (struct rt_qspi_device *)device;
struct rt_qspi_configuration *qspi_cfg = &dev->config;
struct rt_spi_configuration *qspi_cfg_parent = &dev->config.parent;
struct rt_qspi_message *msg = (struct rt_qspi_message *)message;
struct rt_spi_message *msg_parent = message;
/* Multi-line SPI transfers (2, 4, or 8 lines) DSPI QSPI OSPI */
if (msg->qspi_data_lines > 1)
{
rt_uint8_t trans_type = 0;
if (msg->qspi_data_lines > qspi_cfg->qspi_dl_width)
{
LOG_E("data line is invalid");
return 0;
}
/* Check other parameters */
if (qspi_cfg_parent->data_width & (msg->qspi_data_lines - 1))
{
LOG_E("data line and data width do not match");
return 0;
}
if (msg->instruction.qspi_lines != 1 && msg->instruction.qspi_lines != msg->qspi_data_lines)
{
LOG_E("instruction line is invalid");
return 0;
}
if (msg->address.size & 3 || msg->address.size > 32)
{
LOG_E("address size is invalid");
return 0;
}
if (msg->address.size && msg->address.qspi_lines != 1 && msg->address.qspi_lines != msg->qspi_data_lines)
{
LOG_E("address line is invalid");
return 0;
}
if (msg_parent->length > 0x10000)
{
LOG_E("data length is invalid, more than 0x10000");
return 0;
}
if (msg->instruction.qspi_lines != 1)
{
trans_type = 2;
}
if (msg->address.size)
{
if (msg->address.qspi_lines != 1)
{
trans_type = trans_type ? trans_type : 1;
}
else if (trans_type != 0)
{
LOG_E("instruction or address line is invalid");
return 0;
}
}
if (msg->dummy_cycles > 31)
{
LOG_E("dummy cycle is invalid");
return 0;
}
rt_uint8_t tmod = msg_parent->recv_buf ? SPI_TMOD_RO : SPI_TMOD_TO;
rt_size_t length = msg_parent->length;
rt_size_t txfthr = length > (SSIC_TX_ABW / 2) ? (SSIC_TX_ABW / 2) : length - 1;
rt_uint8_t cell_size = (qspi_cfg_parent->data_width + 7) >> 3;
rt_uint8_t *buf = RT_NULL;
/* Allocate buffer for DMA transfer */
if (length)
{
buf = rt_malloc_align(CACHE_ALIGN_TOP(length * cell_size), L1_CACHE_BYTES);
if (buf == RT_NULL)
{
LOG_E("alloc mem error");
return 0;
}
}
/* msg->address.size & ~0x03: Round address.size down to the nearest multiple of 4 and write it to ADDR_L[5:2] */
qspi_reg->spi_ctrlr0 = trans_type | (msg->address.size & ~0x03) | (0x2 << 8) | (msg->dummy_cycles << 11);
qspi_reg->ctrlr0 &= ~((3 << 22) | (3 << 10));
/* Config SPI frame format and transmission mode */
if (length)
{
qspi_reg->ctrlr0 |= (tmod << 10);
qspi_reg->txftlr = (txfthr << 16) | (SSIC_TX_ABW / 2);
qspi_reg->rxftlr = (SSIC_RX_ABW - 1);
qspi_reg->imr = (1 << 11) | (1 << 8);
qspi_reg->dmacr = (1 << 6) | (3 << 3) | (1 << 2);
qspi_reg->ctrlr1 = length - 1;
qspi_reg->spidr = msg->instruction.content;
qspi_reg->spiar = msg->address.content;
if (tmod == SPI_TMOD_TO)
{
rt_memcpy(buf, msg_parent->send_buf, length * cell_size);
rt_hw_cpu_dcache_clean(buf, CACHE_ALIGN_TOP(length * cell_size));
}
qspi_reg->axiar0 = (rt_uint32_t)((uint64_t)buf);
qspi_reg->axiar1 = (rt_uint32_t)((uint64_t)buf >> 32);
}
else
{
tmod = SPI_TMOD_TO;
qspi_reg->ctrlr0 |= (tmod << 10);
qspi_reg->txftlr = ((SSIC_TX_ABW - 1) << 16) | (SSIC_TX_ABW - 1);
qspi_reg->rxftlr = (SSIC_RX_ABW - 1);
qspi_reg->imr = 0;
qspi_reg->dmacr = 0;
}
rt_event_control(&qspi_bus->event, RT_IPC_CMD_RESET, 0);
qspi_reg->ser = 1;
qspi_reg->ssienr = 1;
rt_uint32_t event;
rt_err_t err;
/*
* Config QSPI address and instruction,
* if data is empty, unable dma and send address and instruction by write data register.
*/
if (length)
{
err = rt_event_recv(&qspi_bus->event, BIT(SSI_DONE) | BIT(SSI_AXIE),
RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, 1000, &event);
}
else
{
err = RT_EOK;
event = 0;
qspi_reg->dr[0] = msg->instruction.content;
length++;
if (msg->address.size)
{
qspi_reg->dr[0] = msg->address.content;
length++;
}
qspi_reg->txftlr = 0;
/* Wait for SPI transfer to complete (busy-wait) */
while ((qspi_reg->sr & 0x5) != 0x4)
{
/* Busy wait */
}
}
qspi_reg->ser = 0;
qspi_reg->ssienr = 0;
if (err == -RT_ETIMEOUT)
{
LOG_E("qspi%d transfer data timeout", qspi_bus->idx);
if (buf)
{
rt_free_align(buf);
}
return 0;
}
if (event & BIT(SSI_AXIE))
{
LOG_E("qspi%d dma error", qspi_bus->idx);
if (buf)
{
rt_free_align(buf);
}
return 0;
}
/* Read data from FIFO */
if (tmod == SPI_TMOD_RO)
{
rt_hw_cpu_dcache_invalidate(buf, CACHE_ALIGN_TOP(length * cell_size));
rt_memcpy(msg_parent->recv_buf, buf, length * cell_size);
}
if (buf)
{
rt_free_align(buf);
}
return length;
}
/* Standard SPI transfers */
else
{
if (msg_parent->length == 0)
{
return 0;
}
rt_uint8_t cell_size = (qspi_cfg_parent->data_width + 7) >> 3;
rt_size_t length = msg_parent->length;
rt_size_t count = length > 0x10000 ? 0x10000 : length;
rt_size_t send_single = 0, send_length = 0, recv_single = 0, recv_length = 0;
void *send_buf = (void *)msg_parent->send_buf;
void *recv_buf = msg_parent->recv_buf;
rt_uint8_t tmod = send_buf ? SPI_TMOD_TO : SPI_TMOD_EPROMREAD;
tmod = recv_buf ? tmod & SPI_TMOD_RO : tmod;
/* Check Qspi Parameters */
if (tmod == SPI_TMOD_EPROMREAD)
{
LOG_E("send_buf and recv_buf cannot both be empty");
return 0;
}
if (tmod == SPI_TMOD_RO && qspi_cfg_parent->data_width == 8)
{
if ((msg->address.size & 7) || (msg->dummy_cycles & 7))
{
LOG_E("instruction, address, dummy_cycles invalid");
LOG_E("For read-only mode the instruction, address, dummy_cycles must be set to zero");
LOG_E("For eeprom-read mode the instruction, address, dummy_cycles must be set to multiples of 8");
return 0;
}
else if (msg->address.size)
{
if (length > 0x10000)
{
LOG_E("For eeprom-read mode, data length cannot exceed 0x10000");
return 0;
}
tmod = SPI_TMOD_EPROMREAD;
}
}
/* Prepare the send buffer*/
if (send_buf)
{
send_single = count;
send_buf = rt_malloc(count * cell_size);
if (send_buf == RT_NULL)
{
LOG_E("alloc mem error");
return 0;
}
rt_memcpy(send_buf, msg_parent->send_buf, count * cell_size);
}
else if (tmod == SPI_TMOD_EPROMREAD)
{
send_single = 1 + msg->address.size / 8 + msg->dummy_cycles / 8;
send_buf = rt_malloc(send_single);
if (send_buf == RT_NULL)
{
LOG_E("alloc mem error");
return 0;
}
rt_uint8_t *temp = send_buf;
*temp++ = msg->instruction.content;
for (int i = msg->address.size / 8; i; i--)
{
*temp++ = msg->address.content >> ((i - 1) * 8);
}
for (int i = msg->dummy_cycles / 8; i; i--)
{
*temp++ = 0xFF;
}
}
/* Prepare the receive buffer*/
if (recv_buf)
{
recv_single = count;
recv_buf = rt_malloc(count * cell_size);
if (recv_buf == RT_NULL)
{
LOG_E("alloc mem error");
if (send_buf)
{
rt_free(send_buf);
}
return 0;
}
}
send_length = 0;
recv_length = 0;
qspi_bus->cell_size = cell_size;
qspi_bus->send_buf = send_buf;
qspi_bus->recv_buf = recv_buf;
qspi_bus->send_length = send_single;
qspi_bus->recv_length = recv_single;
qspi_reg->ctrlr0 &= ~((3 << 22) | (3 << 10));
qspi_reg->ctrlr0 |= (tmod << 10);
qspi_reg->ctrlr1 = count - 1;
qspi_reg->txftlr = ((SSIC_TX_ABW / 2) << 16) | (SSIC_TX_ABW / 2);
qspi_reg->rxftlr = count >= (SSIC_RX_ABW / 2) ? (SSIC_RX_ABW / 2 - 1) : count - 1;
qspi_reg->dmacr = 0;
/* Interrupt transmit or receive */
qspi_reg->imr = (1 << 4) | (1 << 0);
rt_event_control(&qspi_bus->event, RT_IPC_CMD_RESET, 0);
qspi_reg->ser = 1;
qspi_reg->ssienr = 1;
if (tmod == SPI_TMOD_RO)
qspi_reg->dr[0] = 0;
rt_uint32_t event;
rt_err_t err;
while (RT_TRUE)
{
/* Waiting for transfer events */
err = rt_event_recv(&qspi_bus->event, BIT(SSI_TXE) | BIT(SSI_RXF),
RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, 10000, &event);
if (err == -RT_ETIMEOUT)
{
LOG_E("qspi%d transfer data timeout", qspi_bus->idx);
length = 0;
if (send_buf)
{
rt_free(send_buf);
}
if (recv_buf)
{
rt_free(recv_buf);
}
return 0;
}
/* Handle Transmit buffer empty */
if (event & BIT(SSI_TXE))
{
send_length += send_single;
if (send_length < length && tmod <= SPI_TMOD_TO)
{
count = length - send_length;
count = count > 0x10000 ? 0x10000 : count;
rt_memcpy(send_buf, msg_parent->send_buf + send_length * cell_size, count * cell_size);
qspi_bus->send_buf = send_buf;
qspi_bus->send_length = count;
send_single = count;
qspi_reg->txftlr = ((SSIC_TX_ABW / 2) << 16) | (SSIC_TX_ABW / 2);
if (tmod == SPI_TMOD_TO)
qspi_reg->imr |= (1 << 0);
}
else if (tmod == SPI_TMOD_TO)
{
/* Wait for SPI transfer to complete (busy-wait) */
while ((qspi_reg->sr & 0x5) != 0x4)
{
/* Busy wait */
}
break;
}
}
/* Handle receive buffer full */
if (event & BIT(SSI_RXF))
{
rt_memcpy(msg_parent->recv_buf + recv_length * cell_size, recv_buf, recv_single * cell_size);
recv_length += recv_single;
if (recv_length >= length)
{
break;
}
count = length - recv_length;
count = count > 0x10000 ? 0x10000 : count;
qspi_bus->recv_buf = recv_buf;
qspi_bus->recv_length = count;
recv_single = count;
qspi_reg->rxftlr = count >= (SSIC_RX_ABW / 2) ? (SSIC_RX_ABW / 2 - 1) : count - 1;
if (tmod == SPI_TMOD_TR)
{
qspi_reg->imr |= (1 << 0) | (1 << 4);
}
else if (tmod == SPI_TMOD_RO)
{
qspi_reg->imr |= (1 << 4);
qspi_reg->ssienr = 0;
qspi_reg->ctrlr1 = count - 1;
qspi_reg->ssienr = 1;
/* Trigger two dummy transfers to restart SPI read in read-only mode.
* This is required by the hardware to ensure correct data reception.
*/
qspi_reg->dr[0] = 0;
qspi_reg->dr[0] = 0;
}
}
}
qspi_reg->ser = 0;
qspi_reg->ssienr = 0;
if (send_buf)
{
rt_free(send_buf);
}
if (recv_buf)
{
rt_free(recv_buf);
}
return length;
}
return 0;
}
static const struct rt_spi_ops k230_qspi_ops =
{
.configure = k230_spi_configure,
.xfer = k230_spi_xfer,
};
static void k230_spi_irq(int vector, void *param)
{
struct k230_spi_dev *qspi_bus = param;
k230_spi_reg_t *qspi_reg = (k230_spi_reg_t *)qspi_bus->base;
vector -= IRQN_SPI0;
vector %= (IRQN_SPI1 - IRQN_SPI0);
/* Handle transmit buffer empty interrupt */
if (vector == SSI_TXE)
{
if (qspi_bus->send_buf == RT_NULL)
{
qspi_reg->imr &= ~1;
}
else if (qspi_bus->cell_size == 1)
{
while ((qspi_bus->send_length) && (qspi_reg->sr & 2))
{
qspi_reg->dr[0] = *((rt_uint8_t *)qspi_bus->send_buf);
qspi_bus->send_buf++;
qspi_bus->send_length--;
}
}
else if (qspi_bus->cell_size == 2)
{
while ((qspi_bus->send_length) && (qspi_reg->sr & 2))
{
qspi_reg->dr[0] = *((rt_uint16_t *)qspi_bus->send_buf);
qspi_bus->send_buf += 2;
qspi_bus->send_length--;
}
}
else if (qspi_bus->cell_size == 4)
{
while ((qspi_bus->send_length) && (qspi_reg->sr & 2))
{
qspi_reg->dr[0] = *((rt_uint32_t *)qspi_bus->send_buf);
qspi_bus->send_buf += 4;
qspi_bus->send_length--;
}
}
else
{
LOG_E("qspi%d datawidth error", qspi_bus->idx);
}
if (qspi_bus->send_length == 0)
{
if (((qspi_reg->ctrlr0 >> 10) & SPI_TMOD_EPROMREAD) == SPI_TMOD_TO)
{
if (qspi_reg->txftlr)
return;
}
qspi_reg->txftlr = 0;
qspi_reg->imr &= ~1;
rt_event_send(&qspi_bus->event, BIT(SSI_TXE));
}
}
/* Handle receive buffer full interrupt */
else if (vector == SSI_RXF)
{
if (qspi_bus->recv_buf == RT_NULL)
{
qspi_reg->imr &= ~0x10;
}
else if (qspi_bus->cell_size == 1)
{
while ((qspi_bus->recv_length) && (qspi_reg->sr & 8))
{
*((rt_uint8_t *)qspi_bus->recv_buf) = qspi_reg->dr[0];
qspi_bus->recv_buf++;
qspi_bus->recv_length--;
}
}
else if (qspi_bus->cell_size == 2)
{
while ((qspi_bus->recv_length) && (qspi_reg->sr & 8))
{
*((rt_uint16_t *)qspi_bus->recv_buf) = qspi_reg->dr[0];
qspi_bus->recv_buf += 2;
qspi_bus->recv_length--;
}
}
else if (qspi_bus->cell_size == 4)
{
while ((qspi_bus->recv_length) && (qspi_reg->sr & 8))
{
*((rt_uint32_t *)qspi_bus->recv_buf) = qspi_reg->dr[0];
qspi_bus->recv_buf += 4;
qspi_bus->recv_length--;
}
}
else
{
LOG_E("qspi%d datawidth error", qspi_bus->idx);
}
if (qspi_bus->recv_length == 0)
{
qspi_reg->imr &= ~0x10;
rt_event_send(&qspi_bus->event, BIT(SSI_RXF));
}
else if (qspi_bus->recv_length <= qspi_reg->rxftlr)
{
qspi_reg->rxftlr = qspi_bus->recv_length - 1;
}
}
/* Handle transfer complete interrupt */
else if (vector == SSI_DONE)
{
/* Clear transfer done interrupt by reading donecr register */
(void)qspi_reg->donecr;
rt_event_send(&qspi_bus->event, BIT(SSI_DONE));
}
/* Handle DMA error interrupt */
else if (vector == SSI_AXIE)
{
/* Clear AXI error interrupt by reading axiecr register */
(void)qspi_reg->axiecr;
rt_event_send(&qspi_bus->event, BIT(SSI_AXIE));
}
}
static struct k230_spi_dev k230_spi_devs[] =
{
#ifdef BSP_USING_SPI0
{
.name = "spi0",
.event_name = "spi0_event",
.pa_base = SPI_OPI_BASE_ADDR,
.size = SPI_OPI_IO_SIZE,
.vector = IRQN_SPI0,
.idx = 0,
.rdse = 0,
.rdsd = 0,
.max_line = 8,
.max_hz = 200000000,
},
#endif
#ifdef BSP_USING_SPI1
{
.name = "spi1",
.event_name = "spi1_event",
.pa_base = SPI_QOPI_BASE_ADDR,
.size = SPI_QOPI_IO_SIZE / 2,
.vector = IRQN_SPI1,
.idx = 1,
.rdse = 0,
.rdsd = 0,
.max_line = 4,
.max_hz = 100000000,
},
#endif
#ifdef BSP_USING_SPI2
{
.name = "spi2",
.event_name = "spi2_event",
.pa_base = SPI_QOPI_BASE_ADDR + SPI_QOPI_IO_SIZE / 2,
.size = SPI_QOPI_IO_SIZE / 2,
.vector = IRQN_SPI2,
.idx = 2,
.rdse = 0,
.rdsd = 0,
.max_line = 4,
.max_hz = 100000000,
},
#endif
};
int rt_hw_qspi_bus_init(void)
{
rt_err_t ret;
int i;
for (i = 0; i < sizeof(k230_spi_devs) / sizeof(k230_spi_devs[0]); i++)
{
k230_spi_devs[i].base = rt_ioremap((void *)k230_spi_devs[i].pa_base, k230_spi_devs[i].size);
ret = rt_qspi_bus_register(&k230_spi_devs[i].dev, k230_spi_devs[i].name, &k230_qspi_ops);
if (ret)
{
LOG_E("%s register fail", k230_spi_devs[i].name);
return ret;
}
rt_event_init(&k230_spi_devs[i].event, k230_spi_devs[i].event_name, RT_IPC_FLAG_PRIO);
rt_hw_interrupt_install(k230_spi_devs[i].vector + SSI_TXE, k230_spi_irq, &k230_spi_devs[i], k230_spi_devs[i].name);
rt_hw_interrupt_umask(k230_spi_devs[i].vector + SSI_TXE);
rt_hw_interrupt_install(k230_spi_devs[i].vector + SSI_RXF, k230_spi_irq, &k230_spi_devs[i], k230_spi_devs[i].name);
rt_hw_interrupt_umask(k230_spi_devs[i].vector + SSI_RXF);
rt_hw_interrupt_install(k230_spi_devs[i].vector + SSI_DONE, k230_spi_irq, &k230_spi_devs[i], k230_spi_devs[i].name);
rt_hw_interrupt_umask(k230_spi_devs[i].vector + SSI_DONE);
rt_hw_interrupt_install(k230_spi_devs[i].vector + SSI_AXIE, k230_spi_irq, &k230_spi_devs[i], k230_spi_devs[i].name);
rt_hw_interrupt_umask(k230_spi_devs[i].vector + SSI_AXIE);
}
return RT_EOK;
}
INIT_DEVICE_EXPORT(rt_hw_qspi_bus_init);

View File

@@ -0,0 +1,203 @@
/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Copyright (c) 2006-2025 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __DRV_SPI_H__
#define __DRV_SPI_H__
#include <stdint.h>
#include <stdbool.h>
#define SSIC_HAS_DMA 2
#define SSIC_AXI_BLW 8
#define SSIC_TX_ABW 256
#define SSIC_RX_ABW 256
#define IRQN_SPI0 146
#define IRQN_SPI1 155
#define IRQN_SPI2 164
#ifndef L1_CACHE_BYTES
#define L1_CACHE_BYTES 64
#endif
#define CACHE_ALIGN_TOP(x) (((x) + L1_CACHE_BYTES - 1) & ~(L1_CACHE_BYTES - 1))
#define CACHE_ALIGN_BOTTOM(x) ((x) & ~(L1_CACHE_BYTES - 1))
#define BIT(n) (1UL << (n))
enum
{
SSI_TXE = 0,
SSI_TXO,
SSI_RXF,
SSI_RXO,
SSI_TXU,
SSI_RXU,
SSI_MST,
SSI_DONE,
SSI_AXIE,
};
/* SPI mode */
enum
{
SPI_FRF_STD_SPI,
SPI_FRF_DUAL_SPI,
SPI_FRF_QUAD_SPI,
SPI_FRF_OCT_SPI,
};
/* SPI transmit mode */
enum
{
SPI_TMOD_TR,
SPI_TMOD_TO,
SPI_TMOD_RO,
SPI_TMOD_EPROMREAD,
};
/* Qspi register */
typedef struct
{
/* SPI Control Register 0 (0x00)*/
volatile uint32_t ctrlr0;
/* SPI Control Register 1 (0x04)*/
volatile uint32_t ctrlr1;
/* SPI Enable Register (0x08)*/
volatile uint32_t ssienr;
/* SPI Microwire Control Register (0x0c)*/
volatile uint32_t mwcr;
/* SPI Slave Enable Register (0x10)*/
volatile uint32_t ser;
/* SPI Baud Rate Select (0x14)*/
volatile uint32_t baudr;
/* SPI Transmit FIFO Threshold Level (0x18)*/
volatile uint32_t txftlr;
/* SPI Receive FIFO Threshold Level (0x1c)*/
volatile uint32_t rxftlr;
/* SPI Transmit FIFO Level Register (0x20)*/
volatile uint32_t txflr;
/* SPI Receive FIFO Level Register (0x24)*/
volatile uint32_t rxflr;
/* SPI Status Register (0x28)*/
volatile uint32_t sr;
/* SPI Interrupt Mask Register (0x2c)*/
volatile uint32_t imr;
/* SPI Interrupt Status Register (0x30)*/
volatile uint32_t isr;
/* SPI Raw Interrupt Status Register (0x34)*/
volatile uint32_t risr;
/* SPI Transmit FIFO Underflow Interrupt Clear Register (0x38)*/
volatile uint32_t txeicr;
/* SPI Receive FIFO Overflow Interrupt Clear Register (0x3c)*/
volatile uint32_t rxoicr;
/* SPI Receive FIFO Underflow Interrupt Clear Register (0x40)*/
volatile uint32_t rxuicr;
/* SPI Multi-Master Interrupt Clear Register (0x44)*/
volatile uint32_t msticr;
/* SPI Interrupt Clear Register (0x48)*/
volatile uint32_t icr;
/* SPI DMA Control Register (0x4c)*/
volatile uint32_t dmacr;
#if SSIC_HAS_DMA == 1
/* SPI DMA Transmit Data Level (0x50)*/
volatile uint32_t dmatdlr;
/* SPI DMA Receive Data Level (0x54)*/
volatile uint32_t dmardlr;
#elif SSIC_HAS_DMA == 2
/* SPI Destination Burst Length (0x50)*/
volatile uint32_t axiawlen;
/* SPI Source Burst Length (0x54)*/
volatile uint32_t axiarlen;
#else
uint32_t resv0[2];
#endif
/* SPI Identification Register (0x58)*/
volatile const uint32_t idr;
/* SPI DWC_ssi component version (0x5c)*/
volatile uint32_t ssic_version_id;
/* SPI Data Register 0-36 (0x60 -- 0xec)*/
volatile uint32_t dr[36];
/* SPI RX Sample Delay Register (0xf0)*/
volatile uint32_t rx_sample_delay;
/* SPI SPI Control Register (0xf4)*/
volatile uint32_t spi_ctrlr0;
/* SPI Transmit Drive Edge Register (0xf8)*/
volatile uint32_t ddr_drive_edge;
/* SPI XIP Mode bits (0xfc)*/
volatile uint32_t xip_mode_bits;
/* SPI XIP INCR transfer opcode (0x100)*/
volatile uint32_t xip_incr_inst;
/* SPI XIP WRAP transfer opcode (0x104)*/
volatile uint32_t xip_wrap_inst;
#if SSIC_CONCURRENT_XIP_EN
/* SPI XIP Control Register (0x108)*/
volatile uint32_t xip_ctrl;
/* SPI XIP Slave Enable Register (0x10c)*/
volatile uint32_t xip_ser;
/* SPI XIP Receive FIFO Overflow Interrupt Clear Register (0x110)*/
volatile uint32_t xrxoicr;
/* SPI XIP time out register for continuous transfers (0x114)*/
volatile uint32_t xip_cnt_time_out;
/* not support dyn ws (0x118)*/
uint32_t resv1[1];
/* SPI Transmit Error Interrupt Clear Register (0x11c)*/
volatile uint32_t spitecr;
#else
uint32_t resv1[6];
#endif
#if SSIC_HAS_DMA == 2
/* SPI Device Register (0x120)*/
volatile uint32_t spidr;
/* SPI Device Address Register (0x124)*/
volatile uint32_t spiar;
/* AXI Address Register 0 (0x128)*/
volatile uint32_t axiar0;
/* AXI Address Register 1 (0x12c)*/
volatile uint32_t axiar1;
/* AXI Master Error Interrupt Clear Register (0x130)*/
volatile uint32_t axiecr;
/* Transfer Done Clear Interrupt Clear Register (0x134)*/
volatile uint32_t donecr;
#endif
/* This register will not be used and is reserved. (0x138 ~ 0x13c)*/
uint32_t resv3[2];
#if SSIC_XIP_WRITE_REG_EN
/* XIP_WRITE_INCR_INST - XIP Write INCR transfer opcode (0x140)*/
volatile uint32_t xip_write_incr_inst;
/* XIP_WRITE_WRAP_INST - XIP Write WRAP transfer opcode (0x144)*/
volatile uint32_t xip_write_wrap_inst;
/* XIP_WRITE_CTRL - XIP Write Control Register (0x148)*/
volatile uint32_t xip_write_ctrl;
#else
uint32_t resv4[3];
#endif
// volatile uint32_t endian;
} __attribute__((packed, aligned(4))) k230_spi_reg_t;
#endif

View File

@@ -33,6 +33,9 @@ if GetDepend('BSP_UTEST_DRIVERS'):
if GetDepend('BSP_USING_I2C'):
src += ['test_i2c.c']
if GetDepend('BSP_USING_SPI'):
src += ['test_spi.c']
group = DefineGroup('utestcases', src, depend = [''])
Return('group')

View File

@@ -0,0 +1,222 @@
/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Copyright (c) 2006-2025 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <rtthread.h>
#include <rtdevice.h>
#include <rtdbg.h>
#include <utest.h>
#include "drv_spi.h"
#include <string.h>
#include "drv_pinctrl.h"
#include "drv_gpio.h"
/*
* 测试 SPI0 在标准SPI模式下的数据发送功能
*
* 功能说明:
* - 查找名为 "spi0" 的SPI总线设备
* - 挂载SPI设备到总线
* - 配置SPI设备参数
* - 模式标准SPI模式0 (RT_SPI_MODE_0)
* - 数据位8位
* - 最大频率1MHz
* - 数据线宽度1标准SPI
* - 准备测试数据(递增序列);
* - 创建SPI消息并发送16字节数据
* - 发送完成接收从机的16字节数据
* - 发送完成后卸载SPI设备。
*
* 硬件说明:
* - 本测试基于 K230 平台;
* - 测试SPI0(OSPI)的标准SPI模式TX和RX功能,使用硬件CS
* - 对应的引脚配置为:
* - CS: GPIO14
* - CLK: GPIO15
* - D0: GPIO16
* - D1: GPIO17
* - 需要连接SPI从设备如SPI调试器等来验证数据传输本测试文件使用一块stm32制作的SPI调试器
* - 如果没有实际从设备可以使用逻辑分析仪或示波器观察SPI波形(但是只能验证TX功能,接收到会是16bit的0xff)
*/
#define SPI0_BUS_NAME "spi0"
#define SPI0_DEV_NAME0 "spi00"
#define TEST_DATA_LENGTH 16
#define SPI0_CS_PIN 14
#define SPI0_CLK_PIN 15
#define SPI0_D0_PIN 16
#define SPI0_D1_PIN 17
#define SPI0_CS_PIN_AF IOMUX_FUNC2
#define SPI0_CLK_PIN_AF IOMUX_FUNC2
#define SPI0_D0_PIN_AF IOMUX_FUNC2
#define SPI0_D1_PIN_AF IOMUX_FUNC2
static void spi_gpio_init(void)
{
LOG_I("SPI demo: initializing SPI0 GPIO...");
k230_pinctrl_set_function(SPI0_CS_PIN, SPI0_CS_PIN_AF);
k230_pinctrl_set_function(SPI0_CLK_PIN, SPI0_CLK_PIN_AF);
k230_pinctrl_set_function(SPI0_D0_PIN, SPI0_D0_PIN_AF);
k230_pinctrl_set_function(SPI0_D1_PIN, SPI0_D1_PIN_AF);
k230_pinctrl_set_oe(SPI0_CS_PIN, 1);
k230_pinctrl_set_oe(SPI0_CLK_PIN, 1);
k230_pinctrl_set_oe(SPI0_D0_PIN, 1);
k230_pinctrl_set_oe(SPI0_D1_PIN, 1);
k230_pinctrl_set_ie(SPI0_CS_PIN, 1);
k230_pinctrl_set_ie(SPI0_CLK_PIN, 1);
k230_pinctrl_set_ie(SPI0_D0_PIN, 1);
k230_pinctrl_set_ie(SPI0_D1_PIN, 1);
}
static void spi_device_demo(void)
{
struct rt_qspi_device *qspi_dev;
LOG_I("Using rt_qspi_device to transmit");
rt_err_t ret;
uint8_t tx_data[TEST_DATA_LENGTH];
uint8_t rx_data[TEST_DATA_LENGTH];
for (int i = 0; i < TEST_DATA_LENGTH; i++)
{
tx_data[i] = i;
}
rt_memset(rx_data, 0, sizeof(rx_data));
/* Find QSPI Bus */
struct rt_spi_bus *spi_bus = (struct rt_spi_bus *)rt_device_find(SPI0_BUS_NAME);
if (!spi_bus)
{
LOG_E("Failed to find SPI bus: %s", SPI0_BUS_NAME);
return;
}
LOG_I("Success to find SPI bus: %s", SPI0_BUS_NAME);
qspi_dev = (struct rt_qspi_device *)rt_malloc(sizeof(struct rt_qspi_device));
if (!qspi_dev)
{
LOG_E("Failed to allocate SPI device memory");
return;
}
LOG_I("Success to allocate QSPI device memory");
/* Attach SPI Device */
ret = rt_spi_bus_attach_device(&(qspi_dev->parent), SPI0_DEV_NAME0, SPI0_BUS_NAME, RT_NULL);
if (ret != RT_EOK)
{
LOG_E("Failed to attach SPI device: %d", ret);
rt_free(qspi_dev);
return;
}
LOG_I("SPI device attached successfully");
/* SPI Device Config*/
struct rt_qspi_configuration qspi_cfg;
qspi_cfg.parent.mode = RT_SPI_MODE_0 | RT_SPI_MSB;
qspi_cfg.parent.data_width = 8;
qspi_cfg.parent.max_hz = 1000000;
qspi_cfg.parent.reserved = 0;
qspi_cfg.qspi_dl_width = 1;
qspi_cfg.medium_size = 0;
qspi_cfg.ddr_mode = 0;
ret = rt_qspi_configure(qspi_dev, &qspi_cfg);
if (ret != RT_EOK)
{
LOG_E("SPI configuration failed: %d", ret);
rt_free(qspi_dev);
return;
}
LOG_I("SPI configuration: Standard SPI, mode=0, data_width=8, max_hz=%d, data_lines=%d",
qspi_cfg.parent.max_hz, qspi_cfg.qspi_dl_width);
LOG_I("Sending test data (length=%d):", TEST_DATA_LENGTH);
for (int i = 0; i < TEST_DATA_LENGTH; i++)
{
rt_kprintf("%02X ", tx_data[i]);
}
rt_kprintf("\n");
/* Create SPI Message */
struct rt_qspi_message msg;
rt_memset(&msg, 0, sizeof(msg));
/*Using Standard SPI*/
msg.instruction.content = 0;
msg.instruction.qspi_lines = 1;
msg.address.content = 0;
msg.address.size = 0;
msg.address.qspi_lines = 1;
msg.qspi_data_lines = 1;
msg.dummy_cycles = 0;
/* SPI Message Config */
msg.parent.send_buf = tx_data;
msg.parent.recv_buf = rx_data;
msg.parent.length = TEST_DATA_LENGTH;
msg.parent.cs_take = 1;
msg.parent.cs_release = 1;
msg.parent.next = RT_NULL;
/* Transfer Data */
ret = rt_qspi_transfer_message(qspi_dev, &msg);
if (ret != TEST_DATA_LENGTH)
{
LOG_E("SPI transfer failed, returned: %d", ret);
}
uassert_int_equal(ret, TEST_DATA_LENGTH);
LOG_I("SPI TX demo: sent %d bytes successfully", ret);
LOG_I("Received data from slave (length=%d):", TEST_DATA_LENGTH);
for (int i = 0; i < TEST_DATA_LENGTH; i++)
{
rt_kprintf("%02X ", rx_data[i]);
}
rt_kprintf("\n");
/* Detach SPI Device */
ret = rt_spi_bus_detach_device(&(qspi_dev->parent));
uassert_int_equal(ret, RT_EOK);
rt_free(qspi_dev);
}
static void testcase(void)
{
UTEST_UNIT_RUN(spi_gpio_init);
UTEST_UNIT_RUN(spi_device_demo);
}
static rt_err_t utest_tc_init(void)
{
LOG_I("SPI test case initialization");
return RT_EOK;
}
static rt_err_t utest_tc_cleanup(void)
{
LOG_I("SPI test case cleanup");
return RT_EOK;
}
UTEST_TC_EXPORT(testcase, "bsp.k230.drivers.spi", utest_tc_init, utest_tc_cleanup, 10);

View File

@@ -503,6 +503,10 @@
/* GD32 Drivers */
/* end of GD32 Drivers */
/* HPMicro SDK */
/* end of HPMicro SDK */
/* end of HAL & SDK Drivers */
/* sensors drivers */

View File

@@ -2,6 +2,5 @@
# If you need to exclude an entire folder, add the folder path in dir_path;
# If you need to exclude a file, add the path to the file in file_path.
dir_path:
- CMSIS
- VangoV85xx_standard_peripheral
# 从 .ignore_format.yml 迁移的规则
/sam*/bsp/

View File

@@ -1,6 +0,0 @@
# files format check exclude path, please follow the instructions below to modify;
# If you need to exclude an entire folder, add the folder path in dir_path;
# If you need to exclude a file, add the path to the file in file_path.
dir_path:
- bsp

View File

@@ -1,6 +0,0 @@
# files format check exclude path, please follow the instructions below to modify;
# If you need to exclude an entire folder, add the folder path in dir_path;
# If you need to exclude a file, add the path to the file in file_path.
dir_path:
- bsp

View File

@@ -1,6 +0,0 @@
# files format check exclude path, please follow the instructions below to modify;
# If you need to exclude an entire folder, add the folder path in dir_path;
# If you need to exclude a file, add the path to the file in file_path.
dir_path:
- bsp

View File

@@ -1,6 +0,0 @@
# files format check exclude path, please follow the instructions below to modify;
# If you need to exclude an entire folder, add the folder path in dir_path;
# If you need to exclude a file, add the path to the file in file_path.
dir_path:
- bsp

View File

@@ -1,7 +1,7 @@
# files format check exclude path, please follow the instructions below to modify;
# If you need to exclude an entire folder, add the folder path in dir_path;
# If you need to exclude a file, add the path to the file in file_path.
dir_path:
- Libraries/N32_Std_Driver
# 从 .ignore_format.yml 迁移的规则
/Libraries/

View File

@@ -1,4 +0,0 @@
# files format check exclude path, please follow the instructions below to modify;
dir_path:
- Libraries

View File

@@ -1,9 +1,7 @@
# files format check exclude path, please follow the instructions below to modify;
# If you need to exclude an entire folder, add the folder path in dir_path;
# If you need to exclude a file, add the path to the file in file_path.
file_path:
dir_path:
- Libraries
# 从 .ignore_format.yml 迁移的规则
/Libraries/

View File

@@ -1,6 +0,0 @@
# files format check exclude path, please follow the instructions below to modify;
# If you need to exclude an entire folder, add the folder path in dir_path;
# If you need to exclude a file, add the path to the file in file_path.
dir_path:
- Libraries

View File

@@ -1,6 +1,7 @@
# files format check exclude path, please follow the instructions below to modify;
# If you need to exclude an entire folder, add the folder path in dir_path;
# If you need to exclude a file, add the path to the file in file_path.
dir_path:
- bsp
# 从 .ignore_format.yml 迁移的规则
/Libraries/

View File

@@ -1,6 +0,0 @@
# files format check exclude path, please follow the instructions below to modify;
# If you need to exclude an entire folder, add the folder path in dir_path;
# If you need to exclude a file, add the path to the file in file_path.
dir_path:
- Libraries

View File

@@ -2,6 +2,5 @@
# If you need to exclude an entire folder, add the folder path in dir_path;
# If you need to exclude a file, add the path to the file in file_path.
dir_path:
- CMSIS
- VangoV85xxP_standard_peripheral
# 从 .ignore_format.yml 迁移的规则
/Libraries/

View File

@@ -2,5 +2,5 @@
# If you need to exclude an entire folder, add the folder path in dir_path;
# If you need to exclude a file, add the path to the file in file_path.
dir_path:
- bsp
# 从 .ignore_format.yml 迁移的规则
/Libraries/

View File

@@ -0,0 +1,7 @@
# files format check exclude path, please follow the instructions below to modify;
# If you need to exclude an entire folder, add the folder path in dir_path;
# If you need to exclude a file, add the path to the file in file_path.
# 从 .ignore_format.yml 迁移的规则
/libraries/N32G45x_Firmware_Library/

View File

@@ -1,6 +0,0 @@
# files format check exclude path, please follow the instructions below to modify;
# If you need to exclude an entire folder, add the folder path in dir_path;
# If you need to exclude a file, add the path to the file in file_path.
dir_path:
- N32G45x_Firmware_Library

View File

@@ -0,0 +1,7 @@
# files format check exclude path, please follow the instructions below to modify;
# If you need to exclude an entire folder, add the folder path in dir_path;
# If you need to exclude a file, add the path to the file in file_path.
# 从 .ignore_format.yml 迁移的规则
/Libraries/N32_Std_Driver/

View File

@@ -0,0 +1,17 @@
# files format check exclude path, please follow the instructions below to modify;
# If you need to exclude an entire folder, add the folder path in dir_path;
# If you need to exclude a file, add the path to the file in file_path.
# 从 .ignore_format.yml 迁移的规则
/imx/imxrt/imxrt1060-nxp-evk/board/board.c/
/imx/imxrt/imxrt1060-nxp-evk/board/MCUX_Config/
/imx/imxrt/imxrt1060-nxp-evk/xip/
/imx/imxrt/libraries/MIMXRT1060/
/lpc/lpc55sxx/Libraries/LPC55*/
/mcx/mcxa/Libraries/MCXA153/
/mcx/mcxc/Libraries/MCXC444/
/mcx/mcxn/Libraries/MCXN947/

View File

@@ -0,0 +1,10 @@
# .clang-format-ignore File Description:
# ----------------------------------------------------------------------------------------
# 1. Used to specify which files or directories should be skipped by the clang-format tool.
# 2. Follows syntax rules similar to .gitignore.
# 3. Supports wildcard patterns and path matching.
# 4. clang-format will recursively apply the .clang-format-ignore rules.
# NXP imxrt1060-nxp-evk library
/board/MCUX_Config/
/xip/

View File

@@ -1,6 +0,0 @@
# files format check exclude path, please follow the instructions below to modify;
dir_path:
- board/board.c
- board/MCUX_Config
- xip

View File

@@ -1,4 +0,0 @@
# files format check exclude path, please follow the instructions below to modify;
dir_path:
- MIMXRT1060

View File

@@ -18,10 +18,6 @@
#include <shell.h>
#endif
#ifdef RT_USING_VBUS
#include <vbus.h>
#endif
/* thread phase init */
void rt_init_thread_entry(void *parameter)
{
@@ -32,10 +28,6 @@ void rt_init_thread_entry(void *parameter)
finsh_set_device(RT_CONSOLE_DEVICE_NAME);
#endif
#endif
#ifdef RT_USING_VBUS
rt_vbus_do_init();
#endif
}
/*the led thread*/
@@ -45,8 +37,6 @@ static struct rt_thread led_thread;
static void led_thread_entry(void *parameter)
{
rt_device_t led_dev;
rt_device_t vbus_dev;
rt_err_t err;
rt_led_hw_init();
@@ -57,32 +47,14 @@ static void led_thread_entry(void *parameter)
return;
}
vbus_dev = rt_device_find("vecho");
if (vbus_dev == RT_NULL)
{
rt_kprintf("can not find the vbus device\n");
return;
}
err = rt_device_open(vbus_dev, RT_DEVICE_OFLAG_RDWR);
if (err != RT_EOK)
{
rt_kprintf("open vbus failed: %d\n", err);
return;
}
while (1)
{
rt_uint8_t led_value;
int len;
len = rt_device_read(vbus_dev, 0, &led_value, sizeof(led_value));
if (len <= 0)
{
rt_kprintf("vbus read err: %d, %d\n", len, rt_get_errno());
}
rt_uint8_t led_value = 1;
led_dev->write(led_dev, 1, &led_value, sizeof(led_value));
rt_thread_delay(500);
led_value = 0;
led_dev->write(led_dev, 1, &led_value, sizeof(led_value));
rt_thread_delay(500);
}
}

View File

@@ -50,6 +50,5 @@ extern int __bss_end;
void rt_hw_board_init(void);
int rt_hw_board_heap_init(void);
int rt_vbus_do_init(void);
#endif

View File

@@ -1,13 +0,0 @@
#ifndef __VBUS_CONF_H__
#define __VBUS_CONF_H__
/* Number of blocks in VBus. The total size of VBus is
* RT_VMM_RB_BLK_NR * 64byte * 2. */
#define RT_VMM_RB_BLK_NR 20
/* We don't use the IRQ number to trigger IRQ in this BSP. */
#define RT_VBUS_GUEST_VIRQ 0
#define RT_VBUS_HOST_VIRQ 0
#endif /* end of include guard: __VBUS_CONF_H__ */

View File

@@ -1,67 +0,0 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2015-01-07 Grissiom add comment
*/
#include <rtthread.h>
#ifdef RT_USING_VBUS
#include <rtdevice.h>
#include <vbus.h>
#include <board.h>
struct rt_vbus_ring rt_vbus_rings[2] rt_section("vbus_ring");
int rt_vbus_do_init(void)
{
return rt_vbus_init(&rt_vbus_rings[1], &rt_vbus_rings[0]);
}
INIT_COMPONENT_EXPORT(rt_vbus_do_init);
int rt_vbus_hw_init(void)
{
NVIC_ClearPendingIRQ(M0_M4CORE_IRQn);
NVIC_EnableIRQ(M0_M4CORE_IRQn);
return 0;
}
void M4CORE_IRQHandler(void)
{
LPC_CREG->M4TXEVENT = 0;
rt_vbus_isr(M0_M4CORE_IRQn, RT_NULL);
}
int rt_vbus_hw_eoi(int irqnr, void *param)
{
/* Nothing to do here as we cleared the interrupt in IRQHandler. */
return 0;
}
struct rt_vbus_dev rt_vbus_chn_devx[] = {
{
.req =
{
.prio = 30,
.name = "vecho",
.is_server = 0,
.recv_wm.low = RT_VMM_RB_BLK_NR / 3,
.recv_wm.high = RT_VMM_RB_BLK_NR * 2 / 3,
.post_wm.low = RT_VMM_RB_BLK_NR / 3,
.post_wm.high = RT_VMM_RB_BLK_NR * 2 / 3,
}
},
{
.req =
{
.name = RT_NULL,
}
},
};
#endif /* RT_USING_VBUS */

View File

@@ -1,40 +0,0 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2015-01-07 Grissiom init commit
*/
#ifndef __VBUS_HW_H__
#define __VBUS_HW_H__
#include <rtthread.h>
#include <board.h>
rt_inline void rt_vbus_tick(unsigned int target_cpu, unsigned int irqnr)
{
__SEV();
}
/* Read memory barrier. */
rt_inline void rt_vbus_smp_rmb(void)
{
__DMB();
}
/* Write memory barrier. */
rt_inline void rt_vbus_smp_wmb(void)
{
__DSB();
}
/* General memory barrier. */
rt_inline void rt_vbus_smp_mb(void)
{
__DSB();
}
#endif /* __VBUS_HW_H__ */

View File

@@ -220,9 +220,6 @@
#define RT_LWIP_MSKADDR3 0
// </section>
#define RT_USING_VBUS
#define _RT_VBUS_RING_SZ 64
#define RT_VBUS_GUEST_VIRQ 0
// </RDTConfigurator>

View File

@@ -1,8 +0,0 @@
#ifndef __VBUS_LOCAL_CONF_H__
#define __VBUS_LOCAL_CONF_H__
#define RT_VBUS_USING_FLOW_CONTROL
#define RT_VBUS_USING_TESTS
#endif /* end of include guard: __VBUS_LOCAL_CONF_H__ */

View File

@@ -18,10 +18,6 @@
#include <shell.h>
#endif
#ifdef RT_USING_VBUS
#include <vbus.h>
#endif
static const unsigned char _M0_CODE[] rt_section("M0_CODE") = {
// #include "M0_CODE.h"
};
@@ -64,10 +60,6 @@ void rt_init_thread_entry(void *parameter)
#endif
#endif
#ifdef RT_USING_VBUS
rt_vbus_do_init();
#endif
_boot_M0();
}
@@ -79,8 +71,6 @@ static void led_thread_entry(void *parameter)
{
rt_uint8_t led_value;
rt_device_t led_dev;
rt_device_t vbus_dev;
rt_err_t err;
rt_led_hw_init();
@@ -91,34 +81,11 @@ static void led_thread_entry(void *parameter)
return;
}
vbus_dev = rt_device_find("vecho");
if (vbus_dev == RT_NULL)
{
rt_kprintf("can not find the vbus device\n");
return;
}
err = rt_device_open(vbus_dev, RT_DEVICE_OFLAG_RDWR);
if (err != RT_EOK)
{
rt_kprintf("open vbus failed: %d\n", err);
return;
}
led_value = 0;
while (1)
{
int len;
led_dev->write(led_dev, 0, &led_value, sizeof(led_value));
led_value = !led_value;
len = rt_device_write(vbus_dev, 0, &led_value, sizeof(led_value));
if (len <= 0)
{
rt_kprintf("vbus write err: %d, %d\n", len, rt_get_errno());
}
rt_thread_delay(1000);
}
}

View File

@@ -50,6 +50,5 @@ extern int __bss_end;
void rt_hw_board_init(void);
int rt_hw_board_heap_init(void);
int rt_vbus_do_init(void);
#endif

View File

@@ -1,13 +0,0 @@
#ifndef __VBUS_CONF_H__
#define __VBUS_CONF_H__
/* Number of blocks in VBus. The total size of VBus is
* RT_VMM_RB_BLK_NR * 64byte * 2. */
#define RT_VMM_RB_BLK_NR 20
/* We don't use the IRQ number to trigger IRQ in this BSP. */
#define RT_VBUS_GUEST_VIRQ 0
#define RT_VBUS_HOST_VIRQ 0
#endif /* end of include guard: __VBUS_CONF_H__ */

View File

@@ -1,67 +0,0 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2015-01-07 Grissiom add comment
*/
#include <rtthread.h>
#ifdef RT_USING_VBUS
#include <rtdevice.h>
#include <vbus.h>
#include <board.h>
struct rt_vbus_ring rt_vbus_rings[2] rt_section("vbus_ring");
int rt_vbus_do_init(void)
{
return rt_vbus_init(&rt_vbus_rings[0], &rt_vbus_rings[1]);
}
INIT_COMPONENT_EXPORT(rt_vbus_do_init);
int rt_vbus_hw_init(void)
{
NVIC_ClearPendingIRQ(M0CORE_IRQn);
NVIC_EnableIRQ(M0CORE_IRQn);
return 0;
}
void M0CORE_IRQHandler(void)
{
LPC_CREG->M0TXEVENT = 0;
rt_vbus_isr(M0CORE_IRQn, RT_NULL);
}
int rt_vbus_hw_eoi(int irqnr, void *param)
{
/* Nothing to do here as we cleared the interrupt in IRQHandler. */
return 0;
}
struct rt_vbus_dev rt_vbus_chn_devx[] = {
{
.req =
{
.prio = 30,
.name = "vecho",
.is_server = 1,
.recv_wm.low = RT_VMM_RB_BLK_NR / 3,
.recv_wm.high = RT_VMM_RB_BLK_NR * 2 / 3,
.post_wm.low = RT_VMM_RB_BLK_NR / 3,
.post_wm.high = RT_VMM_RB_BLK_NR * 2 / 3,
}
},
{
.req =
{
.name = RT_NULL,
}
},
};
#endif /* RT_USING_VBUS */

View File

@@ -1,40 +0,0 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2015-01-07 Grissiom init commit
*/
#ifndef __VBUS_HW_H__
#define __VBUS_HW_H__
#include <rtthread.h>
#include <board.h>
rt_inline void rt_vbus_tick(unsigned int target_cpu, unsigned int irqnr)
{
__SEV();
}
/* Read memory barrier. */
rt_inline void rt_vbus_smp_rmb(void)
{
__DMB();
}
/* Write memory barrier. */
rt_inline void rt_vbus_smp_wmb(void)
{
__DSB();
}
/* General memory barrier. */
rt_inline void rt_vbus_smp_mb(void)
{
__DSB();
}
#endif /* __VBUS_HW_H__ */

View File

@@ -222,10 +222,6 @@
#define RT_LWIP_MSKADDR3 0
// </section>
#define RT_USING_VBUS
#define RT_VBUS_GUEST_VIRQ 0
#define _RT_VBUS_RING_SZ 64
// </RDTConfigurator>
#define RT_CPUS_NR 1
#define RT_BACKTRACE_LEVEL_MAX_NR 32

View File

@@ -1,8 +0,0 @@
#ifndef __VBUS_LOCAL_CONF_H__
#define __VBUS_LOCAL_CONF_H__
#define RT_VBUS_USING_FLOW_CONTROL
#define RT_VBUS_USING_TESTS
#endif /* end of include guard: __VBUS_LOCAL_CONF_H__ */

View File

@@ -1,8 +0,0 @@
# files format check exclude path, please follow the instructions below to modify;
dir_path:
- LPC55S6X
- LPC55S06
- LPC5502
- LPC55S28
- LPC55S36

View File

@@ -0,0 +1,9 @@
# .clang-format-ignore File Description:
# ----------------------------------------------------------------------------------------
# 1. Used to specify which files or directories should be skipped by the clang-format tool.
# 2. Follows syntax rules similar to .gitignore.
# 3. Supports wildcard patterns and path matching.
# 4. clang-format will recursively apply the .clang-format-ignore rules.
# NXP MCXA library
/MCXA153/

View File

@@ -1,4 +0,0 @@
# files format check exclude path, please follow the instructions below to modify;
dir_path:
- MCXA153

View File

@@ -1,4 +0,0 @@
# files format check exclude path, please follow the instructions below to modify;
dir_path:
- MCXC444

View File

@@ -1,4 +0,0 @@
# files format check exclude path, please follow the instructions below to modify;
dir_path:
- MCXN947

View File

@@ -1,4 +1,14 @@
# clang-format ignore file
# .clang-format-ignore File Description:
# ----------------------------------------------------------------------------------------
# 1. Used to specify which files or directories should be skipped by the clang-format tool.
# 2. Follows syntax rules similar to .gitignore.
# 3. Supports wildcard patterns and path matching.
# 4. clang-format will recursively apply the .clang-format-ignore rules.
# Renesas Vendor library
<<<<<<< HEAD
/**/ra/
/**/ra_cfg/
/**/ra_gen/
/**/ra_gen/
/libraries/bsp-template/
/**/RTE/

View File

@@ -1,9 +0,0 @@
# files format check exclude path, please follow the instructions below to modify;
# If you need to exclude an entire folder, add the folder path in dir_path;
# If you need to exclude a file, add the path to the file in file_path.
dir_path:
- ra
- ra_gen
- ra_cfg
- RTE

View File

@@ -0,0 +1,9 @@
# .clang-format-ignore File Description:
# ----------------------------------------------------------------------------------------
# 1. Used to specify which files or directories should be skipped by the clang-format tool.
# 2. Follows syntax rules similar to .gitignore.
# 3. Supports wildcard patterns and path matching.
# 4. clang-format will recursively apply the .clang-format-ignore rules.
/common/rk_hal/

View File

@@ -1,6 +0,0 @@
# files format check exclude path, please follow the instructions below to modify;
# If you need to exclude an entire folder, add the folder path in dir_path;
# If you need to exclude a file, add the path to the file in file_path.
dir_path:
- rk_hal

View File

@@ -0,0 +1,12 @@
# files format check exclude path, please follow the instructions below to modify;
# If you need to exclude an entire folder, add the folder path in dir_path;
# If you need to exclude a file, add the path to the file in file_path.
# 从 .ignore_format.yml 迁移的规则
# 忽略所有 STM32 HAL 库目录
/libraries/STM32*_HAL/
# 忽略所有 STM32 BSP 的 CubeMX 配置目录
/stm32*/board/CubeMX_Config/

View File

@@ -1,23 +0,0 @@
# files format check exclude path, please follow the instructions below to modify;
# If you need to exclude an entire folder, add the folder path in dir_path;
# If you need to exclude a file, add the path to the file in file_path.
dir_path:
- STM32F0xx_HAL
- STM32F1xx_HAL
- STM32F2xx_HAL
- STM32F3xx_HAL
- STM32F4xx_HAL
- STM32F7xx_HAL
- STM32G0xx_HAL
- STM32G4xx_HAL
- STM32H7xx_HAL
- STM32L0xx_HAL
- STM32L1xx_HAL
- STM32L4xx_HAL
- STM32L5xx_HAL
- STM32MPxx_HAL
- STM32U5xx_HAL
- STM32H5xx_HAL
- STM32WBxx_HAL
- STM32WLxx_HAL

View File

@@ -145,6 +145,17 @@ extern "C" {
#endif /* UART5_DMA_RX_CONFIG */
#endif /* BSP_UART5_RX_USING_DMA */
#if defined(BSP_USING_LPUART1)
#ifndef LPUART1_CONFIG
#define LPUART1_CONFIG \
{ \
.name = "hlpuart1", \
.Instance = LPUART1, \
.irq_type = LPUART1_IRQn, \
}
#endif /* LPUART1_CONFIG */
#endif /* BSP_USING_LPUART1 */
#ifdef __cplusplus
}
#endif

View File

@@ -472,11 +472,23 @@ static rt_err_t _can_control(struct rt_can_device *can, int cmd, void *arg)
argval = (rt_uint32_t) arg;
if (argval == 0)
{
HAL_CAN_Stop(&drv_can->CanHandle);
if (HAL_CAN_DeInit(&drv_can->CanHandle) != HAL_OK)
{
LOG_E("CAN deinitialization failed");
return -RT_ERROR;
}
}
else
{
HAL_CAN_Start(&drv_can->CanHandle);
rt_err_t result = _can_config(&drv_can->device, &drv_can->device.config);
if (result != RT_EOK)
{
return result;
}
if (HAL_CAN_Start(&drv_can->CanHandle) != HAL_OK)
{
return -RT_ERROR;
}
}
break;
@@ -500,7 +512,7 @@ static rt_err_t _can_control(struct rt_can_device *can, int cmd, void *arg)
*
* @return `RT_EOK` on success, or an error code on failure.
*/
static int _can_sendmsg(struct rt_can_device *can, const void *buf, rt_uint32_t box_num)
static rt_ssize_t _can_sendmsg(struct rt_can_device *can, const void *buf, rt_uint32_t box_num)
{
CAN_HandleTypeDef *hcan;
hcan = &((struct stm32_can *) can->parent.user_data)->CanHandle;
@@ -515,32 +527,31 @@ static int _can_sendmsg(struct rt_can_device *can, const void *buf, rt_uint32_t
(state == HAL_CAN_STATE_LISTENING))
{
/*check select mailbox is empty */
uint32_t mailbox_mask;
uint32_t tme_flag;
switch (1 << box_num)
{
case CAN_TX_MAILBOX0:
if (HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME0) != SET)
{
/* Return function status */
return -RT_ERROR;
}
mailbox_mask = CAN_TX_MAILBOX0;
tme_flag = CAN_TSR_TME0;
break;
case CAN_TX_MAILBOX1:
if (HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME1) != SET)
{
/* Return function status */
return -RT_ERROR;
}
mailbox_mask = CAN_TX_MAILBOX1;
tme_flag = CAN_TSR_TME1;
break;
case CAN_TX_MAILBOX2:
if (HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME2) != SET)
{
/* Return function status */
return -RT_ERROR;
}
mailbox_mask = CAN_TX_MAILBOX2;
tme_flag = CAN_TSR_TME2;
break;
default:
RT_ASSERT(0);
break;
return -RT_ERROR;
}
if (HAL_IS_BIT_SET(hcan->Instance->TSR, tme_flag) != SET)
{
return -RT_ERROR;
}
if (RT_CAN_STDID == pmsg->ide)
@@ -649,7 +660,7 @@ static rt_ssize_t _can_sendmsg_nonblocking(struct rt_can_device *can, const void
return RT_EOK;
}
static int _can_recvmsg(struct rt_can_device *can, void *buf, rt_uint32_t fifo)
static rt_ssize_t _can_recvmsg(struct rt_can_device *can, void *buf, rt_uint32_t fifo)
{
HAL_StatusTypeDef status;
CAN_HandleTypeDef *hcan;

View File

@@ -1,7 +0,0 @@
# files format check exclude path, please follow the instructions below to modify;
# If you need to exclude an entire folder, add the folder path in dir_path;
# If you need to exclude a file, add the path to the file in file_path.
dir_path:
- CubeMX_Config
- linker_scripts

View File

@@ -1,6 +0,0 @@
# files format check exclude path, please follow the instructions below to modify;
# If you need to exclude an entire folder, add the folder path in dir_path;
# If you need to exclude a file, add the path to the file in file_path.
dir_path:
- CubeMX_Config

View File

@@ -1,6 +0,0 @@
# files format check exclude path, please follow the instructions below to modify;
# If you need to exclude an entire folder, add the folder path in dir_path;
# If you need to exclude a file, add the path to the file in file_path.
dir_path:
- CubeMX_Config

View File

@@ -1,6 +0,0 @@
# files format check exclude path, please follow the instructions below to modify;
# If you need to exclude an entire folder, add the folder path in dir_path;
# If you need to exclude a file, add the path to the file in file_path.
dir_path:
- CubeMX_Config

View File

@@ -1,6 +0,0 @@
# files format check exclude path, please follow the instructions below to modify;
# If you need to exclude an entire folder, add the folder path in dir_path;
# If you need to exclude a file, add the path to the file in file_path.
dir_path:
- CubeMX_Config

View File

@@ -1,6 +0,0 @@
# files format check exclude path, please follow the instructions below to modify;
# If you need to exclude an entire folder, add the folder path in dir_path;
# If you need to exclude a file, add the path to the file in file_path.
dir_path:
- CubeMX_Config

View File

@@ -1,6 +0,0 @@
# files format check exclude path, please follow the instructions below to modify;
# If you need to exclude an entire folder, add the folder path in dir_path;
# If you need to exclude a file, add the path to the file in file_path.
dir_path:
- CubeMX_Config

View File

@@ -1,6 +0,0 @@
# files format check exclude path, please follow the instructions below to modify;
# If you need to exclude an entire folder, add the folder path in dir_path;
# If you need to exclude a file, add the path to the file in file_path.
dir_path:
- CubeMX_Config

View File

@@ -1,6 +0,0 @@
# files format check exclude path, please follow the instructions below to modify;
# If you need to exclude an entire folder, add the folder path in dir_path;
# If you need to exclude a file, add the path to the file in file_path.
dir_path:
- CubeMX_Config

View File

@@ -1,6 +0,0 @@
# files format check exclude path, please follow the instructions below to modify;
# If you need to exclude an entire folder, add the folder path in dir_path;
# If you need to exclude a file, add the path to the file in file_path.
dir_path:
- CubeMX_Config

View File

@@ -1,6 +0,0 @@
# files format check exclude path, please follow the instructions below to modify;
# If you need to exclude an entire folder, add the folder path in dir_path;
# If you need to exclude a file, add the path to the file in file_path.
dir_path:
- CubeMX_Config

View File

@@ -1,6 +0,0 @@
# files format check exclude path, please follow the instructions below to modify;
# If you need to exclude an entire folder, add the folder path in dir_path;
# If you need to exclude a file, add the path to the file in file_path.
dir_path:
- CubeMX_Config

View File

@@ -1,6 +0,0 @@
# files format check exclude path, please follow the instructions below to modify;
# If you need to exclude an entire folder, add the folder path in dir_path;
# If you need to exclude a file, add the path to the file in file_path.
dir_path:
- CubeMX_Config

View File

@@ -1,6 +0,0 @@
# files format check exclude path, please follow the instructions below to modify;
# If you need to exclude an entire folder, add the folder path in dir_path;
# If you need to exclude a file, add the path to the file in file_path.
dir_path:
- CubeMX_Config

View File

@@ -1,6 +0,0 @@
# files format check exclude path, please follow the instructions below to modify;
# If you need to exclude an entire folder, add the folder path in dir_path;
# If you need to exclude a file, add the path to the file in file_path.
dir_path:
- CubeMX_Config

View File

@@ -1,6 +0,0 @@
# files format check exclude path, please follow the instructions below to modify;
# If you need to exclude an entire folder, add the folder path in dir_path;
# If you need to exclude a file, add the path to the file in file_path.
dir_path:
- CubeMX_Config

View File

@@ -1,6 +0,0 @@
# files format check exclude path, please follow the instructions below to modify;
# If you need to exclude an entire folder, add the folder path in dir_path;
# If you need to exclude a file, add the path to the file in file_path.
dir_path:
- CubeMX_Config

View File

@@ -1,6 +0,0 @@
# files format check exclude path, please follow the instructions below to modify;
# If you need to exclude an entire folder, add the folder path in dir_path;
# If you need to exclude a file, add the path to the file in file_path.
dir_path:
- CubeMX_Config

View File

@@ -1,6 +0,0 @@
# files format check exclude path, please follow the instructions below to modify;
# If you need to exclude an entire folder, add the folder path in dir_path;
# If you need to exclude a file, add the path to the file in file_path.
dir_path:
- CubeMX_Config

View File

@@ -1,6 +0,0 @@
# files format check exclude path, please follow the instructions below to modify;
# If you need to exclude an entire folder, add the folder path in dir_path;
# If you need to exclude a file, add the path to the file in file_path.
dir_path:
- CubeMX_Config

View File

@@ -1,6 +0,0 @@
# files format check exclude path, please follow the instructions below to modify;
# If you need to exclude an entire folder, add the folder path in dir_path;
# If you need to exclude a file, add the path to the file in file_path.
dir_path:
- CubeMX_Config

View File

@@ -1,6 +0,0 @@
# files format check exclude path, please follow the instructions below to modify;
# If you need to exclude an entire folder, add the folder path in dir_path;
# If you need to exclude a file, add the path to the file in file_path.
dir_path:
- CubeMX_Config

File diff suppressed because it is too large Load Diff

42
bsp/stm32/stm32f407-micu/.gitignore vendored Normal file
View File

@@ -0,0 +1,42 @@
*.pyc
*.map
*.dblite
*.elf
*.bin
*.hex
*.axf
*.exe
*.pdb
*.idb
*.ilk
*.old
build
Debug
documentation/html
packages/
*~
*.o
*.obj
*.out
*.bak
*.dep
*.lib
*.i
*.d
.DS_Stor*
.config 3
.config 4
.config 5
Midea-X1
*.uimg
GPATH
GRTAGS
GTAGS
.vscode
JLinkLog.txt
JLinkSettings.ini
DebugConfig/
RTE/
settings/
*.uvguix*
cconfig.h

View File

@@ -0,0 +1,15 @@
mainmenu "RT-Thread Configuration"
BSP_DIR := .
RTT_DIR := ../../..
PKGS_DIR := packages
source "$(RTT_DIR)/Kconfig"
osource "$PKGS_DIR/Kconfig"
rsource "../libraries/Kconfig"
if !RT_USING_NANO
rsource "board/Kconfig"
endif

View File

@@ -0,0 +1,137 @@
# 米醋·McoreSTM32电控板 BSP 说明
## 简介
本文档为 **米醋·McoreSTM32电控板** 的 BSP (板级支持包) 说明。
主要内容如下:
- 开发板资源介绍
- BSP 快速上手
- 进阶使用方法
通过阅读快速上手章节开发者可以快速地上手该 BSP将 RT-Thread 运行在开发板上。在进阶使用指南章节,将会介绍更多高级功能,帮助开发者利用 RT-Thread 驱动更多板载资源。
## 开发板介绍
STM32F407VET6是一款泛用性很高的芯片基于 ARM Cortex-M4 内核的 32 位微控制器,属于 STM32 系列。它具有高性能、低功耗和丰富的外设非常适合用于各种嵌入式应用。我们基于这款芯片设计出一块核心板用于嵌入式学习板载了GD32芯片搭载DAP-LINK可用于keil下载调试。板子上还预留一个三色LED、一个用户按键、一个4M的FLASH、一个TF卡槽此外还搭载了比较常用的传感器温湿度传感器和姿态传感器。
开发板外观如下图所示:
![board](figures/board.png)
该开发板常用 **板载资源** 如下:
- MCUSTM32F407VET6主频 168MHz512KB FLASH 192KB RAM
- 外部 FLASHZD25WQ324MB
- 常用外设
- LED3个DS0红色PC2DS1绿色PC1DS2蓝色PC0
- 按键1个USERPC3
- 常用接口USB 转串口、SD 卡接口等
- 调试接口支持SWD板载DAPLink
开发板更多详细信息请参考【立创开源硬件平台】 [米醋·McoreSTM32电控板](https://oshwhub.com/the-first-development-team-of-no/kong-zhi-ban)。
## 外设支持
本 BSP 目前对外设的支持情况如下:
| **板载外设** | **支持情况** | **备注** |
| :----------------- | :----------: | :------------------------------------- |
| DAPLink虚拟串口 | 支持 | 已连接到芯片的UART1PA9,PA10 |
| 三色LED(RGB) | 支持 | 作为系统状态指示灯 |
| 按键 | 暂不支持 | 即将支持 |
| SPI Flash | 暂不支持 | 即将支持 |
| TF卡 | 暂不支持 | 即将支持 |
| CAN | 暂不支持 | 即将支持 |
| ICM-20608-G | 暂不支持 | 即将支持 |
| AHT20 | 暂不支持 |即将支持 |
| **片上外设** | **支持情况** | **备注** |
| GPIO | 支持 | 所有GPIO引脚 |
| UART | 支持 | UART1 |
| SPI | 暂不支持 | 即将支持 |
| I2C | 暂不支持 | 即将支持 |
| SDIO | 暂不支持 | 即将支持 |
| RTC | 暂不支持 | 即将支持 |
| PWM | 暂不支持 | 即将支持 |
| USB Device | 暂不支持 | 即将支持 |
| USB Host | 暂不支持 | 即将支持 |
| IWG | 暂不支持 | 即将支持 |
| **扩展模块** | **支持情况** | **备注** |
| 舵机 | 暂不支持 | 即将支持 |
| 编码电机 | 暂不支持 | 即将支持 |
| 步进电机 | 暂不支持 | 即将支持 |
| 蓝牙 | 暂不支持 |即将支持 |
| CAM | 暂不支持 | 即将支持 |
| OLED | 暂不支持 | 即将支持 |
| 陀螺仪 | 暂不支持 | 即将支持 |
| 八路灰度 | 暂不支持 | 即将支持 |
| LED灯 | 暂不支持 | 即将支持 |
| 按键 | 暂不支持 | 即将支持 |
## 使用说明
使用说明分为如下两个章节:
- 快速上手
本章节是为刚接触 RT-Thread 的新手准备的使用说明,遵循简单的步骤即可将 RT-Thread 操作系统运行在该开发板上,看到实验效果 。
- 进阶使用
本章节是为需要在 RT-Thread 操作系统上使用更多开发板资源的开发者准备的。通过使用 ENV 工具对 BSP 进行配置,可以开启更多板载资源,实现更多高级功能。
### 快速上手
本 BSP 为开发者提供 MDK4、MDK5 和 IAR 工程,并且支持 GCC 开发环境。下面以 MDK5 开发环境为例,介绍如何将系统运行起来。
#### 硬件连接
使用数据线连接开发板到 PC打开电源开关。
#### 编译下载
##### 请注意!!!
在执行编译工作前请先打开ENV执行以下指令该指令用于拉取必要的HAL库及CMSIS库否则无法通过编译
```bash
pkgs --update
```
双击 project.uvprojx 文件,打开 MDK5 工程,编译并下载程序到开发板。
> 工程默认配置使用 DAPLink 仿真器下载程序,在通过 USB 连接开发板的基础上,点击下载按钮即可下载程序到开发板
#### 运行结果
下载程序成功之后系统会自动运行【开发板上的三色LED会以1HZ的频率闪烁】。
连接开发板对应串口到 PC , 在终端工具里打开相应的串口115200-8-1-N复位设备后可以看到 RT-Thread 的输出信息:
```bash
\ | /
- RT - Thread Operating System
/ | \ 5.2.2 build Nov 8 2025 16:39:56
2006 - 2024 Copyright by rt-thread team
msh >
```
### 进阶使用
此 BSP 默认只开启了 GPIO 和 串口1 的功能,如果需使用 SD 卡、Flash 等更多高级功能,需要利用 ENV 工具对BSP 进行配置,步骤如下:
1. 在 bsp 下打开 env 工具。
2. 输入`menuconfig`命令配置工程,配置好之后保存退出。
3. 输入`pkgs --update`命令更新软件包。
4. 输入`scons --target=mdk4/mdk5/iar` 命令重新生成工程。
本章节更多详细的介绍请参考 [STM32 系列 BSP 外设驱动使用教程](../docs/STM32系列BSP外设驱动使用教程.md)。
## 注意事项
- 暂无
## 联系人信息
维护人:
- [戴凌祥](https://gitee.com/dai-lingxiang), 邮箱:<3070269033@qq.com>

View File

@@ -0,0 +1,15 @@
# for module compiling
import os
Import('RTT_ROOT')
from building import *
cwd = GetCurrentDir()
objs = []
list = os.listdir(cwd)
for d in list:
path = os.path.join(cwd, d)
if os.path.isfile(os.path.join(path, 'SConscript')):
objs = objs + SConscript(os.path.join(d, 'SConscript'))
Return('objs')

View File

@@ -0,0 +1,76 @@
import os
import sys
import rtconfig
if os.getenv('RTT_ROOT'):
RTT_ROOT = os.getenv('RTT_ROOT')
else:
RTT_ROOT = os.path.normpath(os.getcwd() + '/../../..')
sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')]
try:
from building import *
except:
print('Cannot found RT-Thread root directory, please check RTT_ROOT')
print(RTT_ROOT)
exit(-1)
def bsp_pkg_check():
import subprocess
check_paths = [
os.path.join("packages", "CMSIS-Core-latest"),
os.path.join("packages", "stm32f4_cmsis_driver-latest"),
os.path.join("packages", "stm32f4_hal_driver-latest")
]
need_update = not all(os.path.exists(p) for p in check_paths)
if need_update:
print("\n===============================================================================")
print("Dependency packages missing, please running 'pkgs --update'...")
print("If no packages are fetched, run 'pkgs --upgrade' first, then 'pkgs --update'...")
print("===============================================================================")
exit(1)
RegisterPreBuildingAction(bsp_pkg_check)
TARGET = 'rt-thread.' + rtconfig.TARGET_EXT
DefaultEnvironment(tools=[])
env = Environment(tools = ['mingw'],
AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS,
CC = rtconfig.CC, CFLAGS = rtconfig.CFLAGS,
AR = rtconfig.AR, ARFLAGS = '-rc',
CXX = rtconfig.CXX, CXXFLAGS = rtconfig.CXXFLAGS,
LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS)
env.PrependENVPath('PATH', rtconfig.EXEC_PATH)
if rtconfig.PLATFORM in ['iccarm']:
env.Replace(CCCOM = ['$CC $CFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -o $TARGET $SOURCES'])
env.Replace(ARFLAGS = [''])
env.Replace(LINKCOM = env["LINKCOM"] + ' --map rt-thread.map')
Export('env')
Export('RTT_ROOT')
Export('rtconfig')
SDK_ROOT = os.path.abspath('./')
if os.path.exists(SDK_ROOT + '/libraries'):
libraries_path_prefix = SDK_ROOT + '/libraries'
else:
libraries_path_prefix = os.path.dirname(SDK_ROOT) + '/libraries'
# prepare building environment
objs = PrepareBuilding(env, RTT_ROOT, has_libcpu=False)
rtconfig.BSP_LIBRARY_TYPE = None
# include drivers
objs.extend(SConscript(os.path.join(libraries_path_prefix, 'HAL_Drivers', 'SConscript'),variant_dir='build/libraries/HAL_Drivers', duplicate=0))
#objs.extend(SConscript(os.path.join(os.getcwd(), 'board', 'ports', 'SConscript')))
# make a building
DoBuilding(TARGET, objs)

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