📄 soc_hdlc.c
字号:
/*******************************************************************************
Copyright (c) 2000, Infineon Technologies. All rights reserved.
No Warranty
Because the program is licensed free of charge, there is no warranty for
the program, to the extent permitted by applicable law. Except when
otherwise stated in writing the copyright holders and/or other parties
provide the program "as is" without warranty of any kind, either
expressed or implied, including, but not limited to, the implied
warranties of merchantability and fitness for a particular purpose. The
entire risk as to the quality and performance of the program is with
you. should the program prove defective, you assume the cost of all
necessary servicing, repair or correction.
In no event unless required by applicable law or agreed to in writing
will any copyright holder, or any other party who may modify and/or
redistribute the program as permitted above, be liable to you for
damages, including any general, special, incidental or consequential
damages arising out of the use or inability to use the program
(including but not limited to loss of data or data being rendered
inaccurate or losses sustained by you or third parties or a failure of
the program to operate with any other programs), even if such holder or
other party has been advised of the possibility of such damages.
*******************************************************************************
Module: SOC_HDLC
Product ID: 22622.1.0.1
Description: Contains HDLC controller handling of SOCRATES.
******************************************************************************/
// Group= SOC_HDLC
/* ============================= */
/* Includes */
/* ============================= */
#include <stdio.h>
#include <intrins.h>
#include <stdlib.h>
#include <string.h>
#include "sysdef.h"
#include "dds.h"
#include "sysvar.h"
#include "sysfunc.h"
#include "modid.h"
#include "reg165.h"
/* ============================= */
/* Local Macros & Definitions */
/* ============================= */
#define MSG_ID_SOCRATES_HDLC_BZ_TRANSMIT_IN 3
#define MSG_ID_SOCRATES_HDLC_BZ_RECEIVE_IN 4
#define MSG_ID_SOCRATES_HDLC_BZ_ERROR_IN 5
#define HDLC_RX 1
#define HDLC_TX 2
#define STATE_TX_ACTIVE 0x01
#define STATE_RX_ACTIVE 0x02
#define STATE_TX_RESET 0x04
#define HDLC_REC_DISABLE 0x00
#define HDLC_REC_ENABLE 0x01
#define HDLC_RFIFO_64BYTE 0x00
#define HDLC_RFIFO_32BYTE 0x01
#define HDLC_RFIFO_16BYTE 0x02
#define HDLC_RFIFO_8BYTE 0x03
#define HDLC_TFIFO_64BYTE 0x00
#define HDLC_TFIFO_32BYTE 0x01
/* ============================= */
/* Global variable definition */
/* ============================= */
WORD8 G_Soc_Hdlc_En;
WORD8 G_Soc_Hdlc_Rfifo;
WORD8 G_Soc_Hdlc_Tfifo;
T_EOC G_Hdlc;
/* ============================= */
/* Local variable definition */
/* ============================= */
/* ============================= */
/* Local function declaration */
/* ============================= */
static void Soc_Read_Fifo(WORD8 cnt, WORD8* buffer);
static void Soc_Write_Fifo(WORD8 cnt, WORD8* buffer);
static void Soc_Set_Fifo_Size(void);
static void Soc_Reset_Receive_Var(void);
static void Soc_Reset_Transmit_Var(void);
/* ============================= */
/* Global function definition */
/* ============================= */
/*******************************************************************************
Description:
Init HDLC part of SOCRATES and HDLC Variables
Arguments:
none
Return Value:
none
*******************************************************************************/
void Soc_Hdlc_Init (void)
{
G_Soc_Hdlc_En = HDLC_REC_ENABLE;
G_Soc_Hdlc_Rfifo = HDLC_RFIFO_64BYTE;
G_Soc_Hdlc_Tfifo = HDLC_TFIFO_64BYTE;
Soc_Hdlc_Reset(HDLC_RX);
Soc_Hdlc_Reset(HDLC_TX);
}
/*******************************************************************************
Description:
Reset HDLC part of SOCRATES
Arguments:
res - defines kind of reset:
0x01: reset HDLC receive direction
0x02: reset HDLC transmit direction
0x03: reset both HDLC receive and transmit direction
Return Value:
none
*******************************************************************************/
void Soc_Hdlc_Reset (WORD8 res)
{
Disable_Interrupt(INT_SOCRATES);
/* Reset receive direction. */
if ((res & HDLC_RX) == HDLC_RX)
{
Out(SOCRATES_CMD_BZ, SOCRATES_CMD_BZ_RMC | SOCRATES_CMD_BZ_RRES);
Soc_Reset_Receive_Var();
}
/* Reset transmit direction. */
if ((res & HDLC_TX) == HDLC_TX)
{
Out(SOCRATES_CMD_BZ, SOCRATES_CMD_BZ_XRES);
Soc_Reset_Transmit_Var();
G_Hdlc.State |= STATE_TX_RESET;
}
Enable_Interrupt(INT_SOCRATES);
}
/*******************************************************************************
Description:
Starts transmission of a HDLC frame. If the count of data is larger then
the FIFO size, the rest of the frame is sent in the interrupt routine.
Arguments:
cnt - number of bytes to be transmitted
data - pointer to data bytes to be transmitted
Return Value:
Returns value -1 if SOCRATES is not ready for transmission, value -1 if last
transmission is still running and value 1 if everything is ok.
*******************************************************************************/
int Soc_Hdlc_Transmit(WORD8 cnt, WORD8 *data)
{
WORD8 cmd = 0;
BIT ready;
/* Disable interrupts. */
Disable_Interrupt(INT_SOCRATES);
ready = FALSE;
/* Set FIFO size and check if
SOCRATES is ready. */
Soc_Set_Fifo_Size();
ready = ((In(SOCRATES_STAT_BZ) & SOCRATES_STAT_BZ_XFW) == SOCRATES_STAT_BZ_XFW);
/* Return if XFIFO is not write
enable or if transmit path still
blocked */
if (!ready)
{
Enable_Interrupt(INT_SOCRATES);
return (-1);
}
if (G_Hdlc.State & STATE_TX_ACTIVE)
{
Enable_Interrupt(INT_SOCRATES);
return (-2);
}
/* Set pointer to message which has to
be transmitted: Transmitter
is now active */
G_Hdlc.State |= STATE_TX_ACTIVE;
G_Hdlc.Tx_Curr = 0;
memcpy (G_Hdlc.Tx_Buffer, data, cnt);
/* If the number of bytes is <=
BUFFER_LENGTH the frame can be
shifted completely into the FIFO */
if (cnt <= G_Hdlc.Tx_Bufsize)
{
Soc_Write_Fifo (cnt, &(G_Hdlc.Tx_Buffer[0]));
G_Hdlc.Tx_Cnt = 0;
G_Hdlc.Tx_Curr = cnt;
}
/* If the number of bytes is >
BUFFER_LENGTH the first
BUFFER_LENGTH bytes are shifted
into the XFIFO. The interrupt
service routine handles the rest */
else
{
Soc_Write_Fifo (G_Hdlc.Tx_Bufsize, &(G_Hdlc.Tx_Buffer[0]));
G_Hdlc.Tx_Cnt = cnt - G_Hdlc.Tx_Bufsize;
G_Hdlc.Tx_Curr = G_Hdlc.Tx_Bufsize;
}
/* The 'transmit transparent frame'
command (XTF) must be used
in transparent mode. */
cmd = SOCRATES_CMD_BZ_XTF;
/* When the frame fits completely
into the XFIFO the XME command
must be given */
if (!G_Hdlc.Tx_Cnt)
cmd |= SOCRATES_CMD_BZ_XME;
/* Output command byte to CMDR */
Out(SOCRATES_CMD_BZ, cmd);
Enable_Interrupt(INT_SOCRATES);
return(1);
}
/*******************************************************************************
Description:
Handle HDLC transmitter interrupts.
Arguments:
none
Return Value:
none
*******************************************************************************/
void Soc_Hdlc_Transmit_Interrupt (void)
{
WORD8 cnt, buflen;
/* Transmit byte counter is 0:
Either there was an HDLC
controller reset or the last
transmission was finished. */
if ((cnt = G_Hdlc.Tx_Cnt) == 0)
{
/* HDLC controller reset command
given previously ?
Do nothing when it was a HDLC
controller reset. Only the
indicating flag must be cleared */
if (G_Hdlc.State & STATE_TX_RESET)
{
G_Hdlc.State &= ~STATE_TX_RESET;
}
/* XPR was generated because the
last transmission is finished */
else
{
/* Report successful reception
to the user. */
Soc_Int_Fifo_Put (HDLC_TX_INT, 0);
/* Reset variables for next HDLC
transmission. */
}
}
/* Transmit counter is not 0:
more data is to be sent ! */
else
{
/* If there are less than FIFO size
bytes left, they all can be
shifted completely into the
XFIFO. The XME command can
be issued. */
buflen = G_Hdlc.Tx_Bufsize;
if (cnt <= buflen)
{
Soc_Write_Fifo(cnt, &(G_Hdlc.Tx_Buffer[G_Hdlc.Tx_Curr]));
G_Hdlc.Tx_Cnt = 0;
Out (SOCRATES_CMD_BZ, SOCRATES_CMD_BZ_XTF | SOCRATES_CMD_BZ_XME);
}
/* More than BUFFER_LENGTH bytes
are left to be sent; write
BUFFER_LENGTH into the XFIFO */
else
{
Soc_Write_Fifo (buflen, &(G_Hdlc.Tx_Buffer[G_Hdlc.Tx_Curr]));
/* Give the transmit command.
Update current buffer pointer
and counter for remaining
bytes. */
Out(SOCRATES_CMD_BZ, SOCRATES_CMD_BZ_XTF);
G_Hdlc.Tx_Curr += buflen;
G_Hdlc.Tx_Cnt -= buflen;
}
}
BFLD (SOCRATES_ISTA_BZ, SOCRATES_ISTA_BZ_XPR, 0x00);
}
/*******************************************************************************
Description:
Handle HDLC receiver interrupts.
Arguments:
rpf - Specifies whether the receive pool is full or the message is end.
Return Value:
none
*******************************************************************************/
void Soc_Hdlc_Receive_Interrupt (WORD8 rpf )
{
WORD16 reccnt = 0;
WORD8 buflen;
/* SOCRATES works not in receive
direction: set FIFO size. */
if (!(G_Hdlc.State & STATE_RX_ACTIVE))
Soc_Set_Fifo_Size();
buflen = G_Hdlc.Rx_Bufsize;
/* BUFFER_LENGTH bytes have been
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -