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

📄 dc550_modemcontroller.c

📁 一款经典的数字电话设计资料
💻 C
字号:
/*****************************************************************************/
/*  CONFIDENTIAL                                                             */
/*  Sigpro Copyright 2003, All rights reserved                               */
/*****************************************************************************/
/*  CLIENT:  Telematrix                                                      */
/*  PROJECT: DC550 Digital Centrex Phone                                     */
/*  FILE:    dc550_modemcontroller.c                                         */
/*****************************************************************************/
/*  The Modem Controller is responsible for handling transport-layer tasks   */
/*  and moderating interaction between the Modem and the Controller.         */
/*****************************************************************************/

#define DC550_MODEMCONTROLLER_EXTERN
#include "dc550_modemcontroller.h"
#include "dc550_interrupt.h"
#include "dc550_controller.h"

#include "dc550_usartdriver.h"

#define TELEPHONE                 1

/******************************************************************************
 *  CONSTANTS
 *****************************************************************************/
#define DIAGMODE_XMIT_QUEUE_SIZE  2

/******************************************************************************
 *  GLOBAL VARIABLES
 *****************************************************************************/
DC550MDCMessage modemcontroller_messages[MODEMCONTROLLER_QUEUESIZE];
DC550CommandIndex modemcontroller_beginindex;
DC550CommandIndex modemcontroller_numberofmessages;

/******************************************************************************
 *  STATIC VARIABLES
 *****************************************************************************/
static DC550MDCMessage queued_msgs_for_xmit[DIAGMODE_XMIT_QUEUE_SIZE];
static int queued_msgs_for_xmit_idx;
static int queued_msgs_for_xmit_cnt;
static BOOL echoMode;
static int total_rx_msgs;

/******************************************************************************
 *  STATIC FUNCTION: void unload_queued_for_xmit_msgs(void)
 ******************************************************************************
 *  DESCRIPTION:
 *  This function is for use by the modem controller module only.
 *  This routine will take the last N messages that were sent by
 *  the software controller while the modem was in diagnostic mode
 *  and queue them up to be sent by the transmit modem.  This routine
 *  is to be called immediately after exiting diagnostic mode to
 *  ensure the proper ordering of the transmit messages.
 *****************************************************************************/
static void unload_queued_for_xmit_msgs(void)
{
  // Unload all queued messages into the "real" transmit queue
  while (queued_msgs_for_xmit_cnt > 0) {

    // The messages are unloaded in "last-in, first-out" order
    queued_msgs_for_xmit_idx--;
    if (queued_msgs_for_xmit_idx < 0)
      queued_msgs_for_xmit_idx = DIAGMODE_XMIT_QUEUE_SIZE-1;
    modemcontroller_send_modemmessage(queued_msgs_for_xmit_idx);
    queued_msgs_for_xmit_cnt--;
  }
}


/******************************************************************************
 *  STATIC FUNCTION: void send_modemmessage(DC550MDCMessage message)
 ******************************************************************************
 *  DESCRIPTION:
 *  This function is for use by the modem controller module only.
 *  It is responsible for queueing bytes that are to be sent over
 *  the modem.  Normally, the software controller interface routine,
 *  modemcontroller_send_modemmessage() will call this routine to
 *  queue up a message.  However, during diagnostic mode, the normal
 *  transmit path via the software controller is disabled and this
 *  routine must be called directly to force the echoed diagnostic
 *  bytes out the transmit modem.
 *****************************************************************************/
static void send_modemmessage(DC550MDCMessage message) {

  if(modemcontroller_numberofmessages < MODEMCONTROLLER_QUEUESIZE) {
    modemcontroller_messages[(modemcontroller_beginindex +
                              modemcontroller_numberofmessages) %
                             MODEMCONTROLLER_QUEUESIZE] = message;
    modemcontroller_numberofmessages++;
  }
}

/******************************************************************************
 *  FUNCTION: void modemcontroller_send_modemmessage(DC550MDCMessage message)
 ******************************************************************************
 *  DESCRIPTION:
 *  This function puts the message in the modemcontroller_messages unless
 *  the queue is full, in which case it discards the message.
 *****************************************************************************/
void modemcontroller_send_modemmessage(DC550MDCMessage message) {

  // Check if we are in diagnostic mode
  if (!echoMode) {
    send_modemmessage(message);
    return;
  }

  // Diagnostic mode - queue up last N messages to be sent
  //  when the switch exits diagnostic mode
  queued_msgs_for_xmit[queued_msgs_for_xmit_idx] = message;
  queued_msgs_for_xmit_idx++;

  // Wrap around if needed
  if (queued_msgs_for_xmit_idx >= DIAGMODE_XMIT_QUEUE_SIZE)
    queued_msgs_for_xmit_idx = 0;

  // Number of messages cannot exceed the queue size
  if (queued_msgs_for_xmit_cnt < DIAGMODE_XMIT_QUEUE_SIZE)
    queued_msgs_for_xmit_cnt++;

}


/******************************************************************************
 *  FUNCTION: void modemcontroller_init(void)
 ******************************************************************************
 *  DESCRIPTION:
 *  This function is called during the initialization phase to initialize all
 *  of the modem controller variables.
 *****************************************************************************/
void modemcontroller_init(void) {
  modemcontroller_beginindex = 0;
  modemcontroller_numberofmessages = 0;
}


/******************************************************************************
 *  FUNCTION: void modemcontroller_exec(void)
 ******************************************************************************
 *  DESCRIPTION:
 *  This function is called to execute the modem controller task.  It does two
 *  jobs:
 *  1. If there is a message in the modemcontroller_messages queue and the
 *     modem is ready to transmit its next message (interrupt_txready == 0),
 *     this function takes the message out of the queue, performs the proper
 *     bitwise rotation, sticks the start bit, direction bit, and address bits
 *     on the message, puts the message in the interrupt_txmessage location,
 *     and sets interrupt_txready to 1.  The modem is responsible for putting
 *     in the repeat, collision, and parity bits.
 *  2. If the modem has received a new message (interrupt_rxready == 1),
 *     this function strips off the unnecessary bits and sends the message
 *     to the software controller and then sets interrupt_rxready to 0.
 *****************************************************************************/
void modemcontroller_exec(void)
{
    extern void modemcontroller_calibrate_display(void);
    extern unsigned char interrupt_txmsgerror;
    extern int addressErrors, parityErrors, collisionsOnTx;
    static int modemcontroller_txmsgs_dropped = 0;
    static int totAddressErrors=0,totParityErrors=0,totCollisionsOnTx=0;

    if (!interrupt_txready && (interrupt_txmsgerror & 0x2)) {
      // Just keeping track of modem reliability...
      modemcontroller_txmsgs_dropped++;
      interrupt_txmsgerror = 0;
      dc550_printf("\r\nModem: tx msg dropped (total=%d)",
        modemcontroller_txmsgs_dropped);
    }
    
    if (!interrupt_txready && (interrupt_txmsgerror & 0x1)) {
      dc550_printf("\r\nModem: tx repeat");
    }

    if (collisionsOnTx != totCollisionsOnTx) {
      totCollisionsOnTx = collisionsOnTx;
      dc550_printf("\r\n**CollisionOnTx (tot=%d)", totCollisionsOnTx);
    }

    if (addressErrors != totAddressErrors) {
      totAddressErrors = addressErrors;
      dc550_printf("\r\n**Address Error (tot=%d)", totAddressErrors);
    }
    if (parityErrors != totParityErrors) {
      totParityErrors = parityErrors;
      dc550_printf("\r\n**Parity Error (tot=%d)", totParityErrors);

    }

  // ----------------------------------------------------------------------  
  // 1: Transmit if there is a message, the modem is ready and
  //    we are not in diagnostic/echo mode
  // ----------------------------------------------------------------------  
  if ( modemcontroller_numberofmessages &&
       !interrupt_txready ) {
    DC550MDCMessage message;                     // This is for debug

    interrupt_txmessage = 
      ((modemcontroller_messages[modemcontroller_beginindex] << 3) | 0x8000);

    message = (interrupt_txmessage >> 3) & 0xff; // This is for debug
    dc550_printf("\r\nS: %c%c",
      ((message >> 4) > 9) ? ('7'+((message>>4))) : ('0'+((message>>4))),
      (((message & 0xf) > 9) ? ('7'+((message&0xf))) : ('0'+((message&0xf)))));

    // Set interrupt_txready to 1
    interrupt_txready = 1;

    // Take message out of the queue
    modemcontroller_beginindex =
      (modemcontroller_beginindex + 1) % MODEMCONTROLLER_QUEUESIZE;
    modemcontroller_numberofmessages--;
  }

  // ----------------------------------------------------------------------  
  // 2: Receive if there is a message
  // ----------------------------------------------------------------------  
  if (interrupt_rxready) {
    DC550MDCMessage message;

    // Free up modem rx path ASAP
    message = ((interrupt_rxmessage >> 3) & 0x00FF);
    interrupt_rxready = 0;
    total_rx_msgs++;

    // Check if we are in diagnostic mode
    if (!echoMode ||
        ( (message == MDC_DMS_CLOSE_ECHO) ||
          (message == MDC_DMS_SOFT_RESET) ||
          (message == MDC_DMS_HARD_RESET) )) {

      // Entering/Exiting Echo/Diag Mode?
      if (message == MDC_DMS_OPEN_ECHO) {
        echoMode = TRUE;
        queued_msgs_for_xmit_idx = 0;
        queued_msgs_for_xmit_cnt = 0;
      }

      else if ( (message == MDC_DMS_CLOSE_ECHO) ||
                (message == MDC_DMS_SOFT_RESET) ||
                (message == MDC_DMS_HARD_RESET) ) {
        echoMode = FALSE;
        unload_queued_for_xmit_msgs();
      }

      // Send the message up for higher level processing
      controller_report_modemcommand(message);
      dc550_printf("\r\nR: %c%c",
          ((message >> 4) > 9 ? ('7'+(message>>4)) : ('0'+(message>>4))),
          ((message & 0xf) > 9 ? ('7'+(message&0xf)) : ('0'+(message&0xf))));
    }

    // We are in diagnostic mode - echo all bytes back to switch
    else {
      send_modemmessage(message);
      dc550_printf("\r\nEcho: %c%c",
          ((message >> 4) > 9 ? ('7'+(message>>4)) : ('0'+(message>>4))),
          ((message & 0xf) > 9 ? ('7'+(message&0xf)) : ('0'+(message&0xf))));
    }
  }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -