📄 soc_hdlc.c
字号:
received and are now
available in the RFIFO.
The message is not complete. */
if (rpf != 0x00)
{
reccnt = buflen;
}
/* RME interrupt:
Receive message end. The RFIFO
contains a complete frame or
the last bytes of a frame */
else
{
/* Get the number of received bytes */
reccnt = ((In(SOCRATES_RBCH_BZ) & 0x0F) << 8) | (In(SOCRATES_RBCL_BZ) & 0xFF);
/* Modulo 33 functionality.
'reccnt' now contains the
number of bytes actually
received. */
if (reccnt)
{
reccnt &= (buflen-1);
if (!reccnt) reccnt = buflen;
}
}
/* Check if SOCRATES is already
working in receive direction
(the flag STATE_RX_ACTIVE
is set after the first RPF
or RME is detected). */
/* SOCRATES works not in receive
direction: received bytes
belong to a new frame. */
if (!(G_Hdlc.State & STATE_RX_ACTIVE))
{
/* If there is something to
receive: allocate memory */
if (reccnt > 0)
{
G_Hdlc.Rx_Curr = 0;
}
G_Hdlc.State |= STATE_RX_ACTIVE;
G_Hdlc.Rx_Cnt = reccnt;
}
/* SOCRATES works already in receive
direction: received bytes
belong to an old frame. */
else
{
/* This counter contains the
bytes which have been
received. */
G_Hdlc.Rx_Cnt += reccnt;
}
/* Read the bytes from the RFIFO
and update buffer pointer. */
if (reccnt)
{
if (G_Hdlc.Rx_Curr + reccnt < HDLC_RX_BUF_SIZE)
{
Soc_Read_Fifo(reccnt, &(G_Hdlc.Rx_Buffer[G_Hdlc.Rx_Curr]));
G_Hdlc.Rx_Curr += reccnt;
}
else
{
Soc_Hdlc_Reset(HDLC_RX);
V24_PRINT (("\n(SLOT %d) HDLC receive buffer overflow - ignoring data!", SLOT_NR));
return;
}
}
/* Give RMC Command to confirm
that data is fetched and
RFIFO can be released. */
Out(SOCRATES_CMD_BZ, SOCRATES_CMD_BZ_RMC);
/* RPF interrupt: no more actions */
if (rpf)
{
BFLD (SOCRATES_ISTA_BZ, SOCRATES_ISTA_BZ_RPF, 0x00);
return;
}
/* Report successful reception
to the user. */
if (G_Soc_Hdlc_En == 0x01)
{
Soc_Int_Fifo_Put (HDLC_RX_INT, 0);
}
BFLD (SOCRATES_ISTA_BZ, SOCRATES_ISTA_BZ_RME|SOCRATES_ISTA_BZ_RPF, 0x00);
}
/*******************************************************************************
Description:
Reports that a HDLC error has happened.
Arguments:
reg - register content which indicated error type
Return Value:
none
*******************************************************************************/
void Soc_Hdlc_Error_Interrupt (WORD8 reg)
{
/* Transmit data underrun error. */
if ((reg & SOCRATES_ISTA_BZ_XDU) == SOCRATES_ISTA_BZ_XDU)
{
Soc_Hdlc_Reset (HDLC_TX);
G_Hdlc.Tx_Error |= 0x02;
}
/* Receive frame overflow error. */
if ((reg & SOCRATES_ISTA_BZ_RFO) == SOCRATES_ISTA_BZ_RFO)
{
Soc_Hdlc_Reset (HDLC_RX);
G_Hdlc.Rx_Error |= 0x01;
}
/* Report indication to user. */
Soc_Int_Fifo_Put (HDLC_ERROR_INT, (G_Hdlc.Tx_Error<<8) | G_Hdlc.Rx_Error);
G_Hdlc.Rx_Error = 0x00;
G_Hdlc.Tx_Error = 0x00;
BFLD (SOCRATES_ISTA_BZ, SOCRATES_ISTA_BZ_XDU|SOCRATES_ISTA_BZ_RFO, 0x00);
}
/*******************************************************************************
Description:
Received HDLC transmit ready from SOCRATES is sent to PC.
Arguments:
none
Return Value:
none
*******************************************************************************/
void Soc_Hdlc_Transmit_Ind (void)
{
P_DDS_MSG pMsg;
/* Send V24INT control messages
to serial interface. */
V24_PRINT (("\n(SLOT %d) i_Socrates_Hdlc_Transmit", SLOT_NR));
/* Check if message is available. */
if (DdsMsgGetNum () > 3)
{
/* Send message to user. */
pMsg = DdsMsgAlloc(0);
pMsg->dst = 0;
pMsg->src = MOD_ID_SOCRATES_MODULE;
pMsg->id = MSG_ID_SOCRATES_HDLC_BZ_TRANSMIT_IN;
pMsg->length = 0;
DdsMsgSend (pMsg);
}
else
{
V24_PRINT ((" Error allocating message"));
}
Soc_Reset_Transmit_Var();
}
/*******************************************************************************
Description:
HDLC data receive from SOCRATES is send to PC.
Arguments:
nr - number of data bytes
*data - pointer to data bytes
Return Value:
none
*******************************************************************************/
void Soc_Hdlc_Receive_Ind (void)
{
P_DDS_MSG pMsg;
WORD8 i;
/* Send V24INT control messages
to serial interface. */
V24_PRINT (("\n(SLOT %d) i_Socrates_Hdlc_Receive: ", SLOT_NR));
V24_PRINT (("DATA="));
for (i = 0;i < G_Hdlc.Rx_Cnt; i++)
V24_PRINT (("0x%02X,", G_Hdlc.Rx_Buffer[i]));
/* Check if message is available. */
if (DdsMsgGetNum () > 3)
{
/* Send message to user. */
pMsg = DdsMsgAlloc(G_Hdlc.Rx_Cnt+1);
MsgWriteWord8 (pMsg, 0, G_Hdlc.Rx_Cnt);
for (i = 0;i < G_Hdlc.Rx_Cnt; i++)
MsgWriteWord8 (pMsg, 1+i, G_Hdlc.Rx_Buffer[i]);
pMsg->dst = 0;
pMsg->src = MOD_ID_SOCRATES_MODULE;
pMsg->id = MSG_ID_SOCRATES_HDLC_BZ_RECEIVE_IN;
pMsg->length = G_Hdlc.Rx_Cnt+1;
DdsMsgSend (pMsg);
}
else
{
V24_PRINT ((" Error allocating message"));
}
/* Reset variables for next HDLC
reception. */
Soc_Reset_Receive_Var();
}
/*******************************************************************************
Description:
Received HDLC error from SOCRATES is send to PC.
Arguments:
tr - HDLC error type in transmit direction
rec - HDLC error type in receive direction
Return Value:
none
*******************************************************************************/
void Soc_Hdlc_Error_Ind (WORD8 tr, WORD8 rec)
{
P_DDS_MSG pMsg;
/* Send V24INT control messages
to serial interface. */
V24_PRINT (("\n(SLOT %d) i_Socrates_Hdlc_Error: ", SLOT_NR));
V24_PRINT (("TR=0x%02X,REC=0x%02X", tr, rec));
/* Check if message is available. */
if (DdsMsgGetNum () > 3)
{
/* Send message to user. */
pMsg = DdsMsgAlloc(2);
MsgWriteWord8 (pMsg, 0, tr);
MsgWriteWord8 (pMsg, 1, rec);
pMsg->dst = 0;
pMsg->src = MOD_ID_SOCRATES_MODULE;
pMsg->id = MSG_ID_SOCRATES_HDLC_BZ_ERROR_IN;
pMsg->length = 2;
DdsMsgSend (pMsg);
}
else
{
V24_PRINT ((" Error allocating message"));
}
}
/* ============================= */
/* Local function definition */
/* ============================= */
/*******************************************************************************
Description:
Reads data bytes from the HDLC FIFO.
Arguments:
cnt - number of bytes to be read
buffer - pointer to buffer for first data byte
Return Value:
none
*******************************************************************************/
static void Soc_Read_Fifo(WORD8 cnt, WORD8* buffer)
{
while (cnt--)
{
*buffer++ = In(SOCRATES_RFIFO_BZ);
}
}
/*******************************************************************************
Description:
Fills the HDLC buffer with data bytes.
Arguments:
cnt - number of bytes to be written
buffer - pointer to first data byte
Return Value:
none
*******************************************************************************/
static void Soc_Write_Fifo(WORD8 cnt, WORD8* buffer)
{
while (cnt--)
{
Out(SOCRATES_XFIFO_BZ, *buffer++);
}
}
/*******************************************************************************
Description:
Sets channels FIFO size in the HDLC structure.
Arguments:
none
Return Value:
none
*******************************************************************************/
static void Soc_Set_Fifo_Size(void)
{
WORD8 size;
/* Check size and set buffer. */
size = ((In(SOCRATES_EXM_BZ) & 0x60) >> 5);
size = 0x40 >> size;
G_Hdlc.Rx_Bufsize = size;
/* Check size and set buffer. */
size = ((In(SOCRATES_EXM_BZ) & 0x80) >> 7);
size = 0x40 >> size;
G_Hdlc.Tx_Bufsize = size;
}
/*******************************************************************************
Description:
Resets all variables for HDLC receive direction.
Arguments:
none
Return Value:
none
*******************************************************************************/
static void Soc_Reset_Receive_Var(void)
{
G_Hdlc.Rx_Curr = 0;
G_Hdlc.Rx_Cnt = 0;
G_Hdlc.State &= ~STATE_RX_ACTIVE;
}
/*******************************************************************************
Description:
Resets all variables for HDLC transmit direction.
Arguments:
none
Return Value:
none
*******************************************************************************/
static void Soc_Reset_Transmit_Var(void)
{
G_Hdlc.Tx_Cnt = 0;
G_Hdlc.Tx_Curr = 0;
G_Hdlc.State &= ~STATE_TX_ACTIVE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -