/** \brief Process data to function 0x03 or 0x04 or 0x17 ** ** This function process PDU response as request function 0x03 or 0x04 or 0x17 ** ** \param[in] handler handler modbus master ** \param[in] pdu pdu received ** \param[out] size size of pdu. ** \return CIAA_MODBUS_E_NO_ERROR correct response ** CIAA_MODBUS_E_PDU_RECEIVED_WRONG incorrect response **/ static uint8_t ciaaModbus_masterProcess0x03_0x04_0x17(uint32_t hModbusMaster, uint8_t *pdu, uint16_t size) { uint16_t loopi; uint8_t ret; /* check if valid byte count and PDU size */ if ( (pdu[1] == (ciaaModbus_masterObj[hModbusMaster].quantityR * 2)) && (size == (2 + ciaaModbus_masterObj[hModbusMaster].quantityR * 2) ) ) { /* if valid, copy data received */ for (loopi = 0 ; loopi < ciaaModbus_masterObj[hModbusMaster].quantityR ; loopi++) { /* copy data to holding registers address */ ciaaModbus_masterObj[hModbusMaster].pDataR[loopi] = ciaaModbus_readInt(&pdu[2+loopi*2]); } /* return no error */ ret = CIAA_MODBUS_E_NO_ERROR; } else { /* return wrong pdu */ ret = CIAA_MODBUS_E_PDU_RECEIVED_WRONG; } return ret; }
static void cmd0x10WriteMultipleReg( uint16_t start, uint16_t quantity, uint8_t bytecount, uint8_t * exceptioncode, uint8_t * buf ) { /* used to indicate quantity of registers processed */ uint16_t quantityRegProcessed; /* loop to write all registers indicated */ do { /* select register address to be write */ switch (start) { /* inputs can not be written! */ case CIAA_MODBUS_ADDRESS_INPUTS: *exceptioncode = CIAA_MODBUS_E_FNC_ERROR; quantityRegProcessed = -1; break; /* write outputs */ case CIAA_MODBUS_ADDRESS_OUTPUS: hr_ciaaOutputs = ciaaModbus_readInt(buf); quantityRegProcessed = 1; break; /* wrong address */ default: *exceptioncode = CIAA_MODBUS_E_WRONG_STR_ADDR; quantityRegProcessed = -1; break; } /* if quantityRegProcessed > 0, successful operation */ if (quantityRegProcessed > 0) { /* update buffer pointer to next register */ buf += (quantityRegProcessed*2); /* next address to be write */ start += quantityRegProcessed; quantity -= quantityRegProcessed; } else { quantity = 0; } /* repeat until: * - read total registers or * - error occurs */ }while (0 < quantity); }
/** \brief Process data to function 0x0F or 0x10 ** ** This function process PDU response as request function 0x0F or 0x10 ** ** \param[in] handler handler modbus master ** \param[in] pdu pdu received ** \param[out] size size of pdu. ** \return CIAA_MODBUS_E_NO_ERROR correct response ** CIAA_MODBUS_E_PDU_RECEIVED_WRONG incorrect response **/ static uint8_t ciaaModbus_masterProcess0x0F_0x10(uint32_t hModbusMaster, uint8_t *pdu, uint16_t size) { uint8_t ret; if ( (ciaaModbus_readInt(&pdu[1]) == ciaaModbus_masterObj[hModbusMaster].startAddressW) && (ciaaModbus_readInt(&pdu[3]) == ciaaModbus_masterObj[hModbusMaster].quantityW) ) { ret = CIAA_MODBUS_E_NO_ERROR; } else { /* set exception code CIAA_MODBUS_E_PDU_RECEIVED_WRONG */ ret = CIAA_MODBUS_E_PDU_RECEIVED_WRONG; } return ret; }
extern int8_t writeMultipleRegisters( uint16_t startingAddress, uint16_t quantityOfRegisters, uint8_t * exceptionCode, uint8_t * buf ) { /* used to indicate total of registers writes */ int8_t ret = 0; /* used to indicate quantity of registers processed */ uint16_t quantityRegProcessed; /* loop to write all registers indicated */ do { /* select register address to be write */ switch (startingAddress) { /* inputs can not be written! */ case MODBUS_ADDR_HR_CIAA_INPUTS: *exceptionCode = CIAAMODBUS_E_FNC_ERROR; quantityRegProcessed = -1; break; /* write outputs */ case MODBUS_ADDR_HR_CIAA_OUTPUTS: hr_ciaaOutputs = ciaaModbus_readInt(buf); quantityRegProcessed = 1; break; /* wrong address */ default: *exceptionCode = CIAAMODBUS_E_WRONG_STR_ADDR; quantityRegProcessed = -1; break; } /* if quantityRegProcessed > 0, successful operation */ if (quantityRegProcessed > 0) { /* update buffer pointer to next register */ buf += (quantityRegProcessed*2); /* next address to be write */ startingAddress += quantityRegProcessed; /* increment count of registers */ ret += quantityRegProcessed; } else { ret = -1; } /* repeat until: * - read total registers or * - error occurs */ }while ((ret > 0) && (ret < quantityOfRegisters)); /* if success return 1 */ if (ret > 1) ret = 1; return ret; }
static void cmd0x10WriteMultipleReg( uint16_t start, uint16_t quantity, uint8_t bytecount, uint8_t * exceptioncode, uint8_t * buf ) { /* used to indicate quantity of registers processed */ uint16_t quantityRegProcessed; uint16_t temp16u; /* loop to write all registers indicated */ do { /* select register address to be write */ switch (start) { /* escritura de estado de teclas */ case MODBUS_ADDRESS_TECLADO_REMOTO: temp16u = ciaaModbus_readInt(buf); //procesarTeclas(temp16u); quantityRegProcessed = 1; break; /* escritura de leds */ case MODBUS_ADDRESS_ESTADO_LEDS: temp16u = ciaaModbus_readInt(buf); leds_set(temp16u); quantityRegProcessed = 1; break; /* wrong address */ default: *exceptioncode = CIAA_MODBUS_E_WRONG_STR_ADDR; quantityRegProcessed = -1; break; } /* if quantityRegProcessed > 0, successful operation */ if (quantityRegProcessed > 0) { /* update buffer pointer to next register */ buf += (quantityRegProcessed*2); /* next address to be write */ start += quantityRegProcessed; quantity -= quantityRegProcessed; } else { quantity = 0; } /* repeat until: * - read total registers or * - error occurs */ }while (0 < quantity); }