embassy-stm32-plus 0.2.1

embassy-stm32 plus
Documentation
### goal


Make Rust Embedded simpler

embassy-stm32_plus is a library based on [embassy-stm32](https://crates.io/crates/embassy-stm32) secondary encapsulation, 
which supports generating peripheral objects directly through Device stream without manually setting Irqs interrupts, 
such as directly generating gpio output objects `p.PA8.output()` and directly generating 
UART objects    
```
p.USART1.builder(Uart1Tx::PA9(p.PA9), Uart1Rx::PA10(p.PA10))
    .build(p.DMA1_CH4, p.DMA1_CH5);
```   
etc

### support now


- STM32F1 ✔
- STM32C0 ✔
- more support comming soon

### example


build.rs file:   
(build.rs is necessary, otherwise it may result in inability to burn)
```rust
fn main() {
    println!("cargo:rustc-link-arg-bins=--nmagic");
    println!("cargo:rustc-link-arg-bins=-Tlink.x");
    println!("cargo:rustc-link-arg-bins=-Tdefmt.x");

    // Set DEFMT_LOG=info through environment variables to enable probe rs to support defmt: Output of info level log for info
    println!("cargo:rustc-env=DEFMT_LOG=info");
}
```

<details open>
<summary>uart example</summary>

Cargo.toml file :

```toml
embassy-stm32-plus = { version = "0.2.1", features = ["stm32f103rc", "exti"] }
embassy-executor = { version = "0.7.0", features = ["arch-cortex-m", "executor-thread"] }

cortex-m-rt = "0.7.5"
defmt = "0.3.10"
```

main.rs file :

```rust
#![no_std]

#![no_main]


use embassy_executor::Spawner;
use embassy_stm32_plus::builder::uart::uart1::rx::Uart1Rx;
use embassy_stm32_plus::builder::uart::uart1::tx::Uart1Tx;
use embassy_stm32_plus::embassy_stm32;
use embassy_stm32_plus::embassy_stm32::mode::Async;
use embassy_stm32_plus::embassy_stm32::usart::{Error, Uart};
use embassy_stm32_plus::traits::uart::uart1::Uart1Trait;

#[embassy_executor::main]

async fn main(_spawner: Spawner) {
    // init stm32, get Peripheral
    let p = embassy_stm32::init(Default::default());

    // set uart baud rate etc
    // let mut uart_config = embassy_stm32::usart::Config::default();
    // uart_config.baudrate = 9600;

    let mut uart = p.USART1.builder(Uart1Tx::PA9(p.PA9), Uart1Rx::PA10(p.PA10))
        // set uart config
        // .config(Config::default())
        .build(p.DMA1_CH4, p.DMA1_CH5).unwrap();
    defmt::info!("uart initialized!");

    let mut buf = [0u8; 1024];
    loop {
        // wait uart read
        let len = match uart.read_until_idle(&mut buf).await {
            Ok(len) => { len }
            Err(e) => {
                defmt::error!("uart read error: {:?}", e);
                continue;
            }
        };

        defmt::info!("uart read, len is {}", len);

        // reply uart
        if let Err(e) = reply_write_flush(&mut uart, &buf[0..len]).await {
            defmt::error!("uart write error: {:?}",e);
        }
    }
}

/// uart write and flush
async fn reply_write_flush(uart: &mut Uart<'static, Async>, buf: &[u8]) -> Result<(), Error> {
    uart.write(b"copy, ").await?;
    uart.write(buf).await?;
    uart.flush().await
}

```

</details>

<details>
<summary>gpio example</summary>

Cargo.toml:

```toml
embassy-stm32-plus = { version = "0.2.1", features = ["stm32f103rc", "exti"] }
embassy-executor = { version = "0.7.0", features = ["arch-cortex-m", "executor-thread"] }
embassy-time = "0.4.0"

cortex-m-rt = "0.7.5"
defmt = "0.3.10"
```

```rust
#![no_std]

#![no_main]


use embassy_executor::Spawner;
use embassy_stm32_plus::embassy_stm32;
use embassy_stm32_plus::traits::gpio::GpioTrait;
use embassy_time::Timer;

#[embassy_executor::main]

async fn main(_spawner: Spawner) {
    // init stm32, get Peripheral
    let p = embassy_stm32::init(Default::default());

    // simple get output/input gpio
    let mut led = p.PA8.output();
    defmt::info!("led initialized!");

    // change gpio level
    loop {
        led.set_high();
        Timer::after_millis(300).await;

        led.set_low();
        Timer::after_millis(300).await;
    }
}
```

</details>

<details>
<summary>more example</summary>

more example coming soon,   
you can try using the following method to directly generate peripheral protocol objects:
`p.PA8.input()`   
`p.PA8.output()`   
`p.ADC.build()`   
`p.CAN1.build(tx,rx)`   
`p.CRC.build()`   
`p.DAC1.builder(ch1,ch2).build(dma_ch1,dma_ch2)`   
`p.ETH.builder(pins,phy).build.`   
`p.FLASH.build()`   
`p.I2C1.builder(scl,sda).build(tx_dma,rx_dma)`   
`p.SPI1.builder(sck,mosi,miso).build(tx_dma,rx_dma)`   
`p.UART1.builder(tx,rx).build(tx_dma,rx_dma)`   
`p.UID.uid()`   
`p.USB.builder(dp,dm).build_cdc_acm(config,usb_buf,state)`   
`p.USB_OTG_FS.builder(dp,dm).build_cdc_acm(config,ep_buf,usb_buf,state)`   
`p.IWDG.build(timeout_us)`

for more API interfaces, please refer to [docs.rs](https://docs.rs/embassy-stm32-plus/0.2.1/embassy_stm32_plus/)

</details>


### Other instructions


- build linrary(.bin): `cargo objcopy --release -- -O binary app.bin`
- build ihex(.hex): `cargo objcopy --release -- -O ihex app.hex`
- debug see [probe-rs]https://probe.rs/
- more see [embassy]https://github.com/embassy-rs/embassy