浏览代码

Merge branch 'MN_REVISION_V2' into 'main'

Mn revision v2

See merge request sensorical/fw/nbus!9
Juraj Ďuďák 10 月之前
父节点
当前提交
d3679a74e9
共有 9 个文件被更改,包括 628 次插入250 次删除
  1. 69 17
      include/app_bridge.h
  2. 14 8
      include/app_dummy.h
  3. 4 8
      include/nbus_cmd.h
  4. 37 0
      include/nbus_types.h
  5. 0 32
      src/app_bridge.c
  6. 200 31
      src/app_dummy.c
  7. 7 8
      src/nbus_app.c
  8. 184 82
      src/nbus_slave_module_unicast.c
  9. 113 64
      src/nbus_slave_sensor_unicast.c

+ 69 - 17
include/app_bridge.h

@@ -12,15 +12,19 @@
 
 typedef enum
 {
+    // read-only sensors
     TYPE_UNKNOWN = 0xFF,
     TYPE_ACCELEROMETER = 0,
     TYPE_GYROSCOPE,
     TYPE_MAGNETOMETER,
-    TYPE_TEMPERATURE,
-    TYPE_HUMIDITY,
-    TYPE_PRESSURE,
-    TYPE_HEART_RATE,
-    TYPE_DEVIATION_DISTANCE,
+    TYPE_THERMOMETER,
+    TYPE_HYGROMETER,
+    TYPE_PRESSURE_GAUGE,
+    TYPE_HEART_RATE_MONITOR,
+    TYPE_LENGTH_GAUGE,
+    // read-write sensors
+    TYPE_LED_CONTROLLER,
+    TYPE_MOTOR_CONTROLLER
 } nBus_sensorType_t;
 
 typedef enum
@@ -33,33 +37,81 @@ typedef enum
     PARAM_SAMPLERATE,
     PARAM_RANGE,
     PARAM_RANGE0,
-    PARAM_FILTER
+    PARAM_FILTER,
+    _NBUS_PARAM_COUNT // number of parameters, must be last!
 } nBus_param_t;
 
-#define PARAM_VALUE_NONE 0x7FFFFFFF
+typedef enum
+{
+    STATUS_NOT_SUPPORTED = 0xFF,
+    STATUS_SUCCESS = 0,
+    STATUS_FAIL = 1
+} nBus_statusType_t;
 
-nBus_param_t *nbus_interface_allParams();
-uint8_t nbus_interface_allParamsCount();
+/**
+ * @brief Definuje formát dát senzora.
+ * @note Bajtová reprezentácia (Little Endian) bude nasledovná: | unit_multiplier | sign | value_multiplier | samples |
+ * byte_length
+ */
+typedef struct __attribute__((packed, aligned(1)))
+{
+    /** Bit určujúci či sú dáta znamienkové.
+     * 0 = ungigned, 1 = signed */
+    uint8_t sign : 1;
 
-nBus_sensorType_t *nbus_interface_allTypes();
-uint8_t nbus_interface_allTypesCount();
+    /** Násobok základnej meranej jednotky (mili, micro, kilo, deka, mega, ...)
+     * uložený v logaritmickom tvare (pr. 2 -> 10^2).
+     * @note: povolený rozsah [-64 , +63]
+     */
+    uint8_t unit_multiplier : 7;
+
+    /** Násobok meranej hodnoty uložený v logaritmickom tvare (pr. 1 -> 10^1).
+     * @note: povolený rozsah [-128 , +127]
+     */
+    uint8_t value_multiplier : 8;
+
+    /** Počet bajtov meranej hodnoty.
+     * @note: povolený rozsah [1 , 8]
+     */
+    uint8_t byte_length : 4;
+
+    /** Počet vzoriek meranej hodnoty.
+     * @note: povolený rozsah [1 , 16]
+     */
+    uint8_t samples : 4;
+} nBus_sensorFormat_t;
+
+typedef struct
+{
+    uint8_t read_only_count;
+    uint8_t read_write_count;
+} nBus_sensorCount_t;
+
+#define PARAM_VALUE_NONE 0x7FFFFFFF
 
 typedef struct
 {
     void (*init)(void *hw_interface, void *hw_config);
     void (*reset)();
     nBus_sensorType_t (*getType)(uint8_t sensor_index);
-    uint8_t (*getSensorCount)();
+    nBus_sensorCount_t (*getSensorCount)();
+
     uint8_t (*getData)(uint8_t sensor_index, uint8_t *data);
-    uint8_t (*setData)(uint8_t *data);
+    nBus_statusType_t (*setData)(uint8_t *data, uint8_t count, uint8_t *response);
+
     uint8_t (*hasParam)(uint8_t sensor_index, nBus_param_t param_name);
     int32_t (*getParam)(uint8_t sensor_index, nBus_param_t param_name);
-    nBus_param_t (*setParam)(uint8_t sensor_index, nBus_param_t param_name, int32_t param_value);
-    void (*start)(void);
-    void (*stop)(void);
+    nBus_statusType_t (*setParam)(uint8_t sensor_index, nBus_param_t param_name, int32_t param_value);
+
+    nBus_statusType_t (*start)(void);
+    nBus_statusType_t (*stop)(void);
     void (*read)(void);
     uint8_t (*store)(void);
-    uint8_t (*calibrate)(uint8_t subslaveIndex, uint8_t calibrationParamsNum, uint8_t *calibrationParams);
+
+    nBus_statusType_t (*calibrate)(uint8_t sensor_index);
+    nBus_sensorFormat_t (*getSensorFormat)(uint8_t sensor_index);
+    nBus_statusType_t (*find)(uint8_t enable);
+    uint8_t (*device_ready)();
 } nBusAppInterface_t;
 
 #endif /* MODULES_NBUS_INC_APP_BRIDGE_H_ */

+ 14 - 8
include/app_dummy.h

@@ -22,18 +22,24 @@ extern "C"
     void dummy_init(void *hw_interface, void *hw_config);
     void dummy_reset();
     nBus_sensorType_t dummy_getType(uint8_t sensor_index);
-    uint8_t dummy_getSensorCount();
+    nBus_sensorCount_t dummy_getSensorCount();
+
     uint8_t dummy_getData(uint8_t sensor_index, uint8_t *data);
-    uint8_t dummy_setData(uint8_t *data);
-    int32_t dummy_getParam(uint8_t sensor_index, nBus_param_t param);
-    uint8_t dummy_hasParam(uint8_t sensor_index, nBus_param_t param);
-    nBus_param_t dummy_setParam(uint8_t sensor_index, nBus_param_t param, int32_t value);
-    void dummy_start(void);
-    void dummy_stop(void);
+    nBus_statusType_t dummy_setData(uint8_t *data, uint8_t count, uint8_t *response);
+
+    uint8_t dummy_hasParam(uint8_t sensor_index, nBus_param_t param_name);
+    int32_t dummy_getParam(uint8_t sensor_index, nBus_param_t param_name);
+    nBus_statusType_t dummy_setParam(uint8_t sensor_index, nBus_param_t param_name, int32_t param_value);
+
+    nBus_statusType_t dummy_start(void);
+    nBus_statusType_t dummy_stop(void);
     void dummy_read(void);
     uint8_t dummy_store(void);
-    uint8_t dummy_calibrate(uint8_t subslaveIndex, uint8_t calibrationParamsNum, uint8_t *calibrationParams);
 
+    nBus_statusType_t dummy_calibrate(uint8_t sensor_index);
+    nBus_sensorFormat_t dummy_getSensorFormat(uint8_t sensor_index);
+    nBus_statusType_t dummy_find(uint8_t enable);
+    uint8_t dummy_device_ready();
 #ifdef __cplusplus
 }
 #endif

+ 4 - 8
include/nbus_cmd.h

@@ -15,6 +15,7 @@
 #ifndef NBUS_CMD_H
 #define NBUS_CMD_H
 
+#define CMD_FIND 0x00
 #define CMD_ECHO 0x01
 #define CMD_STOP 0x02
 #define CMD_START 0x03
@@ -29,14 +30,7 @@
 #define CMD_SYNC 0x0C
 #define CMD_SENSOR_TYPE 0x0D
 #define CMD_INFO 0x0E
-
-// Command  parameters
-#define INFO_MODULE_NAME 0xE1
-#define INFO_MODULE_TYPE 0xE2
-#define INFO_MODULE_UUID 0xE3
-#define INFO_MODULE_HW 0xE4
-#define INFO_MODULE_FW 0xE5 // ?
-#define INFO_MODULE_MEMORY_ID 0xE6
+#define CMD_FORMAT 0x0F
 
 #define PARAM_SENSOR_SAMPLERATE 0x41
 #define PARAM_SENSOR_LPF 0x42
@@ -52,6 +46,8 @@
 #define DEVICE_BUSY (0x06)
 #define DEVICE_NOT_READY (0x07)
 #define PARAM_NOT_IMPLEMENTED (0x10)
+#define ILLEGAL_FUNCTION_PARAM (0x11)
+#define DEVICE_IS_READ_ONLY (0x12)
 
 /**
  * Chyba pri vykonaní príkazu v subslave, napr. ak senzor nie je pripojený.

+ 37 - 0
include/nbus_types.h

@@ -18,6 +18,43 @@
  */
 #define META_SIZE 5
 
+#define RX_META 4
+
+/**
+ * @brief Index Module Address v RX pakete.
+ */
+#define RX_MA 0
+
+/**
+ * @brief Index Sensor Address v RX pakete.
+ */
+#define RX_SA 1
+
+/**
+ * @brief Index Function Code v RX pakete.
+ */
+#define RX_FC 2
+
+/**
+ * @brief Index Data v RX pakete.
+ */
+#define RX_DT 3
+
+/**
+ * @brief Index Data v TX pakete.
+ */
+#define TX_DT 4
+
+/**
+ * @brief Sensor Read-Only Address offset.
+ */
+#define SENSOR_RO_ADDR 1
+
+/**
+ * @brief Sensor Read-Write Address offset.
+ */
+#define SENSOR_RW_ADDR 129
+
 /**
  * @brief Maximálna veľkosť dátovej časti v pakete.
  */

+ 0 - 32
src/app_bridge.c

@@ -1,32 +0,0 @@
-/*
- * app_bridge.c
- *
- *  Created on: Nov 2, 2023
- *      Author: juraj
- */
-#include "app_bridge.h"
-
-nBus_param_t allParams[] = {PARAM_TIMEBASE,   PARAM_RESOLUTION, PARAM_GAIN,   PARAM_OFFSET,
-                            PARAM_SAMPLERATE, PARAM_RANGE,      PARAM_RANGE0, PARAM_FILTER};
-nBus_sensorType_t allTypes[] = {TYPE_ACCELEROMETER, TYPE_GYROSCOPE, TYPE_MAGNETOMETER, TYPE_TEMPERATURE,
-                                TYPE_HUMIDITY,      TYPE_PRESSURE,  TYPE_HEART_RATE};
-
-nBus_param_t *nbus_interface_allParams()
-{
-    return allParams;
-}
-
-uint8_t nbus_interface_allParamsCount()
-{
-    return sizeof(allParams) / sizeof(nBus_param_t);
-}
-
-nBus_sensorType_t *nbus_interface_allTypes()
-{
-    return allTypes;
-}
-
-uint8_t nbus_interface_allTypesCount()
-{
-    return sizeof(nBus_param_t) / sizeof(nBus_sensorType_t);
-}

+ 200 - 31
src/app_dummy.c

@@ -2,9 +2,54 @@
 #include <stdint.h>
 
 nBusAppInterface_t dummy_driver = {
-    dummy_init,     dummy_reset,    dummy_getType, dummy_getSensorCount, dummy_getData, dummy_setData, dummy_hasParam,
-    dummy_getParam, dummy_setParam, dummy_start,   dummy_stop,           dummy_read,    dummy_store,   dummy_calibrate,
-};
+    dummy_init,     dummy_reset,     dummy_getType,         dummy_getSensorCount, dummy_getData,     dummy_setData,
+    dummy_hasParam, dummy_getParam,  dummy_setParam,        dummy_start,          dummy_stop,        dummy_read,
+    dummy_store,    dummy_calibrate, dummy_getSensorFormat, dummy_find,           dummy_device_ready};
+
+////////////////////////////////////////////// Dummy test data structure //////////////////////////////////////////////
+
+uint16_t dummy_data_acc[3] = {0x31F5, 0xCCBD, 0xAABB};              // dec: 12789, -13123, -21829
+uint32_t dummy_data_gyro[3] = {0x1234ABCD, 0xFEDCBA98, 0x89ABCD13}; // dec: 305441741, -19088744, -1985229549
+uint8_t dummy_data_mag[2] = {0xAB, 0x12};                           // dec: 171, 18
+uint64_t dummy_data_hrate[2] = {0x1234ABCD7890ABCD,
+                                0xABCD123498765432}; // dec: 1311862290451049421, -6067173105892699086
+uint16_t dummy_data_pressure[1] = {0x7FAB};          // dec: 32683
+uint8_t dummy_data_led = 0;
+uint16_t dummy_data_motor[2] = {0x0000, 0x0000};
+
+#define DUMMY_SUB_COUNT 7
+#define DUMMY_SENSOR_COUNT 5
+#define DUMMY_ACTUATOR_COUNT 2
+
+// dummy sensors
+uint8_t *dummy_data_sensors[DUMMY_SENSOR_COUNT] = {(uint8_t *)dummy_data_acc, (uint8_t *)dummy_data_gyro,
+                                                   (uint8_t *)dummy_data_mag, (uint8_t *)dummy_data_hrate,
+                                                   (uint8_t *)dummy_data_pressure};
+
+uint8_t dummy_data_sensor_lens[DUMMY_SENSOR_COUNT] = {sizeof(dummy_data_acc), sizeof(dummy_data_gyro),
+                                                      sizeof(dummy_data_mag), sizeof(dummy_data_hrate),
+                                                      sizeof(dummy_data_pressure)};
+
+// dummy actuators
+uint8_t *dummy_data_actuators[DUMMY_ACTUATOR_COUNT] = {(uint8_t *)&dummy_data_led, (uint8_t *)dummy_data_motor};
+
+uint8_t dummy_data_actuator_lens[DUMMY_ACTUATOR_COUNT] = {sizeof(dummy_data_led), sizeof(dummy_data_motor)};
+
+uint32_t dummy_params[_NBUS_PARAM_COUNT];
+
+////////////////////////////////////////////// Dummy test data structure //////////////////////////////////////////////
+
+uint8_t _dummy_memcpy(uint8_t sensor_index, uint8_t *dst, uint8_t *src, uint8_t count)
+{
+    uint8_t i = 0;
+
+    dst[i] = sensor_index;
+
+    for (; i < count; i++)
+        dst[i + 1] = src[i];
+
+    return i + 1;
+}
 
 nBusAppInterface_t *getDummyDriver()
 {
@@ -13,18 +58,19 @@ nBusAppInterface_t *getDummyDriver()
 
 void dummy_init(void *hw_interface, void *hw_config)
 {
+    // init whole module
+
+    for (uint8_t i = 0; i < _NBUS_PARAM_COUNT; i++)
+        dummy_params[i] = 0xABCD1234;
 }
 
 void dummy_reset()
 {
+    // reset all devices
 }
 
 nBus_sensorType_t dummy_getType(uint8_t sensor_index)
 {
-
-    if (sensor_index > dummy_getSensorCount())
-        return TYPE_UNKNOWN;
-
     switch (sensor_index)
     {
     case 1:
@@ -34,61 +80,139 @@ nBus_sensorType_t dummy_getType(uint8_t sensor_index)
     case 3:
         return TYPE_MAGNETOMETER;
     case 4:
-        return TYPE_HEART_RATE;
+        return TYPE_HEART_RATE_MONITOR;
     case 5:
-        return TYPE_PRESSURE;
+        return TYPE_PRESSURE_GAUGE;
+    case 129:
+        return TYPE_LED_CONTROLLER;
+    case 130:
+        return TYPE_MOTOR_CONTROLLER;
     }
     return TYPE_UNKNOWN;
 }
 
-uint8_t dummy_getSensorCount()
+nBus_sensorCount_t dummy_getSensorCount()
 {
-    return 4;
+    return (nBus_sensorCount_t){DUMMY_SENSOR_COUNT, DUMMY_ACTUATOR_COUNT};
 }
 
-uint32_t dummy_data[4] = {0x12345678, 0x9ABCDEF0, 0x87654321, 0x0FEDCBA9};
-
 uint8_t dummy_getData(uint8_t sensor_index, uint8_t *data)
 {
-    for (uint8_t i = 0; i < 4; ++i)
+    uint8_t buff_index = 0;
+
+    switch (sensor_index)
     {
-        data[i] = ((uint8_t *)&dummy_data)[i + (sensor_index - 1) * 8];
-        data[4 + i] = ((uint8_t *)&dummy_data)[4 + i + (sensor_index - 1) * 8];
+    case 1:
+    case 2:
+    case 3:
+    case 4:
+    case 5:
+        return _dummy_memcpy(sensor_index, data, dummy_data_sensors[sensor_index - 1],
+                             dummy_data_sensor_lens[sensor_index - 1]);
+
+    case 129:
+    case 130:
+        return _dummy_memcpy(sensor_index, data, dummy_data_actuators[sensor_index - 129],
+                             dummy_data_actuator_lens[sensor_index - 129]);
+
+    case 0: {
+        uint8_t buff_index = 0;
+
+        for (uint8_t i = 0; i < DUMMY_SENSOR_COUNT; i++)
+            buff_index += _dummy_memcpy(i + 1, data + buff_index, dummy_data_sensors[i], dummy_data_sensor_lens[i]);
+
+        for (uint8_t i = 0; i < DUMMY_ACTUATOR_COUNT; i++)
+            buff_index +=
+                _dummy_memcpy(i + 129, data + buff_index, dummy_data_actuators[i], dummy_data_actuator_lens[i]);
+
+        return buff_index;
     }
+    break;
 
-    return 8;
+    default:
+        return 0;
+    }
 }
 
-uint8_t dummy_setData(uint8_t *data)
+nBus_statusType_t dummy_setData(uint8_t *data, uint8_t count, uint8_t *response)
 {
-    return 1;
+    uint8_t actuaror_id;
+    nBus_sensorFormat_t actuator_format;
+    uint8_t actuator_byte_count;
+    uint8_t response_idx = 0;
+    uint8_t data_idx = 0;
+
+    while (data_idx < count)
+    {
+        actuaror_id = data[data_idx++]; // fetch actuator id
+
+        switch (actuaror_id)
+        {
+        case 129:
+        case 130: {
+            actuator_format = dummy_getSensorFormat(actuaror_id);
+            actuator_byte_count = actuator_format.samples * actuator_format.byte_length;
+
+            // check for overflow
+            // if (data_idx + actuator_byte_count > count)
+            {
+                // response[response_idx++] = actuaror_id;
+                // response[response_idx++] = STATUS_FAIL;
+                // data_idx = count;
+                // break;
+            }
+
+            for (uint8_t i = 0; i < actuator_byte_count; i++)
+            {
+
+                dummy_data_actuators[actuaror_id - 129][i] = data[data_idx++];
+            }
+
+            response[response_idx++] = actuaror_id;
+            response[response_idx++] = STATUS_SUCCESS;
+        }
+        break;
+
+        default:
+            response[response_idx++] = actuaror_id;
+            response[response_idx++] = STATUS_NOT_SUPPORTED;
+        }
+    }
+
+    return response_idx;
 }
 
 int32_t dummy_getParam(uint8_t sensor_index, nBus_param_t param)
 {
-    return 0xABCD4567;
+    return dummy_params[param];
 }
 
 uint8_t dummy_hasParam(uint8_t sensor_index, nBus_param_t param)
 {
-    if (sensor_index < dummy_getSensorCount())
-        return 1;
-    return 0;
+    if (param == PARAM_GAIN)
+        return 0;
+
+    return 1;
 }
 
-nBus_param_t dummy_setParam(uint8_t sensor_index, nBus_param_t param, int32_t value)
+nBus_statusType_t dummy_setParam(uint8_t sensor_index, nBus_param_t param, int32_t value)
 {
-    return param;
+    if (param == PARAM_GAIN)
+        return STATUS_NOT_SUPPORTED;
+
+    dummy_params[param] = value;
+
+    return STATUS_SUCCESS;
 }
 
-void dummy_start(void)
+nBus_statusType_t dummy_start(void)
 {
-    return;
+    return STATUS_SUCCESS;
 }
 
-void dummy_stop(void)
+nBus_statusType_t dummy_stop(void)
 {
-    return;
+    return STATUS_SUCCESS;
 }
 
 void dummy_read(void)
@@ -101,7 +225,52 @@ uint8_t dummy_store(void)
     return 0;
 }
 
-uint8_t dummy_calibrate(uint8_t subslaveIndex, uint8_t calibrationParamsNum, uint8_t *calibrationParams)
+nBus_statusType_t dummy_calibrate(uint8_t sensor_index)
 {
-    return 0;
+    return STATUS_NOT_SUPPORTED;
+}
+
+nBus_sensorFormat_t dummy_getSensorFormat(uint8_t sensor_index)
+{
+    switch (sensor_index)
+    {
+    case 1:
+        return (nBus_sensorFormat_t){
+            .sign = 1, .unit_multiplier = -3, .value_multiplier = 2, .byte_length = 2, .samples = 3};
+        break;
+    case 2:
+        return (nBus_sensorFormat_t){
+            .sign = 1, .unit_multiplier = -4, .value_multiplier = 1, .byte_length = 4, .samples = 3};
+        break;
+    case 3:
+        return (nBus_sensorFormat_t){
+            .sign = 0, .unit_multiplier = 3, .value_multiplier = 2, .byte_length = 1, .samples = 2};
+        break;
+    case 4:
+        return (nBus_sensorFormat_t){
+            .sign = 1, .unit_multiplier = 4, .value_multiplier = -7, .byte_length = 8, .samples = 2};
+        break;
+    case 5:
+        return (nBus_sensorFormat_t){
+            .sign = 1, .unit_multiplier = 4, .value_multiplier = -3, .byte_length = 2, .samples = 1};
+        break;
+    case 129:
+        return (nBus_sensorFormat_t){
+            .sign = 0, .unit_multiplier = 0, .value_multiplier = 0, .byte_length = 1, .samples = 1};
+        break;
+    case 130:
+        return (nBus_sensorFormat_t){
+            .sign = 1, .unit_multiplier = 1, .value_multiplier = -3, .byte_length = 2, .samples = 2};
+        break;
+    }
+}
+
+nBus_statusType_t dummy_find(uint8_t enable)
+{
+    return STATUS_NOT_SUPPORTED;
+}
+
+uint8_t dummy_device_ready()
+{
+    return 1;
 }

+ 7 - 8
src/nbus_app.c

@@ -248,19 +248,18 @@ void nbus_init_memory_driver(nBus_MemoryDriver *memDriver)
 
     nBus.memoryInterface->readHeaderData();
 
-    uint8_t *params = nbus_interface_allParams();
-    uint8_t paramCnt = nbus_interface_allParamsCount();
     uint32_t paramValue;
-    for (uint32_t index = 1; index <= nBus.interface->getSensorCount(); index++)
+    for (uint32_t index = 1; index <= nBus.interface->getSensorCount().read_only_count;
+         index++) // warning only for read only sensors!!!
     {
-        for (int paramIndex = 0; paramIndex < paramCnt; paramIndex++)
+        for (int paramIndex = 0; paramIndex < _NBUS_PARAM_COUNT; paramIndex++)
         {
-            if (nbus_is_param_active(index, params[paramIndex]))
+            if (nbus_is_param_active(index, paramIndex))
             {
-                if (nBus.interface->hasParam(index, params[paramIndex]))
+                if (nBus.interface->hasParam(index, paramIndex))
                 {
-                    paramValue = nbus_memory_read_param(index, params[paramIndex]);
-                    nBus.interface->setParam(index, params[paramIndex], paramValue);
+                    paramValue = nbus_memory_read_param(index, paramIndex);
+                    nBus.interface->setParam(index, paramIndex, paramValue);
                 }
             }
         }

+ 184 - 82
src/nbus_slave_module_unicast.c

@@ -1,51 +1,80 @@
 #include "nbus_slave.h"
-
 #if MODULE_SLAVE == 1
 
 void nbus_slave_unicastToModuleGet(nBus_TypeDef *nbus)
 {
     switch (nbus->function_code.function)
     {
-
     case CMD_ECHO: {
-        for (uint8_t i = 3; i < nbus->rx_length - 1; i++)
+        for (uint8_t i = RX_DT; i < nbus->rx_length - 1; i++)
         {
             nbus->tx_buffer[i + 1] = nbus->rx_buffer[i];
         }
-        nbus->tx_length += (nbus->rx_length - 4);
+        nbus->tx_length += (nbus->rx_length - RX_META);
     }
-
     break;
 
     case CMD_PARAM: {
-        // same as nbus_unicastToSensorSet
-        int32_t param_value = nbus->interface->getParam(0, (nBus_param_t)nbus->rx_buffer[3]);
-        if (param_value == PARAM_VALUE_NONE)
+
+        switch (nbus->rx_length)
         {
-            setErrorResponse(nbus, PARAM_NOT_IMPLEMENTED);
-            break;
+        case RX_META: // get all params
+        {
+            for (uint8_t i = 0, j = 0; i < _NBUS_PARAM_COUNT; i++)
+            {
+                if (nbus->interface->hasParam(0, i))
+                {
+                    int32_t param_value = nbus->interface->getParam(0, i);
+                    nbus->tx_buffer[4 + 5 * j] = i;                             // param id
+                    nbus->tx_buffer[5 + 5 * j] = (uint8_t)(param_value & 0xFF); // param value 4B
+                    nbus->tx_buffer[6 + 5 * j] = (uint8_t)((param_value >> 8) & 0xFF);
+                    nbus->tx_buffer[7 + 5 * j] = (uint8_t)((param_value >> 16) & 0xFF);
+                    nbus->tx_buffer[8 + 5 * j] = (uint8_t)((param_value >> 24) & 0xFF);
+                    nbus->tx_length += 5;
+                    j++;
+                }
+            }
         }
+        break;
 
-        nbus->tx_buffer[4] = (uint8_t)(param_value & 0xFF);
-        nbus->tx_buffer[5] = (uint8_t)((param_value >> 8) & 0xFF);
-        nbus->tx_buffer[6] = (uint8_t)((param_value >> 16) & 0xFF);
-        nbus->tx_buffer[7] = (uint8_t)((param_value >> 24) & 0xFF);
+        case RX_META + 1: // get specified parameter: 4 meta + 1 param id
+        {
+            if (nbus->interface->hasParam(0, (nBus_param_t)nbus->rx_buffer[RX_DT]) == 0) // handle non-existing param
+            {
+                setErrorResponse(nbus, PARAM_NOT_IMPLEMENTED);
+                break;
+            }
 
-        nbus->tx_length += 4;
+            nbus->tx_buffer[4] = nbus->rx_buffer[RX_DT];                                              // param id
+            int32_t param_value = nbus->interface->getParam(0, (nBus_param_t)nbus->rx_buffer[RX_DT]); // param value 4B
+            nbus->tx_buffer[5] = (uint8_t)(param_value & 0xFF);
+            nbus->tx_buffer[6] = (uint8_t)((param_value >> 8) & 0xFF);
+            nbus->tx_buffer[7] = (uint8_t)((param_value >> 16) & 0xFF);
+            nbus->tx_buffer[8] = (uint8_t)((param_value >> 24) & 0xFF);
+            nbus->tx_length += 5;
+        }
+        break;
+
+        default:
+            setErrorResponse(nbus, ILLEGAL_FUNCTION_PARAM);
+            break;
+        }
     }
     break;
 
     case CMD_SENSOR_CNT: {
-        nbus->tx_buffer[4] = nbus->interface->getSensorCount();
-        nbus->tx_length += 1;
+        nBus_sensorCount_t sensor_count = nbus->interface->getSensorCount();
+        nbus->tx_buffer[4] = sensor_count.read_only_count;
+        nbus->tx_buffer[5] = sensor_count.read_write_count;
+        nbus->tx_length += 2;
     }
     break;
 
     case CMD_DATA: {
-        if (nbus->measure_active == MEASURE_RUNNING)
+        if (nbus->interface->device_ready())
         {
             // response: sensor1_index:sensor1_data | sensor2_index:sensor2_data | ...
-            uint8_t cnt = nbus->interface->getData(0, &nbus->tx_buffer[4]);
+            uint8_t cnt = nbus->interface->getData(0, &nbus->tx_buffer[TX_DT]);
             if (cnt == 0)
             {
                 setErrorResponse(nbus, DEVICE_BUSY);
@@ -60,65 +89,110 @@ void nbus_slave_unicastToModuleGet(nBus_TypeDef *nbus)
     break;
 
     case CMD_SENSOR_TYPE: {
+
+        nBus_sensorCount_t sensor_count = nbus->interface->getSensorCount();
+
         // response: sensor1_index:sensor1_type | sensor2_index:sensor2_type | ...
-        for (uint8_t i = 0; i < nbus->interface->getSensorCount(); i++)
+
+        // add read_only sensors
+        uint8_t i = 0;
+        for (; i < sensor_count.read_only_count; i++)
         {
-            nbus->tx_buffer[4 + 2 * i] = i;
-            nbus->tx_buffer[5 + 2 * i] = nbus->interface->getType(i);
+            nbus->tx_buffer[4 + 2 * i] = i + SENSOR_RO_ADDR;
+            nbus->tx_buffer[5 + 2 * i] = nbus->interface->getType(i + SENSOR_RO_ADDR);
+            nbus->tx_length += 2;
+        }
+
+        // add read_write sensors
+        for (uint8_t j = 0; j < sensor_count.read_write_count; j++, i++)
+        {
+            nbus->tx_buffer[4 + 2 * i] = j + SENSOR_RW_ADDR;
+            nbus->tx_buffer[5 + 2 * i] = nbus->interface->getType(j + SENSOR_RW_ADDR);
             nbus->tx_length += 2;
         }
     }
     break;
 
     case CMD_INFO: {
-        switch (nbus->rx_buffer[3])
-        {
-        case INFO_MODULE_NAME:
-            nbus->tx_buffer[4] = MODULE_NAME[0];
-            nbus->tx_buffer[5] = MODULE_NAME[1];
-            nbus->tx_buffer[6] = MODULE_NAME[2];
-            nbus->tx_buffer[7] = MODULE_NAME[3];
-            nbus->tx_buffer[8] = MODULE_NAME[4];
-            nbus->tx_buffer[9] = MODULE_NAME[5];
-            nbus->tx_buffer[10] = MODULE_NAME[6];
-            nbus->tx_buffer[11] = MODULE_NAME[7];
-            nbus->tx_length += 8;
-            break;
-        case INFO_MODULE_TYPE:
-            nbus->tx_buffer[4] = MODULE_TYPE[0];
-            nbus->tx_buffer[5] = MODULE_TYPE[1];
-            nbus->tx_buffer[6] = MODULE_TYPE[2];
-            nbus->tx_length += 3;
-            break;
-        case INFO_MODULE_UUID: {
-// Reference manual: Unique device ID registers
+        // name
+        nbus->tx_buffer[4] = MODULE_NAME[0];
+        nbus->tx_buffer[5] = MODULE_NAME[1];
+        nbus->tx_buffer[6] = MODULE_NAME[2];
+        nbus->tx_buffer[7] = MODULE_NAME[3];
+        nbus->tx_buffer[8] = MODULE_NAME[4];
+        nbus->tx_buffer[9] = MODULE_NAME[5];
+        nbus->tx_buffer[10] = MODULE_NAME[6];
+        nbus->tx_buffer[11] = MODULE_NAME[7];
+        nbus->tx_length += 8;
+        // type
+        nbus->tx_buffer[12] = MODULE_TYPE[0];
+        nbus->tx_buffer[13] = MODULE_TYPE[1];
+        nbus->tx_buffer[14] = MODULE_TYPE[2];
+        nbus->tx_length += 3;
+
+        // uuid - reference manual: Unique device ID registers
 #if defined(STM32)
-            uint32_t(*unique_id_3) = (uint32_t *)(0x1FF80064); // BASE address + 0x14 0ffset
+        uint32_t(*unique_id_3) = (uint32_t *)(0x1FF80064); // BASE address + 0x14 0ffset
 #elif defined(ESP32) || defined(NRF)
-            uint32_t unique_id_3[3] = {1, 2, 3};
+        uint32_t unique_id_3 = 0x12345678;
 #endif
+        nbus->tx_buffer[15] = ((uint8_t *)(&unique_id_3))[0];
+        nbus->tx_buffer[16] = ((uint8_t *)(&unique_id_3))[1];
+        nbus->tx_buffer[17] = ((uint8_t *)(&unique_id_3))[2];
+        nbus->tx_buffer[18] = ((uint8_t *)(&unique_id_3))[3];
+        nbus->tx_length += 4;
+        // fw version
+        nbus->tx_buffer[19] = VERSION_FW[0];
+        nbus->tx_buffer[20] = '.';
+        nbus->tx_buffer[21] = VERSION_FW[1];
+        nbus->tx_length += 3;
+        // hw version
+        nbus->tx_buffer[22] = VERSION_HW[0];
+        nbus->tx_buffer[23] = '.';
+        nbus->tx_buffer[24] = VERSION_HW[1];
+        nbus->tx_length += 3;
+        // module memory
+        nbus->memoryInterface->getId(&nbus->tx_buffer[25]);
+        nbus->tx_length += 8;
+        // sensor count
+        nBus_sensorCount_t sensor_count = nbus->interface->getSensorCount();
+        nbus->tx_buffer[33] = sensor_count.read_only_count;
+        nbus->tx_buffer[34] = sensor_count.read_write_count;
+        nbus->tx_length += 2;
+    }
+    break;
 
-            *(nbus->tx_buffer) = (uint32_t)unique_id_3;
-            nbus->tx_length += 4;
-        }
-        break;
-        case INFO_MODULE_FW:
-            nbus->tx_buffer[4] = VERSION_FW[0];
-            nbus->tx_buffer[5] = '.';
-            nbus->tx_buffer[6] = VERSION_FW[1];
-            nbus->tx_length += 3;
-            break;
-        case INFO_MODULE_HW:
-            nbus->tx_buffer[4] = VERSION_HW[0];
-            nbus->tx_buffer[5] = '.';
-            nbus->tx_buffer[6] = VERSION_HW[1];
-            nbus->tx_length += 3;
-            break;
-        case INFO_MODULE_MEMORY_ID: {
-            uint8_t n = nbus->memoryInterface->getId(&nbus->tx_buffer[4]);
-            nbus->tx_length += n;
+    case CMD_FORMAT: {
+        nBus_sensorCount_t sensor_count = nbus->interface->getSensorCount();
+        nBus_sensorFormat_t format;
+        uint8_t *format_ptr;
+
+        // add read_only sensors
+        uint8_t i = 0;
+        for (; i < sensor_count.read_only_count; ++i)
+        {
+            format = nbus->interface->getSensorFormat(i + SENSOR_RO_ADDR);
+            format_ptr = (uint8_t *)&format;
+            nbus->tx_buffer[4 * i + 4] = i + SENSOR_RO_ADDR;
+            nbus->tx_buffer[4 * i + 5] = format_ptr[0];
+            nbus->tx_buffer[4 * i + 6] = format_ptr[1];
+            nbus->tx_buffer[4 * i + 7] = format_ptr[2];
         }
+
+        nbus->tx_length += 4 * sensor_count.read_only_count;
+
+        // add read_write sensors
+        for (uint8_t j = 0; j < sensor_count.read_write_count; ++j, ++i)
+        {
+            format = nbus->interface->getSensorFormat(j + SENSOR_RW_ADDR);
+            format_ptr = (uint8_t *)&format;
+            nbus->tx_buffer[4 * i + 4] = j + SENSOR_RW_ADDR;
+            nbus->tx_buffer[4 * i + 5] = format_ptr[0];
+            nbus->tx_buffer[4 * i + 6] = format_ptr[1];
+            nbus->tx_buffer[4 * i + 7] = format_ptr[2];
         }
+
+        nbus->tx_length += 4 * sensor_count.read_write_count;
     }
     break;
 
@@ -132,29 +206,50 @@ void nbus_slave_unicastToModuleSet(nBus_TypeDef *nbus)
 {
     switch (nbus->function_code.function)
     {
-    case CMD_PARAM: {
-        // same as nbus_unicastToSensorSet
-        int32_t param_value =
-            nbus->rx_buffer[4] | nbus->rx_buffer[5] << 8 | nbus->rx_buffer[6] << 16 << nbus->rx_buffer[7] << 23;
-        nBus_param_t p = nbus->interface->setParam(0, (nBus_param_t)nbus->rx_buffer[3], param_value);
-        if (p == PARAM_NONE)
-        {
-            setErrorResponse(nbus, PARAM_NOT_IMPLEMENTED);
-            break;
-        }
-        nbus->tx_buffer[4] = OK_CODE;
-        nbus->tx_length += 1;
+    case CMD_STOP: {
+        nbus->measure_active = MEASURE_STOPPED;
+        nbus->tx_buffer[TX_DT] = nbus->interface->stop();
+        nbus->tx_length++;
+        nbus->hw_platform->led_off();
     }
     break;
 
-    case CMD_DATA: {
-        nbus->tx_buffer[4] = nbus->interface->setData(&nbus->rx_buffer[3]);
-        if (nbus->tx_buffer[4] != OK_CODE)
+    case CMD_START: {
+        nbus->measure_active = MEASURE_RUNNING;
+        nbus->tx_buffer[TX_DT] = nbus->interface->start();
+        nbus->tx_length++;
+        nbus->hw_platform->led_on();
+    }
+    break;
+
+    case CMD_PARAM: {
+
+        uint8_t rx_payload = nbus->rx_length - RX_META;
+
+        // empty or wrong number of parameters
+        if (rx_payload == 0 || rx_payload % 5 != 0)
         {
-            nbus->function_code.error = 1;
+            setErrorResponse(nbus, ILLEGAL_FUNCTION_PARAM);
+            break;
         }
+        else
+        {
+            uint8_t param_id;
+            uint32_t param_value;
 
-        nbus->tx_length += 1;
+            uint8_t i = 0;
+
+            for (; rx_payload > 0; rx_payload -= 5)
+            {
+                param_id = nbus->rx_buffer[3 + 5 * i];
+                param_value = *(int32_t *)&nbus->rx_buffer[4 + 5 * i];
+
+                nbus->tx_buffer[4 + 2 * i] = param_id;
+                nbus->tx_buffer[5 + 2 * i] = nbus->interface->setParam(0, param_id, param_value);
+                nbus->tx_length += 2;
+                i++;
+            }
+        }
     }
     break;
 
@@ -172,12 +267,19 @@ void nbus_slave_unicastToModuleSet(nBus_TypeDef *nbus)
 
     case CMD_CALIBRATE: {
         nbus->hw_platform->led_on();
-        nbus->tx_buffer[4] = nbus->interface->calibrate(0, 0, NULL);
+        nbus->tx_buffer[TX_DT] = nbus->interface->calibrate(0);
         nbus->tx_length += 1;
         nbus->hw_platform->led_off();
     }
     break;
 
+    case CMD_DATA: {
+
+        nbus->tx_length +=
+            nbus->interface->setData(&nbus->rx_buffer[RX_DT], nbus->rx_length - RX_META, &nbus->tx_buffer[TX_DT]);
+    }
+    break;
+
     case CMD_RESET: {
         // POZOR!  cas fomatovania: 0.3s (pri 1W pamati)
         memory_params_format();

+ 113 - 64
src/nbus_slave_sensor_unicast.c

@@ -4,67 +4,75 @@
 
 void nbus_slave_unicastToSensorGet(nBus_TypeDef *nbus)
 {
+    nBus_sensorType_t sensor_type = nbus->interface->getType(nbus->rx_buffer[RX_SA]);
+
+    if (sensor_type == TYPE_UNKNOWN) // handle bad sensor address
+    {
+        setErrorResponse(nbus, ILLEGAL_DEVICE_ADDRESS);
+        return;
+    }
+
     switch (nbus->function_code.function)
     {
-    case CMD_SENSOR_TYPE: {
-        nBus_sensorType_t t = nbus->interface->getType(nbus->sensorInfo.address);
-        if (t == TYPE_UNKNOWN)
+    case CMD_PARAM: {
+
+        switch (nbus->rx_length)
         {
-            setErrorResponse(nbus, ILLEGAL_DEVICE_ADDRESS);
-            break;
+        case RX_META: // get all params
+        {
+            for (uint8_t i = 0, j = 0; i < _NBUS_PARAM_COUNT; i++)
+            {
+                if (nbus->interface->hasParam(nbus->rx_buffer[RX_SA], i))
+                {
+                    int32_t param_value = nbus->interface->getParam(nbus->rx_buffer[RX_SA], i);
+                    nbus->tx_buffer[4 + 5 * j] = i;                             // param id
+                    nbus->tx_buffer[5 + 5 * j] = (uint8_t)(param_value & 0xFF); // param value 4B
+                    nbus->tx_buffer[6 + 5 * j] = (uint8_t)((param_value >> 8) & 0xFF);
+                    nbus->tx_buffer[7 + 5 * j] = (uint8_t)((param_value >> 16) & 0xFF);
+                    nbus->tx_buffer[8 + 5 * j] = (uint8_t)((param_value >> 24) & 0xFF);
+
+                    nbus->tx_length += 5;
+                    j++;
+                }
+            }
         }
-        nbus->tx_buffer[4] = t;
-        nbus->tx_length += 1;
-    }
-    break;
+        break;
 
-    case CMD_PARAM: {
-        if (nbus->rx_length >= 5)
+        case RX_META + 1: // get specified parameter: 4 meta + 1 param id
         {
-            if (nbus->interface->hasParam(nbus->sensorInfo.address, (nBus_param_t)nbus->rx_buffer[3]) == 0)
+            if (nbus->interface->hasParam(nbus->rx_buffer[RX_SA], (nBus_param_t)nbus->rx_buffer[RX_DT]) ==
+                0) // handle non-existing param
             {
                 setErrorResponse(nbus, PARAM_NOT_IMPLEMENTED);
                 break;
             }
-            nbus->tx_buffer[4] = nbus->rx_buffer[3];
-            int32_t param_value = nbus->interface->getParam(nbus->sensorInfo.address, (nBus_param_t)nbus->rx_buffer[3]);
+
+            nbus->tx_buffer[4] = nbus->rx_buffer[RX_DT]; // param id
+            int32_t param_value = nbus->interface->getParam(nbus->rx_buffer[RX_SA],
+                                                            (nBus_param_t)nbus->rx_buffer[RX_DT]); // param value 4B
             nbus->tx_buffer[5] = (uint8_t)(param_value & 0xFF);
             nbus->tx_buffer[6] = (uint8_t)((param_value >> 8) & 0xFF);
             nbus->tx_buffer[7] = (uint8_t)((param_value >> 16) & 0xFF);
             nbus->tx_buffer[8] = (uint8_t)((param_value >> 24) & 0xFF);
             nbus->tx_length += 5;
         }
-        else
-        {
-            nBus_param_t *params = nbus_interface_allParams();
-            for (uint8_t i = 0; i < nbus_interface_allParamsCount(); i++)
-            {
-                if (nbus->interface->hasParam(nbus->sensorInfo.address, params[i]))
-                {
-                    int32_t param_value = nbus->interface->getParam(nbus->sensorInfo.address, params[i]);
-                    nbus->tx_buffer[4 + 5 * i] = params[i];
-                    // nbus->tx_buffer[5+2*i] =
-                    // nbus->interface->getParam(nbus->sensorInfo.address, params[i]);
-                    nbus->tx_buffer[5 + 5 * i] = (uint8_t)(param_value & 0xFF);
-                    nbus->tx_buffer[6 + 5 * i] = (uint8_t)((param_value >> 8) & 0xFF);
-                    nbus->tx_buffer[7 + 5 * i] = (uint8_t)((param_value >> 16) & 0xFF);
-                    nbus->tx_buffer[8 + 5 * i] = (uint8_t)((param_value >> 24) & 0xFF);
+        break;
 
-                    nbus->tx_length += 5;
-                }
-            }
+        default:
+            setErrorResponse(nbus, ILLEGAL_FUNCTION_PARAM);
+            break;
         }
     }
     break;
 
     case CMD_DATA: {
-        if (nbus->measure_active == MEASURE_RUNNING)
+        if (nbus->interface->device_ready())
         {
-            uint8_t cnt = nbus->interface->getData(nbus->sensorInfo.address, &nbus->tx_buffer[4]);
+            uint8_t cnt = nbus->interface->getData(nbus->rx_buffer[RX_SA], &nbus->tx_buffer[TX_DT]);
             if (cnt == 0)
             {
                 setErrorResponse(nbus, DEVICE_BUSY);
-                // return;
+                break;
             }
             nbus->tx_length += cnt;
         }
@@ -75,6 +83,23 @@ void nbus_slave_unicastToSensorGet(nBus_TypeDef *nbus)
     }
     break;
 
+    case CMD_SENSOR_TYPE: {
+        nbus->tx_buffer[TX_DT] = sensor_type;
+        nbus->tx_length += 1;
+        break;
+    }
+
+    case CMD_FORMAT: {
+        nBus_sensorFormat_t format = nbus->interface->getSensorFormat(nbus->rx_buffer[RX_SA]);
+        uint8_t *format_ptr = (uint8_t *)&format;
+        nbus->tx_buffer[4] = nbus->rx_buffer[RX_SA]; // sensor address
+        nbus->tx_buffer[5] = format_ptr[0];
+        nbus->tx_buffer[6] = format_ptr[1];
+        nbus->tx_buffer[7] = format_ptr[2];
+        nbus->tx_length += 4;
+    }
+    break;
+
     default: {
         setErrorResponse(nbus, ILLEGAL_FUNCTION);
     }
@@ -83,62 +108,86 @@ void nbus_slave_unicastToSensorGet(nBus_TypeDef *nbus)
 
 void nbus_slave_unicastToSensorSet(nBus_TypeDef *nbus)
 {
-    int32_t param_value;
+    nBus_sensorType_t sensor_type =
+        nbus->interface->getType(nbus->rx_buffer[RX_SA]); // nbus->rx_buffer[1] is whole address with type
+
+    if (sensor_type == TYPE_UNKNOWN) // handle bad sensor address
+    {
+        setErrorResponse(nbus, ILLEGAL_DEVICE_ADDRESS);
+        return;
+    }
+
     switch (nbus->function_code.function)
     {
-    case CMD_PARAM: {
-        if (!nbus->interface->hasParam(nbus->sensorInfo.address, (nBus_param_t)nbus->rx_buffer[3]))
+    case CMD_FIND: {
+        if (nbus->rx_buffer[RX_DT] > 1) // if wrong parameter {0, 1}
         {
-            setErrorResponse(nbus, PARAM_NOT_IMPLEMENTED);
+            setErrorResponse(nbus, ILLEGAL_FUNCTION_PARAM);
             break;
         }
 
-        param_value =
-            nbus->rx_buffer[4] | nbus->rx_buffer[5] << 8 | nbus->rx_buffer[6] << 16 << nbus->rx_buffer[7] << 23;
-        nBus_param_t p =
-            nbus->interface->setParam(nbus->sensorInfo.address, (nBus_param_t)nbus->rx_buffer[3], param_value);
-        if (p == PARAM_NONE)
-        {
-            setErrorResponse(nbus, ILLEGAL_DATA_VALUE);
-            break;
-        }
-        nbus->tx_buffer[4] = OK_CODE;
+        nbus->tx_buffer[TX_DT] = nbus->interface->find(nbus->rx_buffer[RX_DT]);
         nbus->tx_length += 1;
     }
     break;
 
-    case CMD_CALIBRATE: {
-        nbus->hw_platform->led_on();
-        if (1 == nbus->interface->calibrate(nbus->sensorInfo.address, 0, NULL))
+    case CMD_PARAM: {
+
+        uint8_t rx_payload = nbus->rx_length - RX_META;
+
+        // empty or wrong number of parameters
+        if (rx_payload == 0 || rx_payload % 5 != 0)
         {
-            nbus->tx_buffer[4] = 1;
-            nbus->tx_length += 1;
+            setErrorResponse(nbus, ILLEGAL_FUNCTION_PARAM);
+            break;
         }
         else
         {
-            setErrorResponse(nbus, ILLEGAL_DEVICE_ADDRESS);
+            uint8_t param_id;
+            uint32_t param_value;
+
+            uint8_t i = 0;
+
+            for (; rx_payload > 0; rx_payload -= 5)
+            {
+                param_id = nbus->rx_buffer[3 + 5 * i];
+                param_value = *(int32_t *)&nbus->rx_buffer[4 + 5 * i];
+
+                nbus->tx_buffer[4 + 2 * i] = param_id;
+                nbus->tx_buffer[5 + 2 * i] = nbus->interface->setParam(nbus->rx_buffer[RX_SA], param_id, param_value);
+                nbus->tx_length += 2;
+                i++;
+            }
         }
+    }
+    break;
+
+    case CMD_CALIBRATE: {
+        nbus->hw_platform->led_on();
+        nbus->tx_buffer[TX_DT] = nbus->interface->calibrate(nbus->rx_buffer[RX_SA]);
+        nbus->tx_length += 1;
         nbus->hw_platform->led_off();
         break;
     }
 
     case CMD_DATA: {
-        nbus->tx_buffer[4] = nbus->interface->setData(&nbus->rx_buffer[3]);
-        if (nbus->tx_buffer[4] != OK_CODE)
+        if (nbus->sensorInfo.type == 0) // if device is output only (sensor)
         {
-            nbus->function_code.error = 1;
+            setErrorResponse(nbus, DEVICE_IS_READ_ONLY);
+            break;
         }
-        nbus->tx_length += 1;
+
+        nbus->tx_length +=
+            nbus->interface->setData(&nbus->rx_buffer[RX_DT], nbus->rx_length - RX_META, &nbus->tx_buffer[TX_DT]);
     }
     break;
 
     case CMD_STORE: {
-        nBus_param_t *all_params = nbus_interface_allParams();
-        for (uint32_t i = 0; i < nbus_interface_allParamsCount(); i++)
+        for (uint32_t i = 0; i < _NBUS_PARAM_COUNT; i++)
         {
-            if (nbus->interface->hasParam(nbus->sensorInfo.address, all_params[i]))
+            if (nbus->interface->hasParam(nbus->rx_buffer[RX_SA], i))
             {
-                sensor_store_param(nbus, nbus->sensorInfo.address, all_params[i]);
+                sensor_store_param(nbus, nbus->rx_buffer[RX_SA], i);
                 // param_value = nbus->interface->getParam(nbus->sensorInfo.address,
                 // all_params[i]);
                 // nbus->memoryInterface->storeParam(nbus->sensorInfo.address,
@@ -146,7 +195,7 @@ void nbus_slave_unicastToSensorSet(nBus_TypeDef *nbus)
             }
         }
 
-        nbus->tx_buffer[4] = 1;
+        nbus->tx_buffer[TX_DT] = 1;
         nbus->tx_length += 1;
     }
     break;