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