Fixed multiple devices causing overflow in compile. Fixed PICS Float data type not being decoded correctly (bit order reversed).
This commit is contained in:
@@ -3,6 +3,9 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "esp_log.h"
|
||||
#define TAG_MEM "MODBUS_MEM"
|
||||
|
||||
static modbus_point_type_t mem_to_point_type(modbus_mem_type_t type)
|
||||
{
|
||||
switch (type)
|
||||
@@ -233,8 +236,8 @@ static bool apply_pics_to_official_point(modbus_memory_t *mem, modbus_point_t *p
|
||||
{
|
||||
uint32_t v = (pics_i32 < 0) ? 0U : (uint32_t)pics_i32;
|
||||
|
||||
out_words[0] = (uint16_t)((v >> 16) & 0xFFFFU);
|
||||
out_words[1] = (uint16_t)(v & 0xFFFFU);
|
||||
out_words[0] = (uint16_t)(v & 0xFFFFU);
|
||||
out_words[1] = (uint16_t)((v >> 16) & 0xFFFFU);
|
||||
|
||||
if (!write_point_words(mem, pt, out_words, 2U))
|
||||
return false;
|
||||
@@ -248,8 +251,8 @@ static bool apply_pics_to_official_point(modbus_memory_t *mem, modbus_point_t *p
|
||||
|
||||
memcpy(&raw_f32, &f, sizeof(raw_f32));
|
||||
|
||||
out_words[0] = (uint16_t)((raw_f32 >> 16) & 0xFFFFU);
|
||||
out_words[1] = (uint16_t)(raw_f32 & 0xFFFFU);
|
||||
out_words[0] = (uint16_t)(raw_f32 & 0xFFFFU);
|
||||
out_words[1] = (uint16_t)((raw_f32 >> 16) & 0xFFFFU);
|
||||
|
||||
if (!write_point_words(mem, pt, out_words, 2U))
|
||||
return false;
|
||||
@@ -263,10 +266,10 @@ static bool apply_pics_to_official_point(modbus_memory_t *mem, modbus_point_t *p
|
||||
|
||||
memcpy(&raw_f64, &d, sizeof(raw_f64));
|
||||
|
||||
out_words[0] = (uint16_t)((raw_f64 >> 48) & 0xFFFFU);
|
||||
out_words[1] = (uint16_t)((raw_f64 >> 32) & 0xFFFFU);
|
||||
out_words[2] = (uint16_t)((raw_f64 >> 16) & 0xFFFFU);
|
||||
out_words[3] = (uint16_t)(raw_f64 & 0xFFFFU);
|
||||
out_words[0] = (uint16_t)(raw_f64 & 0xFFFFU);
|
||||
out_words[1] = (uint16_t)((raw_f64 >> 16) & 0xFFFFU);
|
||||
out_words[2] = (uint16_t)((raw_f64 >> 32) & 0xFFFFU);
|
||||
out_words[3] = (uint16_t)((raw_f64 >> 48) & 0xFFFFU);
|
||||
|
||||
if (!write_point_words(mem, pt, out_words, 4U))
|
||||
return false;
|
||||
@@ -286,10 +289,10 @@ static bool apply_pics_to_official_point(modbus_memory_t *mem, modbus_point_t *p
|
||||
uint64_t raw_f64;
|
||||
double pics_d;
|
||||
|
||||
raw_f64 = ((uint64_t)pt->pics_words[0] << 48) |
|
||||
((uint64_t)pt->pics_words[1] << 32) |
|
||||
((uint64_t)pt->pics_words[2] << 16) |
|
||||
(uint64_t)pt->pics_words[3];
|
||||
raw_f64 = ((uint64_t)pt->pics_words[3] << 48) |
|
||||
((uint64_t)pt->pics_words[2] << 32) |
|
||||
((uint64_t)pt->pics_words[1] << 16) |
|
||||
(uint64_t)pt->pics_words[0];
|
||||
|
||||
memcpy(&pics_d, &raw_f64, sizeof(pics_d));
|
||||
|
||||
@@ -321,8 +324,8 @@ static bool apply_pics_to_official_point(modbus_memory_t *mem, modbus_point_t *p
|
||||
|
||||
u32 = (uint32_t)v;
|
||||
|
||||
out_words[0] = (uint16_t)((u32 >> 16) & 0xFFFFU);
|
||||
out_words[1] = (uint16_t)(u32 & 0xFFFFU);
|
||||
out_words[0] = (uint16_t)(u32 & 0xFFFFU);
|
||||
out_words[1] = (uint16_t)((u32 >> 16) & 0xFFFFU);
|
||||
|
||||
if (!write_point_words(mem, pt, out_words, 2U))
|
||||
return false;
|
||||
@@ -336,8 +339,8 @@ static bool apply_pics_to_official_point(modbus_memory_t *mem, modbus_point_t *p
|
||||
|
||||
memcpy(&raw_f32, &f, sizeof(raw_f32));
|
||||
|
||||
out_words[0] = (uint16_t)((raw_f32 >> 16) & 0xFFFFU);
|
||||
out_words[1] = (uint16_t)(raw_f32 & 0xFFFFU);
|
||||
out_words[0] = (uint16_t)(raw_f32 & 0xFFFFU);
|
||||
out_words[1] = (uint16_t)((raw_f32 >> 16) & 0xFFFFU);
|
||||
|
||||
if (!write_point_words(mem, pt, out_words, 2U))
|
||||
return false;
|
||||
@@ -350,10 +353,10 @@ static bool apply_pics_to_official_point(modbus_memory_t *mem, modbus_point_t *p
|
||||
|
||||
memcpy(&raw_out_f64, &pics_d, sizeof(raw_out_f64));
|
||||
|
||||
out_words[0] = (uint16_t)((raw_out_f64 >> 48) & 0xFFFFU);
|
||||
out_words[1] = (uint16_t)((raw_out_f64 >> 32) & 0xFFFFU);
|
||||
out_words[2] = (uint16_t)((raw_out_f64 >> 16) & 0xFFFFU);
|
||||
out_words[3] = (uint16_t)(raw_out_f64 & 0xFFFFU);
|
||||
out_words[0] = (uint16_t)(raw_out_f64 & 0xFFFFU);
|
||||
out_words[1] = (uint16_t)((raw_out_f64 >> 16) & 0xFFFFU);
|
||||
out_words[2] = (uint16_t)((raw_out_f64 >> 32) & 0xFFFFU);
|
||||
out_words[3] = (uint16_t)((raw_out_f64 >> 48) & 0xFFFFU);
|
||||
|
||||
if (!write_point_words(mem, pt, out_words, 4U))
|
||||
return false;
|
||||
@@ -396,6 +399,7 @@ static bool write_pics_staging_word(modbus_memory_t *mem,
|
||||
return false;
|
||||
|
||||
pt->pics_words[word_index] = value;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -536,15 +540,44 @@ bool modbus_memory_read_holding_register(modbus_memory_t *mem, uint16_t offset,
|
||||
{
|
||||
const modbus_point_t *pt;
|
||||
|
||||
if (mem == NULL || value == NULL)
|
||||
if (mem == NULL || mem->db == NULL || value == NULL)
|
||||
return false;
|
||||
|
||||
/*
|
||||
* First try normal/official holding register.
|
||||
*/
|
||||
pt = find_point_ro(mem, MB_MEM_HOLDING_REGISTER, offset);
|
||||
if (pt == NULL)
|
||||
return false;
|
||||
if (pt != NULL)
|
||||
{
|
||||
*value = pt->reg_value;
|
||||
return true;
|
||||
}
|
||||
|
||||
*value = pt->reg_value;
|
||||
return true;
|
||||
/*
|
||||
* Then allow reading PICS staging registers directly.
|
||||
* This makes ModScan useful for verifying addresses like 410005-410008.
|
||||
*/
|
||||
pt = modbus_points_find_by_pics_range(mem->db,
|
||||
MB_POINT_HOLDING_REGISTER,
|
||||
offset);
|
||||
|
||||
if (pt != NULL && pt->has_pics_address)
|
||||
{
|
||||
uint16_t word_index;
|
||||
|
||||
if (offset < pt->pics_offset)
|
||||
return false;
|
||||
|
||||
word_index = (uint16_t)(offset - pt->pics_offset);
|
||||
|
||||
if (word_index >= pt->pics_reg_span || word_index >= 4U)
|
||||
return false;
|
||||
|
||||
*value = pt->pics_words[word_index];
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool modbus_memory_write_holding_register(modbus_memory_t *mem, uint16_t offset, uint16_t value)
|
||||
@@ -562,8 +595,14 @@ bool modbus_memory_write_holding_register(modbus_memory_t *mem, uint16_t offset,
|
||||
return true;
|
||||
}
|
||||
|
||||
if (write_pics_staging_word(mem, MB_MEM_HOLDING_REGISTER, offset, value))
|
||||
return true;
|
||||
pt = find_pics_point_rw(mem, MB_MEM_HOLDING_REGISTER, offset);
|
||||
if (pt != NULL)
|
||||
{
|
||||
if (!write_pics_staging_word(mem, MB_MEM_HOLDING_REGISTER, offset, value))
|
||||
return false;
|
||||
|
||||
return apply_pics_to_official_point(mem,pt);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user