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

📄 soc_hdlc.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_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 + -