mirror of
https://github.com/embassy-rs/embassy.git
synced 2025-09-27 12:20:37 +00:00
Merge pull request #4435 from bespsm/mspm0-i2c
MSPM0: Add I2C Controller (blocking & async) + examples for mspm0l1306, mspm0g3507 (tested MCUs)
This commit is contained in:
commit
32f142d585
10
embassy-mspm0/CHANGELOG.md
Normal file
10
embassy-mspm0/CHANGELOG.md
Normal file
@ -0,0 +1,10 @@
|
||||
# Changelog for embassy-mspm0
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## Unreleased - ReleaseDate
|
||||
|
||||
- feat: Add I2C Controller (blocking & async) + examples for mspm0l1306, mspm0g3507 (tested MCUs) (#4435)
|
@ -35,6 +35,7 @@ embassy-hal-internal = { version = "0.3.0", path = "../embassy-hal-internal", fe
|
||||
embassy-embedded-hal = { version = "0.4.0", path = "../embassy-embedded-hal", default-features = false }
|
||||
embassy-executor = { version = "0.8.0", path = "../embassy-executor", optional = true }
|
||||
|
||||
embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = ["unproven"] }
|
||||
embedded-hal = { version = "1.0" }
|
||||
embedded-hal-nb = { version = "1.0" }
|
||||
embedded-hal-async = { version = "1.0" }
|
||||
@ -49,7 +50,7 @@ cortex-m = "0.7.6"
|
||||
critical-section = "1.2.0"
|
||||
|
||||
# mspm0-metapac = { version = "" }
|
||||
mspm0-metapac = { git = "https://github.com/mspm0-rs/mspm0-data-generated/", tag = "mspm0-data-235158ac2865d8aac3a1eceb2d62026eb12bf38f" }
|
||||
mspm0-metapac = { git = "https://github.com/mspm0-rs/mspm0-data-generated/", tag = "mspm0-data-df572e257eabf06e6e0ae6c9077e0a2fec1fb5e1" }
|
||||
|
||||
[build-dependencies]
|
||||
proc-macro2 = "1.0.94"
|
||||
@ -57,7 +58,7 @@ quote = "1.0.40"
|
||||
cfg_aliases = "0.2.1"
|
||||
|
||||
# mspm0-metapac = { version = "", default-features = false, features = ["metadata"] }
|
||||
mspm0-metapac = { git = "https://github.com/mspm0-rs/mspm0-data-generated/", tag = "mspm0-data-235158ac2865d8aac3a1eceb2d62026eb12bf38f", default-features = false, features = ["metadata"] }
|
||||
mspm0-metapac = { git = "https://github.com/mspm0-rs/mspm0-data-generated/", tag = "mspm0-data-df572e257eabf06e6e0ae6c9077e0a2fec1fb5e1", default-features = false, features = ["metadata"] }
|
||||
|
||||
[features]
|
||||
default = ["rt"]
|
||||
|
@ -549,9 +549,11 @@ fn generate_peripheral_instances() -> TokenStream {
|
||||
|
||||
for peripheral in METADATA.peripherals {
|
||||
let peri = format_ident!("{}", peripheral.name);
|
||||
let fifo_size = peripheral.sys_fentries;
|
||||
|
||||
let tokens = match peripheral.kind {
|
||||
"uart" => Some(quote! { impl_uart_instance!(#peri); }),
|
||||
"i2c" => Some(quote! { impl_i2c_instance!(#peri, #fifo_size); }),
|
||||
_ => None,
|
||||
};
|
||||
|
||||
@ -598,6 +600,9 @@ fn generate_pin_trait_impls() -> TokenStream {
|
||||
("uart", "RX") => Some(quote! { impl_uart_rx_pin!(#peri, #pin_name, #pf); }),
|
||||
("uart", "CTS") => Some(quote! { impl_uart_cts_pin!(#peri, #pin_name, #pf); }),
|
||||
("uart", "RTS") => Some(quote! { impl_uart_rts_pin!(#peri, #pin_name, #pf); }),
|
||||
("i2c", "SDA") => Some(quote! { impl_i2c_sda_pin!(#peri, #pin_name, #pf); }),
|
||||
("i2c", "SCL") => Some(quote! { impl_i2c_scl_pin!(#peri, #pin_name, #pf); }),
|
||||
|
||||
_ => None,
|
||||
};
|
||||
|
||||
|
1208
embassy-mspm0/src/i2c.rs
Normal file
1208
embassy-mspm0/src/i2c.rs
Normal file
File diff suppressed because it is too large
Load Diff
@ -15,6 +15,7 @@ mod macros;
|
||||
|
||||
pub mod dma;
|
||||
pub mod gpio;
|
||||
pub mod i2c;
|
||||
pub mod timer;
|
||||
pub mod uart;
|
||||
|
||||
|
45
examples/mspm0g3507/src/bin/i2c.rs
Normal file
45
examples/mspm0g3507/src/bin/i2c.rs
Normal file
@ -0,0 +1,45 @@
|
||||
//! This example uses FIFO with polling, and the maximum FIFO size is 8.
|
||||
//! Refer to async example to handle larger packets.
|
||||
//!
|
||||
//! This example controls AD5171 digital potentiometer via I2C with the LP-MSPM0G3507 board.
|
||||
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use defmt::*;
|
||||
use embassy_executor::Spawner;
|
||||
use embassy_mspm0::i2c::{Config, I2c};
|
||||
use embassy_time::Timer;
|
||||
use {defmt_rtt as _, panic_halt as _};
|
||||
|
||||
const ADDRESS: u8 = 0x6a;
|
||||
|
||||
#[embassy_executor::main]
|
||||
async fn main(_spawner: Spawner) -> ! {
|
||||
let p = embassy_mspm0::init(Default::default());
|
||||
|
||||
let instance = p.I2C1;
|
||||
let scl = p.PB2;
|
||||
let sda = p.PB3;
|
||||
|
||||
let mut i2c = unwrap!(I2c::new_blocking(instance, scl, sda, Config::default()));
|
||||
|
||||
let mut pot_value: u8 = 0;
|
||||
|
||||
loop {
|
||||
let to_write = [0u8, pot_value];
|
||||
|
||||
match i2c.blocking_write(ADDRESS, &to_write) {
|
||||
Ok(()) => info!("New potentioemter value: {}", pot_value),
|
||||
Err(e) => error!("I2c Error: {:?}", e),
|
||||
}
|
||||
|
||||
pot_value += 1;
|
||||
// if reached 64th position (max)
|
||||
// start over from lowest value
|
||||
if pot_value == 64 {
|
||||
pot_value = 0;
|
||||
}
|
||||
Timer::after_millis(500).await;
|
||||
}
|
||||
}
|
50
examples/mspm0g3507/src/bin/i2c_async.rs
Normal file
50
examples/mspm0g3507/src/bin/i2c_async.rs
Normal file
@ -0,0 +1,50 @@
|
||||
//! The example uses FIFO and interrupts, wrapped in async API.
|
||||
//!
|
||||
//! This example controls AD5171 digital potentiometer via I2C with the LP-MSPM0G3507 board.
|
||||
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use defmt::*;
|
||||
use embassy_executor::Spawner;
|
||||
use embassy_mspm0::bind_interrupts;
|
||||
use embassy_mspm0::i2c::{Config, I2c, InterruptHandler};
|
||||
use embassy_mspm0::peripherals::I2C1;
|
||||
use embassy_time::Timer;
|
||||
use {defmt_rtt as _, panic_halt as _};
|
||||
|
||||
const ADDRESS: u8 = 0x6a;
|
||||
|
||||
bind_interrupts!(struct Irqs {
|
||||
I2C1 => InterruptHandler<I2C1>;
|
||||
});
|
||||
|
||||
#[embassy_executor::main]
|
||||
async fn main(_spawner: Spawner) -> ! {
|
||||
let p = embassy_mspm0::init(Default::default());
|
||||
|
||||
let instance = p.I2C1;
|
||||
let scl = p.PB2;
|
||||
let sda = p.PB3;
|
||||
|
||||
let mut i2c = unwrap!(I2c::new_async(instance, scl, sda, Irqs, Config::default()));
|
||||
|
||||
let mut pot_value: u8 = 0;
|
||||
|
||||
loop {
|
||||
let to_write = [0u8, pot_value];
|
||||
|
||||
match i2c.async_write(ADDRESS, &to_write).await {
|
||||
Ok(()) => info!("New potentioemter value: {}", pot_value),
|
||||
Err(e) => error!("I2c Error: {:?}", e),
|
||||
}
|
||||
|
||||
pot_value += 1;
|
||||
// if reached 64th position (max)
|
||||
// start over from lowest value
|
||||
if pot_value == 64 {
|
||||
pot_value = 0;
|
||||
}
|
||||
Timer::after_millis(500).await;
|
||||
}
|
||||
}
|
@ -19,3 +19,7 @@ panic-semihosting = "0.6.0"
|
||||
|
||||
[profile.release]
|
||||
debug = 2
|
||||
|
||||
[profile.dev]
|
||||
debug = 2
|
||||
opt-level = 2
|
||||
|
45
examples/mspm0l1306/src/bin/i2c.rs
Normal file
45
examples/mspm0l1306/src/bin/i2c.rs
Normal file
@ -0,0 +1,45 @@
|
||||
//! This example uses FIFO with polling, and the maximum FIFO size is 8.
|
||||
//! Refer to async example to handle larger packets.
|
||||
//!
|
||||
//! This example controls AD5171 digital potentiometer via I2C with the LP-MSPM0L1306 board.
|
||||
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use defmt::*;
|
||||
use embassy_executor::Spawner;
|
||||
use embassy_mspm0::i2c::{Config, I2c};
|
||||
use embassy_time::Timer;
|
||||
use {defmt_rtt as _, panic_halt as _};
|
||||
|
||||
const ADDRESS: u8 = 0x2c;
|
||||
|
||||
#[embassy_executor::main]
|
||||
async fn main(_spawner: Spawner) -> ! {
|
||||
let p = embassy_mspm0::init(Default::default());
|
||||
|
||||
let instance = p.I2C0;
|
||||
let scl = p.PA1;
|
||||
let sda = p.PA0;
|
||||
|
||||
let mut i2c = unwrap!(I2c::new_blocking(instance, scl, sda, Config::default()));
|
||||
|
||||
let mut pot_value: u8 = 0;
|
||||
|
||||
loop {
|
||||
let to_write = [0u8, pot_value];
|
||||
|
||||
match i2c.blocking_write(ADDRESS, &to_write) {
|
||||
Ok(()) => info!("New potentioemter value: {}", pot_value),
|
||||
Err(e) => error!("I2c Error: {:?}", e),
|
||||
}
|
||||
|
||||
pot_value += 1;
|
||||
// if reached 64th position (max)
|
||||
// start over from lowest value
|
||||
if pot_value == 64 {
|
||||
pot_value = 0;
|
||||
}
|
||||
Timer::after_millis(500).await;
|
||||
}
|
||||
}
|
50
examples/mspm0l1306/src/bin/i2c_async.rs
Normal file
50
examples/mspm0l1306/src/bin/i2c_async.rs
Normal file
@ -0,0 +1,50 @@
|
||||
//! The example uses FIFO and interrupts, wrapped in async API.
|
||||
//!
|
||||
//! This example controls AD5171 digital potentiometer via I2C with the LP-MSPM0L1306 board.
|
||||
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use defmt::*;
|
||||
use embassy_executor::Spawner;
|
||||
use embassy_mspm0::bind_interrupts;
|
||||
use embassy_mspm0::i2c::{Config, I2c, InterruptHandler};
|
||||
use embassy_mspm0::peripherals::I2C0;
|
||||
use embassy_time::Timer;
|
||||
use {defmt_rtt as _, panic_halt as _};
|
||||
|
||||
const ADDRESS: u8 = 0x6a;
|
||||
|
||||
bind_interrupts!(struct Irqs {
|
||||
I2C0 => InterruptHandler<I2C0>;
|
||||
});
|
||||
|
||||
#[embassy_executor::main]
|
||||
async fn main(_spawner: Spawner) -> ! {
|
||||
let p = embassy_mspm0::init(Default::default());
|
||||
|
||||
let instance = p.I2C0;
|
||||
let scl = p.PA1;
|
||||
let sda = p.PA0;
|
||||
|
||||
let mut i2c = unwrap!(I2c::new_async(instance, scl, sda, Irqs, Config::default()));
|
||||
|
||||
let mut pot_value: u8 = 0;
|
||||
|
||||
loop {
|
||||
let to_write = [0u8, pot_value];
|
||||
|
||||
match i2c.async_write(ADDRESS, &to_write).await {
|
||||
Ok(()) => info!("New potentioemter value: {}", pot_value),
|
||||
Err(e) => error!("I2c Error: {:?}", e),
|
||||
}
|
||||
|
||||
pot_value += 1;
|
||||
// if reached 64th position (max)
|
||||
// start over from lowest value
|
||||
if pot_value == 64 {
|
||||
pot_value = 0;
|
||||
}
|
||||
Timer::after_millis(500).await;
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user