extern int8_t readInputRegisters( uint16_t startingAddress, uint16_t quantityOfInputRegisters, uint8_t * exceptionCode, uint8_t * buf ) { int8_t ret; /* check if address and quantity of registers match */ if ( (0x0000 == startingAddress) && (0x01 == quantityOfInputRegisters) ) { /* write register in to buffer */ ciaaModbus_writeInt(&buf[0], inputRegVal); /* return quantity of registers writes */ ret = 1; } else { /* set exception code address wrong */ *exceptionCode = CIAAMODBUS_E_WRONG_STR_ADDR; /* return -1 to indicate that an exception occurred */ ret = -1; } return ret; }
/*==================[internal functions definition]==========================*/ static uint16_t cmd0x03ReadHoldingReg( uint16_t start, uint16_t quantity, uint8_t * exceptioncode, uint8_t * buf ) { /* used to indicate total of registers reads */ int8_t ret = 0; /* used to indicate quantity of registers processed */ uint16_t quantityRegProcessed; uint16_t temp16u; /* loop to read all registers indicated */ do { /* select register address to be read */ switch (start) { /* estado de los leds */ case MODBUS_ADDRESS_ESTADO_LEDS: temp16u = leds_get(); ciaaModbus_writeInt(buf, 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 read */ start += quantityRegProcessed; /* increment count of registers */ ret += quantityRegProcessed; } else { /* an error occurred in reading */ ret = -1; } /* repeat until: * - read total registers or * - error occurs */ }while ((ret > 0) && (ret < quantity)); return ret; }
/*==================[internal functions definition]==========================*/ static uint16_t cmd0x03ReadHoldingReg( uint16_t start, uint16_t quantity, uint8_t * exceptioncode, uint8_t * buf ) { /* used to store holding register value */ uint16_t hrValue; /* used to indicate quantity of registers processed */ int16_t quantityRegProcessed; /* used to indicate total of registers reads */ int8_t ret = 0; /* used to store input or outputs byte */ uint8_t inOutValue; /* loop to read all registers indicated */ do { /* select register address to be read */ switch (start) { /* read inputs of CIAA */ case CIAA_MODBUS_ADDRESS_INPUTS: ciaaPOSIX_read(fd_in, &inOutValue, 1); hrValue = inOutValue; ciaaModbus_writeInt(buf, hrValue); quantityRegProcessed = 1; break; /* read outputs of CIAA */ case CIAA_MODBUS_ADDRESS_OUTPUS: ciaaPOSIX_read(fd_out, &inOutValue, 1); hrValue = inOutValue; ciaaModbus_writeInt(buf, hrValue); 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 read */ start += quantityRegProcessed; /* increment count of registers */ ret += quantityRegProcessed; } else { /* an error occurred in reading */ ret = -1; } /* repeat until: * - read total registers or * - error occurs */ }while ((ret > 0) && (ret < quantity)); return ret; }
extern int8_t readHoldingRegisters( uint16_t startingAddress, uint16_t quantityOfHoldingRegisters, uint8_t * exceptionCode, uint8_t * buf ) { /* used to indicate total of registers reads */ int8_t ret = 0; /* used to indicate quantity of registers processed */ uint16_t quantityRegProcessed; /* loop to read all registers indicated */ do { /* select register address to be read */ switch (startingAddress) { /* read inputs of CIAA */ case MODBUS_ADDR_HR_CIAA_INPUTS: ciaaModbus_writeInt(buf, hr_ciaaInputs); quantityRegProcessed = 1; break; /* read outputs of CIAA */ case MODBUS_ADDR_HR_CIAA_OUTPUTS: ciaaModbus_writeInt(buf, hr_ciaaOutputs); 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 read */ startingAddress += quantityRegProcessed; /* increment count of registers */ ret += quantityRegProcessed; } else { /* an error occurred in reading */ ret = -1; } /* repeat until: * - read total registers or * - error occurs */ }while ((ret > 0) && (ret < quantityOfHoldingRegisters)); return ret; }
extern void ciaaModbus_masterRecvMsg( int32_t handler, uint8_t *id, uint8_t *pdu, uint32_t *size) { uint32_t loopi; /* is there function to perform? */ if (0x00 != ciaaModbus_masterObj[handler].cmd) { /* set slave id */ *id = ciaaModbus_masterObj[handler].slaveId; /* set function code */ pdu[0] = ciaaModbus_masterObj[handler].cmd; /* according to function, make pdu */ switch (pdu[0]) { /* read coils */ case CIAA_MODBUS_FCN_READ_COILS: /* read discrete inputs */ case CIAA_MODBUS_FCN_READ_DISCRETE_INPUTS: /* read holding registers */ case CIAA_MODBUS_FCN_READ_HOLDING_REGISTERS: /* read input registers */ case CIAA_MODBUS_FCN_READ_INPUT_REGISTERS: /* write in buffer: start address */ ciaaModbus_writeInt(&pdu[1], ciaaModbus_masterObj[handler].startAddressR); /* write in buffer: quantity of registers */ ciaaModbus_writeInt(&pdu[3], ciaaModbus_masterObj[handler].quantityR); /* lenght of pdu */ *size = 5; break; /* write single coil */ case CIAA_MODBUS_FCN_WRITE_SINGLE_COIL: /* write single coil */ case CIAA_MODBUS_FCN_WRITE_SINGLE_REGISTER: /* write in buffer: start address */ ciaaModbus_writeInt(&pdu[1], ciaaModbus_masterObj[handler].startAddressW); /* write in buffer: quantity of registers */ ciaaModbus_writeInt(&pdu[3], ciaaModbus_masterObj[handler].dataW); /* lenght of pdu */ *size = 5; break; /* write multiple coils */ case CIAA_MODBUS_FCN_WRITE_MULTIPLE_COILS: /* write in buffer: start address */ ciaaModbus_writeInt(&pdu[1], ciaaModbus_masterObj[handler].startAddressW); /* write in buffer: quantity of registers */ ciaaModbus_writeInt(&pdu[3], ciaaModbus_masterObj[handler].quantityW); /* write in buffer: byte count */ pdu[5] = ciaaModbus_masterObj[handler].quantityW / 8; if (ciaaModbus_masterObj[handler].quantityW % 8) { pdu[5]++; } for (loopi = 0 ; loopi < ciaaModbus_masterObj[handler].quantityW ; loopi++) { /* write in buffer: outputs value */ pdu[6+loopi] = ((uint8_t*)ciaaModbus_masterObj[handler].pDataW)[loopi]; } /* lenght of pdu */ *size = 6 + pdu[5]; break; /* write multiple registers */ case CIAA_MODBUS_FCN_WRITE_MULTIPLE_REGISTERS: /* write in buffer: start address */ ciaaModbus_writeInt(&pdu[1], ciaaModbus_masterObj[handler].startAddressW); /* write in buffer: quantity of registers */ ciaaModbus_writeInt(&pdu[3], ciaaModbus_masterObj[handler].quantityW); /* write in buffer: byte count */ pdu[5] = ciaaModbus_masterObj[handler].quantityW * 2; for (loopi = 0 ; loopi < ciaaModbus_masterObj[handler].quantityW ; loopi++) { /* write in buffer: register value */ ciaaModbus_writeInt(&pdu[6+loopi*2], ciaaModbus_masterObj[handler].pDataW[loopi]); } /* lenght of pdu */ *size = 6 + ciaaModbus_masterObj[handler].quantityW * 2; break; /* write multiple registers */ case CIAA_MODBUS_FCN_READ_WRITE_MULTIPLE_REGISTERS: /* write in buffer: start address (read) */ ciaaModbus_writeInt(&pdu[1], ciaaModbus_masterObj[handler].startAddressR); /* write in buffer: quantity of registers (read)*/ ciaaModbus_writeInt(&pdu[3], ciaaModbus_masterObj[handler].quantityR); /* write in buffer: start address (write) */ ciaaModbus_writeInt(&pdu[5], ciaaModbus_masterObj[handler].startAddressW); /* write in buffer: quantity of registers (write) */ ciaaModbus_writeInt(&pdu[7], ciaaModbus_masterObj[handler].quantityW); /* write in buffer: byte count */ pdu[9] = ciaaModbus_masterObj[handler].quantityW * 2; for (loopi = 0 ; loopi < ciaaModbus_masterObj[handler].quantityW ; loopi++) { /* write in buffer: register value */ ciaaModbus_writeInt(&pdu[10+loopi*2], ciaaModbus_masterObj[handler].pDataW[loopi]); } /* lenght of pdu */ *size = 10 + ciaaModbus_masterObj[handler].quantityW * 2; break; /* function not defined */ default: /* lenght of pdu */ *size = 0; break; } } }