Compare commits

..

2 Commits

Author SHA1 Message Date
copilot-swe-agent[bot]
621d29d5d2 [Documentation] Initial setup for DFS v2 documentation structure
Co-authored-by: BernardXiong <1241087+BernardXiong@users.noreply.github.com>
2025-10-29 00:44:23 +00:00
copilot-swe-agent[bot]
3d9e16007e Initial plan 2025-10-28 23:50:08 +00:00
73 changed files with 251 additions and 10915 deletions

View File

@@ -482,7 +482,6 @@
"RTT_BSP": "xuantie",
"RTT_TOOL_CHAIN": "sourcery-Xuantie-900-gcc-elf-newlib",
"SUB_RTT_BSP": [
"xuantie/smartl/e901",
"xuantie/smartl/e902",
"xuantie/smartl/e906",
"xuantie/smartl/e907",

View File

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

View File

@@ -13,6 +13,9 @@ 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
@@ -43,12 +46,6 @@ 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 }}
@@ -180,10 +177,10 @@ jobs:
- name: Install Xuantie-900-gcc-elf-newlib Tools
if: ${{ matrix.legs.RTT_TOOL_CHAIN == 'sourcery-Xuantie-900-gcc-elf-newlib' && success() }}
run: |
wget -q https://occ-oss-prod.oss-cn-hangzhou.aliyuncs.com/resource//1751370399722/Xuantie-900-gcc-elf-newlib-x86_64-V3.2.0-20250627.tar.gz
sudo tar -zxvf Xuantie-900-gcc-elf-newlib-x86_64-V3.2.0-20250627.tar.gz -C /opt
/opt/Xuantie-900-gcc-elf-newlib-x86_64-V3.2.0/bin/riscv64-unknown-elf-gcc --version
echo "RTT_EXEC_PATH=/opt/Xuantie-900-gcc-elf-newlib-x86_64-V3.2.0/bin" >> $GITHUB_ENV
wget -q https://occ-oss-prod.oss-cn-hangzhou.aliyuncs.com/resource//1744884010580/Xuantie-900-gcc-elf-newlib-x86_64-V3.0.2-20250410.tar.gz
sudo tar -zxvf Xuantie-900-gcc-elf-newlib-x86_64-V3.0.2-20250410.tar.gz -C /opt
/opt/Xuantie-900-gcc-elf-newlib-x86_64-V3.0.2/bin/riscv64-unknown-elf-gcc --version
echo "RTT_EXEC_PATH=/opt/Xuantie-900-gcc-elf-newlib-x86_64-V3.0.2/bin" >> $GITHUB_ENV
- name: Install Xuantie-900-gcc-linux-musl Tools
if: ${{ matrix.legs.RTT_TOOL_CHAIN == 'sourcery-Xuantie-900-gcc-linux-musl' && success() }}
@@ -291,17 +288,4 @@ jobs:
uses: actions/upload-artifact@main
with:
name: 00_all_bsp_output_${{ github.sha }}
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
path: output/

View File

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

View File

@@ -29,17 +29,4 @@ jobs:
shell: bash
run: |
pip install click chardet PyYaml
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
python tools/ci/file_check.py check 'https://github.com/RT-Thread/rt-thread' 'master'

View File

@@ -1,108 +0,0 @@
#
# 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
with:
script: |
const prNumber = ${{ inputs.pr_number }};
const workflowName = '${{ inputs.workflow_name }}';
const workflowStatus = '${{ inputs.workflow_status }}';
// Status emoji mapping
const statusEmoji = workflowStatus === 'success' ? '✅' : '❌';
const timestamp = new Date().toISOString();
// Try to find existing comment
const comments = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber
});
const botComment = comments.data.find(comment =>
comment.user.login === 'github-actions[bot]' &&
comment.body.includes('<!-- CI Status Comment -->')
);
// Get all workflow runs for this PR to build comprehensive status
let allStatuses = {};
if (botComment) {
// Parse existing statuses from comment
const statusRegex = /- (✅|❌|🟡) \*\*(.+?)\*\*/g;
let match;
while ((match = statusRegex.exec(botComment.body)) !== null) {
allStatuses[match[2]] = match[1];
}
}
// Update current workflow status
allStatuses[workflowName] = statusEmoji;
// Build comment body
let commentBody = '<!-- CI Status Comment -->\n';
commentBody += '## 🤖 CI Test Results\n\n';
commentBody += `**Last Updated:** ${timestamp}\n\n`;
commentBody += '### Workflow Status:\n\n';
for (const [name, emoji] of Object.entries(allStatuses)) {
commentBody += `- ${emoji} **${name}**\n`;
}
commentBody += '\n---\n';
commentBody += '✅ Success | ❌ Failure | 🟡 In Progress\n\n';
commentBody += '*This comment is automatically updated as CI workflows complete.*\n';
if (botComment) {
// Update existing comment
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: botComment.id,
body: commentBody
});
console.log(`Updated comment ${botComment.id} on PR #${prNumber}`);
} else {
// Create new comment
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
body: commentBody
});
console.log(`Created new comment on PR #${prNumber}`);
}

View File

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

View File

@@ -54,17 +54,4 @@ jobs:
sudo make install FILESDIR=/usr/local/share/Cppcheck
cppcheck --version
cd ..
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
python tools/ci/cpp_check.py check

View File

@@ -18,13 +18,6 @@ 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 }}
@@ -304,16 +297,4 @@ jobs:
echo "=========================================================================================="
break
fi
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
done

View File

@@ -1,184 +1,3 @@
# RT-Thread v5.2.2 Released
Change Log Since v5.2.1 Release.
## Kernel
* Fix scheduling exception caused by interrupt preemption in rt_schedule.[(#10715)](https://github.com/RT-Thread/rt-thread/pull/10715)
* Fix the legacy issue related to the length of the object name version.[(#10537)](https://github.com/RT-Thread/rt-thread/pull/10537)
* Fixed buffer overflow vulnerability in object.[(#10523)](https://github.com/RT-Thread/rt-thread/pull/10523)
* Add up scheduler critical switch flag.[(#10581)](https://github.com/RT-Thread/rt-thread/pull/10581)
* Update the default value of RT_NAME_MAX to 12.[(#10839)](https://github.com/RT-Thread/rt-thread/pull/10839)
* Feat the rt_scheduler lock nest uses atomic operations.[(#10621)](https://github.com/RT-Thread/rt-thread/pull/10621)
## Components
* **Drivers**
* **Serial:**
* serial_v1
* Fix correct data loss logic when RX ring buffer is full.
* serial_v2
* Fix the bug of RX flush under DMA.
* Add serial V2 buffer configuration via Kconfig.
* Feat optimize serial v2. [(#10603)](https://github.com/RT-Thread/rt-thread/pull/10603)
* Feat modify the default configuration of the RT_SERIAL_CONFIG_DEFAULT structure to support parameters in the absence of DMA configuration.
* **RTC:**
* Add the alarm using local time for calculation.
* **CAN:**
* Fixed the issue where the thread calling CAN int TX was suspended when CAN at the bottom layer failed to work.
* Feat: Implement non-blocking send mechanism and enhance CAN driver functionality.
* **SPI:**
* Add SPI device detach function.[(#10733)](https://github.com/RT-Thread/rt-thread/pull/10733)
* Update and fix up the SPI.
* **ADC:**
* Fixed cppcheck error.
* Remove build warnings.
* **ktime:**
* Remove unused rt_ktime_hrtimer_getcnt for hrtimer.
* **wlan:**
* Update SECURITY_UNKNOWN value.
* **LWP**
* Fix potential signal handler infinite loop for riscv.
* Feat: Restore TP register in arch_thread_signal_enter to fix user-mode memory access.
* **Libc**
* Add comments for some pthread functions.
* pthreads: Fix pthread_cond_timedwait lacks timeout wakeup.
* ensure compatibility with newlib <3.4.0 by handling removed __sdidinit. [(#10791)](https://github.com/RT-Thread/rt-thread/pull/10791)
* **DFS**
* **DFS v2**:
* Fix bugs for function _get_parent_path(). [(#10539)](https://github.com/RT-Thread/rt-thread/pull/10539)
* **Net**
* **SAL/Socket:**
* Fixed CI compilation failure in sal/src/sal_socket.c.
* Fix memory leak when sal_socket failed.
* improve the error return of sal.
* **Netdev:**
* Fixed compilation errors when enabling IPv6 and IPv4 dual-stack support.
* Fixed netdev_unregister missing correct return value. [(#10693)](https://github.com/RT-Thread/rt-thread/pull/10693)
* Expose netdev_set_dns and netdev_set_if. [(#10128)](https://github.com/RT-Thread/rt-thread/pull/10128)
* **AT:**
* at_client add deInit port. [(#10598)](https://github.com/RT-Thread/rt-thread/pull/10598)
* **Finsh:**
* Fixed clear out the useless copy operations. [(#10699)](https://github.com/RT-Thread/rt-thread/pull/10699)
* Feat add support for the Home, Insert, Delete and End keys, and improve input mode processing.[(#10595)](https://github.com/RT-Thread/rt-thread/pull/10595)
* Feat: Add new features (delete by word, switch cursor, etc.).
* **USB:**
* Update (cherryusb): update to v1.5.1.
* Fixed several issues related to cherryusb.[(#10844)](https://github.com/RT-Thread/rt-thread/pull/10844)
* **Ulog:**
* Fix:filter should not be associated with ULOG_USING_COLOR and ULOG_USING_SYSLOG configurations.
* **IPC:**
* Pass rt_tick_t for RT_TIMER_CTRL_SET_TIME and RT_TIMER_CTRL_GET_TIME.[(#10717)](https://github.com/RT-Thread/rt-thread/pull/10717)
## DM
* NVME: fix up the QUEUE alloc error no check.
* Thermal: Fix up the C99, 6.8.1 Labeled statements p4; Fix up the PWM-FAN remove handle data ptr.
* PCI: Add SoC PCI Kconfig import; Multiple PCI-related fixes; Fix and optimize interrupt-related issues.
* WDT: Support related to Intel 6300ESB/Synopsys Watchdog, etc.
## Libcpu
* **AArch64:**
* Fix up MMU and linker warning.
* Fix rt_aspace_init error when KERNEL_VADDR_START >= 0x80000000.
* Add the configuration of libcpu/aarch64 KERNEL ASPACE START.
* Update Hypercall API.
* Remove unused rt_hw_set_gtimer_frq.
* **Cortex-M33:**
* Fix the M33 assembly syntax errors and fix the compilation error of BSP.
* Added HardFault_Handler to save floating point registers.
* **Cortex-M4:**
* Fixed compilation error.
* Added HardFault_Handler to save floating point registers.
* **Cortex-M3:**
* The parameter passed to the unified rt_exception_hook is exception_stack. [(#10619)](https://github.com/RT-Thread/rt-thread/pull/10619)
* **RISC-V:**
* Fix type mismatch of `_query`.
* Fix the support for RV32E. RV32E does not support the s2 register. Modify it to the s1 register.
* Use volatile RW for claim and complete.
* Add spaces to fix `Wliteral-suffix`.
* Add comment for the round down of symb_pc.
* Remove `rt_hw_cpu_id` in `cpuport.h` to fix error.
## Tools
* Add support for package.json, refactor BuildPackage function to handle new format.
* Add documents for tools script; Add NG for tools. [(#10572)](https://github.com/RT-Thread/rt-thread/pull/10572)
* Add workspace generation for RT-Thread root directory.
* Add vsc_workspace target in scons.
* Add DTC (Devicetree Compiler) tools.
* Add clang-format formatting script for CI.
* Optimize the file opening method.
* Clang format ignore migration.
* Improve[clang-format]: optimize the formatting logic for RT-Thread coding standard.
## Action
* Fixed CI: ARDUINO_ADAFRUIT_SENSORLAB compilation failure issue.
* Fixed CI compilation failure in sal/src/sal_socket.c.[(#10854)](https://github.com/RT-Thread/rt-thread/pull/10854)
* Merge same tag with different paths, remove Path display from CI comment.
* Add Copilot review title keywords.
* Add concurrency control to GitHub Actions. [(#10761)](https://github.com/RT-Thread/rt-thread/pull/10761)
* integrate utest run ci. [(#10748)](https://github.com/RT-Thread/rt-thread/pull/10748)
* Improve the comment instructions for the PR format bot.[(#10747)](https://github.com/RT-Thread/rt-thread/pull/10747)
## Documents
* **Doxygen:**
* Fix some document issues.
* Update naming rule for utest-case.
* Update doc for env to latest.
* Update some document content.
* Group name all in lowercase. [(#10530)](https://github.com/RT-Thread/rt-thread/pull/10530)
* Grouping and page optimization related to device driver.
* use layout to control the HTML display.
* Add doxygen comments for scheduler. [(#10366)](https://github.com/RT-Thread/rt-thread/pull/10366) and lwp
* update doxygen version to v1.9.8 .
## Utest
* Add netdev/lwip/filesystem/memory pool/SAL/system performance API test case.
* Support autocomplete of utest cases for `utest_run`. [(#10701)](https://github.com/RT-Thread/rt-thread/pull/10701)
* Feat:reorganize utest menu.
* Feat:rename files and update naming according to new rule.
* Feat:reorganize utest framework structure (initial version).
* Feat:unify config name. [(#10808)](https://github.com/RT-Thread/rt-thread/pull/10808)
* Feat:integrate test cases into utest framework. [(#10665)](https://github.com/RT-Thread/rt-thread/pull/10665)
* Move driver-related test cases under `drivers`.
* Move and enhance C++ test cases.
## BSP
* Some driver issues have been resolved and some driver support has been added.
* **Added/Updated BSPs:**
* **xuantie**
* E901
* **Renesas:**
* ek-ra6e2
* ek-ra4e2
* ek-ra2a1
* ek-ra2e2
* ek-ra4m1
* **GD32:**
* gd32h759i-eval
* gd32470i-eval
* gd32e230-lckfb
* **NXP:**
* MCX E247
* FRDM-MCXE247
* FRDM-MCXA346
* **HPMicro:**
* hpm6p00evk
* hpm5e00evk
* **Phytium**
* **Raspberry RP2350**
# RT-Thread v5.2.1 Released
Change Log Since v5.2.0 Release

View File

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

View File

@@ -227,7 +227,6 @@ CONFIG_FINSH_THREAD_STACK_SIZE=8192
CONFIG_FINSH_USING_HISTORY=y
CONFIG_FINSH_HISTORY_LINES=5
# CONFIG_FINSH_USING_WORD_OPERATION is not set
# CONFIG_FINSH_USING_FUNC_EXT is not set
CONFIG_FINSH_USING_SYMTAB=y
CONFIG_FINSH_CMD_SIZE=80
CONFIG_MSH_USING_BUILT_IN_COMMANDS=y
@@ -426,7 +425,6 @@ CONFIG_RT_USING_POSIX_TIMER=y
#
CONFIG_RT_USING_SAL=y
CONFIG_SAL_INTERNET_CHECK=y
CONFIG_SOCKET_TABLE_STEP_LEN=4
#
# Docking with protocol stacks
@@ -1619,7 +1617,6 @@ CONFIG_PKG_ZLIB_VER="latest"
#
# Drivers Configuration
#
# CONFIG_BSP_USING_I2C is not set
# CONFIG_BSP_USING_RTC is not set
# CONFIG_BSP_USING_ADC is not set
# CONFIG_BSP_USING_TS is not set

View File

@@ -1,31 +1,4 @@
menu "Drivers Configuration"
menuconfig BSP_USING_I2C
bool "Enable I2C"
select RT_USING_I2C
default n
if BSP_USING_I2C
config BSP_USING_I2C0
bool "Enable I2C0"
default n
config BSP_USING_I2C1
bool "Enable I2C1"
default n
config BSP_USING_I2C2
bool "Enable I2C2"
default n
config BSP_USING_I2C3
bool "Enable I2C3"
default n
config BSP_USING_I2C4
bool "Enable I2C4"
default n
endif
config BSP_USING_RTC
bool "Enable RTC"

View File

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

View File

@@ -1,528 +0,0 @@
/* 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 <rthw.h>
#include <rtdevice.h>
#include <riscv_io.h>
#include <ioremap.h>
#include "board.h"
#include "drv_i2c.h"
#include "sysctl_clk.h"
#undef DBG_TAG
#undef DBG_LVL
#define DBG_TAG "drv_i2c"
#define DBG_LVL DBG_INFO
#include <rtdbg.h>
struct _i2c_speed_cfg
{
rt_uint16_t hcnt;
rt_uint16_t lcnt;
rt_uint16_t spklen;
};
struct k230_i2c_dev
{
struct rt_i2c_bus_device dev;
const char *name;
rt_ubase_t base;
size_t size;
int vector;
rt_uint32_t clock;
struct rt_i2c_msg *msg;
struct _i2c_speed_cfg speed_cfg;
};
static rt_size_t k230_i2c_get_timer(rt_size_t base)
{
return rt_tick_get() - base ;
}
static void k230_i2c_enable(struct k230_i2c_dev *dev, rt_bool_t enable)
{
volatile i2c_t *i2c = (i2c_t *)dev->base;
rt_uint32_t en_value = enable ? 1 : 0;
int timeout = 100;
do
{
i2c->enable.enable = en_value;
if(i2c->enable_status.en == en_value)
{
return;
}
/*
* Wait 10 times the signaling period of the highest I2C
* transfer supported by the driver (for 400KHz this is
* 25us) as described in the DesignWare I2C databook.
*/
rt_hw_us_delay(25);
}while(timeout--);
LOG_E("timeout in %s i2c\n", enable ? "enable" : "disable");
}
static void k230_i2c_set_bus_timeout(struct k230_i2c_dev *dev, rt_uint32_t timeout)
{
float tick = 0;
tick = RT_TICK_PER_SECOND / 1000.0f; /* ms to tick */
dev->dev.timeout = (rt_uint32_t)(timeout * tick);
}
static int k230_i2c_set_bus_speed(struct k230_i2c_dev *dev, rt_uint32_t speed)
{
volatile i2c_t *i2c = (i2c_t *)dev->base;
rt_uint32_t i2c_spd, period, spklen, ft;
/*
* Calculate clock counts for I2C speed
* hcnt + lcnt + spklen + 7 + 1 + fall_time * clk = clk / speed
* fall_time = 10ns
* spklen = 0~50ns
*/
spklen = dev->clock * 10 / 1e9;
ft = dev->clock * 10 / 1e9;
period = dev->clock / speed;
period = period - spklen - 7 - 1 - ft;
dev->speed_cfg.lcnt = period / 2;
dev->speed_cfg.hcnt = period - dev->speed_cfg.lcnt;
dev->speed_cfg.spklen = spklen;
if(speed <= I2C_STANDARD_SPEED_UP)
{
i2c_spd = I2C_SPEED_MODE_STANDARD;
}
else if(speed <= I2C_FAST_SPEED_UP)
{
i2c_spd = I2C_SPEED_MODE_FAST;
}
else if(speed <= I2C_MAX_SPEED_UP)
{
i2c_spd = I2C_SPEED_MODE_MAX;
}
else
{
return -RT_EINVAL;
}
/* to set speed cltr must be disabled */
k230_i2c_enable(dev, RT_FALSE);
switch(i2c_spd)
{
case I2C_SPEED_MODE_STANDARD:
i2c->ss_ufm_scl_hcnt.cnt = dev->speed_cfg.hcnt;
i2c->ss_ufm_scl_lcnt.cnt = dev->speed_cfg.lcnt;
i2c->fs_ufm_spklen.spklen = dev->speed_cfg.spklen;
break;
case I2C_SPEED_MODE_FAST:
i2c->fs_scl_hcnt_ufm_tbuf_cnt.cnt = dev->speed_cfg.hcnt;
i2c->fs_scl_lcnt.cnt = dev->speed_cfg.lcnt;
i2c->fs_ufm_spklen.spklen = dev->speed_cfg.spklen;
break;
case I2C_SPEED_MODE_MAX:
i2c->hs_scl_hcnt.cnt = dev->speed_cfg.hcnt;
i2c->hs_scl_lcnt.cnt = dev->speed_cfg.lcnt;
i2c->hs_spklen.spklen = dev->speed_cfg.spklen;
break;
default: break;
}
i2c->con.speed = i2c_spd;
/* Enable back i2c now speed set */
k230_i2c_enable(dev, RT_TRUE);
return RT_EOK;
}
static void k230_i2c_set_addr(struct k230_i2c_dev *dev)
{
volatile i2c_t *i2c = (i2c_t *)dev->base;
rt_uint16_t i2c_addr = dev->msg->addr;
/* Disable i2c */
k230_i2c_enable(dev, RT_FALSE);
if(dev->msg->flags & RT_I2C_ADDR_10BIT || dev->dev.flags & RT_I2C_ADDR_10BIT)
{
i2c->tar.master_10bit_addr = 1;
i2c_addr &= 0x3FF;
}
else
{
i2c->tar.master_10bit_addr = 0;
i2c_addr &= 0x7F;
}
i2c->tar.tar = i2c_addr;
/* Enable i2c */
k230_i2c_enable(dev, RT_TRUE);
}
static void k230_i2c_flush_rxfifo(struct k230_i2c_dev *dev)
{
volatile i2c_t *i2c = (i2c_t *)dev->base;
while(i2c->status.rfne)
{
readl(&i2c->data_cmd);
}
}
static int k230_i2c_wait_for_bus_busy(struct k230_i2c_dev *dev)
{
rt_size_t start_time = k230_i2c_get_timer(0);
volatile i2c_t *i2c = (i2c_t *)dev->base;
while((i2c->status.mst_activity) || !(i2c->status.tfe))
{
/* Evaluate timeout */
if(k230_i2c_get_timer(start_time) > (rt_size_t)dev->dev.timeout * I2C_TX_FIFO_SIZE)
{
return -RT_ETIMEOUT;
}
}
return RT_EOK;
}
static int k230_i2c_xfer_init(struct k230_i2c_dev *dev)
{
volatile i2c_t *i2c = (i2c_t *)dev->base;
rt_uint8_t addr = 0;
if(k230_i2c_wait_for_bus_busy(dev) != RT_EOK)
{
return -RT_EBUSY;
}
k230_i2c_set_addr(dev);
return RT_EOK;
}
static int k230_i2c_xfer_finish(struct k230_i2c_dev *dev)
{
volatile i2c_t *i2c = (i2c_t *)dev->base;
rt_uint32_t start_stop_det = k230_i2c_get_timer(0);
while (1)
{
if(i2c->raw_intr_stat.stop_det)
{
readl(&i2c->clr_stop_det);
break;
}
else if (k230_i2c_get_timer(start_stop_det) > dev->dev.timeout)
{
break;
}
}
if (k230_i2c_wait_for_bus_busy(dev) != RT_EOK)
{
return -RT_EBUSY;
}
k230_i2c_flush_rxfifo(dev);
return RT_EOK;
}
static int _k230_i2c_read(struct k230_i2c_dev *dev)
{
volatile i2c_t *i2c = (i2c_t *)dev->base;
rt_size_t start_time_rx = 0;
rt_uint32_t recv_len = dev->msg->len;
rt_uint32_t tran_len = dev->msg->len;
rt_uint8_t *buffer = dev->msg->buf;
rt_uint32_t cmd = 0;
/* If no start condition is sent before reading, then send a repeated start. */
if(dev->msg->flags & RT_I2C_NO_START)
{
cmd |= I2C_DATA_CMD_RESTART;
}
else
{
if(k230_i2c_xfer_init(dev) != RT_EOK)
{
return -RT_EBUSY;
}
}
start_time_rx = k230_i2c_get_timer(0);
while(recv_len || tran_len)
{
if (tran_len)
{
while(i2c->status.tfnf == 0);
/* Write stop when the last byte */
cmd = tran_len == 1 ? cmd | I2C_DATA_CMD_STOP : cmd;
/* Write to data cmd register to trigger i2c */
writel(cmd | I2C_DATA_CMD_READ, &i2c->data_cmd);
cmd = 0;
tran_len--;
}
if(i2c->status.rfne)
{
*buffer++ = i2c->data_cmd.dat;
recv_len--;
start_time_rx = k230_i2c_get_timer(0);
}
else if(k230_i2c_get_timer(start_time_rx) > dev->dev.timeout)
{
return -RT_ETIMEOUT;
}
}
return k230_i2c_xfer_finish(dev);
}
static int _k230_i2c_write(struct k230_i2c_dev *dev)
{
volatile i2c_t *i2c = (i2c_t *)dev->base;
rt_size_t start_time_tx = 0;
rt_uint32_t tran_len = dev->msg->len;
rt_uint8_t *buffer = dev->msg->buf;
rt_uint32_t cmd = 0;
rt_uint32_t cut = 0;
if (k230_i2c_xfer_init(dev) != RT_EOK)
{
return -RT_EBUSY;
}
start_time_tx = k230_i2c_get_timer(0);
while(tran_len)
{
if(i2c->status.tfnf)
{
/* If there is no stop flag, the stop condition will not be sent at the last byte. */
if(tran_len == 1 && !(dev->msg->flags & RT_I2C_NO_STOP))
{
cmd |= I2C_DATA_CMD_STOP;
}
else
{
cmd &= ~I2C_DATA_CMD_STOP;
}
cmd |= *buffer++;
writel(cmd, &i2c->data_cmd);
cmd = 0;
tran_len--;
start_time_tx = k230_i2c_get_timer(0);
}
else if(k230_i2c_get_timer(start_time_tx) > dev->dev.timeout)
{
return -RT_ETIMEOUT;
}
}
if (dev->msg->flags & RT_I2C_NO_STOP)
{
return RT_EOK;
}
if (k230_i2c_wait_for_bus_busy(dev) != RT_EOK)
{
return -RT_EBUSY;
}
return RT_EOK;
}
static rt_ssize_t k230_i2c_xfer(struct rt_i2c_bus_device *bus, struct rt_i2c_msg msgs[], rt_uint32_t num)
{
struct k230_i2c_dev *i2c_dev = rt_container_of(bus, struct k230_i2c_dev, dev);
volatile i2c_t *i2c = (i2c_t *)i2c_dev->base;
int ret;
rt_ssize_t send_mesgs = num;
for (; num > 0; num--, msgs++)
{
i2c_dev->msg = msgs;
if(msgs->flags & RT_I2C_RD)
{
ret = _k230_i2c_read(i2c_dev);
}
else
{
ret = _k230_i2c_write(i2c_dev);
}
if (ret != RT_EOK)
{
return -RT_EIO;
}
}
return send_mesgs;
}
static rt_err_t k230_i2c_control(struct rt_i2c_bus_device *bus, int cmd, void *args)
{
struct k230_i2c_dev *i2c_dev = rt_container_of(bus, struct k230_i2c_dev, dev);
rt_uint32_t arg = *(rt_uint32_t *)args;
rt_err_t ret;
RT_ASSERT(bus != RT_NULL);
switch (cmd)
{
/* set 10-bit addr mode */
case RT_I2C_DEV_CTRL_10BIT:
if(arg & RT_I2C_ADDR_10BIT)
{
i2c_dev->dev.flags |= RT_I2C_ADDR_10BIT;
}
else
{
i2c_dev->dev.flags &= ~RT_I2C_ADDR_10BIT;
}
break;
case RT_I2C_DEV_CTRL_TIMEOUT:
k230_i2c_set_bus_timeout(i2c_dev, arg);
break;
case RT_I2C_DEV_CTRL_CLK:
ret = k230_i2c_set_bus_speed(i2c_dev, arg);
if (ret != RT_EOK)
{
return -RT_EIO;
}
break;
default: break;
}
return RT_EOK;
}
static void k230_i2c_master_init(struct k230_i2c_dev *dev)
{
volatile i2c_t *i2c = (i2c_t *)dev->base;
/* Disable i2c */
k230_i2c_enable(dev, RT_FALSE);
i2c->con.slave_disable = 1;
i2c->con.restart_en = 1;
i2c->con.master_mode = 1;
i2c->tx_tl.tl = I2C_TX_TL;
i2c->rx_tl.tl = I2C_RX_TL;
i2c->intr_mask.m_stop_det = 1;
/* Enable i2c */
k230_i2c_enable(dev, RT_TRUE);
}
static const struct rt_i2c_bus_device_ops k230_i2c_ops =
{
.master_xfer = k230_i2c_xfer,
.i2c_bus_control = k230_i2c_control,
};
static struct k230_i2c_dev k230_i2c_devs[] =
{
#ifdef BSP_USING_I2C0
{
.name = "i2c0",
.base = I2C0_BASE_ADDR,
.size = I2C0_IO_SIZE,
.vector = K230_IRQ_I2C0,
},
#endif
#ifdef BSP_USING_I2C1
{
.name = "i2c1",
.base = I2C1_BASE_ADDR,
.size = I2C1_IO_SIZE,
.vector = K230_IRQ_I2C1,
},
#endif
#ifdef BSP_USING_I2C2
{
.name = "i2c2",
.base = I2C2_BASE_ADDR,
.size = I2C2_IO_SIZE,
.vector = K230_IRQ_I2C2,
},
#endif
#ifdef BSP_USING_I2C3
{
.name = "i2c3",
.base = I2C3_BASE_ADDR,
.size = I2C3_IO_SIZE,
.vector = K230_IRQ_I2C3,
},
#endif
#ifdef BSP_USING_I2C4
{
.name = "i2c4",
.base = I2C4_BASE_ADDR,
.size = I2C4_IO_SIZE,
.vector = K230_IRQ_I2C4,
},
#endif
};
int rt_hw_i2c_init(void)
{
int i;
for (i = 0; i < sizeof(k230_i2c_devs) / sizeof(k230_i2c_devs[0]); i++)
{
k230_i2c_devs[i].base = (rt_ubase_t)rt_ioremap((void *)k230_i2c_devs[i].base, k230_i2c_devs[i].size);
k230_i2c_devs[i].dev.ops = &k230_i2c_ops;
k230_i2c_devs[i].clock = sysctl_clk_get_leaf_freq(SYSCTL_CLK_I2C0_CORE + i);
k230_i2c_master_init(&k230_i2c_devs[i]);
k230_i2c_set_bus_timeout(&k230_i2c_devs[i], I2C_DEFAULT_TIMEOUT);
k230_i2c_set_bus_speed(&k230_i2c_devs[i], I2C_DEFAULT_SPEED);
rt_i2c_bus_device_register(&k230_i2c_devs[i].dev, k230_i2c_devs[i].name);
LOG_I("i2c%d master mode, i2c%d clock=%dHz\n", i, i, k230_i2c_devs[i].clock);
}
return RT_EOK;
}
INIT_DEVICE_EXPORT(rt_hw_i2c_init);

View File

@@ -1,704 +0,0 @@
/* 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_I2C_H__
#define __DRV_I2C_H__
#include <stdint.h>
#define BIT(x) (1<<(x))
/* Speed Selection */
#define I2C_SPEED_MODE_STANDARD 1
#define I2C_SPEED_MODE_FAST 2
#define I2C_SPEED_MODE_MAX 3
#define I2C_MAX_SPEED_UP 3400000
#define I2C_FAST_SPEED_UP 1000000
#define I2C_STANDARD_SPEED_UP 100000
#define I2C_DEFAULT_SPEED 400000
#define I2C_DEFAULT_TIMEOUT 8 /* 8ms */
/* i2c data cmd definition */
#define I2C_DATA_CMD_READ BIT(8)
#define I2C_DATA_CMD_STOP BIT(9)
#define I2C_DATA_CMD_RESTART BIT(10)
#define I2C_DATA_CMD_FIRST_DATA_BYTE BIT(11)
/* i2c fifo size */
#define I2C_TX_FIFO_SIZE 32 /* 32 * 32bit */
#define I2C_RX_FIFO_SIZE 32 /* 64 * 8bit */
/* fifo threshold register definitions */
#define I2C_TL0 0x00
#define I2C_TL1 0x01
#define I2C_TL2 0x02
#define I2C_TL3 0x03
#define I2C_TL4 0x04
#define I2C_TL5 0x05
#define I2C_TL6 0x06
#define I2C_TL7 0x07
#define I2C_RX_TL I2C_TL0
#define I2C_TX_TL I2C_TL0
/* i2c control register(offset address 0x00) */
typedef struct _i2c_ic_con
{
uint32_t master_mode : 1;
uint32_t speed : 2;
uint32_t slave_10bit_addr : 1;
uint32_t master_10bit_addr : 1;
uint32_t restart_en : 1;
uint32_t slave_disable : 1;
uint32_t stop_det_ifaddressed : 1;
uint32_t tx_empty_ctrl : 1;
uint32_t rx_fifo_full_hld_ctrl : 1;
uint32_t stop_det_if_master_active : 1;
uint32_t bus_clear_feature_ctrl : 1;
uint32_t rsvd_1 : 4; /* reserved */
uint32_t optional_sar_ctrl : 1;
uint32_t smbus_slave_quick_en : 1;
uint32_t smbus_arp_en : 1;
uint32_t smbus_persisent_slv_addr_en : 1;
uint32_t rsvd_2 : 12; /* reserved */
} __attribute__((packed, aligned(4))) i2c_ic_con_t;
/* i2c target address register(offset address 0x04) */
typedef struct _i2c_ic_tar
{
uint32_t tar : 10;
uint32_t gc_or_start : 1;
uint32_t special : 1;
uint32_t master_10bit_addr : 1;
uint32_t device_id : 1;
uint32_t rsvd_1 : 2; /* reserved */
uint32_t smbus_quick_cmd : 1;
uint32_t rsvd_2 : 15; /* reserved */
} __attribute__((packed, aligned(4))) i2c_ic_tar_t;
/* i2c slave address register(offset address 0x08) */
typedef struct _i2c_ic_sar
{
uint32_t sar : 10;
uint32_t rsvd : 22; /* reserved */
} __attribute__((packed, aligned(4))) i2c_ic_sar_t;
/* i2c high speed master mode code address register(offset address 0x0c) */
typedef struct _i2c_ic_hs_maddr
{
uint32_t mar : 3;
uint32_t rsvd : 29; /* reserved */
} __attribute__((packed, aligned(4))) i2c_ic_hs_maddr_t;
/* i2c rx/tx data buffer and command register(offset address 0x10) */
typedef struct _i2c_ic_data_cmd
{
uint32_t dat : 8;
uint32_t cmd : 1;
uint32_t stop : 1;
uint32_t restart : 1;
uint32_t first_data_byte : 1;
uint32_t rsvd : 20; /* reserved */
} __attribute__((packed, aligned(4))) i2c_ic_data_cmd_t;
/* i2c standard/ultra-fast speed clock scl high count register(offset address 0x14) */
typedef struct _i2c_ic_ss_ufm_scl_hcnt
{
uint32_t cnt : 16;
uint32_t rsvd : 16; /* reserved */
} __attribute__((packed, aligned(4))) i2c_ic_ss_ufm_scl_hcnt_t;
/* i2c standard/ultra-fast speed clock scl low count register(offset address 0x18) */
typedef struct _i2c_ic_ss_ufm_scl_lcnt
{
uint32_t cnt : 16;
uint32_t rsvd : 16; /* reserved */
} __attribute__((packed, aligned(4))) i2c_ic_ss_ufm_scl_lcnt_t;
/* i2c fast mode speed clock scl low count/ultra-fast mode speed tbuf idle count register(offset address 0x1c) */
typedef struct _i2c_ic_fs_scl_hcnt_ufm_tbuf_cnt
{
uint32_t cnt : 16;
uint32_t rsvd : 16; /* reserved */
} __attribute__((packed, aligned(4))) i2c_ic_fs_scl_hcnt_ufm_tbuf_cnt_t;
/* i2c fast mode clock scl low count register(offset address 0x20) */
typedef struct _i2c_ic_fs_scl_lcnt
{
uint32_t cnt : 16;
uint32_t rsvd : 16; /* reserved */
} __attribute__((packed, aligned(4))) i2c_ic_fs_scl_lcnt_t;
/* i2c high speed mode clock scl high count register(offset address 0x24) */
typedef struct _i2c_ic_hs_scl_hcnt
{
uint32_t cnt : 16;
uint32_t rsvd : 16; /* reserved */
} __attribute__((packed, aligned(4))) i2c_ic_hs_scl_hcnt_t;
/* i2c high speed mode clock scl low count register(offset address 0x28) */
typedef struct _i2c_ic_hs_scl_lcnt
{
uint32_t cnt : 16;
uint32_t rsvd : 16; /* reserved */
} __attribute__((packed, aligned(4))) i2c_ic_hs_scl_lcnt_t;
/* i2c interrupt status register(offset address 0x2c) */
typedef struct _i2c_ic_intr_stat
{
uint32_t r_rx_under : 1;
uint32_t r_rx_over : 1;
uint32_t r_rx_full : 1;
uint32_t r_tx_over : 1;
uint32_t r_tx_empty : 1;
uint32_t r_rd_req : 1;
uint32_t r_tx_abrt : 1;
uint32_t r_rx_done : 1;
uint32_t r_activity : 1;
uint32_t r_stop_det : 1;
uint32_t r_start_det : 1;
uint32_t r_gen_call : 1;
uint32_t r_restart_det : 1;
uint32_t r_master_on_hold : 1;
uint32_t r_slc_stuck_at_low : 1;
uint32_t rsvd : 17; /* reserved */
} __attribute__((packed, aligned(4))) i2c_ic_intr_stat_t;
/* i2c interrupt mask register(offset address 0x30) */
typedef struct _i2c_ic_intr_mask
{
uint32_t m_rx_under : 1;
uint32_t m_rx_over : 1;
uint32_t m_rx_full : 1;
uint32_t m_tx_over : 1;
uint32_t m_tx_empty : 1;
uint32_t m_rd_req : 1;
uint32_t m_tx_abrt : 1;
uint32_t m_rx_done : 1;
uint32_t m_activity : 1;
uint32_t m_stop_det : 1;
uint32_t m_start_det : 1;
uint32_t m_gen_call : 1;
uint32_t m_restart_det : 1;
uint32_t m_master_on_hold : 1;
uint32_t m_slc_stuck_at_low : 1;
uint32_t rsvd : 17; /* reserved */
} __attribute__((packed, aligned(4))) i2c_ic_intr_mask_t;
/* i2c raw interrupt status register(offset address 0x34) */
typedef struct _i2c_ic_raw_intr_stat
{
uint32_t rx_under : 1;
uint32_t rx_over : 1;
uint32_t rx_full : 1;
uint32_t tx_over : 1;
uint32_t tx_empty : 1;
uint32_t rd_req : 1;
uint32_t tx_abrt : 1;
uint32_t rx_done : 1;
uint32_t activity : 1;
uint32_t stop_det : 1;
uint32_t start_det : 1;
uint32_t gen_call : 1;
uint32_t restart_det : 1;
uint32_t master_on_hold : 1;
uint32_t scl_stuck_at_low : 1;
uint32_t rsvd : 17; /* reserved */
} __attribute__((packed, aligned(4))) i2c_ic_raw_intr_stat_t;
/* i2c receive FIFO threshold register(offset address 0x38) */
typedef struct _i2c_ic_rx_tl
{
uint32_t tl : 8;
uint32_t rsvd : 24; /* reserved */
} __attribute__((packed, aligned(4))) i2c_ic_rx_tl_t;
/* i2c transmit FIFO threshold register(offset address 0x3c) */
typedef struct _i2c_ic_tx_tl
{
uint32_t tl : 8;
uint32_t rsvd : 24; /* reserved */
} __attribute__((packed, aligned(4))) i2c_ic_tx_tl_t;
/* i2c clear combined and individual interrupt register(offset address 0x40) */
typedef struct _i2c_ic_clr_intr
{
uint32_t clr : 1;
uint32_t rsvd : 31; /* reserved */
} __attribute__((packed, aligned(4))) i2c_ic_clr_intr_t;
/* i2c clear rx under interrupt register(offset address 0x44) */
typedef struct _i2c_ic_clr_rx_under
{
uint32_t clr : 1;
uint32_t rsvd : 31; /* reserved */
} __attribute__((packed, aligned(4))) i2c_ic_clr_rx_under_t;
/* i2c clear rx over interrupt register(offset address 0x48) */
typedef struct _i2c_ic_clr_rx_over
{
uint32_t clr : 1;
uint32_t rsvd : 31; /* reserved */
} __attribute__((packed, aligned(4))) i2c_ic_clr_rx_over_t;
/* i2c clear tx over interrupt register(offset address 0x4c) */
typedef struct _i2c_ic_clr_tx_over
{
uint32_t clr : 1;
uint32_t rsvd : 31; /* reserved */
} __attribute__((packed, aligned(4))) i2c_ic_clr_tx_over_t;
/* i2c clear rd req interrupt register(offset address 0x50) */
typedef struct _i2c_ic_clr_rd_req
{
uint32_t clr : 1;
uint32_t rsvd : 31; /* reserved */
} __attribute__((packed, aligned(4))) i2c_ic_clr_rd_req_t;
/* i2c clear tx abrt interrupt register(offset address 0x54) */
typedef struct _i2c_ic_clr_tx_abrt
{
uint32_t clr : 1;
uint32_t rsvd : 31; /* reserved */
} __attribute__((packed, aligned(4))) i2c_ic_clr_tx_abrt_t;
/* i2c clear rx done interrupt register(offset address 0x58) */
typedef struct _i2c_ic_clr_rx_done
{
uint32_t clr : 1;
uint32_t rsvd : 31; /* reserved */
} __attribute__((packed, aligned(4))) i2c_ic_clr_rx_done_t;
/* i2c clear activity interrupt register(offset address 0x5c) */
typedef struct _i2c_ic_clr_activity
{
uint32_t clr : 1;
uint32_t rsvd : 31; /* reserved */
} __attribute__((packed, aligned(4))) i2c_ic_clr_activity_t;
/* i2c clear stop det interrupt register(offset address 0x60) */
typedef struct _i2c_clr_stop_det
{
uint32_t clr : 1;
uint32_t rsvd : 31; /* reserved */
} __attribute__((packed, aligned(4))) i2c_ic_clr_stop_det_t;
/* i2c clear start det interrupt register(offset address 0x64) */
typedef struct _i2c_ic_clr_start_det
{
uint32_t clr : 1;
uint32_t rsvd : 31; /* reserved */
} __attribute__((packed, aligned(4))) i2c_ic_clr_start_det_t;
/* i2c clear gen call interrupt register(offset address 0x68) */
typedef struct _i2c_ic_clr_gen_call
{
uint32_t clr : 1;
uint32_t rsvd : 31; /* reserved */
} __attribute__((packed, aligned(4))) i2c_ic_clr_gen_call_t;
/* i2c enable register(offset address 0x6c) */
typedef struct _i2c_ic_enable
{
uint32_t enable : 1;
uint32_t abort : 1;
uint32_t tx_cmd_block : 1;
uint32_t sda_stuck_recovery_enable : 1;
uint32_t rsvd_1 : 12; /* reserved */
uint32_t smbus_clk_reset : 1;
uint32_t smbus_suspned_en : 1;
uint32_t smbus_alert_en : 1;
uint32_t rsvd_2 : 13; /* reserved */
} __attribute__((packed, aligned(4))) i2c_ic_enable_t;
/* i2c status register(offset address 0x70) */
typedef struct _i2c_ic_status
{
uint32_t activity : 1;
uint32_t tfnf : 1;
uint32_t tfe : 1;
uint32_t rfne : 1;
uint32_t rff : 1;
uint32_t mst_activity : 1;
uint32_t slv_activity : 1;
uint32_t mst_hold_tx_fifo_empty : 1;
uint32_t mst_hold_rx_fifo_full : 1;
uint32_t slv_hold_tx_fifo_empty : 1;
uint32_t slv_hold_rx_fifo_full : 1;
uint32_t sda_stuck_not_recovered : 1;
uint32_t rsvd_1 : 4; /* reserved */
uint32_t smbus_quick_cmd_bit : 1;
uint32_t smbus_slave_addr_valid : 1;
uint32_t smbus_slave_addr_resolved : 1;
uint32_t smbus_suspend_status : 1;
uint32_t smbus_alert : 1;
uint32_t rsvd_2 : 11; /* reserved */
} __attribute__((packed, aligned(4))) i2c_ic_status_t;
/* i2c transmit fifo level register(offset address 0x74) */
typedef struct _i2c_ic_txflr
{
uint32_t txflr : 5;
uint32_t rsvd : 27; /* reserved */
} __attribute__((packed, aligned(4))) i2c_ic_txflr_t;
/* i2c receive fifo level register(offset address 0x78) */
typedef struct _i2c_ic_rxflr
{
uint32_t rxflr : 5;
uint32_t rsvd : 27; /* reserved */
} __attribute__((packed, aligned(4))) i2c_ic_rxflr_t;
/* i2c sda hold time length register(offset address 0x7c) */
typedef struct _i2c_ic_sda_hold
{
uint32_t tx_hold : 16;
uint32_t rx_hold : 8;
uint32_t rsvd : 8; /* reserved */
} __attribute__((packed, aligned(4))) i2c_ic_sda_hold_t;
/* i2c transmit abort source register(offset address 0x80) */
typedef struct _i2c_ic_tx_abrt_source
{
uint32_t abrt_7b_addr_noack : 1;
uint32_t abrt_10addr1_noack : 1;
uint32_t abrt_10addr2_noack : 1;
uint32_t abrt_txdata_noack : 1;
uint32_t abrt_gcall_noack : 1;
uint32_t abrt_gcall_read : 1;
uint32_t abrt_hs_ackdet : 1;
uint32_t abrt_sbyte_ackdet : 1;
uint32_t abrt_hs_norstrt : 1;
uint32_t abrt_sbyte_norstrt : 1;
uint32_t abrt_10b_rd_norstrt : 1;
uint32_t abrt_master_dis : 1;
uint32_t abrt_lost : 1;
uint32_t abrt_slvflush_txfifo : 1;
uint32_t abrt_slv_arblost : 1;
uint32_t abrt_slvrd_intx : 1;
uint32_t abrt_user_abrt : 1;
uint32_t abrt_sda_stuck_at_low : 1;
uint32_t abrt_device_noack : 1;
uint32_t abrt_device_slvaddr_noack : 1;
uint32_t abrt_device_write : 1;
uint32_t rsvd : 2; /* reserved */
uint32_t tx_flush_cnt : 9;
} __attribute__((packed, aligned(4))) i2c_ic_tx_abrt_source_t;
/* i2c generate slave data nack register(offset address 0x84) */
typedef struct _i2c_ic_slv_data_nack_only
{
uint32_t nack : 1;
uint32_t rsvd : 31; /* reserved */
} __attribute__((packed, aligned(4))) i2c_ic_slv_data_nack_only_t;
/* i2c dma control register(offset address 0x88) */
typedef struct _i2c_ic_dma_cr
{
uint32_t rdmae : 1;
uint32_t tdmae : 1;
uint32_t rsvd : 30; /* reserved */
} __attribute__((packed, aligned(4))) i2c_ic_dma_cr_t;
/* i2c dma transmit data level register(offset address 0x8c) */
typedef struct _i2c_ic_dma_tdlr
{
uint32_t dmatdl : 5;
uint32_t rsvd : 27; /* reserved */
} __attribute__((packed, aligned(4))) i2c_ic_dma_tdlr_t;
/* i2c dma receive data level register(offset address 0x90) */
typedef struct _i2c_ic_dma_rdlr
{
uint32_t dmardl : 5;
uint32_t rsvd : 27; /* reserved */
} __attribute__((packed, aligned(4))) i2c_ic_dma_rdlr_t;
/* i2c sda setup register(offset address 0x94) */
typedef struct _i2c_ic_sda_setup
{
uint32_t setup : 8;
uint32_t rsvd : 24; /* reserved */
} __attribute__((packed, aligned(4))) i2c_ic_sda_setup_t;
/* i2c ack general call register(offset address 0x98) */
typedef struct _i2c_ic_ack_general_call
{
uint32_t ask : 1;
uint32_t rsvd : 31; /* reserved */
} __attribute__((packed, aligned(4))) i2c_ic_ack_general_call_t;
/* i2c enable status register(offset address 0x9c) */
typedef struct _i2c_ic_enable_status
{
uint32_t en : 1;
uint32_t slv_disabled_while_busy : 1;
uint32_t slv_rx_data_lost : 1;
uint32_t rsvd : 29; /* reserved */
} __attribute__((packed, aligned(4))) i2c_ic_enable_status_t;
/* i2c ss, fs, or fm+/ufm spike suppression limit register(offset address 0xa0) */
typedef struct _i2c_ic_fs_ufm_spklen
{
uint32_t spklen : 8;
uint32_t rsvd : 24; /* reserved */
} __attribute__((packed, aligned(4))) i2c_ic_fs_ufm_spklen_t;
/* i2c hs spike suppression limit register(offset address 0xa4) */
typedef struct _i2c_ic_hs_spklen
{
uint32_t spklen : 8;
uint32_t rsvd : 24; /* reserved */
} __attribute__((packed, aligned(4))) i2c_ic_hs_spklen_t;
/* i2c clear restart det interrupt register(offset address 0xa8) */
typedef struct _i2c_ic_clr_restart_det
{
uint32_t clr : 1;
uint32_t rsvd : 31; /* reserved */
} __attribute__((packed, aligned(4))) i2c_ic_clr_restart_det_t;
/* i2c scl stuck at low timeout register(offset address 0xac) */
typedef struct _i2c_ic_scl_stuck_at_low_timeout
{
uint32_t timeout : 32;
} __attribute__((packed, aligned(4))) i2c_ic_scl_stuck_at_low_timeout_t;
/* i2c sda stuck at low timeout register(offset address 0xb0) */
typedef struct _i2c_ic_sda_stuck_at_low_timeout
{
uint32_t timeout : 32;
} __attribute__((packed, aligned(4))) i2c_ic_sda_stuck_at_low_timeout_t;
/* i2c clear scl stuck at low detect interrupt register(offset address 0xb4) */
typedef struct _i2c_ic_clr_slc_stuck_det
{
uint32_t clr : 1;
uint32_t rsvd : 31; /* reserved */
} __attribute__((packed, aligned(4))) i2c_ic_clr_slc_stuck_det_t;
/* i2c device id register(offset address 0xb8) */
typedef struct _i2c_ic_device_id
{
uint32_t device_id : 24;
uint32_t rsvd : 8; /* reserved */
} __attribute__((packed, aligned(4))) i2c_ic_device_id_t;
/* i2c smbus slave clock extend timeout register(offset address 0xbc) */
typedef struct _i2c_ic_smbus_clk_low_sext
{
uint32_t timeout : 32;
} __attribute__((packed, aligned(4))) i2c_ic_smbus_clk_low_sext_t;
/* i2c smbus master clock extend timeout register(offset address 0xc0) */
typedef struct _i2c_ic_smbus_clk_low_mext
{
uint32_t timeout : 32;
} __attribute__((packed, aligned(4))) i2c_ic_smbus_clk_low_mext_t;
/* i2c smbus master thigh max bus-idle count register(offset address 0xc4) */
typedef struct _i2c_ic_smbus_thigh_max_idle_count
{
uint32_t cnt : 16;
uint32_t rsvd : 16; /* reserved */
} __attribute__((packed, aligned(4))) i2c_ic_smbus_thigh_max_idle_count_t;
/* i2c smbus interrupt status register(offset address 0xc8) */
typedef struct _i2c_ic_smbus_intr_stat
{
uint32_t r_slv_clock_extnd_timeout : 1;
uint32_t r_mst_clock_extnd_timeout : 1;
uint32_t r_quick_cmd_det : 1;
uint32_t r_host_notify_mst_det : 1;
uint32_t r_arp_prepare_cmd_det : 1;
uint32_t r_arp_rst_cmd_det : 1;
uint32_t r_arp_get_udid_cmd_det : 1;
uint32_t r_arp_assgn_addr_cmd_det : 1;
uint32_t r_slv_rx_pec_nack : 1;
uint32_t r_smbus_suspend_det : 1;
uint32_t r_smbus_alert_det : 1;
uint32_t rsvd : 21; /* reserved */
} __attribute__((packed, aligned(4))) i2c_ic_smbus_intr_stat_t;
/* i2c smbus interrupt mask register(offset address 0xcc) */
typedef struct _i2c_ic_smbus_intr_mask
{
uint32_t m_slv_clock_extnd_timeout : 1;
uint32_t m_mst_clock_extnd_timeout : 1;
uint32_t m_quick_cmd_det : 1;
uint32_t m_host_notify_mst_det : 1;
uint32_t m_arp_prepare_cmd_det : 1;
uint32_t m_arp_rst_cmd_det : 1;
uint32_t m_arp_get_udid_cmd_det : 1;
uint32_t m_arp_assgn_addr_cmd_det : 1;
uint32_t m_slv_rx_pec_nack : 1;
uint32_t m_smbus_suspend_det : 1;
uint32_t m_smbus_alert_det : 1;
uint32_t rsvd : 21; /* reserved */
} __attribute__((packed, aligned(4))) i2c_ic_smbus_intr_mask_t;
/* i2c smbus raw interrupt status register(offset address 0xd0) */
typedef struct _i2c_ic_smbus_raw_intr_stat
{
uint32_t slv_clock_extnd_timeout : 1;
uint32_t mst_clock_extnd_timeout : 1;
uint32_t quick_cmd_det : 1;
uint32_t host_notify_mst_det : 1;
uint32_t arp_prepare_cmd_det : 1;
uint32_t arp_rst_cmd_det : 1;
uint32_t arp_get_udid_cmd_det : 1;
uint32_t arp_assgn_addr_cmd_det : 1;
uint32_t slv_rx_pec_nack : 1;
uint32_t smbus_suspend_det : 1;
uint32_t smbus_alert_det : 1;
uint32_t rsvd : 21; /* reserved */
} __attribute__((packed, aligned(4))) i2c_ic_smbus_raw_intr_stat_t;
/* i2c smbus clear interrupt register(offset address 0xd4) */
typedef struct _i2c_ic_clr_smbus_intr
{
uint32_t slv_clock_extnd_timeout : 1;
uint32_t mst_clock_extnd_timeout : 1;
uint32_t quick_cmd_det : 1;
uint32_t host_notify_mst_det : 1;
uint32_t arp_prepare_cmd_det : 1;
uint32_t arp_rst_cmd_det : 1;
uint32_t arp_get_udid_cmd_det : 1;
uint32_t arp_assgn_addr_cmd_det : 1;
uint32_t slv_rx_pec_nack : 1;
uint32_t smbus_suspend_det : 1;
uint32_t smbus_alert_det : 1;
uint32_t rsvd : 21; /* reserved */
} __attribute__((packed, aligned(4))) i2c_ic_clr_smbus_intr_t;
/* i2c optional slave address register(offset address 0xd8) */
typedef struct _i2c_ic_optional_sar
{
uint32_t sar : 7;
uint32_t rsvd : 25; /* reserved */
} __attribute__((packed, aligned(4))) i2c_ic_optional_sar_t;
/* i2c smbus udid lsb register(offset address 0xdc) */
typedef struct _i2c_ic_smbus_udid_lsb
{
uint32_t udid_lsb : 32;
} __attribute__((packed, aligned(4))) i2c_ic_smbus_udid_lsb_t;
/* i2c component parameter 1 register(offset address 0xf4) */
typedef struct _i2c_ic_comp_param_1
{
uint32_t apb_data_width : 2;
uint32_t max_speed_mode : 2;
uint32_t hc_count_values : 1;
uint32_t intr_io : 1;
uint32_t has_dma : 1;
uint32_t add_encoded_params : 1;
uint32_t rx_buffer_depth : 8;
uint32_t tx_buffer_depth : 8;
uint32_t rsvd : 8; /* reserved */
} __attribute__((packed, aligned(4))) i2c_ic_comp_param_1_t;
/* i2c component version register(offset address 0xf8) */
typedef struct _i2c_ic_comp_version
{
uint32_t version : 32;
} __attribute__((packed, aligned(4))) i2c_ic_comp_version_t;
/* i2c component type register(offset address 0xfc) */
typedef struct _i2c_ic_comp_type
{
uint32_t type : 32;
} __attribute__((packed, aligned(4))) i2c_ic_comp_type_t;
/* i2c register */
typedef struct _i2c
{
i2c_ic_con_t con; /* 0x00 */
i2c_ic_tar_t tar; /* 0x04 */
i2c_ic_sar_t sar; /* 0x08 */
i2c_ic_hs_maddr_t hs_maddr; /* 0x0c */
i2c_ic_data_cmd_t data_cmd; /* 0x10 */
i2c_ic_ss_ufm_scl_hcnt_t ss_ufm_scl_hcnt; /* 0x14 */
i2c_ic_ss_ufm_scl_lcnt_t ss_ufm_scl_lcnt; /* 0x18 */
i2c_ic_fs_scl_hcnt_ufm_tbuf_cnt_t fs_scl_hcnt_ufm_tbuf_cnt; /* 0x1c */
i2c_ic_fs_scl_lcnt_t fs_scl_lcnt; /* 0x20 */
i2c_ic_hs_scl_hcnt_t hs_scl_hcnt; /* 0x24 */
i2c_ic_hs_scl_lcnt_t hs_scl_lcnt; /* 0x28 */
i2c_ic_intr_stat_t intr_stat; /* 0x2c */
i2c_ic_intr_mask_t intr_mask; /* 0x30 */
i2c_ic_raw_intr_stat_t raw_intr_stat; /* 0x34 */
i2c_ic_rx_tl_t rx_tl; /* 0x38 */
i2c_ic_tx_tl_t tx_tl; /* 0x3c */
i2c_ic_clr_intr_t clr_intr; /* 0x40 */
i2c_ic_clr_rx_under_t clr_rx_under; /* 0x44 */
i2c_ic_clr_rx_over_t clr_rx_over; /* 0x48 */
i2c_ic_clr_tx_over_t clr_tx_over; /* 0x4c */
i2c_ic_clr_rd_req_t clr_rd_req; /* 0x50 */
i2c_ic_clr_tx_abrt_t clr_tx_abrt; /* 0x54 */
i2c_ic_clr_rx_done_t clr_rx_done; /* 0x58 */
i2c_ic_clr_activity_t clr_activity; /* 0x5c */
i2c_ic_clr_stop_det_t clr_stop_det; /* 0x60 */
i2c_ic_clr_start_det_t clr_start_det; /* 0x64 */
i2c_ic_clr_gen_call_t clr_gen_call; /* 0x68 */
i2c_ic_enable_t enable; /* 0x6c */
i2c_ic_status_t status; /* 0x70 */
i2c_ic_txflr_t txflr; /* 0x74 */
i2c_ic_rxflr_t rxflr; /* 0x78 */
i2c_ic_sda_hold_t sda_hold; /* 0x7c */
i2c_ic_tx_abrt_source_t tx_abrt_source; /* 0x80 */
i2c_ic_slv_data_nack_only_t slv_data_nack_only; /* 0x84 */
i2c_ic_dma_cr_t dma_cr; /* 0x88 */
i2c_ic_dma_tdlr_t dma_tdlr; /* 0x8c */
i2c_ic_dma_rdlr_t dma_rdlr; /* 0x90 */
i2c_ic_sda_setup_t sda_setup; /* 0x94 */
i2c_ic_ack_general_call_t ack_general_call; /* 0x98 */
i2c_ic_enable_status_t enable_status; /* 0x9c */
i2c_ic_fs_ufm_spklen_t fs_ufm_spklen; /* 0xa0 */
i2c_ic_hs_spklen_t hs_spklen; /* 0xa4 */
i2c_ic_clr_restart_det_t clr_restart_det; /* 0xa8 */
i2c_ic_scl_stuck_at_low_timeout_t scl_stuck_at_low_timeout; /* 0xac */
i2c_ic_sda_stuck_at_low_timeout_t sda_stuck_at_low_timeout; /* 0xb0 */
i2c_ic_clr_slc_stuck_det_t clr_slc_stuck_det; /* 0xb4 */
i2c_ic_device_id_t device_id; /* 0xb8 */
i2c_ic_smbus_clk_low_sext_t smbus_clk_low_sext; /* 0xbc */
i2c_ic_smbus_clk_low_mext_t smbus_clk_low_mext; /* 0xc0 */
i2c_ic_smbus_thigh_max_idle_count_t smbus_thigh_max_idle_count; /* 0xc4 */
i2c_ic_smbus_intr_stat_t smbus_intr_stat; /* 0xc8 */
i2c_ic_smbus_intr_mask_t smbus_intr_mask; /* 0xcc */
i2c_ic_smbus_raw_intr_stat_t smbus_raw_intr_stat; /* 0xd0 */
i2c_ic_clr_smbus_intr_t clr_smbus_intr; /* 0xd4 */
i2c_ic_optional_sar_t optional_sar; /* 0xd8 */
i2c_ic_smbus_udid_lsb_t smbus_udid_lsb; /* 0xdc */
uint32_t rsvd_1[5]; /* 0xe0-0xf0 reserved */
i2c_ic_comp_param_1_t comp_param_1; /* 0xf4 */
i2c_ic_comp_version_t comp_version; /* 0xf8 */
i2c_ic_comp_type_t comp_type; /* 0xfc */
} __attribute__((packed, aligned(4))) i2c_t;
#endif /* __DRV_I2C_H__ */

View File

@@ -29,10 +29,7 @@ if GetDepend('BSP_UTEST_DRIVERS'):
if GetDepend('BSP_USING_RTC'):
src += ['test_rtc.c']
if GetDepend('BSP_USING_I2C'):
src += ['test_i2c.c']
group = DefineGroup('utestcases', src, depend = [''])
Return('group')

View File

@@ -1,204 +0,0 @@
/* 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 <utest.h>
#include <string.h>
#include "drv_i2c.h"
#include "drv_pinctrl.h"
#include "drv_gpio.h"
/*
* 测试K230 I2C的主从机通信在这里采用I2C0作为测试对象
*
* 硬件平台:
* 测试的硬件平台为庐山派开发板使用的I2C0引脚是GPIO048(SCL)
* 和GPIO049(SDA)。
*
* 测试说明:
* 1. 测试I2C0主机模式
* 主机模式下主机向从机发送16字节数据不包括写读地址
* 然后再读取回来进行校验共执行两次分别是400kHz和1MHz速率。
* 注使用的从机为AT24C08 EEPROM设备地址为0x50。
*/
#define I2C_NAME "i2c0"
#define TARGET_ADDR 0x50
#define TEST_BUFFER_SIZE 16
#define I2C_SCL_PIN 48
#define I2C_SDA_PIN 49
#define I2C_SCL_PIN_AF IOMUX_FUNC4
#define I2C_SDA_PIN_AF IOMUX_FUNC4
static void test_i2c0_deinit_pin(void)
{
k230_pinctrl_set_function(I2C_SCL_PIN, IOMUX_FUNC1);
k230_pinctrl_set_function(I2C_SDA_PIN, IOMUX_FUNC1);
k230_pinctrl_set_oe(I2C_SCL_PIN, 0);
k230_pinctrl_set_oe(I2C_SDA_PIN, 0);
k230_pinctrl_set_ie(I2C_SCL_PIN, 1);
k230_pinctrl_set_ie(I2C_SDA_PIN, 1);
kd_pin_mode(I2C_SCL_PIN, GPIO_DM_INPUT);
kd_pin_mode(I2C_SDA_PIN, GPIO_DM_INPUT);
}
static void test_i2c0_init_pin(void)
{
k230_pinctrl_set_function(I2C_SCL_PIN, I2C_SCL_PIN_AF); // I2C0_SCL
k230_pinctrl_set_function(I2C_SDA_PIN, I2C_SDA_PIN_AF); // I2C0_SDA
k230_pinctrl_set_oe(I2C_SCL_PIN, 1);
k230_pinctrl_set_oe(I2C_SDA_PIN, 1);
k230_pinctrl_set_ie(I2C_SCL_PIN, 1);
k230_pinctrl_set_ie(I2C_SDA_PIN, 1);
}
static int test_i2c_check_pin(void)
{
test_i2c0_deinit_pin();
if(kd_pin_read(I2C_SCL_PIN) != 1 || kd_pin_read(I2C_SDA_PIN) != 1)
{
LOG_W("i2c bus is not idle, try to recover it.");
k230_pinctrl_set_oe(I2C_SCL_PIN, 1);
kd_pin_mode(I2C_SCL_PIN, GPIO_DM_OUTPUT);
for(rt_uint8_t i = 0; i < 9; i++)
{
kd_pin_write(I2C_SCL_PIN, 0);
rt_hw_us_delay(2);
kd_pin_write(I2C_SCL_PIN, 1);
rt_hw_us_delay(2);
}
k230_pinctrl_set_oe(I2C_SCL_PIN, 0);
kd_pin_mode(I2C_SCL_PIN, GPIO_DM_INPUT);
}
if(kd_pin_read(I2C_SCL_PIN) != 1 || kd_pin_read(I2C_SDA_PIN) != 1)
{
LOG_E("i2c bus recover failed");
return -RT_ERROR;
}
LOG_I("i2c bus(pin: %u, %u) is idle, init i2c bus pin", I2C_SCL_PIN, I2C_SDA_PIN);
test_i2c0_init_pin();
return RT_EOK;
}
static void _test_i2c0_master(rt_uint8_t *buffer_w, rt_uint8_t *buffer_r, rt_uint32_t size, rt_uint32_t speed)
{
rt_err_t ret = RT_EOK;
struct rt_i2c_bus_device *dev;
struct rt_i2c_msg msgs[2];
dev = rt_i2c_bus_device_find(I2C_NAME);
uassert_not_null(dev);
rt_i2c_control(dev, RT_I2C_DEV_CTRL_CLK, (void *)&speed);
msgs[0].addr = TARGET_ADDR;
msgs[0].flags = RT_I2C_WR;
msgs[0].buf = buffer_w;
msgs[0].len = size + 1;
if(rt_i2c_transfer(dev, msgs, 1) != 1)
{
LOG_E("i2c transfer failed");
uassert_true(0);
}
rt_thread_mdelay(10);
msgs[0].addr = TARGET_ADDR;
msgs[0].flags = RT_I2C_WR | RT_I2C_NO_STOP;
msgs[0].buf = &buffer_r[0];
msgs[0].len = 1;
msgs[1].addr = TARGET_ADDR;
msgs[1].flags = RT_I2C_RD | RT_I2C_NO_START;
msgs[1].buf = &buffer_r[1];
msgs[1].len = size;
if(rt_i2c_transfer(dev, msgs, 2) != 2)
{
LOG_E("i2c transfer failed");
uassert_true(0);
}
LOG_I("Read data:\n");
for(rt_uint8_t i = 1; i < size + 1; i++)
{
LOG_I("0x%02X ", buffer_r[i]);
}
uassert_buf_equal(buffer_w + 1, buffer_r + 1, size);
}
static void test_i2c0_master(void)
{
rt_uint8_t buffer_w[TEST_BUFFER_SIZE + 1];
rt_uint8_t buffer_r[TEST_BUFFER_SIZE + 1];
rt_uint32_t size = TEST_BUFFER_SIZE;
rt_uint32_t speed = 400000; // 400kHz
memset(buffer_w + 1, 0xAA, TEST_BUFFER_SIZE);
buffer_w[0] = 0x00; // memory address
memset(buffer_r, 0x00, TEST_BUFFER_SIZE + 1);
_test_i2c0_master(buffer_w, buffer_r, size, speed);
speed = 1000000; // 1MHz
memset(buffer_w + 1, 0x55, TEST_BUFFER_SIZE);
buffer_w[0] = 0x00; // memory address
memset(buffer_r, 0x00, TEST_BUFFER_SIZE + 1);
_test_i2c0_master(buffer_w, buffer_r, size, speed);
}
static void testcase(void)
{
LOG_I("This is a i2c test case.\n");
UTEST_UNIT_RUN(test_i2c0_master);
}
static rt_err_t utest_tc_init(void)
{
return test_i2c_check_pin();
}
static rt_err_t utest_tc_cleanup(void)
{
LOG_I("i2c bus pin deinit.\n");
test_i2c0_deinit_pin();
return RT_EOK;
}
UTEST_TC_EXPORT(testcase, "bsp.k230.drivers.i2c", utest_tc_init, utest_tc_cleanup, 100);

View File

@@ -276,7 +276,6 @@
#define RT_USING_SAL
#define SAL_INTERNET_CHECK
#define SOCKET_TABLE_STEP_LEN 4
/* Docking with protocol stacks */

View File

@@ -50,10 +50,7 @@ if GetDepend(['RT_USING_DAC']):
src += ['drv_dac.c']
if GetDepend(['RT_USING_CAN']):
if GetDepend(['SOC_SERIES_STM32H7']):
src += ['drv_fdcan.c']
else:
src += ['drv_can.c']
src += ['drv_can.c']
if GetDepend(['RT_USING_PM']):
src += ['drv_pm.c']

View File

@@ -1,703 +0,0 @@
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-02-24 heyuan the first version
* 2020-08-17 malongwei Fix something
* 2025-10-27 pandafeng Fix some bugs
*/
#include "drv_fdcan.h"
#if defined(RT_USING_CAN) && defined(RT_CAN_USING_CANFD)
#if defined(BSP_USING_FDCAN1) || defined(BSP_USING_FDCAN2)
//#define DRV_DEBUG
#define LOG_TAG "drv_fdcan"
#include <drv_log.h>
#ifdef BSP_USING_FDCAN1
static stm32_fdcan_t st_DrvCan1=
{
.name = "fdcan1",
.fdcanHandle.Instance = FDCAN1,
};
#endif
#ifdef BSP_USING_FDCAN2
static stm32_fdcan_t st_DrvCan2=
{
.name = "fdcan2",
.fdcanHandle.Instance = FDCAN2,
};
#endif
/* 40MHz CAN clock */
static const stm32_fdcan_timing_t st_FDCAN_ArbTiming[] =
{
{CAN1MBaud, {1, 29, 10, 8, 0}}, /* 1Mbps */
{CAN800kBaud, {1, 37, 12, 8, 0}}, /* 800kbps */
{CAN500kBaud, {1, 59, 20, 8, 0}}, /* 500kbps */
{CAN250kBaud, {2, 63, 16, 8, 0}}, /* 250kbps */
{CAN125kBaud, {5, 55, 8, 8, 0}}, /* 125kbps */
{CAN100kBaud, {8, 41, 8, 8, 0}}, /* 100kbps */
{CAN50kBaud, {16, 41, 8, 8, 0}}, /* 50kbps */
{CAN20kBaud, {40,41,8,8,0}}, /* 20kbps */
{CAN10kBaud, {100,31,8,8,0}} /* 10kbps */
};
/* 40MHz CAN clock */
static const stm32_fdcan_timing_t st_FDCAN_DataTiming[] =
{
{CAN1MBaud * 8, {1, 3, 1, 1, 0}}, /* 8Mbps */
{CAN500kBaud *8, {1, 7, 2, 1, 0}}, /* 4Mbps */
{CAN250kBaud * 8, {4, 3, 1, 1, 0}}, /* 2Mbps */
{CAN125kBaud *8, {1, 31, 8, 1, 0}}, /* 1Mkbps */
{CAN100kBaud*8, {2, 19, 5, 1, 0}}, /* 800kbps */
{CAN50kBaud *8, {5, 15, 4, 1, 0}}, /* 400kbps */
};
/**
* @brief Convert CAN-FD frame length to DLC (Data Length Code)
*
* CAN-FD DLC mapping (length → DLC):
* Length 0~8 -> DLC 0~8
* Length 9~12 -> DLC 9
* Length 13~16 -> DLC 10
* Length 17~20 -> DLC 11
* Length 21~24 -> DLC 12
* Length 25~32 -> DLC 13
* Length 33~48 -> DLC 14
* Length 49~64 -> DLC 15
*
* @param len Frame length in bytes (0~64)
* @return DLC code (0~15)
*/
uint8_t length_to_dlc(uint8_t len) {
return (len <= 8) ? len :
(len <= 12) ? 9 :
(len <= 16) ? 10 :
(len <= 20) ? 11 :
(len <= 24) ? 12 :
(len <= 32) ? 13 :
(len <= 48) ? 14 : 15;
}
/**
* @brief 获取 FDCAN 仲裁段波特率配置索引
*/
static uint32_t _inline_get_ArbBaudIndex(uint32_t baud_rate)
{
uint32_t len = sizeof(st_FDCAN_ArbTiming) / sizeof(st_FDCAN_ArbTiming[0]);
for (uint32_t i = 0; i < len; i++)
{
if (st_FDCAN_ArbTiming[i].u32Baudrate == baud_rate)
return i;
}
return -1;
}
/**
* @brief Get the index of the FDCAN data segment bitrate configuration.
*
* @param baud_rate The desired data phase baud rate (in bps).
* @retval uint32_t Index of the matching data segment configuration.
* Returns -1 if no matching configuration is found.
*/
static uint32_t _inline_get_DataBaudIndex(uint32_t baud_rate)
{
uint32_t len = sizeof(st_FDCAN_DataTiming) / sizeof(st_FDCAN_DataTiming[0]);
for (uint32_t i = 0; i < len; i++)
{
if (st_FDCAN_DataTiming[i].u32Baudrate == baud_rate)
return i;
}
return -1;
}
static rt_err_t _inline_can_config(struct rt_can_device *can, struct can_configure *cfg)
{
stm32_fdcan_t *pdrv_can;
rt_uint32_t tmp_u32Index;
RT_ASSERT(can);
RT_ASSERT(cfg);
pdrv_can = (stm32_fdcan_t *)can->parent.user_data;
RT_ASSERT(pdrv_can);
pdrv_can->fdcanHandle.Init.FrameFormat = FDCAN_FRAME_FD_BRS;
pdrv_can->fdcanHandle.Init.Mode = FDCAN_MODE_NORMAL;
pdrv_can->fdcanHandle.Init.AutoRetransmission = ENABLE;
pdrv_can->fdcanHandle.Init.TransmitPause = DISABLE;
pdrv_can->fdcanHandle.Init.ProtocolException = ENABLE;
switch (cfg->mode)
{
case RT_CAN_MODE_NORMAL:
pdrv_can->fdcanHandle.Init.Mode = FDCAN_MODE_NORMAL;
break;
case RT_CAN_MODE_LISTEN:
pdrv_can->fdcanHandle.Init.Mode = FDCAN_MODE_BUS_MONITORING;
break;
case RT_CAN_MODE_LOOPBACK:
pdrv_can->fdcanHandle.Init.Mode = FDCAN_MODE_INTERNAL_LOOPBACK;
break;
default:
pdrv_can->fdcanHandle.Init.Mode = FDCAN_MODE_NORMAL;
break;
}
uint32_t arb_idx = _inline_get_ArbBaudIndex(cfg->baud_rate);
if (arb_idx == (uint32_t)-1)
{
LOG_E("not support %d baudrate", cfg->baud_rate);
return -RT_ERROR;
}
/* FDCAN arbitration segment */
pdrv_can->fdcanHandle.Init.NominalPrescaler = st_FDCAN_ArbTiming[arb_idx].cam_bit_timing.prescaler;
pdrv_can->fdcanHandle.Init.NominalSyncJumpWidth = st_FDCAN_ArbTiming[arb_idx].cam_bit_timing.num_sjw;
pdrv_can->fdcanHandle.Init.NominalTimeSeg1 = st_FDCAN_ArbTiming[arb_idx].cam_bit_timing.num_seg1;
pdrv_can->fdcanHandle.Init.NominalTimeSeg2 = st_FDCAN_ArbTiming[arb_idx].cam_bit_timing.num_seg2;
#ifdef RT_CAN_USING_CANFD
if(cfg->enable_canfd) {
uint32_t data_idx = _inline_get_DataBaudIndex(cfg->baud_rate_fd);
if (data_idx == (uint32_t)-1)
{
LOG_E("not support %d baudrate", cfg->baud_rate_fd);
return -RT_ERROR;
}
/* 数据段 */
pdrv_can->fdcanHandle.Init.DataPrescaler = st_FDCAN_DataTiming[data_idx].cam_bit_timing.prescaler;
pdrv_can->fdcanHandle.Init.DataSyncJumpWidth = st_FDCAN_DataTiming[data_idx].cam_bit_timing.num_sjw;
pdrv_can->fdcanHandle.Init.DataTimeSeg1 = st_FDCAN_DataTiming[data_idx].cam_bit_timing.num_seg1;
pdrv_can->fdcanHandle.Init.DataTimeSeg2 = st_FDCAN_DataTiming[data_idx].cam_bit_timing.num_seg2;
}
#endif
/* Configure Message RAM */
if(pdrv_can->fdcanHandle.Instance == FDCAN1)
{
pdrv_can->fdcanHandle.Init.MessageRAMOffset = 0;
}
else
{
pdrv_can->fdcanHandle.Init.MessageRAMOffset = 1280;
}
pdrv_can->fdcanHandle.Init.StdFiltersNbr = 2;
pdrv_can->fdcanHandle.Init.ExtFiltersNbr = 2;
pdrv_can->fdcanHandle.Init.RxFifo0ElmtsNbr = 1;
pdrv_can->fdcanHandle.Init.RxFifo0ElmtSize = FDCAN_DATA_BYTES_64;
pdrv_can->fdcanHandle.Init.RxFifo1ElmtsNbr = 0;
pdrv_can->fdcanHandle.Init.RxFifo1ElmtSize = FDCAN_DATA_BYTES_64;
pdrv_can->fdcanHandle.Init.RxBuffersNbr = 0;
pdrv_can->fdcanHandle.Init.RxBufferSize = FDCAN_DATA_BYTES_64;
pdrv_can->fdcanHandle.Init.TxEventsNbr = 0;
pdrv_can->fdcanHandle.Init.TxBuffersNbr = 3;
pdrv_can->fdcanHandle.Init.TxFifoQueueElmtsNbr = 0;
pdrv_can->fdcanHandle.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
pdrv_can->fdcanHandle.Init.TxElmtSize = FDCAN_DATA_BYTES_64;
if (HAL_FDCAN_Init(&pdrv_can->fdcanHandle) != HAL_OK)
{
return -RT_ERROR;
}
/* default filter config */
HAL_FDCAN_ConfigFilter(&pdrv_can->fdcanHandle , &pdrv_can->FilterConfig);
/*init fdcan tx header*/
pdrv_can->TxHeader.Identifier = 0x000000;
pdrv_can->TxHeader.IdType = FDCAN_EXTENDED_ID;
pdrv_can->TxHeader.TxFrameType = FDCAN_DATA_FRAME;
pdrv_can->TxHeader.DataLength = FDCAN_DLC_BYTES_8;
pdrv_can->TxHeader.ErrorStateIndicator = FDCAN_ESI_ACTIVE;
pdrv_can->TxHeader.BitRateSwitch = FDCAN_BRS_OFF;
pdrv_can->TxHeader.FDFormat = FDCAN_CLASSIC_CAN;
pdrv_can->TxHeader.TxEventFifoControl = FDCAN_NO_TX_EVENTS;
pdrv_can->TxHeader.MessageMarker = 0;
/* can start */
HAL_FDCAN_Start(&pdrv_can->fdcanHandle);
return RT_EOK;
}
static rt_err_t _inline_can_filter_config(stm32_fdcan_t *pdrv_can,struct rt_can_filter_config *puser_can_filter_config)
{
int tmp_i32IndexCount;
RT_ASSERT(pdrv_can);
RT_ASSERT(puser_can_filter_config);
/* get default filter */
for (tmp_i32IndexCount = 0; tmp_i32IndexCount < puser_can_filter_config->count; tmp_i32IndexCount++)
{
pdrv_can->FilterConfig.FilterIndex = puser_can_filter_config->items[tmp_i32IndexCount].hdr_bank;
pdrv_can->FilterConfig.FilterID1 = puser_can_filter_config->items[tmp_i32IndexCount].id;
pdrv_can->FilterConfig.FilterID2 = puser_can_filter_config->items[tmp_i32IndexCount].mask;
if(puser_can_filter_config->items[tmp_i32IndexCount].ide == RT_CAN_EXTID)
{
pdrv_can->FilterConfig.IdType = FDCAN_EXTENDED_ID;
}
else
{
pdrv_can->FilterConfig.IdType = FDCAN_STANDARD_ID;
}
pdrv_can->FilterConfig.FilterType = FDCAN_FILTER_MASK;
pdrv_can->FilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;
if(HAL_FDCAN_ConfigFilter(&pdrv_can->fdcanHandle , &pdrv_can->FilterConfig) != HAL_OK)
{
return -RT_ERROR;
}
}
return RT_EOK;
}
static rt_err_t _inline_can_control(struct rt_can_device *can, int cmd, void *arg)
{
rt_uint32_t argval;
stm32_fdcan_t *pdrv_can;
struct rt_can_filter_config *filter_cfg;
RT_ASSERT(can != RT_NULL);
pdrv_can = (stm32_fdcan_t *)can->parent.user_data;
RT_ASSERT(pdrv_can != RT_NULL);
switch (cmd) {
case RT_DEVICE_CTRL_CLR_INT:
argval = (rt_uint32_t) arg;
if (argval == RT_DEVICE_FLAG_INT_RX) {
HAL_FDCAN_DeactivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_RX_FIFO0_NEW_MESSAGE);
} else if (argval == RT_DEVICE_FLAG_INT_TX) {
HAL_FDCAN_DeactivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_TX_FIFO_EMPTY);
HAL_FDCAN_DeactivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_TX_COMPLETE);
} else if (argval == RT_DEVICE_CAN_INT_ERR) {
HAL_FDCAN_DeactivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_ERROR_WARNING);
HAL_FDCAN_DeactivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_ERROR_PASSIVE);
HAL_FDCAN_DeactivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_ERROR_LOGGING_OVERFLOW);
HAL_FDCAN_DeactivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_BUS_OFF);
HAL_FDCAN_DeactivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_ARB_PROTOCOL_ERROR);
}
break;
case RT_DEVICE_CTRL_SET_INT:
argval = (rt_uint32_t) arg;
if (argval == RT_DEVICE_FLAG_INT_RX) {
HAL_FDCAN_ConfigInterruptLines(&pdrv_can->fdcanHandle, FDCAN_IT_RX_FIFO0_NEW_MESSAGE,
FDCAN_INTERRUPT_LINE0);
HAL_FDCAN_ActivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0);
if (FDCAN1 == pdrv_can->fdcanHandle.Instance) {
HAL_NVIC_SetPriority(FDCAN1_IT0_IRQn, 0, 1);
HAL_NVIC_EnableIRQ(FDCAN1_IT0_IRQn);
} else {
HAL_NVIC_SetPriority(FDCAN2_IT0_IRQn, 0, 1);
HAL_NVIC_EnableIRQ(FDCAN2_IT0_IRQn);
}
} else if (argval == RT_DEVICE_FLAG_INT_TX) {
HAL_FDCAN_ConfigInterruptLines(&pdrv_can->fdcanHandle, FDCAN_IT_TX_COMPLETE, FDCAN_INTERRUPT_LINE1);
HAL_FDCAN_ActivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_TX_COMPLETE, FDCAN_TX_BUFFER0);
HAL_FDCAN_ActivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_TX_COMPLETE, FDCAN_TX_BUFFER1);
HAL_FDCAN_ActivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_TX_COMPLETE, FDCAN_TX_BUFFER2);
if (FDCAN1 == pdrv_can->fdcanHandle.Instance) {
HAL_NVIC_SetPriority(FDCAN1_IT1_IRQn, 0, 2);
HAL_NVIC_EnableIRQ(FDCAN1_IT1_IRQn);
} else {
HAL_NVIC_SetPriority(FDCAN2_IT1_IRQn, 0, 2);
HAL_NVIC_EnableIRQ(FDCAN2_IT1_IRQn);
}
} else if (argval == RT_DEVICE_CAN_INT_ERR) {
HAL_FDCAN_ConfigInterruptLines(&pdrv_can->fdcanHandle, FDCAN_IT_BUS_OFF, FDCAN_INTERRUPT_LINE1);
HAL_FDCAN_ConfigInterruptLines(&pdrv_can->fdcanHandle, FDCAN_IT_ERROR_WARNING, FDCAN_INTERRUPT_LINE1);
HAL_FDCAN_ConfigInterruptLines(&pdrv_can->fdcanHandle, FDCAN_IT_ERROR_PASSIVE, FDCAN_INTERRUPT_LINE1);
HAL_FDCAN_ConfigInterruptLines(&pdrv_can->fdcanHandle, FDCAN_IT_ARB_PROTOCOL_ERROR,
FDCAN_INTERRUPT_LINE1);
HAL_FDCAN_ActivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_BUS_OFF, 0);
HAL_FDCAN_ActivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_ERROR_WARNING, 0);
HAL_FDCAN_ActivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_ERROR_PASSIVE, 0);
HAL_FDCAN_ActivateNotification(&pdrv_can->fdcanHandle, FDCAN_IT_ARB_PROTOCOL_ERROR, 0);
if (FDCAN1 == pdrv_can->fdcanHandle.Instance) {
HAL_NVIC_SetPriority(FDCAN1_IT1_IRQn, 0, 2);
HAL_NVIC_EnableIRQ(FDCAN1_IT1_IRQn);
} else {
HAL_NVIC_SetPriority(FDCAN2_IT1_IRQn, 0, 2);
HAL_NVIC_EnableIRQ(FDCAN2_IT1_IRQn);
}
}
break;
case RT_CAN_CMD_SET_FILTER:
if (RT_NULL == arg) {
/* default filter config */
HAL_FDCAN_ConfigFilter(&pdrv_can->fdcanHandle, &pdrv_can->FilterConfig);
} else {
filter_cfg = (struct rt_can_filter_config *) arg;
_inline_can_filter_config(pdrv_can, filter_cfg);
}
break;
case RT_CAN_CMD_SET_MODE:
argval = (rt_uint32_t) arg;
if (argval != RT_CAN_MODE_NORMAL &&
argval != RT_CAN_MODE_LISTEN &&
argval != RT_CAN_MODE_LOOPBACK &&
argval != RT_CAN_MODE_LOOPBACKANLISTEN) {
return -RT_ERROR;
}
if (argval != pdrv_can->device.config.mode) {
pdrv_can->device.config.mode = argval;
return _inline_can_config(&pdrv_can->device, &pdrv_can->device.config);
}
break;
case RT_CAN_CMD_SET_BAUD:
argval = (rt_uint32_t) arg;
uint32_t arb_idx = _inline_get_ArbBaudIndex(argval);
if (arb_idx == (uint32_t) -1) {
return -RT_ERROR;
}
if (argval != pdrv_can->device.config.baud_rate) {
pdrv_can->device.config.baud_rate = argval;
return _inline_can_config(&pdrv_can->device, &pdrv_can->device.config);
}
break;
case RT_CAN_CMD_SET_PRIV:
argval = (rt_uint32_t) arg;
if (argval != RT_CAN_MODE_PRIV &&
argval != RT_CAN_MODE_NOPRIV) {
return -RT_ERROR;
}
if (argval != pdrv_can->device.config.privmode) {
pdrv_can->device.config.privmode = argval;
return RT_EOK;
}
break;
case RT_CAN_CMD_GET_STATUS: {
rt_uint32_t tmp_u32Errcount;
rt_uint32_t tmp_u32status;
tmp_u32Errcount = pdrv_can->fdcanHandle.Instance->ECR;
tmp_u32status = pdrv_can->fdcanHandle.Instance->PSR;
pdrv_can->device.status.rcverrcnt = (tmp_u32Errcount >> 8) & 0x000000ff;
pdrv_can->device.status.snderrcnt = (tmp_u32Errcount) & 0x000000ff;
pdrv_can->device.status.lasterrtype = tmp_u32status & 0x000000007;
rt_memcpy(arg, &pdrv_can->device.status, sizeof(pdrv_can->device.status));
}
break;
case RT_CAN_CMD_SET_BAUD_FD: {
argval = (rt_uint32_t) arg;
uint32_t data_idx = _inline_get_DataBaudIndex(argval);
if (data_idx == (uint32_t) -1) {
return -RT_ERROR;
}
if (argval != pdrv_can->device.config.baud_rate_fd) {
pdrv_can->device.config.baud_rate_fd = argval;
return _inline_can_config(&pdrv_can->device, &pdrv_can->device.config);
}
}
}
return RT_EOK;
}
static int _inline_can_sendmsg(struct rt_can_device *can, const void *buf, rt_uint32_t box_num)
{
stm32_fdcan_t *pdrv_can;
struct rt_can_msg *pmsg;
uint32_t tmp_u32DataLen;
RT_ASSERT(can);
RT_ASSERT(buf);
pdrv_can = (stm32_fdcan_t *)can->parent.user_data;
RT_ASSERT(pdrv_can);
pmsg = (struct rt_can_msg *) buf;
/* Check the parameters */
tmp_u32DataLen = length_to_dlc( pmsg->len);
if(pmsg->ide == RT_CAN_EXTID)
{
pdrv_can->TxHeader.IdType = FDCAN_EXTENDED_ID;
}
else
{
pdrv_can->TxHeader.IdType = FDCAN_STANDARD_ID;
}
if (RT_CAN_DTR == pmsg->rtr)
{
pdrv_can->TxHeader.TxFrameType = FDCAN_DATA_FRAME;
}
else
{
pdrv_can->TxHeader.TxFrameType = FDCAN_REMOTE_FRAME;
}
pdrv_can->TxHeader.Identifier = pmsg->id;
pdrv_can->TxHeader.DataLength = tmp_u32DataLen;
if (pmsg->fd_frame == 1)
{
pdrv_can->TxHeader.FDFormat = FDCAN_FD_CAN;
}
else {
pdrv_can->TxHeader.FDFormat = FDCAN_CLASSIC_CAN;
}
if(HAL_FDCAN_AddMessageToTxBuffer(&pdrv_can->fdcanHandle, &pdrv_can->TxHeader, pmsg->data, FDCAN_TX_BUFFER0 + box_num) != HAL_OK)
{
return -RT_ERROR;
}
else
{
/* Request transmission */
HAL_FDCAN_EnableTxBufferRequest(&pdrv_can->fdcanHandle,FDCAN_TX_BUFFER0+box_num);
return RT_EOK;
}
}
static int _inline_can_recvmsg(struct rt_can_device *can, void *buf, rt_uint32_t fifo)
{
struct rt_can_msg *pmsg;
stm32_fdcan_t *pdrv_can;
RT_ASSERT(can);
RT_ASSERT(buf);
pdrv_can = (stm32_fdcan_t *)can->parent.user_data;
pmsg = (struct rt_can_msg *) buf;
if(HAL_FDCAN_GetRxMessage(&pdrv_can->fdcanHandle,FDCAN_RX_FIFO0+fifo, &pdrv_can->RxHeader, pmsg->data) != HAL_OK)
{
return 0;
}
else
{
if(pdrv_can->RxHeader.IdType == FDCAN_EXTENDED_ID)
{
pmsg->ide = RT_CAN_EXTID;
}
else
{
pmsg->ide = RT_CAN_STDID;
}
if(pdrv_can->RxHeader.RxFrameType == FDCAN_DATA_FRAME)
{
pmsg->rtr = RT_CAN_DTR;
}
else
{
pmsg->rtr = RT_CAN_RTR;
}
pmsg->id = pdrv_can->RxHeader.Identifier;
pmsg->len = pdrv_can->RxHeader.DataLength;
pmsg->hdr_index = pdrv_can->RxHeader.FilterIndex;
#ifdef RT_CAN_USING_CANFD
pmsg->fd_frame = (pdrv_can->RxHeader.FDFormat >> 16) && 0x20;
pmsg->brs = (pdrv_can->RxHeader.BitRateSwitch >> 16) && 0x10;
#endif
return sizeof(struct rt_can_msg);
}
}
static const struct rt_can_ops _can_ops =
{
_inline_can_config,
_inline_can_control,
_inline_can_sendmsg,
_inline_can_recvmsg,
};
void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs)
{
if((RxFifo0ITs & FDCAN_IT_RX_FIFO0_NEW_MESSAGE) != RESET)
{
if(hfdcan->Instance == FDCAN1)
{
#ifdef BSP_USING_FDCAN1
//CAN1
/* Retreive Rx messages from RX FIFO0 */
rt_hw_can_isr(&st_DrvCan1.device, RT_CAN_EVENT_RX_IND | 0 << 8);
#endif
}
else
{
#ifdef BSP_USING_FDCAN2
//CAN2
/* Retreive Rx messages from RX FIFO0 */
rt_hw_can_isr(&st_DrvCan2.device, RT_CAN_EVENT_RX_IND | 0 << 8);
#endif
}
}
}
void HAL_FDCAN_TxBufferCompleteCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t BufferIndexes)
{
if(hfdcan->Instance == FDCAN1)
{
#ifdef BSP_USING_FDCAN1
//can1
rt_hw_can_isr(&st_DrvCan1.device, RT_CAN_EVENT_TX_DONE | ((BufferIndexes-1) << 8));
#endif
}
else
{
#ifdef BSP_USING_FDCAN2
//can2
rt_hw_can_isr(&st_DrvCan2.device, RT_CAN_EVENT_TX_DONE | ((BufferIndexes-1) << 8));
#endif
}
}
void HAL_FDCAN_TxFifoEmptyCallback(FDCAN_HandleTypeDef *hfdcan)
{
if(hfdcan->Instance == FDCAN1)
{
#ifdef BSP_USING_FDCAN1
rt_hw_can_isr(&st_DrvCan1.device, RT_CAN_EVENT_TX_DONE);
#endif
}
else
{
#ifdef BSP_USING_FDCAN2
rt_hw_can_isr(&st_DrvCan2.device, RT_CAN_EVENT_TX_DONE);
#endif
}
}
void HAL_FDCAN_ErrorCallback(FDCAN_HandleTypeDef *hfdcan)
{
rt_uint32_t tmp_u32Errcount;
rt_uint32_t tmp_u32status;
uint32_t ret = HAL_FDCAN_GetError(hfdcan);
if(hfdcan->Instance == FDCAN1)
{
#ifdef BSP_USING_FDCAN1
if((ret & FDCAN_IT_ARB_PROTOCOL_ERROR) &&
(hfdcan->Instance->CCCR & FDCAN_CCCR_INIT_Msk))
{
//hfdcan->Instance->CCCR |= FDCAN_CCCR_CCE_Msk;
hfdcan->Instance->CCCR &= ~FDCAN_CCCR_INIT_Msk;
st_DrvCan1.device.status.errcode = 0xff;
}
else
{
tmp_u32Errcount = st_DrvCan1.fdcanHandle.Instance->ECR;
tmp_u32status = st_DrvCan1.fdcanHandle.Instance->PSR;
st_DrvCan1.device.status.rcverrcnt = (tmp_u32Errcount>>8)&0x000000ff;
st_DrvCan1.device.status.snderrcnt = (tmp_u32Errcount)&0x000000ff;
st_DrvCan1.device.status.lasterrtype = tmp_u32status&0x000000007;
rt_hw_can_isr(&st_DrvCan1.device, RT_CAN_EVENT_TX_FAIL);
}
#endif /*BSP_USING_FDCAN1*/
}
else
{
#ifdef BSP_USING_FDCAN2
if( (ret & FDCAN_IT_ARB_PROTOCOL_ERROR) &&
(hfdcan->Instance->CCCR & FDCAN_CCCR_INIT_Msk))
{
//hfdcan->Instance->CCCR |= FDCAN_CCCR_CCE_Msk;
hfdcan->Instance->CCCR &= ~FDCAN_CCCR_INIT_Msk;
st_DrvCan2.device.status.errcode = 0xff;
}
else
{
//can2
tmp_u32Errcount = st_DrvCan2.fdcanHandle.Instance->ECR;
tmp_u32status = st_DrvCan2.fdcanHandle.Instance->PSR;
st_DrvCan2.device.status.rcverrcnt = (tmp_u32Errcount>>8)&0x000000ff;
st_DrvCan2.device.status.snderrcnt = (tmp_u32Errcount)&0x000000ff;
st_DrvCan2.device.status.lasterrtype = tmp_u32status&0x000000007;
rt_hw_can_isr(&st_DrvCan2.device, RT_CAN_EVENT_TX_FAIL);
}
#endif /*BSP_USING_FDCAN2*/
}
}
#ifdef BSP_USING_FDCAN1
void FDCAN1_IT0_IRQHandler(void) /* FDCAN1 interrupt line 0 */
{
rt_interrupt_enter();
HAL_FDCAN_IRQHandler(&st_DrvCan1.fdcanHandle);
rt_interrupt_leave();
}
void FDCAN1_IT1_IRQHandler(void) /* FDCAN1 interrupt line 1 */
{
rt_interrupt_enter();
HAL_FDCAN_IRQHandler(&st_DrvCan1.fdcanHandle);
rt_interrupt_leave();
}
#endif /*BSP_USING_FDCAN1*/
#ifdef BSP_USING_FDCAN2
void FDCAN2_IT0_IRQHandler(void) /* FDCAN2 interrupt line 0 */
{
rt_interrupt_enter();
HAL_FDCAN_IRQHandler(&st_DrvCan2.fdcanHandle);
rt_interrupt_leave();
}
void FDCAN2_IT1_IRQHandler(void) /* FDCAN2 interrupt line 1 */
{
rt_interrupt_enter();
HAL_FDCAN_IRQHandler(&st_DrvCan2.fdcanHandle);
rt_interrupt_leave();
}
#endif/*BSP_USING_FDCAN2*/
static int rt_hw_can_init(void)
{
struct can_configure config;
config.baud_rate = CAN1MBaud;
config.msgboxsz = 48;
config.sndboxnumber = 1;
config.mode = RT_CAN_MODE_NORMAL;
config.privmode = RT_CAN_MODE_NOPRIV;
config.ticks = 50;
#ifdef RT_CAN_USING_HDR
config.maxhdr = 14;
#endif
#ifdef RT_CAN_USING_CANFD
config.baud_rate_fd = CAN1MBaud * 8;
config.enable_canfd = 1;
#endif
/* config default filter */
FDCAN_FilterTypeDef sFilterConfig;
sFilterConfig.IdType = FDCAN_STANDARD_ID;
sFilterConfig.FilterIndex = 0;
sFilterConfig.FilterType = FDCAN_FILTER_MASK;
sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;
sFilterConfig.FilterID1 = 0;
sFilterConfig.FilterID2 = 0x7FF;
#ifdef BSP_USING_FDCAN1
st_DrvCan1.FilterConfig = sFilterConfig;
st_DrvCan1.device.config = config;
/* register FDCAN1 device */
rt_hw_can_register(&st_DrvCan1.device, st_DrvCan1.name, &_can_ops, &st_DrvCan1);
#endif /* BSP_USING_FDCAN1 */
#ifdef BSP_USING_FDCAN2
st_DrvCan2.FilterConfig = sFilterConfig;
st_DrvCan2.device.config = config;
/* register FDCAN2 device */
rt_hw_can_register(&st_DrvCan2.device, st_DrvCan2.name, &_can_ops, &st_DrvCan2);
#endif /* BSP_USING_FDCAN2 */
return 0;
}
INIT_BOARD_EXPORT(rt_hw_can_init);
#endif /* BSP_USING_FDCAN1 || BSP_USING_FDCAN2 */
#endif /* RT_USING_CAN */

View File

@@ -1,46 +0,0 @@
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-02-24 heyuan the first version
* 2020-08-17 malongwei Fix something
*/
#ifndef __DRV_FDCAN_H__
#define __DRV_FDCAN_H__
#include <board.h>
#include <rtdevice.h>
#if defined(RT_USING_CAN) && defined(RT_CAN_USING_CANFD)
#ifdef __cplusplus
extern "C" {
#endif
typedef struct
{
const char *name;
FDCAN_HandleTypeDef fdcanHandle;
FDCAN_RxHeaderTypeDef RxHeader;
FDCAN_TxHeaderTypeDef TxHeader;
uint8_t u8RxDataBuffer[8];
uint8_t u8TxDataBuffer[8];
FDCAN_FilterTypeDef FilterConfig; /*FDCAN filter*/
struct rt_can_device device; /* inherit from can device */
} stm32_fdcan_t;
typedef struct {
uint32_t u32Baudrate;
struct rt_can_bit_timing cam_bit_timing;
}stm32_fdcan_timing_t;
#ifdef __cplusplus
}
#endif
#endif /* RT_USING_CAN */
#endif /* __DRV_FDCAN_H__ */

View File

@@ -1,268 +0,0 @@
/*
* Copyright (C) 2017-2024 Alibaba Group Holding Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file gcc_csky.ld
* @brief csky linker file
* @version V1.0
* @date 02. June 2017
******************************************************************************/
MEMORY
{
ISRAM : ORIGIN = 0x00000000 , LENGTH = 0x20000 /* ISRAM 128KB*/
DSRAM : ORIGIN = 0x20000000 , LENGTH = 0x80000 /* DSRAM 512KB*/
SRAM : ORIGIN = 0x60000000 , LENGTH = 0x20000 /* SRAM 128KB, no cacheable*/
}
__min_heap_size = 0x200;
PROVIDE (__ram_end = 0x20080000);
PROVIDE (__heap_end = __ram_end);
REGION_ALIAS("REGION_TEXT", ISRAM);
REGION_ALIAS("REGION_RODATA", ISRAM);
REGION_ALIAS("REGION_DATA", DSRAM);
REGION_ALIAS("REGION_BSS", DSRAM);
ENTRY(Reset_Handler)
SECTIONS
{
.text : {
. = ALIGN(0x4) ;
__stext = . ;
KEEP(*startup.o(*.text))
KEEP(*startup.o(*.vectors))
KEEP(*vectors.o(*.text))
KEEP(*(.text.entry))
*(.text*)
*(.gnu.warning)
*(.stub)
*(.gnu.linkonce.t*)
*(.glue_7t)
*(.glue_7)
*(.jcr)
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN (0x4) ;
PROVIDE(__ctbp = .);
*(.call_table_data)
*(.call_table_text)
. = ALIGN(0x10) ;
__etext = . ;
} > REGION_TEXT
.eh_frame_hdr : {
*(.eh_frame_hdr)
} > REGION_TEXT
.eh_frame : ONLY_IF_RO {
KEEP (*(.eh_frame))
} > REGION_TEXT
.rodata : {
. = ALIGN(0x4) ;
__srodata = .;
*(.rdata)
*(.rdata*)
*(.rdata1)
*(.rdata.*)
*(.rodata*)
*(.srodata*)
. = ALIGN(0x4) ;
__init_array_start = .;
__ctors_start__ = .;
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
__init_array_end = .;
__ctors_end__ = .;
__fini_array_start = .;
__dtors_start__ = .;
KEEP (*(SORT(.fini_array.*)))
KEEP (*(.fini_array))
__fini_array_end = .;
__dtors_end__ = .;
. = ALIGN(0x4) ;
__ctor_start__ = .;
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
__ctor_end__ = .;
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
__dtor_end__ = .;
. = ALIGN(0x4) ;
/*****************************************/
/* section information for finsh shell */
. = ALIGN(0x4);
__fsymtab_start = .;
KEEP(*(FSymTab))
__fsymtab_end = .;
. = ALIGN(0x4);
__vsymtab_start = .;
KEEP(*(VSymTab))
__vsymtab_end = .;
. = ALIGN(0x4);
/* section information for initial. */
__rt_init_start = .;
KEEP(*(SORT(.rti_fn*)))
__rt_init_end = .;
. = ALIGN(0x4) ;
/* section information for at utest */
__rt_utest_tc_tab_start = .;
KEEP(*(UtestTcTab))
__rt_utest_tc_tab_end = .;
. = ALIGN(0x4);
/* section information for at server */
. = ALIGN(0x4);
__rtatcmdtab_start = .;
KEEP(*(RtAtCmdTab))
__rtatcmdtab_end = .;
. = ALIGN(0x4);
/* section information for modules */
. = ALIGN(0x4);
__rtmsymtab_start = .;
KEEP(*(RTMSymTab))
__rtmsymtab_end = .;
/* section information for uPRC */
. = ALIGN(0x4);
__uRPCSvcTab_start = .;
KEEP(*(uRPCSvcTab))
__uRPCSvcTab_end = .;
/* section information for var export */
. = ALIGN(0x4);
__ve_table_start = .;
KEEP(*(SORT(*.VarExpTab.*)))
__ve_table_end = .;
/*****************************************/
/************** added drivers **************/
_cli_region_begin = .;
KEEP(*(CliRegion))
. = ALIGN(0x4);
_cli_region_end = .;
__core_driver_start__ = .;
KEEP(*(.core_driver_entry))
. = ALIGN(0x4);
__core_driver_end__ = .;
__bus_driver_start__ = .;
KEEP(*(*.bus_driver_entry))
__bus_driver_end__ = .;
__early_driver_start__ = .;
KEEP(*(*.early_driver_entry))
__early_driver_end__ = .;
__vfs_driver_start__ = .;
KEEP(*(*.vfs_driver_entry))
__vfs_driver_end__ = .;
__level0_driver_start__ = .;
KEEP(*(*.level0_driver_entry))
__level0_driver_end__ = .;
__level1_driver_start__ = .;
KEEP(*(*.level1_driver_entry))
__level1_driver_end__ = .;
__level2_driver_start__ = .;
KEEP(*(*.level2_driver_entry))
__level2_driver_end__ = .;
__level3_driver_start__ = .;
KEEP(*(*.level3_driver_entry))
__level3_driver_end__ = .;
__post_driver_start__ = .;
KEEP(*(*.post_driver_entry))
__post_driver_end__ = .;
/************** end of drivers *********/
. = ALIGN(0x40) ;
__jvt_base$ = .;
KEEP(*(*.riscv.jvt))
. = ALIGN(0x8) ;
__erodata = .;
__rodata_end__ = .;
} > REGION_RODATA
.data : {
. = ALIGN(0x4) ;
__sdata = . ;
__data_start__ = . ;
data_start = . ;
*(.got.plt)
*(.got)
*(.gnu.linkonce.r*)
*(.data*)
*(.gnu.linkonce.d*)
*(.gcc_except_table*)
__start_init_call = .;
*(.initcall.init)
__stop_init_call = .;
__start_cmd = .;
*(.bootloaddata.cmd)
. = ALIGN(0x4) ;
__stop_cmd = .;
__global_pointer$ = .;
*(.sdata)
*(.sdata.*)
*(.sdata2.*)
*(.gnu.linkonce.s.*)
*(__libc_atexit)
*(__libc_subinit)
*(__libc_subfreeres)
*(.note.ABI-tag)
. = ALIGN(0x4) ;
__edata = .;
__data_end__ = .;
} > REGION_DATA AT > REGION_RODATA
._ram_code : {
. = ALIGN(0x4) ;
__ram_code_start__ = .;
*(.ram.code*)
. = ALIGN(0x4) ;
__ram_code_end__ = .;
} > REGION_DATA AT > REGION_RODATA
.bss : {
. = ALIGN(0x4) ;
__sbss = ALIGN(0x4) ;
__bss_start__ = . ;
*(.dynsbss)
*(.sbss)
*(.sbss.*)
*(.scommon)
*(.dynbss)
*(.bss*)
*(COMMON)
. = ALIGN(0x4) ;
__ebss = . ;
__bss_end__ = .;
__end = . ;
end = . ;
} > REGION_BSS AT > REGION_BSS
._user_heap (NOLOAD): {
. = ALIGN(0x4) ;
*(.stack*)
. = ALIGN(0x4) ;
__heap_start = .;
. += __min_heap_size;
. = ALIGN(0x4) ;
} > REGION_BSS AT > REGION_BSS
}

View File

@@ -1,281 +0,0 @@
/*
* Copyright (C) 2017-2024 Alibaba Group Holding Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file gcc_csky.ld
* @brief csky linker file
* @version V1.0
* @date 02. June 2017
******************************************************************************/
MEMORY
{
ISRAM : ORIGIN = 0x00000000 , LENGTH = 0x20000 /* ISRAM 128KB*/
DSRAM : ORIGIN = 0x00100000 , LENGTH = 0x80000 /* DSRAM 512KB*/
SRAM : ORIGIN = 0x001D0000 , LENGTH = 0x20000 /* SRAM 128KB, no cacheable*/
}
__min_heap_size = 0x200;
PROVIDE (__ram_end = 0x00180000);
PROVIDE (__heap_end = __ram_end);
REGION_ALIAS("REGION_TEXT", ISRAM);
REGION_ALIAS("REGION_RODATA", ISRAM);
REGION_ALIAS("REGION_DATA", DSRAM);
REGION_ALIAS("REGION_BSS", DSRAM);
ENTRY(Reset_Handler)
SECTIONS
{
.text : {
. = ALIGN(0x4) ;
__stext = . ;
KEEP(*startup.o(*.text))
} > REGION_TEXT
.mtvec 0x40 : {
KEEP(*vectors.o(*.mtvec))
} > REGION_TEXT
. = MAX(., 0x80);
.vectors 0x80 : {
KEEP(*startup.o(*.vectors))
} > REGION_TEXT
. = MAX(., 0x300);
.text 0x300 : {
__jvt_base$ = .;
KEEP(*(*.riscv.jvt))
. = ALIGN(0x4) ;
__jvt_end$ = .;
} > REGION_TEXT
.text : {
. = ALIGN(0x4) ;
KEEP(*vectors.o(*.text))
KEEP(*(.text.entry))
*(.text*)
*(.gnu.warning)
*(.stub)
*(.gnu.linkonce.t*)
*(.glue_7t)
*(.glue_7)
*(.jcr)
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN (0x4) ;
PROVIDE(__ctbp = .);
*(.call_table_data)
*(.call_table_text)
. = ALIGN(0x10) ;
__etext = . ;
} > REGION_TEXT
.eh_frame_hdr : {
*(.eh_frame_hdr)
} > REGION_TEXT
.eh_frame : ONLY_IF_RO {
KEEP (*(.eh_frame))
} > REGION_TEXT
.rodata : {
. = ALIGN(0x4) ;
__srodata = .;
*(.rdata)
*(.rdata*)
*(.rdata1)
*(.rdata.*)
*(.rodata*)
*(.srodata*)
. = ALIGN(0x4) ;
__init_array_start = .;
__ctors_start__ = .;
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
__init_array_end = .;
__ctors_end__ = .;
__fini_array_start = .;
__dtors_start__ = .;
KEEP (*(SORT(.fini_array.*)))
KEEP (*(.fini_array))
__fini_array_end = .;
__dtors_end__ = .;
. = ALIGN(0x4) ;
__ctor_start__ = .;
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
__ctor_end__ = .;
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
__dtor_end__ = .;
. = ALIGN(0x4) ;
/*****************************************/
/* section information for finsh shell */
. = ALIGN(0x4);
__fsymtab_start = .;
KEEP(*(FSymTab))
__fsymtab_end = .;
. = ALIGN(0x4);
__vsymtab_start = .;
KEEP(*(VSymTab))
__vsymtab_end = .;
. = ALIGN(0x4);
/* section information for initial. */
__rt_init_start = .;
KEEP(*(SORT(.rti_fn*)))
__rt_init_end = .;
. = ALIGN(0x4) ;
/* section information for at utest */
__rt_utest_tc_tab_start = .;
KEEP(*(UtestTcTab))
__rt_utest_tc_tab_end = .;
. = ALIGN(0x4);
/* section information for at server */
. = ALIGN(0x4);
__rtatcmdtab_start = .;
KEEP(*(RtAtCmdTab))
__rtatcmdtab_end = .;
. = ALIGN(0x4);
/* section information for modules */
. = ALIGN(0x4);
__rtmsymtab_start = .;
KEEP(*(RTMSymTab))
__rtmsymtab_end = .;
/* section information for uPRC */
. = ALIGN(0x4);
__uRPCSvcTab_start = .;
KEEP(*(uRPCSvcTab))
__uRPCSvcTab_end = .;
/* section information for var export */
. = ALIGN(0x4);
__ve_table_start = .;
KEEP(*(SORT(*.VarExpTab.*)))
__ve_table_end = .;
/*****************************************/
/************** added drivers **************/
_cli_region_begin = .;
KEEP(*(CliRegion))
. = ALIGN(0x4);
_cli_region_end = .;
__core_driver_start__ = .;
KEEP(*(.core_driver_entry))
. = ALIGN(0x4);
__core_driver_end__ = .;
__bus_driver_start__ = .;
KEEP(*(*.bus_driver_entry))
__bus_driver_end__ = .;
__early_driver_start__ = .;
KEEP(*(*.early_driver_entry))
__early_driver_end__ = .;
__vfs_driver_start__ = .;
KEEP(*(*.vfs_driver_entry))
__vfs_driver_end__ = .;
__level0_driver_start__ = .;
KEEP(*(*.level0_driver_entry))
__level0_driver_end__ = .;
__level1_driver_start__ = .;
KEEP(*(*.level1_driver_entry))
__level1_driver_end__ = .;
__level2_driver_start__ = .;
KEEP(*(*.level2_driver_entry))
__level2_driver_end__ = .;
__level3_driver_start__ = .;
KEEP(*(*.level3_driver_entry))
__level3_driver_end__ = .;
__post_driver_start__ = .;
KEEP(*(*.post_driver_entry))
__post_driver_end__ = .;
/************** end of drivers *********/
. = ALIGN(0x8) ;
__erodata = .;
__rodata_end__ = .;
} > REGION_RODATA
.data : {
. = ALIGN(0x4) ;
__sdata = . ;
__data_start__ = . ;
data_start = . ;
*(.got.plt)
*(.got)
*(.gnu.linkonce.r*)
*(.data*)
*(.gnu.linkonce.d*)
*(.gcc_except_table*)
__start_init_call = .;
*(.initcall.init)
__stop_init_call = .;
__start_cmd = .;
*(.bootloaddata.cmd)
. = ALIGN(0x4) ;
__stop_cmd = .;
__global_pointer$ = .;
*(.sdata)
*(.sdata.*)
*(.sdata2.*)
*(.gnu.linkonce.s.*)
*(__libc_atexit)
*(__libc_subinit)
*(__libc_subfreeres)
*(.note.ABI-tag)
. = ALIGN(0x4) ;
__edata = .;
__data_end__ = .;
} > REGION_DATA AT > REGION_RODATA
._ram_code : {
. = ALIGN(0x4) ;
__ram_code_start__ = .;
*(.ram.code*)
. = ALIGN(0x4) ;
__ram_code_end__ = .;
} > REGION_DATA AT > REGION_RODATA
.bss : {
. = ALIGN(0x4) ;
__sbss = ALIGN(0x4) ;
__bss_start__ = . ;
*(.dynsbss)
*(.sbss)
*(.sbss.*)
*(.scommon)
*(.dynbss)
*(.bss*)
*(COMMON)
. = ALIGN(0x4) ;
__ebss = . ;
__bss_end__ = .;
__end = . ;
end = . ;
} > REGION_BSS AT > REGION_BSS
._user_heap (NOLOAD): {
. = ALIGN(0x4) ;
*(.stack*)
. = ALIGN(0x4) ;
__heap_start = .;
. += __min_heap_size;
. = ALIGN(0x4) ;
} > REGION_BSS AT > REGION_BSS
}

View File

@@ -1,273 +0,0 @@
/*
* Copyright (C) 2017-2024 Alibaba Group Holding Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file gcc_csky.ld
* @brief csky linker file
* @version V1.0
* @date 02. June 2017
******************************************************************************/
MEMORY
{
ISRAM : ORIGIN = 0x00000000 , LENGTH = 0x20000 /* ISRAM 128KB*/
DSRAM : ORIGIN = 0x00100000 , LENGTH = 0x80000 /* DSRAM 512KB*/
SRAM : ORIGIN = 0x001D0000 , LENGTH = 0x20000 /* SRAM 128KB, no cacheable*/
}
__min_heap_size = 0x200;
PROVIDE (__ram_end = 0x00180000);
PROVIDE (__heap_end = __ram_end);
REGION_ALIAS("REGION_TEXT", ISRAM);
REGION_ALIAS("REGION_RODATA", ISRAM);
REGION_ALIAS("REGION_DATA", DSRAM);
REGION_ALIAS("REGION_BSS", DSRAM);
ENTRY(Reset_Handler)
SECTIONS
{
.text : {
. = ALIGN(0x4) ;
__stext = . ;
KEEP(*startup.o(*.text))
KEEP(*startup.o(*.vectors))
. = ALIGN(0x40) ;
KEEP(*vectors.o(*.mtvec))
} > REGION_TEXT
.text : {
. = ALIGN(0x4) ;
KEEP(*vectors.o(*.text))
KEEP(*(.text.entry))
*(.text*)
*(.gnu.warning)
*(.stub)
*(.gnu.linkonce.t*)
*(.glue_7t)
*(.glue_7)
*(.jcr)
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN (0x4) ;
PROVIDE(__ctbp = .);
*(.call_table_data)
*(.call_table_text)
. = ALIGN(0x10) ;
__etext = . ;
} > REGION_TEXT
.eh_frame_hdr : {
*(.eh_frame_hdr)
} > REGION_TEXT
.eh_frame : ONLY_IF_RO {
KEEP (*(.eh_frame))
} > REGION_TEXT
.rodata : {
. = ALIGN(0x4) ;
__srodata = .;
*(.rdata)
*(.rdata*)
*(.rdata1)
*(.rdata.*)
*(.rodata*)
*(.srodata*)
. = ALIGN(0x4) ;
__init_array_start = .;
__ctors_start__ = .;
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
__init_array_end = .;
__ctors_end__ = .;
__fini_array_start = .;
__dtors_start__ = .;
KEEP (*(SORT(.fini_array.*)))
KEEP (*(.fini_array))
__fini_array_end = .;
__dtors_end__ = .;
. = ALIGN(0x4) ;
__ctor_start__ = .;
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
__ctor_end__ = .;
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
__dtor_end__ = .;
. = ALIGN(0x4) ;
/*****************************************/
/* section information for finsh shell */
. = ALIGN(0x4);
__fsymtab_start = .;
KEEP(*(FSymTab))
__fsymtab_end = .;
. = ALIGN(0x4);
__vsymtab_start = .;
KEEP(*(VSymTab))
__vsymtab_end = .;
. = ALIGN(0x4);
/* section information for initial. */
__rt_init_start = .;
KEEP(*(SORT(.rti_fn*)))
__rt_init_end = .;
. = ALIGN(0x4) ;
/* section information for at utest */
__rt_utest_tc_tab_start = .;
KEEP(*(UtestTcTab))
__rt_utest_tc_tab_end = .;
. = ALIGN(0x4);
/* section information for at server */
. = ALIGN(0x4);
__rtatcmdtab_start = .;
KEEP(*(RtAtCmdTab))
__rtatcmdtab_end = .;
. = ALIGN(0x4);
/* section information for modules */
. = ALIGN(0x4);
__rtmsymtab_start = .;
KEEP(*(RTMSymTab))
__rtmsymtab_end = .;
/* section information for uPRC */
. = ALIGN(0x4);
__uRPCSvcTab_start = .;
KEEP(*(uRPCSvcTab))
__uRPCSvcTab_end = .;
/* section information for var export */
. = ALIGN(0x4);
__ve_table_start = .;
KEEP(*(SORT(*.VarExpTab.*)))
__ve_table_end = .;
/*****************************************/
/************** added drivers **************/
_cli_region_begin = .;
KEEP(*(CliRegion))
. = ALIGN(0x4);
_cli_region_end = .;
__core_driver_start__ = .;
KEEP(*(.core_driver_entry))
. = ALIGN(0x4);
__core_driver_end__ = .;
__bus_driver_start__ = .;
KEEP(*(*.bus_driver_entry))
__bus_driver_end__ = .;
__early_driver_start__ = .;
KEEP(*(*.early_driver_entry))
__early_driver_end__ = .;
__vfs_driver_start__ = .;
KEEP(*(*.vfs_driver_entry))
__vfs_driver_end__ = .;
__level0_driver_start__ = .;
KEEP(*(*.level0_driver_entry))
__level0_driver_end__ = .;
__level1_driver_start__ = .;
KEEP(*(*.level1_driver_entry))
__level1_driver_end__ = .;
__level2_driver_start__ = .;
KEEP(*(*.level2_driver_entry))
__level2_driver_end__ = .;
__level3_driver_start__ = .;
KEEP(*(*.level3_driver_entry))
__level3_driver_end__ = .;
__post_driver_start__ = .;
KEEP(*(*.post_driver_entry))
__post_driver_end__ = .;
/************** end of drivers *********/
. = ALIGN(0x40) ;
__jvt_base$ = .;
KEEP(*(*.riscv.jvt))
. = ALIGN(0x8) ;
__erodata = .;
__rodata_end__ = .;
} > REGION_RODATA
.data : {
. = ALIGN(0x4) ;
__sdata = . ;
__data_start__ = . ;
data_start = . ;
*(.got.plt)
*(.got)
*(.gnu.linkonce.r*)
*(.data*)
*(.gnu.linkonce.d*)
*(.gcc_except_table*)
__start_init_call = .;
*(.initcall.init)
__stop_init_call = .;
__start_cmd = .;
*(.bootloaddata.cmd)
. = ALIGN(0x4) ;
__stop_cmd = .;
__global_pointer$ = .;
*(.sdata)
*(.sdata.*)
*(.sdata2.*)
*(.gnu.linkonce.s.*)
*(__libc_atexit)
*(__libc_subinit)
*(__libc_subfreeres)
*(.note.ABI-tag)
. = ALIGN(0x4) ;
__edata = .;
__data_end__ = .;
} > REGION_DATA AT > REGION_RODATA
._ram_code : {
. = ALIGN(0x4) ;
__ram_code_start__ = .;
*(.ram.code*)
. = ALIGN(0x4) ;
__ram_code_end__ = .;
} > REGION_DATA AT > REGION_RODATA
.bss : {
. = ALIGN(0x4) ;
__sbss = ALIGN(0x4) ;
__bss_start__ = . ;
*(.dynsbss)
*(.sbss)
*(.sbss.*)
*(.scommon)
*(.dynbss)
*(.bss*)
*(COMMON)
. = ALIGN(0x4) ;
__ebss = . ;
__bss_end__ = .;
__end = . ;
end = . ;
} > REGION_BSS AT > REGION_BSS
._user_heap (NOLOAD): {
. = ALIGN(0x4) ;
*(.stack*)
. = ALIGN(0x4) ;
__heap_start = .;
. += __min_heap_size;
. = ALIGN(0x4) ;
} > REGION_BSS AT > REGION_BSS
}

View File

@@ -1,13 +0,0 @@
from building import *
import os
cwd = GetCurrentDir()
CPPPATH = [cwd]
src = ['startup.S']
src += ['system.c']
src += ['trap_c.c']
src += ['vectors.S']
group = DefineGroup('sys', src, depend = [''], CPPPATH = CPPPATH)
Return('group')

View File

@@ -1,200 +0,0 @@
/*
* Copyright (C) 2017-2024 Alibaba Group Holding Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <csi_config.h>
.global __rt_rvstack
#ifndef CONFIG_SUPPORT_NON_VECTOR_IRQ
.section .vectors, "aw", @progbits
.align 6
.globl __Vectors
.type __Vectors, @object
__Vectors:
.long Default_Handler
.long Default_Handler
.long Default_Handler
.long tspend_handler
.long Default_Handler
.long Default_Handler
.long Default_Handler
.long Default_IRQHandler
.long Default_Handler
.long Default_Handler
.long Default_Handler
.long Default_Handler
.long Default_Handler
.long Default_Handler
.long Default_Handler
.long Default_Handler
/* External interrupts */
.long Default_IRQHandler
#if CONFIG_IRQ_LATENCY
.long IRQ_LATENCY_IRQHandler
#else
.long Default_IRQHandler
#endif
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
#else
.section .vectors, "aw", @progbits
.align 6
.globl __Vectors
.type __Vectors, @object
__Vectors:
.long do_irq
.long do_irq
.long do_irq
.long tspend_handler
.long do_irq
.long do_irq
.long do_irq
.long do_irq
.long do_irq
.long do_irq
.long do_irq
.long do_irq
.long do_irq
.long do_irq
.long do_irq
/* External interrupts */
.long do_irq
.long do_irq
.long do_irq
.long do_irq
.long do_irq
.long do_irq
.long do_irq
.long do_irq
.long do_irq
.long do_irq
.long do_irq
.long do_irq
.long do_irq
.long do_irq
.long do_irq
.long do_irq
.long do_irq
.long do_irq
.long do_irq
.long do_irq
.long do_irq
.long do_irq
.long do_irq
.long do_irq
.long do_irq
.long do_irq
.long do_irq
.long do_irq
.long do_irq
.long do_irq
.long do_irq
.long do_irq
#endif
.text
.align 2
j Reset_Handler
.align 2
.long 0x594B5343 /* CSKY ASCII */
.long 0x594B5343 /* CSKY ASCII */
.align 2
_start:
.text
.globl Reset_Handler
.align 2
.type Reset_Handler, %function
Reset_Handler:
.option push
.option norelax
la gp, __global_pointer$
la a0, __jvt_base$
csrw jvt, a0
.option pop
la a0, Default_Handler
ori a0, a0, 3
csrw mtvec, a0
la a0, __Vectors
csrw mtvt, a0
la sp, g_top_irqstack
csrw mscratch, sp
#ifdef CONFIG_KERNEL_NONE
la sp, g_top_mainstack
#endif
#ifndef __NO_SYSTEM_INIT
jal SystemInit
#endif
jal rtthread_startup
.size Reset_Handler, . - Reset_Handler
__exit:
j __exit
.section .stack, "aw", @nobits
.align 3
.global g_base_irqstack
.global g_top_irqstack
g_base_irqstack:
.space CONFIG_ARCH_INTERRUPTSTACK
g_top_irqstack:
__rt_rvstack:
#ifdef CONFIG_KERNEL_NONE
.align 3
.global g_base_mainstack
.global g_top_mainstack
g_base_mainstack:
.space CONFIG_ARCH_MAINSTACK
g_top_mainstack:
#endif
.section .data
.weak __jvt_base$
.long 0

View File

@@ -1,105 +0,0 @@
/*
* Copyright (C) 2017-2024 Alibaba Group Holding Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <csi_config.h>
#include <soc.h>
#include <csi_core.h>
#include <drv/irq.h>
#include <drv/dma.h>
#include <drv/tick.h>
#include <drv/etb.h>
#include <drv/spiflash.h>
#include "riscv_csr.h"
#if (defined(CONFIG_KERNEL_RHINO) || defined(CONFIG_KERNEL_FREERTOS) || defined(CONFIG_KERNEL_RTTHREAD)) && defined(CONFIG_KERNEL_NONE)
#error "Please check the current system is baremetal or not!!!"
#endif
extern void section_data_copy(void);
extern void section_ram_code_copy(void);
extern void section_bss_clear(void);
static void cache_init(void)
{
csi_icache_enable();
}
static void section_init(void)
{
#if CONFIG_XIP
section_data_copy();
section_ram_code_copy();
#endif
section_bss_clear();
}
static void clic_init(void)
{
int i;
/* get interrupt level from info */
CLIC->CLICCFG = (((CLIC->CLICINFO & CLIC_INFO_CLICINTCTLBITS_Msk) >> CLIC_INFO_CLICINTCTLBITS_Pos) << CLIC_CLICCFG_NLBIT_Pos);
for (i = 0; i < 64; i++)
{
CLIC->CLICINT[i].IP = 0;
#ifndef CONFIG_SUPPORT_NON_VECTOR_IRQ
CLIC->CLICINT[i].ATTR = 1; /* use vector interrupt */
#else
CLIC->CLICINT[i].ATTR = 0; /* use non-vector interrupt */
#endif
csi_vic_set_prio(i, 3);
}
/* tspend use vector&positive interrupt */
CLIC->CLICINT[Machine_Software_IRQn].ATTR = 0x3;
csi_vic_set_prio(Machine_Software_IRQn, 1);
csi_irq_enable(Machine_Software_IRQn);
}
static void interrupt_init(void)
{
clic_init();
#ifdef CONFIG_KERNEL_NONE
__enable_excp_irq();
#endif
}
/**
* @brief initialize the system
* Initialize the psr and vbr.
* @param None
* @return None
*/
void SystemInit(void)
{
extern int cpu_features_init(void);
cpu_features_init();
/* enable XUANTIEISAEE & COPINSTEE */
uint32_t status = __get_MXSTATUS();
status |= (1 << 22) | (1 << 24);
__set_MXSTATUS(status);
cache_init();
section_init();
interrupt_init();
soc_set_sys_freq(20000000);
csi_tick_init();
}

View File

@@ -1,67 +0,0 @@
/*
* Copyright (C) 2017-2024 Alibaba Group Holding Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <csi_core.h>
#if defined(AOS_COMP_DEBUG) && (AOS_COMP_DEBUG > 0)
#include <debug/dbg.h>
#else
#define printk printf
#endif
void (*trap_c_callback)(void);
void trap_c(uintptr_t *regs)
{
int i;
unsigned long vec = 0;
vec = __get_MCAUSE();
printk("CPU Exception(mcause);: NO.0x%lx", vec);
printk("\n");
for (i = 0; i < 15; i++)
{
printk("x%d: %p\t", i + 1, (void *)regs[i]);
if ((i % 4) == 3)
{
printk("\n");
}
}
printk("\n");
printk("mepc : %p\n", (void *)regs[15]);
printk("mstatus: %p\n", (void *)regs[16]);
if (trap_c_callback)
{
trap_c_callback();
}
while (1);
}
__attribute__((weak)) void exceptionHandler(void *context)
{
trap_c((uintptr_t *)context);
}

View File

@@ -1,496 +0,0 @@
/*
* Copyright (C) 2017-2024 Alibaba Group Holding Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "riscv_asm_macro.h"
#define RISCV_MCAUSE_IRQ_POS 31
#define MSTATUS_IEN 8
.section .stack, "aw", @nobits
.align 2
.global g_trapstackbase
.global g_top_trapstack
g_trapstackbase:
.space CONFIG_ARCH_INTERRUPTSTACK
g_top_trapstack:
#if CONFIG_SUPPORT_IRQ_NESTED
#define IRQ_NESTED_MAX (6)
.section .bss
.align 2
irq_nested_level:
.long 0
irq_nested_mcause:
.long 0, 0, 0, 0, 0, 0
#endif
/* for interrupt tail-chaining debug */
#if CONFIG_DEBUG_TAIL_CHAINING
.global g_irq_tailchain_loops
g_irq_tailchain_loops:
.long 0
#endif
.text
#if !CONFIG_SUPPORT_IRQ_NESTED
.align 2
.weak Default_IRQHandler
.type Default_IRQHandler, %function
Default_IRQHandler:
#if CONFIG_PROFILING_PERF && CONFIG_PERF_BACKTRACE_USE_FP
addi sp, sp, -4
sw s0, (sp)
#endif
csrw mscratch, sp
la sp, g_top_irqstack
addi sp, sp, -52
sw t0, 4(sp)
sw t1, 8(sp)
sw t2, 12(sp)
csrr t0, mepc
csrr t1, mcause
csrr t2, mstatus
sw t1, 40(sp)
sw t0, 44(sp)
sw t2, 48(sp)
sw ra, 0(sp)
sw a0, 16(sp)
sw a1, 20(sp)
sw a2, 24(sp)
sw a3, 28(sp)
sw a4, 32(sp)
sw a5, 36(sp)
la t0, do_irq
jalr t0
lw a1, 40(sp)
andi a0, a1, 0x3FF
slli a0, a0, 2
/* clear pending */
li a2, 0xE0801000
add a2, a2, a0
lb a3, 0(a2)
li a4, 1
not a4, a4
and a5, a4, a3
sb a5, 0(a2)
csrw mcause, a1
lw t0, 44(sp)
lw t1, 48(sp)
csrw mepc, t0
csrw mstatus, t1
lw ra, 0(sp)
lw t0, 4(sp)
lw t1, 8(sp)
lw t2, 12(sp)
lw a0, 16(sp)
lw a1, 20(sp)
lw a2, 24(sp)
lw a3, 28(sp)
lw a4, 32(sp)
lw a5, 36(sp)
addi sp, sp, 52
csrr sp, mscratch
#if CONFIG_PROFILING_PERF && CONFIG_PERF_BACKTRACE_USE_FP
addi sp, sp, 4
#endif
mret
#else
.align 2
.weak Default_IRQHandler
.type Default_IRQHandler, %function
Default_IRQHandler:
addi sp, sp, -8
sw t0, 0(sp)
sw t1, 4(sp)
la t0, irq_nested_level
lw t1, (t0)
addi t1, t1, 1
sw t1, (t0)
li t0, IRQ_NESTED_MAX
/* nested too deeply, may be error happens */
bgt t1, t0, Default_Handler
addi t1, t1, -1
la t0, irq_nested_mcause
slli t1, t1, 2
add t0, t0, t1
csrr t1, mcause
sw t1, (t0)
la t0, irq_nested_level
lw t1, (t0)
li t0, 1
bgt t1, t0, .Lnested1
#if CONFIG_PROFILING_PERF && CONFIG_PERF_BACKTRACE_USE_FP
addi sp, sp, -8
sw s0, (sp)
csrr t0, mepc
sw t0, 4(sp)
#endif
csrw mscratch, sp
la sp, g_top_irqstack
j .Lnested2
.Lnested1:
lw t0, 0(sp)
lw t1, 4(sp)
addi sp, sp, 8
.Lnested2:
addi sp, sp, -52
sw t0, 4(sp)
sw t1, 8(sp)
sw t2, 12(sp)
csrr t0, mepc
csrr t1, mcause
csrr t2, mstatus
sw t1, 40(sp)
sw t0, 44(sp)
sw t2, 48(sp)
csrs mstatus, 8
sw ra, 0(sp)
sw a0, 16(sp)
sw a1, 20(sp)
sw a2, 24(sp)
sw a3, 28(sp)
sw a4, 32(sp)
sw a5, 36(sp)
la t0, do_irq
jalr t0
csrc mstatus, 8
lw a1, 40(sp)
andi a0, a1, 0x3FF
slli a0, a0, 2
/* clear pending */
li a2, 0xE0801000
add a2, a2, a0
lb a3, 0(a2)
li a4, 1
not a4, a4
and a5, a4, a3
sb a5, 0(a2)
la t0, irq_nested_level
lw t1, (t0)
addi t1, t1, -1
sw t1, (t0)
bgt t1, zero, .Lnested3
csrw mcause, a1
lw t0, 44(sp)
lw t1, 48(sp)
csrw mepc, t0
csrw mstatus, t1
lw ra, 0(sp)
lw t0, 4(sp)
lw t1, 8(sp)
lw t2, 12(sp)
lw a0, 16(sp)
lw a1, 20(sp)
lw a2, 24(sp)
lw a3, 28(sp)
lw a4, 32(sp)
lw a5, 36(sp)
addi sp, sp, 52
csrr sp, mscratch
#if CONFIG_PROFILING_PERF && CONFIG_PERF_BACKTRACE_USE_FP
addi sp, sp, 8
#endif
lw t0, 0(sp)
lw t1, 4(sp)
addi sp, sp, 8
mret
.Lnested3:
/* keep mpil in current mcause & load exception code before */
addi t1, t1, -1
la t0, irq_nested_mcause
slli t1, t1, 2
add t1, t0, t1
lw t0, (t1)
andi t0, t0, 0x3FF
andi a0, a1, 0xFFFFFC00
or t0, a0, t0
csrw mcause, t0
lw t0, 44(sp)
lw t1, 48(sp)
csrw mepc, t0
csrw mstatus, t1
lw ra, 0(sp)
lw t0, 4(sp)
lw t1, 8(sp)
lw t2, 12(sp)
lw a0, 16(sp)
lw a1, 20(sp)
lw a2, 24(sp)
lw a3, 28(sp)
lw a4, 32(sp)
lw a5, 36(sp)
addi sp, sp, 52
mret
#endif
.size Default_IRQHandler, . - Default_IRQHandler
/******************************************************************************
* Functions:
* void trap(void);
* default exception handler
******************************************************************************/
.align 2
.global trap
.type trap, %function
trap:
csrw mscratch, sp
la sp, g_top_trapstack
addi sp, sp, -76
sw x1, (0 )(sp)
sw x3, (8 )(sp)
sw x4, (12)(sp)
sw x5, (16)(sp)
sw x6, (20)(sp)
sw x7, (24)(sp)
sw x8, (28)(sp)
sw x9, (32)(sp)
sw x10,(36)(sp)
sw x11,(40)(sp)
sw x12,(44)(sp)
sw x13,(48)(sp)
sw x14,(52)(sp)
sw x15,(56)(sp)
csrr a0, mepc
sw a0, (60)(sp)
csrr a0, mstatus
sw a0, (64)(sp)
csrr a0, mcause
sw a0, (68)(sp)
csrr a0, mtval
sw a0, (72)(sp)
csrr a0, mscratch
sw a0, (4 )(sp)
mv a0, sp
la a1, exceptionHandler
jalr a1
.size trap, . - trap
.align 6
.weak Default_Handler
.type Default_Handler, %function
Default_Handler:
/* Check for nmi */
addi sp, sp, -8
sw t0, 0x0(sp)
sw t1, 0x4(sp)
csrr t0, mcause
#if (CONFIG_SUPPORT_NON_VECTOR_IRQ) && (!CONFIG_SUPPORT_IRQ_NESTED)
srli t1, t0, RISCV_MCAUSE_IRQ_POS
bnez t1, is_interrupt
#endif
andi t0, t0, 0x3FF
li t1, 24
beq t0, t1, .NMI_Handler
lw t0, 0x0(sp)
lw t1, 0x4(sp)
addi sp, sp, 8
j trap
#if (CONFIG_SUPPORT_NON_VECTOR_IRQ) && (!CONFIG_SUPPORT_IRQ_NESTED)
is_interrupt:
lw t0, 0x0(sp)
lw t1, 0x4(sp)
addi sp, sp, 8
csrw mscratch, sp
la sp, g_top_irqstack
addi sp, sp, -52
sw t0, 4(sp)
sw t1, 8(sp)
sw t2, 12(sp)
csrr t0, mepc
csrr t1, mcause
csrr t2, mstatus
sw t1, 40(sp)
sw t0, 44(sp)
sw t2, 48(sp)
sw ra, 0(sp)
sw a0, 16(sp)
sw a1, 20(sp)
sw a2, 24(sp)
sw a3, 28(sp)
sw a4, 32(sp)
sw a5, 36(sp)
#if CONFIG_DEBUG_TAIL_CHAINING
li t2, 0
la t1, g_irq_tailchain_loops
sw t2, 0(t1)
#endif
csrrsi t0, mnxti, MSTATUS_IEN
beqz t0, irq_done
irq_loop:
#if CONFIG_DEBUG_TAIL_CHAINING
la t2, g_irq_tailchain_loops
lw t1, 0(t2)
addi t1, t1, 1
sw t1, 0(t2)
#endif
lw t1, 0(t0)
jalr t1
csrrsi t0, mnxti, MSTATUS_IEN
bnez t0, irq_loop
#if CONFIG_DEBUG_TAIL_CHAINING
li t2, 0
la a1, g_irq_tailchain_loops
sw t2, 0(a1)
#endif
irq_done:
lw t0, 40(sp)
lw t1, 44(sp)
lw t2, 48(sp)
csrw mcause, t0
csrw mepc, t1
csrw mstatus, t2
lw ra, 0(sp)
lw t0, 4(sp)
lw t1, 8(sp)
lw t2, 12(sp)
lw a0, 16(sp)
lw a1, 20(sp)
lw a2, 24(sp)
lw a3, 28(sp)
lw a4, 32(sp)
lw a5, 36(sp)
addi sp, sp, 52
csrr sp, mscratch
mret
#endif /* (CONFIG_SUPPORT_NON_VECTOR_IRQ) && (!CONFIG_SUPPORT_IRQ_NESTED) */
.NMI_Handler:
/* mscratch may be used before */
addi sp, sp, -4
csrr t0, mscratch
sw t0, 0x0(sp)
csrw mscratch, sp
la sp, g_top_trapstack
addi sp, sp, -52
sw t0, 4(sp)
sw t1, 8(sp)
sw t2, 12(sp)
csrr t0, mepc
csrr t1, mcause
csrr t2, mstatus
sw t1, 40(sp)
sw t0, 44(sp)
sw t2, 48(sp)
sw ra, 0(sp)
sw a0, 16(sp)
sw a1, 20(sp)
sw a2, 24(sp)
sw a3, 28(sp)
sw a4, 32(sp)
sw a5, 36(sp)
la t0, handle_nmi_exception
jalr t0
lw a1, 40(sp)
andi a0, a1, 0x3FF
slli a0, a0, 2
/* clear pending */
li a2, 0xE0801000
add a2, a2, a0
lb a3, 0(a2)
li a4, 1
not a4, a4
and a5, a4, a3
sb a5, 0(a2)
csrw mcause, a1
lw t0, 44(sp)
lw t1, 48(sp)
csrw mepc, t0
csrw mstatus, t1
lw ra, 0(sp)
lw t0, 4(sp)
lw t1, 8(sp)
lw t2, 12(sp)
lw a0, 16(sp)
lw a1, 20(sp)
lw a2, 24(sp)
lw a3, 28(sp)
lw a4, 32(sp)
lw a5, 36(sp)
addi sp, sp, 52
csrr sp, mscratch
/* restore mscratch */
lw t0, 0x0(sp)
csrw mscratch, t0
addi sp, sp, 4
lw t0, 0x0(sp)
lw t1, 0x4(sp)
addi sp, sp, 8
mret
.size Default_Handler, . - Default_Handler
/* Macro to define default handlers. Default handler
* will be weak symbol and just dead loops. They can be
* overwritten by other handlers */
.macro def_irq_handler handler_name
.weak \handler_name
.set \handler_name, Default_Handler
.endm
def_irq_handler tspend_handler

View File

@@ -9,7 +9,6 @@ src += ['sys_clk.c']
src += ['tick.c']
src += ['target_get.c']
src += ['devices.c']
src += ['feature.c']
group = DefineGroup('sys', src, depend = [''], CPPPATH = CPPPATH)

View File

@@ -1,319 +0,0 @@
/*
* Copyright (C) 2017-2024 Alibaba Group Holding Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <csi_core.h>
/* I/D Cache will enable in cache_init */
void cpu_features_init(void)
{
#if CONFIG_CPU_XUANTIE_E901PLUS_CP || CONFIG_CPU_XUANTIE_E901PLUS_B_CP || CONFIG_CPU_XUANTIE_E901PLUS_M_CP || CONFIG_CPU_XUANTIE_E901PLUS_BM_CP
return;
#endif
#if CONFIG_CPU_XUANTIE_E901_CP || CONFIG_CPU_XUANTIE_E901_B_CP || CONFIG_CPU_XUANTIE_E901_ZM_CP || CONFIG_CPU_XUANTIE_E901_BZM_CP
return;
#endif
#if CONFIG_CPU_XUANTIE_E902 || CONFIG_CPU_XUANTIE_E902M || CONFIG_CPU_XUANTIE_E902T || CONFIG_CPU_XUANTIE_E902MT
return;
#endif
#if CONFIG_CPU_XUANTIE_E906 || CONFIG_CPU_XUANTIE_E906F || CONFIG_CPU_XUANTIE_E906FD || CONFIG_CPU_XUANTIE_E906P || CONFIG_CPU_XUANTIE_E906FP || CONFIG_CPU_XUANTIE_E906FDP
rv_csr_write(CSR_MXSTATUS, 0x440800);
rv_csr_write(CSR_MHCR, 0x103f & (~0x3));
return;
#endif
#if CONFIG_CPU_XUANTIE_E907 || CONFIG_CPU_XUANTIE_E907F || CONFIG_CPU_XUANTIE_E907FD || CONFIG_CPU_XUANTIE_E907P || CONFIG_CPU_XUANTIE_E907FP || CONFIG_CPU_XUANTIE_E907FDP
rv_csr_write(CSR_MXSTATUS, 0x440800);
rv_csr_write(CSR_MHINT, 0x600c);
rv_csr_write(CSR_MHCR, 0x103f & (~0x3));
return;
#endif
volatile unsigned int i, cpu_type, cpu_ver, cpu_tnmodel;
unsigned long version[8];
/* As CPUID is a fifo register, try to find
* the CPUID[0] whose index(bit[31:28]) == 0 */
for (i = 0; i < 8; i++)
{
version[0] = rv_csr_read(CSR_MCPUID);
if (((version[0]&0xf0000000) >> 28) == 0)
break;
}
for (i = 1; i < 8; i++)
version[i] = rv_csr_read(CSR_MCPUID);
cpu_type = (version[0] >> 18) & 0xf;
cpu_tnmodel = (version[0] >> 14) & 0x1;
cpu_ver = (version[1] >> 12) & 0xffff;
rv_csr_write(CSR_MCOR, 0x70013);
/*
* Warning: CSR_MCCR2 contains an L2 cache latency setting,
* you need to confirm it by your own soc design.
*/
switch (cpu_type)
{
case 0x1:
if (cpu_ver >= 0x0)
{
rv_csr_write(CSR_MSMPR, 0x1);
rv_csr_write(CSR_MCCR2, 0xe249000b);
rv_csr_write(CSR_MXSTATUS, 0x638000);
rv_csr_write(CSR_MHINT, 0x1ee30c);
rv_csr_write(CSR_MHCR, 0x11ff & (~0x3));
rv_csr_write(CSR_MHINT2,0x180);
} else {
while(1);
}
break;
case 0x2:
if (cpu_ver >= 0x0)
{
rv_csr_write(CSR_MSMPR, 0x1);
rv_csr_write(CSR_MCCR2, 0xa042000a);
rv_csr_write(CSR_MXSTATUS, 0x438100);
rv_csr_write(CSR_MHINT, 0x21aa10c);
rv_csr_write(CSR_MHCR, 0x10011ff & (~0x3));
rv_csr_write(CSR_MHINT4, 0x10000080);
#if __riscv_xlen == 64
rv_csr_write(CSR_MENVCFG, 0x4000000000000000);
#endif
} else {
while(1);
}
break;
case 0x3:
if (cpu_ver >= 0x1080 && cpu_ver <= 0x10bf)
{ /* 1.2.0~1.2.x */
rv_csr_write(CSR_MCCR2, 0xe0010009);
rv_csr_write(CSR_MXSTATUS, 0x638000);
rv_csr_write(CSR_MHINT, 0x6e30c);
rv_csr_write(CSR_MHCR, 0x1ff & (~0x3));
} else if (cpu_ver == 0x10ca)
{ /* 1.3.10 */
rv_csr_write(CSR_MSMPR, 0x1);
rv_csr_write(CSR_MCCR2, 0xe2490009);
rv_csr_write(CSR_MXSTATUS, 0x638000);
rv_csr_write(CSR_MHINT, 0x66e30c);
rv_csr_write(CSR_MHCR, 0x17f & (~0x3));
rv_csr_write(CSR_MHINT2, 0x420000);
rv_csr_write(CSR_MHINT4, 0x410);
} else if (cpu_ver >= 0x1100 && cpu_ver <= 0x113f)
{ /* 1.4.0~1.4.x */
rv_csr_write(CSR_MSMPR, 0x1);
rv_csr_write(CSR_MCCR2, 0xe2490009);
rv_csr_write(CSR_MXSTATUS, 0x638000);
rv_csr_write(CSR_MHINT, 0x16e30c);
rv_csr_write(CSR_MHCR, 0x1ff & (~0x3));
} else if (cpu_ver >= 0x1140 && cpu_ver <= 0x117f)
{ /* 1.5.0~1.5.x */
rv_csr_write(CSR_MSMPR, 0x1);
rv_csr_write(CSR_MCCR2, 0xe2490009);
rv_csr_write(CSR_MXSTATUS, 0x638000);
rv_csr_write(CSR_MHINT, 0xe6e30c);
rv_csr_write(CSR_MHINT2, 0x180);
rv_csr_write(CSR_MHCR, 0x1ff & (~0x3));
} else if (cpu_ver >= 0x1180 && cpu_ver <= 0x1183)
{ /* 1.6.0~1.6.3 */
rv_csr_write(CSR_MSMPR, 0x1);
rv_csr_write(CSR_MCCR2, 0xe249000b);
rv_csr_write(CSR_MXSTATUS, 0x638000);
rv_csr_write(CSR_MHINT, 0x1ee30c);
rv_csr_write(CSR_MHINT2, 0x180);
rv_csr_write(CSR_MHCR, 0x1ff & (~0x3));
} else if (cpu_ver >= 0x1184 && cpu_ver <= 0x123f)
{ /* 1.6.4~1.8.x */
rv_csr_write(CSR_MSMPR, 0x1);
rv_csr_write(CSR_MCCR2, 0xe249000b);
rv_csr_write(CSR_MXSTATUS, 0x638000);
rv_csr_write(CSR_MHINT, 0x1ee30c);
rv_csr_write(CSR_MHINT2, 0x180);
rv_csr_write(CSR_MHCR, 0x11ff & (~0x3));
} else if (cpu_ver >= 0x2000 && cpu_ver <= 0x200e)
{ /* 2.0.0~2.0.14 */
rv_csr_write(CSR_MSMPR, 0x1);
rv_csr_write(CSR_MCCR2, 0xe249000b);
rv_csr_write(CSR_MXSTATUS, 0x438000);
rv_csr_write(CSR_MHINT, 0x31ea32c);
rv_csr_write(CSR_MHINT2, 0x180);
rv_csr_write(CSR_MHCR, 0x11ff & (~0x3));
#if __riscv_xlen == 64
rv_csr_write(CSR_MENVCFG, 0x4000000000000000);
#endif
} else if (cpu_ver >= 0x200f && cpu_ver <= 0x2045)
{ /* 2.0.15~2.1.5 */
rv_csr_write(CSR_MSMPR, 0x1);
rv_csr_write(CSR_MCCR2, 0xe249000b);
rv_csr_write(CSR_MXSTATUS, 0x438000);
rv_csr_write(CSR_MHINT, 0x11ea32c);
rv_csr_write(CSR_MHINT2, 0x180);
rv_csr_write(CSR_MHCR, 0x11ff & (~0x3));
#if __riscv_xlen == 64
rv_csr_write(CSR_MENVCFG, 0x4000000000000000);
#endif
} else if (cpu_ver >= 0x2046 && cpu_ver <= 0x20c3)
{ /* 2.1.6~2.3.3 */
rv_csr_write(CSR_MSMPR, 0x1);
rv_csr_write(CSR_MCCR2, 0xe249000b);
rv_csr_write(CSR_MXSTATUS, 0x438000);
rv_csr_write(CSR_MHINT, 0x31ea32c);
rv_csr_write(CSR_MHINT2, 0x180);
rv_csr_write(CSR_MHCR, 0x11ff & (~0x3));
#if __riscv_xlen == 64
rv_csr_write(CSR_MENVCFG, 0x4000000000000000);
#endif
} else if (cpu_ver >= 0x20c4 && cpu_ver <= 0x2fff)
{ /* 2.3.4~2.x.x */
rv_csr_write(CSR_MSMPR, 0x1);
rv_csr_write(CSR_MCCR2, 0xe249000b);
rv_csr_write(CSR_MXSTATUS, 0x438100);
rv_csr_write(CSR_MHINT, 0x31ea32c);
rv_csr_write(CSR_MHINT2, 0x180);
rv_csr_write(CSR_MHCR, 0x11ff & (~0x3));
rv_csr_write(CSR_MHINT4, 0x2080);
#if __riscv_xlen == 64
rv_csr_write(CSR_MENVCFG, 0x4000000000000000);
#endif
} else if (cpu_ver >= 0x3000 && cpu_ver <= 0x3fff)
{ /* 3.0.0~3.x.x */
rv_csr_write(CSR_MSMPR, 0x1);
rv_csr_write(CSR_MCCR2, 0xe249000b);
rv_csr_write(CSR_MXSTATUS, 0x438100);
rv_csr_write(CSR_MHINT, 0x31ea32c);
rv_csr_write(CSR_MHINT2, 0x180);
rv_csr_write(CSR_MHCR, 0x11ff & (~0x3));
rv_csr_write(CSR_MHINT4, 0x2080);
#if __riscv_xlen == 64
rv_csr_write(CSR_MENVCFG, 0x4000000000000000);
#endif
} else {
while(1);
}
break;
case 0x4:
if (cpu_ver >= 0x1002 && cpu_ver <= 0xffff)
{
rv_csr_write(CSR_MHCR, 0x17f & (~0x3));
rv_csr_write(CSR_MXSTATUS, 0x638000);
rv_csr_write(CSR_MHINT, 0x650c);
} else {
while(1);
}
break;
case 0x5:
if(cpu_tnmodel == 0)
{ /* c908 */
if (cpu_ver >= 0x0000 && cpu_ver <= 0x0007)
{ /* 0.0.0~0.0.7 */
rv_csr_write(CSR_MSMPR, 0x1);
rv_csr_write(CSR_MCCR2, 0xe0420008);
rv_csr_write(CSR_MXSTATUS, 0x638000);
rv_csr_write(CSR_MHINT, 0x2c50c);
rv_csr_write(CSR_MHCR, 0x11ff & (~0x3));
} else if (cpu_ver >= 0x0040 && cpu_ver <= 0x1002)
{ /* 0.1.0~1.0.2 */
rv_csr_write(CSR_MSMPR, 0x1);
rv_csr_write(CSR_MCCR2, 0xa042000a);
rv_csr_write(CSR_MXSTATUS, 0x438000);
rv_csr_write(CSR_MHINT, 0x21aa10c);
rv_csr_write(CSR_MHCR, 0x10011ff & (~0x3));
#if __riscv_xlen == 64
rv_csr_write(CSR_MENVCFG, 0x4000000000000000);
#endif
} else if (cpu_ver >= 0x1003 && cpu_ver <= 0x100b)
{ /* 1.0.3~1.0.11 */
rv_csr_write(CSR_MSMPR, 0x1);
rv_csr_write(CSR_MCCR2, 0xa042000a);
rv_csr_write(CSR_MXSTATUS, 0x438000);
rv_csr_write(CSR_MHINT, 0x1aa10c);
rv_csr_write(CSR_MHCR, 0x10011ff & (~0x3));
#if __riscv_xlen == 64
rv_csr_write(CSR_MENVCFG, 0x4000000000000000);
#endif
} else if (cpu_ver >= 0x100c && cpu_ver <= 0x1fff)
{ /* 1.0.12~ */
rv_csr_write(CSR_MSMPR, 0x1);
rv_csr_write(CSR_MCCR2, 0xa042000a);
rv_csr_write(CSR_MXSTATUS, 0x438100);
rv_csr_write(CSR_MHINT, 0x21aa10c);
rv_csr_write(CSR_MHCR, 0x10011ff & (~0x3));
rv_csr_write(CSR_MHINT4, 0x10000080);
#if __riscv_xlen == 64
rv_csr_write(CSR_MENVCFG, 0x4000000000000000);
#endif
} else if (cpu_ver >= 0x2000 && cpu_ver <= 0xffff)
{ /* 2.0.0~ */
rv_csr_write(CSR_MSMPR, 0x1);
rv_csr_write(CSR_MCCR2, 0xa042000a);
rv_csr_write(CSR_MXSTATUS, 0x438100);
rv_csr_write(CSR_MHINT, 0x21aa10c);
rv_csr_write(CSR_MHCR, 0x10011ff & (~0x3));
rv_csr_write(CSR_MHINT4, 0x10000080);
#if __riscv_xlen == 64
rv_csr_write(CSR_MENVCFG, 0x4000000000000000);
#endif
} else {
while(1);
}
} else if (cpu_tnmodel == 1)
{
if (cpu_ver >= 0x0)
{
rv_csr_write(CSR_MSMPR, 0x1);
rv_csr_write(CSR_MCCR2, 0xA0420002);
rv_csr_write(CSR_MXSTATUS, 0x438100);
rv_csr_write(CSR_MHINT, 0x21AA10C);
rv_csr_write(CSR_MHCR, 0x10011FF & (~0x3));
rv_csr_write(CSR_MHINT4, 0x10000080);
#if __riscv_xlen == 64
rv_csr_write(CSR_MENVCFG, 0x4000000000000000);
#endif
} else {
while(1);
}
} else {
while(1);
}
break;
case 0x6:
if (cpu_ver >= 0x0)
{
rv_csr_write(CSR_MSMPR, 0x1);
rv_csr_write(CSR_MCCR2, 0xA0420002);
rv_csr_write(CSR_MXSTATUS, 0x438000);
rv_csr_write(CSR_MHINT, 0x3A1AA10C);
rv_csr_write(CSR_MHCR, 0x10011BF & (~0x3));
#if __riscv_xlen == 64
rv_csr_write(CSR_MENVCFG, 0x4000000000000000);
#endif
} else {
while(1);
}
break;
default:
/* FIXME: maybe qemu */
break;
}
}

View File

@@ -295,13 +295,7 @@ typedef struct {
#define CACHE_MHCR_IE_Pos 0U /*!< CACHE MHCR: IE Position */
#define CACHE_MHCR_IE_Msk (0x1UL << CACHE_MHCR_IE_Pos) /*!< CACHE MHCR: IE Mask */
#if CONFIG_CPU_XUANTIE_E902 || CONFIG_CPU_XUANTIE_E902M || CONFIG_CPU_XUANTIE_E902T || CONFIG_CPU_XUANTIE_E902MT \
|| CONFIG_CPU_XUANTIE_E901PLUS_CP || CONFIG_CPU_XUANTIE_E901PLUS_B_CP || CONFIG_CPU_XUANTIE_E901PLUS_M_CP || CONFIG_CPU_XUANTIE_E901PLUS_BM_CP \
|| CONFIG_CPU_XUANTIE_E901_CP || CONFIG_CPU_XUANTIE_E901_B_CP || CONFIG_CPU_XUANTIE_E901_ZM_CP || CONFIG_CPU_XUANTIE_E901_BZM_CP
#define CACHE_INV_ADDR_Pos 4U
#else
#define CACHE_INV_ADDR_Pos 5U
#endif
#define CACHE_INV_ADDR_Msk (0xFFFFFFFFUL << CACHE_INV_ADDR_Pos)
/*@} end of group CSI_CACHE */
@@ -439,12 +433,8 @@ typedef struct {
*/
/* Memory mapping of THEAD CPU */
#ifndef CONFIG_TCIP_BASE
#define CONFIG_TCIP_BASE 0xE0000000UL
#endif
#define CORET_BASE (CONFIG_TCIP_BASE + 0x4000UL) /*!< CORET Base Address */
#define CLIC_BASE (CONFIG_TCIP_BASE + 0x800000UL) /*!< CLIC Base Address */
#define CORET_BASE (0xE0004000UL) /*!< CORET Base Address */
#define CLIC_BASE (0xE0800000UL) /*!< CLIC Base Address */
#define SYSMAP_BASE (0xEFFFF000UL) /*!< SYSMAP Base Address */
#define CORET ((CORET_Type *) CORET_BASE ) /*!< SysTick configuration struct */
@@ -481,12 +471,11 @@ __STATIC_INLINE int csi_get_cpu_id(void)
*/
__STATIC_INLINE int csi_get_cache_line_size(void)
{
#if CONFIG_CPU_XUANTIE_E902 || CONFIG_CPU_XUANTIE_E902M || CONFIG_CPU_XUANTIE_E902T || CONFIG_CPU_XUANTIE_E902MT \
|| CONFIG_CPU_XUANTIE_E901PLUS_CP || CONFIG_CPU_XUANTIE_E901PLUS_B_CP || CONFIG_CPU_XUANTIE_E901PLUS_M_CP || CONFIG_CPU_XUANTIE_E901PLUS_BM_CP \
|| CONFIG_CPU_XUANTIE_E901_CP || CONFIG_CPU_XUANTIE_E901_B_CP || CONFIG_CPU_XUANTIE_E901_ZM_CP || CONFIG_CPU_XUANTIE_E901_BZM_CP
return 16;
#if CONFIG_CPU_XUANTIE_E906 || CONFIG_CPU_XUANTIE_E906F || CONFIG_CPU_XUANTIE_E906FD || CONFIG_CPU_XUANTIE_E906P || CONFIG_CPU_XUANTIE_E906FP || CONFIG_CPU_XUANTIE_E906FDP \
|| CONFIG_CPU_XUANTIE_E907 || CONFIG_CPU_XUANTIE_E907F || CONFIG_CPU_XUANTIE_E907FD || CONFIG_CPU_XUANTIE_E907P || CONFIG_CPU_XUANTIE_E907FP || CONFIG_CPU_XUANTIE_E907FDP
return 8;
#else
return 32;
return 4;
#endif
}
@@ -557,7 +546,6 @@ __STATIC_INLINE uint32_t csi_vic_get_pending_irq(int32_t IRQn)
__STATIC_INLINE void csi_vic_set_pending_irq(int32_t IRQn)
{
CLIC->CLICINT[IRQn].IP |= CLIC_INTIP_IP_Msk;
__DSB();
}
/**
@@ -568,7 +556,6 @@ __STATIC_INLINE void csi_vic_set_pending_irq(int32_t IRQn)
__STATIC_INLINE void csi_vic_clear_pending_irq(int32_t IRQn)
{
CLIC->CLICINT[IRQn].IP &= ~CLIC_INTIP_IP_Msk;
__DSB();
}
/**
@@ -581,10 +568,7 @@ __STATIC_INLINE void csi_vic_clear_pending_irq(int32_t IRQn)
__STATIC_INLINE void csi_vic_set_prio(int32_t IRQn, uint32_t priority)
{
uint8_t nlbits = (CLIC->CLICINFO & CLIC_INFO_CLICINTCTLBITS_Msk) >> CLIC_INFO_CLICINTCTLBITS_Pos;
uint8_t ctl = CLIC->CLICINT[IRQn].CTL;
ctl <<= nlbits;
ctl >>= nlbits;
CLIC->CLICINT[IRQn].CTL = ctl | (priority << (8 - nlbits));
CLIC->CLICINT[IRQn].CTL = (CLIC->CLICINT[IRQn].CTL & (~CLIC_INTCFG_PRIO_Msk)) | (priority << (8 - nlbits));
__DSB();
}
@@ -630,7 +614,6 @@ __STATIC_INLINE uint32_t csi_vic_set_thresh(uint32_t thresh)
CLIC->MINTTHRESH = 0xff << 24;
CLIC->MINTTHRESH = thresh << 24;
__DSB();
return temp;
}
@@ -659,22 +642,18 @@ __STATIC_INLINE void csi_mpu_config_region(uint32_t idx, uint32_t base_addr, reg
uint8_t pmpxcfg = 0;
uint32_t addr = 0;
if (idx > 15)
{
if (idx > 15) {
return;
}
if (!enable)
{
if (!enable) {
attr.a = (address_matching_e)0;
}
if (attr.a == ADDRESS_MATCHING_TOR)
{
if (attr.a == ADDRESS_MATCHING_TOR) {
addr = base_addr >> 2;
} else {
if (size == REGION_SIZE_4B)
{
if (size == REGION_SIZE_4B) {
addr = base_addr >> 2;
attr.a = (address_matching_e)2;
} else {
@@ -714,8 +693,7 @@ __STATIC_INLINE void csi_mpu_disable_region(uint32_t idx)
__STATIC_INLINE uint32_t _csi_coret_config(unsigned long coret_base, uint32_t ticks, int32_t IRQn)
{
CORET_Type *coret = (CORET_Type *)coret_base;
if ((coret->MTIMECMP != 0) && (coret->MTIMECMP != 0xFFFFFFFFFFFFFFFFULL))
{
if ((coret->MTIMECMP != 0) && (coret->MTIMECMP != 0xffffffffffffffff)) {
coret->MTIMECMP = coret->MTIMECMP + ticks;
} else {
coret->MTIMECMP = coret->MTIME + ticks;
@@ -836,8 +814,7 @@ __ALWAYS_STATIC_INLINE void csi_coret_irq_disable(void)
*/
__STATIC_INLINE uint8_t __get_SYSMAPCFGx(uint32_t idx)
{
switch (idx)
{
switch (idx) {
case 0:
return SYSMAP->SYSMAPCFG0;
case 1:
@@ -867,8 +844,7 @@ __STATIC_INLINE uint8_t __get_SYSMAPCFGx(uint32_t idx)
*/
__STATIC_INLINE void __set_SYSMAPCFGx(uint32_t idx, uint32_t sysmapxcfg)
{
switch (idx)
{
switch (idx) {
case 0:
SYSMAP->SYSMAPCFG0 = sysmapxcfg;
break;
@@ -906,8 +882,7 @@ __STATIC_INLINE void __set_SYSMAPCFGx(uint32_t idx, uint32_t sysmapxcfg)
*/
__STATIC_INLINE uint32_t __get_SYSMAPADDRx(uint32_t idx)
{
switch(idx)
{
switch(idx) {
case 0:
return SYSMAP->SYSMAPADDR0;
case 1:
@@ -937,8 +912,7 @@ __STATIC_INLINE uint32_t __get_SYSMAPADDRx(uint32_t idx)
*/
__STATIC_INLINE void __set_SYSMAPADDRx(uint32_t idx, uint32_t sysmapxaddr)
{
switch (idx)
{
switch (idx) {
case 0:
SYSMAP->SYSMAPADDR0 = sysmapxaddr;
break;
@@ -979,8 +953,7 @@ __STATIC_INLINE void csi_sysmap_config_region(uint32_t idx, uint32_t base_addr,
{
uint32_t addr = 0;
if (idx > 7)
{
if (idx > 7) {
return;
}
@@ -1017,15 +990,16 @@ __STATIC_INLINE int csi_icache_is_enable()
__STATIC_INLINE void csi_icache_enable (void)
{
#if (__ICACHE_PRESENT == 1U)
if (!csi_icache_is_enable())
{
if (!csi_icache_is_enable()) {
uint32_t cache;
__DSB();
__ISB();
__ICACHE_IALL();
cache = __get_MHCR();
cache |= CACHE_MHCR_IE_Msk;
__set_MHCR(cache);
__DSB();
__ISB();
}
#endif
}
@@ -1038,15 +1012,16 @@ __STATIC_INLINE void csi_icache_enable (void)
__STATIC_INLINE void csi_icache_disable (void)
{
#if (__ICACHE_PRESENT == 1U)
if (csi_icache_is_enable())
{
if (csi_icache_is_enable()) {
uint32_t cache;
__DSB();
__ISB();
cache = __get_MHCR();
cache &= ~CACHE_MHCR_IE_Msk; /* disable icache */
__set_MHCR(cache);
__ICACHE_IALL(); /* invalidate all icache */
__DSB();
__ISB();
}
#endif
}
@@ -1060,8 +1035,10 @@ __STATIC_INLINE void csi_icache_invalid (void)
{
#if (__ICACHE_PRESENT == 1U)
__DSB();
__ISB();
__ICACHE_IALL(); /* invalidate all icache */
__DSB();
__ISB();
#endif
}
@@ -1081,16 +1058,17 @@ __STATIC_INLINE int csi_dcache_is_enable()
__STATIC_INLINE void csi_dcache_enable (void)
{
#if (__DCACHE_PRESENT == 1U)
if (!csi_dcache_is_enable())
{
if (!csi_dcache_is_enable()) {
uint32_t cache;
__DSB();
__ISB();
__DCACHE_IALL(); /* invalidate all dcache */
cache = __get_MHCR();
cache |= CACHE_MHCR_DE_Msk; /* enable dcache */
__set_MHCR(cache);
__DSB();
__ISB();
}
#endif
}
@@ -1103,15 +1081,16 @@ __STATIC_INLINE void csi_dcache_enable (void)
__STATIC_INLINE void csi_dcache_disable (void)
{
#if (__DCACHE_PRESENT == 1U)
if (csi_dcache_is_enable())
{
if (csi_dcache_is_enable()) {
uint32_t cache;
__DSB();
__ISB();
cache = __get_MHCR();
cache &= ~(uint32_t)CACHE_MHCR_DE_Msk; /* disable all Cache */
__set_MHCR(cache);
__DCACHE_IALL(); /* invalidate all Cache */
__DSB();
__ISB();
}
#endif
}
@@ -1125,8 +1104,10 @@ __STATIC_INLINE void csi_dcache_invalid (void)
{
#if (__DCACHE_PRESENT == 1U)
__DSB();
__ISB();
__DCACHE_IALL(); /* invalidate all Cache */
__DSB();
__ISB();
#endif
}
@@ -1139,8 +1120,10 @@ __STATIC_INLINE void csi_dcache_clean (void)
{
#if (__DCACHE_PRESENT == 1U)
__DSB();
__ISB();
__DCACHE_CALL(); /* clean all Cache */
__DSB();
__ISB();
#endif
}
@@ -1153,8 +1136,10 @@ __STATIC_INLINE void csi_dcache_clean_invalid (void)
{
#if (__DCACHE_PRESENT == 1U)
__DSB();
__ISB();
__DCACHE_CIALL(); /* clean and inv all Cache */
__DSB();
__ISB();
#endif
}
@@ -1170,12 +1155,11 @@ __STATIC_INLINE void csi_dcache_invalid_range (unsigned long *addr, size_t dsize
#if (__DCACHE_PRESENT == 1U)
int linesize = csi_get_cache_line_size();
long op_size = dsize + (unsigned long)addr % linesize;
unsigned long op_addr = (unsigned long)addr & CACHE_INV_ADDR_Msk;
unsigned long op_addr = (unsigned long)addr;
__DSB();
while (op_size > 0)
{
while (op_size > 0) {
__DCACHE_IPA(op_addr);
op_addr += linesize;
op_size -= linesize;
@@ -1202,8 +1186,7 @@ __STATIC_INLINE void csi_dcache_clean_range (unsigned long *addr, size_t dsize)
__DSB();
while (op_size > 0)
{
while (op_size > 0) {
__DCACHE_CPA(op_addr);
op_addr += linesize;
op_size -= linesize;
@@ -1226,12 +1209,11 @@ __STATIC_INLINE void csi_dcache_clean_invalid_range (unsigned long *addr, size_t
#if (__DCACHE_PRESENT == 1U)
int linesize = csi_get_cache_line_size();
long op_size = dsize + (unsigned long)addr % linesize;
unsigned long op_addr = (unsigned long) addr & CACHE_INV_ADDR_Msk;
unsigned long op_addr = (unsigned long) addr;
__DSB();
while (op_size > 0)
{
while (op_size > 0) {
__DCACHE_CIPA(op_addr);
op_addr += linesize;
op_size -= linesize;
@@ -1467,4 +1449,3 @@ __STATIC_INLINE void csi_irq_restore(uint32_t irq_state)
#endif /* __CORE_RV32_H_DEPENDANT */
#endif /* __CSI_GENERIC */

View File

@@ -219,7 +219,7 @@ typedef struct {
*/
typedef struct {
uint32_t RESERVED0;
uint32_t RESERVED0; /*!< Offset: 0x000 (R/W) CLINT configure register */
__IOM uint32_t PLIC_PRIO[1023];
__IOM uint32_t PLIC_IP[32];
uint32_t RESERVED1[3972 / 4 - 1];
@@ -403,9 +403,7 @@ typedef struct {
#define CACHE_MHCR_IE_Msk (0x1UL << CACHE_MHCR_IE_Pos) /*!< CACHE MHCR: IE Mask */
#if CONFIG_CPU_XUANTIE_R908 || CONFIG_CPU_XUANTIE_R908FD || CONFIG_CPU_XUANTIE_R908FDV \
|| CONFIG_CPU_XUANTIE_R908_CP || CONFIG_CPU_XUANTIE_R908FD_CP || CONFIG_CPU_XUANTIE_R908FDV_CP \
|| CONFIG_CPU_XUANTIE_R908_CP_XT || CONFIG_CPU_XUANTIE_R908FD_CP_XT || CONFIG_CPU_XUANTIE_R908FDV_CP_XT \
|| CONFIG_CPU_XUANTIE_C908X || CONFIG_CPU_XUANTIE_C908X_CP || CONFIG_CPU_XUANTIE_C908X_CP_XT
|| CONFIG_CPU_XUANTIE_R908_CP || CONFIG_CPU_XUANTIE_R908FD_CP || CONFIG_CPU_XUANTIE_R908FDV_CP
#define MCER_ECC_FATAL_Pos 34U
#define MCER_ECC_FATAL_Msk (0x1ULL << MCER_ECC_FATAL_Pos)
@@ -442,7 +440,7 @@ typedef struct {
#define CACHE_MCER2H_RAMID_Msk (0x3ULL << CACHE_MCER2H_RAMID_Pos)
#define CACHE_INV_ADDR_Pos 6U
#define CACHE_INV_ADDR_Msk (~((0x1ULL << CACHE_INV_ADDR_Pos) - 1))
#define CACHE_INV_ADDR_Msk (0xFFFFFFFFULL << CACHE_INV_ADDR_Pos)
enum MCER_FAULT_RAMID {
/* L1 Cache, JTLB and TCM (RAMID of MCER)*/
@@ -464,19 +462,19 @@ enum MCER2_FAULT_RAMID {
/*@} end of group CSI_CACHE */
/* MSTATUS Register */
#define MSTATUS_TVM_MASK (1L << 20) /* mstatus.TVM [20] */
#define MSTATUS_MPP_MASK (3L << 11) /* mstatus.SPP [11:12] */
// MSTATUS Register
#define MSTATUS_TVM_MASK (1L << 20) // mstatus.TVM [20]
#define MSTATUS_MPP_MASK (3L << 11) // mstatus.SPP [11:12]
#ifndef MSTATUS_MPP_M
#define MSTATUS_MPP_M (3L << 11) /* Machine mode 11 */
#define MSTATUS_MPP_M (3L << 11) // Machine mode 11
#endif
#define MSTATUS_MPP_S (1L << 11) /* Supervisor mode 01 */
#define MSTATUS_MPP_U (0L << 11) /* User mode 00 */
#define MSTATUS_MPP_S (1L << 11) // Supervisor mode 01
#define MSTATUS_MPP_U (0L << 11) // User mode 00
/* SSTATUS Register */
#define SSTATUS_SPP_MASK (3L << 8) /* sstatus.SPP [8:9] */
#define SSTATUS_SPP_S (1L << 8) /* Supervisor mode 01 */
#define SSTATUS_SPP_U (0L << 8) /* User mode 00 */
// SSTATUS Register
#define SSTATUS_SPP_MASK (3L << 8) // sstatus.SPP [8:9]
#define SSTATUS_SPP_S (1L << 8) // Supervisor mode 01
#define SSTATUS_SPP_U (0L << 8) // User mode 00
typedef enum {
USER_MODE = 0,
@@ -677,8 +675,7 @@ __STATIC_INLINE void csi_vic_enable_irq(int32_t IRQn)
PLIC_Type *plic = (PLIC_Type *)CONFIG_PLIC_BASE;
#if CONFIG_INTC_CLIC_PLIC
if (IRQn > PLIC_IRQ_OFFSET)
{
if (IRQn > PLIC_IRQ_OFFSET) {
IRQn -= PLIC_IRQ_OFFSET;
} else {
CLIC->CLICINT[IRQn].IE |= CLIC_INTIE_IE_Msk;
@@ -722,8 +719,7 @@ __STATIC_INLINE void csi_vic_disable_irq(int32_t IRQn)
PLIC_Type *plic = (PLIC_Type *)CONFIG_PLIC_BASE;
#if CONFIG_INTC_CLIC_PLIC
if (IRQn > PLIC_IRQ_OFFSET)
{
if (IRQn > PLIC_IRQ_OFFSET) {
IRQn -= PLIC_IRQ_OFFSET;
} else {
CLIC->CLICINT[IRQn].IE &= ~CLIC_INTIE_IE_Msk;
@@ -769,8 +765,7 @@ __STATIC_INLINE uint32_t csi_vic_get_enabled_irq(int32_t IRQn)
PLIC_Type *plic = (PLIC_Type *)CONFIG_PLIC_BASE;
#if CONFIG_INTC_CLIC_PLIC
if (IRQn > PLIC_IRQ_OFFSET)
{
if (IRQn > PLIC_IRQ_OFFSET) {
IRQn -= PLIC_IRQ_OFFSET;
} else {
return (uint32_t)(CLIC->CLICINT[IRQn].IE & CLIC_INTIE_IE_Msk);
@@ -813,8 +808,7 @@ __STATIC_INLINE uint32_t csi_vic_get_pending_irq(int32_t IRQn)
{
PLIC_Type *plic = (PLIC_Type *)CONFIG_PLIC_BASE;
#if CONFIG_INTC_CLIC_PLIC
if (IRQn > PLIC_IRQ_OFFSET)
{
if (IRQn > PLIC_IRQ_OFFSET) {
IRQn -= PLIC_IRQ_OFFSET;
} else {
return (uint32_t)(CLIC->CLICINT[IRQn].IP & CLIC_INTIP_IP_Msk);
@@ -832,17 +826,14 @@ __STATIC_INLINE void csi_vic_set_pending_irq(int32_t IRQn)
{
PLIC_Type *plic = (PLIC_Type *)CONFIG_PLIC_BASE;
#if CONFIG_INTC_CLIC_PLIC
if (IRQn > PLIC_IRQ_OFFSET)
{
if (IRQn > PLIC_IRQ_OFFSET) {
IRQn -= PLIC_IRQ_OFFSET;
} else {
CLIC->CLICINT[IRQn].IP |= CLIC_INTIP_IP_Msk;
__DSB();
return;
}
#endif
plic->PLIC_IP[IRQn/32] = plic->PLIC_IP[IRQn/32] | (0x1 << (IRQn%32));
__DSB();
}
/**
@@ -854,17 +845,14 @@ __STATIC_INLINE void csi_vic_clear_pending_irq(int32_t IRQn)
{
PLIC_Type *plic = (PLIC_Type *)CONFIG_PLIC_BASE;
#if CONFIG_INTC_CLIC_PLIC
if (IRQn > PLIC_IRQ_OFFSET)
{
if (IRQn > PLIC_IRQ_OFFSET) {
IRQn -= PLIC_IRQ_OFFSET;
} else {
CLIC->CLICINT[IRQn].IP &= ~CLIC_INTIP_IP_Msk;
__DSB();
return;
}
#endif
plic->PLIC_H0_SCLAIM = IRQn;
__DSB();
}
/**
@@ -913,21 +901,16 @@ __STATIC_INLINE void csi_vic_set_prio(int32_t IRQn, uint32_t priority)
{
PLIC_Type *plic = (PLIC_Type *)CONFIG_PLIC_BASE;
#if CONFIG_INTC_CLIC_PLIC
if (IRQn > PLIC_IRQ_OFFSET)
{
if (IRQn > PLIC_IRQ_OFFSET) {
IRQn -= PLIC_IRQ_OFFSET;
} else {
uint8_t nlbits = (CLIC->CLICINFO & CLIC_INFO_CLICINTCTLBITS_Msk) >> CLIC_INFO_CLICINTCTLBITS_Pos;
uint8_t ctl = CLIC->CLICINT[IRQn].CTL;
ctl <<= nlbits;
ctl >>= nlbits;
CLIC->CLICINT[IRQn].CTL = ctl | (priority << (8 - nlbits));
CLIC->CLICINT[IRQn].CTL = (CLIC->CLICINT[IRQn].CTL & (~CLIC_INTCFG_PRIO_Msk)) | (priority << (8 - nlbits));
__DSB();
return;
}
#endif
plic->PLIC_PRIO[IRQn - 1] = priority;
__DSB();
}
/**
@@ -943,8 +926,7 @@ __STATIC_INLINE uint32_t csi_vic_get_prio(int32_t IRQn)
{
PLIC_Type *plic = (PLIC_Type *)CONFIG_PLIC_BASE;
#if CONFIG_INTC_CLIC_PLIC
if (IRQn > PLIC_IRQ_OFFSET)
{
if (IRQn > PLIC_IRQ_OFFSET) {
IRQn -= PLIC_IRQ_OFFSET;
} else {
uint8_t nlbits = (CLIC->CLICINFO & CLIC_INFO_CLICINTCTLBITS_Msk) >> CLIC_INFO_CLICINTCTLBITS_Pos;
@@ -1009,22 +991,18 @@ __STATIC_INLINE void csi_mpu_config_region(uint32_t idx, uint32_t base_addr, reg
uint8_t pmpxcfg = 0;
uint32_t addr = 0;
if (idx > 15)
{
if (idx > 15) {
return;
}
if (!enable)
{
if (!enable) {
attr.a = (address_matching_e)0;
}
if (attr.a == ADDRESS_MATCHING_TOR)
{
if (attr.a == ADDRESS_MATCHING_TOR) {
addr = base_addr >> 2;
} else {
if (size == REGION_SIZE_4B)
{
if (size == REGION_SIZE_4B) {
addr = base_addr >> 2;
attr.a = (address_matching_e)2;
} else {
@@ -1071,8 +1049,7 @@ __STATIC_INLINE uint32_t _csi_clint_config2(unsigned long coret_base, uint16_t h
uint64_t value = (((uint64_t)(CLINT_TIMECMPn_VAL(&clint->STIMECMPH0, hartid))) << 32) + \
(uint64_t)(CLINT_TIMECMPn_VAL(&clint->STIMECMPL0, hartid));
if ((value != 0) && (value != 0xffffffffffffffff))
{
if ((value != 0) && (value != 0xffffffffffffffff)) {
value = value + (uint64_t)ticks;
} else {
value = __get_MTIME() + ticks;
@@ -1083,8 +1060,7 @@ __STATIC_INLINE uint32_t _csi_clint_config2(unsigned long coret_base, uint16_t h
uint64_t value = (((uint64_t)(CLINT_TIMECMPn_VAL(&clint->MTIMECMPH0, hartid))) << 32) + \
(uint64_t)(CLINT_TIMECMPn_VAL(&clint->MTIMECMPL0, hartid));
if ((value != 0) && (value != 0xffffffffffffffff))
{
if ((value != 0) && (value != 0xffffffffffffffff)) {
value = value + (uint64_t)ticks;
} else {
value = __get_MTIME() + ticks;
@@ -1298,15 +1274,16 @@ __STATIC_INLINE int csi_icache_is_enable()
__STATIC_INLINE void csi_icache_enable(void)
{
#if (__ICACHE_PRESENT == 1U)
if (!csi_icache_is_enable())
{
if (!csi_icache_is_enable()) {
uint32_t cache;
__DSB();
__ISB();
__ICACHE_IALL();
cache = __get_MHCR();
cache |= CACHE_MHCR_IE_Msk;
__set_MHCR(cache);
__DSB();
__ISB();
}
#endif
}
@@ -1319,15 +1296,16 @@ __STATIC_INLINE void csi_icache_enable(void)
__STATIC_INLINE void csi_icache_disable(void)
{
#if (__ICACHE_PRESENT == 1U)
if (csi_icache_is_enable())
{
if (csi_icache_is_enable()) {
uint32_t cache;
__DSB();
__ISB();
cache = __get_MHCR();
cache &= ~CACHE_MHCR_IE_Msk; /* disable icache */
__set_MHCR(cache);
__ICACHE_IALL(); /* invalidate all icache */
__DSB();
__ISB();
}
#endif
}
@@ -1341,8 +1319,10 @@ __STATIC_INLINE void csi_icache_invalid(void)
{
#if (__ICACHE_PRESENT == 1U)
__DSB();
__ISB();
__ICACHE_IALL(); /* invalidate all icache */
__DSB();
__ISB();
#endif
}
@@ -1362,16 +1342,17 @@ __STATIC_INLINE int csi_dcache_is_enable()
__STATIC_INLINE void csi_dcache_enable(void)
{
#if (__DCACHE_PRESENT == 1U)
if (!csi_dcache_is_enable())
{
if (!csi_dcache_is_enable()) {
uint32_t cache;
__DSB();
__ISB();
__DCACHE_IALL(); /* invalidate all dcache */
cache = __get_MHCR();
cache |= CACHE_MHCR_DE_Msk; /* enable dcache */
__set_MHCR(cache);
__DSB();
__ISB();
}
#endif
}
@@ -1384,15 +1365,16 @@ __STATIC_INLINE void csi_dcache_enable(void)
__STATIC_INLINE void csi_dcache_disable(void)
{
#if (__DCACHE_PRESENT == 1U)
if (csi_dcache_is_enable())
{
if (csi_dcache_is_enable()) {
uint32_t cache;
__DSB();
__ISB();
cache = __get_MHCR();
cache &= ~(uint32_t)CACHE_MHCR_DE_Msk; /* disable all Cache */
__set_MHCR(cache);
__DCACHE_IALL(); /* invalidate all Cache */
__DSB();
__ISB();
}
#endif
}
@@ -1405,8 +1387,10 @@ __STATIC_INLINE void csi_dcache_invalid(void)
{
#if (__DCACHE_PRESENT == 1U)
__DSB();
__ISB();
__DCACHE_IALL(); /* invalidate all Cache */
__DSB();
__ISB();
#endif
}
@@ -1419,8 +1403,10 @@ __STATIC_INLINE void csi_dcache_clean(void)
{
#if (__DCACHE_PRESENT == 1U)
__DSB();
__ISB();
__DCACHE_CALL(); /* clean all Cache */
__DSB();
__ISB();
#endif
}
@@ -1433,8 +1419,10 @@ __STATIC_INLINE void csi_dcache_clean_invalid(void)
{
#if (__DCACHE_PRESENT == 1U)
__DSB();
__ISB();
__DCACHE_CIALL(); /* clean and inv all Cache */
__DSB();
__ISB();
#endif
}
@@ -1449,12 +1437,11 @@ __STATIC_INLINE void csi_dcache_invalid_range(unsigned long *addr, size_t dsize)
#if (__DCACHE_PRESENT == 1U)
int linesize = csi_get_cache_line_size();
long op_size = dsize + (unsigned long)addr % linesize;
unsigned long op_addr = (unsigned long)addr & CACHE_INV_ADDR_Msk;
unsigned long op_addr = (unsigned long)addr;
__DSB();
#if CBO_INSN_SUPPORT
while (op_size > 0)
{
while (op_size > 0) {
__CBO_INVAL(op_addr);
op_addr += linesize;
op_size -= linesize;
@@ -1463,18 +1450,14 @@ __STATIC_INLINE void csi_dcache_invalid_range(unsigned long *addr, size_t dsize)
cpu_work_mode_t cpu_work_mode;
cpu_work_mode = (cpu_work_mode_t)__get_CPU_WORK_MODE();
if (cpu_work_mode == MACHINE_MODE)
{
while (op_size > 0)
{
if (cpu_work_mode == MACHINE_MODE) {
while (op_size > 0) {
__DCACHE_IPA(op_addr);
op_addr += linesize;
op_size -= linesize;
}
} else if (cpu_work_mode == SUPERVISOR_MODE)
{
while (op_size > 0)
{
} else if (cpu_work_mode == SUPERVISOR_MODE) {
while (op_size > 0) {
__DCACHE_IVA(op_addr);
op_addr += linesize;
op_size -= linesize;
@@ -1504,8 +1487,7 @@ __STATIC_INLINE void csi_dcache_clean_range(unsigned long *addr, size_t dsize)
__DSB();
#if CBO_INSN_SUPPORT
while (op_size > 0)
{
while (op_size > 0) {
__CBO_CLEAN(op_addr);
op_addr += linesize;
op_size -= linesize;
@@ -1514,18 +1496,14 @@ __STATIC_INLINE void csi_dcache_clean_range(unsigned long *addr, size_t dsize)
cpu_work_mode_t cpu_work_mode;
cpu_work_mode = (cpu_work_mode_t)__get_CPU_WORK_MODE();
if (cpu_work_mode == MACHINE_MODE)
{
while (op_size > 0)
{
if (cpu_work_mode == MACHINE_MODE) {
while (op_size > 0) {
__DCACHE_CPA(op_addr);
op_addr += linesize;
op_size -= linesize;
}
} else if (cpu_work_mode == SUPERVISOR_MODE)
{
while (op_size > 0)
{
} else if (cpu_work_mode == SUPERVISOR_MODE) {
while (op_size > 0) {
__DCACHE_CVA(op_addr);
op_addr += linesize;
op_size -= linesize;
@@ -1550,12 +1528,11 @@ __STATIC_INLINE void csi_dcache_clean_invalid_range(unsigned long *addr, size_t
#if (__DCACHE_PRESENT == 1U)
int linesize = csi_get_cache_line_size();
long op_size = dsize + (unsigned long)addr % linesize;
unsigned long op_addr = (unsigned long) addr & CACHE_INV_ADDR_Msk;
unsigned long op_addr = (unsigned long) addr;
__DSB();
#if CBO_INSN_SUPPORT
while (op_size > 0)
{
while (op_size > 0) {
__CBO_FLUSH(op_addr);
op_addr += linesize;
op_size -= linesize;
@@ -1564,18 +1541,14 @@ __STATIC_INLINE void csi_dcache_clean_invalid_range(unsigned long *addr, size_t
cpu_work_mode_t cpu_work_mode;
cpu_work_mode = (cpu_work_mode_t)__get_CPU_WORK_MODE();
if (cpu_work_mode == MACHINE_MODE)
{
while (op_size > 0)
{
if (cpu_work_mode == MACHINE_MODE) {
while (op_size > 0) {
__DCACHE_CIPA(op_addr);
op_addr += linesize;
op_size -= linesize;
}
} else if (cpu_work_mode == SUPERVISOR_MODE)
{
while (op_size > 0)
{
} else if (cpu_work_mode == SUPERVISOR_MODE) {
while (op_size > 0) {
__DCACHE_CIVA(op_addr);
op_addr += linesize;
op_size -= linesize;
@@ -1736,14 +1709,10 @@ __STATIC_INLINE void csi_mmu_invalid_tlb_all(void)
#if CONFIG_CPU_XUANTIE_C907 || CONFIG_CPU_XUANTIE_C907FD || CONFIG_CPU_XUANTIE_C907FDV || CONFIG_CPU_XUANTIE_C907FDVM \
|| CONFIG_CPU_XUANTIE_C908 || CONFIG_CPU_XUANTIE_C908V || CONFIG_CPU_XUANTIE_C908I \
|| CONFIG_CPU_XUANTIE_C908X || CONFIG_CPU_XUANTIE_C908X_CP || CONFIG_CPU_XUANTIE_C908X_CP_XT \
|| CONFIG_CPU_XUANTIE_C910V2 || CONFIG_CPU_XUANTIE_C920V2 \
|| CONFIG_CPU_XUANTIE_C910V3 || CONFIG_CPU_XUANTIE_C920V3 \
|| CONFIG_CPU_XUANTIE_C910V3_CP || CONFIG_CPU_XUANTIE_C920V3_CP \
|| CONFIG_CPU_XUANTIE_C910V3_CP_XT || CONFIG_CPU_XUANTIE_C920V3_CP_XT \
|| CONFIG_CPU_XUANTIE_C910V3 || CONFIG_CPU_XUANTIE_C910V3_CP || CONFIG_CPU_XUANTIE_C920V3 || CONFIG_CPU_XUANTIE_C920V3_CP \
|| CONFIG_CPU_XUANTIE_R908 || CONFIG_CPU_XUANTIE_R908FD || CONFIG_CPU_XUANTIE_R908FDV \
|| CONFIG_CPU_XUANTIE_R908_CP || CONFIG_CPU_XUANTIE_R908FD_CP || CONFIG_CPU_XUANTIE_R908FDV_CP \
|| CONFIG_CPU_XUANTIE_R908_CP_XT || CONFIG_CPU_XUANTIE_R908FD_CP_XT || CONFIG_CPU_XUANTIE_R908FDV_CP_XT \
|| CONFIG_CPU_XUANTIE_R910 || CONFIG_CPU_XUANTIE_R920
/**
\ingroup CSI_tcm_register
@@ -2032,4 +2001,3 @@ __STATIC_INLINE int csi_xmlenb_get_value(void)
#endif /* __CORE_RV32_H_DEPENDANT */
#endif /* __CSI_GENERIC */

View File

@@ -704,19 +704,15 @@ __STATIC_INLINE uint8_t __get_PMPxCFG(unsigned long idx)
{
unsigned long pmpcfgx = 0;
if (idx < 4)
{
if (idx < 4) {
pmpcfgx = __get_PMPCFG0();
} else if (idx >= 4 && idx < 8)
{
} else if (idx >= 4 && idx < 8) {
idx -= 4;
pmpcfgx = __get_PMPCFG1();
} else if (idx >= 8 && idx < 12)
{
} else if (idx >= 8 && idx < 12) {
idx -= 8;
pmpcfgx = __get_PMPCFG2();
} else if (idx >= 12 && idx < 16)
{
} else if (idx >= 12 && idx < 16) {
idx -= 12;
pmpcfgx = __get_PMPCFG3();
} else {
@@ -761,25 +757,21 @@ __STATIC_INLINE void __set_PMPxCFG(unsigned long idx, uint8_t pmpxcfg)
{
unsigned long pmpcfgx = 0;
if (idx < 4)
{
if (idx < 4) {
pmpcfgx = __get_PMPCFG0();
pmpcfgx = (pmpcfgx & ~(0xFF << (idx << 3))) | ((unsigned long)(pmpxcfg) << (idx << 3));
__set_PMPCFG0(pmpcfgx);
} else if (idx >= 4 && idx < 8)
{
} else if (idx >= 4 && idx < 8) {
idx -= 4;
pmpcfgx = __get_PMPCFG1();
pmpcfgx = (pmpcfgx & ~(0xFF << (idx << 3))) | ((unsigned long)(pmpxcfg) << (idx << 3));
__set_PMPCFG1(pmpcfgx);
} else if (idx >= 8 && idx < 12)
{
} else if (idx >= 8 && idx < 12) {
idx -= 8;
pmpcfgx = __get_PMPCFG2();
pmpcfgx = (pmpcfgx & ~(0xFF << (idx << 3))) | ((unsigned long)(pmpxcfg) << (idx << 3));
__set_PMPCFG2(pmpcfgx);
} else if (idx >= 12 && idx < 16)
{
} else if (idx >= 12 && idx < 16) {
idx -= 12;
pmpcfgx = __get_PMPCFG3();
pmpcfgx = (pmpcfgx & ~(0xFF << (idx << 3))) | ((unsigned long)(pmpxcfg) << (idx << 3));
@@ -930,8 +922,7 @@ __ALWAYS_STATIC_INLINE unsigned long __get_PMPADDR15(void)
*/
__STATIC_INLINE unsigned long __get_PMPADDRx(unsigned long idx)
{
switch (idx)
{
switch (idx) {
case 0:
return __get_PMPADDR0();
@@ -1078,8 +1069,7 @@ __ALWAYS_STATIC_INLINE void __set_PMPADDR15(unsigned long pmpaddr)
*/
__STATIC_INLINE void __set_PMPADDRx(unsigned long idx, unsigned long pmpaddr)
{
switch (idx)
{
switch (idx) {
case 0:
__set_PMPADDR0(pmpaddr);
break;
@@ -1637,8 +1627,7 @@ __ALWAYS_STATIC_INLINE uint32_t __RBIT(uint32_t value)
result = value; /* r will be reversed bits of v; first get LSB of v */
for (value >>= 1U; value; value >>= 1U)
{
for (value >>= 1U; value; value >>= 1U) {
result <<= 1U;
result |= value & 1U;
s--;
@@ -1670,30 +1659,26 @@ __ALWAYS_STATIC_INLINE int32_t __SSAT(int32_t x, uint32_t y)
posMax = 1;
for (i = 0; i < (y - 1); i++)
{
for (i = 0; i < (y - 1); i++) {
posMax = posMax * 2;
}
if (x > 0)
{
if (x > 0) {
posMax = (posMax - 1);
if (x > posMax)
{
if (x > posMax) {
x = posMax;
}
/* x &= (posMax * 2 + 1); */
// x &= (posMax * 2 + 1);
} else {
negMin = -posMax;
if (x < negMin)
{
if (x < negMin) {
x = negMin;
}
/* x &= (posMax * 2 - 1); */
// x &= (posMax * 2 - 1);
}
return (x);
@@ -1710,8 +1695,7 @@ __ALWAYS_STATIC_INLINE uint32_t __USAT(uint32_t value, uint32_t sat)
{
uint32_t result;
if ((((0xFFFFFFFF >> sat) << sat) & value) != 0)
{
if ((((0xFFFFFFFF >> sat) << sat) & value) != 0) {
result = 0xFFFFFFFF >> (32 - sat);
} else {
result = value;
@@ -1731,11 +1715,9 @@ __ALWAYS_STATIC_INLINE uint32_t __IUSAT(uint32_t value, uint32_t sat)
{
uint32_t result;
if (value & 0x80000000)
{ /* only overflow set bit-31 */
if (value & 0x80000000) { /* only overflow set bit-31 */
result = 0;
} else if ((((0xFFFFFFFF >> sat) << sat) & value) != 0)
{
} else if ((((0xFFFFFFFF >> sat) << sat) & value) != 0) {
result = 0xFFFFFFFF >> (32 - sat);
} else {
result = value;
@@ -2961,17 +2943,14 @@ __ALWAYS_STATIC_INLINE int32_t __QADD(int32_t x, int32_t y)
{
int32_t result;
if (y >= 0)
{
if ((int32_t)((uint32_t)x + (uint32_t)y) >= x)
{
if (y >= 0) {
if ((int32_t)((uint32_t)x + (uint32_t)y) >= x) {
result = x + y;
} else {
result = 0x7FFFFFFF;
}
} else {
if ((int32_t)((uint32_t)x + (uint32_t)y) < x)
{
if ((int32_t)((uint32_t)x + (uint32_t)y) < x) {
result = x + y;
} else {
result = 0x80000000;
@@ -2997,11 +2976,9 @@ __ALWAYS_STATIC_INLINE int32_t __QSUB(int32_t x, int32_t y)
tmp = (long)x - (long)y;
if (tmp > 0x7fffffff)
{
if (tmp > 0x7fffffff) {
tmp = 0x7fffffff;
} else if (tmp < (-2147483647 - 1))
{
} else if (tmp < (-2147483647 - 1)) {
tmp = -2147483647 - 1;
}
@@ -3307,4 +3284,3 @@ __ALWAYS_STATIC_INLINE uint32_t __UXTB16(uint32_t x)
#endif
#endif /* _CSI_RV32_GCC_H_ */

View File

@@ -1589,8 +1589,7 @@ __ALWAYS_STATIC_INLINE uint32_t __RBIT(uint32_t value)
result = value; /* r will be reversed bits of v; first get LSB of v */
for (value >>= 1U; value; value >>= 1U)
{
for (value >>= 1U; value; value >>= 1U) {
result <<= 1U;
result |= value & 1U;
s--;
@@ -1622,30 +1621,26 @@ __ALWAYS_STATIC_INLINE int32_t __SSAT(int32_t x, uint32_t y)
posMax = 1;
for (i = 0; i < (y - 1); i++)
{
for (i = 0; i < (y - 1); i++) {
posMax = posMax * 2;
}
if (x > 0)
{
if (x > 0) {
posMax = (posMax - 1);
if (x > posMax)
{
if (x > posMax) {
x = posMax;
}
/* x &= (posMax * 2 + 1); */
// x &= (posMax * 2 + 1);
} else {
negMin = -posMax;
if (x < negMin)
{
if (x < negMin) {
x = negMin;
}
/* x &= (posMax * 2 - 1); */
// x &= (posMax * 2 - 1);
}
return (x);
@@ -1662,8 +1657,7 @@ __ALWAYS_STATIC_INLINE uint32_t __USAT(uint32_t value, uint32_t sat)
{
uint32_t result;
if ((((0xFFFFFFFF >> sat) << sat) & value) != 0)
{
if ((((0xFFFFFFFF >> sat) << sat) & value) != 0) {
result = 0xFFFFFFFF >> (32 - sat);
} else {
result = value;
@@ -1683,11 +1677,9 @@ __ALWAYS_STATIC_INLINE uint32_t __IUSAT(uint32_t value, uint32_t sat)
{
uint32_t result;
if (value & 0x80000000)
{ /* only overflow set bit-31 */
if (value & 0x80000000) { /* only overflow set bit-31 */
result = 0;
} else if ((((0xFFFFFFFF >> sat) << sat) & value) != 0)
{
} else if ((((0xFFFFFFFF >> sat) << sat) & value) != 0) {
result = 0xFFFFFFFF >> (32 - sat);
} else {
result = value;
@@ -1737,7 +1729,7 @@ __ALWAYS_STATIC_INLINE uint32_t __RRX(uint32_t op1)
__ALWAYS_STATIC_INLINE uint8_t __LDRBT(volatile uint8_t *addr)
{
uint32_t result;
/* #warning "__LDRBT" */
//#warning "__LDRBT"
__ASM volatile("ldb %0, (%1, 0)" : "=r"(result) : "r"(addr));
return ((uint8_t) result); /* Add explicit type cast here */
}
@@ -1753,7 +1745,7 @@ __ALWAYS_STATIC_INLINE uint16_t __LDRHT(volatile uint16_t *addr)
{
uint32_t result;
/* #warning "__LDRHT" */
//#warning "__LDRHT"
__ASM volatile("ldh %0, (%1, 0)" : "=r"(result) : "r"(addr));
return ((uint16_t) result); /* Add explicit type cast here */
}
@@ -1769,7 +1761,7 @@ __ALWAYS_STATIC_INLINE uint32_t __LDRT(volatile uint32_t *addr)
{
uint32_t result;
/* #warning "__LDRT" */
//#warning "__LDRT"
__ASM volatile("ldw %0, (%1, 0)" : "=r"(result) : "r"(addr));
return (result);
}
@@ -1783,7 +1775,7 @@ __ALWAYS_STATIC_INLINE uint32_t __LDRT(volatile uint32_t *addr)
*/
__ALWAYS_STATIC_INLINE void __STRBT(uint8_t value, volatile uint8_t *addr)
{
/* #warning "__STRBT" */
//#warning "__STRBT"
__ASM volatile("stb %1, (%0, 0)" :: "r"(addr), "r"((uint32_t)value) : "memory");
}
@@ -1796,7 +1788,7 @@ __ALWAYS_STATIC_INLINE void __STRBT(uint8_t value, volatile uint8_t *addr)
*/
__ALWAYS_STATIC_INLINE void __STRHT(uint16_t value, volatile uint16_t *addr)
{
/* #warning "__STRHT" */
//#warning "__STRHT"
__ASM volatile("sth %1, (%0, 0)" :: "r"(addr), "r"((uint32_t)value) : "memory");
}
@@ -1809,7 +1801,7 @@ __ALWAYS_STATIC_INLINE void __STRHT(uint16_t value, volatile uint16_t *addr)
*/
__ALWAYS_STATIC_INLINE void __STRT(uint32_t value, volatile uint32_t *addr)
{
/* #warning "__STRT" */
//#warning "__STRT"
__ASM volatile("stw %1, (%0, 0)" :: "r"(addr), "r"(value) : "memory");
}
@@ -1834,7 +1826,7 @@ __ALWAYS_STATIC_INLINE void __STRT(uint32_t value, volatile uint32_t *addr)
*/
__ALWAYS_STATIC_INLINE uint32_t __get_FPUType(void)
{
/* FIXME: */
//FIXME:
return 0;
}
@@ -2959,17 +2951,14 @@ __ALWAYS_STATIC_INLINE int32_t __QADD(int32_t x, int32_t y)
{
int32_t result;
if (y >= 0)
{
if (x + y >= x)
{
if (y >= 0) {
if (x + y >= x) {
result = x + y;
} else {
result = 0x7FFFFFFF;
}
} else {
if (x + y < x)
{
if (x + y < x) {
result = x + y;
} else {
result = 0x80000000;
@@ -2995,11 +2984,9 @@ __ALWAYS_STATIC_INLINE int32_t __QSUB(int32_t x, int32_t y)
tmp = (int64_t)x - (int64_t)y;
if (tmp > 0x7fffffff)
{
if (tmp > 0x7fffffff) {
tmp = 0x7fffffff;
} else if (tmp < (-2147483647 - 1))
{
} else if (tmp < (-2147483647 - 1)) {
tmp = -2147483647 - 1;
}
@@ -3304,4 +3291,3 @@ __ALWAYS_STATIC_INLINE uint32_t __UXTB16(uint32_t x)
}
#endif /* _CSI_GCC_H_ */

View File

@@ -31,9 +31,7 @@
#if CONFIG_CPU_XUANTIE_E906 || CONFIG_CPU_XUANTIE_E906F || CONFIG_CPU_XUANTIE_E906FD || CONFIG_CPU_XUANTIE_E906P || CONFIG_CPU_XUANTIE_E906FP || CONFIG_CPU_XUANTIE_E906FDP \
|| CONFIG_CPU_XUANTIE_E907 || CONFIG_CPU_XUANTIE_E907F || CONFIG_CPU_XUANTIE_E907FD || CONFIG_CPU_XUANTIE_E907P || CONFIG_CPU_XUANTIE_E907FP || CONFIG_CPU_XUANTIE_E907FDP \
|| CONFIG_CPU_XUANTIE_E902 || CONFIG_CPU_XUANTIE_E902M || CONFIG_CPU_XUANTIE_E902T || CONFIG_CPU_XUANTIE_E902MT \
|| CONFIG_CPU_XUANTIE_E901PLUS_CP || CONFIG_CPU_XUANTIE_E901PLUS_B_CP || CONFIG_CPU_XUANTIE_E901PLUS_M_CP || CONFIG_CPU_XUANTIE_E901PLUS_BM_CP \
|| CONFIG_CPU_XUANTIE_E901_CP || CONFIG_CPU_XUANTIE_E901_B_CP || CONFIG_CPU_XUANTIE_E901_ZM_CP || CONFIG_CPU_XUANTIE_E901_BZM_CP
|| CONFIG_CPU_XUANTIE_E902 || CONFIG_CPU_XUANTIE_E902M || CONFIG_CPU_XUANTIE_E902T || CONFIG_CPU_XUANTIE_E902MT
#define CONFIG_CPU_XUANTIE_E9XX 1
#endif
@@ -307,30 +305,6 @@ __ALWAYS_STATIC_INLINE unsigned long __get_MTVT(void)
return (result);
}
/**
\brief Get MTIME
\details Returns the content of the MTIME Register.
\return MTIME Register value
*/
__ALWAYS_STATIC_INLINE unsigned long __get_MTIME(void)
{
unsigned long result;
__ASM volatile("rdtime %0" : "=r"(result));
return (result);
}
/**
\brief Get MTIMEH
\details Returns the content of the MTIME Register.
\return MTIME Register value
*/
__ALWAYS_STATIC_INLINE unsigned long __get_MTIMEH(void)
{
unsigned long result;
__ASM volatile("rdtimeh %0" : "=r"(result));
return (result);
}
/**
\brief Get SP
\details Returns the content of the SP Register.
@@ -498,16 +472,6 @@ __ALWAYS_STATIC_INLINE unsigned long __get_MCYCLE(void)
return (result);
}
/**
\brief Set MCYCLE
\details Write MCYCLE Register
\param [in] value MCYCLE Register value to set
*/
__ALWAYS_STATIC_INLINE void __set_MCYCLE(unsigned long value)
{
__ASM volatile("csrw mcycle, %0" : : "r"(value));
}
/**
\brief Get MCYCLEH Register
\details Returns the content of the MCYCLEH Register.
@@ -521,16 +485,6 @@ __ALWAYS_STATIC_INLINE unsigned long __get_MCYCLEH(void)
return (result);
}
/**
\brief Set MCYCLEH
\details Write MCYCLEH Register
\param [in] value MCYCLEH Register value to set
*/
__ALWAYS_STATIC_INLINE void __set_MCYCLEH(unsigned long value)
{
__ASM volatile("csrw mcycleh, %0" : : "r"(value));
}
/**
\brief Get MINSTRET Register
\details Returns the content of the MINSTRET Register.
@@ -544,16 +498,6 @@ __ALWAYS_STATIC_INLINE unsigned long __get_MINSTRET(void)
return (result);
}
/**
\brief Set MINSTRET
\details Write MINSTRET Register
\param [in] value MINSTRET Register value to set
*/
__ALWAYS_STATIC_INLINE void __set_MINSTRET(unsigned long value)
{
__ASM volatile("csrw minstret, %0" : : "r"(value));
}
/**
\brief Get MINSTRETH Register
\details Returns the content of the MINSTRETH Register.
@@ -567,16 +511,6 @@ __ALWAYS_STATIC_INLINE unsigned long __get_MINSTRETH(void)
return (result);
}
/**
\brief Set MINSTRETH
\details Write MINSTRETH Register
\param [in] value MINSTRETH Register value to set
*/
__ALWAYS_STATIC_INLINE void __set_MINSTRETH(unsigned long value)
{
__ASM volatile("csrw minstreth, %0" : : "r"(value));
}
#if (CONFIG_CPU_XUANTIE_E907 || CONFIG_CPU_XUANTIE_E907F || CONFIG_CPU_XUANTIE_E907FD || CONFIG_CPU_XUANTIE_E907P || CONFIG_CPU_XUANTIE_E907FP || CONFIG_CPU_XUANTIE_E907FDP)
/**
\brief Get MITCMCR
@@ -624,375 +558,6 @@ __ALWAYS_STATIC_INLINE void __set_MDTCMCR(unsigned long mdtcmcr)
}
#endif /* end e907xx */
/**
\brief Set MCOUNTINHIBIT
\details Write MCOUNTINHIBIT Register.
\param [in] value MCOUNTINHIBIT Register value to set
*/
__ALWAYS_STATIC_INLINE void __set_MCOUNTINHIBIT(uint32_t value)
{
__ASM volatile("csrw mcountinhibit, %0" : : "r"(value));
}
/**
\brief Get MCOUNTINHIBIT
\details Read MCOUNTINHIBIT Register
\return MCOUNTINHIBIT Register value
*/
__ALWAYS_STATIC_INLINE unsigned int __get_MCOUNTINHIBIT(void)
{
uint32_t result;
__ASM volatile("csrr %0, mcountinhibit" : "=r"(result));
return result;
}
/**
\brief Set MHPMEVENT
\details Write MHPMEVENT Register
\param [in] idx Index of MHPMEVENT Register
\param [in] value MHPMEVENT Register value to set
*/
__ALWAYS_STATIC_INLINE void __set_MHPMEVENT(unsigned long idx, unsigned long value)
{
switch (idx)
{
case 0: rv_csr_write(0x7E0, value); break;
case 2: rv_csr_write(0x7E1, value); break;
case 3: rv_csr_write(0x323, value); break;
case 4: rv_csr_write(0x324, value); break;
case 5: rv_csr_write(0x325, value); break;
case 6: rv_csr_write(0x326, value); break;
case 7: rv_csr_write(0x327, value); break;
case 8: rv_csr_write(0x328, value); break;
case 9: rv_csr_write(0x329, value); break;
case 10: rv_csr_write(0x32a, value); break;
case 11: rv_csr_write(0x32b, value); break;
case 12: rv_csr_write(0x32c, value); break;
case 13: rv_csr_write(0x32d, value); break;
case 14: rv_csr_write(0x32e, value); break;
case 15: rv_csr_write(0x32f, value); break;
case 16: rv_csr_write(0x330, value); break;
case 17: rv_csr_write(0x331, value); break;
case 18: rv_csr_write(0x332, value); break;
case 19: rv_csr_write(0x333, value); break;
case 20: rv_csr_write(0x334, value); break;
case 21: rv_csr_write(0x335, value); break;
case 22: rv_csr_write(0x336, value); break;
case 23: rv_csr_write(0x337, value); break;
case 24: rv_csr_write(0x338, value); break;
case 25: rv_csr_write(0x339, value); break;
case 26: rv_csr_write(0x33a, value); break;
case 27: rv_csr_write(0x33b, value); break;
case 28: rv_csr_write(0x33c, value); break;
case 29: rv_csr_write(0x33d, value); break;
case 30: rv_csr_write(0x33e, value); break;
case 31: rv_csr_write(0x33F, value); break;
default: break;
}
}
/**
\brief Get MHPMEVENT
\details Read MHPMEVENT Register.
\param [in] idx Index of MHPMEVENT Register to read.
\return MHPMEVENT Register Value
*/
__ALWAYS_STATIC_INLINE unsigned long __get_MHPMEVENT(unsigned long idx)
{
switch (idx)
{
case 0: return rv_csr_read(0x7E0);
case 2: return rv_csr_read(0x7E1);
case 3: return rv_csr_read(0x323);
case 4: return rv_csr_read(0x324);
case 5: return rv_csr_read(0x325);
case 6: return rv_csr_read(0x326);
case 7: return rv_csr_read(0x327);
case 8: return rv_csr_read(0x328);
case 9: return rv_csr_read(0x329);
case 10: return rv_csr_read(0x32a);
case 11: return rv_csr_read(0x32b);
case 12: return rv_csr_read(0x32c);
case 13: return rv_csr_read(0x32d);
case 14: return rv_csr_read(0x32e);
case 15: return rv_csr_read(0x32f);
case 16: return rv_csr_read(0x330);
case 17: return rv_csr_read(0x331);
case 18: return rv_csr_read(0x332);
case 19: return rv_csr_read(0x333);
case 20: return rv_csr_read(0x334);
case 21: return rv_csr_read(0x335);
case 22: return rv_csr_read(0x336);
case 23: return rv_csr_read(0x337);
case 24: return rv_csr_read(0x338);
case 25: return rv_csr_read(0x339);
case 26: return rv_csr_read(0x33a);
case 27: return rv_csr_read(0x33b);
case 28: return rv_csr_read(0x33c);
case 29: return rv_csr_read(0x33d);
case 30: return rv_csr_read(0x33e);
case 31: return rv_csr_read(0x33F);
default: return 0;
}
}
/**
\brief Set MHPMEVENTH
\details Write MHPMEVENTH Register
\param [in] idx Index of MHPMEVENT Register
\param [in] value MHPMEVENTH Register value to set
*/
__ALWAYS_STATIC_INLINE void __set_MHPMEVENTH(unsigned long idx, unsigned long value)
{
switch (idx)
{
case 3: rv_csr_write(0x723, value); break;
case 4: rv_csr_write(0x724, value); break;
case 5: rv_csr_write(0x725, value); break;
case 6: rv_csr_write(0x726, value); break;
case 7: rv_csr_write(0x727, value); break;
case 8: rv_csr_write(0x728, value); break;
case 9: rv_csr_write(0x729, value); break;
case 10: rv_csr_write(0x72A, value); break;
case 11: rv_csr_write(0x72B, value); break;
case 12: rv_csr_write(0x72C, value); break;
case 13: rv_csr_write(0x72D, value); break;
case 14: rv_csr_write(0x72E, value); break;
case 15: rv_csr_write(0x72F, value); break;
case 16: rv_csr_write(0x730, value); break;
case 17: rv_csr_write(0x731, value); break;
case 18: rv_csr_write(0x732, value); break;
case 19: rv_csr_write(0x733, value); break;
case 20: rv_csr_write(0x734, value); break;
case 21: rv_csr_write(0x735, value); break;
case 22: rv_csr_write(0x736, value); break;
case 23: rv_csr_write(0x737, value); break;
case 24: rv_csr_write(0x738, value); break;
case 25: rv_csr_write(0x739, value); break;
case 26: rv_csr_write(0x73A, value); break;
case 27: rv_csr_write(0x73B, value); break;
case 28: rv_csr_write(0x73C, value); break;
case 29: rv_csr_write(0x73D, value); break;
case 30: rv_csr_write(0x73E, value); break;
case 31: rv_csr_write(0x73F, value); break;
default: break;
}
}
/**
\brief Get MHPMEVENTH
\details Read MHPMEVENTH Register.
\param [in] idx Index of MHPMEVENTH Register to read.
\return MHPMEVENTH Register Value
*/
__ALWAYS_STATIC_INLINE unsigned long __get_MHPMEVENTH(unsigned long idx)
{
switch (idx)
{
case 3: return rv_csr_read(0x723);
case 4: return rv_csr_read(0x724);
case 5: return rv_csr_read(0x725);
case 6: return rv_csr_read(0x726);
case 7: return rv_csr_read(0x727);
case 8: return rv_csr_read(0x728);
case 9: return rv_csr_read(0x729);
case 10: return rv_csr_read(0x72A);
case 11: return rv_csr_read(0x72B);
case 12: return rv_csr_read(0x72C);
case 13: return rv_csr_read(0x72D);
case 14: return rv_csr_read(0x72E);
case 15: return rv_csr_read(0x72F);
case 16: return rv_csr_read(0x730);
case 17: return rv_csr_read(0x731);
case 18: return rv_csr_read(0x732);
case 19: return rv_csr_read(0x733);
case 20: return rv_csr_read(0x734);
case 21: return rv_csr_read(0x735);
case 22: return rv_csr_read(0x736);
case 23: return rv_csr_read(0x737);
case 24: return rv_csr_read(0x738);
case 25: return rv_csr_read(0x739);
case 26: return rv_csr_read(0x73A);
case 27: return rv_csr_read(0x73B);
case 28: return rv_csr_read(0x73C);
case 29: return rv_csr_read(0x73D);
case 30: return rv_csr_read(0x73E);
case 31: return rv_csr_read(0x73F);
default: return 0;
}
}
/**
\brief Set MHPMCOUNTER
\details Write MHPMCOUNTER Register
\param [in] idx Index of MHPMCOUNTER Register
\param [in] value MHPMCOUNTER Register value to set
*/
__ALWAYS_STATIC_INLINE void __set_MHPMCOUNTER(unsigned long idx, unsigned long value)
{
switch (idx)
{
case 3: rv_csr_write(0xB03, (value)); break;
case 4: rv_csr_write(0xB04, (value)); break;
case 5: rv_csr_write(0xB05, (value)); break;
case 6: rv_csr_write(0xB06, (value)); break;
case 7: rv_csr_write(0xB07, (value)); break;
case 8: rv_csr_write(0xB08, (value)); break;
case 9: rv_csr_write(0xB09, (value)); break;
case 10: rv_csr_write(0xB0A, (value)); break;
case 11: rv_csr_write(0xB0B, (value)); break;
case 12: rv_csr_write(0xB0C, (value)); break;
case 13: rv_csr_write(0xB0D, (value)); break;
case 14: rv_csr_write(0xB0E, (value)); break;
case 15: rv_csr_write(0xB0F, (value)); break;
case 16: rv_csr_write(0xB10, (value)); break;
case 17: rv_csr_write(0xB11, (value)); break;
case 18: rv_csr_write(0xB12, (value)); break;
case 19: rv_csr_write(0xB13, (value)); break;
case 20: rv_csr_write(0xB14, (value)); break;
case 21: rv_csr_write(0xB15, (value)); break;
case 22: rv_csr_write(0xB16, (value)); break;
case 23: rv_csr_write(0xB17, (value)); break;
case 24: rv_csr_write(0xB18, (value)); break;
case 25: rv_csr_write(0xB19, (value)); break;
case 26: rv_csr_write(0xB1A, (value)); break;
case 27: rv_csr_write(0xB1B, (value)); break;
case 28: rv_csr_write(0xB1C, (value)); break;
case 29: rv_csr_write(0xB1D, (value)); break;
case 30: rv_csr_write(0xB1E, (value)); break;
case 31: rv_csr_write(0xB1F, (value)); break;
default: break;
}
}
/**
\brief Get MHPMCOUNTER
\details Write MHPMCOUNTER Register.
\param [in] idx Index of MHPMCOUNTER Register
\return MHPMCOUNTER Register Value
*/
__ALWAYS_STATIC_INLINE unsigned long __get_MHPMCOUNTER(unsigned long idx)
{
switch (idx)
{
case 3: return rv_csr_read(0xB03);
case 4: return rv_csr_read(0xB04);
case 5: return rv_csr_read(0xB05);
case 6: return rv_csr_read(0xB06);
case 7: return rv_csr_read(0xB07);
case 8: return rv_csr_read(0xB08);
case 9: return rv_csr_read(0xB09);
case 10: return rv_csr_read(0xB0A);
case 11: return rv_csr_read(0xB0B);
case 12: return rv_csr_read(0xB0C);
case 13: return rv_csr_read(0xB0D);
case 14: return rv_csr_read(0xB0E);
case 15: return rv_csr_read(0xB0F);
case 16: return rv_csr_read(0xB10);
case 17: return rv_csr_read(0xB11);
case 18: return rv_csr_read(0xB12);
case 19: return rv_csr_read(0xB13);
case 20: return rv_csr_read(0xB14);
case 21: return rv_csr_read(0xB15);
case 22: return rv_csr_read(0xB16);
case 23: return rv_csr_read(0xB17);
case 24: return rv_csr_read(0xB18);
case 25: return rv_csr_read(0xB19);
case 26: return rv_csr_read(0xB1A);
case 27: return rv_csr_read(0xB1B);
case 28: return rv_csr_read(0xB1C);
case 29: return rv_csr_read(0xB1D);
case 30: return rv_csr_read(0xB1E);
case 31: return rv_csr_read(0xB1F);
default: return 0;
}
}
/**
\brief Set MHPMCOUNTERH
\details Write MHPMCOUNTERH Register
\param [in] idx Index of MHPMCOUNTERH Register
\param [in] value MHPMCOUNTERH Register value to set
*/
__ALWAYS_STATIC_INLINE void __set_MHPMCOUNTERH(unsigned long idx, unsigned long value)
{
switch (idx)
{
case 3: rv_csr_write(0xB83, (value)); break;
case 4: rv_csr_write(0xB84, (value)); break;
case 5: rv_csr_write(0xB85, (value)); break;
case 6: rv_csr_write(0xB86, (value)); break;
case 7: rv_csr_write(0xB87, (value)); break;
case 8: rv_csr_write(0xB88, (value)); break;
case 9: rv_csr_write(0xB89, (value)); break;
case 10: rv_csr_write(0xB8A, (value)); break;
case 11: rv_csr_write(0xB8B, (value)); break;
case 12: rv_csr_write(0xB8C, (value)); break;
case 13: rv_csr_write(0xB8D, (value)); break;
case 14: rv_csr_write(0xB8E, (value)); break;
case 15: rv_csr_write(0xB8F, (value)); break;
case 16: rv_csr_write(0xB90, (value)); break;
case 17: rv_csr_write(0xB91, (value)); break;
case 18: rv_csr_write(0xB92, (value)); break;
case 19: rv_csr_write(0xB93, (value)); break;
case 20: rv_csr_write(0xB94, (value)); break;
case 21: rv_csr_write(0xB95, (value)); break;
case 22: rv_csr_write(0xB96, (value)); break;
case 23: rv_csr_write(0xB97, (value)); break;
case 24: rv_csr_write(0xB98, (value)); break;
case 25: rv_csr_write(0xB99, (value)); break;
case 26: rv_csr_write(0xB9A, (value)); break;
case 27: rv_csr_write(0xB9B, (value)); break;
case 28: rv_csr_write(0xB9C, (value)); break;
case 29: rv_csr_write(0xB9D, (value)); break;
case 30: rv_csr_write(0xB9E, (value)); break;
case 31: rv_csr_write(0xB9F, (value)); break;
default: break;
}
}
/**
\brief Get MHPMCOUNTERH
\details Write MHPMCOUNTERH Register.
\param [in] idx Index of MHPMCOUNTERH Register
\return MHPMCOUNTERH Register Value
*/
__ALWAYS_STATIC_INLINE unsigned long __get_MHPMCOUNTERH(unsigned long idx)
{
switch (idx)
{
case 3: return rv_csr_read(0xB83);
case 4: return rv_csr_read(0xB84);
case 5: return rv_csr_read(0xB85);
case 6: return rv_csr_read(0xB86);
case 7: return rv_csr_read(0xB87);
case 8: return rv_csr_read(0xB88);
case 9: return rv_csr_read(0xB89);
case 10: return rv_csr_read(0xB8A);
case 11: return rv_csr_read(0xB8B);
case 12: return rv_csr_read(0xB8C);
case 13: return rv_csr_read(0xB8D);
case 14: return rv_csr_read(0xB8E);
case 15: return rv_csr_read(0xB8F);
case 16: return rv_csr_read(0xB90);
case 17: return rv_csr_read(0xB91);
case 18: return rv_csr_read(0xB92);
case 19: return rv_csr_read(0xB93);
case 20: return rv_csr_read(0xB94);
case 21: return rv_csr_read(0xB95);
case 22: return rv_csr_read(0xB96);
case 23: return rv_csr_read(0xB97);
case 24: return rv_csr_read(0xB98);
case 25: return rv_csr_read(0xB99);
case 26: return rv_csr_read(0xB9A);
case 27: return rv_csr_read(0xB9B);
case 28: return rv_csr_read(0xB9C);
case 29: return rv_csr_read(0xB9D);
case 30: return rv_csr_read(0xB9E);
case 31: return rv_csr_read(0xB9F);
default: return 0;
}
}
/**
\brief Get MVENDORID Register
@@ -1093,19 +658,15 @@ __STATIC_INLINE uint8_t __get_PMPxCFG(unsigned long idx)
{
unsigned long pmpcfgx = 0;
if (idx < 4)
{
if (idx < 4) {
pmpcfgx = __get_PMPCFG0();
} else if (idx >=4 && idx < 8)
{
} else if (idx >=4 && idx < 8) {
idx -= 4;
pmpcfgx = __get_PMPCFG1();
} else if (idx >=8 && idx < 12)
{
} else if (idx >=8 && idx < 12) {
idx -= 8;
pmpcfgx = __get_PMPCFG2();
} else if (idx >=12 && idx < 16)
{
} else if (idx >=12 && idx < 16) {
idx -= 12;
pmpcfgx = __get_PMPCFG3();
} else {
@@ -1150,25 +711,21 @@ __STATIC_INLINE void __set_PMPxCFG(unsigned long idx, uint8_t pmpxcfg)
{
unsigned long pmpcfgx = 0;
if (idx < 4)
{
if (idx < 4) {
pmpcfgx = __get_PMPCFG0();
pmpcfgx = (pmpcfgx & ~(0xFF << (idx << 3))) | (pmpxcfg << (idx << 3));
__set_PMPCFG0(pmpcfgx);
} else if (idx >=4 && idx < 8)
{
} else if (idx >=4 && idx < 8) {
idx -= 4;
pmpcfgx = __get_PMPCFG1();
pmpcfgx = (pmpcfgx & ~(0xFF << (idx << 3))) | (pmpxcfg << (idx << 3));
__set_PMPCFG1(pmpcfgx);
} else if (idx >=8 && idx < 12)
{
} else if (idx >=8 && idx < 12) {
idx -= 8;
pmpcfgx = __get_PMPCFG2();
pmpcfgx = (pmpcfgx & ~(0xFF << (idx << 3))) | (pmpxcfg << (idx << 3));
__set_PMPCFG2(pmpcfgx);
} else if (idx >=12 && idx < 16)
{
} else if (idx >=12 && idx < 16) {
idx -= 12;
pmpcfgx = __get_PMPCFG3();
pmpcfgx = (pmpcfgx & ~(0xFF << (idx << 3))) | (pmpxcfg << (idx << 3));
@@ -1319,8 +876,7 @@ __ALWAYS_STATIC_INLINE unsigned long __get_PMPADDR15(void)
*/
__STATIC_INLINE unsigned long __get_PMPADDRx(unsigned long idx)
{
switch (idx)
{
switch (idx) {
case 0: return __get_PMPADDR0();
case 1: return __get_PMPADDR1();
case 2: return __get_PMPADDR2();
@@ -1434,8 +990,7 @@ __ALWAYS_STATIC_INLINE void __set_PMPADDR15(unsigned long pmpaddr)
*/
__STATIC_INLINE void __set_PMPADDRx(unsigned long idx, unsigned long pmpaddr)
{
switch (idx)
{
switch (idx) {
case 0: __set_PMPADDR0(pmpaddr); break;
case 1: __set_PMPADDR1(pmpaddr); break;
case 2: __set_PMPADDR2(pmpaddr); break;
@@ -1546,7 +1101,7 @@ __ALWAYS_STATIC_INLINE void __ISB(void)
__ALWAYS_STATIC_INLINE void __DSB(void)
{
__ASM volatile("fence iorw, iorw");
#if __riscv_xtheadsync
#ifndef __riscv_xtheadse
__ASM volatile("sync");
#endif
}
@@ -1557,9 +1112,7 @@ __ALWAYS_STATIC_INLINE void __DSB(void)
*/
__ALWAYS_STATIC_INLINE void __ICACHE_IALL(void)
{
#if __riscv_xtheadcmo
__ASM volatile("icache.iall");
#endif
}
/**
@@ -1569,9 +1122,7 @@ __ALWAYS_STATIC_INLINE void __ICACHE_IALL(void)
*/
__ALWAYS_STATIC_INLINE void __ICACHE_IPA(unsigned long addr)
{
#if __riscv_xtheadcmo
__ASM volatile("icache.ipa %0" : : "r"(addr));
#endif
}
/**
@@ -1580,7 +1131,7 @@ __ALWAYS_STATIC_INLINE void __ICACHE_IPA(unsigned long addr)
*/
__ALWAYS_STATIC_INLINE void __DCACHE_IALL(void)
{
#if __riscv_xtheadcmo
#ifndef __riscv_xtheadse
__ASM volatile("dcache.iall");
#endif
}
@@ -1591,7 +1142,7 @@ __ALWAYS_STATIC_INLINE void __DCACHE_IALL(void)
*/
__ALWAYS_STATIC_INLINE void __DCACHE_CALL(void)
{
#if __riscv_xtheadcmo
#ifndef __riscv_xtheadse
__ASM volatile("dcache.call");
#endif
}
@@ -1602,7 +1153,7 @@ __ALWAYS_STATIC_INLINE void __DCACHE_CALL(void)
*/
__ALWAYS_STATIC_INLINE void __DCACHE_CIALL(void)
{
#if __riscv_xtheadcmo
#ifndef __riscv_xtheadse
__ASM volatile("dcache.ciall");
#endif
}
@@ -1614,9 +1165,7 @@ __ALWAYS_STATIC_INLINE void __DCACHE_CIALL(void)
*/
__ALWAYS_STATIC_INLINE void __DCACHE_IPA(unsigned long addr)
{
#if __riscv_xtheadcmo
__ASM volatile("dcache.ipa %0" : : "r"(addr));
#endif
}
/**
@@ -1626,9 +1175,7 @@ __ALWAYS_STATIC_INLINE void __DCACHE_IPA(unsigned long addr)
*/
__ALWAYS_STATIC_INLINE void __DCACHE_CPA(unsigned long addr)
{
#if __riscv_xtheadcmo
__ASM volatile("dcache.cpa %0" : : "r"(addr));
#endif
}
/**
@@ -1638,9 +1185,7 @@ __ALWAYS_STATIC_INLINE void __DCACHE_CPA(unsigned long addr)
*/
__ALWAYS_STATIC_INLINE void __DCACHE_CIPA(unsigned long addr)
{
#if __riscv_xtheadcmo
__ASM volatile("dcache.cipa %0" : : "r"(addr));
#endif
}
@@ -1732,8 +1277,7 @@ __ALWAYS_STATIC_INLINE unsigned long __RBIT(unsigned long value)
result = value; /* r will be reversed bits of v; first get LSB of v */
for (value >>= 1U; value; value >>= 1U)
{
for (value >>= 1U; value; value >>= 1U) {
result <<= 1U;
result |= value & 1U;
s--;
@@ -1765,30 +1309,26 @@ __ALWAYS_STATIC_INLINE int32_t __SSAT(int32_t x, unsigned long y)
posMax = 1;
for (i = 0; i < (y - 1); i++)
{
for (i = 0; i < (y - 1); i++) {
posMax = posMax * 2;
}
if (x > 0)
{
if (x > 0) {
posMax = (posMax - 1);
if (x > posMax)
{
if (x > posMax) {
x = posMax;
}
/* x &= (posMax * 2 + 1); */
// x &= (posMax * 2 + 1);
} else {
negMin = -posMax;
if (x < negMin)
{
if (x < negMin) {
x = negMin;
}
/* x &= (posMax * 2 - 1); */
// x &= (posMax * 2 - 1);
}
return (x);
@@ -1805,8 +1345,7 @@ __ALWAYS_STATIC_INLINE unsigned long __USAT(unsigned long value, unsigned long s
{
unsigned long result;
if ((((0xFFFFFFFF >> sat) << sat) & value) != 0)
{
if ((((0xFFFFFFFF >> sat) << sat) & value) != 0) {
result = 0xFFFFFFFF >> (32 - sat);
} else {
result = value;
@@ -1826,11 +1365,9 @@ __ALWAYS_STATIC_INLINE unsigned long __IUSAT(unsigned long value, unsigned long
{
unsigned long result;
if (value & 0x80000000)
{ /* only overflow set bit-31 */
if (value & 0x80000000) { /* only overflow set bit-31 */
result = 0;
} else if ((((0xFFFFFFFF >> sat) << sat) & value) != 0)
{
} else if ((((0xFFFFFFFF >> sat) << sat) & value) != 0) {
result = 0xFFFFFFFF >> (32 - sat);
} else {
result = value;
@@ -2277,7 +1814,6 @@ __ALWAYS_STATIC_INLINE unsigned long __USAD8(unsigned long x, unsigned long y)
return (u + t + s + r);
}
#if 0
/**
\brief Unsigned sum of quad 8-bit unsigned absolute difference with 32-bit accumulate.
\details This function enables you to perform four unsigned 8-bit subtractions, and add the absolute values
@@ -2315,7 +1851,6 @@ __ALWAYS_STATIC_INLINE unsigned long __USADA8(unsigned long x, unsigned long y,
#endif
return (u + t + s + r + sum);
}
#endif
/**
\brief Dual 16-bit saturating addition.
@@ -3058,17 +2593,14 @@ __ALWAYS_STATIC_INLINE int32_t __QADD(int32_t x, int32_t y)
{
int32_t result;
if (y >= 0)
{
if ((int32_t)((unsigned long)x + (unsigned long)y) >= x)
{
if (y >= 0) {
if ((int32_t)((unsigned long)x + (unsigned long)y) >= x) {
result = x + y;
} else {
result = 0x7FFFFFFF;
}
} else {
if ((int32_t)((unsigned long)x + (unsigned long)y) < x)
{
if ((int32_t)((unsigned long)x + (unsigned long)y) < x) {
result = x + y;
} else {
result = 0x80000000;
@@ -3094,11 +2626,9 @@ __ALWAYS_STATIC_INLINE int32_t __QSUB(int32_t x, int32_t y)
tmp = (int64_t)x - (int64_t)y;
if (tmp > 0x7fffffff)
{
if (tmp > 0x7fffffff) {
tmp = 0x7fffffff;
} else if (tmp < (-2147483647 - 1))
{
} else if (tmp < (-2147483647 - 1)) {
tmp = -2147483647 - 1;
}
@@ -3403,4 +2933,3 @@ __ALWAYS_STATIC_INLINE unsigned long __UXTB16(unsigned long x)
}
#endif /* _CSI_RV32_GCC_H_ */

View File

@@ -32,14 +32,10 @@
#if CONFIG_CPU_XUANTIE_C907 || CONFIG_CPU_XUANTIE_C907FD || CONFIG_CPU_XUANTIE_C907FDV || CONFIG_CPU_XUANTIE_C907FDVM \
|| CONFIG_CPU_XUANTIE_C907_RV32 || CONFIG_CPU_XUANTIE_C907FD_RV32 || CONFIG_CPU_XUANTIE_C907FDV_RV32 || CONFIG_CPU_XUANTIE_C907FDVM_RV32 \
|| CONFIG_CPU_XUANTIE_C908 || CONFIG_CPU_XUANTIE_C908V || CONFIG_CPU_XUANTIE_C908I \
|| CONFIG_CPU_XUANTIE_C908X || CONFIG_CPU_XUANTIE_C908X_CP || CONFIG_CPU_XUANTIE_C908X_CP_XT \
|| CONFIG_CPU_XUANTIE_C910V2 || CONFIG_CPU_XUANTIE_C920V2 \
|| CONFIG_CPU_XUANTIE_C910V3 || CONFIG_CPU_XUANTIE_C920V3 \
|| CONFIG_CPU_XUANTIE_C910V3_CP || CONFIG_CPU_XUANTIE_C920V3_CP \
|| CONFIG_CPU_XUANTIE_C910V3_CP_XT || CONFIG_CPU_XUANTIE_C920V3_CP_XT \
|| CONFIG_CPU_XUANTIE_C910V2 || CONFIG_CPU_XUANTIE_C910V3 || CONFIG_CPU_XUANTIE_C910V3_CP \
|| CONFIG_CPU_XUANTIE_C920V2 || CONFIG_CPU_XUANTIE_C920V3 || CONFIG_CPU_XUANTIE_C920V3_CP \
|| CONFIG_CPU_XUANTIE_R908 || CONFIG_CPU_XUANTIE_R908FD || CONFIG_CPU_XUANTIE_R908FDV \
|| CONFIG_CPU_XUANTIE_R908_CP || CONFIG_CPU_XUANTIE_R908FD_CP || CONFIG_CPU_XUANTIE_R908FDV_CP \
|| CONFIG_CPU_XUANTIE_R908_CP_XT || CONFIG_CPU_XUANTIE_R908FD_CP_XT || CONFIG_CPU_XUANTIE_R908FDV_CP_XT
|| CONFIG_CPU_XUANTIE_R908_CP || CONFIG_CPU_XUANTIE_R908FD_CP || CONFIG_CPU_XUANTIE_R908FDV_CP
#define CBO_INSN_SUPPORT 1
#endif
@@ -498,19 +494,7 @@ __ALWAYS_STATIC_INLINE unsigned long __get_MTIME(void)
unsigned long result;
__ASM volatile("rdtime %0" : "=r"(result));
/* __ASM volatile("csrr %0, 0xc01" : "=r"(result)); */
return (result);
}
/**
\brief Get MTIMEH
\details Returns the content of the MTIME Register.
\return MTIME Register value
*/
__ALWAYS_STATIC_INLINE unsigned long __get_MTIMEH(void)
{
unsigned long result;
__ASM volatile("rdtimeh %0" : "=r"(result));
//__ASM volatile("csrr %0, 0xc01" : "=r"(result));
return (result);
}
@@ -854,30 +838,24 @@ __STATIC_INLINE uint8_t __get_PMPxCFG(unsigned long idx)
unsigned long pmpcfgx = 0;
#if __riscv_xlen == 32
if (idx < 4)
{
if (idx < 4) {
pmpcfgx = __get_PMPCFG0();
} else if (idx >= 4 && idx < 8)
{
} else if (idx >= 4 && idx < 8) {
idx -= 4;
pmpcfgx = __get_PMPCFG1();
} else if (idx >= 8 && idx < 12)
{
} else if (idx >= 8 && idx < 12) {
idx -= 8;
pmpcfgx = __get_PMPCFG2();
} else if (idx >= 12 && idx < 16)
{
} else if (idx >= 12 && idx < 16) {
idx -= 12;
pmpcfgx = __get_PMPCFG3();
} else {
return 0;
}
#else
if (idx < 8)
{
if (idx < 8) {
pmpcfgx = __get_PMPCFG0();
} else if (idx >= 8 && idx < 16)
{
} else if (idx >= 8 && idx < 16) {
idx -= 8;
pmpcfgx = __get_PMPCFG2();
} else {
@@ -928,25 +906,21 @@ __STATIC_INLINE void __set_PMPxCFG(unsigned long idx, uint8_t pmpxcfg)
unsigned long pmpcfgx = 0;
#if __riscv_xlen == 32
if (idx < 4)
{
if (idx < 4) {
pmpcfgx = __get_PMPCFG0();
pmpcfgx = (pmpcfgx & ~(0xFF << (idx << 3))) | ((unsigned long)(pmpxcfg) << (idx << 3));
__set_PMPCFG0(pmpcfgx);
} else if (idx >= 4 && idx < 8)
{
} else if (idx >= 4 && idx < 8) {
idx -= 4;
pmpcfgx = __get_PMPCFG1();
pmpcfgx = (pmpcfgx & ~(0xFF << (idx << 3))) | ((unsigned long)(pmpxcfg) << (idx << 3));
__set_PMPCFG1(pmpcfgx);
} else if (idx >= 8 && idx < 12)
{
} else if (idx >= 8 && idx < 12) {
idx -= 8;
pmpcfgx = __get_PMPCFG2();
pmpcfgx = (pmpcfgx & ~(0xFF << (idx << 3))) | ((unsigned long)(pmpxcfg) << (idx << 3));
__set_PMPCFG2(pmpcfgx);
} else if (idx >= 12 && idx < 16)
{
} else if (idx >= 12 && idx < 16) {
idx -= 12;
pmpcfgx = __get_PMPCFG3();
pmpcfgx = (pmpcfgx & ~(0xFF << (idx << 3))) | ((unsigned long)(pmpxcfg) << (idx << 3));
@@ -955,13 +929,11 @@ __STATIC_INLINE void __set_PMPxCFG(unsigned long idx, uint8_t pmpxcfg)
return;
}
#else
if (idx < 8)
{
if (idx < 8) {
pmpcfgx = __get_PMPCFG0();
pmpcfgx = (pmpcfgx & ~(0xFF << (idx << 3))) | ((unsigned long)(pmpxcfg) << (idx << 3));
__set_PMPCFG0(pmpcfgx);
} else if (idx >= 8 && idx < 16)
{
} else if (idx >= 8 && idx < 16) {
idx -= 8;
pmpcfgx = __get_PMPCFG2();
pmpcfgx = (pmpcfgx & ~(0xFF << (idx << 3))) | ((unsigned long)(pmpxcfg) << (idx << 3));
@@ -1113,8 +1085,7 @@ __ALWAYS_STATIC_INLINE unsigned long __get_PMPADDR15(void)
*/
__STATIC_INLINE unsigned long __get_PMPADDRx(unsigned long idx)
{
switch (idx)
{
switch (idx) {
case 0:
return __get_PMPADDR0();
@@ -1261,8 +1232,7 @@ __ALWAYS_STATIC_INLINE void __set_PMPADDR15(unsigned long pmpaddr)
*/
__STATIC_INLINE void __set_PMPADDRx(unsigned long idx, unsigned long pmpaddr)
{
switch (idx)
{
switch (idx) {
case 0:
__set_PMPADDR0(pmpaddr);
break;
@@ -1618,9 +1588,7 @@ __ALWAYS_STATIC_INLINE void __ISB(void)
__ALWAYS_STATIC_INLINE void __DSB(void)
{
__ASM volatile("fence iorw, iorw");
#if __riscv_xtheadsync
__ASM volatile("sync");
#endif
}
/**
@@ -1640,9 +1608,7 @@ __ALWAYS_STATIC_INLINE void __DMB(void)
*/
__ALWAYS_STATIC_INLINE void __SYNC_IS(void)
{
#if __riscv_xtheadsync
__ASM volatile("sync.is");
#endif
}
/**
@@ -1651,9 +1617,7 @@ __ALWAYS_STATIC_INLINE void __SYNC_IS(void)
*/
__ALWAYS_STATIC_INLINE void __ICACHE_IALL(void)
{
#if __riscv_xtheadcmo
__ASM volatile("icache.iall");
#endif
}
/**
@@ -1662,9 +1626,7 @@ __ALWAYS_STATIC_INLINE void __ICACHE_IALL(void)
*/
__ALWAYS_STATIC_INLINE void __ICACHE_IALLS(void)
{
#if __riscv_xtheadcmo
__ASM volatile("icache.ialls");
#endif
}
/**
@@ -1674,9 +1636,7 @@ __ALWAYS_STATIC_INLINE void __ICACHE_IALLS(void)
*/
__ALWAYS_STATIC_INLINE void __ICACHE_IPA(unsigned long addr)
{
#if __riscv_xtheadcmo
__ASM volatile("icache.ipa %0" : : "r"(addr));
#endif
}
/**
@@ -1686,9 +1646,7 @@ __ALWAYS_STATIC_INLINE void __ICACHE_IPA(unsigned long addr)
*/
__ALWAYS_STATIC_INLINE void __ICACHE_IVA(unsigned long addr)
{
#if __riscv_xtheadcmo
__ASM volatile("icache.iva %0" : : "r"(addr));
#endif
}
/**
@@ -1697,9 +1655,7 @@ __ALWAYS_STATIC_INLINE void __ICACHE_IVA(unsigned long addr)
*/
__ALWAYS_STATIC_INLINE void __DCACHE_IALL(void)
{
#if __riscv_xtheadcmo
__ASM volatile("dcache.iall");
#endif
}
/**
@@ -1708,9 +1664,7 @@ __ALWAYS_STATIC_INLINE void __DCACHE_IALL(void)
*/
__ALWAYS_STATIC_INLINE void __DCACHE_CALL(void)
{
#if __riscv_xtheadcmo
__ASM volatile("dcache.call");
#endif
}
/**
@@ -1719,9 +1673,7 @@ __ALWAYS_STATIC_INLINE void __DCACHE_CALL(void)
*/
__ALWAYS_STATIC_INLINE void __DCACHE_CIALL(void)
{
#if __riscv_xtheadcmo
__ASM volatile("dcache.ciall");
#endif
}
/**
@@ -1731,9 +1683,7 @@ __ALWAYS_STATIC_INLINE void __DCACHE_CIALL(void)
*/
__ALWAYS_STATIC_INLINE void __DCACHE_CISW(unsigned long wayset)
{
#if __riscv_xtheadcmo
__ASM volatile("dcache.cisw %0" : : "r"(wayset));
#endif
}
#if CBO_INSN_SUPPORT
@@ -1784,9 +1734,7 @@ __ALWAYS_STATIC_INLINE void __CBO_ZERO(unsigned long addr)
*/
__ALWAYS_STATIC_INLINE void __DCACHE_CPA(unsigned long addr)
{
#if __riscv_xtheadcmo
__ASM volatile("dcache.cpa %0" : : "r"(addr));
#endif
}
/**
@@ -1796,9 +1744,7 @@ __ALWAYS_STATIC_INLINE void __DCACHE_CPA(unsigned long addr)
*/
__ALWAYS_STATIC_INLINE void __DCACHE_CVA(unsigned long addr)
{
#if __riscv_xtheadcmo
__ASM volatile("dcache.cva %0" : : "r"(addr));
#endif
}
/**
@@ -1808,9 +1754,7 @@ __ALWAYS_STATIC_INLINE void __DCACHE_CVA(unsigned long addr)
*/
__ALWAYS_STATIC_INLINE void __DCACHE_CIPA(unsigned long addr)
{
#if __riscv_xtheadcmo
__ASM volatile("dcache.cipa %0" : : "r"(addr));
#endif
}
/**
@@ -1820,9 +1764,7 @@ __ALWAYS_STATIC_INLINE void __DCACHE_CIPA(unsigned long addr)
*/
__ALWAYS_STATIC_INLINE void __DCACHE_CIVA(unsigned long addr)
{
#if __riscv_xtheadcmo
__ASM volatile("dcache.civa %0" : : "r"(addr));
#endif
}
/**
@@ -1832,9 +1774,7 @@ __ALWAYS_STATIC_INLINE void __DCACHE_CIVA(unsigned long addr)
*/
__ALWAYS_STATIC_INLINE void __DCACHE_IPA(unsigned long addr)
{
#if __riscv_xtheadcmo
__ASM volatile("dcache.ipa %0" : : "r"(addr));
#endif
}
/**
@@ -1844,9 +1784,7 @@ __ALWAYS_STATIC_INLINE void __DCACHE_IPA(unsigned long addr)
*/
__ALWAYS_STATIC_INLINE void __DCACHE_IVA(unsigned long addr)
{
#if __riscv_xtheadcmo
__ASM volatile("dcache.iva %0" : : "r"(addr));
#endif
}
#endif
@@ -1858,9 +1796,7 @@ __ALWAYS_STATIC_INLINE void __DCACHE_IVA(unsigned long addr)
*/
__ALWAYS_STATIC_INLINE void __DCACHE_CPAL1(unsigned long addr)
{
#if __riscv_xtheadcmo
__ASM volatile("dcache.cpal1 %0" : : "r"(addr));
#endif
}
/**
@@ -1870,9 +1806,7 @@ __ALWAYS_STATIC_INLINE void __DCACHE_CPAL1(unsigned long addr)
*/
__ALWAYS_STATIC_INLINE void __DCACHE_CVAL1(unsigned long addr)
{
#if __riscv_xtheadcmo
__ASM volatile("dcache.cval1 %0" : : "r"(addr));
#endif
}
/**
@@ -1882,9 +1816,7 @@ __ALWAYS_STATIC_INLINE void __DCACHE_CVAL1(unsigned long addr)
*/
__ALWAYS_STATIC_INLINE void __DCACHE_ISW(unsigned long wayset)
{
#if __riscv_xtheadcmo
__ASM volatile("dcache.isw %0" : : "r"(wayset));
#endif
}
#if (__L2CACHE_PRESENT == 1U)
@@ -2016,7 +1948,7 @@ __ALWAYS_STATIC_INLINE void __set_MCER2H(unsigned long mcer2h)
__ALWAYS_STATIC_INLINE unsigned long __get_SSBEPA2(void)
{
register unsigned long result;
/* __ASM volatile("csrr %0, ssbepa2" : "=r"(result)); */
//__ASM volatile("csrr %0, ssbepa2" : "=r"(result));
__ASM volatile("csrr %0, 0x5d2" : "=r"(result));
return (result);
}
@@ -2028,7 +1960,7 @@ __ALWAYS_STATIC_INLINE unsigned long __get_SSBEPA2(void)
*/
__ALWAYS_STATIC_INLINE void __set_SSBEPA2(unsigned long ssbepa2)
{
/* __ASM volatile("csrw ssbepa2, %0" : : "r"(ssbepa2)); */
//__ASM volatile("csrw ssbepa2, %0" : : "r"(ssbepa2));
__ASM volatile("csrw 0x5d2, %0" : : "r"(ssbepa2));
}
@@ -2040,7 +1972,7 @@ __ALWAYS_STATIC_INLINE void __set_SSBEPA2(unsigned long ssbepa2)
__ALWAYS_STATIC_INLINE unsigned long __get_MSBEPA2(void)
{
register unsigned long result;
/* __ASM volatile("csrr %0, msbepa2" : "=r"(result)); */
//__ASM volatile("csrr %0, msbepa2" : "=r"(result));
__ASM volatile("csrr %0, 0x7fc" : "=r"(result));
return (result);
}
@@ -2052,7 +1984,7 @@ __ALWAYS_STATIC_INLINE unsigned long __get_MSBEPA2(void)
*/
__ALWAYS_STATIC_INLINE void __set_MSBEPA2(unsigned long msbepa2)
{
/* __ASM volatile("csrw msbepa2, %0" : : "r"(msbepa2)); */
//__ASM volatile("csrw msbepa2, %0" : : "r"(msbepa2));
__ASM volatile("csrw 0x7fc, %0" : : "r"(msbepa2));
}
@@ -2132,7 +2064,7 @@ __ALWAYS_STATIC_INLINE void __set_MCERH(unsigned long mcerh)
__ALWAYS_STATIC_INLINE unsigned long __get_SSBEPA(void)
{
register unsigned long result;
/* __ASM volatile("csrr %0, ssbepa" : "=r"(result)); */
//__ASM volatile("csrr %0, ssbepa" : "=r"(result));
__ASM volatile("csrr %0, 0x5d1" : "=r"(result));
return (result);
}
@@ -2144,7 +2076,7 @@ __ALWAYS_STATIC_INLINE unsigned long __get_SSBEPA(void)
*/
__ALWAYS_STATIC_INLINE void __set_SSBEPA(unsigned long ssbepa)
{
/* __ASM volatile("csrw ssbepa, %0" : : "r"(ssbepa)); */
//__ASM volatile("csrw ssbepa, %0" : : "r"(ssbepa));
__ASM volatile("csrw 0x5d1, %0" : : "r"(ssbepa));
}
@@ -2156,7 +2088,7 @@ __ALWAYS_STATIC_INLINE void __set_SSBEPA(unsigned long ssbepa)
__ALWAYS_STATIC_INLINE unsigned long __get_MSBEPA(void)
{
register unsigned long result;
/* __ASM volatile("csrr %0, msbepa" : "=r"(result)); */
//__ASM volatile("csrr %0, msbepa" : "=r"(result));
__ASM volatile("csrr %0, 0x7fb" : "=r"(result));
return (result);
}
@@ -2168,7 +2100,7 @@ __ALWAYS_STATIC_INLINE unsigned long __get_MSBEPA(void)
*/
__ALWAYS_STATIC_INLINE void __set_MSBEPA(unsigned long msbepa)
{
/* __ASM volatile("csrw msbepa, %0" : : "r"(msbepa)); */
//__ASM volatile("csrw msbepa, %0" : : "r"(msbepa));
__ASM volatile("csrw 0x7fb, %0" : : "r"(msbepa));
}
@@ -2327,8 +2259,7 @@ __ALWAYS_STATIC_INLINE unsigned int __get_MCOUNTINHIBIT(void)
*/
__ALWAYS_STATIC_INLINE void __set_MHPMEVENT(unsigned long idx, unsigned long value)
{
switch (idx)
{
switch (idx) {
case 0: rv_csr_write(0x7E0, value); break;
case 2: rv_csr_write(0x7E1, value); break;
case 3: rv_csr_write(0x323, value); break;
@@ -2372,8 +2303,7 @@ __ALWAYS_STATIC_INLINE void __set_MHPMEVENT(unsigned long idx, unsigned long val
*/
__ALWAYS_STATIC_INLINE unsigned long __get_MHPMEVENT(unsigned long idx)
{
switch (idx)
{
switch (idx) {
case 0: return rv_csr_read(0x7E0);
case 2: return rv_csr_read(0x7E1);
case 3: return rv_csr_read(0x323);
@@ -2417,8 +2347,7 @@ __ALWAYS_STATIC_INLINE unsigned long __get_MHPMEVENT(unsigned long idx)
*/
__ALWAYS_STATIC_INLINE void __set_MHPMEVENTH(unsigned long idx, unsigned long value)
{
switch (idx)
{
switch (idx) {
case 3: rv_csr_write(0x723, value); break;
case 4: rv_csr_write(0x724, value); break;
case 5: rv_csr_write(0x725, value); break;
@@ -2460,8 +2389,7 @@ __ALWAYS_STATIC_INLINE void __set_MHPMEVENTH(unsigned long idx, unsigned long va
*/
__ALWAYS_STATIC_INLINE unsigned long __get_MHPMEVENTH(unsigned long idx)
{
switch (idx)
{
switch (idx) {
case 3: return rv_csr_read(0x723);
case 4: return rv_csr_read(0x724);
case 5: return rv_csr_read(0x725);
@@ -2503,8 +2431,7 @@ __ALWAYS_STATIC_INLINE unsigned long __get_MHPMEVENTH(unsigned long idx)
*/
__ALWAYS_STATIC_INLINE void __set_MHPMCOUNTER(unsigned long idx, unsigned long value)
{
switch (idx)
{
switch (idx) {
case 3: rv_csr_write(0xB03, (value)); break;
case 4: rv_csr_write(0xB04, (value)); break;
case 5: rv_csr_write(0xB05, (value)); break;
@@ -2546,8 +2473,7 @@ __ALWAYS_STATIC_INLINE void __set_MHPMCOUNTER(unsigned long idx, unsigned long v
*/
__ALWAYS_STATIC_INLINE unsigned long __get_MHPMCOUNTER(unsigned long idx)
{
switch (idx)
{
switch (idx) {
case 3: return rv_csr_read(0xB03);
case 4: return rv_csr_read(0xB04);
case 5: return rv_csr_read(0xB05);
@@ -2589,8 +2515,7 @@ __ALWAYS_STATIC_INLINE unsigned long __get_MHPMCOUNTER(unsigned long idx)
*/
__ALWAYS_STATIC_INLINE void __set_MHPMCOUNTERH(unsigned long idx, unsigned long value)
{
switch (idx)
{
switch (idx) {
case 3: rv_csr_write(0xB83, (value)); break;
case 4: rv_csr_write(0xB84, (value)); break;
case 5: rv_csr_write(0xB85, (value)); break;
@@ -2632,8 +2557,7 @@ __ALWAYS_STATIC_INLINE void __set_MHPMCOUNTERH(unsigned long idx, unsigned long
*/
__ALWAYS_STATIC_INLINE unsigned long __get_MHPMCOUNTERH(unsigned long idx)
{
switch (idx)
{
switch (idx) {
case 3: return rv_csr_read(0xB83);
case 4: return rv_csr_read(0xB84);
case 5: return rv_csr_read(0xB85);
@@ -2746,8 +2670,7 @@ __ALWAYS_STATIC_INLINE uint32_t __RBIT(uint32_t value)
result = value; /* r will be reversed bits of v; first get LSB of v */
for (value >>= 1U; value; value >>= 1U)
{
for (value >>= 1U; value; value >>= 1U) {
result <<= 1U;
result |= value & 1U;
s--;
@@ -2779,30 +2702,26 @@ __ALWAYS_STATIC_INLINE int32_t __SSAT(int32_t x, uint32_t y)
posMax = 1;
for (i = 0; i < (y - 1); i++)
{
for (i = 0; i < (y - 1); i++) {
posMax = posMax * 2;
}
if (x > 0)
{
if (x > 0) {
posMax = (posMax - 1);
if (x > posMax)
{
if (x > posMax) {
x = posMax;
}
/* x &= (posMax * 2 + 1); */
// x &= (posMax * 2 + 1);
} else {
negMin = -posMax;
if (x < negMin)
{
if (x < negMin) {
x = negMin;
}
/* x &= (posMax * 2 - 1); */
// x &= (posMax * 2 - 1);
}
return (x);
@@ -2819,8 +2738,7 @@ __ALWAYS_STATIC_INLINE uint32_t __USAT(uint32_t value, uint32_t sat)
{
uint32_t result;
if ((((0xFFFFFFFF >> sat) << sat) & value) != 0)
{
if ((((0xFFFFFFFF >> sat) << sat) & value) != 0) {
result = 0xFFFFFFFF >> (32 - sat);
} else {
result = value;
@@ -2840,11 +2758,9 @@ __ALWAYS_STATIC_INLINE uint32_t __IUSAT(uint32_t value, uint32_t sat)
{
uint32_t result;
if (value & 0x80000000)
{ /* only overflow set bit-31 */
if (value & 0x80000000) { /* only overflow set bit-31 */
result = 0;
} else if ((((0xFFFFFFFF >> sat) << sat) & value) != 0)
{
} else if ((((0xFFFFFFFF >> sat) << sat) & value) != 0) {
result = 0xFFFFFFFF >> (32 - sat);
} else {
result = value;
@@ -4070,17 +3986,14 @@ __ALWAYS_STATIC_INLINE int32_t __QADD(int32_t x, int32_t y)
{
int32_t result;
if (y >= 0)
{
if ((int32_t)((uint32_t)x + (uint32_t)y) >= x)
{
if (y >= 0) {
if ((int32_t)((uint32_t)x + (uint32_t)y) >= x) {
result = x + y;
} else {
result = 0x7FFFFFFF;
}
} else {
if ((int32_t)((uint32_t)x + (uint32_t)y) < x)
{
if ((int32_t)((uint32_t)x + (uint32_t)y) < x) {
result = x + y;
} else {
result = 0x80000000;
@@ -4106,11 +4019,9 @@ __ALWAYS_STATIC_INLINE int32_t __QSUB(int32_t x, int32_t y)
tmp = (long)x - (long)y;
if (tmp > 0x7fffffff)
{
if (tmp > 0x7fffffff) {
tmp = 0x7fffffff;
} else if (tmp < (-2147483647 - 1))
{
} else if (tmp < (-2147483647 - 1)) {
tmp = -2147483647 - 1;
}
@@ -4416,4 +4327,3 @@ __ALWAYS_STATIC_INLINE uint32_t __UXTB16(uint32_t x)
#endif
#endif /* _CSI_RV32_GCC_H_ */

View File

@@ -123,67 +123,7 @@
})
#endif
#define CSR_MCOR 0x7c2
#define CSR_MHCR 0x7c1
#define CSR_MCCR2 0x7c3
#define CSR_MHINT 0x7c5
#define CSR_MHINT2 0x7cc
#define CSR_MHINT3 0x7cd
#define CSR_MHINT4 0x7ce
#define CSR_MXSTATUS 0x7c0
#define CSR_PLIC_BASE 0xfc1
#define CSR_MRMR 0x7c6
#define CSR_MRVBR 0x7c7
#define CSR_MCOUNTERWEN 0x7c9
#define CSR_MSMPR 0x7f3
#define CSR_MARCHID 0xf12
#define CSR_MIMPID 0xf13
#define CSR_MHARTID 0xf14
#define CSR_MCPUID 0xfc0
#define CSR_MSTATUS 0x300
#define CSR_MISA 0x301
#define CSR_MEDELEG 0x302
#define CSR_MIDELEG 0x303
#define CSR_MIE 0x304
#define CSR_MTVEC 0x305
#define CSR_MCOUNTEREN 0x306
#define CSR_MENVCFG 0x30a
#define CSR_MSTATUSH 0x310
#define CSR_MSCRATCH 0x340
#define CSR_MEPC 0x341
#define CSR_MCAUSE 0x342
#define CSR_MTVAL 0x343
#define CSR_MIP 0x344
#define CSR_MTINST 0x34a
#define CSR_MTVAL2 0x34b
/* Machine Memory Protection */
#define CSR_PMPCFG0 0x3a0
#define CSR_PMPCFG1 0x3a1
#define CSR_PMPCFG2 0x3a2
#define CSR_PMPCFG3 0x3a3
#define CSR_PMPCFG4 0x3a4
#define CSR_PMPCFG5 0x3a5
#define CSR_PMPCFG6 0x3a6
#define CSR_PMPCFG7 0x3a7
#define CSR_PMPCFG8 0x3a8
#define CSR_PMPCFG9 0x3a9
#define CSR_PMPCFG10 0x3aa
#define CSR_PMPCFG11 0x3ab
#define CSR_PMPCFG12 0x3ac
#define CSR_PMPCFG13 0x3ad
#define CSR_PMPCFG14 0x3ae
#define CSR_PMPCFG15 0x3af
#define CSR_PMPADDR0 0x3b0
#define CSR_PMPADDR1 0x3b1
#define CSR_PMPADDR2 0x3b2
#define CSR_PMPADDR3 0x3b3
#define CSR_PMPADDR4 0x3b4
#define CSR_PMPADDR5 0x3b5
#define CSR_PMPADDR6 0x3b6
#define CSR_PMPADDR7 0x3b7
#endif /* __CSI_RV_COMMON_H__ */

View File

@@ -54,9 +54,7 @@
#if CONFIG_CPU_XUANTIE_E906 || CONFIG_CPU_XUANTIE_E906F || CONFIG_CPU_XUANTIE_E906FD || CONFIG_CPU_XUANTIE_E906P || CONFIG_CPU_XUANTIE_E906FP || CONFIG_CPU_XUANTIE_E906FDP \
|| CONFIG_CPU_XUANTIE_E907 || CONFIG_CPU_XUANTIE_E907F || CONFIG_CPU_XUANTIE_E907FD || CONFIG_CPU_XUANTIE_E907P || CONFIG_CPU_XUANTIE_E907FP || CONFIG_CPU_XUANTIE_E907FDP \
|| CONFIG_CPU_XUANTIE_E902 || CONFIG_CPU_XUANTIE_E902M || CONFIG_CPU_XUANTIE_E902T || CONFIG_CPU_XUANTIE_E902MT \
|| CONFIG_CPU_XUANTIE_E901PLUS_CP || CONFIG_CPU_XUANTIE_E901PLUS_B_CP || CONFIG_CPU_XUANTIE_E901PLUS_M_CP || CONFIG_CPU_XUANTIE_E901PLUS_BM_CP \
|| CONFIG_CPU_XUANTIE_E901_CP || CONFIG_CPU_XUANTIE_E901_B_CP || CONFIG_CPU_XUANTIE_E901_ZM_CP || CONFIG_CPU_XUANTIE_E901_BZM_CP
|| CONFIG_CPU_XUANTIE_E902 || CONFIG_CPU_XUANTIE_E902M || CONFIG_CPU_XUANTIE_E902T || CONFIG_CPU_XUANTIE_E902MT
#include <core/core_rv32.h>
#include <core/csi_rv32_gcc.h>
#else
@@ -114,28 +112,18 @@ __STATIC_INLINE const char* csi_get_cpu_name()
return "c908v";
#elif CONFIG_CPU_XUANTIE_C908I
return "c908i";
#elif CONFIG_CPU_XUANTIE_C908X
return "c908x";
#elif CONFIG_CPU_XUANTIE_C908X_CP
return "c908x-cp";
#elif CONFIG_CPU_XUANTIE_C908X_CP_XT
return "c908x-cp-xt";
#elif CONFIG_CPU_XUANTIE_C910V2
return "c910v2";
#elif CONFIG_CPU_XUANTIE_C910V3
return "c910v3";
#elif CONFIG_CPU_XUANTIE_C910V3_CP
return "c910v3-cp";
#elif CONFIG_CPU_XUANTIE_C910V3_CP_XT
return "c910v3-cp-xt";
#elif CONFIG_CPU_XUANTIE_C920V2
return "c920v2";
#elif CONFIG_CPU_XUANTIE_C920V3
return "c920v3";
#elif CONFIG_CPU_XUANTIE_C920V3_CP
return "c920v3-cp";
#elif CONFIG_CPU_XUANTIE_C920V3_CP_XT
return "c920v3-cp-xt";
#elif CONFIG_CPU_XUANTIE_R910
return "r910";
#elif CONFIG_CPU_XUANTIE_R920
@@ -152,28 +140,7 @@ __STATIC_INLINE const char* csi_get_cpu_name()
return "r908fd-cp";
#elif CONFIG_CPU_XUANTIE_R908FDV_CP
return "r908fdv-cp";
#elif CONFIG_CPU_XUANTIE_R908_CP_XT
return "r908-cp-xt";
#elif CONFIG_CPU_XUANTIE_R908FD_CP_XT
return "r908fd-cp-xt";
#elif CONFIG_CPU_XUANTIE_R908FDV_CP_XT
return "r908fdv-cp-xt";
#elif CONFIG_CPU_XUANTIE_E901PLUS_CP
return "e901plus-cp";
#elif CONFIG_CPU_XUANTIE_E901PLUS_B_CP
return "e901plusb-cp";
#elif CONFIG_CPU_XUANTIE_E901PLUS_M_CP
return "e901plusm-cp";
#elif CONFIG_CPU_XUANTIE_E901PLUS_BM_CP
return "e901plusbm-cp";
#elif CONFIG_CPU_XUANTIE_E901_CP
return "e901-cp";
#elif CONFIG_CPU_XUANTIE_E901_B_CP
return "e901b-cp";
#elif CONFIG_CPU_XUANTIE_E901_ZM_CP
return "e901zm-cp";
#elif CONFIG_CPU_XUANTIE_E901_BZM_CP
return "e901bzm-cp";
#elif CONFIG_CPU_XUANTIE_E902
return "e902";
#elif CONFIG_CPU_XUANTIE_E902M
@@ -217,4 +184,3 @@ __STATIC_INLINE const char* csi_get_cpu_name()
#endif
#endif /* _CORE_H_ */

View File

@@ -119,4 +119,3 @@ extern const char *PFORMAT_E;
#endif
#endif /* _SYSLOG_H_ */

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -1,27 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>project</name>
<comment />
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
<triggers>clean,full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
<triggers>full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.cdt.core.cnature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
</natures>
<linkedResources />
</projectDescription>

View File

@@ -1,3 +0,0 @@
content-types/enabled=true
content-types/org.eclipse.cdt.core.asmSource/file-extensions=s
eclipse.preferences.version=1

View File

@@ -1,20 +0,0 @@
#RT-Thread Studio Project Configuration
# Mon Sep 22 13:30:04 2025
cfg_version=v3.0
board_name=
bsp_version=
bsp_path=
chip_name=
project_base_rtt_bsp=true
is_use_scons_build=true
hardware_adapter=
selected_rtt_version=latest
board_base_nano_proj=false
is_base_example_project=false
example_name=
project_type=rt-thread
os_branch=master
os_version=latest
project_name=project
output_project_path=E:\rt-thread\bsp\xuantie\smartl\e901

View File

@@ -1,18 +0,0 @@
mainmenu "RT-Thread Configuration"
BSP_DIR := .
RTT_DIR := ../../../../
PKGS_DIR := packages
config XUANTIAN_SMARTL_E901
bool
select ARCH_RISCV32
select RT_USING_COMPONENTS_INIT
select RT_USING_USER_MAIN
default y
source "$(RTT_DIR)/Kconfig"
source "$PKGS_DIR/Kconfig"
source "$BSP_DIR/board/Kconfig"

View File

@@ -1,100 +0,0 @@
# XuanTie - E901 Series
## 一 简介
### 1. 内核
玄铁 E901+ 是基于 RISC-V 指令架构的低成本、高能效的 32 位嵌入式 CPU 处理器,用户可以以近似 8 位CPU 的成本获得 32 位嵌入式处理器的效率与性能。E901+ 处理器兼容 RV32E[M] [B]_Zc 指令架构,采用 16/32 位混合编码系统,指令系统与流水线硬件结构精简高效。同时支持配置协处理器接口,用于满足用户 DSADomain Specific Accelerator需求加速特定应用执行并支持用户进行自定义指令扩展。
E901+ 主要针对智能卡、智能电网、低成本微控制器、无线传感网络等嵌入式应用。
### 2.特点
E902 处理器体系结构的主要特点如下:
E901+ 处理器体系结构的主要特点如下:
• 支持 RV32E [M] [B]_Zc 指令集
• 16 个 32 位通用寄存器
• 两级顺序执行流水线
• 支持 RISC-V 机器模式和用户模式
• 支持 RISC-V Debug 架构,支持标准五线 JTAG 调试接口,支持 CJTAG 两线调试接口
• 支持以下硬件乘/除法器配置:
**** 不配置硬件乘/除法器
**** 配置单周期快速硬件乘法器以及多周期1-33慢速硬件除法器
**** 配置多周期3-33慢速硬件乘法器以及多周期1-33慢速硬件除法器
• 兼容 RISC-V CLIC 中断标准,支持中断优先级可配置,支持中断嵌套和中断咬尾
• 外部中断源数量最高可配置为 112 个
• 兼容 RISC-V PMP 内存保护标准0/2/4/8/16 区域可配置
• 支持指令总线和系统总线,指令总线支持 AHB-Lite即 AHB 3.0)协议,系统总线协议支持 AHB 2.0
和 AHB-Lite
• 支持指令高速缓存,缓存行 16 字节,容量 2KiB/4KiB/8KiB 可配
• 支持玄铁扩展编程模型
• 支持复位启动地址硬件集成时可配置
• 支持软复位操作
• 支持协处理器接口可配置
### 3.BSP支持情况
- 当前BSP支持下述内核
```asciiarmor
e901plusbm-cp
```
- 当前BSP默认设置的内核是e901plusbm-cp。
- 当使用其他内核架构时需要修改rtconfig.py文件中的`MCPU`字段。
### 4.运行QEMU
- BSP根目录下存在`qemu.bat`脚本生成可执行文件后可点击该脚本直接启动QEMU.
## 二 工具
- 编译器: https://www.xrvm.cn/community/download?id=4433353576298909696
- 模拟器: https://www.xrvm.cn/community/download?id=4397435198627713024
若上述链接中的编译器与模拟器不能使用可以使用下述CDK中的编译器与模拟器
- SDKhttps://www.xrvm.cn/community/download?id=4397799570420076544
## 三 调试方法
**下述调试方法以E902举例本BSP操作方式一致**搭建完成RT-Thread开发环境在BSP根目录使用env工具在当前目录打开env。
![](figures/1.env.png)
使用前执行一次**menuconfig**命令更新rtconfig.h配置然后在当前目录执行**scons -j12**命令编译生成可可执行文件。
<img src="figures/2.scons.png" alt="env" style="zoom: 95%;" />
生成可执行文件可以直接在命令行启动qemu或者配置vscode脚本借助vscode强大的插件进行图形化调试qemu的相关命令可以查看玄铁qemu的[用户手册](https://www.xrvm.cn/community/download?id=4397435198627713024)下述是启动qemu的命令在powershell或命令行可直接执行下述命令注意qemu需要导出至环境变量或者使用绝对路径。
```shell
qemu-system-riscv64 -machine smartl -nographic -kernel rtthread.elf -cpu e906
```
下述是使用vscode调试的展示。
<img src="figures/3.vscode.png" alt="env" style="zoom: 63%;" />
一起为RISC-V加油

View File

@@ -1,19 +0,0 @@
# for module compiling
import os
Import('RTT_ROOT')
from building import *
cwd = GetCurrentDir()
objs = []
list = os.listdir(cwd)
for item in list:
path = os.path.join(cwd, item)
if item == 'libraries' or not os.path.isdir(path):
continue
sconscript_path = os.path.join(path, 'SConscript')
if os.path.isfile(sconscript_path):
objs.extend(SConscript(os.path.join(item, 'SConscript')))
Return('objs')

View File

@@ -1,54 +0,0 @@
import os
import sys
import rtconfig
from SCons.Script import *
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)
TARGET = 'rtthread.' + 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)
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'
SDK_LIB = libraries_path_prefix
Export('SDK_LIB')
# prepare building environment
objs = PrepareBuilding(env, RTT_ROOT, has_libcpu=False)
bsp_vdir = 'build'
library_vdir = 'build/libraries'
# common include drivers
objs.extend(SConscript(os.path.join(libraries_path_prefix, 'SConscript'), variant_dir=library_vdir, duplicate=0))
# make a building
DoBuilding(TARGET, objs)

View File

@@ -1,10 +0,0 @@
from building import *
import os
cwd = GetCurrentDir()
CPPPATH = [cwd]
src = ['main.c']
group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH)
Return('group')

View File

@@ -1,19 +0,0 @@
/*
* Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-04-21 Wangshun first version
*/
#include <rtthread.h>
#include <rtdevice.h>
#include "pre_main.h"
int main(void)
{
rt_kprintf("Hello RT-Thread!\r\n");
}

View File

@@ -1,30 +0,0 @@
menu "Hardware Drivers Config"
config SOC_XUANTIE
bool
select RT_USING_COMPONENTS_INIT
select RT_USING_USER_MAIN
default y
menu "On-chip Peripheral Drivers"
menuconfig BSP_USING_UART
bool "Enable UART"
select RT_USING_SERIAL
default n
if BSP_USING_UART
config BSP_USING_UART0
bool "Enable UART0"
default n
endif
menuconfig ENABLE_FPU
bool "Enable FPU"
select ARCH_RISCV_FPU
default n
endmenu
endmenu

View File

@@ -1,33 +0,0 @@
import os
import rtconfig
from building import *
Import('SDK_LIB')
cwd = GetCurrentDir()
# add general drivers
src = ['board.c']
path = [cwd]
CPPDEFINES = [
'CONFIG_KERNEL_RTTHREAD=1',
'__RT_KERNEL_SOURCE__=1',
'CONFIG_CSI_V2=1',
'CONFIG_CSI=csi2',
'CONFIG_INIT_TASK_STACK_SIZE=4096',
'CONFIG_APP_TASK_STACK_SIZE=8192',
'CONFIG_ARCH_MAINSTACK=4096',
'CONFIG_ARCH_INTERRUPTSTACK=4096',
'CONFIG_XIP=1',
'CONFIG_LIBC_MINI_PRINTF_SUPPORT=1',
'CONFIG_SYSTICK_HZ=100',
'CONFIG_BOARD_SMARTL_EVB=1',
'CONFIG_DEBUG=1',
'CLI_CONFIG_STACK_SIZE=4096',
'CONFIG_CPU_XUANTIE_E901PLUS_BM_CP=1',
]
group = DefineGroup('Drivers', src, depend = [''], CPPPATH = path, CPPDEFINES = CPPDEFINES)
Return('group')

View File

@@ -1,42 +0,0 @@
/*
* Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-04-23 Wangshun first version
*/
#include <board.h>
#include <rthw.h>
#include <rtthread.h>
#include <drv_usart.h>
extern unsigned long __heap_start;
extern unsigned long __heap_end;
/**
* This function will initialize your board.
*/
void rt_hw_board_init()
{
rt_hw_interrupt_init();
#ifdef RT_USING_HEAP
rt_system_heap_init((void *)&__heap_start, (void *)&__heap_end);
#endif
#ifdef BSP_USING_UART
rt_hw_usart_init();
#endif
#ifdef RT_USING_CONSOLE
rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
#endif
#ifdef RT_USING_COMPONENTS_INIT
rt_components_board_init();
#endif
}

View File

@@ -1,443 +0,0 @@
/*
* Copyright (C) 2017-2024 Alibaba Group Holding Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
This is an example board.h for Board Compment, New Board should flow the macro defines.
*/
#ifndef __BOARD_H__
#define __BOARD_H__
#include <soc.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Common Board Features Define */
/*
The Common BOARD_XXX Macro Defines Boards supported features which may reference by Solutions.
Common board macro include:
. BOARD_NAME
· UART
· GPIO
· PWM
· ADC
· BUTTON
· LED
· WIFI
· BT
· AUDIO
BOARD_XXX Macro descripted below should be defined if the board support.
*/
/****************************************************************************/
/*
This riscv dummy board include:
· UART x1
· GPIO x2
· PWM x2
· ADC x1
· BUTTON x2
· LED x2
· WIFI x0
· BT x0
· AUDIO x1
*/
#ifndef CONFIG_BOARD_UART
#define CONFIG_BOARD_UART 1
#endif
#ifndef CONFIG_BOARD_GPIO
#define CONFIG_BOARD_GPIO 0
#endif
#ifndef CONFIG_BOARD_PWM
#define CONFIG_BOARD_PWM 0
#endif
#ifndef CONFIG_BOARD_ADC
#define CONFIG_BOARD_ADC 0
#endif
#ifndef CONFIG_BOARD_BUTTON
#define CONFIG_BOARD_BUTTON 0
#endif
#ifndef CONFIG_BOARD_LED
#define CONFIG_BOARD_LED 0
#endif
#ifndef CONFIG_BOARD_WIFI
#define CONFIG_BOARD_WIFI 0
#endif
#ifndef CONFIG_BOARD_BT
#define CONFIG_BOARD_BT 0
#endif
#ifndef CONFIG_BOARD_AUDIO
#define CONFIG_BOARD_AUDIO 0
#endif
#define BOARD_NAME "RISCV_DUMMY"
/* the board pins, can be used as uart, gpio, pwd... */
#define BOARD_PIN0 (0)
#define BOARD_PIN1 (1)
#define BOARD_PIN2 (2)
#define BOARD_PIN3 (3)
#define BOARD_PIN4 (4)
#define BOARD_PIN5 (5)
#define BOARD_PIN6 (6)
#define BOARD_PIN7 (7)
#define BOARD_PIN8 (8)
#define BOARD_PIN9 (9)
#define BOARD_PIN10 (10)
#define BOARD_PIN11 (11)
#define BOARD_PIN12 (12)
/* ... */
#if defined(CONFIG_BOARD_UART) && CONFIG_BOARD_UART
/* UART */
/*
The total supported uart numbers on this board, 0 meas No uart support.
the BOARD_UART<x>_XXX, x in rang of (0, BOARD_UART_NUM - 1)
*/
#ifndef BOARD_UART_NUM
#define BOARD_UART_NUM (1)
#endif
#if defined(BOARD_UART_NUM) && BOARD_UART_NUM > 0
/* the board uart0 tx pin */
#define BOARD_UART0_TX_PIN (BOARD_PIN0)
/* the borad uart0 rx pin */
#define BOARD_UART0_RX_PIN (BOARD_PIN1)
/* The real UART port reference to board logic port 0 */
#define BOARD_UART0_IDX (0)
/* The default baudrate for uart0 */
#define BOARD_UART0_BAUD (115200)
/* #define BOARD_UART1_IDX (1) */
/* #define BOARD_UART1_BAUD (115200) */
/* ... */
#endif /* defined(BOARD_UART_NUM) && BOARD_UART_NUM > 0 */
#endif /* defined(CONFIG_BOARD_UART) && CONFIG_BOARD_UART */
#if defined(CONFIG_BOARD_GPIO) && CONFIG_BOARD_GPIO
/* GPIO */
/*
The total supported GPIO Pin numbers on this board, 0 meas No uart support.
the BOARD_GPIO_PIN<x>, x in rang of (0, BOARD_GPIO_PIN_NUM - 1)
*/
#ifndef BOARD_GPIO_PIN_NUM
#define BOARD_GPIO_PIN_NUM (2)
#endif
#if defined(BOARD_GPIO_PIN_NUM) && BOARD_GPIO_PIN_NUM > 0
/* The real gpio reference to board logic gpio pin */
#define BOARD_GPIO_PIN0 (BOARD_PIN2)
#define BOARD_GPIO_PIN1 (BOARD_PIN3)
/* #define BOARD_GPIO_PIN2 (x) */
/* #define BOARD_GPIO_PIN3 (x) */
#endif /* defined(BOARD_GPIO_PIN_NUM) && BOARD_GPIO_PIN_NUM > 0 */
#endif /* defined(CONFIG_BOARD_GPIO) && CONFIG_BOARD_GPIO */
#if defined(CONFIG_BOARD_PWM) && CONFIG_BOARD_PWM
/* PWM */
/* the board supported pwm channels */
#ifndef BOARD_PWM_NUM
#define BOARD_PWM_NUM (2)
#endif
#if defined(BOARD_PWM_NUM) && BOARD_PWM_NUM > 0
/* the board pwm pin */
#define BOARD_PWM0_PIN (BOARD_PIN4)
/* The real pwm channel reference to board logic pwm channel */
#define BOARD_PWM0_CH (0)
#define BOARD_PWM1_PIN (BOARD_PIN5)
#define BOARD_PWM1_CH (1)
#endif /* defined(BOARD_PWM_NUM) && BOARD_PWM_NUM > 0 */
#endif /* defined(CONFIG_BOARD_PWM) && CONFIG_BOARD_PWM */
#if defined(CONFIG_BOARD_ADC) && CONFIG_BOARD_ADC > 0
/* ADC */
/* the board supported adc channels */
#ifndef BOARD_ADC_NUM
#define BOARD_ADC_NUM (1)
#endif
#if defined(BOARD_ADC_NUM) && BOARD_ADC_NUM > 0
/* the board adc pin */
#define BOARD_ADC0_PIN (BOARD_PIN6)
/* The real adc channel reference to board logic adc channel */
#define BOARD_ADC0_CH (0)
#endif /* defined(BOARD_ADC_NUM) && BOARD_ADC_NUM > 0 */
#endif /* defined(CONFIG_BOARD_ADC) && CONFIG_BOARD_ADC > 0 */
#if defined(CONFIG_BOARD_BUTTON) && CONFIG_BOARD_BUTTON > 0
/* BUTTON */
#ifndef BOARD_BUTTON_NUM
/*
the board supported buttons, include gpio button and adc button,
BOARD_BUTTON_NUM = BOARD_BUTTON_GPIO_NUM + BOARD_BUTTON_ADC_NUM.
*/
#define BOARD_BUTTON_NUM (4)
#endif
#if defined(BOARD_BUTTON_NUM) && BOARD_BUTTON_NUM > 0
#define BOARD_BUTTON0_PIN (BOARD_PIN7)
#define BOARD_BUTTON1_PIN (BOARD_PIN8)
#define BOARD_BUTTON2_PIN (BOARD_PIN9)
#define BOARD_BUTTON3_PIN (BOARD_PIN10)
/* GPIO BUTTON */
/* the board supported GPIO Buttons */
#ifndef BOARD_BUTTON_GPIO_NUM
#define BOARD_BUTTON_GPIO_NUM (2)
#endif
#if defined(BOARD_BUTTON_GPIO_NUM) && BOARD_BUTTON_GPIO_NUM > 0
/* the board logic button id, in range of (0, BOARD_BUTTON_GPIO_NUM - 1) */
#define BOARD_BUTTON0 (0)
/* for gpio button, define the pin numner. if the gpio pin used as gpio button, it shoudn't reference as BOARD_GPIO_PINx
*/
#define BOARD_BUTTON0_GPIO_PIN (BOARD_BUTTON0_PIN)
#define BOARD_BUTTON1 (1)
#define BOARD_BUTTON1_GPIO_PIN (BOARD_BUTTON1_PIN)
#endif /* defined(BOARD_BUTTON_GPIO_NUM) && BOARD_BUTTON_GPIO_NUM > 0 */
/* ADC BUTTON */
/* the board supported adc Buttons */
#ifndef BOARD_BUTTON_ADC_NUM
#define BOARD_BUTTON_ADC_NUM (2)
#endif
#if defined(BOARD_BUTTON_ADC_NUM) && BOARD_BUTTON_ADC_NUM > 0
/* the board logic adc button id, in range of (BOARD_BUTTON_GPIO_NUM, BOARD_BUTTON_NUM - 1), if not suuport GPIO Button,
* BOARD_BUTTON_GPIO_NUM should be 0 */
#define BOARD_BUTTON2 (BOARD_BUTTON_GPIO_NUM + 0)
#define BOARD_BUTTON2_ADC_PIN (BOARD_BUTTON2_PIN)
/* the adc channel used for button2, if the adc channel used as adc button, it shoudn't reference as BOARD_ADCx_CH*/
#define BOARD_BUTTON2_ADC_CH (1)
/* the adc device name */
#define BOARD_BUTTON2_ADC_NAME "adc1"
/* adc voltage reference */
#define BOARD_BUTTON2_ADC_REF (100)
/* adc voltage range */
#define BOARD_BUTTON2_ADC_RANG (500)
#define BOARD_BUTTON3 (BOARD_BUTTON_GPIO_NUM + 1)
#define BOARD_BUTTON3_ADC_PIN (BOARD_BUTTON3_PIN)
#define BOARD_BUTTON3_ADC_CH (1)
#define BOARD_BUTTON3_ADC_NAME "adc1"
#define BOARD_BUTTON3_ADC_REF (600)
#define BOARD_BUTTON3_ADC_RANG (500)
/* #define BOARD_ADC_BUTTON2 (2) */
/* #define BOARD_ADC_BUTTON2_CH (1) */
/* #define BOARD_ADC_BUTTON2_NAME "adc1" */
/* #define BOARD_ADC_BUTTON2_REF xxx */
/* #define BOARD_ADC_BUTTON2_RANG xxx */
#endif /* defined(BOARD_BUTTON_ADC_NUM) && BOARD_BUTTON_ADC_NUM > 0 */
#endif /* defined(BOARD_BUTTON_NUM) && BOARD_BUTTON_NUM > 0 */
#endif /* defined(BOARD_BUTTON_NUM) && BOARD_BUTTON_NUM > 0 */
#if defined(CONFIG_BOARD_LED) && CONFIG_BOARD_LED > 0
/* LED */
/* the board supported leds */
#ifndef BOARD_LED_NUM
#define BOARD_LED_NUM (2)
#endif
#define BOARD_LED0_PIN BOARD_PIN11
#define BOARD_LED1_PIN BOARD_PIN12
/* PWM LED */
/* the board supported pwm leds */
#ifndef BOARD_LED_PWM_NUM
#define BOARD_LED_PWM_NUM (1)
#endif
#if defined(BOARD_LED_PWM_NUM) && BOARD_LED_PWM_NUM > 0
#define BOARD_LED0_PWM_PIN (BOARD_LED0_PIN)
/* the pwm channel used for led0, if the pwm channel used as led0, it shoudn't reference as BOARD_PWMx_CH */
#define BOARD_LED0_PWM_CH (0)
#endif /* defined(BOARD_LED_PWM_NUM) && BOARD_LED_PWM_NUM > 0 */
/* GPIO LED */
#ifndef BOARD_LED_GPIO_NUM
#define BOARD_LED_GPIO_NUM (1)
#endif
#if defined(BOARD_LED_GPIO_NUM) && BOARD_LED_GPIO_NUM > 0
/* the gpio pin used for led0, if the gpio pin used as led, it shoudn't reference as BOARD_GPIO_PINx */
#define BOARD_LED1_GPIO_PIN (BOARD_LED1_PIN)
#endif /* defined(BOARD_LED_GPIO_NUM) && BOARD_LED_GPIO_NUM > 0 */
#endif /* defined(CONFIG_BOARD_LED) && CONFIG_BOARD_LED > 0 */
#if defined(CONFIG_BOARD_BT) && CONFIG_BOARD_BT > 0
/* BT */
/* the board support bluetooth */
#ifndef BOARD_BT_SUPPORT
#define BOARD_BT_SUPPORT 1
#endif
#endif /* defined(CONFIG_BOARD_BT) && CONFIG_BOARD_BT > 0 */
#if defined(CONFIG_BOARD_WIFI) && CONFIG_BOARD_WIFI > 0
/* WIFI */
/* the board support wifi */
#ifndef BOARD_WIFI_SUPPORT
#define BOARD_WIFI_SUPPORT 1
#endif
#endif /* defined(CONFIG_BOARD_WIFI) && CONFIG_BOARD_WIFI > 0 */
#if defined(CONFIG_BOARD_AUDIO) && CONFIG_BOARD_AUDIO > 0
/* Audio */
/* the board support audio */
#ifndef BOARD_AUDIO_SUPPORT
#define BOARD_AUDIO_SUPPORT 1
#endif
#endif /* defined(CONFIG_BOARD_AUDIO) && CONFIG_BOARD_AUDIO > 0 */
/****************************************************************************/
/* Common solutions defines */
/* Console config, Almost all solutions and demos use these. */
#ifndef CONSOLE_UART_IDX
#define CONSOLE_UART_IDX (BOARD_UART0_IDX)
#endif
#ifndef CONFIG_CLI_USART_BAUD
#define CONFIG_CLI_USART_BAUD (BOARD_UART0_BAUD)
#endif
#ifndef CONFIG_CONSOLE_UART_BUFSIZE
#define CONFIG_CONSOLE_UART_BUFSIZE (128)
#endif
/****************************************************************************/
/* Commom test demos defines */
/* i2c */
#define EXAMPLE_IIC_IDX 0 /* 1 */
#define EXAMPLE_PIN_IIC_SDA 0 /* PC1 */
#define EXAMPLE_PIN_IIC_SCL 0 /* PC0 */
#define EXAMPLE_PIN_IIC_SDA_FUNC 0 /* PC1_I2C1_SDA */
#define EXAMPLE_PIN_IIC_SCL_FUNC 0 /* PC0_I2C1_SCL */
/* adc */
#define EXAMPLE_ADC_CH0 0 /* PA8 */
#define EXAMPLE_ADC_CH0_FUNC 0 /* PA8_ADC_A0 */
#define EXAMPLE_ADC_CH12 0 /* PA26 */
#define EXAMPLE_ADC_CH12_FUNC 0 /* PA26_ADC_A12 */
/****************************************************************************/
/* Vendor board defines */
/* other board specific defines */
/* #define CUSTOM_BOARD_xxx */
/****************************************************************************/
/**
* @brief init the board for default: pin mux, etc.
* re-implement if need.
* @return
*/
void board_init(void);
/**
* @brief init the board gpio pin for default: pin mux, etc.
* re-implement if need.
* @return
*/
void board_gpio_pin_init(void);
/**
* @brief init the board uart for default: pin mux, etc.
* re-implement if need.
* @return
*/
void board_uart_init(void);
/**
* @brief init the board pwm for default: pin mux, etc.
* re-implement if need.
* @return
*/
void board_pwm_init(void);
/**
* @brief init the board adc for default: pin mux, etc.
* re-implement if need.
* @return
*/
void board_adc_init(void);
/**
* @brief init the board button for default: pin mux, etc.
* re-implement if need.
* @return
*/
void board_button_init(void);
/**
* @brief init the board led for default: pin mux, etc.
* re-implement if need.
* @return
*/
void board_led_init(void);
/**
* @brief init the board wifi for default: pin mux, etc.
* re-implement if need.
* @return
*/
void board_wifi_init(void);
/**
* @brief init the board bt for default: pin mux, etc.
* re-implement if need.
* @return
*/
void board_bt_init(void);
/**
* @brief init the board audio for default: pin mux, etc.
* re-implement if need.
* @return
*/
void board_audio_init(void);
#ifdef __cplusplus
}
#endif
#endif /* __BOARD_H__ */

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 164 KiB

View File

@@ -1,8 +0,0 @@
@echo off
set OBJDUMP=D:\RT-ThreadStudio\repo\Extract\ToolChain_Support_Packages\RISC-V\XTGccElfNewlib\V3.0.1\R\bin\riscv64-unknown-elf-objdump
set TARGET=E:\rt-thread\bsp\xuantie\smartl\e901\rtthread.elf
set OUTPUT=rtthread.asm
%OBJDUMP% -d %TARGET% > %OUTPUT%
echo Disassembly generated to %OUTPUT%
pause

View File

@@ -1,91 +0,0 @@
@echo off
cls
echo /*
echo * Copyright (c) 2006 - 2025, RT-Thread Development Team
echo *
echo * SPDX-License-Identifier: Apache-2.0
echo *
echo * Change Logs:
echo * Date Author Notes
echo * 2025/04/29 Wangshun first version
echo * 2025/05/14 Optimized Improved robustness and error handling
echo */
echo.
setlocal enabledelayedexpansion
set "CONFIG_FILE=qemu_config.txt"
set "CPU_CONFIG_FILE=cpu_config.txt"
set "DEFAULT_QEMU_DIR=E:\XuanTieCore\6.QEMU"
set "ELF_PATH=%CD%\rtthread.elf"
:: Load QEMU directory from config file or set default
if exist "!CONFIG_FILE!" (
set /p QEMU_DIR=<"!CONFIG_FILE!"
if not defined QEMU_DIR set "QEMU_DIR=!DEFAULT_QEMU_DIR!"
) else (
set "QEMU_DIR=!DEFAULT_QEMU_DIR!"
)
:: Load CPU parameter from config file or set default
if exist "!CPU_CONFIG_FILE!" (
set /p CPU_PARAM=<"!CPU_CONFIG_FILE!"
if not defined CPU_PARAM set "CPU_PARAM=e901"
) else (
set "CPU_PARAM=e901"
)
:: Prompt for new QEMU directory
set /p "USER_INPUT=Enter new QEMU directory (Enter for default: !QEMU_DIR!): "
if defined USER_INPUT (
set "USER_INPUT=!USER_INPUT: =!"
if not "!USER_INPUT!"=="" (
set "QEMU_DIR=!USER_INPUT!"
echo !QEMU_DIR!>"!CONFIG_FILE!"
)
)
:: Validate QEMU path
set "QEMU_PATH=!QEMU_DIR!\qemu-system-riscv32.exe"
if not exist "!QEMU_PATH!" (
echo Error: QEMU executable not found at "!QEMU_PATH!".
echo Please verify the QEMU directory and try again.
pause
exit /b 1
)
:: Prompt for new CPU parameter
echo Current CPU parameter: !CPU_PARAM!
set /p "CPU_INPUT=Enter new -cpu parameter (Enter for default): "
if defined CPU_INPUT (
set "CPU_INPUT=!CPU_INPUT: =!"
if not "!CPU_INPUT!"=="" (
set "CPU_PARAM=!CPU_INPUT!"
echo !CPU_PARAM!>"!CPU_CONFIG_FILE!"
)
)
:: Validate ELF file
if not exist "!ELF_PATH!" (
echo Error: rtthread.elf not found at "!ELF_PATH!".
pause
exit /b 1
)
:: Display QEMU version
echo.
"!QEMU_PATH!" --version
:: Run QEMU
echo.
"!QEMU_PATH!" -machine smartl -kernel "!ELF_PATH!" -nographic -cpu !CPU_PARAM!
if !ERRORLEVEL! neq 0 (
echo Error: QEMU failed to run. Check configuration or paths.
pause
exit /b !ERRORLEVEL!
)
echo QEMU terminated.
pause
endlocal

View File

@@ -1,419 +0,0 @@
#ifndef RT_CONFIG_H__
#define RT_CONFIG_H__
#define XUANTIAN_SMARTL_E901
/* RT-Thread Kernel */
/* klibc options */
/* rt_vsnprintf options */
/* end of rt_vsnprintf options */
/* rt_vsscanf options */
/* end of rt_vsscanf options */
/* rt_memset options */
/* end of rt_memset options */
/* rt_memcpy options */
/* end of rt_memcpy options */
/* rt_memmove options */
/* end of rt_memmove options */
/* rt_memcmp options */
/* end of rt_memcmp options */
/* rt_strstr options */
/* end of rt_strstr options */
/* rt_strcasecmp options */
/* end of rt_strcasecmp options */
/* rt_strncpy options */
/* end of rt_strncpy options */
/* rt_strcpy options */
/* end of rt_strcpy options */
/* rt_strncmp options */
/* end of rt_strncmp options */
/* rt_strcmp options */
/* end of rt_strcmp options */
/* rt_strlen options */
/* end of rt_strlen options */
/* rt_strnlen options */
/* end of rt_strnlen options */
/* end of klibc options */
#define RT_NAME_MAX 8
#define RT_CPUS_NR 1
#define RT_ALIGN_SIZE 8
#define RT_THREAD_PRIORITY_32
#define RT_THREAD_PRIORITY_MAX 32
#define RT_TICK_PER_SECOND 1000
#define RT_USING_OVERFLOW_CHECK
#define RT_USING_HOOK
#define RT_HOOK_USING_FUNC_PTR
#define RT_USING_IDLE_HOOK
#define RT_IDLE_HOOK_LIST_SIZE 4
#define IDLE_THREAD_STACK_SIZE 256
#define RT_USING_TIMER_SOFT
#define RT_TIMER_THREAD_PRIO 4
#define RT_TIMER_THREAD_STACK_SIZE 1024
/* kservice options */
/* end of kservice options */
#define RT_USING_DEBUG
#define RT_DEBUGING_ASSERT
#define RT_DEBUGING_COLOR
#define RT_DEBUGING_CONTEXT
/* Inter-Thread communication */
#define RT_USING_SEMAPHORE
#define RT_USING_MUTEX
#define RT_USING_EVENT
#define RT_USING_MAILBOX
#define RT_USING_MESSAGEQUEUE
/* end of Inter-Thread communication */
/* Memory Management */
#define RT_USING_MEMPOOL
#define RT_USING_SMALL_MEM
#define RT_USING_SMALL_MEM_AS_HEAP
#define RT_USING_HEAP
/* end of Memory Management */
#define RT_USING_DEVICE
#define RT_USING_CONSOLE
#define RT_CONSOLEBUF_SIZE 128
#define RT_CONSOLE_DEVICE_NAME "uart0"
#define RT_VER_NUM 0x50201
#define RT_BACKTRACE_LEVEL_MAX_NR 32
/* end of RT-Thread Kernel */
#define ARCH_RISCV
#define ARCH_RISCV32
/* RT-Thread Components */
#define RT_USING_COMPONENTS_INIT
#define RT_USING_USER_MAIN
#define RT_MAIN_THREAD_STACK_SIZE 2048
#define RT_MAIN_THREAD_PRIORITY 10
#define RT_USING_MSH
#define RT_USING_FINSH
#define FINSH_USING_MSH
#define FINSH_THREAD_NAME "tshell"
#define FINSH_THREAD_PRIORITY 20
#define FINSH_THREAD_STACK_SIZE 4096
#define FINSH_USING_HISTORY
#define FINSH_HISTORY_LINES 5
#define FINSH_USING_SYMTAB
#define FINSH_CMD_SIZE 80
#define MSH_USING_BUILT_IN_COMMANDS
#define FINSH_USING_DESCRIPTION
#define FINSH_ARG_MAX 10
#define FINSH_USING_OPTION_COMPLETION
/* DFS: device virtual file system */
#define RT_USING_DFS
#define DFS_USING_POSIX
#define DFS_USING_WORKDIR
#define DFS_FD_MAX 16
#define RT_USING_DFS_V1
#define DFS_FILESYSTEMS_MAX 4
#define DFS_FILESYSTEM_TYPES_MAX 4
#define RT_USING_DFS_DEVFS
/* end of DFS: device virtual file system */
/* Device Drivers */
#define RT_USING_DEVICE_IPC
#define RT_UNAMED_PIPE_NUMBER 64
#define RT_USING_SERIAL
#define RT_USING_SERIAL_V1
#define RT_SERIAL_USING_DMA
#define RT_SERIAL_RB_BUFSZ 64
#define RT_USING_PIN
/* end of Device Drivers */
/* C/C++ and POSIX layer */
/* ISO-ANSI C layer */
/* Timezone and Daylight Saving Time */
#define RT_LIBC_USING_LIGHT_TZ_DST
#define RT_LIBC_TZ_DEFAULT_HOUR 8
#define RT_LIBC_TZ_DEFAULT_MIN 0
#define RT_LIBC_TZ_DEFAULT_SEC 0
/* end of Timezone and Daylight Saving Time */
/* end of ISO-ANSI C layer */
/* POSIX (Portable Operating System Interface) layer */
/* Interprocess Communication (IPC) */
/* Socket is in the 'Network' category */
/* end of Interprocess Communication (IPC) */
/* end of POSIX (Portable Operating System Interface) layer */
/* end of C/C++ and POSIX layer */
/* Network */
/* end of Network */
/* Memory protection */
/* end of Memory protection */
/* Utilities */
/* end of Utilities */
/* Using USB legacy version */
/* end of Using USB legacy version */
/* end of RT-Thread Components */
/* RT-Thread Utestcases */
/* end of RT-Thread Utestcases */
/* RT-Thread online packages */
/* IoT - internet of things */
/* Wi-Fi */
/* Marvell WiFi */
/* end of Marvell WiFi */
/* Wiced WiFi */
/* end of Wiced WiFi */
/* CYW43012 WiFi */
/* end of CYW43012 WiFi */
/* BL808 WiFi */
/* end of BL808 WiFi */
/* CYW43439 WiFi */
/* end of CYW43439 WiFi */
/* end of Wi-Fi */
/* IoT Cloud */
/* end of IoT Cloud */
/* end of IoT - internet of things */
/* security packages */
/* end of security packages */
/* language packages */
/* JSON: JavaScript Object Notation, a lightweight data-interchange format */
/* end of JSON: JavaScript Object Notation, a lightweight data-interchange format */
/* XML: Extensible Markup Language */
/* end of XML: Extensible Markup Language */
/* end of language packages */
/* multimedia packages */
/* LVGL: powerful and easy-to-use embedded GUI library */
/* end of LVGL: powerful and easy-to-use embedded GUI library */
/* u8g2: a monochrome graphic library */
/* end of u8g2: a monochrome graphic library */
/* end of multimedia packages */
/* tools packages */
/* end of tools packages */
/* system packages */
/* enhanced kernel services */
/* end of enhanced kernel services */
/* acceleration: Assembly language or algorithmic acceleration packages */
/* end of acceleration: Assembly language or algorithmic acceleration packages */
/* CMSIS: ARM Cortex-M Microcontroller Software Interface Standard */
/* end of CMSIS: ARM Cortex-M Microcontroller Software Interface Standard */
/* Micrium: Micrium software products porting for RT-Thread */
/* end of Micrium: Micrium software products porting for RT-Thread */
/* end of system packages */
/* peripheral libraries and drivers */
/* HAL & SDK Drivers */
/* STM32 HAL & SDK Drivers */
/* end of STM32 HAL & SDK Drivers */
/* Infineon HAL Packages */
/* end of Infineon HAL Packages */
/* Kendryte SDK */
/* end of Kendryte SDK */
/* WCH HAL & SDK Drivers */
/* end of WCH HAL & SDK Drivers */
/* AT32 HAL & SDK Drivers */
/* end of AT32 HAL & SDK Drivers */
/* HC32 DDL Drivers */
/* end of HC32 DDL Drivers */
/* NXP HAL & SDK Drivers */
/* end of NXP HAL & SDK Drivers */
/* NUVOTON Drivers */
/* end of NUVOTON Drivers */
/* GD32 Drivers */
/* end of GD32 Drivers */
/* end of HAL & SDK Drivers */
/* sensors drivers */
/* end of sensors drivers */
/* touch drivers */
/* end of touch drivers */
/* end of peripheral libraries and drivers */
/* AI packages */
/* end of AI packages */
/* Signal Processing and Control Algorithm Packages */
/* end of Signal Processing and Control Algorithm Packages */
/* miscellaneous packages */
/* project laboratory */
/* end of project laboratory */
/* samples: kernel and components samples */
/* end of samples: kernel and components samples */
/* entertainment: terminal games and other interesting software packages */
/* end of entertainment: terminal games and other interesting software packages */
/* end of miscellaneous packages */
/* Arduino libraries */
/* Projects and Demos */
/* end of Projects and Demos */
/* Sensors */
/* end of Sensors */
/* Display */
/* end of Display */
/* Timing */
/* end of Timing */
/* Data Processing */
/* end of Data Processing */
/* Data Storage */
/* Communication */
/* end of Communication */
/* Device Control */
/* end of Device Control */
/* Other */
/* end of Other */
/* Signal IO */
/* end of Signal IO */
/* Uncategorized */
/* end of Arduino libraries */
/* end of RT-Thread online packages */
/* Hardware Drivers Config */
#define SOC_XUANTIE
/* On-chip Peripheral Drivers */
#define BSP_USING_UART
#define BSP_USING_UART0
/* end of On-chip Peripheral Drivers */
/* end of Hardware Drivers Config */
#endif

View File

@@ -1,98 +0,0 @@
import os
ARCH = 'risc-v'
CPU = 'e901'
# toolchains options
CROSS_TOOL = 'gcc'
#------- toolchains path -------------------------------------------------------
if os.getenv('RTT_CC'):
CROSS_TOOL = os.getenv('RTT_CC')
if CROSS_TOOL == 'gcc':
PLATFORM = 'gcc'
EXEC_PATH = r'D:\C-Sky\CDKRepo\Toolchain\XTGccElfNewlib\V3.2.0\R\bin'
else:
print('Please make sure your toolchains is GNU GCC!')
exit(0)
if os.getenv('RTT_EXEC_PATH'):
EXEC_PATH = os.getenv('RTT_EXEC_PATH')
BUILD = 'debug'
#BUILD = 'release'
CORE = 'risc-v'
MAP_FILE = 'rtthread.map'
LINK_FILE = '../../libraries/xuantie_libraries/chip_riscv_dummy/gcc_flash_smartl_lite.ld'
if os.path.exists('./libraries'):
LINK_FILE = './libraries/xuantie_libraries/chip_riscv_dummy/gcc_flash_smartl_lite.ld'
TARGET_NAME = 'rtthread.bin'
#------- GCC settings ----------------------------------------------------------
if PLATFORM == 'gcc':
# toolchains
PREFIX = 'riscv64-unknown-elf-'
CC = PREFIX + 'gcc'
CXX= PREFIX + 'g++'
AS = PREFIX + 'gcc'
AR = PREFIX + 'ar'
LINK = PREFIX + 'gcc'
TARGET_EXT = 'elf'
SIZE = PREFIX + 'size'
OBJDUMP = PREFIX + 'objdump'
OBJCPY = PREFIX + 'objcopy'
MCPU = ' -mcpu=e901plusbm-cp ' # Modify here based on CPU architecture.
MCPU_DEFINE = ' -DCONFIG_CPU_XUANTIE_E901PLUS_BM_CP=1 ' # Modify here based on CPU architecture.
DEVICE = MCPU + MCPU_DEFINE + ' -Wno-main -mcmodel=medany'
GLOBAL_DEFINES = (
'-DCONFIG_KERNEL_RTTHREAD=1 '
'-D__RT_KERNEL_SOURCE__=1 '
'-DCONFIG_CSI_V2=1 '
'-DCONFIG_CSI=csi2 '
'-DCONFIG_INIT_TASK_STACK_SIZE=4096 '
'-DCONFIG_APP_TASK_STACK_SIZE=8192 '
'-DCONFIG_ARCH_MAINSTACK=4096 '
'-DCONFIG_ARCH_INTERRUPTSTACK=4096 '
'-DCONFIG_XIP=1 '
'-DCONFIG_LIBC_MINI_PRINTF_SUPPORT=1 '
'-DCONFIG_SYSTICK_HZ=100 '
'-DCONFIG_BOARD_SMARTL_EVB=1 '
'-DCONFIG_DEBUG=1 '
'-DCLI_CONFIG_STACK_SIZE=4096 '
)
CFLAGS = DEVICE + ' -g -Wall -Wno-unused-function -Wformat -Wformat-security -Warray-bounds -Wuninitialized \
-Wreturn-type -Wcomment -Wswitch -Wparentheses -specs=minilibc.specs -MP -MMD -Os -Wpointer-arith \
-Wno-undef -ffunction-sections -fdata-sections -fno-inline-functions -fno-builtin \
-fno-strict-aliasing -Wno-char-subscripts -Wno-unused-but-set-variable ' + GLOBAL_DEFINES
AFLAGS = DEVICE + ' -g -Wall -Wno-unused-function -Wformat -Wformat-security -Warray-bounds -Wuninitialized \
-Wreturn-type -Wcomment -Wswitch -Wparentheses -specs=minilibc.specs -MP -MMD -Os -Wpointer-arith \
-Wno-undef -ffunction-sections -fdata-sections -fno-inline-functions -fno-builtin \
-fno-strict-aliasing -Wno-char-subscripts -Wno-unused-but-set-variable ' + ' -MP -MMD -D"Default_IRQHandler=SW_handler" ' + GLOBAL_DEFINES
LFLAGS = DEVICE + ' -MP -MMD -Wl,-zmax-page-size=1024 -Wl,-Map=yoc.map -Wl,-zmax-page-size=1024 -Wl,-Map=yoc.map -Wl,--whole-archive -Wl,--no-whole-archive -specs=minilibc.specs -nostartfiles -Wl,--gc-sections '
LFLAGS += ' -T ' + LINK_FILE
CPATH = ''
LPATH = ''
if BUILD == 'debug':
CFLAGS += ' -Os -g3'
AFLAGS += ' -g3'
else:
CFLAGS += ' -O2 -g2'
CXXFLAGS = CFLAGS
POST_ACTION = OBJCPY + ' -O binary $TARGET ' + TARGET_NAME + '\n'
POST_ACTION += SIZE + ' $TARGET\n'
def dist_handle(BSP_ROOT, dist_dir):
import sys
cwd_path = os.getcwd()
sys.path.append(os.path.join(os.path.dirname(BSP_ROOT), '../tools'))
from sdk_dist import dist_do_building
dist_do_building(BSP_ROOT, dist_dir)

View File

@@ -1,250 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Project Name="xuantie_rtthread" Version="1" Language="C">
<Description/>
<Dependencies Name="Debug"/>
<VendorInfo>
<VendorName>new_psf_project_SmartL_E906FD-R2S2(V1.7.9)</VendorName>
</VendorInfo>
<ToolsConfig>
<Compiler>
<Name>XTGccElfNewlib</Name>
<Version>latest</Version>
</Compiler>
</ToolsConfig>
<DebugSessions>
<watchExpressions/>
<memoryExpressions>;;;</memoryExpressions>
<statistics>;;MHZ</statistics>
<peripheralTabs/>
<WatchDisplayFormat/>
<LocalDisplayFormat/>
<debugLayout/>
<memoryTabColSizeExpressions/>
<QuickWatchDisplayFormat/>
</DebugSessions>
<BuildConfigs>
<BuildConfig Name="BuildSet">
<Target>
<ROMBank Selected="1">
<ROM1>
<InUse>no</InUse>
<Start/>
<Size/>
</ROM1>
<ROM2>
<InUse>no</InUse>
<Start/>
<Size/>
</ROM2>
<ROM3>
<InUse>no</InUse>
<Start/>
<Size/>
</ROM3>
<ROM4>
<InUse>no</InUse>
<Start/>
<Size/>
</ROM4>
<ROM5>
<InUse>no</InUse>
<Start/>
<Size/>
</ROM5>
</ROMBank>
<RAMBank>
<RAM1>
<InUse>no</InUse>
<Start/>
<Size/>
<Init>yes</Init>
</RAM1>
<RAM2>
<InUse>no</InUse>
<Start/>
<Size/>
<Init>yes</Init>
</RAM2>
<RAM3>
<InUse>no</InUse>
<Start/>
<Size/>
<Init>yes</Init>
</RAM3>
<RAM4>
<InUse>no</InUse>
<Start/>
<Size/>
<Init>yes</Init>
</RAM4>
<RAM5>
<InUse>no</InUse>
<Start/>
<Size/>
<Init>yes</Init>
</RAM5>
</RAMBank>
<CPU>e901plusbm-cp</CPU>
<UseMiniLib>yes</UseMiniLib>
<Endian>little</Endian>
<UseHardFloat>no</UseHardFloat>
<UseEnhancedLRW>no</UseEnhancedLRW>
<UseContinueBuild>no</UseContinueBuild>
<ToolchainID/>
<ToolchainVersion/>
<UseSemiHost>no</UseSemiHost>
</Target>
<Output>
<OutputName>$(ProjectName)</OutputName>
<Type>Executable</Type>
<CreateHexFile>no</CreateHexFile>
<CreateBinFile>no</CreateBinFile>
<Preprocessor>no</Preprocessor>
<Disassmeble>yes</Disassmeble>
<CallGraph>no</CallGraph>
<Map>no</Map>
</Output>
<User>
<BeforeCompile>
<RunUserProg>no</RunUserProg>
<UserProgName/>
<IsBatchScript>no</IsBatchScript>
</BeforeCompile>
<BeforeMake>
<RunUserProg>no</RunUserProg>
<UserProgName/>
<IsBatchScript>no</IsBatchScript>
</BeforeMake>
<AfterMake>
<RunUserProg>no</RunUserProg>
<UserProgName/>
<IsBatchScript>no</IsBatchScript>
</AfterMake>
<Tools/>
</User>
<Compiler>
<Define/>
<Undefine/>
<Optim>Optimize size (-Os)</Optim>
<DebugLevel>Maximum (-g3)</DebugLevel>
<IncludePath>$(ProjectPath);$(ProjectPath)/../../../../../csi_core/include;$(ProjectPath)/../../../../../csi_driver/include;$(ProjectPath)/../../../../../libs/include;$(ProjectPath)/../../../../../csi_driver/smartl_rv32/include;$(ProjectPath)/../../../../../csi_kernel/include;$(ProjectPath)/../../../../../csi_kernel/freertosv10.3.1/include/;$(ProjectPath)/../../../../../csi_kernel/freertosv10.3.1/FreeRTOS/Source/include;$(ProjectPath)/../../../../../csi_kernel/freertosv10.3.1/FreeRTOS/Source/portable/GCC/riscv;$(ProjectPath)/../../../../../csi_kernel/freertosv10.3.1/FreeRTOS/Source/portable/GCC/riscv/chip_specific_extensions/thead_rv32;$(ProjectPath)/../../../../../board/smartl_e906_evb/include;$(ProjectPath)/../../../../../projects/tests/dtest/include;$(ProjectPath)/../../../../../projects/tests/kernel/include;;;;;;;$(ProjectPath)/../../../../../projects/tests/kernel/freertos/configs</IncludePath>
<OtherFlags>-ffunction-sections -fdata-sections</OtherFlags>
<Verbose>no</Verbose>
<Ansi>no</Ansi>
<Syntax>no</Syntax>
<Pedantic>no</Pedantic>
<PedanticErr>no</PedanticErr>
<InhibitWarn>no</InhibitWarn>
<AllWarn>yes</AllWarn>
<WarnErr>no</WarnErr>
<OneElfS>yes</OneElfS>
<OneElfSPerData>no</OneElfSPerData>
<Fstrict>no</Fstrict>
</Compiler>
<Asm>
<Define/>
<Undefine/>
<IncludePath/>
<OtherFlags>-D"Default_IRQHandler=SW_handler"</OtherFlags>
<DebugLevel>gdwarf2</DebugLevel>
</Asm>
<Linker>
<Garbage>yes</Garbage>
<Garbage2>yes</Garbage2>
<LDFile>$(ProjectPath)/../../libraries/xuantie_libraries/chip_riscv_dummy/gcc_flash_smartl.ld</LDFile>
<LibName>m</LibName>
<LibPath/>
<OtherFlags>-Wl,-zmax-page-size=1024</OtherFlags>
<AutoLDFile>no</AutoLDFile>
<LinkType/>
<IncludeAllLibs>no</IncludeAllLibs>
<LinkSpecsType>none</LinkSpecsType>
<LinkUseNewlibNano>no</LinkUseNewlibNano>
<LinkUseMinilibc>no</LinkUseMinilibc>
</Linker>
<Debug>
<LoadApplicationAtStartup>yes</LoadApplicationAtStartup>
<Connector>SIM</Connector>
<StopAt>yes</StopAt>
<StopAtText>main</StopAtText>
<InitFile>$(ProjectPath)/utilities/gdb.init</InitFile>
<PreInit/>
<AfterLoadFile/>
<AutoRun>yes</AutoRun>
<ResetType>Hard Reset</ResetType>
<SoftResetVal>0</SoftResetVal>
<ResetAfterLoad>no</ResetAfterLoad>
<AfterResetFile/>
<Dumpcore>no</Dumpcore>
<DumpcoreText/>
<SVCFile/>
<ConfigICE>
<IP>localhost</IP>
<PORT>1025</PORT>
<CPUNumber>0</CPUNumber>
<Clock>12000</Clock>
<Delay>10</Delay>
<NResetDelay>100</NResetDelay>
<WaitReset>50</WaitReset>
<DDC>yes</DDC>
<TRST>no</TRST>
<PreReset>no</PreReset>
<DebugPrint>no</DebugPrint>
<Connect>Normal</Connect>
<ResetType>soft</ResetType>
<SoftResetVal>0</SoftResetVal>
<RTOSType>None</RTOSType>
<DownloadToFlash>no</DownloadToFlash>
<ResetAfterConnect>yes</ResetAfterConnect>
<GDBName/>
<GDBServerType>Local</GDBServerType>
<OtherFlags/>
<ICEEnablePCSampling>no</ICEEnablePCSampling>
<ICESamplingFreq>1000</ICESamplingFreq>
<RemoteICEEnablePCSampling>no</RemoteICEEnablePCSampling>
<RemoteICESamplingPort>1026</RemoteICESamplingPort>
<Version>latest</Version>
<SupportRemoteICEAsyncDebug>no</SupportRemoteICEAsyncDebug>
</ConfigICE>
<ConfigSIM>
<SIMTarget>soccfg/riscv32/smartl_e901_cfg.xml</SIMTarget>
<OtherFlags/>
<NoGraphic>yes</NoGraphic>
<Log>no</Log>
<SimTrace>no</SimTrace>
<Version>latest</Version>
</ConfigSIM>
<ConfigOpenOCD>
<OpenOCDExecutablePath/>
<OpenOCDLocally>yes</OpenOCDLocally>
<OpenOCDTelnetPortEnable>no</OpenOCDTelnetPortEnable>
<OpenOCDTelnetPort>4444</OpenOCDTelnetPort>
<OpenOCDTclPortEnable>no</OpenOCDTclPortEnable>
<OpenOCDTclPort>6666</OpenOCDTclPort>
<OpenOCDConfigOptions/>
<OpenOCDTimeout>5000</OpenOCDTimeout>
<OpenOCDRemoteIP>localhost</OpenOCDRemoteIP>
<OpenOCDRemotePort>3333</OpenOCDRemotePort>
<PluginID>openocd-sifive</PluginID>
<Version>latest</Version>
</ConfigOpenOCD>
</Debug>
<Flash>
<InitFile>$(ProjectPath)/../../../../../utilities//flash.init</InitFile>
<PreInit/>
<Erase>Erase Sectors</Erase>
<Algorithms Path=""/>
<Program>yes</Program>
<Verify>no</Verify>
<ResetAndRun>no</ResetAndRun>
<ResetType/>
<SoftResetVal/>
<FlashIndex>no</FlashIndex>
<FlashIndexVal>0</FlashIndexVal>
<External>no</External>
<Command/>
<Arguments/>
</Flash>
</BuildConfig>
</BuildConfigs>
</Project>

View File

@@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<CDK_Workspace Name="template" Database="LanguageSever" DoubleClick="Yes">
<DefaultPackPath>$(CDKWS)\__workspace_pack__</DefaultPackPath>
<Project Name="xuantie_rtthread" Path="template.cdkproj" RootPath="" Active="Yes"/>
<BuildMatrix>
<WorkspaceConfiguration Name="Debug" Selected="yes">
<Environment/>
<Project Name="xuantie_rtthread" ConfigName="BuildSet"/>
</WorkspaceConfiguration>
</BuildMatrix>
</CDK_Workspace>

View File

@@ -1,6 +0,0 @@
set *(int *)0x0=0x6f
si
reset
set *(int *)0x40011008=0x0
set *(int *)0x4001101c=0x0

View File

@@ -13,13 +13,13 @@
*/
/**
* @addtogroup cortex-m33
* @addtogroup cortex-m4
*/
/*@{*/
#include <rtconfig.h>
.cpu cortex-m33
.cpu cortex-m4
.syntax unified
.thumb
.text

View File

@@ -1,135 +0,0 @@
#!/usr/bin/env python3
import json
import os
from datetime import datetime, timedelta
from typing import List, Dict, Any
def load_monitoring_results() -> List[Dict[str, Any]]:
"""加载 monitoring_results.json"""
if not os.path.exists("monitoring_results.json"):
print("No monitoring results found")
return []
try:
with open("monitoring_results.json", "r", encoding="utf-8") as f:
return json.load(f)
except (json.JSONDecodeError, OSError) as e:
print(f"Error loading monitoring_results.json: {e}")
return []
def get_beijing_time() -> datetime:
return datetime.utcnow() + timedelta(hours=8)
def format_time(dt: datetime) -> str:
return dt.strftime("%Y-%m-%d %H:%M")
def classify_error(step_name: str, job_name: str) -> str:
"""错误类型分类"""
step_lower = step_name.lower()
if any(x in step_lower for x in ["test", "suite", "pytest", "unittest"]):
return "TEST_FAILURE"
if "lint" in step_lower or "flake8" in step_lower:
return "LINT_ERROR"
if "build" in step_lower or "compile" in step_lower:
return "BUILD_ERROR"
if "deploy" in step_lower or "upload" in step_lower or "publish" in step_lower:
return "DEPLOY_ERROR"
if "check" in step_lower or "validate" in step_lower or "verify" in step_lower:
return "VALIDATION_ERROR"
if "generate" in step_lower or "render" in step_lower:
return "GENERATION_ERROR"
return "UNKNOWN"
def generate_report():
"""生成符合最新样式的故障聚合报告"""
results = load_monitoring_results()
if not results:
return
failed_workflows = [r for r in results if r.get('conclusion') == 'failure']
if not failed_workflows:
print("No failed workflows to report")
return
now = get_beijing_time()
date_str = now.strftime("%Y%m%d")
# 时间范围
created_times = [
datetime.fromisoformat(r["created_at"].replace("Z", "+00:00")) + timedelta(hours=8)
for r in failed_workflows
]
updated_times = [
datetime.fromisoformat(r["updated_at"].replace("Z", "+00:00")) + timedelta(hours=8)
for r in failed_workflows
]
start_time = min(created_times)
end_time = max(updated_times)
total = len(results)
failed_count = len(failed_workflows)
success_rate = 0.0 if total == 0 else round((total - failed_count) / total * 100, 1)
# === 第一行:用于 JS 提取标题(必须)===
report = f"# {date_str}_ci_integration-failed-report\n\n"
# === 第二行用户看到的主标题H1===
report += f"# 🚨 {date_str} GitHub Actions 故障聚合报告 | Incident Aggregate Report\n\n"
# === 执行概览 ===
report += f"## 执行概览 | Executive Summary\n"
report += f"- **监控时间范围 | Monitoring Period**: {format_time(start_time)}{format_time(end_time)} (UTC+8)\n"
report += f"- **检测到失败运行 | Failed Runs Detected**: {failed_count}\n"
report += f"- **成功率 | Success Rate**: {success_rate}% \n\n"
# === 故障详情 ===
report += f"## 🔍 故障详情 | Failure Details\n\n"
for wf in failed_workflows:
run_id = wf.get("run_id", "N/A")
name = wf["name"]
html_url = wf.get("html_url", "#")
details = wf.get("failure_details", [])
report += f"**📌 Run-{run_id}** | [{name}]({html_url})\n"
if not details:
report += "└─ 无失败作业详情 | No details of failed jobs\n\n"
continue
failed_jobs = [j for j in details if j.get("steps")]
for i, job in enumerate(failed_jobs):
job_name = job["name"]
steps = job["steps"]
job_prefix = "└─" if i == len(failed_jobs) - 1 else "├─"
report += f"{job_prefix} **失败作业 | Failed Job**: {job_name}\n"
for j, step in enumerate(steps):
step_name = step["name"]
step_num = step["number"]
error_type = classify_error(step_name, job_name)
step_prefix = " └─" if j == len(steps) - 1 else " ├─"
report += f"{step_prefix} **失败步骤 | Failed Step**: {step_name} (Step {step_num})\n"
indent = " " if j == len(steps) - 1 else ""
report += f"{indent}**错误类型 | Error Type**: `{error_type}`\n"
report += "\n"
# === Team Collaboration & Support ===
report += f"## 👥 团队协作与支持 | Team Collaboration & Support\n\n"
report += f"请求维护支持本报告需要RT-Thread官方团队的专业经验进行审核与指导。 \n"
report += f"Call for Maintenance Support: This report requires the expertise of the RT-Thread official team for review and guidance.\n\n"
report += f"提审负责人:@Rbb666 @kurisaW\n"
report += f"Requested Reviewers from RT-Thread: @Rbb666 @kurisaW\n\n"
report += f"烦请尽快关注此事,万分感谢。 \n"
report += f"Your prompt attention to this matter is greatly appreciated.\n"
# 保存
try:
with open("failure_details.md", "w", encoding="utf-8") as f:
f.write(report.rstrip() + "\n")
print("Report generated: failure_details.md")
print(f"Report size: {os.path.getsize('failure_details.md')} bytes")
except Exception as e:
print(f"Error writing report: {e}")
if __name__ == "__main__":
generate_report()

View File

@@ -1,227 +0,0 @@
#!/usr/bin/env python3
import os
import json
import requests
import time
import sys
from datetime import datetime, timezone
def monitor_workflows(github_token, repo, workflow_names, start_time):
"""监控工作流运行"""
headers = {
"Authorization": f"token {github_token}",
"Accept": "application/vnd.github.v3+json"
}
monitoring_results = []
for workflow_name in workflow_names:
print(f"\n=== Monitoring {workflow_name} ===")
try:
workflow_id = get_workflow_id(github_token, repo, workflow_name)
if not workflow_id:
monitoring_results.append({
"name": workflow_name,
"status": "error",
"conclusion": "error",
"error": "Workflow not found"
})
continue
# 查找开始时间后的运行
runs = get_recent_runs(github_token, repo, workflow_id, start_time)
if not runs:
print(f"No runs found for {workflow_name} after {start_time}")
# 尝试查找任何正在运行的工作流
all_runs = get_all_runs(github_token, repo, workflow_id, 10)
if all_runs:
latest_run = all_runs[0]
print(f"Using latest run instead: {latest_run['id']} created at {latest_run['created_at']}")
result = monitor_single_run(github_token, repo, latest_run["id"], workflow_name)
monitoring_results.append(result)
else:
monitoring_results.append({
"name": workflow_name,
"status": "not_found",
"conclusion": "not_found",
"error": f"No runs found after {start_time}"
})
else:
# 监控找到的运行
run_to_monitor = runs[0] # 取最新的一个
print(f"Monitoring run: {run_to_monitor['id']}")
result = monitor_single_run(github_token, repo, run_to_monitor["id"], workflow_name)
monitoring_results.append(result)
except Exception as e:
print(f"Error monitoring {workflow_name}: {str(e)}")
monitoring_results.append({
"name": workflow_name,
"status": "error",
"conclusion": "error",
"error": str(e)
})
return monitoring_results
def get_all_runs(github_token, repo, workflow_id, per_page=10):
"""获取所有运行"""
headers = {
"Authorization": f"token {github_token}",
"Accept": "application/vnd.github.v3+json"
}
url = f"https://api.github.com/repos/{repo}/actions/workflows/{workflow_id}/runs"
params = {"per_page": per_page}
response = requests.get(url, headers=headers, params=params)
if response.status_code == 200:
return response.json()["workflow_runs"]
return []
def get_recent_runs(github_token, repo, workflow_id, start_time):
"""获取开始时间后的运行"""
all_runs = get_all_runs(github_token, repo, workflow_id, 10)
start_time_dt = datetime.fromisoformat(start_time.replace('Z', '+00:00'))
recent_runs = []
for run in all_runs:
run_time = datetime.fromisoformat(run["created_at"].replace('Z', '+00:00'))
if run_time >= start_time_dt:
recent_runs.append(run)
return recent_runs
def monitor_single_run(github_token, repo, run_id, workflow_name):
"""监控单个运行"""
headers = {
"Authorization": f"token {github_token}",
"Accept": "application/vnd.github.v3+json"
}
max_wait_time = 1800 # 30分钟
check_interval = 30
start_time = time.time()
print(f"Monitoring {workflow_name} (run {run_id})")
while time.time() - start_time < max_wait_time:
url = f"https://api.github.com/repos/{repo}/actions/runs/{run_id}"
response = requests.get(url, headers=headers)
if response.status_code != 200:
print(f"Error getting run status: {response.status_code}")
time.sleep(check_interval)
continue
run_data = response.json()
status = run_data["status"]
conclusion = run_data.get("conclusion")
print(f" {workflow_name}: status={status}, conclusion={conclusion}")
if status == "completed":
result = {
"name": workflow_name,
"run_id": run_id,
"status": status,
"conclusion": conclusion,
"html_url": run_data["html_url"],
"created_at": run_data["created_at"],
"updated_at": run_data["updated_at"]
}
if conclusion == "failure":
result["failure_details"] = get_failure_logs(github_token, repo, run_id)
return result
time.sleep(check_interval)
# 超时
return {
"name": workflow_name,
"run_id": run_id,
"status": "timed_out",
"conclusion": "timed_out",
"html_url": f"https://github.com/{repo}/actions/runs/{run_id}",
"error": "Monitoring timed out after 30 minutes"
}
def get_failure_logs(github_token, repo, run_id):
"""获取失败日志"""
headers = {
"Authorization": f"token {github_token}",
"Accept": "application/vnd.github.v3+json"
}
try:
jobs_url = f"https://api.github.com/repos/{repo}/actions/runs/{run_id}/jobs"
jobs_response = requests.get(jobs_url, headers=headers)
failure_details = []
if jobs_response.status_code == 200:
jobs_data = jobs_response.json()["jobs"]
for job in jobs_data:
if job["conclusion"] == "failure":
job_info = {
"name": job["name"],
"steps": []
}
for step in job["steps"]:
if step["conclusion"] == "failure":
job_info["steps"].append({
"name": step["name"],
"number": step["number"]
})
failure_details.append(job_info)
return failure_details
except Exception as e:
print(f"Error getting failure logs: {e}")
return []
def get_workflow_id(github_token, repo, workflow_name):
"""获取工作流ID"""
headers = {
"Authorization": f"token {github_token}",
"Accept": "application/vnd.github.v3+json"
}
url = f"https://api.github.com/repos/{repo}/actions/workflows"
response = requests.get(url, headers=headers)
if response.status_code == 200:
workflows = response.json()["workflows"]
for workflow in workflows:
if workflow["name"] == workflow_name:
return workflow["id"]
return None
def main():
github_token = os.getenv("GITHUB_TOKEN")
repo = os.getenv("GITHUB_REPOSITORY")
workflows_json = os.getenv("TARGET_WORKFLOWS")
start_time = sys.argv[1] if len(sys.argv) > 1 else datetime.now(timezone.utc).isoformat()
if not all([github_token, repo, workflows_json]):
raise ValueError("Missing required environment variables")
workflows = json.loads(workflows_json)
results = monitor_workflows(github_token, repo, workflows, start_time)
with open("monitoring_results.json", "w") as f:
json.dump(results, f, indent=2)
print(f"\n=== Monitoring Summary ===")
for result in results:
status_icon = "" if result.get("conclusion") == "success" else "" if result.get("conclusion") == "failure" else "⚠️"
print(f"{status_icon} {result['name']}: {result.get('conclusion', 'unknown')}")
if __name__ == "__main__":
main()

View File

@@ -1 +0,0 @@
requests>=2.25.1

View File

@@ -1,98 +0,0 @@
#!/usr/bin/env python3
import os
import json
import requests
import time
from datetime import datetime, timezone
def trigger_workflow_directly(workflow_name, github_token, repo):
"""直接触发工作流"""
headers = {
"Authorization": f"token {github_token}",
"Accept": "application/vnd.github.v3+json"
}
# 首先获取工作流ID
workflow_id = get_workflow_id(github_token, repo, workflow_name)
if not workflow_id:
print(f"✗ Workflow '{workflow_name}' not found")
return False
# 使用 workflow_dispatch API 直接触发
dispatch_url = f"https://api.github.com/repos/{repo}/actions/workflows/{workflow_id}/dispatches" # 🔧 修复:添加这行
# 根据工作流实际定义的输入参数进行调整
dispatch_data = {
"ref": "master",
"inputs": {
"trigger_type": "scheduled" # 使用工作流实际定义的输入参数
}
}
try:
print(f"Triggering workflow: {workflow_name} (ID: {workflow_id})")
response = requests.post(dispatch_url, headers=headers, json=dispatch_data) # 🔧 修复:现在 dispatch_url 已定义
if response.status_code == 204:
print(f"✓ Successfully triggered workflow: {workflow_name}")
return True
else:
print(f"✗ Failed to trigger {workflow_name}: {response.status_code}")
print(f"Response: {response.text}")
return False
except Exception as e:
print(f"✗ Error triggering {workflow_name}: {str(e)}")
return False
def get_workflow_id(github_token, repo, workflow_name):
"""获取工作流ID"""
headers = {
"Authorization": f"token {github_token}",
"Accept": "application/vnd.github.v3+json"
}
url = f"https://api.github.com/repos/{repo}/actions/workflows"
response = requests.get(url, headers=headers)
if response.status_code == 200:
workflows = response.json()["workflows"]
for workflow in workflows:
if workflow["name"] == workflow_name:
return workflow["id"]
print(f"Available workflows: {[w['name'] for w in workflows]}")
else:
print(f"Failed to get workflows: {response.status_code}")
return None
def main():
github_token = os.getenv("GITHUB_TOKEN")
repo = os.getenv("GITHUB_REPOSITORY")
workflows_json = os.getenv("TARGET_WORKFLOWS")
if not all([github_token, repo, workflows_json]):
raise ValueError("Missing required environment variables")
try:
workflows = json.loads(workflows_json)
except json.JSONDecodeError:
raise ValueError("Invalid TARGET_WORKFLOWS JSON format")
print(f"Directly triggering {len(workflows)} workflows...")
success_count = 0
for i, workflow in enumerate(workflows):
success = trigger_workflow_directly(workflow, github_token, repo)
if success:
success_count += 1
# 在触发之间等待
if i < len(workflows) - 1:
print("Waiting 10 seconds before next trigger...")
time.sleep(10)
print(f"Triggering completed: {success_count}/{len(workflows)} successful")
if __name__ == "__main__":
main()

View File

@@ -1,113 +0,0 @@
#!/usr/bin/env python3
import os
import json
import requests
import time
import sys
from datetime import datetime, timezone
def wait_for_workflows_to_appear(github_token, repo, workflow_names, start_time, max_wait=300):
"""等待工作流出现在API中"""
headers = {
"Authorization": f"token {github_token}",
"Accept": "application/vnd.github.v3+json"
}
print(f"Waiting for {len(workflow_names)} workflows to appear...")
print(f"Start time: {start_time}")
print(f"Max wait time: {max_wait} seconds")
found_workflows = set()
start_timestamp = time.time()
while time.time() - start_timestamp < max_wait:
all_found = True
for workflow_name in workflow_names:
if workflow_name in found_workflows:
continue
workflow_id = get_workflow_id(github_token, repo, workflow_name)
if not workflow_id:
print(f"Workflow {workflow_name} not found, skipping")
found_workflows.add(workflow_name)
continue
# 检查是否有新的运行
runs = get_recent_runs(github_token, repo, workflow_id, start_time)
if runs:
print(f"✓ Found new run for {workflow_name}: {runs[0]['id']}")
found_workflows.add(workflow_name)
else:
print(f"⏳ Waiting for {workflow_name}...")
all_found = False
if all_found:
print("✓ All workflows have started!")
return True
time.sleep(10) # 每10秒检查一次
print("⚠️ Timeout waiting for workflows to appear")
print(f"Found {len(found_workflows)} out of {len(workflow_names)} workflows")
return False
def get_workflow_id(github_token, repo, workflow_name):
"""获取工作流ID"""
headers = {
"Authorization": f"token {github_token}",
"Accept": "application/vnd.github.v3+json"
}
url = f"https://api.github.com/repos/{repo}/actions/workflows"
response = requests.get(url, headers=headers)
if response.status_code == 200:
workflows = response.json()["workflows"]
for workflow in workflows:
if workflow["name"] == workflow_name:
return workflow["id"]
return None
def get_recent_runs(github_token, repo, workflow_id, start_time):
"""获取开始时间后的运行"""
headers = {
"Authorization": f"token {github_token}",
"Accept": "application/vnd.github.v3+json"
}
url = f"https://api.github.com/repos/{repo}/actions/workflows/{workflow_id}/runs"
params = {"per_page": 5}
response = requests.get(url, headers=headers, params=params)
if response.status_code != 200:
return []
runs = response.json()["workflow_runs"]
start_time_dt = datetime.fromisoformat(start_time.replace('Z', '+00:00'))
recent_runs = []
for run in runs:
run_time = datetime.fromisoformat(run["created_at"].replace('Z', '+00:00'))
if run_time >= start_time_dt:
recent_runs.append(run)
return recent_runs
def main():
github_token = os.getenv("GITHUB_TOKEN")
repo = os.getenv("GITHUB_REPOSITORY")
workflows_json = os.getenv("TARGET_WORKFLOWS")
start_time = sys.argv[1] if len(sys.argv) > 1 else datetime.now(timezone.utc).isoformat()
if not all([github_token, repo, workflows_json]):
raise ValueError("Missing required environment variables")
workflows = json.loads(workflows_json)
success = wait_for_workflows_to_appear(github_token, repo, workflows, start_time)
if not success:
print("Proceeding anyway, some workflows may not be detected...")
if __name__ == "__main__":
main()