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

📄 main.c

📁 Cypress 的VOIP DEMO 研究VOIP终端的朋友可以研究研究
💻 C
📖 第 1 页 / 共 2 页
字号:
//
// monitorChannel() - Resynchronize or change channels as needed
//
// Periodically evaluate Rx Packet average.  Average reflects the number of 
//  missed voice samples (ie: BOTH slots were bad and speaker audio was lost).
//
// The risetime of the FAST average (rxPktAve_Q3) is ~16 samples or ~50 mS
// The risetime of the SLOW average (rxPktAve_Q8) is ~560 samples or ~1.5 sec
//
// The FAST average detects total signal loss quickly, while the SLOW average
//  detects maginal signal quality.
//
// ---------------------------------------------------------------------------

// When perfect, Gast average rxPktAve_Q3 = 127 or (15*8)
#define BAD_FAST  (rxPktAve_Q3 < 32)    //  32 = BAD_SLOW = 25% * FastPerfect

// When perfect, Slow average rxPktAve_Q8 = 127 or (127*256/256)
#define BAD_SLOW  (rxPktAve_Q8 < 121)   // 121 = BAD_FAST = 95% * SlowPerfect


static void monitorChannel(void) {
    if (BAD_FAST || BAD_SLOW) {
        if (BAD_SLOW) {         // If SLOW trigger, then always change chan
            nxtVoiceCh();       //  because after resync, assume PERFECT
        }
        slotCt = 0xFF;          //  synchronize at next ISR
        while (slotCt == 0xFF); // Wait for ISR to synchronize
        rxPktAve_Q8 = 127;      // Slow filter starts PERFECT
    }
}



/////////////////////////////////////////////////////////////////////////////
// ---------------------------------------------------------------------------
//
// serveSw1() - Monitor SW1 for activity
//
// ---------------------------------------------------------------------------
//BYTE serveSw1(void) {
//    static WORD swTimer;
//    static BYTE swState;
//    #define SW1_OFF         0
//    #define SW1_GOING_ON    1
//    #define SW1_ON          2
//    #define SW1_GOING_OFF   3
//    BYTE retval = SW1_IDLE;
//    
//    switch (swState) {
//    case SW1_OFF:
//        if (IS_SW1_ON) {
//            swState = SW1_GOING_ON;
//            timeSet(&swTimer, 10);      // 3 * 10 mS debounce
//        }
//        break;
//    case SW1_GOING_ON:
//        if (IS_SW1_ON) {
//            if (timeExpired(&swTimer)) {
//                swState = SW1_ON;
//                retval = SW1_JUST_ON;
//            }
//        }
//        else {
//            swState = SW1_OFF;          // Switch bounced, ingore
//        }
//        break;
//    case SW1_ON:
//        if (IS_SW1_OFF) {
//            swState = SW1_GOING_OFF;
//            timeSet(&swTimer, 10);      // 3 * 10 mS debounce
//        }
//        retval = SW1_IS_ON;
//        break;
//    case SW1_GOING_OFF:
//        if (IS_SW1_OFF) {
//            if (timeExpired(&swTimer)) {
//                retval = SW1_JUST_OFF;
//                swState = SW1_OFF;
//            }
//        }
//        else {
//            swState = SW1_ON;           // Switch bounced, ingore
//        }
//        break;
//    }
//    return(retval);
//}

    
extern BYTE testDelta;
// ---------------------------------------------------------------------------
//
// Service arriving PCM data from PC 
//
// ---------------------------------------------------------------------------
static void doUsbOut(void) {
    WORD *ptmp;
    BYTE count;
    signed char ivar;
    static BYTE ledScaler;
    
    // -----------------------------------------------------------------------
    // If endpoint has data, then copy it to RAM page
    // -----------------------------------------------------------------------
	if (INT_CLR2 & INT_MSK2_EP2)
    {
        INT_CLR2 &= ~INT_MSK2_EP2;
        
    	count = USB_bReadOutEP(2, (BYTE *)usbOutIn, USB_EPOUT_BYTE_LEN);
        USB_EnableOutISOCEP(2);
        
        // -------------------------------------------------------------------
        // Preprocess 8 samples just loaded
        //  1) Convert data from 2's complement to unipolar
        //      0x8000 --> 0x0000 (  0 scale voltage)
        //      0xFFFF --> 0x7FFF (0.5 scale voltage - 1)
        //      0x0000 --> 0x8000 (0.5 scale voltage)
        //      0x7FFF --> 0xFFFF (1.0 scale voltage)
        //  2) Convert to 15-bit number
        //      High bit will eventually indicate insert/delete point
        // -------------------------------------------------------------------
        usbOutIn = outPreprocess(usbOutIn);     // Also circular advance ptr

//        if (testDelta == 0)     LED_RED_ON;     //; TEST ONLY
//        else                    LED_RED_OFF;    //; TEST ONLY
        if (++ledScaler == 120)
        {
            LED_RED_ON;
        }
        else if (ledScaler == 130)
        {
            LED_RED_OFF;
            ledScaler = 0;
        }
    }
    
    // -----------------------------------------------------------------------
    // Insert or delete PCM sample to maintain nominal PCM buffer depth
    // -----------------------------------------------------------------------
    ivar = usbOutIn - usbOutOt;     // ivar = # words in buffer
    if (ivar < 0)                   // If negative, it's more than 50%
        ivar += USB_BUF_SIZE;
    if (ivar > 24*4)                    // ivar = # samples in buffer
    {
        // search backwards 24 samples from usbOutIn to locate closest values
        // delete ONE sample from buffer
        decUsbOutInCyclic();
        ++outDeleteCt;
//        LED_RED_ON;
//        LED_RED_OFF;
    }
    else if (ivar < 24*2)
    {
        // search backwards 24 samples from usbOutOt to locate closest values
        // insert ONE sample to buffer
        *usbOutIn = 0x4000;       // 0.5 scale (15-bit unipolar for ADPCM)
        incUsbOutInCyclic();
        ++outInsertCt;
//        LED_RED_ON;
        LED_RED_OFF;
    }
}

static BYTE findClosest(BYTE *pBuf)
{
    return(0);
}


    
// ---------------------------------------------------------------------------
//
// Service departing PCM data to PC 
//
// ---------------------------------------------------------------------------
static void doUsbIn(void) {

	if (asmIsUsbInEnough() == TRUE      // If enough data in buffer
    && (INT_CLR2 & INT_MSK2_EP1) != 0   // If endpoint is is empty
    ) {
        INT_CLR2 &= ~INT_MSK2_EP1;
        USB_LoadInISOCEP(1, (BYTE*)&usbInOt[0], 16, USB_TOGGLE);
        asmUsbInOtAdv();

        LED_RED_OFF;
    }
}    

/////////////////////////////////////////////////////////////////////////////
void timeSet(WORD *pTimer, WORD time)       // 3 mS per count
{
    WORD VoipCt;
    do {                        // ISR may update this 16-bit value and PSoC
       VoipCt = voipCt;         //  doesn't have atomic access,
    } while (VoipCt != voipCt); //  so read until stable
    
    *pTimer = VoipCt + time;
}
BOOL timeExpired(WORD *pTimer)
{
    WORD delta;
    WORD VoipCt;
    do {                        // ISR may update this 16-bit value and PSoC
       VoipCt = voipCt;         //  doesn't have atomic access,
    } while (VoipCt != voipCt); //  so read until stable
    
    delta = *pTimer - VoipCt;
    if (((BYTE)(delta>>8)&0x80) == 0)   return FALSE;   // not expired
    else                                return TRUE;    // expired
}


// ---------------------------------------------------------------------------
//
// doRs232Stats() - Create UART debug data stream.
//
//  The 4800,n,8,1 UART attached in the 8KHz ISR sends a 10-bit character 
//  every 3 mS (24 interrupts).  Since 1/4800 Hz = 208 uS and the 8KHz ISR
//  is every 125 uS, the bits are generated about every 1.67 interrupts 
//  (this is approximated by either every other or every interrupt).
//
//  Every 3 mS, an unbuffered character is sent from the "holding register".
//
// ---------------------------------------------------------------------------
static void doRs232Stats(void)
{
#pragma data:Page3Data
    static BYTE charState;
    static WORD num0;         //
    static WORD num1;         // Static copy of data to decompose
    static WORD num2;         // Static copy of data to decompose
    static BYTE delta;
    static BYTE neg;
    static BYTE min;
    static BYTE num8;
    static BYTE num9;
#pragma data:data
   
       
    switch (charState) {
    case  0:
        uartTxD = CR;
        num0 = hexdec(voiceCh+1);   // RF is 1 MHz above CHANNEL_ADR
        num1 = mibMissRx_1 > 0xFFF ? 0xFFF : mibMissRx_1;   // saturate
        num2 = mibMissRx_2 > 0x0FF ? 0x0FF : mibMissRx_2;   // saturate

        num8 = hexdec(rssiAveA_Q3>>3);  // Ave RSSI: Antenna A
//        num9 = rxPktAve_Q3>>3;
        num9 = rxPktAve_Q8;

        // ---------------------------------------------------------------
        // Get RSSI difference between each antenna time-slot
        // Get worst RSSI of best antenna
        // ---------------------------------------------------------------
        delta = 0x99;                   // default to meaningless Delta
        #define RESET_MIN 0xFF
        if      (tstRssiMin1 == RESET_MIN)  min = hexdec(tstRssiMin0);
        else if (tstRssiMin0 == RESET_MIN)  min = hexdec(tstRssiMin1);
        else if (tstRssiMin0 >= tstRssiMin1) {
            delta = hexdec(tstRssiMin0 - tstRssiMin1);
            neg = 0;   // positive delta
            min = hexdec(tstRssiMin0);
        }                    
        else {
            delta = hexdec(tstRssiMin1 - tstRssiMin0);
            neg = 1;   // negative delta
            min = hexdec(tstRssiMin1);
        }
        tstRssiMin0 = tstRssiMin1 = RESET_MIN;
        tstRssiMax0 = tstRssiMax1 = 0x00;
        break;
    case 1 : uartTxD = LF;                              break;
    case 2 : uartTxD = hexAscMsn((BYTE)(num0));         break;
    case 3 : uartTxD = hexAscLsn((BYTE)(num0));         break;
    case 4 : uartTxD = ' ';                             break;
    case 5 : uartTxD = hexAscLsn((BYTE)(num1>>8));      break;
    case 6 : uartTxD = hexAscMsn((BYTE)(num1>>0));      break;
    case 7 : uartTxD = hexAscLsn((BYTE)(num1>>0));      break;
    case 8 : uartTxD = ':';                             break;
    case 9 : uartTxD = hexAscMsn((BYTE)(num2>>0));      break;
    case 10: uartTxD = hexAscLsn((BYTE)(num2>>0));      break;
    case 11: uartTxD = neg == 0 ? ' ':'-';              break;
    case 12: uartTxD = hexAscMsn(delta);                break;
    case 13: uartTxD = hexAscLsn(delta);                break;
    case 14: uartTxD = ' ';                 break;
    case 15: uartTxD = hexAscMsn(min);      break;    // Max of the Min
    case 16: uartTxD = hexAscLsn(min);      break;
    case 17: uartTxD = ' ';                 break;
    case 18: uartTxD = hexAscMsn(num8);     break;
    case 19: uartTxD = hexAscLsn(num8);     break;
    case 20: uartTxD = ' ';                 break;
    case 21: uartTxD = hexAscMsn(num9);     break;
    case 22: uartTxD = hexAscLsn(num9);
            // fallthru
    default: charState = 0xFF;                          break;
    }
    ++charState;
}
// ###########################################################################

⌨️ 快捷键说明

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