📄 dc550_modemcontroller.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 + -