⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 soc_eoc.c

📁 Infineon公司有一款实现SHDSL协议(ADSL协议的变种)的芯片
💻 C
📖 第 1 页 / 共 2 页
字号:
/*******************************************************************************
       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 + -