Skip to content

Commit 7ef594e

Browse files
author
tcollet
committed
Move save and restore operation to a dedicated command
Save and restore are required for any commands and not only for the USER_DATA. Two new commands are created for that and README is changed accordingly. For these new commands BMT456 does not exepct call to sendbyte but a write byte on the command with a dummy value. A test is done on the BMR version to know how to execute the command. Moreover for the restore two options are provided to reload the default configuration or the last saved configuration. No automatic save is done after a restore.
1 parent aaef84a commit 7ef594e

File tree

6 files changed

+119
-27
lines changed

6 files changed

+119
-27
lines changed

README.md

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,36 @@ bmr --bus /dev/i2c-1 --addr 0x40 <command> [subcommand] [--pretty-off|P]
2828
* `--addr` 7-bit device address (default: `0x40`).
2929
* `--pretty-off|P` disable pretty output
3030

31+
## save — save current configuration
32+
33+
```bash
34+
bmr ... save
35+
```
36+
37+
### What it does
38+
39+
Save all modifications to be permanent for next power cycle or call to restart
40+
command.
41+
42+
## restore — restore configuration
43+
44+
```bash
45+
bmr ... restore [default]
46+
```
47+
48+
### What it does
49+
50+
Reload and apply factory default configuration if default is set, otherwise
51+
reload the last saved configuration i.e. similar to call to the restart command.
52+
53+
### Use case
54+
55+
Drop the current change:
56+
57+
```bash
58+
bmr --bus /dev/i2c-1 --addr 0x40 restore
59+
```
60+
3161
## read — Telemetry & sensor data
3262

3363
```bash
@@ -202,22 +232,20 @@ margins/timing profiles.
202232

203233
```bash
204234
bmr ... user-data get
205-
bmr ... user-data set --ascii "Hello" [--store]
235+
bmr ... user-data set --ascii "Hello"
206236
```
207237

208238
### What it does
209239

210240
Accesses vendor `USER_DATA_00` (0xB0) area for storing small notes or process
211-
metadata (e.g., calibration token). With `--store`, the tool persists changes
212-
via `STORE_USER_ALL` or device-specific store, observing NVM latency. See App
213-
Note 302 for STORE/RESTORE semantics and timing.
241+
metadata (e.g., calibration token).
214242

215243
### Use case
216244

217245
Stamp a unit with a calibration tag, manufacturing information:
218246

219247
```bash
220-
bmr ... user-data set --ascii "Cal=OK@2025-11-09" --store
248+
bmr ... user-data set --ascii "Cal=OK@2025-11-09"
221249
```
222250

223251
Wait ~5–10 ms before re-reading to allow NVM write to complete.
@@ -605,7 +633,7 @@ Set typical limits and verify live sensors:
605633
bmr --bus /dev/i2c-1 --addr 0x40 temp set --ot-fault 110 --ot-warn 100 --ut-warn -20 --ut-fault -40
606634

607635
# Persist if desired (device NVM):
608-
bmr --bus /dev/i2c-1 --addr 0x40 user-data set --store
636+
bmr --bus /dev/i2c-1 --addr 0x40 save
609637

610638
# Read back limits and live temps
611639
bmr --bus /dev/i2c-1 --addr 0x40 temp get all
@@ -663,7 +691,7 @@ bmr --bus /dev/i2c-1 --addr 0x40 set temp \
663691
**Persist to NVM** (optional, if you want the policy/limits after power cycle):
664692

665693
```bash
666-
bmr --bus /dev/i2c-1 --addr 0x40 user-data set --store
694+
bmr --bus /dev/i2c-1 --addr 0x40 save
667695
```
668696

669697
**Verify**:
@@ -694,7 +722,7 @@ bmr --bus /dev/i2c-1 --addr 0x40 set temp --ot-fault 20
694722
bmr --bus /dev/i2c-1 --addr 0x40 set temp --ut-fault 30
695723

696724
# Persist to NVM if you want the policy to survive power cycles
697-
#bmr --bus /dev/i2c-1 --addr 0x40 user-data set --store
725+
#bmr --bus /dev/i2c-1 --addr 0x40 save
698726
```
699727

700728
The rail shall shutdown, wait 16s, retry once, then:
@@ -709,7 +737,7 @@ bmr --bus /dev/i2c-1 --addr 0x40 temp set \
709737
--ot-fault 110 --ot-warn 100 --ut-warn -20 --ut-fault -40
710738

711739
# Persist to NVM if you want the policy to survive power cycles
712-
bmr --bus /dev/i2c-1 --addr 0x40 user-data set --store
740+
bmr --bus /dev/i2c-1 --addr 0x40 save
713741
```
714742

715743
## rw — direct access to a byte / word register

src/main.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "mfr_ramp_data.h"
1010
#include "mfr_addr_offset.h"
1111
#include "mfr_status_data.h"
12+
#include "mfr_save_restore.h"
1213
#include "timing_cmd.h"
1314
#include "read_cmd.h"
1415
#include "onoff_cmd.h"
@@ -47,13 +48,15 @@ usage(const char *p) {
4748
"\n"
4849
"Commands:\n"
4950
" read [vin|vout|iout|temp1|temp2|duty|freq|all]\n"
51+
" save\n"
52+
" restore [default]\n"
5053
" status\n"
5154
" snapshot [--cycle 0..19] [--decode]\n"
5255
" mfr-multi-pin get|set [--mode MODE] [--pg pushpull|highz] [--pg-enable 0|1] [--sec-rc-pull 0|1]\n"
5356
" id\n"
5457
" fwdata\n"
5558
" restart\n"
56-
" user-data get|set [--hex XX..|--ascii STR] [--store|--restore]\n"
59+
" user-data get|set [--hex XX..|--ascii STR]\n"
5760
" timing get|set [--profile safe|sequenced|fast|prebias]\n"
5861
" fault get [all|temp|vin|vout|tonmax|iout]\n"
5962
" fault temp set [--ot-delay 16s|32s|2^n] [--ot-mode disable-retry] [--ot-retries cont]\n"
@@ -278,6 +281,16 @@ main(int argc, char *const *argv) {
278281
goto fini;
279282
}
280283

284+
if (!strcmp(cmd, "save")) {
285+
rc = cmd_save(fd);
286+
goto fini;
287+
}
288+
289+
if (!strcmp(cmd, "restore")) {
290+
rc = cmd_restore(fd, sub_argc, sub_argv);
291+
goto fini;
292+
}
293+
281294
usage(argv[0]);
282295
rc = EXIT_FAILURE;
283296

src/meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ sources = [
1414
'mfr_ramp_data.c',
1515
'mfr_status_data.c',
1616
'mfr_addr_offset.c',
17+
'mfr_save_restore.c',
1718
'timing_cmd.c',
1819
'read_cmd.c',
1920
'status_cmd.c',

src/mfr_save_restore.c

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/* SPDX-License-Identifier: AGPL-3.0-or-later */
2+
3+
#include "pmbus_io.h"
4+
#include <stdio.h>
5+
#include <string.h>
6+
7+
int
8+
cmd_save(int fd) {
9+
uint8_t b[64];
10+
11+
/*
12+
* For BMR456 STORE and RESTORE is not based on send byte but on a write byte with a dummy value
13+
* Product version is read to know how to execute the command
14+
*/
15+
pmbus_rd_block(fd, MFR_MODEL, b, (int)sizeof b);
16+
17+
if (strncmp((char *)b, "BMR456", (size_t)6))
18+
pmbus_send_byte(fd, PMBUS_STORE_USER_ALL);
19+
else
20+
pmbus_wr_byte(fd, PMBUS_STORE_USER_ALL, 0x01);
21+
22+
puts("OK");
23+
24+
return 0;
25+
}
26+
27+
int
28+
cmd_restore(int fd, int argc, char *const *argv) {
29+
uint8_t b[64];
30+
bool isDefault = false;
31+
32+
if ((argc) && !strcmp(argv[0], "default"))
33+
isDefault = true;
34+
35+
36+
/*
37+
* For BMR456 STORE and RESTORE is not based on send byte but on a write byte with a dummy value
38+
* Product version is read to know how to execute the command
39+
*/
40+
pmbus_rd_block(fd, MFR_MODEL, b, (int)sizeof b);
41+
42+
if (isDefault) {
43+
if (strncmp((char *)b, "BMR456", (size_t)6))
44+
pmbus_send_byte(fd, PMBUS_RESTORE_DEFAULT_ALL);
45+
else
46+
pmbus_wr_byte(fd, PMBUS_RESTORE_DEFAULT_ALL, 0x01);
47+
} else {
48+
if (strncmp((char *)b, "BMR456", (size_t)6))
49+
pmbus_send_byte(fd, PMBUS_RESTORE_USER_ALL);
50+
else
51+
pmbus_wr_byte(fd, PMBUS_RESTORE_USER_ALL, 0x01);
52+
}
53+
54+
puts("OK");
55+
56+
return 0;
57+
}

src/mfr_save_restore.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
/* SPDX-License-Identifier: AGPL-3.0-or-later */
2+
#pragma once
3+
4+
int cmd_save(int fd);
5+
int cmd_restore(int fd, int argc, char *const *argv);

src/mfr_user_data.c

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,23 +11,24 @@
1111

1212
int
1313
cmd_user_data(int fd, int argc, char *const *argv, int pretty) {
14+
uint8_t b[64];
15+
1416
if (argc < 1) {
1517
fprintf(stderr, "user-data get|set ...\n");
1618
return 2;
1719
}
1820

1921
if (!strcmp(argv[0], "get")) {
20-
uint8_t buf[64];
21-
int n = pmbus_rd_block(fd, MFR_USER_DATA_00, buf, sizeof buf);
22+
int n = pmbus_rd_block(fd, MFR_USER_DATA_00, b, sizeof b);
2223
if (n < 0) {
2324
perror("USER_DATA_00");
2425
return 1;
2526
}
2627

2728
json_t *o = json_object();
2829
json_object_set_new(o, "len", json_integer(n));
29-
json_object_set_new(o, "ascii", json_stringn((char *) buf, n));
30-
json_add_hex_ascii(o, "hex", buf, (size_t)n);
30+
json_object_set_new(o, "ascii", json_stringn((char *) b, n));
31+
json_add_hex_ascii(o, "hex", b, (size_t)n);
3132

3233
json_print_or_pretty(o, pretty);
3334

@@ -36,20 +37,14 @@ cmd_user_data(int fd, int argc, char *const *argv, int pretty) {
3637

3738
if (!strcmp(argv[0], "set")) {
3839
const char *hex = NULL, *ascii = NULL;
39-
bool store = false, restore = false;
4040

4141
for (int i = 1; i < argc; i++) {
4242
if (!strcmp(argv[i], "--hex") && i + 1 < argc)
4343
hex = argv[++i];
4444
else if (!strcmp(argv[i], "--ascii") && i + 1 < argc)
4545
ascii = argv[++i];
46-
else if (!strcmp(argv[i], "--store"))
47-
store = true;
48-
else if (!strcmp(argv[i], "--restore"))
49-
restore = true;
5046
}
5147

52-
uint8_t b[64];
5348
int n = 0;
5449

5550
if (hex) {
@@ -85,13 +80,6 @@ cmd_user_data(int fd, int argc, char *const *argv, int pretty) {
8580
return 1;
8681
}
8782

88-
if (store)
89-
pmbus_send_byte(fd, PMBUS_STORE_USER_ALL);
90-
if (restore)
91-
pmbus_send_byte(fd, PMBUS_RESTORE_USER_ALL);
92-
93-
puts("OK");
94-
9583
return 0;
9684
}
9785

0 commit comments

Comments
 (0)