Skip to content

Commit 874e174

Browse files
authored
Merge pull request #123 from inputlabs/115-profile-overwrite
Profile overwrite
2 parents cc262c4 + a20337b commit 874e174

File tree

6 files changed

+100
-47
lines changed

6 files changed

+100
-47
lines changed

docs/ctrl_protocol.md

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,13 @@ PROC | 2
4242
CONFIG_GET | 3
4343
CONFIG_SET | 4
4444
CONFIG_SHARE | 5
45-
PROFILE_GET | 6
46-
PROFILE_SET | 7
47-
PROFILE_SHARE | 8
45+
SECTION_GET | 6
46+
SECTION_SET | 7
47+
SECTION_SHARE | 8
4848
STATUS_GET | 9
4949
STATUS_SET | 10
5050
STATUS_SHARE | 11
51+
PROFILE_OVERWRITE | 12
5152

5253
### Procedure index
5354
Procedure index as defined in [hid.h](/src/headers/hid.h).
@@ -201,35 +202,49 @@ Direction: `Controller` -> `App`
201202
| Version | Device Id | Message type | Payload size | Payload | Payload | Payload
202203
| | | CONFIG_SHARE | 6 | CONFIG INDEX | PRESET INDEX | PRESETS VALUE
203204

204-
## Profile GET message
205+
## Section GET message
205206
Request the current value of some specific profile section.
206207

207208
Direction: `Controller` <- `App`
208209

209210
| Byte 0 | 1 | 2 | 3 | 4 | 5 |
210211
| - | - | - | - | - | - |
211212
| Version | Device Id | Message type | Payload size | Payload | Payload
212-
| | | PROFILE_GET | 2 | PROFILE INDEX | SECTION INDEX
213+
| | | SECTION_GET | 2 | PROFILE INDEX | SECTION INDEX
213214

214-
## Profile SET message
215+
## Section SET message
215216
Change the value of some specific profile section.
216217

217218
Direction: `Controller` <- `App`
218219

219220
| Byte 0 | 1 | 2 | 3 | 4 | 5 | 6~64 |
220221
| - | - | - | - | - | - | - |
221222
| Version | Device Id | Message type | Payload size | Payload | Payload | Payload
222-
| | | PROFILE_SET | 58 | PROFILE INDEX | SECTION INDEX | SECTION DATA
223+
| | | SECTION_SET | 58 | PROFILE INDEX | SECTION INDEX | SECTION DATA
223224

224-
## Profile SHARE message
225+
## Section SHARE message
225226
Notify the current value of some specific profile section.
226227

227228
Direction: `Controller` -> `App`
228229

229230
| Byte 0 | 1 | 2 | 3 | 4 | 5 | 6~64 |
230231
| - | - | - | - | - | - | - |
231232
| Version | Device Id | Message type | Payload size | Payload | Payload | Payload
232-
| | | PROFILE_SHARE | 58 | PROFILE INDEX | SECTION INDEX | SECTION DATA
233+
| | | SECTION_SHARE | 58 | PROFILE INDEX | SECTION INDEX | SECTION DATA
234+
235+
## Profile OVERWRITE message
236+
Replaces a controller profile with a profile from another slot or default profile.
237+
238+
Direction: `App` -> `Controller`
239+
240+
| Byte 0 | 1 | 2 | 3 | 4 | 5
241+
| - | - | - | - | - | -
242+
| Version | Device Id | Message type | Payload size | Payload | Payload
243+
| | | PROFILE_OVERWRITE | 2 | PROFILE TO | PROFILE FROM
244+
245+
**Profile To:** The target profile slot index to be overwritten (1 to 12).
246+
247+
**Profile From:** The profile index to be used as data source. Positive values (1, 12) to use another profile from memory as is. Negative values (-1 to -9) to use profile built-in defaults.
233248

234249
## Example of config interchange
235250
```mermaid

src/config.c

Lines changed: 51 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ void config_profile_load(uint8_t index) {
5858
CtrlProfileMeta meta = config_profile_cache[index].sections[SECTION_META].meta;
5959
if (meta.control_byte != NVM_CONTROL_BYTE) {
6060
debug("Config: Profile %i not found\n", index);
61-
config_profile_default(index);
61+
config_profile_default(index, index);
6262
}
6363
uint32_t version = (
6464
(meta.version_major * 1000000) +
@@ -67,7 +67,7 @@ void config_profile_load(uint8_t index) {
6767
);
6868
if (version < NVM_PROFILE_VERSION) {
6969
debug("Config: Profile %i incompatible version (%lu)\n", index, version);
70-
config_profile_default(index);
70+
config_profile_default(index, index);
7171
}
7272
// Tag as synced.
7373
config_profile_cache_synced[index] = true;
@@ -105,6 +105,11 @@ void config_profile_set_sync(uint8_t index, bool state) {
105105
}
106106

107107
void config_sync() {
108+
// Do not check in every cycle.
109+
static uint16_t i = 0;
110+
i++;
111+
if (i != NVM_SYNC_FREQUENCY) return;
112+
else i = 0;
108113
// Sync main config.
109114
if (!config_cache_synced) {
110115
config_write();
@@ -490,39 +495,61 @@ bool config_problems_are_pending() {
490495
return problem_calibration || problem_gyro;
491496
}
492497

493-
void config_profile_default(uint8_t index) {
494-
info("Config: Profile %i init from default\n", index);
495-
config_profile_clear_cache(index);
496-
if (index == 0) config_profile_default_home( &(config_profile_cache[index]));
497-
if (index == 1) config_profile_default_fps_fusion( &(config_profile_cache[index]));
498-
if (index == 2) config_profile_default_racing( &(config_profile_cache[index]));
499-
if (index == 3) config_profile_default_console( &(config_profile_cache[index]));
500-
if (index == 4) config_profile_default_desktop( &(config_profile_cache[index]));
501-
if (index == 5) config_profile_default_fps_wasd( &(config_profile_cache[index]));
502-
if (index == 6) config_profile_default_flight( &(config_profile_cache[index]));
503-
if (index == 7) config_profile_default_console_legacy( &(config_profile_cache[index]));
504-
if (index == 8) config_profile_default_rts( &(config_profile_cache[index]));
505-
if (index == 9) config_profile_default_custom( &(config_profile_cache[index]));
506-
if (index == 10) config_profile_default_custom( &(config_profile_cache[index]));
507-
if (index == 11) config_profile_default_custom( &(config_profile_cache[index]));
508-
if (index == 12) config_profile_default_custom( &(config_profile_cache[index]));
509-
if (index == 13) config_profile_default_console_legacy( &(config_profile_cache[index]));
498+
void config_profile_default(uint8_t indexTo, int8_t indexFrom) {
499+
info("Config: Profile %i init from default %i\n", indexTo, indexFrom);
500+
config_profile_clear_cache(indexTo);
501+
if (indexFrom == 0) config_profile_default_home( &(config_profile_cache[indexTo]));
502+
if (indexFrom == 1) config_profile_default_fps_fusion( &(config_profile_cache[indexTo]));
503+
if (indexFrom == 2) config_profile_default_racing( &(config_profile_cache[indexTo]));
504+
if (indexFrom == 3) config_profile_default_console( &(config_profile_cache[indexTo]));
505+
if (indexFrom == 4) config_profile_default_desktop( &(config_profile_cache[indexTo]));
506+
if (indexFrom == 5) config_profile_default_fps_wasd( &(config_profile_cache[indexTo]));
507+
if (indexFrom == 6) config_profile_default_flight( &(config_profile_cache[indexTo]));
508+
if (indexFrom == 7) config_profile_default_console_legacy( &(config_profile_cache[indexTo]));
509+
if (indexFrom == 8) config_profile_default_rts( &(config_profile_cache[indexTo]));
510+
if (indexFrom == 9) config_profile_default_custom( &(config_profile_cache[indexTo]));
511+
if (indexFrom == 10) config_profile_default_custom( &(config_profile_cache[indexTo]));
512+
if (indexFrom == 11) config_profile_default_custom( &(config_profile_cache[indexTo]));
513+
if (indexFrom == 12) config_profile_default_custom( &(config_profile_cache[indexTo]));
514+
if (indexFrom == 13) config_profile_default_console_legacy( &(config_profile_cache[indexTo]));
510515
// Add number to the name of the default custom profiles.
511-
if (index >= 9 && index<=12) {
512-
char *name = config_profile_cache[index].sections[SECTION_META].meta.name;
516+
if (indexTo >= 9 && indexTo<=12) {
517+
char *name = config_profile_cache[indexTo].sections[SECTION_META].meta.name;
513518
char custom_name[9]; // Custom=6 +space +digit +nullterm.
514-
snprintf(custom_name, 9, "Custom %i", index-8);
519+
snprintf(custom_name, 9, "Custom %i", indexTo-8);
515520
memcpy(name, custom_name, sizeof(custom_name));
516521
}
517522
// Save in NVM.
518-
config_profile_write(index);
523+
config_profile_write(indexTo);
519524
}
520525

521526
void config_profile_default_all() {
522527
debug("Config: Init all profiles from defaults\n");
523528
for(uint8_t i=0; i<NVM_PROFILE_SLOTS; i++) {
524-
config_profile_default(i);
529+
config_profile_default(i, i);
530+
}
531+
}
532+
533+
void config_profile_overwrite(uint8_t indexTo, int8_t indexFrom) {
534+
debug("Config: Profile overwrite %i -> %i\n", indexFrom, indexTo);
535+
// Remember name.
536+
char name[24];
537+
CtrlProfileMeta *meta = &(config_profile_cache[indexTo]).sections[SECTION_META].meta;
538+
memcpy(name, meta->name, 24);
539+
// From default.
540+
if (indexFrom < 0) {
541+
config_profile_default(indexTo, -indexFrom);
542+
}
543+
// From other profile slot.
544+
if (indexFrom > 0) {
545+
memcpy(
546+
&config_profile_cache[indexTo],
547+
&config_profile_cache[indexFrom],
548+
sizeof(CtrlProfile)
549+
);
525550
}
551+
// Restore name.
552+
memcpy(meta->name, name, 24);
526553
}
527554

528555
void config_init_profiles_from_nvm() {

src/ctrl.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,11 +90,11 @@ Ctrl ctrl_config_share(uint8_t index) {
9090
return ctrl;
9191
}
9292

93-
Ctrl ctrl_profile_share(uint8_t profile_index, uint8_t section_index) {
93+
Ctrl ctrl_section_share(uint8_t profile_index, uint8_t section_index) {
9494
Ctrl ctrl = {
9595
.protocol_version = CTRL_PROTOCOL_VERSION,
9696
.device_id = ALPAKKA,
97-
.message_type = PROFILE_SHARE,
97+
.message_type = SECTION_SHARE,
9898
.len = 60
9999
};
100100
// Profile section struct cast into packed int array.

src/headers/config.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
#define CFG_IMU_TICK_SAMPLES 128 // Multi-sampling per pooling cycle.
2727
#define CFG_HID_REPORT_PRIORITY_RATIO 8
2828

29+
#define NVM_SYNC_FREQUENCY (CFG_TICK_FREQUENCY / 2)
30+
2931
#define CFG_CALIBRATION_SAMPLES_THUMBSTICK 100000 // Samples.
3032
#define CFG_CALIBRATION_SAMPLES_GYRO 200000 // Samples.
3133
#define CFG_CALIBRATION_SAMPLES_ACCEL 100000 // Samples.
@@ -126,7 +128,7 @@ CtrlProfile* config_profile_read(uint8_t index);
126128
void config_profile_write(uint8_t index);
127129
void config_profile_set_sync(uint8_t index, bool state);
128130
void config_profile_default_all();
129-
void config_profile_default(uint8_t index);
131+
void config_profile_default(uint8_t indexTo, int8_t indexFrom);
130132
void config_profile_default_home(CtrlProfile *profile);
131133
void config_profile_default_fps_fusion(CtrlProfile *profile);
132134
void config_profile_default_fps_wasd(CtrlProfile *profile);
@@ -137,6 +139,7 @@ void config_profile_default_console_legacy(CtrlProfile *profile);
137139
void config_profile_default_desktop(CtrlProfile *profile);
138140
void config_profile_default_rts(CtrlProfile *profile);
139141
void config_profile_default_custom(CtrlProfile *profile);
142+
void config_profile_overwrite(uint8_t indexTo, int8_t indexFrom);
140143

141144
// Problems.
142145
void config_set_problem_calibration(bool state);

src/headers/ctrl.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,13 @@ typedef enum Ctrl_msg_type_enum {
2020
CONFIG_GET,
2121
CONFIG_SET,
2222
CONFIG_SHARE,
23-
PROFILE_GET,
24-
PROFILE_SET,
25-
PROFILE_SHARE,
23+
SECTION_GET,
24+
SECTION_SET,
25+
SECTION_SHARE,
2626
STATUS_GET,
2727
STATUS_SET,
2828
STATUS_SHARE,
29+
PROFILE_OVERWRITE,
2930
} Ctrl_msg_type;
3031

3132
typedef enum Ctrl_cfg_type_enum {
@@ -215,4 +216,4 @@ Ctrl ctrl_empty();
215216
Ctrl ctrl_log(uint8_t* offset_ptr, uint8_t len);
216217
Ctrl ctrl_status_share();
217218
Ctrl ctrl_config_share(uint8_t index);
218-
Ctrl ctrl_profile_share(uint8_t profile_index, uint8_t section_index);
219+
Ctrl ctrl_section_share(uint8_t profile_index, uint8_t section_index);

src/webusb.c

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ bool webusb_flush() {
8484
bool sent = webusb_transfer(ctrl);
8585
if (sent) webusb_pending_config_share = 0;
8686
} else if (webusb_pending_profile_share || webusb_pending_section_share) {
87-
ctrl = ctrl_profile_share(webusb_pending_profile_share, webusb_pending_section_share);
87+
ctrl = ctrl_section_share(webusb_pending_profile_share, webusb_pending_section_share);
8888
bool sent = webusb_transfer(ctrl);
8989
if (sent) {
9090
webusb_pending_profile_share = 0;
@@ -152,7 +152,7 @@ void webusb_handle_config_get(Ctrl_cfg_type key) {
152152
webusb_pending_config_share = key;
153153
}
154154

155-
void webusb_handle_profile_get(uint8_t profile, uint8_t section) {
155+
void webusb_handle_section_get(uint8_t profile, uint8_t section) {
156156
webusb_pending_profile_share = profile;
157157
webusb_pending_section_share = section;
158158
}
@@ -189,14 +189,18 @@ void webusb_handle_config_set(Ctrl_cfg_type key, uint8_t preset, uint8_t values[
189189
}
190190
}
191191

192-
void webusb_handle_profile_set(uint8_t profileIndex, uint8_t sectionIndex, uint8_t section[58]) {
192+
void webusb_handle_section_set(uint8_t profileIndex, uint8_t sectionIndex, uint8_t section[58]) {
193+
debug("WebUSB: Handle profile SET %i %i\n", profileIndex, sectionIndex);
193194
// Update profile in config.
194195
CtrlProfile *profile_cfg = config_profile_read(profileIndex);
195196
profile_cfg->sections[sectionIndex] = *(CtrlSection*)section;
196197
// Update profile runtime.
197198
Profile *profile = profile_get(profileIndex);
198199
profile->load_from_config(profile, profile_cfg);
199200
config_profile_set_sync(profileIndex, false);
201+
// Send back data as confirmation.
202+
webusb_pending_profile_share = profileIndex;
203+
webusb_pending_section_share = sectionIndex;
200204
}
201205

202206
void webusb_read() {
@@ -220,16 +224,19 @@ void webusb_read() {
220224
&ctrl.payload[2] // Preset values. (Reference to sub-array).
221225
);
222226
}
223-
if (ctrl.message_type == PROFILE_GET) {
224-
webusb_handle_profile_get(ctrl.payload[0], ctrl.payload[1]);
227+
if (ctrl.message_type == SECTION_GET) {
228+
webusb_handle_section_get(ctrl.payload[0], ctrl.payload[1]);
225229
}
226-
if (ctrl.message_type == PROFILE_SET) {
227-
webusb_handle_profile_set(
230+
if (ctrl.message_type == SECTION_SET) {
231+
webusb_handle_section_set(
228232
ctrl.payload[0],
229233
ctrl.payload[1],
230234
&ctrl.payload[2]
231235
);
232236
}
237+
if (ctrl.message_type == PROFILE_OVERWRITE) {
238+
config_profile_overwrite(ctrl.payload[0], ctrl.payload[1]);
239+
}
233240
}
234241

235242
void webusb_set_pending_config_share(bool value) {

0 commit comments

Comments
 (0)