{"id":20316048,"url":"https://github.com/lupyuen/bl602-rust-wrapper","last_synced_at":"2025-04-11T17:40:36.625Z","repository":{"id":57515949,"uuid":"360207904","full_name":"lupyuen/bl602-rust-wrapper","owner":"lupyuen","description":"Rust Wrapper for BL602 IoT SDK","archived":false,"fork":false,"pushed_at":"2021-07-31T06:10:45.000Z","size":6044,"stargazers_count":16,"open_issues_count":1,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-25T13:39:41.796Z","etag":null,"topics":["bl602","bl604","macro","riscv","riscv32","rust"],"latest_commit_sha":null,"homepage":"https://lupyuen.github.io/articles/adc","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lupyuen.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null},"funding":{"github":["lupyuen"],"patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":["paypal.me/lupyuen"]}},"created_at":"2021-04-21T14:52:14.000Z","updated_at":"2024-02-17T14:25:20.000Z","dependencies_parsed_at":"2022-08-28T16:50:23.568Z","dependency_job_id":null,"html_url":"https://github.com/lupyuen/bl602-rust-wrapper","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lupyuen%2Fbl602-rust-wrapper","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lupyuen%2Fbl602-rust-wrapper/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lupyuen%2Fbl602-rust-wrapper/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lupyuen%2Fbl602-rust-wrapper/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lupyuen","download_url":"https://codeload.github.com/lupyuen/bl602-rust-wrapper/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248451334,"owners_count":21105851,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bl602","bl604","macro","riscv","riscv32","rust"],"created_at":"2024-11-14T18:24:02.402Z","updated_at":"2025-04-11T17:40:31.613Z","avatar_url":"https://github.com/lupyuen.png","language":"Rust","funding_links":["https://github.com/sponsors/lupyuen","paypal.me/lupyuen"],"categories":[],"sub_categories":[],"readme":"# Rust Wrapper for BL602 IoT SDK\n\nRead the article and docs...\n\n-   [\"Rust on RISC-V BL602: Is It Sunny?\"](https://lupyuen.github.io/articles/adc)\n\n-   [\"Run Rust RISC-V Firmware with BL602 IoT SDK\"](https://lupyuen.github.io/articles/rust)\n\n-   [Rust Docs](https://lupyuen.github.io/bl602-rust-wrapper/)\n\n-   [Rust Crate `bl602-sdk`](https://crates.io/crates/bl602-sdk)\n\n-   [Rust Crate `bl602-macros`](https://crates.io/crates/bl602-macros)\n\n-   [Check this Twitter Thread for updates](https://twitter.com/MisterTechBlog/status/1416608940876435462)\n\n## Usage\n\nHere's how we call the Rust Wrapper for BL602 GPIO HAL in our BL602 Rust Firmware...\n\n```rust\nuse bl602_sdk::gpio;\n...\n//  Configure the LED GPIO for output (instead of input)\ngpio::enable_output(LED_GPIO, 0, 0)        //  No pullup, no pulldown\n    .expect(\"GPIO enable output failed\");  //  Halt on error\n\n//  Blink the LED 5 times\nfor i in 0..10 {  //  Iterates 10 times from 0 to 9 (`..` excludes 10)\n\n    //  Toggle the LED GPIO between 0 (on) and 1 (off)\n    gpio::output_set(  //  Set the GPIO output (from BL602 GPIO HAL)\n        LED_GPIO,      //  GPIO pin number\n        i % 2          //  0 for low, 1 for high\n    ).expect(\"GPIO output failed\");  //  Halt on error\n```\n\n[From `sdk_app_rust_gpio/rust/src/lib.rs`](https://github.com/lupyuen/bl_iot_sdk/blob/adc/customer_app/sdk_app_rust_gpio/rust/src/lib.rs)\n\nBuild the BL602 Firmware with the [`run.sh` script](https://github.com/lupyuen/bl_iot_sdk/blob/adc/customer_app/sdk_app_rust_gpio/run.sh)\n\n## Generate Rust Wrapper\n\nTo generate the Rust Wrapper...\n\n```bash\n#  Install bindgen and clang: https://rust-lang.github.io/rust-bindgen/requirements.html \ncargo install bindgen\nsudo apt install llvm-dev libclang-dev clang\n\n#  Download the source code\ngit clone --recursive https://github.com/lupyuen/bl602-rust-wrapper\ngit clone --recursive https://github.com/lupyuen/bl_iot_sdk\n\n#  Generate the Rust Bindings for BL602 IoT SDK\ncd bl602-rust-wrapper\nscripts/gen-bindings.sh\n\n#  Build the docs and the test project\nscripts/build.sh\n```\n\n## How It Works\n\nThis script...\n\n-   [`scripts/gen-bindings.sh`](scripts/gen-bindings.sh)\n\nReads the BL602 IoT SDK Header Files...\n\n```c\n//  Function Declarations from BL602 IoT SDK (GPIO HAL)\n//  https://github.com/lupyuen/bl_iot_sdk/blob/master/components/hal_drv/bl602_hal/bl_gpio.h\nint bl_gpio_enable_output(uint8_t pin, uint8_t pullup, uint8_t pulldown);\nint bl_gpio_output_set(uint8_t pin, uint8_t value);\n```\n\nAnd auto-generates the Rust Bindings...\n\n-   [`bl602-sdk/src/gpio.rs`](bl602-sdk/src/gpio.rs)\n-   [`bl602-sdk/src/i2c.rs`](bl602-sdk/src/i2c.rs)\n-   [`bl602-sdk/src/pwm.rs`](bl602-sdk/src/pwm.rs)\n-   [`bl602-sdk/src/spi.rs`](bl602-sdk/src/spi.rs)\n-   [More Bindings](bl602-sdk/src)\n\n```rust\n//  Rust Bindings for BL602 GPIO generated by gen-bindings.sh\n#[safe_wrap(_)] extern \"C\" {\n    pub fn bl_gpio_enable_output(pin: u8, pullup: u8, pulldown: u8) -\u003e ::cty::c_int;\n}\n\n#[safe_wrap(_)] extern \"C\" {\n    pub fn bl_gpio_output_set(pin: u8, value: u8) -\u003e ::cty::c_int;\n}\n```\n\nWhich call the `safe_wrap` Procedural Macro...\n\n-   [`bl602-macros/src/safe_wrap.rs`](bl602-macros/src/safe_wrap.rs)\n\nTo produce the Rust Wrapper for BL602 IoT SDK...\n\n-   [Expanded `safe_wrap` macros: `logs/sdk-expanded.rs`](logs/sdk-expanded.rs)\n\n```rust\n//  Expanded version of `safe_wrap` macros for the GPIO Rust Bindings\n#[doc = \"Configure a GPIO Pin for Output Mode. See `bl_gpio_enable_output` in \\\"Enable GPIO\\\" \u003chttps://lupyuen.github.io/articles/led#enable-gpio\u003e\"]\npub fn enable_output(pin: u8, pullup: u8, pulldown: u8)\n    -\u003e BlResult\u003c()\u003e {\n    \"----------Extern Decl----------\";\n    extern \"C\" {\n        pub fn bl_gpio_enable_output(pin: u8, pullup: u8, pulldown: u8)\n        -\u003e ::cty::c_int;\n    }\n    \"----------Validation----------\";\n    unsafe {\n        \"----------Call----------\";\n        let res =\n            bl_gpio_enable_output(pin as u8, pullup as u8,\n                                    pulldown as u8);\n        \"----------Result----------\";\n        match res { 0 =\u003e Ok(()), _ =\u003e Err(BlError::from(res)), }\n    }\n}\n\n#[doc = \"Set output value of GPIO Pin. See `bl_gpio_output_set` in \\\"Read and Write GPIO\\\" \u003chttps://lupyuen.github.io/articles/led#read-and-write-gpio\u003e\"]\npub fn output_set(pin: u8, value: u8) -\u003e BlResult\u003c()\u003e {\n    \"----------Extern Decl----------\";\n    extern \"C\" {\n        pub fn bl_gpio_output_set(pin: u8, value: u8)\n        -\u003e ::cty::c_int;\n    }\n    \"----------Validation----------\";\n    unsafe {\n        \"----------Call----------\";\n        let res = bl_gpio_output_set(pin as u8, value as u8);\n        \"----------Result----------\";\n        match res { 0 =\u003e Ok(()), _ =\u003e Err(BlError::from(res)), }\n    }\n}\n```\n\nLinks to [\"The RISC-V BL602 Book\"](https://lupyuen.github.io/articles/book) are defined here...\n\n-   [`bl602-sdk/doclinks.md`](bl602-sdk/doclinks.md)\n\n## Build Log\n\nBuild the docs and the test project with this script...\n\n-   [`scripts/build.sh`](scripts/build.sh)\n\n```text\n+ export RUST_BACKTRACE=1\n+ RUST_BACKTRACE=1\n+ rust_build_options='     --target riscv32imacf-unknown-none-elf.json     -Z build-std=core '\n+ pushd bl602-macros\n/mnt/c/pinecone/bl602-rust-wrapper/bl602-macros /mnt/c/pinecone/bl602-rust-wrapper\n+ cargo build\n   Compiling proc-macro2 v1.0.27\n   Compiling unicode-xid v0.2.2\n   Compiling memchr v2.4.0\n   Compiling syn v1.0.73\n   Compiling cty v0.2.1\n   Compiling rustc-serialize v0.3.24\n   Compiling lazy_static v1.4.0\n   Compiling cstr_core v0.2.4\n   Compiling quote v1.0.9\n   Compiling bl602-macros v0.0.2 (/mnt/c/pinecone/bl602-rust-wrapper/bl602-macros)\n    Finished dev [unoptimized + debuginfo] target(s) in 50.67s\n+ popd\n/mnt/c/pinecone/bl602-rust-wrapper\n+ cp bl602-sdk/doclinks.md .\n+ pushd bl602-sdk\n/mnt/c/pinecone/bl602-rust-wrapper/bl602-sdk /mnt/c/pinecone/bl602-rust-wrapper\n+ cargo rustc --target riscv32imacf-unknown-none-elf.json -Z build-std=core -- -Z unstable-options --pretty expanded\n   Compiling compiler_builtins v0.1.47\n   Compiling core v0.0.0 (/home/user/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core)\n   Compiling heapless v0.7.3\n   Compiling rustc-std-workspace-core v1.99.0 (/home/user/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/rustc-std-workspace-core)\n   Compiling byteorder v1.4.3\n   Compiling stable_deref_trait v1.2.0\n   Compiling cty v0.2.1\n   Compiling hash32 v0.2.1\n   Compiling bl602-sdk v0.0.6 (/mnt/c/pinecone/bl602-rust-wrapper/bl602-sdk)\n    Finished dev [unoptimized + debuginfo] target(s) in 33.50s\n+ cargo build --target riscv32imacf-unknown-none-elf.json -Z build-std=core\n   Compiling bl602-sdk v0.0.6 (/mnt/c/pinecone/bl602-rust-wrapper/bl602-sdk)\n    Finished dev [unoptimized + debuginfo] target(s) in 7.85s\n+ cargo doc --target riscv32imacf-unknown-none-elf.json -Z build-std=core\n    Checking unicode-xid v0.2.2\n Documenting unicode-xid v0.2.2\n    Checking cty v0.2.1\n Documenting cty v0.2.1\n    Checking lazy_static v1.4.0\n Documenting rustc-serialize v0.3.24\n    Checking rustc-serialize v0.3.24\n Documenting lazy_static v1.4.0\n    Checking memchr v2.4.0\n Documenting memchr v2.4.0\n    Checking proc-macro2 v1.0.27\n    Checking byteorder v1.4.3\n Documenting byteorder v1.4.3\n    Checking stable_deref_trait v1.2.0\n Documenting stable_deref_trait v1.2.0\n    Checking cstr_core v0.2.4\n Documenting proc-macro2 v1.0.27\n    Checking quote v1.0.9\n Documenting cstr_core v0.2.4\n    Checking hash32 v0.2.1\n    Checking syn v1.0.73\n    Checking heapless v0.7.3\n Documenting hash32 v0.2.1\n Documenting quote v1.0.9\n Documenting heapless v0.7.3\n Documenting syn v1.0.73\n Documenting bl602-macros v0.0.2 (/mnt/c/pinecone/bl602-rust-wrapper/bl602-macros)\n Documenting bl602-sdk v0.0.6 (/mnt/c/pinecone/bl602-rust-wrapper/bl602-sdk)\n    Finished dev [unoptimized + debuginfo] target(s) in 48.79s\n+ popd\n/mnt/c/pinecone/bl602-rust-wrapper\n+ echo 'Moved to [`bl602-sdk/doclinks.md`](bl602-sdk/doclinks.md)'\n+ cp -r target/riscv32imacf-unknown-none-elf/doc/bl602_sdk docs    \n+ cp -r target/riscv32imacf-unknown-none-elf/doc/src docs\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flupyuen%2Fbl602-rust-wrapper","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flupyuen%2Fbl602-rust-wrapper","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flupyuen%2Fbl602-rust-wrapper/lists"}