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

📄 vi_raw.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              : vi_raw.c    1.23
 *
 *  Last update              : 17:34:24 - 00/11/09
 *
 *  Description              :
 *
 *  An example program that demonstrate the use of raw-video input.
 *  It is a code only example, although it runs on the target it
 *  does notproduce output other than some debug printf's into
 *  memory.
 *
 *  Since this example does not have the workaroudn for 21217
 *  implemented it will run only on tm1s1.1 or better.
 *
 *  ======>>>>>>>>>   IMPORTANT NOTICE   <<<<<<<<<<<<<==========
 *
 *  Video In Users should take care of the workarounds
 *  for hardware bugs 3016, 21217, 21336, 21390.
 *
 *  Even more important, this example does not include the
 *  workaround for 21217. It traps for that and will not
 *  execute.
 */


#include <assert.h>
#include <stdlib.h>
#include <tmlib/tmtypes.h>
#include <tmlib/tmlibc.h>
#include <tmlib/dprintf.h>
#include <tmlib/AppModel.h>
#include <tm1/tmVI.h>
#include <tm1/tmVImmio.h>
#include <tm1/tmProcessor.h>
#include <tm1/tmPCSW.h>

#include <tm1/tmHelp.h>

#define CACHE_LINE_SIZE    64

/* play with this when interrupts
 * come in too fast
 */
#define BUF_SIZE    (128*CACHE_LINE_SIZE)

static Char *buffer1;
static Char *buffer2;

static viInstanceSetup_t visetup;
static viRawSetup_t virawsetup;

static volatile int cnt;

static volatile int overflow_cnt = 0;
static unitSelect_t videoInUnit = unit0;

static UInt32 mmioBase = VI1_MMIO_BASE;

static void
my_abort(Char * name, Int err)
{
    assert(name != Null);
    fprintf(stderr, "%s failed, error code %x\n", name, err);
    exit(-1);
}

void printUsage(char *cmd)
{
    fprintf(stderr, "Usage:\n");
    fprintf(stderr, "%s [-vi n]\n", cmd);
    fprintf(stderr, "where n can be 1 or 2\n");
    fprintf(stderr, "Example: %s -vi 2 launches %s using the 2nd video in unit\n", cmd, cmd);
}

void Init(int argc, char **argv)
{
    Int viUnit;
    pprocCapabilities_t pprocCap;    
    tmLibdevErr_t       err;

    /*
     * workaround when dummycode is needed: remap U to SDRAM base,
     * hardware bug fixed in tm1s1.1
     */

    if (err = procGetCapabilities(&pprocCap))
    {
        my_abort("procGetCapabilities", err);
    }
    
    if (pprocCap->revisionID <= PROC_REVISION_1_0S && 
        pprocCap->deviceID <= PROC_DEVICE_TM1000) 
    {
        fprintf(stderr,
                "Sorry, cannot execute on an older chip than "
                "tm1s1.1,\nsoftware workaround for hardware "
                "bug 21217 is not\nimplemented in this example\n");
        exit(-1);
    }
    
    /* handle the command line */ 
    if (argc == 3)
    {
        /* if the user specified the -vi command, select the correct VI */
        if (strcmp(argv[1], "-vi") == 0)
        {
            if (1 == sscanf(argv[2], "%d", &viUnit))
            {
                switch (viUnit)
                {
                case 1:
                    videoInUnit = unit0;
                    break;
                case 2:
                    videoInUnit = unit1;
                    break;
                default:
                    printUsage(argv[0]);
                    exit(1);
                    break;
                }
            }
        }
        else
        {
            printUsage(argv[0]);
            exit(1);
        }
    }
    /* no argument specified, we assume this is VI1 (unit0) */
    else if (argc == 1)
    {
        videoInUnit = unit0;
    }
    else 
    {
        printUsage(argv[0]);
        exit(1);
    }

    /* default to unit0 in the case of the unit specified on the command line
     * is not available on the HW. Note that a viOpen with a wrong unit
     * number would have returned TMLIBDEV_ERR_NOT_AVAILABLE_IN_HW
     */
    switch(pprocCap->deviceID)
    {
    case PROC_DEVICE_TM1000:
    case PROC_DEVICE_TM1100:
    case PROC_DEVICE_TM1300:
        if (videoInUnit != unit0)
        {
            fprintf(stderr, "Default to unit0 (VI1). VI2 is not availabled on this chip\n");
        }
        videoInUnit = unit0;
        break;
    default:
        /* we suppose this is ok */
        break;
    }

    /* get the mmio base according to the unit */
    switch(videoInUnit) 
    {
    case unit0:
        mmioBase = VI1_MMIO_BASE;
        break;
    case unit1:
        mmioBase = VI2_MMIO_BASE;
        break;
    default:
        /* this should not happen */
        break;
    }
}


void 
process_buffer(char *buf)
{
    /*
     * do something with this buffer, Don't forget to invalidate the
     * memory first, due to speculative loads it can be in the D$
     */
    _cache_invalidate((char *) buf, BUF_SIZE);

    /*
     * Since I do not know whether this is PAL or NTSC or whatever
     * format, I'll just display something
     */
    DP(("Doing buffer %x\n", buf));

    /*
     * If you write in the buffer then invalidate the buffer again here,
     * before passing it back to vi.
     */
}



void 
_vi_raw_handler(void)
{
    Int         vi_stat = MMIO(mmioBase + VI_STATUS_OFFSET);
    Bool        buf1full, buf2full;

    if ((vi_stat & 0x2B) == 0) {

        /*
         * This is due to hardware bug 21390, a spurious interrupt
         * may occur. 0x2B are the ones we enabled.
         */
        return;
    }

    cnt++;

    if (viHBE(vi_stat) | viOVERRUN(vi_stat))
        goto exception;

    buf1full = viBUF1FULL(vi_stat) != 0;
    buf2full = viBUF2FULL(vi_stat) != 0;
    if (buf1full) {

        /*
         * It would have been better if we had multi tasking, then we
         * would make that task active, now do the work in the
         * handler.
         */
        process_buffer(buffer1);

        /*
         * If buffer 2 is full here, we have probably missed data
         */

        viAckBUF1FULL_ACKM(mmioBase);
    }
    else if (buf2full) {
        /* comments, see above */

        process_buffer(buffer2);

        viAckBUF2FULL_ACKM(mmioBase);
    }
    return;

    /*
     * All these exceptions should not occur. When they occur the buffer
     * sizes are too small, or the Highway bandwidth size is not
     * correctly partitioned for this application, or there is too much
     * processing going on on the incoming data. You can increase the
     * buffer size to lower the nrof interrupts, or intorduce a third
     * buffer. When you get HBE play with the highway arbitration
     * registers
     */

exception:
    if (viHBE(vi_stat)) {
        DP(("Better gimme some extra bandwidth!!\n"));
        viAckHBE_ACKM(mmioBase);
    }
    if (viOVERRUN(vi_stat)) {
        DP(("Sorry, Couldn't keep up: both buffers are full\n"));
        overflow_cnt++;
        viAckBUF1FULL_ACKM(mmioBase);
        viAckBUF2FULL_ACKM(mmioBase);
        viAckOVR_ACKM(mmioBase);
    }
}

static void vi_raw_handler(void)
{
    /*
     * Do not make it interruptible since VI executes level triggered
     * only
     */
#pragma TCS_handler
    AppModel_suspend_scheduling();
    AppModel_run_on_sstack((AppModel_Fun)_vi_raw_handler, Null);
    AppModel_resume_scheduling();
}

Char       *
allocSz(int bufSz)
{
    Char       *temp;

    if ((temp = (Char *) _cache_malloc(bufSz, -1)) == Null)
        my_abort("_cache_malloc", 0);

    memset(temp, 0, bufSz);
    _cache_copyback((void *) temp, bufSz);

    return temp;
}

static void
raw_capture_setup(Int instance)
{
    tmLibdevErr_t err;

    buffer1 = allocSz(BUF_SIZE);
    buffer2 = allocSz(BUF_SIZE);

    memset(&visetup, 0, sizeof (viInstanceSetup_t));

    visetup.hbeEnable = True;

    visetup.isr = vi_raw_handler;
    visetup.interruptPriority = intPRIO_3;    /* pick some */
    visetup.videoStandard = vasNTSC;          /* just to init the decoder */
    visetup.adapterType = vaaCVBS;            /* so that we have a clock */

    if (err = viInstanceSetup(instance, &visetup))
        my_abort("viInstanceSetup", err);

    memset(&virawsetup, 0, sizeof (viRawSetup_t));

    virawsetup.buf1fullEnable = True;
    virawsetup.buf2fullEnable = True;
    virawsetup.mode = viSTREAM8;
    virawsetup.overrunEnable = True;
    virawsetup.size = BUF_SIZE;
    virawsetup.base1 = buffer1;
    virawsetup.base2 = buffer2;

    if (err = viRawSetup(instance, &virawsetup))
        my_abort("viRawSetup", err);
}

int
main(int argc, char **argv)
{
    Int         instance;
    tmLibdevErr_t err;

    fprintf(stderr, "\nTM-1 Demo program Video In in raw mode\n\n");

    fprintf(stderr, "Running on "); tmHelpReportSystem(stderr);

    Init(argc, argv);
    
    if (err = viOpen(&instance))
        my_abort("viOpen", err);

    raw_capture_setup(instance);

    if (err = viStart(instance))
        my_abort("viStart", err);

    /* do until we have seen a 100 interrupts */
    while (cnt < 100);

    fprintf(stderr, "Processed 100 buffers on VI");
    fprintf(stderr, ((videoInUnit == unit0) ? "1" : "2"));
    if (overflow_cnt > 0)
        fprintf(stderr, ", but got %d overflow situations\n", overflow_cnt);
    else
        fprintf(stderr, " succesfully\n");

    if (err = viStop(instance))
        my_abort("viStop", err);

    if (err = viClose(instance))
        my_abort("viClose", err);

    if (buffer1)
        _cache_free(buffer1);
    if (buffer2)
        _cache_free(buffer2);
    return 0;
}

⌨️ 快捷键说明

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