/* 
 * File:   MB_MasterSM.h
 * Author: chang
 *
 * Created on July 30, 2024, 10:05 AM
 */

#ifndef MB_MASTERSM_H
#define	MB_MASTERSM_H

#ifdef	__cplusplus
extern "C" {
#endif
#include "stdint.h"
//#include "modbus.h"   //because "modbus_User.h" contains "modbus.h"
#include "modbus_User.h"   
    
#ifndef MB_MasterSM_Module  
    #define myExtern extern
#else
    #define myExtern
#endif

//#define ERROR_MAX_TRY 3    //For max try when error
#ifndef MB_MasterSM_Module     
    extern  uint8_t ERROR_MAX_TRY;  //we compile it into library in variable , so customer can change it. 
#else
    uint8_t ERROR_MAX_TRY=3;      //Default= 3 times, you can change it in your application by set "ERROR_MAX_TRY=...." statement 
#endif
  

//This is for MASTER modbus command type
#define SINGLE_WRITE_HOLDING_TYPE 0
#define MULTIPLE_WRITE_HOLDING_TYPE 1 
#define SINGLE_WRITE_COIL_TYPE 2
#define MULTIPLE_WRITE_COIL_TYPE 3 
#define WRITE_USER1_HOLDING_TYPE 4 
#define WRITE_USER2_HOLDING_TYPE 5
#define MASK_WRITE_HOLDING_TYPE 6    
    
#define READ_INPUT_TYPE 0
#define READ_HOLDING_TYPE 1 
#define READ_DISCRETE_TYPE 2
#define READ_COIL_TYPE 3 
#define READ_USER1_HOLDING_TYPE 4 
#define READ_USER2_HOLDING_TYPE 5     

    
myExtern uint32_t cmd_LogicalRuller;  //Bit31 :  1- I am Execting cmd, others don't send command, Bit0-14 :writing, Bit15-Bit30: reading
//myExtern uint8_t CMDType[31]; 
myExtern uint8_t * CMDType[31];    //CMDType[i]: i is  cmd_LogicalRuller command bit number
myExtern uint8_t * WriteServerID[15];  //every element is uint8_t array,  If Server ID qty  is more than 1, must write the same value(same address)
                                       //it is good for writing the same command for multiple the same type devices.
myExtern uint8_t  WriteServerID_Qty[15];
//myExtern uint16_t WriteStartAddress[15];
myExtern uint16_t * WriteStartAddress[15];
myExtern uint16_t * WriteValue[15];   //For make write WriteValue[i][0]:AND Mask value, WriteValue[i][1]:OR Mask value
//myExtern uint16_t WriteSize[15];   // For word regs, it is WriteValue size. For bit regs, WriteValue size= (WriteSize +15)/16, that is to say, WriteSize is bit size
myExtern uint16_t * WriteSize[15];
myExtern uint16_t WriteOK[20];  //WriteOK[i].bit0 ;1 => Success for writing in cmd_LogicalRuller.bit0 ,  i is device number for the same bit in cmd_LogicalRuller (more than 1 Server ID))
                                // WriteOK[i].bit1: 1=> Success for writing in cmd_LogicalRuller.bit1,  i is device number for the same bit in cmd_LogicalRuller (more than 1 Server ID))
                                //...
                                //WriteOK[i].bit14: 1=> Success for writing in cmd_LogicalRuller.bit14,  i is device number for the same bit in cmd_LogicalRuller (more than 1 Server ID))
                                //when more than 20 Server ID for one bit of cmd_LogicalRuller , it still work, but don't tell you OK or Error 
#define GET_CMD_TYPE(i) (*CMDType[i])    //For weiying:
                                        //0: single write holding, 1:multiple write holdings 2:single write coil, 
                                        //3:multiple write coil, 4: write user1 holding, 5: write user2 holding, 6:Mask write
                                        //For reading:
                                         //0: read input regs, 1:read holding regs 2:read discrete regs, 
                                         //3:read coils, 4: read user1 holding, 5: read user2 holding
//#define SET_CMD_TYPE(i, value) (*CMDType[i]=value)

//myExtern uint8_t  ReadServerID[16];
myExtern uint8_t  * ReadServerID[16];
//myExtern uint16_t ReadStartAddress[16];
myExtern uint16_t * ReadStartAddress[16];
myExtern uint16_t * ReadOutValue[16];
//myExtern uint16_t ReadOutSize[16];   // For word regs, it is ReadOutValue size. For bit regs, ReadOutValue size= (ReadOutSize +15)/16, that is to say, ReadOutSize is bit size
myExtern uint16_t * ReadOutSize[16];
myExtern uint16_t ReadOK;  //ReadOK.bit0 ;1 => Success for reading in cmd_LogicalRuller.bit15 
                           //ReadOK.bit1 ;1 => Success for reading in cmd_LogicalRuller.bit16 
                           //...
                           //ReadOK.bit15: 1 => Success for reading in cmd_LogicalRuller.bit30 

#define setOneGroupDeviceWriteCmd(i)  (cmd_LogicalRuller|=(1uL<<i)|0x80000000)  //i =0 to 14,  Set cmd_LogicalRuller bit 31=1, and writing command bit (i) to 1
#define setOneDeviceReadCmd(i)  (cmd_LogicalRuller|=(1uL<<(i+15)|0x80000000))  //i=0 to 15, Set cmd_LogicalRuller bit 31=1,and read command bit (15+i) to 1
#define setMultipleGroupDevicesWriteCmd(DeviceBits)  (cmd_LogicalRuller|=(DeviceBits)|0x80000000)  //DeviceBits= 0x0 to 0x7FFF,  Set cmd_LogicalRuller bit 31=1, and writing command bit =DeviceBits
#define setMultipleDevicesReadCmd(DeviceBits)  (cmd_LogicalRuller|=(DeviceBits<<15)|0x80000000)  //DeviceBits= 0x0 to 0xFFFF, Set cmd_LogicalRuller bit 31=1,and read command bit DeviceBits<<15

#define isWriteOrReadCmdDone (cmd_LogicalRuller==0x80000000)   //Judgement of Reador write done
#define setMaster2Idle (cmd_LogicalRuller=0)        //When Reador write done, we must call it to set master to idle
#define isMasterIdle (!cmd_LogicalRuller)    //Only when Idle, we can call send read or write command

#define isOneWriteCmdDone(i) ((cmd_LogicalRuller & (1UL<<(i)))==0x0)   //Judgement of i-th write done, i=0 to 14
#define isOneReadCmdDone(i) ((cmd_LogicalRuller & (1UL<<((i)+15)))==0x0)   //Judgement of i-th read done, i=0 to 15

void MODBUS_Master_Poll(ModbusMaster_t *modbus);

#ifdef	__cplusplus
}
#endif

#endif	/* MB_MASTERSM_H */

