Skip to content
Open
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
18 changes: 10 additions & 8 deletions driver/src/gpio/esp32_gpio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,26 +49,28 @@ register_structs! {
}

/// GPIO output pin for ESP32-C3, e.g. SPI CS via `embedded_hal_bus::spi::ExclusiveDevice`.
pub struct Esp32GpioOutputPin<const PIN: u8>;
pub struct Esp32GpioOutputPin {
pin: u8,
}

impl<const PIN: u8> Esp32GpioOutputPin<PIN> {
pub const fn new() -> Self {
Esp32GpioOutputPin
impl Esp32GpioOutputPin {
pub const fn new(pin: u8) -> Self {
Esp32GpioOutputPin { pin }
}
}

impl<const PIN: u8> blueos_hal::PlatPeri for Esp32GpioOutputPin<PIN> {}
impl blueos_hal::PlatPeri for Esp32GpioOutputPin {}

impl<const PIN: u8> blueos_hal::gpio::OutputPin for Esp32GpioOutputPin<PIN> {
impl blueos_hal::gpio::OutputPin for Esp32GpioOutputPin {
fn set_low(&self) -> blueos_hal::err::Result<()> {
let gpio_regs = &*GPIO_BASE;
gpio_regs.out_w1tc.write(GpioOut::DATA.val(1 << PIN));
gpio_regs.out_w1tc.write(GpioOut::DATA.val(1 << self.pin));
Ok(())
}

fn set_high(&self) -> blueos_hal::err::Result<()> {
let gpio_regs = &*GPIO_BASE;
gpio_regs.out_w1ts.write(GpioOut::DATA.val(1 << PIN));
gpio_regs.out_w1ts.write(GpioOut::DATA.val(1 << self.pin));
Ok(())
}
}
2 changes: 1 addition & 1 deletion driver/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
#![feature(const_nonnull_new)]

pub mod clock_control;
pub mod hwinfo;
pub mod gpio;
pub mod hwinfo;
pub mod i2c;
pub mod interrupt_controller;
pub mod pinctrl;
Expand Down
File renamed without changes.
4 changes: 2 additions & 2 deletions driver/src/spi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
// limitations under the License.

#[cfg(soc_esp32c3)]
pub mod esp32_spi2;
pub mod esp32_spi;

/// SPI clock phase (CPHA).
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
Expand Down Expand Up @@ -46,7 +46,7 @@ pub struct SpiConfig {
}

impl SpiConfig {
/// Mode 0 (CPOL=0, CPHA=0), MSB-first, 20MHz — typical SPI NOR Flash config
/// Mode 0 (CPOL=0, CPHA=0), MSB-first, 20MHz — typical SPI NOR Flash config.
pub fn spi_flash_default() -> Self {
SpiConfig {
baudrate: 20_000_000,
Expand Down
1 change: 1 addition & 0 deletions kconfig/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ _kconfig_files = [
"//kernel/kernel/src/scheduler/Kconfig",
"//kernel/kernel/src/vfs/Kconfig",
"//kernel/kernel/src/net/Kconfig",
"//kernel/kernel/src/devices/Kconfig",
"//kernel/arch/riscv/Kconfig",
"//kernel/arch/arm/cortex_m/Kconfig",
"//kernel/arch/arm/arm64/Kconfig",
Expand Down
1 change: 1 addition & 0 deletions kconfig/config/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ rsource "../../kernel/src/allocator/Kconfig"
rsource "../../kernel/src/scheduler/Kconfig"
rsource "../../kernel/src/vfs/Kconfig"
rsource "../../kernel/src/net/Kconfig"
rsource "../../kernel/src/devices/Kconfig"

config UNITTEST_THREAD_NUM
int "The num of thread used by uniitest."
Expand Down
21 changes: 20 additions & 1 deletion kernel/src/boards/raspberry_pico2_cortexm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use crate::{
arch::{self, irq::IrqNumber},
boot,
boot::INIT_BSS_DONE,
devices::clock::systick,
devices::{clock::systick, i2c_core::block_i2c::BlockI2c},
irq::IrqTrace,
time,
};
Expand Down Expand Up @@ -149,3 +149,22 @@ static ARM_PL011_ISR: ArmPl011Isr<0x40070000, crate::drivers::serial::Serial> =
tx_isr: Some(crate::drivers::serial::Serial::xmitchars),
rx_isr: Some(crate::drivers::serial::Serial::recvchars),
};

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

if let Ok(block_i2c) = BlockI2c::new(get_device!(i2c0)) {
let i2c0_bus = Arc::new(Bus::new(block_i2c));
for device in crate::boards::get_bus_devices!(i2c0_bus) {
i2c0_bus.register_device(device).unwrap();
}
if let Ok(d) = i2c0_bus.probe_driver(&crate::drivers::sensor::bme280::Bme280DriverModule) {
if let Err(e) = d.init(&i2c0_bus) {
log::warn!("Failed to init Bme280 driver: {}", e);
}
} else {
log::warn!("Failed to probe Bme280 driver");
}
}
}
12 changes: 12 additions & 0 deletions kernel/src/boards/seeed_xiao_esp32c3/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,18 @@ choice
Set irq priority bits to 8.
endchoice

config ST7789
bool "Enable LCD st7789"
default y
help
Enable st7789

config USE_EMBEDDED_HAL_V1
bool "Impl embedded-hal-1.0.0 for driver"
default y
help
Impl embedded-hal-1.0.0 for driver

config SOC_ESP32C3
bool "Esp32c3"
default y
Expand Down
64 changes: 61 additions & 3 deletions kernel/src/boards/seeed_xiao_esp32c3/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ use crate::{
arch::riscv::{local_irq_enabled, trap_entry, Context},
scheduler, time,
};
use blueos_driver::{interrupt_controller::Interrupt, uart::esp32_usb_serial::Esp32UsbSerialIsr};
use blueos_driver::{
interrupt_controller::Interrupt, spi::esp32_spi::Esp32Spi2,
uart::esp32_usb_serial::Esp32UsbSerialIsr,
};
use blueos_hal::{isr::IsrDesc, Has8bitDataReg};

// FIXME: Only support unit0 for now
Expand Down Expand Up @@ -145,10 +148,16 @@ crate::define_peripheral! {
blueos_driver::uart::esp32_usb_serial::Esp32UsbSerial::new()),
(intc, blueos_driver::interrupt_controller::esp32_intc::Esp32Intc,
blueos_driver::interrupt_controller::esp32_intc::Esp32Intc::new(0x600c_2000)),
(spi2, blueos_driver::spi::esp32_spi::Esp32Spi2<0x6002_4000, 0x600C_0000, 80_000_000>,
blueos_driver::spi::esp32_spi::Esp32Spi2::<0x6002_4000, 0x600C_0000, 80_000_000>::new()),
(dc_pin, blueos_driver::gpio::esp32_gpio::Esp32GpioOutputPin,
blueos_driver::gpio::esp32_gpio::Esp32GpioOutputPin::new(5)),
(rst_pin, blueos_driver::gpio::esp32_gpio::Esp32GpioOutputPin,
blueos_driver::gpio::esp32_gpio::Esp32GpioOutputPin::new(4)),
(lcd_cs, blueos_driver::gpio::esp32_gpio::Esp32GpioOutputPin,
blueos_driver::gpio::esp32_gpio::Esp32GpioOutputPin::new(20)),
}

crate::define_pin_states!(None);

#[inline(always)]
pub(crate) fn send_ipi(_hart: usize) {}

Expand All @@ -161,3 +170,52 @@ static ESP32_USB_SERIAL_ISR: Esp32UsbSerialIsr<0x6004_3000, crate::drivers::seri
tx_isr: Some(crate::drivers::serial::Serial::xmitchars),
rx_isr: Some(crate::drivers::serial::Serial::recvchars),
};

crate::define_pin_states!(
blueos_driver::pinctrl::esp32_pinctrl::Esp32IoMuxPinctrl,
(8, 1, false, false, false, 2, Some(63), None, false), // SCK
(9, 1, true, false, false, 2, None, Some(64), false), // MISO
(10, 1, false, false, false, 2, Some(65), None, false), // MOSI
(20, 1, false, true, false, 2, None, None, true), // lcd cs
(5, 1, false, true, false, 2, None, None, true), // lcd dc
(4, 1, false, true, false, 2, None, None, true), // lcd rst
);

crate::define_bus! {
(
spi2_bus,
crate::devices::spi_core::block_spi::BlockSpi<blueos_driver::spi::esp32_spi::Esp32Spi2<0x6002_4000, 0x600C_0000, 80_000_000>, blueos_driver::gpio::esp32_gpio::Esp32GpioOutputPin<7>>,
(st7789, crate::drivers::lcd::st7789::St7789Config<blueos_driver::gpio::esp32_gpio::Esp32GpioOutputPin>,
crate::drivers::lcd::st7789::St7789Config::<blueos_driver::gpio::esp32_gpio::Esp32GpioOutputPin> {
rst: get_device!(rst_pin),
dc: get_device!(dc_pin),
}
),
)
}

pub(crate) fn init_spi_bus() {
use crate::{devices::bus::Bus, drivers::InitDriver};
use alloc::sync::Arc;

if let Ok(block_spi) = crate::devices::spi_core::block_spi::BlockSpi::new(
get_device!(spi2),
get_device!(lcd_cs),
&blueos_driver::spi::SpiConfig::spi_flash_default(),
) {
let spi2_bus = Arc::new(Bus::new(block_spi));
for device in crate::boards::get_bus_devices!(spi2_bus) {
spi2_bus.register_device(device).unwrap();
}
if let Ok(d) = spi2_bus.probe_driver(&crate::drivers::lcd::st7789::St7789DriverModule::<
blueos_driver::gpio::esp32_gpio::Esp32GpioOutputPin,
>::new())
{
if let Err(e) = d.init(&spi2_bus) {
log::warn!("Failed to init ST7789 driver: {}", e);
}
}
} else {
log::warn!("Failed to init BlockSpi");
}
}
31 changes: 8 additions & 23 deletions kernel/src/boot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,6 @@ use crate::{
drivers::InitDriver,
};

#[cfg(use_bme280)]
static I2C0_BUS: Once<Arc<Bus<crate::boards::get_bus_ty!(i2c0_bus)>>> = Once::new();

fn init_pin_states<P: blueos_hal::pinctrl::AlterFuncPin>(pin_states: &[&P]) {
for pin_state in pin_states {
pin_state.init();
Expand Down Expand Up @@ -107,26 +104,6 @@ extern "C" fn init() {
Err(err) => panic!("Failed to init console: {}", crate::error::Error::from(err)),
}

#[cfg(use_bme280)]
{
if let Ok(block_i2c) = BlockI2c::new(crate::boards::get_device!(i2c0)) {
I2C0_BUS.call_once(|| Arc::new(Bus::new(block_i2c)));
let i2c0_bus = I2C0_BUS.get().unwrap();
for device in crate::boards::get_bus_devices!(i2c0_bus) {
i2c0_bus.register_device(device).unwrap();
}
if let Ok(d) =
i2c0_bus.probe_driver(&crate::drivers::sensor::bme280::Bme280DriverModule)
{
if let Err(e) = d.init(&i2c0_bus) {
log::warn!("Failed to init Bme280 driver: {}", e);
}
}
} else {
log::warn!("Failed to init BlockI2c");
}
}

#[cfg(virtio)]
{
use crate::devices::virtio;
Expand All @@ -149,12 +126,20 @@ extern "C" fn init() {
net::init();
net::net_manager::init();
}

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

#[cfg(enable_vfs)]
init_vfs();
// 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();

init_apps();

arch::start_schedule(scheduler::schedule);
unreachable!("We should have jumped to the schedule loop!");
}
Expand Down
10 changes: 10 additions & 0 deletions kernel/src/devices/Kconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# General Device Configuration

config SPI_CORE
default n
bool "enable spi core"

config I2C_CORE
default n
bool "enable i2c core"

13 changes: 3 additions & 10 deletions kernel/src/devices/bus/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,21 +67,14 @@ impl<B: BusInterface> Bus<B> {
&self,
dev: &M,
) -> crate::drivers::Result<T> {
let mut driver = Default::default();
let devices = self.devices.read();
let it = super::DeviceListIterator::new(&devices, None);
let mut matched = false;
for node in it {
if let Ok(driv) = M::probe(unsafe { node.as_ref() }.owner().data) {
driver = driv;
matched = true;
break;
if let Ok(driver) = M::probe(unsafe { node.as_ref() }.owner().data) {
return Ok(driver);
}
}

if !matched {
return Err(crate::error::code::ENODEV);
}
Ok(driver)
Err(crate::error::code::ENODEV)
}
}
Loading