From 4e4267e55aca033c5269bdebfdbd43a0aaaa3019 Mon Sep 17 00:00:00 2001 From: Harry Ho Date: Mon, 15 Jun 2020 15:40:39 +0800 Subject: [PATCH] Add reading SFR registers via SPI * uses stm32f4xx_hal crate --- Cargo.lock | 293 +++++++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 28 +++++ src/lib.rs | 4 + src/spi.rs | 84 +++++++++++++++ 4 files changed, 409 insertions(+) create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 src/lib.rs create mode 100644 src/spi.rs diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..6cf48df --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,293 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "aligned" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb1ce8b3382016136ab1d31a1b5ce807144f8b7eb2d5f16b2108f0f07edceb94" +dependencies = [ + "as-slice", +] + +[[package]] +name = "as-slice" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37dfb65bc03b2bc85ee827004f14a6817e04160e3b1a28931986a666a9290e70" +dependencies = [ + "generic-array 0.12.3", + "generic-array 0.13.2", + "stable_deref_trait", +] + +[[package]] +name = "bare-metal" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5deb64efa5bd81e31fcd1938615a6d98c82eafcbcd787162b6f63b91d6bac5b3" +dependencies = [ + "rustc_version", +] + +[[package]] +name = "bitflags" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" + +[[package]] +name = "byteorder" +version = "1.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" + +[[package]] +name = "cast" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b9434b9a5aa1450faa3f9cb14ea0e8c53bb5d2b3c1bfd1ab4fc03e9f33fbfb0" +dependencies = [ + "rustc_version", +] + +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[package]] +name = "cortex-m" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2954942fbbdd49996704e6f048ce57567c3e1a4e2dc59b41ae9fde06a01fc763" +dependencies = [ + "aligned", + "bare-metal", + "volatile-register", +] + +[[package]] +name = "cortex-m-rt" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00d518da72bba39496024b62607c1d8e37bcece44b2536664f1132a73a499a28" +dependencies = [ + "cortex-m-rt-macros", + "r0", +] + +[[package]] +name = "cortex-m-rt-macros" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4717562afbba06e760d34451919f5c3bf3ac15c7bb897e8b04862a7428378647" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "embedded-hal" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee4908a155094da7723c2d60d617b820061e3b4efcc3d9e293d206a5a76c170b" +dependencies = [ + "nb", + "void", +] + +[[package]] +name = "enc424j600" +version = "0.1.0" +dependencies = [ + "aligned", + "log", + "smoltcp", + "stm32f4xx-hal", + "volatile-register", +] + +[[package]] +name = "generic-array" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec" +dependencies = [ + "typenum", +] + +[[package]] +name = "generic-array" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ed1e761351b56f54eb9dcd0cfaca9fd0daecf93918e1cfc01c8a3d26ee7adcd" +dependencies = [ + "typenum", +] + +[[package]] +name = "log" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "managed" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c75de51135344a4f8ed3cfe2720dc27736f7711989703a0b43aadf3753c55577" + +[[package]] +name = "nb" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1411551beb3c11dedfb0a90a0fa256b47d28b9ec2cdff34c25a2fa59e45dbdc" + +[[package]] +name = "proc-macro2" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "beae6331a816b1f65d04c45b078fd8e6c93e8071771f41b8163255bbd8d7c8fa" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r0" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2a38df5b15c8d5c7e8654189744d8e396bddc18ad48041a500ce52d6948941f" + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" + +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +dependencies = [ + "semver", +] + +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" + +[[package]] +name = "smoltcp" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fe46639fd2ec79eadf8fe719f237a7a0bd4dac5d957f1ca5bbdbc1c3c39e53a" +dependencies = [ + "bitflags", + "byteorder", + "log", + "managed", +] + +[[package]] +name = "stable_deref_trait" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8" + +[[package]] +name = "stm32f4" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11460b4de3a84f072e2cf6e76306c64d27f405a0e83bace0a726f555ddf4bf33" +dependencies = [ + "bare-metal", + "cortex-m", + "vcell", +] + +[[package]] +name = "stm32f4xx-hal" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3a2f044469d1e3aff2cd02bee8b2724f3d5d91f3175e5d1ec99770320d16192" +dependencies = [ + "bare-metal", + "cast", + "cortex-m", + "cortex-m-rt", + "embedded-hal", + "nb", + "rand_core", + "stm32f4", + "void", +] + +[[package]] +name = "syn" +version = "1.0.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5304cfdf27365b7585c25d4af91b35016ed21ef88f17ced89c7093b43dba8b6" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "typenum" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33" + +[[package]] +name = "unicode-xid" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" + +[[package]] +name = "vcell" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "876e32dcadfe563a4289e994f7cb391197f362b6315dc45e8ba4aa6f564a4b3c" + +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" + +[[package]] +name = "volatile-register" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d67cb4616d99b940db1d6bd28844ff97108b498a6ca850e5b6191a532063286" +dependencies = [ + "vcell", +] diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..581538d --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,28 @@ +[package] +categories = ["embedded", "no-std"] +name = "enc424j600" +description = "Embbeded Rust Ethernet driver for ENC424J600 Ethernet controller with SPI interface, compatible with STM32F4xx" +authors = ["Harry Ho "] +version = "0.1.0" +keywords = ["ethernet", "eth", "enc424j600", "stm32", "stm32f4xx"] +repository = "https://github.com/smoltcp-rs/ENC424J600" +edition = "2018" + +[dependencies] +volatile-register = "0.2" +aligned = "0.3" +stm32f4xx-hal = { version = "0.8" , optional = true } +smoltcp = { version = "0.6.0", default-features = false, features = ["proto-ipv4", "proto-ipv6", "socket-icmp", "socket-udp", "socket-tcp", "log", "verbose", "ethernet"], optional = true } +log = { version = "0.4", optional = true } + +[features] +smoltcp-phy = ["smoltcp", "log"] +stm32f407 = ["stm32f4xx-hal/stm32f407"] +default = [] + +[profile.release] +codegen-units = 1 +incremental = false +debug = true +opt-level = "s" +lto = true diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..544911f --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,4 @@ +#![no_std] + +/// STM32F4xx-HAL specific implementations +pub mod spi; diff --git a/src/spi.rs b/src/spi.rs new file mode 100644 index 0000000..4977290 --- /dev/null +++ b/src/spi.rs @@ -0,0 +1,84 @@ +use core::fmt; +use stm32f4xx_hal::{ + hal::{ + blocking::spi::Transfer, + digital::v2::OutputPin, + }, + time::MegaHertz, + spi, +}; + +/// Must use SPI mode cpol=0, cpha=0 +pub const SPI_MODE: spi::Mode = spi::Mode { + polarity: spi::Polarity::IdleLow, + phase: spi::Phase::CaptureOnFirstTransition, +}; +/// Max freq = 14 MHz +pub const SPI_CLOCK: MegaHertz = MegaHertz(14); + +/// SPI Opcodes +const RCRU: u8 = 0b00100000; +const WCRU: u8 = 0b00100010; + +/// Struct for SPI I/O interface on ENC424J600 +/// Note: stm32f4xx_hal::spi's pins include: SCK, MISO, MOSI +pub struct SpiPort, + NSS: OutputPin> { + spi: SPI, + nss: NSS, +} + +impl , + NSS: OutputPin, + E: fmt::Debug> SpiPort { + // TODO: return as Result() + pub fn new(spi: SPI, mut nss: NSS) -> Self { + nss.set_high(); + + SpiPort { + spi, + nss + } + } + + pub fn read_reg_8b(&mut self, addr: u8) -> Result { + // Using RCRU instruction to read using unbanked (full) address + let mut r_data = self.transfer(RCRU, addr, 0)?; + Ok(r_data) + } + + pub fn read_reg_16b(&mut self, lo_addr: u8) -> Result { + let mut r_data_lo = self.read_reg_8b(lo_addr)?; + let mut r_data_hi = self.read_reg_8b(lo_addr + 1)?; + // Combine top and bottom 8-bit to return 16-bit + Ok(((r_data_hi as u16) << 8) | r_data_lo as u16) + } + + pub fn write_reg_8b(&mut self, addr: u8, data: u8) -> Result { + // TODO: addr should be separated from w_data + // Using WCRU instruction to write using unbanked (full) address + self.transfer(WCRU, addr, data)?; + Ok(0x01) // TODO: should not be just 0x01 + } + + fn transfer(&mut self, opcode: u8, addr: u8, data: u8) + -> Result { + // TODO: Currently assumes read/write data is only 1-byte + // Enable chip select + self.nss.set_low(); + // Start writing to SLAVE + // TODO: don't just use 3 bytes + let mut buf: [u8; 3] = [0; 3]; + buf[0] = opcode; + buf[1] = addr; + buf[2] = data; + let result = self.spi.transfer(&mut buf); + // Disable chip select + self.nss.set_high(); + + match result { + Ok(_) => Ok(buf[2]), + Err(e) => Err(e), + } + } +} \ No newline at end of file