fabhardware.fabmeter/main/modbus_utils.h
2023-07-24 02:02:48 +02:00

61 lines
2.2 KiB
C

#pragma once
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
// The macro to get offset for parameter in the appropriate structure
#define HOLD_OFFSET(field) ((uint16_t)(offsetof(holding_reg_params_t, field) + 1))
#define INPUT_OFFSET(field) ((uint16_t)(offsetof(input_reg_params_t, field) + 1))
#define COIL_OFFSET(field) ((uint16_t)(offsetof(coil_reg_params_t, field) + 1))
// Discrete offset macro
#define DISCR_OFFSET(field) ((uint16_t)(offsetof(discrete_reg_params_t, field) + 1))
#define STR(fieldname) ((const char*)( fieldname ))
// Options can be used as bit masks or parameter limits
#define OPTS(min_val, max_val, step_val) { .opt1 = min_val, .opt2 = max_val, .opt3 = step_val }
// BigEndian 32bit swap
// just swap the two 16 bit registers since the two bytes in each
// register are already swapped (BigEndian) as per modbus standard.
# define __beswap_32(x) \
(__extension__ \
({ uint32_t __bsx = (x); \
((((__bsx) >> 16) & 0xffff) | (((__bsx) & 0xffff) << 16)); }))
// The function to get pointer to parameter storage (instance) according to parameter description table
static void* master_get_param_data(const mb_parameter_descriptor_t* param_descriptor)
{
assert(param_descriptor != NULL);
void* instance_ptr = NULL;
if (param_descriptor->param_offset != 0) {
switch(param_descriptor->mb_param_type)
{
case MB_PARAM_HOLDING:
instance_ptr = ((void*)&holding_reg_params + param_descriptor->param_offset - 1);
break;
case MB_PARAM_INPUT:
instance_ptr = ((void*)&input_reg_params + param_descriptor->param_offset - 1);
break;
case MB_PARAM_COIL:
instance_ptr = ((void*)&coil_reg_params + param_descriptor->param_offset - 1);
break;
case MB_PARAM_DISCRETE:
instance_ptr = ((void*)&discrete_reg_params + param_descriptor->param_offset - 1);
break;
default:
instance_ptr = NULL;
break;
}
} else {
ESP_LOGE("MB_UTILS", "Wrong parameter offset for CID #%d", param_descriptor->cid);
assert(instance_ptr != NULL);
}
return instance_ptr;
}
#ifdef __cplusplus
}
#endif