Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions drivers/flash/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,14 @@

load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")

rust_library(
name = "opcode",
srcs = ["opcode.rs"],
crate_name = "spi_flash_opcode",
edition = "2024",
visibility = ["//visibility:public"],
)

rust_library(
name = "spi_flash",
srcs = ["spi_flash.rs"],
Expand All @@ -13,6 +21,7 @@ rust_library(
],
visibility = ["//visibility:public"],
deps = [
":opcode",
"//hal/blocking/flash",
"//hal/blocking/flash:driver",
"//util/error",
Expand Down
103 changes: 103 additions & 0 deletions drivers/flash/opcode.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
// Licensed under the Apache-2.0 license
// SPDX-License-Identifier: Apache-2.0

//! Standard SPI Flash opcodes.

#![no_std]

use core::ops::Deref;

/// Standard SPI Flash Command Opcode.
#[derive(Clone, Copy, PartialEq, Eq, Debug, Default)]
#[repr(transparent)]
pub struct Opcode(pub u8);

impl Opcode {
// Read commands
pub const READ: Self = Self(0x03);
pub const FAST_READ: Self = Self(0x0B);
pub const FAST_QUAD_READ: Self = Self(0x6B);
pub const READ_4B: Self = Self(0x13);
pub const FAST_QUAD_READ_4B: Self = Self(0x6C);

// Program commands
pub const PAGE_PROGRAM: Self = Self(0x02);
pub const PAGE_PROGRAM_QUAD: Self = Self(0x32);
pub const PAGE_PROGRAM_4B: Self = Self(0x12);
pub const PAGE_PROGRAM_QUAD_4B: Self = Self(0x34);

// Erase commands
pub const SECTOR_ERASE: Self = Self(0x20);
pub const SECTOR_ERASE_4B: Self = Self(0x21);
pub const BLOCK_ERASE_32K: Self = Self(0x52);
pub const BLOCK_ERASE_32K_4B: Self = Self(0x5C);
pub const BLOCK_ERASE_64K: Self = Self(0xD8);
pub const BLOCK_ERASE_64K_4B: Self = Self(0xDC);
pub const CHIP_ERASE: Self = Self(0xC7);
pub const CHIP_ERASE2: Self = Self(0x60);

// Control and Status commands
pub const WRITE_ENABLE: Self = Self(0x06);
pub const WRITE_DISABLE: Self = Self(0x04);
pub const READ_STATUS: Self = Self(0x05);
pub const WRITE_STATUS: Self = Self(0x01);
pub const WRITE_EAR: Self = Self(0xC5);
pub const ENTER_4B_ADDR_MODE: Self = Self(0xB7);
pub const EXIT_4B_ADDR_MODE: Self = Self(0xE9);
pub const RESET_ENABLE: Self = Self(0x66);
pub const RESET: Self = Self(0x99);

// Identification and Parameters commands
pub const SFDP: Self = Self(0x5A);
pub const JEDEC_ID: Self = Self(0x9F);
}

impl Deref for Opcode {
type Target = u8;

fn deref(&self) -> &Self::Target {
&self.0
}
}

impl From<u8> for Opcode {
fn from(val: u8) -> Self {
Self(val)
}
}

impl From<Opcode> for u8 {
fn from(val: Opcode) -> Self {
val.0
}
}

impl From<Opcode> for u32 {
fn from(val: Opcode) -> Self {
val.0 as u32
}
}

// Backward-compatible u8 constants mapped to canonical Opcode definitions
pub const OP_STATUS: u8 = Opcode::READ_STATUS.0;
pub const OP_WRITE_EN: u8 = Opcode::WRITE_ENABLE.0;
pub const OP_WR_STATUS: u8 = Opcode::WRITE_STATUS.0;
pub const OP_WR_EAR: u8 = Opcode::WRITE_EAR.0;
pub const OP_READ: u8 = Opcode::READ.0;
pub const OP_QREAD: u8 = Opcode::FAST_QUAD_READ.0;
pub const OP_READ4B: u8 = Opcode::READ_4B.0;
pub const OP_QREAD4B: u8 = Opcode::FAST_QUAD_READ_4B.0;
pub const OP_CHIP_ERASE: u8 = Opcode::CHIP_ERASE.0;
pub const OP_ERASE_4K: u8 = Opcode::SECTOR_ERASE.0;
pub const OP_ERASE4B_4K: u8 = Opcode::SECTOR_ERASE_4B.0;
pub const OP_ERASE_64K: u8 = Opcode::BLOCK_ERASE_64K.0;
pub const OP_ERASE4B_64K: u8 = Opcode::BLOCK_ERASE_64K_4B.0;
pub const OP_PROGRAM: u8 = Opcode::PAGE_PROGRAM.0;
pub const OP_QPROGRAM: u8 = Opcode::PAGE_PROGRAM_QUAD.0;
pub const OP_PROGRAM4B: u8 = Opcode::PAGE_PROGRAM_4B.0;
pub const OP_QPROGRAM4B: u8 = Opcode::PAGE_PROGRAM_QUAD_4B.0;
pub const OP_SFDP_READ: u8 = Opcode::SFDP.0;
pub const OP_RESET_ENABLE: u8 = Opcode::RESET_ENABLE.0;
pub const OP_RESET: u8 = Opcode::RESET.0;
pub const OP_READ_JEDEC_ID: u8 = Opcode::JEDEC_ID.0;
pub const OP_ENTER_4B_ADDR_MODE: u8 = Opcode::ENTER_4B_ADDR_MODE.0;
23 changes: 1 addition & 22 deletions drivers/flash/spi_flash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -462,28 +462,7 @@ pub struct Status {
reserved7: bool,
}

const OP_STATUS: u8 = 0x05;
const OP_WRITE_EN: u8 = 0x06;
const OP_WR_STATUS: u8 = 0x01;
const OP_WR_EAR: u8 = 0xC5;
const OP_READ: u8 = 0x03;
const OP_QREAD: u8 = 0x6B;
const OP_READ4B: u8 = 0x13;
const OP_QREAD4B: u8 = 0x6C;
const OP_CHIP_ERASE: u8 = 0xC7;
const OP_ERASE_4K: u8 = 0x20;
const OP_ERASE4B_4K: u8 = 0x21;
const OP_ERASE_64K: u8 = 0xD8;
const OP_ERASE4B_64K: u8 = 0xDC;
const OP_PROGRAM: u8 = 0x02;
const OP_QPROGRAM: u8 = 0x32;
const OP_PROGRAM4B: u8 = 0x12;
const OP_QPROGRAM4B: u8 = 0x34;
const OP_SFDP_READ: u8 = 0x5a;
const OP_RESET_ENABLE: u8 = 0x66;
const OP_RESET: u8 = 0x99;
const OP_READ_JEDEC_ID: u8 = 0x9f;
const OP_ENTER_4B_ADDR_MODE: u8 = 0xB7;
pub use spi_flash_opcode::*;

/// A RandomRead implementation that can be used to access SFDP bytes.
pub struct SfdpRandRead<'a, S: embedded_hal::spi::SpiDevice> {
Expand Down
16 changes: 16 additions & 0 deletions target/earlgrey/drivers/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -104,3 +104,19 @@ rust_library(
"@ureg",
],
)

rust_library(
name = "spi_device",
srcs = ["spi_device.rs"],
crate_name = "earlgrey_spi_device",
edition = "2024",
visibility = ["//visibility:public"],
deps = [
"//drivers/flash:opcode",
"//target/earlgrey/registers:spi_device",
"//util/error",
"//util/regcpy",
"@rust_crates//:aligned",
"@ureg",
],
)
Loading