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

📄 soc_hdlc.c

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