eMBException eMBMasterFuncWriteMultipleCoils( UCHAR * pucFrame, USHORT * usLen ) { USHORT usRegAddress; USHORT usCoilCnt; UCHAR ucByteCount; UCHAR ucByteCountVerify; UCHAR *ucMBFrame; eMBException eStatus = MB_EX_NONE; eMBErrorCode eRegStatus; /* If this request is broadcast, the *usLen is not need check. */ if( ( *usLen == MB_PDU_FUNC_WRITE_MUL_SIZE ) || xMBMasterRequestIsBroadcast() ) { vMBMasterGetPDUSndBuf(&ucMBFrame); usRegAddress = ( USHORT )( pucFrame[MB_PDU_FUNC_WRITE_MUL_ADDR_OFF] << 8 ); usRegAddress |= ( USHORT )( pucFrame[MB_PDU_FUNC_WRITE_MUL_ADDR_OFF + 1] ); usRegAddress++; usCoilCnt = ( USHORT )( pucFrame[MB_PDU_FUNC_WRITE_MUL_COILCNT_OFF] << 8 ); usCoilCnt |= ( USHORT )( pucFrame[MB_PDU_FUNC_WRITE_MUL_COILCNT_OFF + 1] ); ucByteCount = ucMBFrame[MB_PDU_REQ_WRITE_MUL_BYTECNT_OFF]; /* Compute the number of expected bytes in the request. */ if( ( usCoilCnt & 0x0007 ) != 0 ) { ucByteCountVerify = ( UCHAR )( usCoilCnt / 8 + 1 ); } else { ucByteCountVerify = ( UCHAR )( usCoilCnt / 8 ); } if( ( usCoilCnt >= 1 ) && ( ucByteCountVerify == ucByteCount ) ) { eRegStatus = eMBMasterRegCoilsCB( &ucMBFrame[MB_PDU_REQ_WRITE_MUL_VALUES_OFF], usRegAddress, usCoilCnt, MB_REG_WRITE ); /* If an error occured convert it into a Modbus exception. */ if( eRegStatus != MB_ENOERR ) { eStatus = prveMBError2Exception( eRegStatus ); } } else { eStatus = MB_EX_ILLEGAL_DATA_VALUE; } } else { /* Can't be a valid write coil register request because the length * is incorrect. */ eStatus = MB_EX_ILLEGAL_DATA_VALUE; } return eStatus; }
eMBException eMBMasterFuncWriteCoil(uint8_t *pucFrame, uint16_t *usLen) { uint16_t usRegAddress; uint8_t ucBuf[2]; eMBException eStatus = MB_EX_NONE; eMBErrorCode eRegStatus; if (*usLen == (MB_PDU_FUNC_WRITE_SIZE + MB_PDU_SIZE_MIN)) { usRegAddress = (uint16_t) (pucFrame[MB_PDU_FUNC_WRITE_ADDR_OFF] << 8); usRegAddress |= (uint16_t) (pucFrame[MB_PDU_FUNC_WRITE_ADDR_OFF + 1]); usRegAddress++; if ((pucFrame[MB_PDU_FUNC_WRITE_VALUE_OFF + 1] == 0x00) && ((pucFrame[MB_PDU_FUNC_WRITE_VALUE_OFF] == 0xFF) || (pucFrame[MB_PDU_FUNC_WRITE_VALUE_OFF] == 0x00))) { ucBuf[1] = 0; if (pucFrame[MB_PDU_FUNC_WRITE_VALUE_OFF] == 0xFF) { ucBuf[0] = 1; } else { ucBuf[0] = 0; } eRegStatus = eMBMasterRegCoilsCB(&ucBuf[0], usRegAddress, 1, MB_REG_WRITE); /* If an error occured convert it into a Modbus exception. */ if (eRegStatus != MB_ENOERR) { eStatus = prveMBError2Exception(eRegStatus); } } else { eStatus = MB_EX_ILLEGAL_DATA_VALUE; } } else { /* Can't be a valid write coil register request because the length is * incorrect. */ eStatus = MB_EX_ILLEGAL_DATA_VALUE; } return eStatus; }
eMBException eMBMasterFuncReadCoils(uint8_t *pucFrame, uint16_t *usLen) { uint8_t *ucMBFrame; uint16_t usRegAddress; uint16_t usCoilCount; uint8_t ucByteCount; eMBException eStatus = MB_EX_NONE; eMBErrorCode eRegStatus; /* If this request is broadcast, and it's read mode. This request don't need * execute. */ if (xMBMasterRequestIsBroadcast()) { eStatus = MB_EX_NONE; } else if (*usLen >= MB_PDU_SIZE_MIN + MB_PDU_FUNC_READ_SIZE_MIN) { vMBMasterGetPDUSndBuf(&ucMBFrame); usRegAddress = (uint16_t) (ucMBFrame[MB_PDU_REQ_READ_ADDR_OFF] << 8); usRegAddress |= (uint16_t) (ucMBFrame[MB_PDU_REQ_READ_ADDR_OFF + 1]); usRegAddress++; usCoilCount = (uint16_t) (ucMBFrame[MB_PDU_REQ_READ_COILCNT_OFF] << 8); usCoilCount |= (uint16_t) (ucMBFrame[MB_PDU_REQ_READ_COILCNT_OFF + 1]); /* Test if the quantity of coils is a multiple of 8. If not last byte is * only partially field with unused coils set to zero. */ if ((usCoilCount & 0x0007) != 0) { ucByteCount = (uint8_t) (usCoilCount / 8 + 1); } else { ucByteCount = (uint8_t) (usCoilCount / 8); } /* Check if the number of registers to read is valid. If not return * Modbus illegal data value exception. */ if ((usCoilCount >= 1) && (ucByteCount == pucFrame[MB_PDU_FUNC_READ_COILCNT_OFF])) { /* Make callback to fill the buffer. */ eRegStatus = eMBMasterRegCoilsCB(&pucFrame[MB_PDU_FUNC_READ_VALUES_OFF], usRegAddress, usCoilCount, MB_REG_READ); /* If an error occurred convert it into a Modbus exception. */ if (eRegStatus != MB_ENOERR) { eStatus = prveMBError2Exception(eRegStatus); } } else { eStatus = MB_EX_ILLEGAL_DATA_VALUE; } } else { /* Can't be a valid read coil register request because the length is * incorrect. */ eStatus = MB_EX_ILLEGAL_DATA_VALUE; } return eStatus; }