mirror of
https://github.com/RT-Thread/rt-thread.git
synced 2025-11-16 12:34:33 +00:00
Compare commits
49 Commits
v5.2.2-bet
...
30e1e5e9dc
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
30e1e5e9dc | ||
|
|
ae2a5758bc | ||
|
|
ee20484759 | ||
|
|
4e41e700f0 | ||
|
|
327006cb88 | ||
|
|
92377190ba | ||
|
|
b53293863d | ||
|
|
6a5489f947 | ||
|
|
832fe803df | ||
|
|
8286196d9f | ||
|
|
ec5e72c59a | ||
|
|
538e5ff6d5 | ||
|
|
ddfe2cd61c | ||
|
|
ec27e09df8 | ||
|
|
f56875fff5 | ||
|
|
9150317539 | ||
|
|
32d2cf17c7 | ||
|
|
0d78fa460e | ||
|
|
a81023b88d | ||
|
|
e525c38cb8 | ||
|
|
284081fe4c | ||
|
|
11a2f7eac6 | ||
|
|
d80c211075 | ||
|
|
5119fc5433 | ||
|
|
596f0a8c37 | ||
|
|
44cf90a4ef | ||
|
|
2c9257831e | ||
|
|
6e184553d1 | ||
|
|
cbe9f5d82c | ||
|
|
5b87ac609e | ||
|
|
8153fe5fd9 | ||
|
|
c631b39317 | ||
|
|
96a125ca41 | ||
|
|
2e1cf8d981 | ||
|
|
95f7287313 | ||
|
|
d39a439603 | ||
|
|
4ee00eba9b | ||
|
|
934c8195f4 | ||
|
|
97f316f5d0 | ||
|
|
55306ad133 | ||
|
|
e3640ffc3d | ||
|
|
fa6f86eda3 | ||
|
|
925eab78df | ||
|
|
e458c0df7e | ||
|
|
c91a7f46f5 | ||
|
|
d3ba09a0d7 | ||
|
|
ba509f92c2 | ||
|
|
666fa243f2 | ||
|
|
a10922b01b |
2
.github/ALL_BSP_COMPILE.json
vendored
2
.github/ALL_BSP_COMPILE.json
vendored
@@ -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
139
.github/workflows/README_CI_RESULTS.md
vendored
Normal 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 文件中概述的标准贡献流程。
|
||||
24
.github/workflows/bsp_buildings.yml
vendored
24
.github/workflows/bsp_buildings.yml
vendored
@@ -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
303
.github/workflows/ci_results_comment.yml
vendored
Normal 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}`);
|
||||
}
|
||||
15
.github/workflows/format_check.yml
vendored
15
.github/workflows/format_check.yml
vendored
@@ -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
110
.github/workflows/post_ci_status.yml
vendored
Normal 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}`);
|
||||
}
|
||||
200
.github/workflows/scheduled-ci-trigger.yml
vendored
Normal file
200
.github/workflows/scheduled-ci-trigger.yml
vendored
Normal 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);
|
||||
15
.github/workflows/static_code_analysis.yml
vendored
15
.github/workflows/static_code_analysis.yml
vendored
@@ -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
|
||||
21
.github/workflows/utest_auto_run.yml
vendored
21
.github/workflows/utest_auto_run.yml
vendored
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
1108
bsp/README.md
1108
bsp/README.md
File diff suppressed because it is too large
Load Diff
9
bsp/Vango/.clang-format-ignore
Normal file
9
bsp/Vango/.clang-format-ignore
Normal 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/
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
11
bsp/k230/drivers/interdrv/spi/SConscript
Normal file
11
bsp/k230/drivers/interdrv/spi/SConscript
Normal 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')
|
||||
734
bsp/k230/drivers/interdrv/spi/drv_spi.c
Normal file
734
bsp/k230/drivers/interdrv/spi/drv_spi.c
Normal 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);
|
||||
203
bsp/k230/drivers/interdrv/spi/drv_spi.h
Normal file
203
bsp/k230/drivers/interdrv/spi/drv_spi.h
Normal 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
|
||||
@@ -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')
|
||||
222
bsp/k230/drivers/utest/test_spi.c
Normal file
222
bsp/k230/drivers/utest/test_spi.c
Normal 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);
|
||||
@@ -503,6 +503,10 @@
|
||||
/* GD32 Drivers */
|
||||
|
||||
/* end of GD32 Drivers */
|
||||
|
||||
/* HPMicro SDK */
|
||||
|
||||
/* end of HPMicro SDK */
|
||||
/* end of HAL & SDK Drivers */
|
||||
|
||||
/* sensors drivers */
|
||||
|
||||
@@ -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/
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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/
|
||||
@@ -1,4 +0,0 @@
|
||||
# files format check exclude path, please follow the instructions below to modify;
|
||||
|
||||
dir_path:
|
||||
- Libraries
|
||||
@@ -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/
|
||||
@@ -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
|
||||
@@ -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/
|
||||
@@ -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
|
||||
@@ -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/
|
||||
@@ -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/
|
||||
7
bsp/n32/.clang-format-ignore
Normal file
7
bsp/n32/.clang-format-ignore
Normal 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/
|
||||
@@ -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
|
||||
7
bsp/n32g452xx/.clang-format-ignore
Normal file
7
bsp/n32g452xx/.clang-format-ignore
Normal 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/
|
||||
17
bsp/nxp/.clang-format-ignore
Normal file
17
bsp/nxp/.clang-format-ignore
Normal 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/
|
||||
10
bsp/nxp/imx/imxrt/imxrt1060-nxp-evk/.clang-format-ignore
Normal file
10
bsp/nxp/imx/imxrt/imxrt1060-nxp-evk/.clang-format-ignore
Normal 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/
|
||||
@@ -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
|
||||
@@ -1,4 +0,0 @@
|
||||
# files format check exclude path, please follow the instructions below to modify;
|
||||
|
||||
dir_path:
|
||||
- MIMXRT1060
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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__ */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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__ */
|
||||
@@ -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>
|
||||
|
||||
|
||||
|
||||
@@ -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__ */
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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__ */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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__ */
|
||||
@@ -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
|
||||
|
||||
@@ -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__ */
|
||||
@@ -1,8 +0,0 @@
|
||||
# files format check exclude path, please follow the instructions below to modify;
|
||||
|
||||
dir_path:
|
||||
- LPC55S6X
|
||||
- LPC55S06
|
||||
- LPC5502
|
||||
- LPC55S28
|
||||
- LPC55S36
|
||||
9
bsp/nxp/mcx/mcxa/Libraries/.clang-format-ignore
Normal file
9
bsp/nxp/mcx/mcxa/Libraries/.clang-format-ignore
Normal 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/
|
||||
@@ -1,4 +0,0 @@
|
||||
# files format check exclude path, please follow the instructions below to modify;
|
||||
|
||||
dir_path:
|
||||
- MCXA153
|
||||
@@ -1,4 +0,0 @@
|
||||
# files format check exclude path, please follow the instructions below to modify;
|
||||
|
||||
dir_path:
|
||||
- MCXC444
|
||||
@@ -1,4 +0,0 @@
|
||||
# files format check exclude path, please follow the instructions below to modify;
|
||||
|
||||
dir_path:
|
||||
- MCXN947
|
||||
@@ -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/
|
||||
|
||||
@@ -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
|
||||
9
bsp/rockchip/.clang-format-ignore
Normal file
9
bsp/rockchip/.clang-format-ignore
Normal 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/
|
||||
@@ -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
|
||||
12
bsp/stm32/.clang-format-ignore
Normal file
12
bsp/stm32/.clang-format-ignore
Normal 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/
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
1456
bsp/stm32/stm32f407-micu/.config
Normal file
1456
bsp/stm32/stm32f407-micu/.config
Normal file
File diff suppressed because it is too large
Load Diff
42
bsp/stm32/stm32f407-micu/.gitignore
vendored
Normal file
42
bsp/stm32/stm32f407-micu/.gitignore
vendored
Normal 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
|
||||
15
bsp/stm32/stm32f407-micu/Kconfig
Normal file
15
bsp/stm32/stm32f407-micu/Kconfig
Normal 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
|
||||
137
bsp/stm32/stm32f407-micu/README.md
Normal file
137
bsp/stm32/stm32f407-micu/README.md
Normal 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卡槽,此外还搭载了比较常用的传感器,温湿度传感器和姿态传感器。
|
||||
|
||||
开发板外观如下图所示:
|
||||
|
||||

|
||||
|
||||
该开发板常用 **板载资源** 如下:
|
||||
|
||||
- MCU:STM32F407VET6,主频 168MHz,512KB FLASH ,192KB RAM
|
||||
- 外部 FLASH:ZD25WQ32,4MB
|
||||
- 常用外设
|
||||
- LED:3个,DS0(红色,PC2),DS1(绿色,PC1),DS2(蓝色,PC0)
|
||||
- 按键:1个,USER(PC3)
|
||||
- 常用接口:USB 转串口、SD 卡接口等
|
||||
- 调试接口,支持SWD(板载DAPLink)
|
||||
|
||||
开发板更多详细信息请参考【立创开源硬件平台】 [米醋·McoreSTM32电控板](https://oshwhub.com/the-first-development-team-of-no/kong-zhi-ban)。
|
||||
|
||||
## 外设支持
|
||||
|
||||
本 BSP 目前对外设的支持情况如下:
|
||||
|
||||
| **板载外设** | **支持情况** | **备注** |
|
||||
| :----------------- | :----------: | :------------------------------------- |
|
||||
| DAPLink虚拟串口 | 支持 | 已连接到芯片的UART1(PA9,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>
|
||||
15
bsp/stm32/stm32f407-micu/SConscript
Normal file
15
bsp/stm32/stm32f407-micu/SConscript
Normal 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')
|
||||
76
bsp/stm32/stm32f407-micu/SConstruct
Normal file
76
bsp/stm32/stm32f407-micu/SConstruct
Normal 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
Reference in New Issue
Block a user