MeshX 0.4
This repository provides an implementation for Bluetooth Low Energy (BLE) Mesh network nodes. The project allows you to create BLE mesh nodes that can communicate with each other, enabling the development of smart home solutions or other IoT-based applications.
Loading...
Searching...
No Matches
meshx_gpio_kv.h File Reference

MeshX GPIO KV Engine Serialization Format. More...

#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include "interface/utils/meshx_fal_interface.h"
#include "meshx_gpio_types.h"

Go to the source code of this file.

Data Structures

struct  meshx_gpio_config_header_kv_t
 Header for serialized GPIO configuration stored in KV Engine. More...
struct  meshx_gpio_pin_config_kv_t
 Serialized GPIO pin configuration for KV Engine storage. More...
struct  meshx_gpio_pwm_config_kv_t
 Serialized PWM configuration for KV Engine storage. More...
struct  meshx_gpio_intr_config_kv_t
 Serialized interrupt configuration for KV Engine storage. More...
struct  meshx_gpio_pin_state_kv_t
 Serialized GPIO pin state for KV Engine storage. More...

Macros

#define MESHX_GPIO_CONFIG_VERSION_CURRENT   1
 Current GPIO configuration serialization format version.
#define MESHX_GPIO_CONFIG_VERSION_MIN   1
 Minimum supported version (for backward compatibility).
#define MESHX_GPIO_CONFIG_VERSION_MAX   1
 Maximum supported version (for forward compatibility).
#define MESHX_GPIO_KV_PRODUCT_NAME_MAX_LEN   16
 Maximum length for product name in key prefix.
#define MESHX_GPIO_KV_KEY_MAX_LEN   32
 Maximum total key length (KV Engine limit is 32).
#define MESHX_GPIO_KV_KEY_CONFIG   "config"
 Key suffix for main GPIO configuration.
#define MESHX_GPIO_KV_KEY_STATE   "state"
 Key suffix for GPIO pin state.
#define MESHX_GPIO_KV_KEY_PWM   "pwm"
 Key suffix for PWM configuration.
#define MESHX_GPIO_KV_KEY_INTR   "intr"
 Key suffix for interrupt configuration.
#define MESHX_GPIO_CONFIG_HEADER_SIZE   sizeof(meshx_gpio_config_header_kv_t)
 Size of configuration header.
#define MESHX_GPIO_PIN_CONFIG_SIZE   sizeof(meshx_gpio_pin_config_kv_t)
 Size of basic pin configuration.
#define MESHX_GPIO_PWM_CONFIG_SIZE   sizeof(meshx_gpio_pwm_config_kv_t)
 Size of PWM configuration extension.
#define MESHX_GPIO_INTR_CONFIG_SIZE   sizeof(meshx_gpio_intr_config_kv_t)
 Size of interrupt configuration extension.
#define MESHX_GPIO_PIN_STATE_SIZE   sizeof(meshx_gpio_pin_state_kv_t)
 Size of pin state record.
#define MESHX_GPIO_PIN_MAX_SIZE
 Maximum size per pin (including extensions).
#define MESHX_GPIO_CONFIG_TOTAL_SIZE(pin_count)
 Calculate total config size for given pin count.
#define MESHX_GPIO_CONFIG_FLAG_HAS_PWM   (1 << 0)
 Flag: Configuration has PWM extensions.
#define MESHX_GPIO_CONFIG_FLAG_HAS_INTR   (1 << 1)
 Flag: Configuration has interrupt extensions.
#define MESHX_GPIO_CONFIG_FLAG_MIGRATED   (1 << 2)
 Flag: Configuration is migrated from older version.
#define MESHX_GPIO_CONFIG_FLAG_READ_ONLY   (1 << 3)
 Flag: Configuration is in read-only mode.
#define MESHX_GPIO_CONFIG_TYPE_NONE   0
 No extended configuration.
#define MESHX_GPIO_CONFIG_TYPE_PWM   1
 PWM configuration follows.
#define MESHX_GPIO_CONFIG_TYPE_INTR   2
 Interrupt configuration follows.

Functions

static uint8_t meshx_gpio_kv_make_config_key (const char *product_name, char *buf, uint8_t buf_len)
 Construct KV Engine key for GPIO configuration.
static uint8_t meshx_gpio_kv_make_state_key (const char *product_name, uint8_t logical_pin, char *buf, uint8_t buf_len)
 Construct KV Engine key for GPIO pin state.
static uint8_t meshx_gpio_kv_make_pwm_key (const char *product_name, uint8_t logical_pin, char *buf, uint8_t buf_len)
 Construct KV Engine key for PWM configuration.
static uint8_t meshx_gpio_kv_make_intr_key (const char *product_name, uint8_t logical_pin, char *buf, uint8_t buf_len)
 Construct KV Engine key for interrupt configuration.
static uint16_t meshx_gpio_kv_calc_crc16 (const uint8_t *data, uint32_t len)
 Calculate CRC16 compatible with KV Engine.
static bool meshx_gpio_kv_verify_crc16 (const uint8_t *data, uint32_t len)
 Verify CRC16 of serialized GPIO configuration.
static void meshx_gpio_kv_init_header (meshx_gpio_config_header_kv_t *header, uint8_t pin_count)
 Initialize a GPIO configuration header.
static void meshx_gpio_kv_finalize_crc16 (uint8_t *data, uint32_t len)
 Calculate and set CRC16 for serialized configuration.
static void meshx_gpio_kv_serialize_pin (const meshx_gpio_pin_config_t *src, meshx_gpio_pin_config_kv_t *dst)
 Convert runtime pin config to serialized format.
static void meshx_gpio_kv_deserialize_pin (const meshx_gpio_pin_config_kv_t *src, meshx_gpio_pin_config_t *dst)
 Convert serialized pin config to runtime format.
static void meshx_gpio_kv_serialize_pwm (const meshx_gpio_pin_config_t *src, meshx_gpio_pwm_config_kv_t *dst)
 Serialize PWM configuration.
static void meshx_gpio_kv_deserialize_pwm (const meshx_gpio_pwm_config_kv_t *src, meshx_gpio_pin_config_t *dst)
 Deserialize PWM configuration.
static void meshx_gpio_kv_serialize_intr (const meshx_gpio_pin_config_t *src, meshx_gpio_intr_config_kv_t *dst)
 Serialize interrupt configuration.
static void meshx_gpio_kv_deserialize_intr (const meshx_gpio_intr_config_kv_t *src, meshx_gpio_pin_config_t *dst)
 Deserialize interrupt configuration.
static bool meshx_gpio_kv_is_version_supported (uint8_t version)
 Check if a configuration version is supported.
static bool meshx_gpio_kv_needs_migration (uint8_t from_version, uint8_t to_version)
 Get migration requirement between versions.
meshx_err_t meshx_gpio_kv_init (const meshx_fal_partition_t *kv_partition, const char *product_name)
 Initialize GPIO KV Engine persistence.
meshx_err_t meshx_gpio_save_config_to_kv (const meshx_gpio_pin_config_t *configs, uint8_t pin_count)
 Save GPIO configuration to KV Engine.
meshx_err_t meshx_gpio_load_config_from_kv (meshx_gpio_pin_config_t *configs, uint8_t max_pins, uint8_t *out_pin_count)
 Load GPIO configuration from KV Engine.
meshx_err_t meshx_gpio_config_exists_in_kv (bool *exists)
 Check if GPIO configuration exists in KV Engine.
meshx_err_t meshx_gpio_save_pin_state_to_kv (uint8_t logical_pin, const meshx_gpio_pin_state_t *state)
 Save current pin state to KV Engine.
meshx_err_t meshx_gpio_load_pin_state_from_kv (uint8_t logical_pin, meshx_gpio_pin_state_t *state)
 Load pin state from KV Engine.
meshx_err_t meshx_gpio_export_config (const meshx_gpio_pin_config_t *configs, uint8_t pin_count, uint8_t *buf, uint16_t buf_len, uint16_t *out_size)
 Export GPIO configuration to serialized format.
meshx_err_t meshx_gpio_import_config (const uint8_t *buf, uint16_t buf_len, meshx_gpio_pin_config_t *configs, uint8_t max_pins, uint8_t *out_pin_count)
 Import GPIO configuration from serialized format.
meshx_err_t meshx_gpio_clear_config_in_kv (void)
 Clear GPIO configuration from KV Engine.
meshx_err_t meshx_gpio_kv_deinit (void)
 Deinitialize GPIO KV Engine persistence.
bool meshx_gpio_kv_is_initialized (void)
 Check if GPIO KV persistence is initialized.

Detailed Description

MeshX GPIO KV Engine Serialization Format.

This file defines the binary serialization structures for GPIO configuration persistence using the MeshX KV Engine. The format is designed for:

  • Compact storage with versioning support
  • CRC16 checksums compatible with KV Engine's CRC algorithm
  • Product-specific key prefixes for OTA update compatibility
  • Forward/backward compatibility for configuration migration
Author
MeshX Team
Date
2024

Macro Definition Documentation

◆ MESHX_GPIO_CONFIG_FLAG_HAS_INTR

#define MESHX_GPIO_CONFIG_FLAG_HAS_INTR   (1 << 1)

Flag: Configuration has interrupt extensions.

◆ MESHX_GPIO_CONFIG_FLAG_HAS_PWM

#define MESHX_GPIO_CONFIG_FLAG_HAS_PWM   (1 << 0)

Flag: Configuration has PWM extensions.

◆ MESHX_GPIO_CONFIG_FLAG_MIGRATED

#define MESHX_GPIO_CONFIG_FLAG_MIGRATED   (1 << 2)

Flag: Configuration is migrated from older version.

◆ MESHX_GPIO_CONFIG_FLAG_READ_ONLY

#define MESHX_GPIO_CONFIG_FLAG_READ_ONLY   (1 << 3)

Flag: Configuration is in read-only mode.

◆ MESHX_GPIO_CONFIG_HEADER_SIZE

#define MESHX_GPIO_CONFIG_HEADER_SIZE   sizeof(meshx_gpio_config_header_kv_t)

Size of configuration header.

◆ MESHX_GPIO_CONFIG_TOTAL_SIZE

#define MESHX_GPIO_CONFIG_TOTAL_SIZE ( pin_count)
Value:
#define MESHX_GPIO_PIN_CONFIG_SIZE
Size of basic pin configuration.
Definition meshx_gpio_kv.h:243
#define MESHX_GPIO_CONFIG_HEADER_SIZE
Size of configuration header.
Definition meshx_gpio_kv.h:240

Calculate total config size for given pin count.

259#define MESHX_GPIO_CONFIG_TOTAL_SIZE(pin_count) \
260 (MESHX_GPIO_CONFIG_HEADER_SIZE + ((pin_count) * MESHX_GPIO_PIN_CONFIG_SIZE))

◆ MESHX_GPIO_CONFIG_TYPE_INTR

#define MESHX_GPIO_CONFIG_TYPE_INTR   2

Interrupt configuration follows.

◆ MESHX_GPIO_CONFIG_TYPE_NONE

#define MESHX_GPIO_CONFIG_TYPE_NONE   0

No extended configuration.

◆ MESHX_GPIO_CONFIG_TYPE_PWM

#define MESHX_GPIO_CONFIG_TYPE_PWM   1

PWM configuration follows.

◆ MESHX_GPIO_CONFIG_VERSION_CURRENT

#define MESHX_GPIO_CONFIG_VERSION_CURRENT   1

Current GPIO configuration serialization format version.

◆ MESHX_GPIO_CONFIG_VERSION_MAX

#define MESHX_GPIO_CONFIG_VERSION_MAX   1

Maximum supported version (for forward compatibility).

◆ MESHX_GPIO_CONFIG_VERSION_MIN

#define MESHX_GPIO_CONFIG_VERSION_MIN   1

Minimum supported version (for backward compatibility).

◆ MESHX_GPIO_INTR_CONFIG_SIZE

#define MESHX_GPIO_INTR_CONFIG_SIZE   sizeof(meshx_gpio_intr_config_kv_t)

Size of interrupt configuration extension.

◆ MESHX_GPIO_KV_KEY_CONFIG

#define MESHX_GPIO_KV_KEY_CONFIG   "config"

Key suffix for main GPIO configuration.

◆ MESHX_GPIO_KV_KEY_INTR

#define MESHX_GPIO_KV_KEY_INTR   "intr"

Key suffix for interrupt configuration.

◆ MESHX_GPIO_KV_KEY_MAX_LEN

#define MESHX_GPIO_KV_KEY_MAX_LEN   32

Maximum total key length (KV Engine limit is 32).

◆ MESHX_GPIO_KV_KEY_PWM

#define MESHX_GPIO_KV_KEY_PWM   "pwm"

Key suffix for PWM configuration.

◆ MESHX_GPIO_KV_KEY_STATE

#define MESHX_GPIO_KV_KEY_STATE   "state"

Key suffix for GPIO pin state.

◆ MESHX_GPIO_KV_PRODUCT_NAME_MAX_LEN

#define MESHX_GPIO_KV_PRODUCT_NAME_MAX_LEN   16

Maximum length for product name in key prefix.

◆ MESHX_GPIO_PIN_CONFIG_SIZE

#define MESHX_GPIO_PIN_CONFIG_SIZE   sizeof(meshx_gpio_pin_config_kv_t)

Size of basic pin configuration.

◆ MESHX_GPIO_PIN_MAX_SIZE

#define MESHX_GPIO_PIN_MAX_SIZE
Value:
#define MESHX_GPIO_PWM_CONFIG_SIZE
Size of PWM configuration extension.
Definition meshx_gpio_kv.h:246

Maximum size per pin (including extensions).

255#define MESHX_GPIO_PIN_MAX_SIZE (MESHX_GPIO_PIN_CONFIG_SIZE + \
256 MESHX_GPIO_PWM_CONFIG_SIZE)

◆ MESHX_GPIO_PIN_STATE_SIZE

#define MESHX_GPIO_PIN_STATE_SIZE   sizeof(meshx_gpio_pin_state_kv_t)

Size of pin state record.

◆ MESHX_GPIO_PWM_CONFIG_SIZE

#define MESHX_GPIO_PWM_CONFIG_SIZE   sizeof(meshx_gpio_pwm_config_kv_t)

Size of PWM configuration extension.

Function Documentation

◆ meshx_gpio_clear_config_in_kv()

meshx_err_t meshx_gpio_clear_config_in_kv ( void )

Clear GPIO configuration from KV Engine.

Removes the stored GPIO configuration, forcing fallback to defaults on next load.

Returns
meshx_err_t MESHX_SUCCESS on success, error code on failure
581{
583 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "KV persistence not initialized");
585 }
586
587 /* Construct KV key */
589 if (meshx_gpio_kv_make_config_key(current_product_name, key, sizeof(key)) == 0) {
590 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "Failed to construct config key");
591 return MESHX_FAIL;
592 }
593
594 /* Remove from KV Engine */
596 if (err != MESHX_SUCCESS) {
597 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "Failed to remove config: %d", err);
598 return err;
599 }
600
601 /* Commit the removal */
603 if (err != MESHX_SUCCESS) {
604 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "Failed to commit removal: %d", err);
605 return err;
606 }
607
608 MESHX_LOGI(MODULE_ID_COMPONENT_MESHX_GPIO, "Cleared GPIO config from KV");
609 return MESHX_SUCCESS;
610}
meshx_err_t
MeshX Error Codes.
Definition meshx_err.h:43
@ MESHX_FAIL
Definition meshx_err.h:45
@ MESHX_ERR_GPIO_NOT_INITIALIZED
Definition meshx_err.h:70
static bool kv_persistence_initialized
Flag indicating if KV persistence is initialized.
Definition meshx_gpio_kv.c:46
static char current_product_name[16+1]
Current product name for key prefix.
Definition meshx_gpio_kv.c:43
#define MESHX_GPIO_KV_KEY_MAX_LEN
Maximum total key length (KV Engine limit is 32).
Definition meshx_gpio_kv.h:51
static uint8_t meshx_gpio_kv_make_config_key(const char *product_name, char *buf, uint8_t buf_len)
Construct KV Engine key for GPIO configuration.
Definition meshx_gpio_kv.h:72
meshx_err_t meshx_kv_engine_commit(void)
Commit all buffered changes to flash.
Definition meshx_kv_engine.c:181
meshx_err_t meshx_kv_engine_remove(const char *key)
Remove a key from the KV engine.
Definition meshx_kv_engine.c:223
#define MESHX_LOGI(module_id, format,...)
Definition meshx_log.h:126
#define MESHX_LOGE(module_id, format,...)
Definition meshx_log.h:114
**This function is called by the parent element when a state change request *is received It validates the request and returns a result to the element not the model layer **return * MESHX_SUCCESS
Definition meshx_model_level.cpp:385
@ MODULE_ID_COMPONENT_MESHX_GPIO
Definition module_id.h:44

◆ meshx_gpio_config_exists_in_kv()

meshx_err_t meshx_gpio_config_exists_in_kv ( bool * exists)

Check if GPIO configuration exists in KV Engine.

Parameters
[out]existstrue if configuration exists, false otherwise
Returns
meshx_err_t MESHX_SUCCESS on success, error code on failure
385{
387 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "KV persistence not initialized");
389 }
390
391 if (!exists) {
392 return MESHX_INVALID_ARG;
393 }
394
395 /* Construct KV key */
397 if (meshx_gpio_kv_make_config_key(current_product_name, key, sizeof(key)) == 0) {
398 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "Failed to construct config key");
399 return MESHX_FAIL;
400 }
401
402 /* Try to read with zero-length buffer to check existence */
403 uint8_t dummy;
404 meshx_err_t err = meshx_kv_engine_read(key, &dummy, 0);
405
406 *exists = (err == MESHX_SUCCESS);
407
408 return MESHX_SUCCESS;
409}
@ MESHX_INVALID_ARG
Definition meshx_err.h:46
meshx_err_t meshx_kv_engine_read(const char *key, void *buf, uint16_t len)
Read a value from the KV engine.
Definition meshx_kv_engine.c:105

◆ meshx_gpio_export_config()

meshx_err_t meshx_gpio_export_config ( const meshx_gpio_pin_config_t * configs,
uint8_t pin_count,
uint8_t * buf,
uint16_t buf_len,
uint16_t * out_size )

Export GPIO configuration to serialized format.

Exports the configuration in binary format for transfer to another device.

Parameters
configsArray of pin configurations
pin_countNumber of pins
[out]bufOutput buffer
buf_lenBuffer length
[out]out_sizeActual exported size
Returns
meshx_err_t MESHX_SUCCESS on success, error code on failure
537{
538 if (!configs || !buf || !out_size) {
539 return MESHX_INVALID_ARG;
540 }
541
542 /* Export uses the same serialization format as KV storage */
543 return serialize_gpio_config(configs, pin_count, buf, buf_len, out_size);
544}
static meshx_err_t serialize_gpio_config(const meshx_gpio_pin_config_t *configs, uint8_t pin_count, uint8_t *buf, uint16_t buf_len, uint16_t *out_size)
Serialize GPIO configuration to buffer.
Definition meshx_gpio_kv.c:62

◆ meshx_gpio_import_config()

meshx_err_t meshx_gpio_import_config ( const uint8_t * buf,
uint16_t buf_len,
meshx_gpio_pin_config_t * configs,
uint8_t max_pins,
uint8_t * out_pin_count )

Import GPIO configuration from serialized format.

Imports configuration from binary format received from another device.

Parameters
bufInput buffer
buf_lenBuffer length
[out]configsArray to store imported configurations
max_pinsMaximum pins that can be stored
[out]out_pin_countActual number of pins imported
Returns
meshx_err_t MESHX_SUCCESS on success, error code on failure
563{
564 if (!buf || !configs || !out_pin_count) {
565 return MESHX_INVALID_ARG;
566 }
567
568 /* Import uses the same deserialization format as KV storage */
569 return deserialize_gpio_config(buf, buf_len, configs, max_pins, out_pin_count);
570}
static meshx_err_t deserialize_gpio_config(const uint8_t *buf, uint16_t buf_len, meshx_gpio_pin_config_t *configs, uint8_t max_pins, uint8_t *out_pin_count)
Deserialize GPIO configuration from buffer.
Definition meshx_gpio_kv.c:136

◆ meshx_gpio_kv_calc_crc16()

uint16_t meshx_gpio_kv_calc_crc16 ( const uint8_t * data,
uint32_t len )
inlinestatic

Calculate CRC16 compatible with KV Engine.

Uses the same CRC-16 algorithm as meshx_kv_engine.c (Modbus CRC-16 with polynomial 0xA001). This ensures the GPIO subsystem can independently verify data integrity.

Parameters
dataPointer to data buffer
lenLength of data in bytes
Returns
CRC16 value
307{
308 uint16_t crc = 0xFFFF;
309 for (uint32_t i = 0; i < len; i++) {
310 crc ^= data[i];
311 for (int j = 0; j < 8; j++) {
312 if (crc & 1) {
313 crc = (crc >> 1) ^ 0xA001;
314 } else {
315 crc >>= 1;
316 }
317 }
318 }
319 return crc;
320}

◆ meshx_gpio_kv_deinit()

meshx_err_t meshx_gpio_kv_deinit ( void )

Deinitialize GPIO KV Engine persistence.

Cleans up KV persistence resources. Does not affect the underlying KV Engine partition.

Returns
meshx_err_t MESHX_SUCCESS on success, error code on failure
621{
623 return MESHX_SUCCESS;
624 }
625
626 gpio_kv_partition = NULL;
627 memset(current_product_name, 0, sizeof(current_product_name));
629
630 MESHX_LOGI(MODULE_ID_COMPONENT_MESHX_GPIO, "GPIO KV persistence deinitialized");
631 return MESHX_SUCCESS;
632}
static const meshx_fal_partition_t * gpio_kv_partition
KV Engine partition reference (set during initialization).
Definition meshx_gpio_kv.c:40

◆ meshx_gpio_kv_deserialize_intr()

void meshx_gpio_kv_deserialize_intr ( const meshx_gpio_intr_config_kv_t * src,
meshx_gpio_pin_config_t * dst )
inlinestatic

Deserialize interrupt configuration.

Parameters
srcSource serialized configuration
dstDestination runtime configuration
503{
504 if (!src || !dst) return;
505
509}
uint8_t trigger_type
Definition meshx_gpio_kv.h:212
uint16_t task_stack_size
Definition meshx_gpio_kv.h:214
uint8_t task_priority
Definition meshx_gpio_kv.h:213
union meshx_gpio_pin_config_t::@052245231341204203052073036272225075106126036255 mode_config
Mode-specific configuration (union based on mode).
uint8_t task_priority
Definition meshx_gpio_types.h:65
uint16_t task_stack_size
Definition meshx_gpio_types.h:66
struct meshx_gpio_pin_config_t::@052245231341204203052073036272225075106126036255::@372143037256331057042353173011302234062346240366 interrupt
Interrupt configuration (for input pins with interrupts).
uint8_t trigger
Definition meshx_gpio_types.h:64

◆ meshx_gpio_kv_deserialize_pin()

void meshx_gpio_kv_deserialize_pin ( const meshx_gpio_pin_config_kv_t * src,
meshx_gpio_pin_config_t * dst )
inlinestatic

Convert serialized pin config to runtime format.

Parameters
srcSource serialized configuration
dstDestination runtime configuration
428{
429 if (!src || !dst) return;
430
431 dst->logical_pin = src->logical_pin;
432 dst->physical_pin = src->physical_pin;
433 dst->mode = src->mode;
434 dst->pull = src->pull;
435 dst->drive_strength = src->drive_strength;
436 dst->initial_level = src->initial_level;
437 dst->signal_inversion = src->signal_inversion ? true : false;
438}
uint8_t logical_pin
Definition meshx_gpio_kv.h:179
uint8_t pull
Definition meshx_gpio_kv.h:182
uint8_t mode
Definition meshx_gpio_kv.h:181
uint8_t physical_pin
Definition meshx_gpio_kv.h:180
uint8_t drive_strength
Definition meshx_gpio_kv.h:183
uint8_t signal_inversion
Definition meshx_gpio_kv.h:185
uint8_t initial_level
Definition meshx_gpio_kv.h:184
uint8_t logical_pin
Definition meshx_gpio_types.h:52
uint8_t mode
Definition meshx_gpio_types.h:54
uint8_t drive_strength
Definition meshx_gpio_types.h:56
uint8_t initial_level
Definition meshx_gpio_types.h:57
uint8_t physical_pin
Definition meshx_gpio_types.h:53
bool signal_inversion
Definition meshx_gpio_types.h:58
uint8_t pull
Definition meshx_gpio_types.h:55

◆ meshx_gpio_kv_deserialize_pwm()

void meshx_gpio_kv_deserialize_pwm ( const meshx_gpio_pwm_config_kv_t * src,
meshx_gpio_pin_config_t * dst )
inlinestatic

Deserialize PWM configuration.

Parameters
srcSource serialized configuration
dstDestination runtime configuration
466{
467 if (!src || !dst) return;
468
472 dst->mode_config.pwm.channel = src->channel;
473}
uint8_t channel
Definition meshx_gpio_types.h:74
uint8_t resolution
Definition meshx_gpio_types.h:73
uint32_t frequency
Definition meshx_gpio_types.h:71
uint8_t duty_cycle
Definition meshx_gpio_types.h:72
struct meshx_gpio_pin_config_t::@052245231341204203052073036272225075106126036255::@134165302231261162316035331261052006324312255312 pwm
PWM configuration (for PWM output pins).
uint8_t duty_cycle
Definition meshx_gpio_kv.h:198
uint8_t channel
Definition meshx_gpio_kv.h:200
uint8_t resolution
Definition meshx_gpio_kv.h:199
uint32_t frequency
Definition meshx_gpio_kv.h:197

◆ meshx_gpio_kv_finalize_crc16()

void meshx_gpio_kv_finalize_crc16 ( uint8_t * data,
uint32_t len )
inlinestatic

Calculate and set CRC16 for serialized configuration.

Parameters
dataPointer to serialized data buffer (including header)
lenTotal length of data
378{
379 if (!data || len < MESHX_GPIO_CONFIG_HEADER_SIZE) return;
380
382
383 /* CRC covers everything after the crc16 field */
384 const uint8_t *crc_data = data + offsetof(meshx_gpio_config_header_kv_t, total_size);
385 uint32_t crc_len = len - offsetof(meshx_gpio_config_header_kv_t, total_size);
386
387 header->crc16 = meshx_gpio_kv_calc_crc16(crc_data, crc_len);
388}
static uint16_t meshx_gpio_kv_calc_crc16(const uint8_t *data, uint32_t len)
Calculate CRC16 compatible with KV Engine.
Definition meshx_gpio_kv.h:306
Header for serialized GPIO configuration stored in KV Engine.
Definition meshx_gpio_kv.h:162
uint16_t crc16
Definition meshx_gpio_kv.h:165

◆ meshx_gpio_kv_init()

meshx_err_t meshx_gpio_kv_init ( const meshx_fal_partition_t * kv_partition,
const char * product_name )

Initialize GPIO KV Engine persistence.

This function initializes the KV Engine for GPIO configuration storage. It must be called before any other GPIO KV functions.

Parameters
kv_partitionPointer to the flash partition to use for KV storage
product_nameProduct name for key prefix (max 16 chars)
Returns
meshx_err_t MESHX_SUCCESS on success, error code on failure
232{
233 if (!kv_partition || !product_name) {
234 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "Invalid arguments for KV init");
235 return MESHX_INVALID_ARG;
236 }
237
238 /* Initialize KV Engine */
239 meshx_err_t err = meshx_kv_engine_init(kv_partition);
240 if (err != MESHX_SUCCESS) {
241 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "Failed to initialize KV Engine: %d", err);
242 return err;
243 }
244
245 /* Store partition reference */
246 gpio_kv_partition = kv_partition;
247
248 /* Store product name for key prefix */
251
253
254 MESHX_LOGI(MODULE_ID_COMPONENT_MESHX_GPIO, "GPIO KV persistence initialized for product: %s",
256 return MESHX_SUCCESS;
257}
#define MESHX_GPIO_KV_PRODUCT_NAME_MAX_LEN
Maximum length for product name in key prefix.
Definition meshx_gpio_kv.h:48
meshx_err_t meshx_kv_engine_init(const meshx_fal_partition_t *part)
Initialize the KV engine.
Definition meshx_kv_engine.c:66

◆ meshx_gpio_kv_init_header()

void meshx_gpio_kv_init_header ( meshx_gpio_config_header_kv_t * header,
uint8_t pin_count )
inlinestatic

Initialize a GPIO configuration header.

Parameters
headerPointer to header to initialize
pin_countNumber of pins in configuration
358{
359 if (!header) return;
360
362 header->pin_count = pin_count;
363 header->crc16 = 0;
364 header->total_size = (uint16_t)MESHX_GPIO_CONFIG_TOTAL_SIZE(pin_count);
365 header->flags = 0;
366 header->reserved[0] = 0;
367 header->reserved[1] = 0;
368 header->reserved[2] = 0;
369}
#define MESHX_GPIO_CONFIG_TOTAL_SIZE(pin_count)
Calculate total config size for given pin count.
Definition meshx_gpio_kv.h:259
#define MESHX_GPIO_CONFIG_VERSION_CURRENT
Current GPIO configuration serialization format version.
Definition meshx_gpio_kv.h:35
uint8_t flags
Definition meshx_gpio_kv.h:167
uint16_t total_size
Definition meshx_gpio_kv.h:166
uint8_t reserved[3]
Definition meshx_gpio_kv.h:168
uint8_t pin_count
Definition meshx_gpio_kv.h:164
uint8_t version
Definition meshx_gpio_kv.h:163

◆ meshx_gpio_kv_is_initialized()

bool meshx_gpio_kv_is_initialized ( void )

Check if GPIO KV persistence is initialized.

Returns
true if initialized, false otherwise
640{
642}

◆ meshx_gpio_kv_is_version_supported()

bool meshx_gpio_kv_is_version_supported ( uint8_t version)
inlinestatic

Check if a configuration version is supported.

Parameters
versionVersion number to check
Returns
true if version is supported, false otherwise
522{
523 return (version >= MESHX_GPIO_CONFIG_VERSION_MIN &&
525}
#define MESHX_GPIO_CONFIG_VERSION_MIN
Minimum supported version (for backward compatibility).
Definition meshx_gpio_kv.h:38
#define MESHX_GPIO_CONFIG_VERSION_MAX
Maximum supported version (for forward compatibility).
Definition meshx_gpio_kv.h:41

◆ meshx_gpio_kv_make_config_key()

uint8_t meshx_gpio_kv_make_config_key ( const char * product_name,
char * buf,
uint8_t buf_len )
inlinestatic

Construct KV Engine key for GPIO configuration.

Parameters
product_nameProduct name (max 16 chars)
bufBuffer to store the key
buf_lenBuffer length
Returns
Key length, or 0 on error
74{
75 if (!product_name || !buf || buf_len < MESHX_GPIO_KV_KEY_MAX_LEN) {
76 return 0;
77 }
78 return (uint8_t)snprintf(buf, buf_len, "gpio_%.*s_%s",
80 product_name,
82}
#define MESHX_GPIO_KV_KEY_CONFIG
Key suffix for main GPIO configuration.
Definition meshx_gpio_kv.h:54

◆ meshx_gpio_kv_make_intr_key()

uint8_t meshx_gpio_kv_make_intr_key ( const char * product_name,
uint8_t logical_pin,
char * buf,
uint8_t buf_len )
inlinestatic

Construct KV Engine key for interrupt configuration.

Parameters
product_nameProduct name (max 16 chars)
logical_pinLogical pin number
bufBuffer to store the key
buf_lenBuffer length
Returns
Key length, or 0 on error
139{
140 if (!product_name || !buf || buf_len < MESHX_GPIO_KV_KEY_MAX_LEN) {
141 return 0;
142 }
143 return (uint8_t)snprintf(buf, buf_len, "gpio_%.*s_%s_%u",
145 product_name,
147 logical_pin);
148}
#define MESHX_GPIO_KV_KEY_INTR
Key suffix for interrupt configuration.
Definition meshx_gpio_kv.h:63

◆ meshx_gpio_kv_make_pwm_key()

uint8_t meshx_gpio_kv_make_pwm_key ( const char * product_name,
uint8_t logical_pin,
char * buf,
uint8_t buf_len )
inlinestatic

Construct KV Engine key for PWM configuration.

Parameters
product_nameProduct name (max 16 chars)
logical_pinLogical pin number
bufBuffer to store the key
buf_lenBuffer length
Returns
Key length, or 0 on error
117{
118 if (!product_name || !buf || buf_len < MESHX_GPIO_KV_KEY_MAX_LEN) {
119 return 0;
120 }
121 return (uint8_t)snprintf(buf, buf_len, "gpio_%.*s_%s_%u",
123 product_name,
125 logical_pin);
126}
#define MESHX_GPIO_KV_KEY_PWM
Key suffix for PWM configuration.
Definition meshx_gpio_kv.h:60

◆ meshx_gpio_kv_make_state_key()

uint8_t meshx_gpio_kv_make_state_key ( const char * product_name,
uint8_t logical_pin,
char * buf,
uint8_t buf_len )
inlinestatic

Construct KV Engine key for GPIO pin state.

Parameters
product_nameProduct name (max 16 chars)
logical_pinLogical pin number
bufBuffer to store the key
buf_lenBuffer length
Returns
Key length, or 0 on error
95{
96 if (!product_name || !buf || buf_len < MESHX_GPIO_KV_KEY_MAX_LEN) {
97 return 0;
98 }
99 return (uint8_t)snprintf(buf, buf_len, "gpio_%.*s_%s_%u",
101 product_name,
103 logical_pin);
104}
#define MESHX_GPIO_KV_KEY_STATE
Key suffix for GPIO pin state.
Definition meshx_gpio_kv.h:57

◆ meshx_gpio_kv_needs_migration()

bool meshx_gpio_kv_needs_migration ( uint8_t from_version,
uint8_t to_version )
inlinestatic

Get migration requirement between versions.

Parameters
from_versionSource version
to_versionTarget version
Returns
true if migration is needed, false if direct loading is possible
536{
537 return (from_version != to_version);
538}

◆ meshx_gpio_kv_serialize_intr()

void meshx_gpio_kv_serialize_intr ( const meshx_gpio_pin_config_t * src,
meshx_gpio_intr_config_kv_t * dst )
inlinestatic

Serialize interrupt configuration.

Parameters
srcSource runtime interrupt configuration
dstDestination serialized configuration
483{
484 if (!src || !dst) return;
485
489 dst->flags = 0;
490 dst->reserved[0] = 0;
491 dst->reserved[1] = 0;
492 dst->reserved[2] = 0;
493}
uint8_t flags
Definition meshx_gpio_kv.h:215
uint8_t reserved[3]
Definition meshx_gpio_kv.h:216

◆ meshx_gpio_kv_serialize_pin()

void meshx_gpio_kv_serialize_pin ( const meshx_gpio_pin_config_t * src,
meshx_gpio_pin_config_kv_t * dst )
inlinestatic

Convert runtime pin config to serialized format.

Parameters
srcSource runtime configuration
dstDestination serialized configuration
398{
399 if (!src || !dst) return;
400
401 dst->logical_pin = src->logical_pin;
402 dst->physical_pin = src->physical_pin;
403 dst->mode = src->mode;
404 dst->pull = src->pull;
405 dst->drive_strength = src->drive_strength;
406 dst->initial_level = src->initial_level;
407 dst->signal_inversion = src->signal_inversion ? 1 : 0;
408
409 /* Determine config type based on mode */
410 if (src->mode == 5) { /* MESHX_GPIO_MODE_PWM_OUTPUT */
412 } else if (src->mode == 0 && src->mode_config.interrupt.trigger != 0) {
413 /* Input mode with interrupt */
415 } else {
417 }
418}
#define MESHX_GPIO_CONFIG_TYPE_NONE
No extended configuration.
Definition meshx_gpio_kv.h:283
#define MESHX_GPIO_CONFIG_TYPE_PWM
PWM configuration follows.
Definition meshx_gpio_kv.h:286
#define MESHX_GPIO_CONFIG_TYPE_INTR
Interrupt configuration follows.
Definition meshx_gpio_kv.h:289
uint8_t config_type
Definition meshx_gpio_kv.h:186

◆ meshx_gpio_kv_serialize_pwm()

void meshx_gpio_kv_serialize_pwm ( const meshx_gpio_pin_config_t * src,
meshx_gpio_pwm_config_kv_t * dst )
inlinestatic

Serialize PWM configuration.

Parameters
srcSource runtime PWM configuration
dstDestination serialized configuration
448{
449 if (!src || !dst) return;
450
454 dst->channel = src->mode_config.pwm.channel;
455 dst->reserved = 0;
456}
uint8_t reserved
Definition meshx_gpio_kv.h:201

◆ meshx_gpio_kv_verify_crc16()

bool meshx_gpio_kv_verify_crc16 ( const uint8_t * data,
uint32_t len )
inlinestatic

Verify CRC16 of serialized GPIO configuration.

Parameters
dataPointer to serialized data (including header)
lenTotal length of data
Returns
true if CRC is valid, false otherwise
330{
331 if (!data || len < MESHX_GPIO_CONFIG_HEADER_SIZE) {
332 return false;
333 }
334
335 const meshx_gpio_config_header_kv_t *header =
336 (const meshx_gpio_config_header_kv_t *)data;
337
338 /* CRC covers everything after the crc16 field in the header */
339 const uint8_t *crc_data = data + offsetof(meshx_gpio_config_header_kv_t, total_size);
340 uint32_t crc_len = len - offsetof(meshx_gpio_config_header_kv_t, total_size);
341
342 uint16_t calculated = meshx_gpio_kv_calc_crc16(crc_data, crc_len);
343 return (calculated == header->crc16);
344}

◆ meshx_gpio_load_config_from_kv()

meshx_err_t meshx_gpio_load_config_from_kv ( meshx_gpio_pin_config_t * configs,
uint8_t max_pins,
uint8_t * out_pin_count )

Load GPIO configuration from KV Engine.

This function loads and deserializes GPIO configuration from KV Engine. If the configuration is not found or corrupted, returns MESHX_NOT_FOUND to allow fallback to compiled defaults.

Parameters
configsArray to store loaded pin configurations
max_pinsMaximum pins that can be stored
[out]out_pin_countActual number of pins loaded
Returns
meshx_err_t MESHX_SUCCESS on success, MESHX_NOT_FOUND if not found, error code on other failures
334{
336 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "KV persistence not initialized");
338 }
339
340 if (!configs || !out_pin_count) {
341 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "Invalid arguments for load");
342 return MESHX_INVALID_ARG;
343 }
344
345 /* Construct KV key */
347 if (meshx_gpio_kv_make_config_key(current_product_name, key, sizeof(key)) == 0) {
348 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "Failed to construct config key");
349 return MESHX_FAIL;
350 }
351
352 /* Read from KV Engine */
353 uint8_t buffer[MESHX_GPIO_KV_MAX_CONFIG_SIZE];
354 uint16_t read_size = sizeof(buffer);
355
356 meshx_err_t err = meshx_kv_engine_read(key, buffer, read_size);
357 if (err != MESHX_SUCCESS) {
358 if (err == MESHX_NOT_FOUND) {
359 MESHX_LOGI(MODULE_ID_COMPONENT_MESHX_GPIO, "No GPIO config found in KV, using defaults");
360 } else {
361 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "Failed to read KV: %d", err);
362 }
363 return err;
364 }
365
366 /* Deserialize configuration */
367 err = deserialize_gpio_config(buffer, read_size, configs, max_pins, out_pin_count);
368 if (err != MESHX_SUCCESS) {
369 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "Failed to deserialize config (corrupted?): %d", err);
370 /* Return NOT_FOUND to trigger fallback to defaults */
371 return MESHX_NOT_FOUND;
372 }
373
374 MESHX_LOGI(MODULE_ID_COMPONENT_MESHX_GPIO, "Loaded GPIO config: %d pins", *out_pin_count);
375 return MESHX_SUCCESS;
376}
@ MESHX_NOT_FOUND
Definition meshx_err.h:50
#define MESHX_GPIO_KV_MAX_CONFIG_SIZE
Maximum buffer size for GPIO configuration serialization.
Definition meshx_gpio_kv.c:30

◆ meshx_gpio_load_pin_state_from_kv()

meshx_err_t meshx_gpio_load_pin_state_from_kv ( uint8_t logical_pin,
meshx_gpio_pin_state_t * state )

Load pin state from KV Engine.

Loads previously persisted runtime state of a GPIO pin.

Parameters
logical_pinLogical pin number
[out]statePointer to store loaded pin state
Returns
meshx_err_t MESHX_SUCCESS on success, MESHX_NOT_FOUND if not found, error code on other failures
479{
481 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "KV persistence not initialized");
483 }
484
485 if (!state) {
486 return MESHX_INVALID_ARG;
487 }
488
489 /* Construct KV key for state */
491 if (meshx_gpio_kv_make_state_key(current_product_name, logical_pin, key, sizeof(key)) == 0) {
492 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "Failed to construct state key");
493 return MESHX_FAIL;
494 }
495
496 /* Read from KV Engine */
498 uint16_t read_size = sizeof(state_kv);
499
500 meshx_err_t err = meshx_kv_engine_read(key, &state_kv, read_size);
501 if (err != MESHX_SUCCESS) {
502 if (err == MESHX_NOT_FOUND) {
503 MESHX_LOGD(MODULE_ID_COMPONENT_MESHX_GPIO, "No state found for pin %u", logical_pin);
504 } else {
505 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "Failed to read pin state: %d", err);
506 }
507 return err;
508 }
509
510 /* Apply loaded state */
511 state->current_level = state_kv.current_level;
512 state->mode_state.pwm.started = state_kv.pwm_started;
513 state->mode_state.pwm.duty_cycle = state_kv.current_duty;
514
515 MESHX_LOGD(MODULE_ID_COMPONENT_MESHX_GPIO, "Loaded state for pin %u: level=%u",
516 logical_pin, state->current_level);
517 return MESHX_SUCCESS;
518}
static uint8_t meshx_gpio_kv_make_state_key(const char *product_name, uint8_t logical_pin, char *buf, uint8_t buf_len)
Construct KV Engine key for GPIO pin state.
Definition meshx_gpio_kv.h:92
#define MESHX_LOGD(module_id, format,...)
Definition meshx_log.h:132
uint8_t state
Definition meshx_serial.c:39
Serialized GPIO pin state for KV Engine storage.
Definition meshx_gpio_kv.h:226
uint8_t current_duty
Definition meshx_gpio_kv.h:230
uint8_t current_level
Definition meshx_gpio_kv.h:228
uint8_t pwm_started
Definition meshx_gpio_kv.h:229

◆ meshx_gpio_save_config_to_kv()

meshx_err_t meshx_gpio_save_config_to_kv ( const meshx_gpio_pin_config_t * configs,
uint8_t pin_count )

Save GPIO configuration to KV Engine.

This function serializes and saves the GPIO configuration to KV Engine with versioning and CRC validation.

Parameters
configsArray of pin configurations to save
pin_countNumber of pins in configuration
Returns
meshx_err_t MESHX_SUCCESS on success, error code on failure
271{
273 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "KV persistence not initialized");
275 }
276
277 if (!configs || pin_count == 0) {
278 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "Invalid arguments for save");
279 return MESHX_INVALID_ARG;
280 }
281
282 /* Construct KV key */
284 if (meshx_gpio_kv_make_config_key(current_product_name, key, sizeof(key)) == 0) {
285 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "Failed to construct config key");
286 return MESHX_FAIL;
287 }
288
289 /* Serialize configuration */
290 uint8_t buffer[MESHX_GPIO_KV_MAX_CONFIG_SIZE];
291 uint16_t config_size = 0;
292
293 meshx_err_t err = serialize_gpio_config(configs, pin_count, buffer, sizeof(buffer), &config_size);
294 if (err != MESHX_SUCCESS) {
295 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "Failed to serialize config: %d", err);
296 return err;
297 }
298
299 /* Save to KV Engine (buffered in RAM) */
300 err = meshx_kv_engine_set(key, buffer, config_size);
301 if (err != MESHX_SUCCESS) {
302 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "Failed to set KV value: %d", err);
303 return err;
304 }
305
306 /* Commit to flash */
308 if (err != MESHX_SUCCESS) {
309 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "Failed to commit KV: %d", err);
310 return err;
311 }
312
313 MESHX_LOGI(MODULE_ID_COMPONENT_MESHX_GPIO, "Saved GPIO config: %d pins, %d bytes",
314 pin_count, config_size);
315 return MESHX_SUCCESS;
316}
meshx_err_t meshx_kv_engine_set(const char *key, const void *buf, uint16_t len)
Buffer a write operation in RAM.
Definition meshx_kv_engine.c:157

◆ meshx_gpio_save_pin_state_to_kv()

meshx_err_t meshx_gpio_save_pin_state_to_kv ( uint8_t logical_pin,
const meshx_gpio_pin_state_t * state )

Save current pin state to KV Engine.

Persists the runtime state of a GPIO pin across reboots.

Parameters
logical_pinLogical pin number
statePointer to pin state to save
Returns
meshx_err_t MESHX_SUCCESS on success, error code on failure
422{
424 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "KV persistence not initialized");
426 }
427
428 if (!state) {
429 return MESHX_INVALID_ARG;
430 }
431
432 /* Construct KV key for state */
434 if (meshx_gpio_kv_make_state_key(current_product_name, logical_pin, key, sizeof(key)) == 0) {
435 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "Failed to construct state key");
436 return MESHX_FAIL;
437 }
438
439 /* Serialize pin state */
440 meshx_gpio_pin_state_kv_t state_kv = {
441 .logical_pin = logical_pin,
442 .current_level = state->current_level,
443 .pwm_started = state->mode_state.pwm.started,
444 .current_duty = state->mode_state.pwm.duty_cycle,
445 .reserved = 0
446 };
447
448 /* Save to KV Engine */
449 meshx_err_t err = meshx_kv_engine_set(key, &state_kv, sizeof(state_kv));
450 if (err != MESHX_SUCCESS) {
451 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "Failed to save pin state: %d", err);
452 return err;
453 }
454
455 /* Commit to flash */
457 if (err != MESHX_SUCCESS) {
458 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "Failed to commit pin state: %d", err);
459 return err;
460 }
461
462 MESHX_LOGD(MODULE_ID_COMPONENT_MESHX_GPIO, "Saved state for pin %u: level=%u",
463 logical_pin, state->current_level);
464 return MESHX_SUCCESS;
465}