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

📄 ssitest.c

📁 用于TM1300/PNX1300系列DSP(主要用于视频处理)的外部设备的源码
💻 C
字号:
/*
 * Copyright (c) 1995-1999 by TriMedia Technologies. 
 *
 * +------------------------------------------------------------------+
 * | This software is furnished under a license and may only be used  |
 * | and copied in accordance with the terms and conditions of  such  |
 * | a license and with the inclusion of this copyright notice. This  |
 * | software or any other copies of this software may not be provided|
 * | or otherwise made available to any other person.  The ownership  |
 * | and title of this software is not transferred.                   |
 * |                                                                  |
 * | The information in this software is subject  to change without   |
 * | any  prior notice and should not be construed as a commitment by |
 * | TriMedia Technologies.                                           |
 * |                                                                  |
 * | this code and information is provided "as is" without any        |
 * | warranty of any kind, either expressed or implied, including but |
 * | not limited to the implied warranties of merchantability and/or  |
 * | fitness for any particular purpose.                              |
 * +------------------------------------------------------------------+
 *
 *  Module name              : ssitest.c    1.31
 *
 *  Last update              : 17:32:34 - 00/11/09
 *
 *  Description:
 *
 *  The SSI test demonstrates the use of the TM SSI to control
 *  the Thomson ST7545 analog front end.  The SSI itself is fairly basic,
 *  but the 7545 is rather complex.  This demo glosses over the complexities
 *  of the 7545:  A canned initialization sequence is used.
 *  The more complete control required for a real modem would use a higher
 *  level interface with more details.
 *  We have, for instance, written a pSOS ST7545 device driver for this.
 */

#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <tmlib/dprintf.h>

#include <tmlib/AppModel.h>
#include <tmlib/tmtypes.h>
#include <tm1/tmInterrupts.h>
#include <tm1/tmBoard.h>
#include <ops/custom_defs.h>
#include <tm1/tmSSI.h>

#include <tm1/tmHelp.h>

#define     MAX_TX_BUF_SIZE     1024

#define     DEFAULT_TX_DATA     0x3DFF

#define     CONFIG_ARRAY_SIZE   256


/* ST7545 AFE config array:  FSS is 5 */
static UInt16 st7545ConfigArray[] = {
    0x3FFF, 0xFFFF, 0xFFFF, 0xFFFF,
    0x3FFF, 0xFFFF, 0xFFFF, 0xFFFF,
    0x39A1, 0xFFFF, 0xFFFF, 0xFFFF,
    0x3FFF, 0xFFFF, 0xFFFF, 0xFFFF,
    0x3BD0, 0xFFFF, 0xFFFF, 0xFFFF,
    0x3FFF, 0xFFFF, 0xFFFF, 0xFFFF,
    0x3872, 0xFFFF, 0xFFFF, 0x39A1,
    0x3A82, 0xFFFF, 0xFFFF, 0x3872,
    0x3FFF, 0xFFFF, 0xFFFF, 0x3BC0,
    0xE7FF, 0xFFFF, 0x0000, 0x0000,
    0xA7FF, 0x3AD0, 0x0000, 0x0000,
    0xA7FF, 0x0000, 0x0000, 0x3998,
    0xA7FF, 0x0000, 0x0000, 0x0000,
    0xA7FF, 0x0000, 0x3998, 0x0000,
    0xA7FF, 0x0000, 0xB510, 0x4DB8,
    0xA7FF, 0x0460, 0xCBF8, 0xA000,
    0xA7FF, 0xB638, 0x4690, 0x1248,
    0xA7FF, 0xCE80, 0xA000, 0xB738,
    0xA7FF, 0x41E0, 0x05E8, 0xD8A8,
    0xA7FF, 0xA000, 0xB390, 0x5580,
    0xA7FF, 0x0268, 0x2078, 0xA000,
    0xA7FF, 0x0000, 0x0000, 0x0050,
    0xEFFF, 0xFFFF, 0x0000, 0x0000,
    0xAFFF, 0x38B0, 0x0000, 0x0000,
    0xAFFF, 0x0000, 0x0000, 0x3998,
    0xAFFF, 0x0000, 0x0000, 0xB5A8,
    0xAFFF, 0x4780, 0x0290, 0xC000,
    0xAFFF, 0xA000, 0xBF18, 0x41C0,
    0xAFFF, 0x18B0, 0x2078, 0xA000,
    0xAFFF, 0xB348, 0x5610, 0x0430,
    0xAFFF, 0xD8A8, 0xA000, 0xB460,
    0xAFFF, 0x4F08, 0x0980, 0xCE80,
    0xAFFF, 0xA000, 0xB6F8, 0x4228,
    0xAFFF, 0x1DA0, 0xCBF8, 0xA000,
    0xAFFF, 0x0000, 0x0000, 0x0048,
    0xF7FF, 0xFFFF, 0x0000, 0x0000,
    0xB7FF, 0x3AD0, 0x0000, 0x0000,
    0xB7FF, 0x0000, 0x0000, 0x3998,
    0xB7FF, 0x0000, 0x0000, 0x0000,
    0xB7FF, 0x0000, 0x3998, 0x0000,
    0xB7FF, 0x0000, 0xB510, 0x4DB8,
    0xB7FF, 0x0460, 0xCBF8, 0xA000,
    0xB7FF, 0xB638, 0x4690, 0x1248,
    0xB7FF, 0xCE80, 0xA000, 0xB738,
    0xB7FF, 0x41E0, 0x05E8, 0xD8A8,
    0xB7FF, 0xA000, 0xB390, 0x5580,
    0xB7FF, 0x0268, 0x2078, 0xA000,
    0xB7FF, 0x0000, 0x0000, 0x0050,
    0x3FFF, 0xFFFF, 0xFFFF, 0xFFFF,
    0x3FFF, 0xFFFF, 0xFFFF, 0xFFFF,
    0x3FFF, 0xFFFF, 0xFFFF, 0xFFFF,
    0x3FFF, 0xFFFF, 0xFFFF, 0xFFFF,
    0x3FFF, 0xFFFF, 0xFFFF, 0xFFFF,
    0x3FFF, 0xFFFF, 0xFFFF, 0xFFFF,
    0x3FFF, 0xFFFF, 0xFFFF, 0xFFFF,
    0x3FFF, 0xFFFF, 0xFFFF, 0xFFFF,
    0x3FFF, 0xFFFF, 0xFFFF, 0xFFFF,
    0x3FFF, 0xFFFF, 0xFFFF, 0xFFFF,
    0x3FFF, 0xFFFF, 0xFFFF, 0xFFFF,
    0x3FFF, 0xFFFF, 0xFFFF, 0xFFFF,
    0x3FFF, 0xFFFF, 0xFFFF, 0xFFFF,
    0x3FFF, 0xFFFF, 0xFFFF, 0xFFFF,
    0x3FFF, 0xFFFF, 0xFFFF, 0xFFFF,
    0x3FFF, 0xFFFF, 0xFFFF, 0xFFFF,
    0x3FFF, 0x0000, 0xFFFF, 0xFFFF,    /* repeating waveform starts here */
    0x3FFF, 0x0000, 0xFFFF, 0xFFFF,
    0x3FFF, 0x2000, 0xFFFF, 0xFFFF,
    0x3FFF, 0x4000, 0xFFFF, 0xFFFF,
    0x3FFF, 0x6000, 0xFFFF, 0xFFFF,
    0x3FFF, 0x8000, 0xFFFF, 0xFFFF,
    0x3FFF, 0xA000, 0xFFFF, 0xFFFF,
    0x3FFF, 0xC000, 0xFFFF, 0xFFFF,
    0x3FFF, 0xF000, 0xFFFF, 0xFFFF,
};

static void ssiTestISR(void);
static void st7545ConfigFunc(void);

static UInt16 *TxBuffer, *RxBuffer;
static UInt TxPtr, RxPtr;
static UInt TxBufSize, RxBufSize;
static void (*initFunc) (void);    /* Used in the ISR */
volatile static Bool InitFlag = True;


int 
main(int argc, char **argv)
{

    tmLibdevErr_t retval;
    Int         ssiInstance;
    float       gain;
    int         i, freq, sRate;
    FILE       *fp;
    char        ins[80];
    pssiCapabilities_t pssiCap;
    ssiInstanceSetup_t ssiSetup;
    ssiFrameSetup_t ssiFrame;
    Bool        offHook = False;

    DPsize(1024 * 1024);
    DP(("Entering SSI device library test program, V2.03\n\n"));

    printf("\nTrimedia SSI device library test program, V2.03 \n");
    ssiGetCapabilities(&pssiCap);
    printf("SSI library version %d.%d.%d\n",
           pssiCap->version.majorVersion, 
           pssiCap->version.minorVersion, 
           pssiCap->version.buildVersion);
    printf("SSI using %s AFE and support is enabled for ", pssiCap->afeName);
    if (pssiCap->connectionFlags & sacConnectToPOTS)
        printf("Plain Old Telepone Service");
    if (pssiCap->connectionFlags & sacConnectToISDN)
        printf("ISDN Service");
    if (pssiCap->connectionFlags & sacConnectToOTHER)
        printf("Other Service");
    printf("\n\n");

    DP(("Running on ")); tmHelpReportSystem(Null);
    printf("Running on "); tmHelpReportSystem(stdout);

    printf("\nThis program tests the TM SSI library with the ST7545 AFE.\n");
    printf("The telecom connection should be plugged into a phone line "
           "for these tests.\n");

    /* Setup the Tx buffer */
    TxBuffer = (UInt16 *) malloc(MAX_TX_BUF_SIZE * sizeof (UInt16));
    if (!TxBuffer) {
        printf("failed to malloc Tx Buffer\n");
        return (1);
    }
    /* Initialize the TxBuffer with a sine wave */
    freq = 800;
    gain = 0.707;
    sRate = 9600;
    TxBufSize = sRate / freq;    /* number of 16 bit words */
    for (i = 0; i < TxBufSize; i++) {
        float       val, arg;
        Int16       ival;

        arg = 2.0 * 3.1415927 * (float) i / (float) TxBufSize;
        val = gain * 32000.0 * sin(arg);
        ival = (Int16) val;
        TxBuffer[i] = (UInt16) ival;
    }
    for (; i < MAX_TX_BUF_SIZE; i++)
        TxBuffer[i] = 0;

    /* Setup the Rx buffer */
    RxBufSize = 20 * 9600;    /* 20 seconds at 9600hz */
    RxBuffer = (UInt16 *) malloc(RxBufSize * sizeof (UInt16));
    if (!RxBuffer) {
        printf("failed to malloc Rx Buffer\n");
        return (2);
    }
    RxPtr = 0;
    for (i = 0; i < RxBufSize; i++)
        RxBuffer[i] = 0;

    /* open the interface */
    retval = ssiOpen(&ssiInstance);
    if (retval)
        printf("ssiOpen failed with %x\n", retval);

    /* setup the SSI Control Block, and call open */
    ssiSetup.configBuffer = Null;              /* not used */
    ssiSetup.configBufferLength = 0;           /* not used */
    ssiSetup.interruptPriority = intPRIO_6;    /* SSI needs high priority */
    ssiSetup.isr = ssiTestISR;
    ssiSetup.interruptLevelSelect = 12;        /* ils */
    ssiSetup.txInterruptEnable = True;
    ssiSetup.rxInterruptEnable = False;
    ssiSetup.changeDetectorInterruptEnable = False;
    retval = ssiInstanceSetup(ssiInstance, &ssiSetup);
    if (retval) {
        printf("SSI Test:  Initial ssiSetup failed with "
               "error code 0x%x\n", retval);
        return (retval);
    }
    ssiFrame.validSlotsPerFrame = 4;    /* vss: must be even! */
    ssiFrame.slotsPerFrame = 5;         /* fss */
    ssiSetFraming(ssiInstance, &ssiFrame);

    /*
     * We use a canned array to intitialize the 7545.  A 7545 library is
     * available...
     */
    TxPtr = 0;
    initFunc = st7545ConfigFunc;
    InitFlag = True;
    initFunc();        /* primes the pipeline */
    ssiStart(ssiInstance);
    for (i = 0; InitFlag; i++) {    /* the ISR sets initFunc to NULL when
                                     * init is completed 
                                     */
        microsleep(5);
        if (i > 10000 / 5) {        /* 10 ms */
            printf("SSI Init timeout error\n");
            return (1);
        }
    }
    printf("ST7545 init completed after %d microseconds. \n", i * 5);

    /* take the phone off hook */
    ssiOffHook(ssiInstance);
    offHook = True;
    printf("\nA sine wave at %d Hz, %2.1f db is being generated. \n", 
           freq, 20 * log10(gain));

    while (1) {
        char        ic;
        int         count;

        if (offHook)
            printf("h to hangup. s for sine, a for silence, q to exit:\n");
        else
            printf("h to take phone off hook. s for sine, a "
                   "for silence, q to exit:\n");
        gets(ins);
        switch (*ins) {
        case 'h':
            if (offHook) {
                ssiOnHook(ssiInstance);
                offHook = False;
                break;
            }
            ssiOffHook(ssiInstance);
            offHook = True;
            break;

        case 's':
            count = sscanf(ins, "%c %d %f", &ic, &freq, &gain);
            if (count == 1) {
                printf("Enter the sinewave frequency in Hertz:\n");
                freq = 800;
                gets(ins);
                sscanf(ins, "%d", &freq);
                gain = 0.707;
                printf("Enter the amplitude of the sinewave "
                       "(1.0 is full scale)\n");
                gets(ins);
                sscanf(ins, "%f", &gain);
            }
            printf("A sine wave at %d Hz, %2.1f db down (%f) is "
                   "being generated. \n", freq, 20.0 * log10(gain), gain);
            TxBufSize = sRate / freq;    /* number of 16 bit
                             * words */
            if (TxBufSize > MAX_TX_BUF_SIZE)
                TxBufSize = MAX_TX_BUF_SIZE;

            /*
             * create a buffer full of sine waves to test output.
             * The default Tx Data was filled in by the ssiOpen()
             */
            for (i = 0; i < TxBufSize; i++) {
                float       val, arg;
                Int16       ival;

                arg = 2.0 * 3.1415927 * (float) i / (float) TxBufSize;
                val = gain * 32000.0 * sin(arg);
                ival = (Int16) val;
                TxBuffer[i] = (UInt16) ival;
            }
            break;

        case 'a':
            for (i = 0; i < TxBufSize; i++)
                TxBuffer[i] = 0;
            printf("SSI Test paused\n");
            break;

        case 'q':
            ssiOnHook(ssiInstance);
            ssiClose(ssiInstance);
            printf("Writing 16 bit data captured from SSI to ssiin.bin:\n");
            fp = fopen("ssiin.bin", "wb");
            if (!fp) {
                printf("failed to open ssiin.bin for writing\n");
                return (1);
            }
            fwrite(RxBuffer, RxBufSize, sizeof (UInt16), fp);
            fclose(fp);
            printf("Recorded 16 bit data from input written to file. \n");
            free(RxBuffer);
            free(TxBuffer);
            return 0;

        }
    }
}

static Int  lastCalled = 0;
static UInt isrCount = 0;

static void 
_ssiTestISR(void)
{
    int         now, diff;
    UInt32      csr;

    ++isrCount;
    now = cycles();
    diff = now - lastCalled;
    if ((lastCalled != 0) && (diff > 83333))
        DP(("\nssiTestISR %d:  WARNING: Possible latency overrun.  "
            "Cycle count %d \n", isrCount, diff));
    /* 83333 = 32/4 * 100MHz/9600Hz */
    lastCalled = now;

    csr = MMIO(SSI_CSR);    /* only need to read once */
    if (ssiFES(csr)) {    /* Framing error. */
        ssiAckCFES();
        DP(("FE "));
    }
    if (ssiCDS(csr)) {    /* Change Dectect (Ring). */
        ssiAckCCDS();
        DP(("CD "));
    }
    if (ssiTUE(csr)) {    /* Transmit Underrun Error */
        ssiAckCTUE();    /* Clear the interrupt. */
        DP(("TU "));
    }
    if (ssiROE(csr)) {    /* Receive overrun Error */
        ssiAckCROE();    /* Clear the interrupt. */
        DP(("RO "));
    }

    if (InitFlag)
        initFunc();
    else {
        while (ssiGetWAW() > 1) {
            MMIO(SSI_TXDR) = SSI_WordSwap(DEFAULT_TX_DATA, TxBuffer[TxPtr]);
            TxPtr = (TxPtr + 1) % TxBufSize;
            MMIO(SSI_TXDR) = SSI_WordSwap(DEFAULT_TX_DATA, DEFAULT_TX_DATA);
        }
    }
    while (ssiGetWAR() > 1) {
        int         a;
        /* it is the access to SSI_RXACK which actually increments the FIFO pointer.
         * This is done so that a speculative load from SSI_RXDR will not lose
         * data.  Here, I need the first 32 bits (read in a), but not the second.
         * So I read RXDR once, and ack twice.
         */
        a = MMIO(SSI_RXDR);
        MMIO(SSI_RXACK) = 1;    /* Signal the read. */
        MMIO(SSI_RXACK) = 1;    /* Signal the read. */

        /* store the low word in capture buffer */
        RxBuffer[RxPtr++] = 0xFFFF & a;
        RxPtr %= RxBufSize;
    }
}

static void 
ssiTestISR(void)
{
#pragma TCS_handler
    AppModel_suspend_scheduling();
    AppModel_run_on_sstack((AppModel_Fun)_ssiTestISR, Null);
    AppModel_resume_scheduling();
}

static void 
st7545ConfigFunc(void)
{
    while (ssiGetWAW() > 1) {
        MMIO(SSI_TXDR) = SSI_WordSwap(st7545ConfigArray[TxPtr++], 
                                      st7545ConfigArray[TxPtr++]);
        MMIO(SSI_TXDR) = SSI_WordSwap(st7545ConfigArray[TxPtr++], 
                                      st7545ConfigArray[TxPtr++]);
        if (TxPtr > CONFIG_ARRAY_SIZE) {
            InitFlag = False;
            TxPtr = 0;
        }
    }

}


⌨️ 快捷键说明

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