Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Flash #22

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
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
130 changes: 23 additions & 107 deletions kampela-system/src/devices/flash.rs
Original file line number Diff line number Diff line change
@@ -1,39 +1,40 @@
use efm32pg23_fix::{Peripherals};
use crate::peripherals::usart::*;
use cortex_m::asm::delay;
use core::ops::{Shl, Shr};


#[allow(dead_code)]
#[repr(u8)]
enum FlashCommand {
WriteEnable = 0x06, /* 06 xx xx xx xx sets the (WEL) write enable latch bit */
WriteDisable = 0x04, /* 04 xx xx xx xx resets the (WEL) write enable latch bit*/
ReadId = 0x9f, /* 9f xx xx xx xx outputs JEDEC ID: 1 byte manufacturer ID & 2 byte device ID */
ReadDiscoverableParameters = 0x5A, /* 5A xx xx xx xx Serial Flash Discoverable Parameters */
ReadStatusRegister = 0x05, /* 05 xx xx xx xx to read out the values of the status register */
// ReadStatusRegister = 0x05, /* 05 xx xx xx xx to read out the values of the status register */
ReadStatusRegisterAdressed = 0x65,
WriteStatusRegister = 0x01, /* 01 xx xx xx xx to write new values to the status register */
// WriteStatusRegister = 0x01, /* 01 xx xx xx xx to write new values to the status register */
WriteStatusRegisterAdressed = 0x71,
Read = 0x03, /* 03 a1 a2 a3 xx n bytes read out until CS# goes high */
FastRead = 0x0b, /* 0b a1 a2 a3 dd n bytes read out until CS# goes high */
Read2 = 0xbb, /* bb 12 3d xx xx n bytes read out by 2 I/O until CS# goes high */
Read4 = 0xeb, /* eb 3a 3d xx xx n bytes read out by 4 x I/O until CS# goes high */
// FastRead = 0x0b, /* 0b a1 a2 a3 dd n bytes read out until CS# goes high */
// Read2 = 0xbb, /* bb 12 3d xx xx n bytes read out by 2 I/O until CS# goes high */
// Read4 = 0xeb, /* eb 3a 3d xx xx n bytes read out by 4 x I/O until CS# goes high */
ErasePage = 0x81, /* 20 a1 a2 a3 xx to erase the selected page 256 bytes */
EraseSector = 0x20, /* 20 a1 a2 a3 xx to erase the selected sector */
EraseBlock = 0xd8, /* d8 a1 a2 a3 xx to erase the selected block */
EraseChip = 0x60, /* 60 xx xx xx xx to erase whole chip (cmd or 0xc7) */
// EraseSector = 0x20, /* 20 a1 a2 a3 xx to erase the selected sector */
// EraseBlock = 0xd8, /* d8 a1 a2 a3 xx to erase the selected block */
// EraseChip = 0x60, /* 60 xx xx xx xx to erase whole chip (cmd or 0xc7) */
WritePage = 0x02, /* 02 a1 a2 a3 xx to program the selected page */
WritePage4 = 0x38, /* 38 3a 3d xx xx quad input to program the selected page */
WriteContinously = 0xad, /* ad a1 a2 a3 xx continously program whole chip, the address is automaticlly increase */
DeepPowerDown = 0xb9, /* b9 xx xx xx xx enters deep power down mode */
// WritePage4 = 0x38, /* 38 3a 3d xx xx quad input to program the selected page */
// WriteContinously = 0xad, /* ad a1 a2 a3 xx continously program whole chip, the address is automaticlly increase */
// DeepPowerDown = 0xb9, /* b9 xx xx xx xx enters deep power down mode */
UltraDeepPowerDown = 0x79, /* 79 Ultra-Deep Power-Down mode */
ResumeFromPowerDown = 0xab, /* ab xx xx xx xx release from deep power down mode */
ReadIdMfid = 0x90, /* 90 ?? ?? ?? xx output the manufacter ID & device ID */
EnterSecuredMode = 0xb1, /* b1 xx xx xx xx to enter the 512 bit secured OTP mode */
ExitSecuredMode = 0xc1, /* c1 xx xx xx xx to exit the 512 bit secured OTP mode */
ReadSecuredRegister = 0x2b, /* 2b xx xx xx xx to read value of secured register */
WriteSecuredRegister = 0x2f, /* 2f xx xx xx xx to set the lock down bit as "1" (once lock down, can not be updated) */
EnableStatusOutput = 0x70,/* 70 xx xx xx xx to enable SO to output RY/BY# during CP mode */
DisableStatusOutput = 0x80,/* 80 xx xx xx xx to disable SO to output RY/BY# during CP mode */
// ReadIdMfid = 0x90, /* 90 ?? ?? ?? xx output the manufacter ID & device ID */
// EnterSecuredMode = 0xb1, /* b1 xx xx xx xx to enter the 512 bit secured OTP mode */
// ExitSecuredMode = 0xc1, /* c1 xx xx xx xx to exit the 512 bit secured OTP mode */
// ReadSecuredRegister = 0x2b, /* 2b xx xx xx xx to read value of secured register */
// WriteSecuredRegister = 0x2f, /* 2f xx xx xx xx to set the lock down bit as "1" (once lock down, can not be updated) */
// EnableStatusOutput = 0x70,/* 70 xx xx xx xx to enable SO to output RY/BY# during CP mode */
// DisableStatusOutput = 0x80,/* 80 xx xx xx xx to disable SO to output RY/BY# during CP mode */
ActiveStatus = 0x25, /* Outputs ready/busy state to data output pin */
EnableSoftReset = 0x66,
SoftReset = 0x99,
Expand Down Expand Up @@ -64,7 +65,7 @@ fn flash_read_u32(peripherals: &mut Peripherals) -> u32 {
let mut res: u32 = 0;
for _ in 0..4 {
res >>= 8;
res |= (write_to_usart(peripherals, 0) as u32) << 24;
res |= (write_to_usart(peripherals, 0) as u32).shl(24);
}
res
}
Expand Down Expand Up @@ -117,95 +118,11 @@ pub fn flash_lock(peripherals: &mut Peripherals) {
macro_rules! flash_write_addr {
( $( $periph: tt, $addr: tt ),* ) => {
$(
flash_write_some($periph, &[(($addr>>16)&0xff) as u8, (($addr>>8)&0xff) as u8, ($addr&0xff)as u8]);
flash_write_some($periph, &[($addr.shr(16) as u8)&0xff, ($addr.shr(8) as u8)&0xff, ($addr as u8)&0xff]);
)*
};
}

#[allow(dead_code)]
enum StatusRegister {
SR1 = 0x01,
SR2 = 0x02,
SR3 = 0x03,
SR4 = 0x04,
SR5 = 0x05,
}

#[allow(dead_code)]
enum StatusRegister1 {
/**
* SRP0 works with the SRP1 bit in Status Register 1 and the WP
* pin to control write protection. Types of protection include software
* protection, hardware protection, one-time programmable (OTP)
* protection, and power supply lock-down protectio
*/
StatusRegisterProtect0 = 1<<7,
/**
* BPSIZE controls the size of the blocks protected by the Block
* Protect Bits (BP2, BP1, BP0 in bits 4:2 of this register). Its
* encoding is:
* 0: 64 kB block size
* 1: 4 kB block size
* The blocks can be protected from the bottom up, or from the top
* down, as described in the TB bit of this register
*/
BlockProtectSize0 = 1<<6,
/**
* TB controls the direction of the blocks to be protected by the
* Block Protect Bits (BP2, BP1, BP0 in bits 4:2 of this register). Its
* encoding is:
* 0: Protect from bottom up
* 1: Protect from top down
* The size of the protected blocks can also be selected, as
* described in the BPSIZE bit of this register.
*/
TopBottom = 1<<5,
/**
* The Block Protect field provides write protection control and
* status. These bits are set using the Write Status Register 1 (01h)
* command. This field can be programmed to protect all, none, or a
* portion of the memory array. When that portion of the memory is
* selected, it is protected from the Program and Erase commands
* as described in the Memory Protection table.
* The default is 3’b000 for this field, indicating that none of the
* memory array is protected.
*/
BlockProtect2 = 1<<4,
BlockProtect1 = 1<<3,
BlockProtect0 = 1<<2,
/**
* WEL gives the current status of the internal Write Enable Latch.
* When WEL is logic 0, the device does not accept any program,
* erase, memory protection, or Write Status Register commands.
* WEL defaults to logic 0 after a device power-up or reset.
* Its encoding is:
* 0: Device is not write enabled (default).
* 1: Device is write enabled.
* If WEL is 1, it is not reset to a logic 0 if an operation aborts due to
* an incomplete or unrecognized command being clocked into the
* device before the CS pin is deasserted.
* To reset the WEL bit when an operation aborts prematurely, the
* entire command for a program, erase, memory protection, or Write
* Status Register command must have been clocked into the
* device.
* When the Write Enable (06h) command is executed, the WEL bit
* is set. Conversely, when the Volatile Status Register Write Enable
* (50h) command is executed, the WEL bit is not set
*/
WriteEnableLatchStatus = 1<<1,
/**
* RDY/BSY determines if an internal operation, such as a program
* or erase, is in progress. To poll the RDY/BSY bit to detect the
* completion of a program or erase cycle, new Status Register data
* must be continually clocked out of the device until the state of the
* RDY/BSY bit changes from a logic 1 to a logic 0.
* Its encoding is:
* 0: Device is ready.
* 1: Device is busy with an internal operation.
*/
BusyStatus = 1<<0,
}

pub fn flash_read_sr(peripherals: &mut Peripherals) -> [u8;6] {

let mut res = [0u8; 6];
Expand Down Expand Up @@ -262,7 +179,7 @@ pub fn flash_get_size(peripherals: &mut Peripherals) -> u32 {
flash_cmd(peripherals, FlashCommand::ReadDiscoverableParameters);
let mut jdt_head: [u8; 12] = [0; 12];
flash_read_some(peripherals, &mut jdt_head);
let size_offset = ((1 + jdt_head[11]) as usize) << 3 + 4;
let size_offset: usize = ((jdt_head[10] as usize) + 1).shl(3) + 4_usize;
for _ in 0..size_offset {
write_to_usart(peripherals, 0);
}
Expand All @@ -283,7 +200,6 @@ pub fn flash_read(peripherals: &mut Peripherals, addr: u32, data: &mut [u8]) {
select_flash(&mut peripherals.GPIO_S);
flash_cmd(peripherals, FlashCommand::Read);
flash_write_addr!(peripherals, addr);
// flash_write_some(peripherals, &[0u8, 0u8, 0u8]);
flash_read_some(peripherals, data);
deselect_flash(&mut peripherals.GPIO_S);
}