-
Notifications
You must be signed in to change notification settings - Fork 48
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
Changes to Flash.rs #83
Merged
Merged
Changes from 5 commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
d99ba9d
Changes to Flash.rs
amcelroy 9b31810
Added changes systec-ms
amcelroy b6466d7
FlashWriter.write requires additional user input
amcelroy 883ca94
Merge branch 'stm32-rs:main' into flash_patches
amcelroy fcc39d3
Merge branch 'stm32-rs:main' into flash_patches
amcelroy f5fdae3
Post review changes
amcelroy File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,220 @@ | ||
#![allow(unsafe_code)] | ||
#![allow(warnings)] | ||
#![allow(missing_docs)] | ||
#![allow(unused_variables)] | ||
#![no_main] | ||
#![no_std] | ||
|
||
#[rtic::app(device = stm32g4xx_hal::stm32g4::stm32g474, peripherals = true)] | ||
mod app { | ||
use stm32g4xx_hal::flash::{FlashExt, FlashSize, FlashWriter, Parts}; | ||
use stm32g4xx_hal::prelude::*; | ||
use stm32g4xx_hal::rcc::{PllConfig, RccExt}; | ||
|
||
use panic_halt as _; // you can put a breakpoint on `rust_begin_unwind` to catch panics | ||
|
||
// Resources shared between tasks | ||
#[shared] | ||
struct Shared {} | ||
|
||
// Local resources to specific tasks (cannot be shared) | ||
#[local] | ||
struct Local {} | ||
|
||
fn compare_arrays(a: &[u8], b: &[u8]) -> bool { | ||
if a.len() != b.len() { | ||
return false; | ||
} | ||
for i in 0..a.len() { | ||
if a[i] != b[i] { | ||
return false; | ||
} | ||
} | ||
true | ||
} | ||
|
||
#[init] | ||
fn init(cx: init::Context) -> (Shared, Local, init::Monotonics) { | ||
// let dp = Peripherals::take().unwrap(); | ||
// let cp = cortex_m::Peripherals::take().expect("cannot take core peripherals"); | ||
|
||
let dp = cx.device; | ||
let cp = cx.core; | ||
|
||
let rcc = dp.RCC.constrain(); | ||
let mut pll_config = stm32g4xx_hal::rcc::PllConfig::default(); | ||
|
||
// Sysclock is based on PLL_R | ||
pll_config.mux = stm32g4xx_hal::rcc::PLLSrc::HSI; // 16MHz | ||
pll_config.n = stm32g4xx_hal::rcc::PllNMul::MUL_32; | ||
pll_config.m = stm32g4xx_hal::rcc::PllMDiv::DIV_2; // f(vco) = 16MHz*32/2 = 256MHz | ||
pll_config.r = Some(stm32g4xx_hal::rcc::PllRDiv::DIV_2); // f(sysclock) = 256MHz/2 = 128MHz | ||
|
||
// Note to future self: The AHB clock runs the timers, among other things. | ||
// Please refer to the Clock Tree manual to determine if it is worth | ||
// changing to a lower speed for battery life savings. | ||
let mut clock_config = stm32g4xx_hal::rcc::Config::default() | ||
.pll_cfg(pll_config) | ||
.clock_src(stm32g4xx_hal::rcc::SysClockSrc::PLL); | ||
|
||
// After clock configuration, the following should be true: | ||
// Sysclock is 128MHz | ||
// AHB clock is 128MHz | ||
// APB1 clock is 128MHz | ||
// APB2 clock is 128MHz | ||
// The ADC will ultimately be put into synchronous mode and will derive | ||
// its clock from the AHB bus clock, with a prescalar of 2 or 4. | ||
|
||
let mut rcc = rcc.freeze(clock_config); | ||
|
||
unsafe { | ||
let mut flash = &(*stm32g4xx_hal::stm32::FLASH::ptr()); | ||
flash.acr.modify(|_, w| { | ||
w.latency().bits(0b1000) // 8 wait states | ||
}); | ||
} | ||
|
||
// *** FLASH Memory *** | ||
//let mut data = [0xBE, 0xEF, 0xCA, 0xFE]; | ||
let one_byte = [0x12 as u8]; | ||
let two_bytes = [0xAB, 0xCD as u8]; | ||
let three_bytes = [0x12, 0x34, 0x56 as u8]; | ||
let four_bytes = [0xAB, 0xCD, 0xEF, 0xBA as u8]; | ||
let eight_bytes = [0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0 as u8]; | ||
let sixteen_bytes = [ | ||
0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, | ||
0xDE, 0xF0 as u8, | ||
]; | ||
let mut flash = dp.FLASH.constrain(); | ||
let mut flash_writer = flash.writer::<2048>(FlashSize::Sz256K); | ||
const FLASH_SPACING: u32 = 16; // Separate flash writes by 16 bytes | ||
|
||
flash_writer.erase(0x1FC00, 128).unwrap(); // Erase entire page | ||
|
||
for i in 0..6 { | ||
match i { | ||
0 => { | ||
// This test should fail, as the data needs to be divisible by 8 and force padding is false | ||
let result = flash_writer.write(0x1FC00 + i * FLASH_SPACING, &one_byte, false); | ||
assert!(result.is_err()); | ||
no111u3 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
assert_eq!( | ||
result.err().unwrap(), | ||
stm32g4xx_hal::flash::Error::ArrayMustBeDivisibleBy8 | ||
); | ||
|
||
// This test should pass, as the data needs to be divisible by 8 and force padding is true, so the one_byte array will be padded with 7 bytes of 0xFF | ||
let result = flash_writer.write(0x1FC00 + i * FLASH_SPACING, &one_byte, true); | ||
assert!(result.is_ok()); | ||
} | ||
1 => { | ||
// This test should fail, as the data needs to be divisible by 8 and force padding is false | ||
let result = flash_writer.write(0x1FC00 + i * FLASH_SPACING, &two_bytes, false); | ||
assert!(result.is_err()); | ||
assert_eq!( | ||
result.err().unwrap(), | ||
stm32g4xx_hal::flash::Error::ArrayMustBeDivisibleBy8 | ||
); | ||
|
||
// This test should pass, as the data needs to be divisible by 8 and force padding is true, so the one_byte array will be padded with 7 bytes of 0xFF | ||
let result = flash_writer.write(0x1FC00 + i * FLASH_SPACING, &two_bytes, true); | ||
assert!(result.is_ok()); | ||
} | ||
2 => { | ||
// This test should fail, as the data needs to be divisible by 8 and force padding is false | ||
let result = | ||
flash_writer.write(0x1FC00 + i * FLASH_SPACING, &three_bytes, false); | ||
assert!(result.is_err()); | ||
assert_eq!( | ||
result.err().unwrap(), | ||
stm32g4xx_hal::flash::Error::ArrayMustBeDivisibleBy8 | ||
); | ||
|
||
// This test should pass, as the data needs to be divisible by 8 and force padding is true, so the one_byte array will be padded with 7 bytes of 0xFF | ||
let result = | ||
flash_writer.write(0x1FC00 + i * FLASH_SPACING, &three_bytes, true); | ||
assert!(result.is_ok()); | ||
} | ||
3 => { | ||
// This test should fail, as the data needs to be divisible by 8 and force padding is false | ||
let result = | ||
flash_writer.write(0x1FC00 + i * FLASH_SPACING, &four_bytes, false); | ||
assert!(result.is_err()); | ||
assert_eq!( | ||
result.err().unwrap(), | ||
stm32g4xx_hal::flash::Error::ArrayMustBeDivisibleBy8 | ||
); | ||
|
||
// This test should pass, as the data needs to be divisible by 8 and force padding is true, so the one_byte array will be padded with 7 bytes of 0xFF | ||
let result = flash_writer.write(0x1FC00 + i * FLASH_SPACING, &four_bytes, true); | ||
assert!(result.is_ok()); | ||
} | ||
4 => flash_writer | ||
.write(0x1FC00 + i * FLASH_SPACING, &eight_bytes, false) | ||
.unwrap(), | ||
5 => flash_writer | ||
.write(0x1FC00 + i * 16, &sixteen_bytes, false) | ||
.unwrap(), | ||
_ => (), | ||
} | ||
} | ||
|
||
for i in 0..6 { | ||
match i { | ||
0 => { | ||
let bytes = flash_writer.read(0x1FC00 as u32, one_byte.len()).unwrap(); | ||
assert!(compare_arrays(&bytes, &one_byte)); | ||
} | ||
1 => { | ||
let bytes = flash_writer | ||
.read(0x1FC00 + i * FLASH_SPACING, two_bytes.len()) | ||
.unwrap(); | ||
assert!(compare_arrays(&bytes, &two_bytes)); | ||
} | ||
2 => { | ||
let bytes = flash_writer | ||
.read(0x1FC00 + i * FLASH_SPACING, three_bytes.len()) | ||
.unwrap(); | ||
assert!(compare_arrays(&bytes, &three_bytes)); | ||
} | ||
3 => { | ||
let bytes = flash_writer | ||
.read(0x1FC00 + i * FLASH_SPACING, four_bytes.len()) | ||
.unwrap(); | ||
assert!(compare_arrays(&bytes, &four_bytes)); | ||
} | ||
4 => { | ||
let bytes = flash_writer | ||
.read(0x1FC00 + i * FLASH_SPACING, eight_bytes.len()) | ||
.unwrap(); | ||
assert!(compare_arrays(&bytes, &eight_bytes)); | ||
} | ||
5 => { | ||
let bytes = flash_writer | ||
.read(0x1FC00 + i * FLASH_SPACING, sixteen_bytes.len()) | ||
.unwrap(); | ||
assert!(compare_arrays(&bytes, &sixteen_bytes)); | ||
} | ||
_ => (), | ||
} | ||
} | ||
|
||
( | ||
// Initialization of shared resources | ||
Shared {}, | ||
// Initialization of task local resources | ||
Local {}, | ||
// Move the monotonic timer to the RTIC run-time, this enables | ||
// scheduling | ||
init::Monotonics(), | ||
) | ||
} | ||
|
||
// Background task, runs whenever no other tasks are running | ||
#[idle] | ||
fn idle(mut cx: idle::Context) -> ! { | ||
loop { | ||
// Sleep until next interrupt | ||
cortex_m::asm::wfi(); | ||
} | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use constant instead magic numbers