WIP write multiple registers

This commit is contained in:
Duke NUCem
2021-10-11 17:05:54 +02:00
parent 12cd3df5a3
commit 0bfc93d3ea
4 changed files with 74 additions and 7 deletions

View File

@@ -107,6 +107,7 @@ typedef enum {
typedef enum {
MODBUS_EXCEPTION_ILLEGAL_FUNCTION = 1,
MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS = 2,
MODBUS_EXCEPTION_ILLEGAL_REGISTER_QUANTITY = 2,
MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE = 3,
MODBUS_EXCEPTION_SLAVE_DEVICE_FAILURE = 4,
MODBUS_EXCEPTION_ACKNOWLEDGE = 5,

View File

@@ -291,7 +291,11 @@ int main(void)
/* TODO: Process data and light a desired color of LED */
/* TODO: Add hystheresis */
if (sensor_config.led_on) {
/* Reset the TIM21 Elapsed Period Flag */
tim21_elapsed_period = 0;
}
/* TEST END */
if (sensor_config.led_on) {
if (CO2 <= sensor_config.led_co2_alert_limit1) {
/* CO2 is OK -> GREEN */
LL_GPIO_SetOutputPin(LED_R_GPIO_Port, LED_R_Pin);
@@ -315,11 +319,6 @@ int main(void)
LL_GPIO_SetOutputPin(LED_G_GPIO_Port, LED_G_Pin);
LL_GPIO_SetOutputPin(LED_B_GPIO_Port, LED_B_Pin);
}
/* Reset the TIM21 Elapsed Period Flag */
tim21_elapsed_period = 0;
}
/* TEST END */
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */

View File

@@ -58,6 +58,7 @@ int8_t modbus_copy_reply_to_buffer(uint8_t *buffer, uint8_t *msg_len, modbus_tra
uint16_t crc16;
uint8_t byte_count;
// TODO use relative indices (increments) instead of absolute
buffer[0] = modbus_slave_address;
buffer[1] = transaction->function_code;
*msg_len = 5;
@@ -86,6 +87,13 @@ int8_t modbus_copy_reply_to_buffer(uint8_t *buffer, uint8_t *msg_len, modbus_tra
buffer[5] = (uint8_t) transaction->holding_registers[0];
*msg_len = 8;
break;
case MODBUS_WRITE_MULTIPLE_REGISTERS:
buffer[2] = (uint8_t) (transaction->register_address >> 8);
buffer[3] = (uint8_t) transaction->register_address;
buffer[4] = (uint8_t) (transaction->register_count >> 8);
buffer[5] = (uint8_t) transaction->register_count;
*msg_len = 8;
}
}
crc16 = modbus_CRC16(buffer, *msg_len - 2); /* last two bytes is the checksum itself */
@@ -109,11 +117,18 @@ int8_t modbus_slave_set_address(uint8_t address)
int8_t modbus_slave_process_msg(const uint8_t *buffer, int len)
{
/*
* TODO list:
*
* 1) check that errors and exceptions are handled according to Modbus_Application_Protocol_V1_1b.pdf
* 2) buffer overflow prevention: for each function code, check that buffer is long enough
*/
/* transaction holds message context and content:
* it wraps all necessary buffers and variables */
modbus_transaction_t transaction;
int8_t callback_result;
uint8_t buffer_pos = 0;
uint8_t byte_count;
if (len < MODBUS_MINIMAL_FRAME_LEN) {
/* frame too short; return error */
@@ -188,11 +203,22 @@ int8_t modbus_slave_process_msg(const uint8_t *buffer, int len)
return MODBUS_ERROR;
}
transaction.register_address = (buffer[buffer_pos++] << 8) | buffer[buffer_pos++];
// TODO check length!
if (flags & MODBUS_FLAG_WRITE) {
if (flags & MODBUS_FLAG_SINGLE) {
transaction.holding_registers[0] = (buffer[buffer_pos++] << 8) | buffer[buffer_pos++];
} else {
// write multiple register - TODO
/* Write multiple registers */
transaction.register_count = (buffer[buffer_pos++] << 8) | buffer[buffer_pos++];
byte_count = buffer[buffer_pos++];
if (transaction.register_count > 123 || 2*transaction.register_count != byte_count) {
/* Max number of register is defined by Modbus_Application_Protocol_V1_1b, section 6.12 */
transaction.exception.exception_code = MODBUS_EXCEPTION_ILLEGAL_REGISTER_QUANTITY;
} else {
for (uint8_t i = 0; i < transaction.register_count; i++) {
transaction.holding_registers[i] = (buffer[buffer_pos++] << 8) | buffer[buffer_pos++];
}
}
}
} else {
transaction.register_count = (buffer[buffer_pos++] << 8) | buffer[buffer_pos++];