SP8EBC-ParaTNC/system/src/modbus_rtu/rtu_request.c

62 wiersze
1.4 KiB
C

/*
* rtu_request.c
*
* Created on: 18.09.2020
* Author: mateusz
*/
#include <stdarg.h>
#include <string.h>
#include "./modbus_rtu/rtu_request.h"
#include "./modbus_rtu/rtu_return_values.h"
#include "./modbus_rtu/rtu_crc.h"
int32_t rtu_request_03_04_registers(int8_t input_or_holding, uint8_t* output, uint8_t output_ln, uint8_t* output_ln_used, uint8_t slave_address, uint16_t base_register, uint8_t number_of_registers) {
int32_t retval = MODBUS_RET_UNINITIALIZED;
uint16_t crc = 0;
// check if there is a room for a RTU frame
if (output == 0x00 || output_ln < 8) {
retval = MODBUS_RET_TOO_SHORT;
}
else {
// initialize the output buffer for RTU binary frame
memset(output, 0x00, output_ln);
// put the slave address
*output = slave_address;
// put the function code
if (input_or_holding == 0) {
*(output + 1) = 0x04;
}
else {
*(output + 1) = 0x03;
}
// put the base address to be read from the slave
*(output + 2) = (base_register & 0xFF00) >> 8;
*(output + 3) = base_register & 0xFF;
// put the numbers of register to be read from slave
*(output + 4) = 0x00; // all in all modbus RTU can transfer no more than 125 at once
*(output + 5) = number_of_registers;
// calculate the CRC from the content
crc = rtu_crc_buffer(output, 6);
// append the crc value
*(output + 7) = (crc & 0xFF00) >> 8;
*(output + 6) = crc & 0xFF;
*output_ln_used = 8;
retval = MODBUS_RET_OK;
}
return retval;
}