
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
//-------------------------------------------------------//
// Project Code : ESS100K3L-01-19
// File Name : Modbus.cpp
// Created on : 2019. 06. 07.
// Description :
// Author : KimJeongWoo
// Last modified Date :
//-------------------------------------------------------//
#include "CommonLib.h"
//
// 1. SCIRXBUF레지스터는 EasyDSP나 에뮬레이터에서 절대 보지 말것.
// FIFO 카운터를 감소시켜 처리 시퀀스에 오류를 발생함.
// 이는 모든 FIFO를 사용하는 UART의 경우 문제 발생의 여지가 있음.
// 꼭 모니터링이 필요 한 경우는 SCIRXEMU 레지스터를 이용하여 볼것.
//
// 2. FIFO를 사용하는 경유 SCIRXBUF.all 대신 SCIRXBUF.RXDT를 사용 하여야 함
//
// 3. RX FIFO가 Overflow가 되는 경우 먼저 들어온 순서대로 삭제됨 (FIFO)
#define CPUCLK 200000000L // CPU Main Clock
#if(MODBUSA_ENB)
#define MODBUSA_RX_RDY ScicRegs.SCIRXST.bit.RXRDY
#define MODBUSA_RX_FIFO ScicRegs.SCIFFRX.bit.RXFFST
#define MODBUSA_RX_FIFO_RST ScicRegs.SCIFFRX.bit.RXFIFORESET
#define MODBUSA_RX_OVF ScicRegs.SCIFFRX.bit.RXFFOVF
#define MODBUSA_RX_OVFCLR ScicRegs.SCIFFRX.bit.RXFFOVRCLR
#define MODBUSA_RX_BUF ScicRegs.SCIRXBUF.bit.SAR
#define MODBUSA_RX_ERROR ScicRegs.SCIRXST.bit.RXERROR
#define MODBUSA_TX_RDY ScicRegs.SCICTL2.bit.TXRDY
#define MODBUSA_TX_FIFO ScicRegs.SCIFFTX.bit.TXFFST
#define MODBUSA_TX_BUF ScicRegs.SCITXBUF.bit.TXDT
#define MODBUSA_TX_EMTPY ScicRegs.SCICTL2.bit.TXEMPTY
#define MODBUSA_SWRESET ScicRegs.SCICTL1.bit.SWRESET = 0,\
ScicRegs.SCICTL1.all = 0x0023
#define MODBUSA_FIFO_RST ScicRegs.SCIFFTX.bit.SCIRST = 1
//---------------------------- Serial Modbus A set parameter RS485----------------------------------//
#define MODBUSA_LSPCLK (CPUCLK/4) // Peripheral Low Speed Clock for SCI-
#define MODBUSA_BAUDRATE 9600L
#define MODBUSA_BRR_VAL (MODBUSA_LSPCLK/(8*MODBUSA_BAUDRATE)-1) // MODBUSA BaudRate ���� Register ��
//16번 funccode로 123개 동시 write 명령시 231 바이트
//
#define MODBUSA_RECEIVE_MAX_BYTE 250
#define MODBUSA_RECEIVE_MIN_BYTE 2
#define MODBUSA_TRANS_MAX_BYTE 250
#define MODBUSA_START_ADDR 0
#define MODBUSA_MAX_ADDR 1500
#pragma SET_DATA_SECTION(".Modbus")
unsigned int ModbusASlaveID = 1;
unsigned int ModbusARxCnt = 0, ModbusARxOk = 0, ModbusARxErr = 0, ModbusATxReady = 0, ModbusATxCnt = 0, ModbusATxDataLength = 0;
unsigned int ModbusACharTime = 0, ModbusACnt = 0, ModbusAStop = 0, ModbusACharTimeset = 8;
unsigned int ModbusAExceptionCode = 0;
unsigned char ModbusARxBuf[MODBUSA_RECEIVE_MAX_BYTE];
unsigned char ModbusATxBuf[MODBUSA_TRANS_MAX_BYTE];
unsigned int ModbusA_Connection_Check = 0;
unsigned int Flag_ModbusA_Data_reset = 0;
volatile void *ModbusAPtr[MODBUSAPTRMAX];
unsigned int ModbusATxWaitCnt = 0;
unsigned int ModbusAFrmStartFlag = 0;
unsigned int ModbusARxMaxFlag = 0;
unsigned int ModbusARxStop = 0;
#pragma SET_DATA_SECTION()
#endif
//--------------------------------------------------------------------------------------------------//
#if (MODBUSA_ENB)
void ModbusACheckBuffer()
{
int kk = 0;
if (MODBUSA_RX_OVF == 0)
{
if (MODBUSA_RX_FIFO != 0)
{
if (ModbusAFrmStartFlag == 0)
{
ModbusARxBuf[0] = MODBUSA_RX_BUF;
if (ModbusARxBuf[0] == ModbusASlaveID)
{
ModbusAFrmStartFlag = 1;
ModbusARxCnt = 1;
}
}
else if (ModbusAFrmStartFlag == 1)
{
if (ModbusARxCnt <= MODBUSA_RECEIVE_MAX_BYTE)
{
ModbusARxBuf[ModbusARxCnt++] = MODBUSA_RX_BUF;
}
else
{
ModbusAFrmStartFlag = 0;
ModbusARxCnt = 0;
}
}
ModbusACharTime = 0;
ModbusAStop = 0;
} //
else if (MODBUSA_RX_FIFO == 0)
{
if (ModbusACharTime <= ModbusACharTimeset) ModbusACharTime++;
else if (ModbusACharTime > ModbusACharTimeset)
{
ModbusACharTime = 0;
kk = ModbusARxCnt;
ModbusARxCnt = 0;
if (ModbusAFrmStartFlag == 1)
{
ModbusACnt = kk;
if ((ModbusARxBuf[0] == ModbusASlaveID) && (ModbusACnt >= 4))
{
if (ModbusACRC16(ModbusACnt - 2, 1)) // CRC check
{
//CRC
memcpy(&ModbusATxBuf, &ModbusARxBuf, ModbusACnt);
ModbusARxOk = 1;
}
}
}
ModbusAFrmStartFlag = 0;
}
}
}
else
{
MODBUSA_RX_OVFCLR = 1;
MODBUSA_RX_FIFO_RST = 0;
MODBUSA_RX_FIFO_RST = 1;
}
if (ModbusATxReady == 1)
{
if (MODBUSA_TX_FIFO < 16)
{
if (ModbusATxCnt < (ModbusATxDataLength))
{
MODBUSA_TX_BUF = ModbusATxBuf[ModbusATxCnt];
ModbusATxCnt++;
ModbusATxWaitCnt = 0;
}
else
{
if (MODBUSA_TX_EMTPY == 1)
{
if (ModbusATxWaitCnt++ > (ModbusACharTimeset - 1))
{
ModbusATxReady = 0;
ModbusATxCnt = 0;
ModbusATxWaitCnt = 0;
}
}
else
{
}
}
}
}
if (MODBUSA_RX_ERROR != 0) MODBUSA_SWRESET;
}
void ModbusAResponse() // 10msec routine
{
if (ModbusARxOk == 1)
{
if (ModbusACnt > MODBUSA_RECEIVE_MAX_BYTE)
{
ModbusAExceptionCode = 2;
ModbusABadResponse(); //to many bytes in frame */
}
else if (ModbusACnt < MODBUSA_RECEIVE_MIN_BYTE)
{
ModbusAExceptionCode = 2;
ModbusABadResponse(); //to few bytes frame*/
}
else
{
if (ModbusATxBuf[1] == 3) ModbusA3rdResponse();
else if (ModbusATxBuf[1] == 4) ModbusA4thResponse();
else if (ModbusATxBuf[1] == 6) ModbusA6thResponse();
else if (ModbusATxBuf[1] == 16) ModbusA16thResponse();
else ModbusABadResponse();
}
ModbusARxOk = 0;
}
}
int ModbusACRC16(int dataLength, int RXTXset) //CRC 16 for SERIAL checksum
{
//RXTXset : 0 TX CRC, 1 RX CRC
Uint16 lowCRC;
Uint16 highCRC;
Uint16 CRC;
Uint16 CRC_OK;
if (RXTXset == 1)
{
CRC = CRC16(ModbusARxBuf, dataLength);
highCRC = (CRC >> 8) & 0x00FF;
lowCRC = (CRC & 0x00FF);
if (ModbusARxBuf[dataLength + 1] == highCRC)
{
if (ModbusARxBuf[dataLength] == lowCRC) CRC_OK = 1;
else CRC_OK = 0;
//for test
}
else CRC_OK = 0;
}
else if (RXTXset == 0)
{
CRC = CRC16(ModbusATxBuf, dataLength);
highCRC = (CRC >> 8) & 0x00FF;
lowCRC = (CRC & 0x00FF);
ModbusATxBuf[dataLength] = lowCRC;
ModbusATxBuf[dataLength + 1] = highCRC;
CRC_OK = 1;
}
return CRC_OK;
}
void ModbusA3rdResponse() //response for ipos 03 function (read registers)
{
int j, temp_address, temp_length, *temp_data;
temp_address = ((ModbusATxBuf[2] << 8) & 0x0ff00) + (ModbusATxBuf[3] & 0x00ff);
temp_length = ModbusATxBuf[5] & 0x00ff;
ModbusATxBuf[2] = temp_length * 2;
for (j = 0; j < temp_length; j++)
{
temp_data = (int*) (ModbusAPtr[MODBUSA_START_ADDR + temp_address + j]);
ModbusATxBuf[j * 2 + 3] = ((*temp_data & 0x0ff00) >> 8) & 0x00ff;
ModbusATxBuf[j * 2 + 4] = (*temp_data & 0x00ff);
}
ModbusATxReady = ModbusACRC16(temp_length * 2 + 3, 0); //ADD+FUNC(2)+DATA
ModbusATxDataLength = temp_length * 2 + 5;
}
void ModbusA4thResponse() //response for MODBUS 4 function read registers
{
int temp_address, temp_length, *temp_data, j;
temp_address = ((ModbusATxBuf[2] << 8) & 0x0ff00) + (ModbusATxBuf[3] & 0x0ff);
temp_length = ModbusATxBuf[5] & 0xff;
ModbusATxBuf[2] = temp_length * 2;
for (j = 0; j < temp_length; j++)
{
temp_data = (int*) (ModbusAPtr[MODBUSA_START_ADDR + temp_address + j]);
ModbusATxBuf[j * 2 + 3] = ((*temp_data & 0x0ff00) >> 8) & 0xff;
ModbusATxBuf[j * 2 + 4] = (*temp_data & 0xff);
}
ModbusATxReady = ModbusACRC16(temp_length * 2 + 3, 0); //ADD+FUNC(2)+DATA
ModbusATxDataLength = temp_length * 2 + 5;
// ModbusTxDataLength=temp_length*2+7;
}
void ModbusA6thResponse() //response for MODBUS 3 function write single registers
{
int temp_address;
int temp_data;
int *ari1;
temp_address = (short) ((ModbusATxBuf[2] << 8) & 0x0ff00) + (ModbusATxBuf[3] & 0x0ff);
if (ModbusASerialRange(temp_address) == 1) ModbusAExceptionCode = 2;
else
{
temp_data = (((ModbusATxBuf[4] & 0xff) << 8) & 0xff00) + (ModbusATxBuf[5] & 0xff);
ari1 = (int*) ModbusAPtr[MODBUSA_START_ADDR + temp_address];
if (temp_data > 32767) *ari1 = (temp_data | 0xffff0000);
else *ari1 = temp_data;
ModbusATxReady = ModbusACRC16(6, 0);
ModbusATxDataLength = 8;
}
}
void ModbusA16thResponse() //response for MODBUS 16 function write multiple registers
{
int temp_address, temp_length, j;
register int temp_data;
int *ari1;
temp_address = ((ModbusATxBuf[2] << 8) & 0x0ff00) + (ModbusATxBuf[3] & 0x0ff);
temp_length = ModbusATxBuf[5] & 0xff;
if (ModbusASerialRange(temp_address + temp_length) == 1) ModbusAExceptionCode = 2;
else
{
for (j = 0; j < temp_length; j++)
{
temp_data = (((ModbusATxBuf[7 + 2 * j] & 0xff) << 8) & 0xff00) + (ModbusATxBuf[8 + 2 * j] & 0xff);
ari1 = (int*) ModbusAPtr[MODBUSA_START_ADDR + temp_address + j];
if (temp_data > 32767) *ari1 = (temp_data | 0xffff0000);
else *ari1 = temp_data;
}
}
ModbusATxReady = ModbusACRC16(6, 0);
ModbusATxDataLength = 8;
}
void ModbusABadResponse()
{
ModbusATxBuf[0] = ModbusASlaveID;
ModbusATxBuf[1] = ModbusATxBuf[1] + 0x00000080;
ModbusATxBuf[2] = ModbusAExceptionCode;
ModbusATxReady = ModbusACRC16(3, 0);
ModbusATxDataLength = 5;
}
int ModbusASerialRange(int address)
{
if ((address >= 0) && (address < MODBUSA_MAX_ADDR)) return 0; //read write enable
else return 1; //read only
}
void Init_ModbusA_Buffer()
{
memset(&ModbusARxBuf, 0, sizeof(ModbusARxBuf) / sizeof(int));
memset(&ModbusATxBuf, 0, sizeof(ModbusATxBuf) / sizeof(int));
}
#endif
//-------------------------ModbusB------------------------------------------------------//
#if (MODBUSB_ENB)
#define MODBUSB_RX_RDY ScibRegs.SCIRXST.bit.RXRDY
#define MODBUSB_RX_FIFO ScibRegs.SCIFFRX.bit.RXFFST
#define MODBUSB_RX_FIFO_RST ScibRegs.SCIFFRX.bit.RXFIFORESET
#define MODBUSB_RX_OVF ScibRegs.SCIFFRX.bit.RXFFOVF
#define MODBUSB_RX_OVFCLR ScibRegs.SCIFFRX.bit.RXFFOVRCLR
#define MODBUSB_RX_BUF ScibRegs.SCIRXBUF.bit.SAR
#define MODBUSB_RX_ERROR ScibRegs.SCIRXST.bit.RXERROR
#define MODBUSB_TX_RDY ScibRegs.SCICTL2.bit.TXRDY
#define MODBUSB_TX_FIFO ScibRegs.SCIFFTX.bit.TXFFST
#define MODBUSB_TX_BUF ScibRegs.SCITXBUF.bit.TXDT
#define MODBUSB_TX_EMTPY ScibRegs.SCICTL2.bit.TXEMPTY
#define MODBUSB_SWRESET ScibRegs.SCICTL1.bit.SWRESET = 0,\
ScibRegs.SCICTL1.all = 0x0023
#define MODBUSB_FIFO_RST ScibRegs.SCIFFTX.bit.SCIRST = 1;
//#define MODBUSB_RX_RDY ScidRegs.SCIRXST.bit.RXRDY
//#define MODBUSB_RX_FIFO ScidRegs.SCIFFRX.bit.RXFFST
//#define MODBUSB_RX_FIFO_RST ScidRegs.SCIFFRX.bit.RXFIFORESET
//#define MODBUSB_RX_OVF ScidRegs.SCIFFRX.bit.RXFFOVF
//#define MODBUSB_RX_OVFCLR ScidRegs.SCIFFRX.bit.RXFFOVRCLR
//
//#define MODBUSB_RX_BUF ScidRegs.SCIRXBUF.bit.SAR
//#define MODBUSB_RX_ERROR ScidRegs.SCIRXST.bit.RXERROR
//
//#define MODBUSB_TX_RDY ScidRegs.SCICTL2.bit.TXRDY
//#define MODBUSB_TX_FIFO ScidRegs.SCIFFTX.bit.TXFFST
//#define MODBUSB_TX_BUF ScidRegs.SCITXBUF.bit.TXDT
//#define MODBUSB_TX_EMTPY ScidRegs.SCICTL2.bit.TXEMPTY
//#define MODBUSB_SWRESET ScidRegs.SCICTL1.bit.SWRESET = 0,\
// ScidRegs.SCICTL1.all = 0x0023
//#define MODBUSB_FIFO_RST ScidRegs.SCIFFTX.bit.SCIRST = 1;
//---------------------------- Serial Modbus B set parameter RS485----------------------------------//
#define MODBUSB_LSPCLK (CPUCLK/4) // Peripheral Low Speed Clock for SCI-
#define MODBUSB_BAUDRATE 38400L
#define MODBUSB_BRR_VAL (MODBUSB_LSPCLK/(8*MODBUSB_BAUDRATE)-1) // MODBUSB BaudRate ���� Register ��
//16�� funccode�� 123�� ���� write ��ɽ� 231 ����Ʈ
#define MODBUSB_RECEIVE_MAX_BYTE 400
#define MODBUSB_RECEIVE_MIN_BYTE 2
#define MODBUSB_TRANS_MAX_BYTE 400
#define MODBUSB_START_ADDR 0
#define MODBUSB_MAX_ADDR 1500
unsigned int ModbusBSlaveID = 2;
unsigned int ModbusBRxCnt = 0, ModbusBRxOk = 0, ModbusBRxErr = 0, ModbusBTxReady = 0, ModbusBTxCnt = 0, ModbusBTxDataLength = 0;
unsigned int ModbusBCharTime = 0, ModbusBCnt = 0, ModbusBStop = 0, ModbusBCharTimeset = 8;
unsigned int ModbusBExceptionCode = 0;
unsigned char ModbusBRxBuf[MODBUSB_RECEIVE_MAX_BYTE];
unsigned char ModbusBTxBuf[MODBUSB_TRANS_MAX_BYTE];
unsigned int ModbusB_Connection_Check = 0;
unsigned int Flag_ModbusB_Data_reset = 0;
volatile void *ModbusBPtr[MODBUSBPTRMAX];
unsigned int ModbusBTxWaitCnt = 0;
unsigned int ModbusBFrmStartFlag = 0;
unsigned int ModbusBRxMaxFlag = 0;
unsigned int ModbusBRxStop = 0;
#endif
//--------------------------------------------------------------------------------------------------//
#if (MODBUSB_ENB)
void ModbusBCheckBuffer()
{
int kk = 0;
if (MODBUSB_RX_OVF == 0)
{
if (MODBUSB_RX_FIFO != 0)
{
if (ModbusBFrmStartFlag == 0)
{
ModbusBRxBuf[0] = MODBUSB_RX_BUF;
if (ModbusBRxBuf[0] == ModbusBSlaveID)
{
ModbusBFrmStartFlag = 1;
ModbusBRxCnt = 1;
}
}
else if (ModbusBFrmStartFlag == 1)
{
if (ModbusBRxCnt <= MODBUSB_RECEIVE_MAX_BYTE)
{
ModbusBRxBuf[ModbusBRxCnt++] = MODBUSB_RX_BUF;
}
else
{
ModbusBFrmStartFlag = 0;
ModbusBRxCnt = 0;
}
}
ModbusBCharTime = 0;
ModbusBStop = 0;
} //
else if (MODBUSB_RX_FIFO == 0)
{
if (ModbusBCharTime <= ModbusBCharTimeset) ModbusBCharTime++;
else if (ModbusBCharTime > ModbusBCharTimeset)
{
ModbusBCharTime = 0;
kk = ModbusBRxCnt;
ModbusBRxCnt = 0;
if (ModbusBFrmStartFlag == 1)
{
ModbusBCnt = kk;
if ((ModbusBRxBuf[0] == ModbusBSlaveID) && (ModbusBCnt >= 4))
{
if (ModbusBCRC16(ModbusBCnt - 2, 1)) // ���ŵ� ������ CRC check
{
//CRC ����
memcpy(&ModbusBTxBuf, &ModbusBRxBuf, ModbusBCnt);
ModbusBRxOk = 1;
}
}
}
ModbusBFrmStartFlag = 0;
}
}
}
else
{
MODBUSB_RX_OVFCLR = 1;
MODBUSB_RX_FIFO_RST = 0;
MODBUSB_RX_FIFO_RST = 1;
}
if (ModbusBTxReady == 1)
{
if (MODBUSB_TX_FIFO < 16)
{
if (ModbusBTxCnt < (ModbusBTxDataLength))
{
MODBUSB_TX_BUF = ModbusBTxBuf[ModbusBTxCnt];
ModbusBTxCnt++;
ModbusBTxWaitCnt = 0;
}
else
{
if (MODBUSB_TX_EMTPY == 1)
{
if (ModbusBTxWaitCnt++ > (ModbusBCharTimeset - 1))
{
ModbusBTxReady = 0;
ModbusBTxCnt = 0;
ModbusBTxWaitCnt = 0;
}
}
else
{
}
}
}
}
if (MODBUSB_RX_ERROR != 0) MODBUSB_SWRESET;
}
void ModbusBResponse() // 10msec routine�� ����
{
if (ModbusBRxOk == 1)
{
if (ModbusBCnt > MODBUSB_RECEIVE_MAX_BYTE)
{
ModbusBExceptionCode = 2;
ModbusBBadResponse(); //to many bytes in frame */
}
else if (ModbusBCnt < MODBUSB_RECEIVE_MIN_BYTE)
{
ModbusBExceptionCode = 2;
ModbusBBadResponse(); //to few bytes frame*/
}
else
{
if (ModbusBTxBuf[1] == 3) ModbusB3rdResponse();
else if (ModbusBTxBuf[1] == 4) ModbusB4thResponse();
else if (ModbusBTxBuf[1] == 6) ModbusB6thResponse();
else if (ModbusBTxBuf[1] == 16) ModbusB16thResponse();
else ModbusBBadResponse();
}
ModbusBRxOk = 0;
}
}
int ModbusBCRC16(int dataLength, int RXTXset) //CRC 16 for SERIAL checksum
{
//RXTXset : 0 TX CRC, 1 RX CRC
Uint16 lowCRC;
Uint16 highCRC;
Uint16 CRC;
Uint16 CRC_OK;
if (RXTXset == 1)
{
CRC = CRC16(ModbusBRxBuf, dataLength);
highCRC = (CRC >> 8) & 0x00FF;
lowCRC = (CRC & 0x00FF);
if (ModbusBRxBuf[dataLength + 1] == highCRC)
{
if (ModbusBRxBuf[dataLength] == lowCRC) CRC_OK = 1;
else CRC_OK = 0;
//for test
dInverter_Status++;
}
else CRC_OK = 0;
}
else if (RXTXset == 0)
{
CRC = CRC16(ModbusBTxBuf, dataLength);
highCRC = (CRC >> 8) & 0x00FF;
lowCRC = (CRC & 0x00FF);
ModbusBTxBuf[dataLength] = lowCRC;
ModbusBTxBuf[dataLength + 1] = highCRC;
CRC_OK = 1;
}
return CRC_OK;
}
void ModbusB3rdResponse() //response for ipos 03 function (read registers)
{
int j, temp_address, temp_length, *temp_data;
temp_address = ((ModbusBTxBuf[2] << 8) & 0x0ff00) + (ModbusBTxBuf[3] & 0x00ff);
temp_length = ModbusBTxBuf[5] & 0x00ff;
ModbusBTxBuf[2] = temp_length * 2;
for (j = 0; j < temp_length; j++)
{
temp_data = (int*) (ModbusBPtr[MODBUSB_START_ADDR + temp_address + j]); // ����address���� temp_length ��ŭ
ModbusBTxBuf[j * 2 + 3] = ((*temp_data & 0x0ff00) >> 8) & 0x00ff;
ModbusBTxBuf[j * 2 + 4] = (*temp_data & 0x00ff);
}
ModbusBTxReady = ModbusBCRC16(temp_length * 2 + 3, 0); //ADD+FUNC(2)+DATA
ModbusBTxDataLength = temp_length * 2 + 5;
}
void ModbusB4thResponse() //response for MODBUS 4 function read registers
{
int temp_address, temp_length, *temp_data, j;
temp_address = ((ModbusBTxBuf[2] << 8) & 0x0ff00) + (ModbusBTxBuf[3] & 0x0ff);
temp_length = ModbusBTxBuf[5] & 0xff;
ModbusBTxBuf[2] = temp_length * 2;
for (j = 0; j < temp_length; j++)
{
temp_data = (int*) (ModbusBPtr[MODBUSB_START_ADDR + temp_address + j]);
ModbusBTxBuf[j * 2 + 3] = ((*temp_data & 0x0ff00) >> 8) & 0xff;
ModbusBTxBuf[j * 2 + 4] = (*temp_data & 0xff);
}
ModbusBTxReady = ModbusBCRC16(temp_length * 2 + 3, 0); //ADD+FUNC(2)+DATA
ModbusBTxDataLength = temp_length * 2 + 5;
// ModbusTxDataLength=temp_length*2+7;
}
void ModbusB6thResponse() //response for MODBUS 3 function write single registers
{
int temp_address;
int temp_data;
int *ari1;
temp_address = (short) ((ModbusBTxBuf[2] << 8) & 0x0ff00) + (ModbusBTxBuf[3] & 0x0ff);
if (ModbusBSerialRange(temp_address) == 1) ModbusBExceptionCode = 2;
else
{
temp_data = (((ModbusBTxBuf[4] & 0xff) << 8) & 0xff00) + (ModbusBTxBuf[5] & 0xff);
ari1 = (int*) ModbusBPtr[MODBUSB_START_ADDR + temp_address];
if (temp_data > 32767) *ari1 = (temp_data | 0xffff0000);
else *ari1 = temp_data;
ModbusBTxReady = ModbusBCRC16(6, 0);
ModbusBTxDataLength = 8;
}
}
void ModbusB16thResponse() //response for MODBUS 16 function write multiple registers
{
int temp_address, temp_length, j;
register int temp_data;
int *ari1;
temp_address = ((ModbusBTxBuf[2] << 8) & 0x0ff00) + (ModbusBTxBuf[3] & 0x0ff);
temp_length = ModbusBTxBuf[5] & 0xff;
if (ModbusBSerialRange(temp_address + temp_length) == 1) ModbusBExceptionCode = 2;
else
{
for (j = 0; j < temp_length; j++)
{
temp_data = (((ModbusBTxBuf[7 + 2 * j] & 0xff) << 8) & 0xff00) + (ModbusBTxBuf[8 + 2 * j] & 0xff);
ari1 = (int*) ModbusBPtr[MODBUSB_START_ADDR + temp_address + j];
if (temp_data > 32767) *ari1 = (temp_data | 0xffff0000);
else *ari1 = temp_data;
}
}
ModbusBTxReady = ModbusBCRC16(6, 0);
ModbusBTxDataLength = 8;
}
void ModbusBBadResponse()
{
ModbusBTxBuf[0] = ModbusBSlaveID;
ModbusBTxBuf[1] = ModbusBTxBuf[1] + 0x00000080;
ModbusBTxBuf[2] = ModbusBExceptionCode;
ModbusBTxReady = ModbusBCRC16(3, 0);
ModbusBTxDataLength = 5;
}
int ModbusBSerialRange(int address)
{
if ((address >= 0) && (address < MODBUSB_MAX_ADDR)) return 0; //read write enable
else return 1; //read only
}
void Init_ModbusB_Buffer()
{
memset(&ModbusBRxBuf, 0, sizeof(ModbusBRxBuf) / sizeof(int));
memset(&ModbusBTxBuf, 0, sizeof(ModbusBTxBuf) / sizeof(int));
}
#endif
float Char3_5Time = 0.;
void InitModbusSci()
{
#if (MODBUSA_ENB)
ScicRegs.SCIFFTX.bit.SCIFFENA = 1; //FIFO Enable
ScicRegs.SCIFFTX.bit.TXFFIENA = 0; //FIFO Tx-Interrupt Disable
ScicRegs.SCIFFRX.bit.RXFFIENA = 0; //FIFO Rx-Interrupt Disable
ScicRegs.SCIFFTX.bit.TXFIFORESET = 1;
ScicRegs.SCIFFRX.bit.RXFIFORESET = 1;
ScicRegs.SCIFFCT.bit.FFTXDLY = 0;
//
ScicRegs.SCIFFTX.bit.SCIRST = 1;
ScicRegs.SCIFFCT.bit.ABDCLR = 1; // Clear ABD(Auto baud bit)
ScicRegs.SCICCR.all = 0x0007; // 1 stop bit, No loopback
// No parity,8 char bits,
// async mode, idle-line protocol
ScicRegs.SCICTL1.all = 0x0003; // enable TX, RX, internal SCICLK,
// Disable RX ERR, SLEEP, TXWAKE
// ScicRegs.SCICTL2.all = 0x0003;
// ScicRegs.SCICTL2.bit.RXBKINTENA = 1; // RX/BK INT ENA=1,
// ScicRegs.SCICTL2.bit.TXINTENA = 1; // TX INT ENA=1,
ScicRegs.SCIHBAUD.bit.BAUD = (MODBUSA_BRR_VAL >> 8);
ScicRegs.SCILBAUD.bit.BAUD = (MODBUSA_BRR_VAL & 0xFF);
ScicRegs.SCICTL1.all = 0x0023; // Relinquish SCI from Reset
Init_ModbusA_Buffer();
// 11bit per char
Char3_5Time = 1.0 / MODBUSA_BAUDRATE * 11 * 3.5;
if(Char3_5Time <= 1.75e-3 ) Char3_5Time = 1.75e-3;
//1.75ms 이하인 경우 1.75ms
ModbusACharTimeset = (unsigned int)(Char3_5Time / Tsamp);
#endif
#if(MODBUSB_ENB)
//-------------------------------------SCI-B----------------------------------------------------//
ScibRegs.SCIFFTX.bit.SCIFFENA = 1; //FIFO Enable
ScibRegs.SCIFFTX.bit.TXFFIENA = 0; //FIFO Tx-Interrupt Disable
ScibRegs.SCIFFRX.bit.RXFFIENA = 0; //FIFO Rx-Interrupt Disable
ScibRegs.SCIFFTX.bit.TXFIFORESET = 1;
ScibRegs.SCIFFRX.bit.RXFIFORESET = 1;
ScibRegs.SCIFFCT.bit.FFTXDLY = 0;
ScibRegs.SCIFFTX.bit.SCIRST = 1;
ScibRegs.SCIFFCT.bit.ABDCLR = 1; // Clear ABD(Auto baud bit)
ScibRegs.SCICCR.all = 0x0007; // 1 stop bit, No loopback
// No parity,8 char bits,
// async mode, idle-line protocol
ScibRegs.SCICTL1.all = 0x0003; // enable TX, RX, internal SCICLK,
ScibRegs.SCIHBAUD.bit.BAUD = (MODBUSB_BRR_VAL >> 8);
ScibRegs.SCILBAUD.bit.BAUD = (MODBUSB_BRR_VAL & 0xFF);
ScibRegs.SCICTL1.all = 0x0023; // Relinquish SCI from Reset
//-------------------------------------SCI-D----------------------------------------------------//
// ScidRegs.SCIFFTX.bit.SCIFFENA = 1; //FIFO Enable
//
// ScidRegs.SCIFFTX.bit.TXFFIENA = 0; //FIFO Tx-Interrupt Disable
// ScidRegs.SCIFFRX.bit.RXFFIENA = 0; //FIFO Rx-Interrupt Disable
// ScidRegs.SCIFFTX.bit.TXFIFORESET = 1;
// ScidRegs.SCIFFRX.bit.RXFIFORESET = 1;
// ScidRegs.SCIFFCT.bit.FFTXDLY = 0;
// //
// ScidRegs.SCIFFTX.bit.SCIRST = 1;
//
// ScidRegs.SCIFFCT.bit.ABDCLR = 1; // Clear ABD(Auto baud bit)
//
// ScidRegs.SCICCR.all = 0x0007; // 1 stop bit, No loopback
// // No parity,8 char bits,
// // async mode, idle-line protocol
// ScidRegs.SCICTL1.all = 0x0003; // enable TX, RX, internal SCICLK,
//
// ScidRegs.SCIHBAUD.bit.BAUD = (MODBUSB_BRR_VAL >> 8);
// ScidRegs.SCILBAUD.bit.BAUD = (MODBUSB_BRR_VAL & 0xFF);
//
// ScidRegs.SCICTL1.all = 0x0023; // Relinquish SCI from Reset
Init_ModbusB_Buffer();
Char3_5Time = 1.0 / MODBUSB_BAUDRATE * 11 * 3.5;
if(Char3_5Time <= 1.75e-3 ) Char3_5Time = 1.75e-3;
//char 타임자동계산
ModbusBCharTimeset = (unsigned int)(Char3_5Time / Tsamp);
#endif
InitModbusPtr();
}
//-------------------------ModbusA/B ���� �Լ�--------------------------------------//
void ModbusALLCheckBuffer()
{
#if(MODBUSA_ENB)
ModbusACheckBuffer();
#endif
#if(MODBUSB_ENB)
ModbusBCheckBuffer();
#endif
}
void ModbusALLResponse()
{
#if(MODBUSA_ENB)
ModbusAResponse();
#endif
#if(MODBUSB_ENB)
ModbusBResponse();
#endif
}
void InitSci()
{
// SCI_setConfig(SCID_BASE, DEVICE_LSPCLK_FREQ, 9600, (SCI_CONFIG_WLEN_8 | SCI_CONFIG_STOP_ONE | SCI_CONFIG_PAR_NONE));
// SCI_resetChannels(SCID_BASE);
// SCI_resetRxFIFO(SCID_BASE);
// SCI_resetTxFIFO(SCID_BASE);
// SCI_clearInterruptStatus(SCID_BASE, SCI_INT_TXFF | SCI_INT_RXFF);
// SCI_enableFIFO(SCID_BASE);
// SCI_enableModule(SCID_BASE);
// SCI_performSoftwareReset(SCID_BASE);
ScidRegs.SCIFFTX.bit.SCIFFENA = 1; //FIFO Enable
ScidRegs.SCIFFTX.bit.TXFFIENA = 0; //FIFO Tx-Interrupt Disable
ScidRegs.SCIFFRX.bit.RXFFIENA = 0; //FIFO Rx-Interrupt Disable
ScidRegs.SCIFFTX.bit.TXFIFORESET = 1;
ScidRegs.SCIFFRX.bit.RXFIFORESET = 1;
ScidRegs.SCIFFCT.bit.FFTXDLY = 0;
//
ScidRegs.SCIFFTX.bit.SCIRST = 1;
ScidRegs.SCIFFCT.bit.ABDCLR = 1; // Clear ABD(Auto baud bit)
ScidRegs.SCICCR.all = 0x0007; // 1 stop bit, No loopback
// No parity,8 char bits,
// async mode, idle-line protocol
ScidRegs.SCICTL1.all = 0x0003; // enable TX, RX, internal SCICLK,
// Disable RX ERR, SLEEP, TXWAKE
// ScicRegs.SCICTL2.all = 0x0003;
// ScicRegs.SCICTL2.bit.RXBKINTENA = 1; // RX/BK INT ENA=1,
// ScicRegs.SCICTL2.bit.TXINTENA = 1; // TX INT ENA=1,
ScidRegs.SCIHBAUD.bit.BAUD = (MODBUSA_BRR_VAL >> 8);
ScidRegs.SCILBAUD.bit.BAUD = (MODBUSA_BRR_VAL & 0xFF);
ScidRegs.SCICTL1.all = 0x0023; // Relinquish SCI from Reset
}