mirror of
				https://github.com/espressif/esp-idf.git
				synced 2025-10-30 20:51:41 +00:00 
			
		
		
		
	 66fb5a29bb
			
		
	
	66fb5a29bb
	
	
	
		
			
			Apply the pre-commit hook whitespace fixes to all files in the repo. (Line endings, blank lines at end of file, trailing whitespace)
		
			
				
	
	
		
			127 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			127 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
|  /*
 | |
|   * FreeRTOS Modbus Libary: A Modbus serial implementation for FreeRTOS
 | |
|   * Copyright (C) 2006 Christian Walter <wolti@sil.at>
 | |
|   *
 | |
|   * This library is free software; you can redistribute it and/or
 | |
|   * modify it under the terms of the GNU Lesser General Public
 | |
|   * License as published by the Free Software Foundation; either
 | |
|   * version 2.1 of the License, or (at your option) any later version.
 | |
|   *
 | |
|   * This library is distributed in the hope that it will be useful,
 | |
|   * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
|   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | |
|   * Lesser General Public License for more details.
 | |
|   *
 | |
|   * You should have received a copy of the GNU Lesser General Public
 | |
|   * License along with this library; if not, write to the Free Software
 | |
|   * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | |
|   */
 | |
| 
 | |
| /* ----------------------- System includes ----------------------------------*/
 | |
| #include "stdlib.h"
 | |
| #include "string.h"
 | |
| 
 | |
| /* ----------------------- Platform includes --------------------------------*/
 | |
| #include "port.h"
 | |
| 
 | |
| /* ----------------------- Modbus includes ----------------------------------*/
 | |
| #include "mb.h"
 | |
| #include "mbframe.h"
 | |
| #include "mbproto.h"
 | |
| #include "mbconfig.h"
 | |
| 
 | |
| /* ----------------------- Defines ------------------------------------------*/
 | |
| #define MB_PDU_FUNC_READ_ADDR_OFF           ( MB_PDU_DATA_OFF )
 | |
| #define MB_PDU_FUNC_READ_DISCCNT_OFF        ( MB_PDU_DATA_OFF + 2 )
 | |
| #define MB_PDU_FUNC_READ_SIZE               ( 4 )
 | |
| #define MB_PDU_FUNC_READ_DISCCNT_MAX        ( 0x07D0 )
 | |
| 
 | |
| /* ----------------------- Static functions ---------------------------------*/
 | |
| eMBException    prveMBError2Exception( eMBErrorCode eErrorCode );
 | |
| 
 | |
| /* ----------------------- Start implementation -----------------------------*/
 | |
| #if MB_SLAVE_RTU_ENABLED || MB_SLAVE_ASCII_ENABLED || MB_TCP_ENABLED
 | |
| 
 | |
| #if MB_FUNC_READ_COILS_ENABLED
 | |
| 
 | |
| eMBException
 | |
| eMBFuncReadDiscreteInputs( UCHAR * pucFrame, USHORT * usLen )
 | |
| {
 | |
|     USHORT          usRegAddress;
 | |
|     USHORT          usDiscreteCnt;
 | |
|     UCHAR           ucNBytes;
 | |
|     UCHAR          *pucFrameCur;
 | |
| 
 | |
|     eMBException    eStatus = MB_EX_NONE;
 | |
|     eMBErrorCode    eRegStatus;
 | |
| 
 | |
|     if( *usLen == ( MB_PDU_FUNC_READ_SIZE + MB_PDU_SIZE_MIN ) )
 | |
|     {
 | |
|         usRegAddress = ( USHORT )( pucFrame[MB_PDU_FUNC_READ_ADDR_OFF] << 8 );
 | |
|         usRegAddress |= ( USHORT )( pucFrame[MB_PDU_FUNC_READ_ADDR_OFF + 1] );
 | |
|         usRegAddress++;
 | |
| 
 | |
|         usDiscreteCnt = ( USHORT )( pucFrame[MB_PDU_FUNC_READ_DISCCNT_OFF] << 8 );
 | |
|         usDiscreteCnt |= ( USHORT )( pucFrame[MB_PDU_FUNC_READ_DISCCNT_OFF + 1] );
 | |
| 
 | |
|         /* Check if the number of registers to read is valid. If not
 | |
|          * return Modbus illegal data value exception.
 | |
|          */
 | |
|         if( ( usDiscreteCnt >= 1 ) &&
 | |
|             ( usDiscreteCnt < MB_PDU_FUNC_READ_DISCCNT_MAX ) )
 | |
|         {
 | |
|             /* Set the current PDU data pointer to the beginning. */
 | |
|             pucFrameCur = &pucFrame[MB_PDU_FUNC_OFF];
 | |
|             *usLen = MB_PDU_FUNC_OFF;
 | |
| 
 | |
|             /* First byte contains the function code. */
 | |
|             *pucFrameCur++ = MB_FUNC_READ_DISCRETE_INPUTS;
 | |
|             *usLen += 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( ( usDiscreteCnt & 0x0007 ) != 0 )
 | |
|             {
 | |
|                 ucNBytes = ( UCHAR ) ( usDiscreteCnt / 8 + 1 );
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 ucNBytes = ( UCHAR ) ( usDiscreteCnt / 8 );
 | |
|             }
 | |
|             *pucFrameCur++ = ucNBytes;
 | |
|             *usLen += 1;
 | |
| 
 | |
|             eRegStatus =
 | |
|                 eMBRegDiscreteCB( pucFrameCur, usRegAddress, usDiscreteCnt );
 | |
| 
 | |
|             /* If an error occured convert it into a Modbus exception. */
 | |
|             if( eRegStatus != MB_ENOERR )
 | |
|             {
 | |
|                 eStatus = prveMBError2Exception( eRegStatus );
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 /* The response contains the function code, the starting address
 | |
|                  * and the quantity of registers. We reuse the old values in the
 | |
|                  * buffer because they are still valid. */
 | |
|                 *usLen += ucNBytes;;
 | |
|             }
 | |
|         }
 | |
|         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;
 | |
| }
 | |
| 
 | |
| #endif
 | |
| 
 | |
| #endif
 |