📄 soc_eoc.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_EOC
Product ID: 22622.1.0.1
Description: Contains HDLC EOC controller handling of SOCRATES.
******************************************************************************/
// Group= SOC_EOC
/* ============================= */
/* 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_E_TRANSMIT_IN 21
#define MSG_ID_SOCRATES_HDLC_E_RECEIVE_IN 23
#define MSG_ID_SOCRATES_HDLC_E_ERROR_IN 24
#define EOC_RX 1
#define EOC_TX 2
#define STATE_TX_ACTIVE 0x01
#define STATE_RX_ACTIVE 0x02
#define STATE_TX_RESET 0x04
/* ============================= */
/* Global variable definition */
/* ============================= */
T_EOC G_Eoc;
/* ============================= */
/* 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_Reset_Receive_Var(void);
static void Soc_Reset_Transmit_Var(void);
/* ============================= */
/* Global function definition */
/* ============================= */
void Soc_Eoc_Transmit_Ind (void);
void Soc_Eoc_Receive_Ind (void);
void Soc_Eoc_Error_Ind (void);
/*******************************************************************************
Description:
Initialize variables for HDLC-EOC part of SOCRATES.
Arguments:
none
Return Value:
none
Remarks:
none
*******************************************************************************/
void Soc_Eoc_Init (void)
{
G_Eoc.Tx_Bufsize = 0x4b;
Soc_Reset_Receive_Var ();
Soc_Reset_Transmit_Var ();
}
/*******************************************************************************
Description:
Reset HDLC-EOC part of SOCRATES and internal variables.
Arguments:
res - defines kind of reset:
0x01: reset HDLC-EOC receive direction
0x02: reset HDLC-EOC transmit direction
0x03: reset both HDLC-EOC receive and transmit direction
Return Value:
none
Remarks:
none
*******************************************************************************/
void Soc_Eoc_Reset (WORD8 res)
{
Disable_Interrupt(INT_SOCRATES);
/* Reset receive direction. */
if ((res & EOC_RX) == EOC_RX)
{
/* Reset FIFO */
BFLD (SOCRATES_CMD_E, 0x00, SOCRATES_CMD_E_RRES_E);
/* wait for acknowledge */
WHILE_NOT_ABORT (!(In(SOCRATES_STAT_E) & SOCRATES_STAT_E_RRESA_E));
/* take back reset */
BFLD (SOCRATES_CMD_E, SOCRATES_CMD_E_RRES_E, 0x00);
BFLD (SOCRATES_ISTA_E, (SOCRATES_ISTA_E_RPF_E|SOCRATES_ISTA_E_RFO_E), 0x00);
Soc_Reset_Receive_Var();
}
/* Reset transmit direction. */
if ((res & EOC_TX) == EOC_TX)
{
/* Reset FIFO */
BFLD (SOCRATES_CMD_E, 0x00, SOCRATES_CMD_E_XRES_E);
/* wait for acknowledge */
WHILE_NOT_ABORT (!(In(SOCRATES_STAT_E) & SOCRATES_STAT_E_XRESA_E));
/* take back reset */
BFLD (SOCRATES_CMD_E, SOCRATES_CMD_E_XRES_E, 0x00);
BFLD (SOCRATES_ISTA_E, (SOCRATES_ISTA_E_XPR_E|SOCRATES_ISTA_E_XDU_E|SOCRATES_ISTA_E_XDOV_E), 0x00);
Soc_Reset_Transmit_Var();
}
Enable_Interrupt(INT_SOCRATES);
}
/*******************************************************************************
Description:
Starts transmission of a HDLC-EOC frame. If the count of data is larger than
the FIFO size, the rest of the frame is sent by 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 -2 if last
transmission is still running and value 1 if everything is ok.
Remarks:
none
*******************************************************************************/
int Soc_Eoc_Transmit(WORD16 cnt, WORD8 *data)
{
WORD8 cmd = 0;
/* Disable interrupts. */
Disable_Interrupt(INT_SOCRATES);
/* Return if XFIFO is not write
enable or if transmit path still
blocked */
if (G_Eoc.State & STATE_TX_ACTIVE) /* already one transmission active */
{
Enable_Interrupt(INT_SOCRATES);
return (-2);
}
/* Set pointer to message which has to
be transmitted: Transmitter
is now active */
G_Eoc.State |= STATE_TX_ACTIVE;
G_Eoc.Tx_Curr = 0;
memcpy (G_Eoc.Tx_Buffer, data, cnt);
/* If the number of bytes is <=
BUFFER_LENGTH the frame can be
shifted completely into the FIFO */
if (cnt <= (WORD16) G_Eoc.Tx_Bufsize)
{
Soc_Write_Fifo (cnt, &(G_Eoc.Tx_Buffer[0]));
/* set MsgEnd */
cmd = SOCRATES_XBC_E_XME_E;
G_Eoc.Tx_Curr = cnt;
G_Eoc.Tx_Cnt = cnt - 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_Eoc.Tx_Bufsize, &(G_Eoc.Tx_Buffer[0]));
G_Eoc.Tx_Cnt = cnt - G_Eoc.Tx_Bufsize;
G_Eoc.Tx_Curr = G_Eoc.Tx_Bufsize;
}
/* Output length and MsgEnd */
cmd |= G_Eoc.Tx_Curr;
Out (SOCRATES_XBC_E, cmd);
/* first block needs no XPR_E ! */
Enable_Interrupt(INT_SOCRATES);
return(1);
}
/*******************************************************************************
Description:
Handle HDLC-EOC transmitter interrupts. Especially continues transmission
of messages larger than one FIFO block.
Arguments:
none
Return Value:
none
Remarks:
none
*******************************************************************************/
void Soc_Eoc_Transmit_Interrupt (void)
{
WORD8 buflen;
WORD16 cnt;
/* Transmit byte counter is 0:
Either there was an HDLC-EOC
controller reset or the last
transmission was finished. */
if ((cnt = G_Eoc.Tx_Cnt) == 0)
{
if (G_Eoc.State & STATE_TX_ACTIVE)
{
/* Report successful transmission
to the user. */
Soc_Int_Fifo_Put (EOC_TX_INT, 0);
}
/* 0 byte to send */
Out (SOCRATES_XBC_E, 0x00);
/* reset XPR_E */
BFLD (SOCRATES_ISTA_E, SOCRATES_ISTA_E_XPR_E, 0x00);
}
/* 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_Eoc.Tx_Bufsize;
if (cnt <= (WORD16) buflen)
{
Soc_Write_Fifo (cnt, &(G_Eoc.Tx_Buffer[G_Eoc.Tx_Curr]));
/* write size and MsgEnd */
Out (SOCRATES_XBC_E, SOCRATES_XBC_E_XME_E | cnt);
/* Reset TransmitPoolReady */
BFLD (SOCRATES_ISTA_E, SOCRATES_ISTA_E_XPR_E, 0x00);
G_Eoc.Tx_Cnt = 0;
}
/* More than BUFFER_LENGTH bytes
are left to be sent; write
BUFFER_LENGTH into the XFIFO */
else
{
Soc_Write_Fifo(buflen, &(G_Eoc.Tx_Buffer[G_Eoc.Tx_Curr]));
/* write size */
Out (SOCRATES_XBC_E, buflen);
/* Reset TransmitPoolReady */
BFLD (SOCRATES_ISTA_E, SOCRATES_ISTA_E_XPR_E, 0x00);
G_Eoc.Tx_Curr += buflen;
G_Eoc.Tx_Cnt -= buflen;
}
}
}
/*******************************************************************************
Description:
Handle HDLC-EOC receiver interrupts. All received FIFO blocks are taken in a
buffer and given to Soc_Eoc_Receive_Ind for printout if last block
was received.
Arguments:
none
Return Value:
none
Remarks:
none
*******************************************************************************/
void Soc_Eoc_Receive_Interrupt (void)
{
WORD16 reccnt = 0;
WORD8 lastblock;
/* reccnt bytes have been
received and are now
available in the RFIFO. */
reccnt = In (SOCRATES_RBC_E) & ~0x80;
lastblock = In (SOCRATES_RBC_E) & 0x80;
/* Check if SOCRATES is already
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -