# psoc-rs

Rust drivers and hardware abstraction layer for Infineon [PSOC](https://www.infineon.com/products/microcontroller/32-bit-psoc-arm-cortex) microcontrollers.

## Current status

This project currently supports all devices in the [PSOC 6](https://www.infineon.com/products/microcontroller/32-bit-psoc-arm-cortex/psoc-6-m4-mcu) and [PSOC Control C3](https://www.infineon.com/products/microcontroller/32-bit-psoc-arm-cortex/32-bit-psoc-control-arm-cortex-m33-mcu) families. Peripheral Access Crates generated by [svd2pac](https://github.com/Infineon/svd2pac) (providing raw register access) are complete and available in the `pacs/` directory and published to crates.io under the `psoc-pac-` prefix. The `psoc` crate provides linker scripts, startup code, and (mostly complete) clock configuration for all devices in supported families, and flashing and debugging is supported through [`probe-rs`](https://probe.rs).

However, HAL abstractions and drivers are currently minimal and in a very early alpha state. Currently, only clocking and GPIO are implemented, and breaking changes are likely as the design evolves. We will continue to add more drivers and supported device families over time, and we welcome contributions as well.

If you are interested in a particular device or driver, please open an issue!

## Getting started

To build an application from scratch, add `psoc` as a dependency in your `Cargo.toml` and
specify your device with a feature flag. You'll also need
[`cortex-m-rt`](https://crates.io/crates/cortex-m-rt), and a panic handler such as
[`panic-halt`](https://crates.io/crates/panic-halt) or
[`panic-probe`](https://crates.io/crates/panic-probe).

```toml
[dependencies]
psoc = { version = "0.1", features = ["device-psc3m5fds2afq1"] }

cortex-m-rt = "0.7.5"
panic-halt = "1.0.0"
```


Specify flashing, linker, and target options in `.cargo/config.toml`:

```toml
[target.'cfg(all(target_arch = "arm", target_os = "none"))']
runner = ["probe-rs", "run", "--log-format=oneline", "--speed=16000"]

[build]
rustflags = [
    "-Clink-arg=-Tpsoc.x",
    "-Clink-arg=-Tdefmt.x",
    "-C", "link-arg=--nmagic"
]

# Pick ONE of these for your target
# target = "thumbv6m-none-eabi"         # Cortex-M0/M0+
# target = "thumbv7m-none-eabi"         # Cortex-M3
# target = "thumbv7em-none-eabi"        # Cortex-M4/M7 (no FPU)
# target = "thumbv7em-none-eabihf"      # Cortex-M4/M7 (with FPU)
# target = "thumbv8m.main-none-eabi"    # Cortex-M33/M55/M85 (no FPU)
target = "thumbv8m.main-none-eabihf"    # Cortex-M33/M55/M85 (with FPU)
```

Write a main function and initialize the device:

```rust
#![no_main]
#![no_std]

use panic_halt as _;

#[cortex_m_rt::entry]
fn main() -> ! {
    let mut device = psoc::device::Device::take();
    // Initialize clocks
    device.clock.configure(&Default::default(), None);

    // Initialize an LED pin
    let led_port = device
        .gpio
        .8
        .p5(psoc::gpio::mode::Strong::<false>, Default::default())
        .initialize();
    let mut led_pin = led_port.5;
    loop {
        led_pin.toggle();
        psoc::sys::delay_microseconds(500_000);
    }
}
```

Install probe-rs, and flash with `cargo flash --release`.

See the [example applications](https://github.com/Infineon/psoc-rs/tree/main/examples) for
examples on how to structure applications and BSPS, and recommended configuration for
improved compiler optimizations and IDE integration.

### Important note about documentation

The documentation available on docs.rs only covers a single chip ([PSC3M5FDS2AFQ1](https://www.infineon.com/part/PSC3M5FDS2AFQ1), a PSOC Control C3 device). Available drivers and APIs vary across devices. It is recommended to build documentation locally for your specific chip by running `cargo doc --open` in your project.

## Contributing

Contributions are welcome; feel free to open a PR!

Helpful resources:
- [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) for an overview of the codebase's structure, terminology, and style
- Hardware documentation:
    - [PSOC 6 technical reference manuals](https://documentation.infineon.com/psoc6/docs/zrs1651212645947)
    - [PSOC Control C3 reference manuals](https://documentation.infineon.com/psoccontrolc3/docs/qxr1731247603412)
- ModusToolbox Peripheral Driver Library (in C, not used directly by this project but useful to cross-reference
    - [API reference](https://infineon.github.io/mtb-pdl-cat1/pdl_api_reference_manual/html/modules.html)
    - [Source code](https://github.com/Infineon/mtb-pdl-cat1)

Be sure to test your changes using `scripts/check_all.rs` to ensure your code compiles across all supported devices.
