-
Notifications
You must be signed in to change notification settings - Fork 80
Add esp32c3 support #334
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
xuchang-vivo
wants to merge
53
commits into
vivoblueos:main
Choose a base branch
from
xuchang-vivo:xc/seeed_xiao_esp32c3_support
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Add esp32c3 support #334
Changes from all commits
Commits
Show all changes
53 commits
Select commit
Hold shift + click to select a range
2f2ac22
minor
xuchang-vivo a4a5726
minor
xuchang-vivo 229657d
minor
xuchang-vivo 8fdac14
minor
xuchang-vivo 773b65f
laji
xuchang-vivo bec8df5
wip
xuchang-vivo 79313ee
minor
xuchang-vivo da54624
add intr
xuchang-vivo 9dcba33
minor
xuchang-vivo a35caa9
minor
xuchang-vivo 6b4a67b
minor
xuchang-vivo ed725e2
minor
xuchang-vivo 11f8bb4
del idf deps
xuchang-vivo 24072ac
add riscv kconfig
xuchang-vivo 01be4fc
set mie
xuchang-vivo 6a4215b
minor
xuchang-vivo 1f96ce1
minor
xuchang-vivo 6f9e74f
minor
xuchang-vivo 6af199b
minor
xuchang-vivo 9a25aec
minor
xuchang-vivo 0ed38ff
minor
xuchang-vivo 8ed7d18
minor
xuchang-vivo e7bf354
minor
xuchang-vivo 872dae0
minor
xuchang-vivo dbb6e7b
make fifo tx enable
xuchang-vivo 759b5d8
disable wdt
xuchang-vivo c4e85a2
add intc
xuchang-vivo a4f4938
minor
xuchang-vivo 38888e7
add copyright
xuchang-vivo b5391ff
add link.x
xuchang-vivo 072f41d
make mtime optional
xuchang-vivo 6baeada
minor
xuchang-vivo 81d96ff
Apply suggestion from @lawkai-vivo
lawkai-vivo f738d19
Update kconfig/config/seeed_xiao_esp32c3/debug/defconfig
lawkai-vivo 6f561e8
Update driver/src/systimer/esp32_sys_timer.rs
xuchang-vivo 44b2583
Update driver/src/systimer/esp32_sys_timer.rs
xuchang-vivo c9c20a2
add unittest_kernel
xuchang-vivo 85fce7b
fix bug
xuchang-vivo feda848
set unittest thread num options
xuchang-vivo 809776b
fix
xuchang-vivo 9275715
del unncessary logic
xuchang-vivo 9f46885
minor
xuchang-vivo 773d0a9
add check_all
xuchang-vivo 2e1f230
del kconfig.test
xuchang-vivo d9108ea
fix compile error
xuchang-vivo 6b35776
minor
xuchang-vivo bddf29a
minor
xuchang-vivo 09522fa
minor
xuchang-vivo e81d05f
Update driver/src/interrupt_controller/esp32_intc.rs
xuchang-vivo 66d42f2
Update driver/src/interrupt_controller/esp32_intc.rs
xuchang-vivo 8012b8c
Update driver/src/interrupt_controller/esp32_intc.rs
xuchang-vivo b974536
Update driver/src/interrupt_controller/esp32_intc.rs
xuchang-vivo 20170b7
fix
xuchang-vivo File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,84 @@ | ||
| // Copyright (c) 2026 vivo Mobile Communication Co., Ltd. | ||
| // | ||
| // 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. | ||
|
|
||
| use tock_registers::{ | ||
| interfaces::{ReadWriteable, Readable, Writeable}, | ||
| register_bitfields, register_structs, | ||
| registers::ReadWrite, | ||
| }; | ||
|
|
||
| use crate::{ | ||
| interrupt_controller::Interrupt, static_ref::StaticRef, | ||
| uart::esp32_usb_serial::JFIFO_ST_REG::OUT_FIFO_FULL, | ||
| }; | ||
|
|
||
| register_structs! { | ||
| pub IntcRegisters { | ||
| (0x000 => _reserved0), | ||
| (0x104 => cpu_int_enable_reg: ReadWrite<u32>), | ||
| (0x108 => _reserved1), | ||
| (0x118 => priority_reg: [ReadWrite<u32, PRIORITY_REG::Register>; 31]), | ||
| (0x194 => threshold_reg: ReadWrite<u32, THRESHOLD_REG::Register>), | ||
| (0x198 => @END), | ||
| } | ||
| } | ||
|
|
||
| register_bitfields! [ | ||
| u32, | ||
|
|
||
| pub PRIORITY_REG [ | ||
| PRIORITY OFFSET(0) NUMBITS(4) [], | ||
| ], | ||
|
|
||
| pub THRESHOLD_REG [ | ||
| THRESHOLD OFFSET(0) NUMBITS(4) [], | ||
| ], | ||
| ]; | ||
|
|
||
| pub struct Esp32Intc { | ||
| registers: StaticRef<IntcRegisters>, | ||
| } | ||
|
|
||
| impl Esp32Intc { | ||
| pub const fn new(base: usize) -> Self { | ||
| Self { | ||
| registers: unsafe { StaticRef::new(base as *const IntcRegisters) }, | ||
| } | ||
| } | ||
|
|
||
| pub fn allocate_irq(&self, irq: Interrupt) { | ||
| let mut map_reg = | ||
| self.registers.inner() as *const IntcRegisters as usize + irq.source_no * 4; | ||
| unsafe { | ||
| core::ptr::write_volatile(map_reg as *mut u32, irq.irq_no as u32); | ||
| } | ||
| } | ||
|
|
||
| pub fn enable_irq(&self, irq: Interrupt) { | ||
| let mut enable_reg = self.registers.cpu_int_enable_reg.get(); | ||
| enable_reg |= 1 << irq.irq_no; | ||
| self.registers.cpu_int_enable_reg.set(enable_reg); | ||
| } | ||
|
|
||
| pub fn set_priority(&self, irq: Interrupt, priority: u8) { | ||
| self.registers.priority_reg[(irq.irq_no - 1) as usize] | ||
| .write(PRIORITY_REG::PRIORITY.val(priority as u32)); | ||
| } | ||
|
|
||
| pub fn set_threshold(&self, threshold: u8) { | ||
| self.registers | ||
| .threshold_reg | ||
| .write(THRESHOLD_REG::THRESHOLD.val(threshold as u32)); | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| // Copyright (c) 2026 vivo Mobile Communication Co., Ltd. | ||
| // | ||
| // 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. | ||
|
|
||
| #[cfg(target_chip = "esp32c3")] | ||
| pub mod esp32_intc; | ||
|
|
||
| pub struct Interrupt { | ||
| pub(crate) source_no: usize, | ||
| pub(crate) irq_no: usize, | ||
| } | ||
|
|
||
| impl Interrupt { | ||
| pub const fn new(source_no: usize, irq_no: usize) -> Self { | ||
| Self { source_no, irq_no } | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,240 @@ | ||
| // Copyright (c) 2026 vivo Mobile Communication Co., Ltd. | ||
| // | ||
| // 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. | ||
|
|
||
| use blueos_hal::clock::Clock; | ||
| use tock_registers::{ | ||
| interfaces::{ReadWriteable, Readable, Writeable}, | ||
| register_bitfields, register_structs, | ||
| registers::ReadWrite, | ||
| }; | ||
|
|
||
| register_bitfields! [ | ||
| u32, | ||
|
|
||
| pub CONF [ | ||
| CLK_EN OFFSET(31) NUMBITS(1) [], | ||
| UNIT0_WORK_EN OFFSET(30) NUMBITS(1) [], | ||
| UNIT1_WORK_EN OFFSET(29) NUMBITS(1) [], | ||
| UNIT0_CORE0_STALL_EN OFFSET(28) NUMBITS(1) [], | ||
| UNIT1_CORE0_STALL_EN OFFSET(26) NUMBITS(1) [], | ||
| TARGET0_WORK_EN OFFSET(24) NUMBITS(1) [], | ||
| TARGET1_WORK_EN OFFSET(23) NUMBITS(1) [], | ||
| TARGET2_WORK_EN OFFSET(22) NUMBITS(1) [] | ||
| ], | ||
|
|
||
| pub UNIT_OP [ | ||
| UPDATE OFFSET(30) NUMBITS(1) [], | ||
| VALUE_VALID OFFSET(29) NUMBITS(1) [] | ||
| ], | ||
|
|
||
| pub UNIT_LOAD_HI [ | ||
| LOAD_HI OFFSET(0) NUMBITS(20) [] | ||
| ], | ||
|
|
||
| pub UNIT_LOAD_LO [ | ||
| LOAD_LO OFFSET(0) NUMBITS(32) [] | ||
| ], | ||
|
|
||
| pub UNIT_VALUE_HI [ | ||
| VALUE_HI OFFSET(0) NUMBITS(20) [] | ||
| ], | ||
|
|
||
| pub UNIT_VALUE_LO [ | ||
| VALUE_LO OFFSET(0) NUMBITS(32) [] | ||
| ], | ||
|
|
||
| pub UNIT_LOAD [ | ||
| LOAD OFFSET(0) NUMBITS(1) [] | ||
| ], | ||
|
|
||
| pub TARGET_HI [ | ||
| HI OFFSET(0) NUMBITS(20) [] | ||
| ], | ||
|
|
||
| pub TARGET_LO [ | ||
| LO OFFSET(0) NUMBITS(32) [] | ||
| ], | ||
|
|
||
| pub TARGET_CONF [ | ||
| PERIOD OFFSET(0) NUMBITS(26) [], | ||
| PERIOD_MODE OFFSET(30) NUMBITS(1) [], | ||
| TIMER_UNIT_SEL OFFSET(31) NUMBITS(1) [] | ||
| ], | ||
|
|
||
| pub COMP_LOAD [ | ||
| LOAD OFFSET(0) NUMBITS(1) [] | ||
| ], | ||
|
|
||
| pub INT_ENA [ | ||
| TARGET0 OFFSET(0) NUMBITS(1) [], | ||
| TARGET1 OFFSET(1) NUMBITS(1) [], | ||
| TARGET2 OFFSET(2) NUMBITS(1) [] | ||
| ], | ||
|
|
||
| pub INT_RAW [ | ||
| TARGET0 OFFSET(0) NUMBITS(1) [], | ||
| TARGET1 OFFSET(1) NUMBITS(1) [], | ||
| TARGET2 OFFSET(2) NUMBITS(1) [] | ||
| ], | ||
|
|
||
| pub INT_CLR [ | ||
| TARGET0 OFFSET(0) NUMBITS(1) [], | ||
| TARGET1 OFFSET(1) NUMBITS(1) [], | ||
| TARGET2 OFFSET(2) NUMBITS(1) [] | ||
| ], | ||
|
|
||
| pub INT_ST [ | ||
| TARGET0 OFFSET(0) NUMBITS(1) [], | ||
| TARGET1 OFFSET(1) NUMBITS(1) [], | ||
| TARGET2 OFFSET(2) NUMBITS(1) [] | ||
| ] | ||
| ]; | ||
|
|
||
| register_structs! { | ||
|
|
||
| Registers { | ||
| (0x00 => conf: ReadWrite<u32, CONF::Register>), | ||
| (0x04 => unit0_op: ReadWrite<u32, UNIT_OP::Register>), | ||
| (0x08 => _reserved0), | ||
| (0x0C => unit0_load_hi: ReadWrite<u32, UNIT_LOAD_HI::Register>), | ||
| (0x10 => unit0_load_lo: ReadWrite<u32, UNIT_LOAD_LO::Register>), | ||
| (0x14 => _reserved1), | ||
| (0x1C => target0_hi: ReadWrite<u32, TARGET_HI::Register>), | ||
| (0x20 => target0_lo: ReadWrite<u32, TARGET_LO::Register>), | ||
| (0x24 => _reserved2), | ||
| (0x34 => target0_conf: ReadWrite<u32, TARGET_CONF::Register>), | ||
| (0x38 => _reserved3), | ||
| (0x40 => unit0_value_hi: ReadWrite<u32, UNIT_VALUE_HI::Register>), | ||
| (0x44 => unit0_value_lo: ReadWrite<u32, UNIT_VALUE_LO::Register>), | ||
| (0x48 => _reserved4), | ||
| (0x50 => comp0_load: ReadWrite<u32, COMP_LOAD::Register>), | ||
| (0x54 => _reserved5), | ||
| (0x5C => unit0_load: ReadWrite<u32, UNIT_LOAD::Register>), | ||
| (0x60 => _reserved6), | ||
| (0x64 => int_ena: ReadWrite<u32, INT_ENA::Register>), | ||
| (0x68 => int_raw: ReadWrite<u32, INT_RAW::Register>), | ||
| (0x6C => int_clr: ReadWrite<u32, INT_CLR::Register>), | ||
| (0x70 => int_st: ReadWrite<u32, INT_ST::Register>), | ||
| (0x74 => @END), | ||
| } | ||
| } | ||
|
|
||
| /// FIXME: Only Supports Timer Unit 0 for now | ||
| pub struct Esp32SysTimer<const BASE_ADDR: usize, const HZ: u64>; | ||
|
|
||
| impl<const BASE_ADDR: usize, const HZ: u64> Esp32SysTimer<BASE_ADDR, HZ> { | ||
| fn registers() -> &'static Registers { | ||
| unsafe { &*(BASE_ADDR as *const Registers) } | ||
| } | ||
|
|
||
| fn enable_interrupt(enable: bool) { | ||
| Self::registers().int_ena.modify(if enable { | ||
| INT_ENA::TARGET0::SET | ||
| } else { | ||
| INT_ENA::TARGET0::CLEAR | ||
| }); | ||
| } | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we have to implement a specific sys_timer for Esp32? Is there a generic abstract design implementation for different boards? |
||
|
|
||
| pub fn init() { | ||
| // enable unit 0 | ||
| Self::registers().conf.modify(CONF::CLK_EN::SET); | ||
| Self::registers().conf.modify(CONF::UNIT0_WORK_EN::SET); | ||
| Self::registers().conf.modify(CONF::TARGET0_WORK_EN::CLEAR); | ||
| // select unit 0 vs comparator 0 | ||
| Self::set_unit(); | ||
| // CLR interrupt | ||
| Self::registers().int_clr.modify(INT_CLR::TARGET0::SET); | ||
| // disable comparator | ||
| Self::set_comparator_enable(false); | ||
| // enable interrupt | ||
| Self::enable_interrupt(true); | ||
| // set TARGET mode | ||
| Self::registers() | ||
| .target0_conf | ||
| .modify(TARGET_CONF::PERIOD_MODE::CLEAR); | ||
| } | ||
|
|
||
| #[inline] | ||
| pub fn clear_interrupt() { | ||
| Self::registers().int_clr.modify(INT_CLR::TARGET0::SET); | ||
| } | ||
|
|
||
| fn set_unit() { | ||
| Self::registers() | ||
| .target0_conf | ||
| .modify(TARGET_CONF::TIMER_UNIT_SEL::CLEAR); | ||
| } | ||
|
|
||
| pub fn set_comparator_enable(enable: bool) { | ||
| Self::registers().conf.modify(if enable { | ||
| CONF::TARGET0_WORK_EN::SET | ||
| } else { | ||
| CONF::TARGET0_WORK_EN::CLEAR | ||
| }); | ||
| } | ||
| } | ||
|
|
||
| impl<const BASE_ADDR: usize, const HZ: u64> Clock for Esp32SysTimer<BASE_ADDR, HZ> { | ||
| // this code is modified from | ||
| // https://github.com/esp-rs/esp-hal/blob/6100b7d90973539cf73d51e72cc20e6e275a98c6/esp-hal/src/timer/systimer.rs#L371-L387 | ||
| // This can be a shared reference as long as this type isn't Sync. | ||
| // FIXME: A stress test should be added to verify whether this API is stalled in multi-task. | ||
| fn estimate_current_cycles() -> u64 { | ||
| Self::registers().unit0_op.modify(UNIT_OP::UPDATE::SET); | ||
| while !Self::registers().unit0_op.is_set(UNIT_OP::VALUE_VALID) {} | ||
|
|
||
| let mut lo_prev = Self::registers() | ||
| .unit0_value_lo | ||
| .read(UNIT_VALUE_LO::VALUE_LO); | ||
| loop { | ||
| let lo = lo_prev; | ||
| let hi = Self::registers() | ||
| .unit0_value_hi | ||
| .read(UNIT_VALUE_HI::VALUE_HI); | ||
| lo_prev = Self::registers() | ||
| .unit0_value_lo | ||
| .read(UNIT_VALUE_LO::VALUE_LO); | ||
|
|
||
| if lo == lo_prev { | ||
| return ((hi as u64) << 32) | lo as u64; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| fn hz() -> u64 { | ||
| HZ | ||
| } | ||
|
|
||
| fn interrupt_at(moment: u64) { | ||
| Self::set_comparator_enable(false); | ||
| Self::clear_interrupt(); | ||
| Self::registers() | ||
| .target0_conf | ||
| .modify(TARGET_CONF::PERIOD_MODE::CLEAR); | ||
| Self::registers() | ||
| .target0_hi | ||
| .write(TARGET_HI::HI.val((moment >> 32) as u32)); | ||
| Self::registers() | ||
| .target0_lo | ||
| .write(TARGET_LO::LO.val((moment & 0xFFFF_FFFF) as u32)); | ||
|
|
||
| // load comparator | ||
| Self::registers().comp0_load.write(COMP_LOAD::LOAD::SET); | ||
| Self::set_comparator_enable(true); | ||
| } | ||
|
|
||
| fn stop() { | ||
| Self::set_comparator_enable(false); | ||
| } | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.