Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 3 additions & 17 deletions hal/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,23 +53,9 @@ pub trait Configuration<P> {

/// Platform peripheral base trait
///
/// Defines the fundamental operations that all platform peripherals must implement.
/// This trait provides a unified interface for enabling and disabling peripheral devices
/// across different hardware platforms.
///
/// All peripheral drivers should implement this trait to ensure consistent power
/// management and resource control capabilities.
///
/// # Trait Bounds
///
/// This trait requires implementations to be:
/// - `Sync` - Safe to share references between threads, Peripherals are often accessed from multiple contexts.
/// - `Send` - Safe to transfer ownership between threads, Peripherals always exists in system memory.
/// - `'static` - Lives for the entire duration of the program
///
/// These bounds ensure that peripheral instances can be safely used in multi-threaded
/// environments and stored in static variables, which is common in embedded systems.
pub trait PlatPeri: Sync + Send + 'static {
/// Peripherals would be a global singleton,
/// and the HAL layer would provide a static reference to the peripheral.
pub trait PlatPeri: 'static {
fn enable(&self) {}
fn disable(&self) {}
}
Expand Down
26 changes: 24 additions & 2 deletions kernel/src/boards/seeed_xiao_esp32c3/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,27 @@ choice
Set irq priority bits to 8.
endchoice

choice
config LCD
bool "Enable LCD device"
default n
help
Enable LCD module

config FT6336U
bool "Enable touch screen device"
default n
help
Enable touch screen

config GPIO
bool "Enable gpio device"
default n
help
Enable gpio device

if LCD

choice
prompt "LCD controller"
default ST7789

Expand All @@ -32,7 +52,9 @@ choice
bool "Enable LCD ST7796"
help
Enable the ST7796 LCD controller.
endchoice
endchoice

endif

config BME280
bool "BME280 Sensor"
Expand Down
87 changes: 86 additions & 1 deletion kernel/src/boards/seeed_xiao_esp32c3/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,9 @@ const RTC_CNTL_WDTCONFIG0_REG: usize = RTC_CNTL_BASE + 0x90;

const USB_SERIAL_JTAG_IRQ: Interrupt = Interrupt::new(26, USB_SERIAL_JTAG_INT_NUM);
const SYSTIMER_TARGET0_IRQ: Interrupt = Interrupt::new(37, TARGET0_INT_NUM);
const LED_DEVICE_MAJOR: usize = 242;
const LED_B_DEVICE_MINOR: usize = 0;
const LED_R_DEVICE_MINOR: usize = 1;

pub(crate) fn init() {
assert!(!local_irq_enabled());
Expand Down Expand Up @@ -189,6 +192,10 @@ crate::define_peripheral! {
blueos_driver::gpio::esp32_gpio::Esp32GpioOutputPin::new(21)),
(lcd_cs, blueos_driver::gpio::esp32_gpio::Esp32GpioOutputPin,
blueos_driver::gpio::esp32_gpio::Esp32GpioOutputPin::new(20)),
(led_b, blueos_driver::gpio::esp32_gpio::Esp32GpioOutputPin,
blueos_driver::gpio::esp32_gpio::Esp32GpioOutputPin::new(2)),
(led_r, blueos_driver::gpio::esp32_gpio::Esp32GpioOutputPin,
blueos_driver::gpio::esp32_gpio::Esp32GpioOutputPin::new(3)),
}

#[inline(always)]
Expand All @@ -215,6 +222,8 @@ crate::define_pin_states!(
(5, 1, false, true, false, 2, None, None, true, false), // lcd dc
(4, 1, false, true, false, 2, None, None, true, false), // lcd rst
(21, 1, false, true, false, 2, None, None, true, false), // touch rst
(2, 1, false, true, false, 2, None, None, true, false), // led blue
(3, 1, false, true, false, 2, None, None, true, false), // led red
);

crate::define_bus! {
Expand All @@ -226,19 +235,35 @@ crate::define_bus! {
crate::drivers::lcd::st7789::St7789Config::<blueos_driver::gpio::esp32_gpio::Esp32GpioOutputPin> {
rst: get_device!(rst_pin),
dc: get_device!(dc_pin),
cs: Some(get_device!(lcd_cs)),
}
),
#[cfg(st7796)]
(st7796, crate::drivers::lcd::st7796::St7796Config<blueos_driver::gpio::esp32_gpio::Esp32GpioOutputPin>,
crate::drivers::lcd::st7796::St7796Config::<blueos_driver::gpio::esp32_gpio::Esp32GpioOutputPin> {
rst: get_device!(rst_pin),
dc: get_device!(dc_pin),
cs: Some(get_device!(lcd_cs)),
orientation: mipidsi::options::Orientation::new()
.rotate(mipidsi::options::Rotation::Deg0)
.flip_horizontal(),
}
),
),
(
i2c_bus,
crate::devices::i2c_core::block_i2c::BlockI2c<blueos_driver::i2c::esp32_i2c::Esp32I2c>,
#[cfg(ft6336u)]
(ft6336u, crate::drivers::input::ft6336u::Ft6336uConfig<blueos_driver::gpio::esp32_gpio::Esp32GpioOutputPin>,
crate::drivers::input::ft6336u::Ft6336uConfig::<blueos_driver::gpio::esp32_gpio::Esp32GpioOutputPin> {
rst: get_device!(touch_rst_pin),
}
),
#[cfg(bme280)]
(bme280, crate::drivers::sensor::bme280::Bme280Config,
crate::drivers::sensor::bme280::Bme280Config::new(0x76)
),
),
}

pub(crate) fn init_spi_bus() {
Expand Down Expand Up @@ -283,4 +308,64 @@ pub(crate) fn init_spi_bus() {
}
}

pub(crate) fn init_i2c_bus() {}
pub(crate) fn init_i2c_bus() {
use crate::{
devices::{bus::Bus, i2c_core::block_i2c::BlockI2c},
drivers::InitDriver,
};
use alloc::sync::Arc;

if let Ok(block_i2c) = BlockI2c::new(get_device!(i2c0)) {
let i2c_bus = Arc::new(Bus::new(block_i2c));
for device in crate::boards::get_bus_devices!(i2c_bus) {
i2c_bus.register_device(device).unwrap();
}

#[cfg(ft6336u)]
if let Ok(driver) =
i2c_bus.probe_driver(&crate::drivers::input::ft6336u::Ft6336uDriverModule::<
blueos_driver::gpio::esp32_gpio::Esp32GpioOutputPin,
>::new())
{
if let Err(error) = driver.init(&i2c_bus) {
log::warn!("Failed to initialize FT6336U driver: {}", error);
}
} else {
log::warn!("Failed to probe FT6336U driver");
}

#[cfg(bme280)]
if let Ok(driver) =
i2c_bus.probe_driver(&crate::drivers::sensor::bme280::Bme280DriverModule)
{
if let Err(error) = driver.init(&i2c_bus) {
log::warn!("Failed to initialize BME280 driver: {}", error);
}
} else {
log::warn!("Failed to probe BME280 driver");
}
} else {
log::warn!("Failed to initialize ESP32-C3 I2C0 bus");
}
}

pub(crate) fn init_gpio() {
crate::devices::gpio::GeneralGpio::new(
get_device!(led_b),
Some(crate::devices::gpio::Level::High),
)
.register(
alloc::string::String::from("led_b"),
crate::devices::DeviceId::new(LED_DEVICE_MAJOR, LED_B_DEVICE_MINOR),
)
.expect("Failed to register led_b");
crate::devices::gpio::GeneralGpio::new(
get_device!(led_r),
Some(crate::devices::gpio::Level::High),
)
.register(
alloc::string::String::from("led_r"),
crate::devices::DeviceId::new(LED_DEVICE_MAJOR, LED_R_DEVICE_MINOR),
)
.expect("Failed to register led_r");
}
18 changes: 12 additions & 6 deletions kernel/src/boot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,12 @@ extern "C" fn init() {
// initialize virtio
virtio::init_virtio(&fdt);
}
#[cfg(spi_core)]
crate::boards::init_spi_bus();
#[cfg(i2c_core)]
crate::boards::init_i2c_bus();
#[cfg(gpio)]
crate::boards::init_gpio();
#[cfg(enable_vfs)]
init_vfs();

Expand All @@ -129,11 +135,6 @@ extern "C" fn init() {
net::net_manager::init();
}

#[cfg(spi_core)]
crate::boards::init_spi_bus();
#[cfg(i2c_core)]
crate::boards::init_i2c_bus();

// it's an bug in fact, but at now we use a workaround let newlib do the c++ runtime initialization
#[cfg(not(target_board = "newlib_mps3_an547"))]
run_init_array();
Expand Down Expand Up @@ -197,7 +198,12 @@ fn init_apps() {
unsafe {
let mut app = addr_of!(__bk_app_array_start);
while app < addr_of!(__bk_app_array_end) {
thread::Builder::new(thread::Entry::C(*app)).start();
let stack =
thread::Stack::from_size(blueos_kconfig::CONFIG_MAIN_THREAD_STACK_SIZE as usize)
.expect("Invalid main thread stack size");
thread::Builder::new(thread::Entry::C(*app))
.set_stack(stack)
.start();
app = app.offset(1);
}
}
Expand Down
7 changes: 1 addition & 6 deletions kernel/src/devices/bus/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,7 @@ pub struct Bus<B: BusInterface> {
unsafe impl<B: BusInterface> Send for Bus<B> {}
unsafe impl<B: BusInterface> Sync for Bus<B> {}

pub trait BusInterface: Sync + Send + Sized {
type Region;
fn read_region(&self, region: Self::Region, buffer: &mut [u8]) -> crate::drivers::Result<()>;

fn write_region(&self, region: Self::Region, data: &[u8]) -> crate::drivers::Result<()>;
}
pub trait BusInterface: Sized {}

impl<B: BusInterface> Bus<B> {
pub fn new(intf: B) -> Self {
Expand Down
Loading