Skip to content

Commit 0d9c436

Browse files
committed
feat: add core register read and write functions
1 parent 8c7460d commit 0d9c436

File tree

8 files changed

+153
-6
lines changed

8 files changed

+153
-6
lines changed
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/**
2+
* @brief Undocumented API functions for STM32CubeProgrammer
3+
* Credits to: https://github.com/wervin/stm32cubeprog-rs
4+
*/
5+
6+
#pragma once
7+
8+
#ifdef __cplusplus
9+
extern "C" {
10+
#endif
11+
12+
#include <stdint.h>
13+
#include "DeviceDataStructure.h"
14+
15+
#if (defined WIN32 || defined _WIN32 || defined WINCE)
16+
# define CP_EXPORTS __declspec(dllexport)
17+
#else
18+
# define CP_EXPORTS
19+
#endif
20+
21+
/**
22+
* \brief Write a core register.
23+
* \param register : The register to write.
24+
* \param data : The data to write.
25+
* \return 0 if the writing operation correctly finished, otherwise an error occurred.
26+
*/
27+
int writeCoreRegister(unsigned int register, unsigned int data);
28+
29+
/**
30+
* \brief Read a core register.
31+
* \param register : The register to read.
32+
* \param data : The data read.
33+
* \return 0 if the reading operation correctly finished, otherwise an error occurred.
34+
*/
35+
int readCoreRegister(unsigned int register, unsigned int *data);
36+
37+
#ifdef __cplusplus
38+
}
39+
#endif
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// Bindgen wrapper
2+
#include "CubeProgrammer_API.h"
3+
#include "CubeProgrammer_API_Undocumented.h"

stm32cubeprogrammer-sys/justfile

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,13 @@
1-
bindgen_header := "include/CubeProgrammer_API.h"
1+
# Nushell needs to be installeds
2+
set shell := ["nu", "-c"]
3+
4+
shebang := if os() == 'windows' {
5+
'nu.exe'
6+
} else {
7+
'/usr/bin/env nu'
8+
}
9+
10+
bindgen_header := "include/wrapper.h"
211

312
bindgen_output := if os() == 'windows' {
413
"src/bindings_windows.rs"
@@ -8,4 +17,4 @@ bindgen_output := if os() == 'windows' {
817

918
# Generate bindings for the CubeProgrammer API dynamic library
1019
generate-bindings:
11-
bindgen {{source_directory()}}/{{bindgen_header}} --dynamic-loading CubeProgrammer_API --output {{source_directory()}}/{{bindgen_output}} -- -x c++
20+
bindgen {{source_directory()}}/{{bindgen_header}} --dynamic-loading CubeProgrammer_API --output {{source_directory()}}/{{bindgen_output}} -- -x c++ -target x86_64-pc-windows-msvc

stm32cubeprogrammer-sys/src/bindings_windows.rs

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* automatically generated by rust-bindgen 0.70.1 */
1+
/* automatically generated by rust-bindgen 0.71.1 */
22

33
pub const _VCRT_COMPILER_PREPROCESSOR: u32 = 1;
44
pub const _SAL_VERSION: u32 = 20;
@@ -1240,6 +1240,20 @@ pub struct CubeProgrammer_API {
12401240
) -> ::std::os::raw::c_int,
12411241
::libloading::Error,
12421242
>,
1243+
pub writeCoreRegister: Result<
1244+
unsafe extern "C" fn(
1245+
arg1: ::std::os::raw::c_uint,
1246+
data: ::std::os::raw::c_uint,
1247+
) -> ::std::os::raw::c_int,
1248+
::libloading::Error,
1249+
>,
1250+
pub readCoreRegister: Result<
1251+
unsafe extern "C" fn(
1252+
arg1: ::std::os::raw::c_uint,
1253+
data: *mut ::std::os::raw::c_uint,
1254+
) -> ::std::os::raw::c_int,
1255+
::libloading::Error,
1256+
>,
12431257
}
12441258
impl CubeProgrammer_API {
12451259
pub unsafe fn new<P>(path: P) -> Result<Self, ::libloading::Error>
@@ -1331,6 +1345,8 @@ impl CubeProgrammer_API {
13311345
let getHsmVersion = __library.get(b"getHsmVersion\0").map(|sym| *sym);
13321346
let getHsmType = __library.get(b"getHsmType\0").map(|sym| *sym);
13331347
let getHsmLicense = __library.get(b"getHsmLicense\0").map(|sym| *sym);
1348+
let writeCoreRegister = __library.get(b"writeCoreRegister\0").map(|sym| *sym);
1349+
let readCoreRegister = __library.get(b"readCoreRegister\0").map(|sym| *sym);
13341350
Ok(CubeProgrammer_API {
13351351
__library,
13361352
__va_start,
@@ -1404,6 +1420,8 @@ impl CubeProgrammer_API {
14041420
getHsmVersion,
14051421
getHsmType,
14061422
getHsmLicense,
1423+
writeCoreRegister,
1424+
readCoreRegister,
14071425
})
14081426
}
14091427
pub unsafe fn __security_init_cookie(&self) {
@@ -2074,4 +2092,26 @@ impl CubeProgrammer_API {
20742092
.as_ref()
20752093
.expect("Expected function, got error."))(hsmSlotId, outLicensePath)
20762094
}
2095+
#[doc = " \\brief Write a core register.\n \\param register : The register to write.\n \\param data : The data to write.\n \\return 0 if the writing operation correctly finished, otherwise an error occurred."]
2096+
pub unsafe fn writeCoreRegister(
2097+
&self,
2098+
arg1: ::std::os::raw::c_uint,
2099+
data: ::std::os::raw::c_uint,
2100+
) -> ::std::os::raw::c_int {
2101+
(self
2102+
.writeCoreRegister
2103+
.as_ref()
2104+
.expect("Expected function, got error."))(arg1, data)
2105+
}
2106+
#[doc = " \\brief Read a core register.\n \\param register : The register to read.\n \\param data : The data read.\n \\return 0 if the reading operation correctly finished, otherwise an error occurred."]
2107+
pub unsafe fn readCoreRegister(
2108+
&self,
2109+
arg1: ::std::os::raw::c_uint,
2110+
data: *mut ::std::os::raw::c_uint,
2111+
) -> ::std::os::raw::c_int {
2112+
(self
2113+
.readCoreRegister
2114+
.as_ref()
2115+
.expect("Expected function, got error."))(arg1, data)
2116+
}
20772117
}

stm32cubeprogrammer/src/api_types.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,31 @@ pub enum ErrorCode {
2828
UnknownError = -17,
2929
}
3030

31+
/// CoreRegister of the target
32+
#[derive(Debug, Copy, Clone, strum::Display, IntoPrimitive, FromPrimitive)]
33+
#[repr(u32)]
34+
pub enum CoreRegister {
35+
R0 = 0,
36+
R1,
37+
R2,
38+
R3,
39+
R4,
40+
R5,
41+
R6,
42+
R7,
43+
R8,
44+
R9,
45+
R10,
46+
R11,
47+
R12,
48+
SP,
49+
LR,
50+
PC,
51+
52+
#[num_enum(catch_all)]
53+
Unknown(u32),
54+
}
55+
3156
/// Return code which is mapped to an error if it is not equal to SUCCESS
3257
/// Sometimes success is 0, sometimes it is 1
3358
#[derive(Debug, From, Into)]

stm32cubeprogrammer/src/cube_programmer.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -733,6 +733,30 @@ impl ConnectedProgrammer<'_> {
733733
api_types::ReturnCode::<1>::from(unsafe { self.api().startWirelessStack() })
734734
.check(crate::error::Action::StartWirelessStack)
735735
}
736+
737+
/// Write [`crate::api_types::CoreRegister`]
738+
pub fn write_core_register(&self, register: crate::api_types::CoreRegister, value: u32) -> CubeProgrammerResult<()> {
739+
self.check_connection()?;
740+
741+
api_types::ReturnCode::<0>::from(unsafe {
742+
self.api().writeCoreRegister(register.into(), value)
743+
})
744+
.check(crate::error::Action::WriteCoreRegister)
745+
}
746+
747+
/// Read [`crate::api_types::CoreRegister`]
748+
pub fn read_core_register(&self, register: crate::api_types::CoreRegister) -> CubeProgrammerResult<u32> {
749+
self.check_connection()?;
750+
751+
let mut value = 0;
752+
753+
api_types::ReturnCode::<0>::from(unsafe {
754+
self.api().readCoreRegister(register.into(), &mut value)
755+
})
756+
.check(crate::error::Action::ReadCoreRegister)?;
757+
758+
Ok(value)
759+
}
736760
}
737761

738762
impl ConnectedFusProgrammer<'_> {

stm32cubeprogrammer/src/error.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ pub enum Action {
3131
DeleteWirelessStack,
3232
StartWirelessStack,
3333
ListConnectedProbes,
34+
WriteCoreRegister,
35+
ReadCoreRegister,
3436
}
3537

3638
#[derive(Debug, Error, Display)]

stm32cubeprogrammer/src/lib.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
//! ```no_run
55
//! use stm32cubeprogrammer::{
66
//! probe::{ConnectionParameters, Protocol, ResetMode},
7-
//! CubeProgrammer,
7+
//! CubeProgrammer, CoreRegister
88
//! };
99
//!
1010
//! // You need to supply the path to the root directory of the STM32CubeProgrammer installation
@@ -28,6 +28,11 @@
2828
//! .expect("Failed to connect to target");
2929
//!
3030
//! println!("Target information: {}", connected.target_information());
31+
//!
32+
//! connected.write_core_register(CoreRegister::R0, 0x12345678).expect("Failed to write core register");
33+
//!
34+
//! let r0 = connected.read_core_register(CoreRegister::R0).expect("Failed to read core register");
35+
//! println!("R0: 0x{:08X}", r0);
3136
//!
3237
//! // If there are multiple connected probes with a target, you can establish multiple connections simultaneously
3338
//! let connected_other = programmer
@@ -56,6 +61,7 @@
5661
//! - Downloading files as hex or bin
5762
//! - Reading and writing memory
5863
//! - Uses the [`bytemuck::Pod`](https://docs.rs/bytemuck/1.21.0/bytemuck/trait.Pod.html) trait for reading and writing data from/to memory
64+
//! - Reading and writing of core registers
5965
//! - Resetting the target
6066
//! - Enabling and disabling readout protection (Level B)
6167
//! - Reset target
@@ -85,12 +91,11 @@
8591
//!
8692
//! # Warranty
8793
//! This crate is supplied as is without any warranty. Use at your own risk.
88-
8994
pub mod api_log;
9095
pub use api_log::{LogMessageType, Verbosity};
9196

9297
pub mod api_types;
93-
pub use api_types::{fus, probe, TargetInformation};
98+
pub use api_types::{fus, probe, TargetInformation, CoreRegister};
9499

95100
pub mod display;
96101
pub use display::DisplayCallback;

0 commit comments

Comments
 (0)