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

📄 vivot.c

📁 TM1300/PNX1300系列DSP(主要用于视频处理)的自动boot程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * Copyright (c) 1995,2000 TriMedia Technologies Inc.     
 *
 * +------------------------------------------------------------------+
 * | 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              : vivot.c   1.6
 *
 *  Last update              : 23:59:51 - 97/03/31
 *
 *  Description              :
 *
 *  Revision                 :
 *              Built for the TCS 1.1 release
 *
 */


#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <tm1/mmio.h>
#include <ops/custom_defs.h>
#include <tm1/tmVI.h>
#include <tm1/tmVO.h>
#include <tm1/tmBoard.h>
#include <tm1/tmAvFormats.h>
#include <tm1/tmVImmio.h>
#include <tm1/tmVOmmio.h>
#include <tm1/tmInterrupts.h>
#include <tm1/tmProcessor.h>
#include <tmlib/tmlibc.h>
#include <tmlib/dprintf.h>

#define  VID_RDY_VI             1	/* buffer is ready for vi to use */
#define  VID_RDY_MM             2	/* buffer is ready for mm to use */
#define  VID_RDY_VO             4	/* buffer is ready for vo to use */

#define				NUM_BUF_ENTRIES		4

#define 			CACHE_LINE_SIZE		64

typedef struct _videoBuf {	/* video buffer structure example */
	UInt32      Y;		/* buffer pointer for Y */
	UInt32      U;		/* buffer pointer for U */
	UInt32      V;		/* buffer pointer for V */
	UInt32      flag;	/* flags used in buffer management */
} vBuf, *pvBuf;

static vBuf fullResBuf[NUM_BUF_ENTRIES];
static vBuf cif422Buf[NUM_BUF_ENTRIES];
static vBuf bkBuf[1];
static vBuf genBuf[NUM_BUF_ENTRIES];

static Int                      viInst;
static viInstanceSetup_t 	viInstSup;
static viYUVSetup_t 		viYUVSup;

static Int  			voInst;
static voInstanceSetup_t 	voInstSup;
static voYUVSetup_t 		voYUVSup;
static voOverlaySetup_t 	voOverlaySup;

static Int  cifStride = 384;
static Int  cifWidth  = 352;
static Int  cifHeight = 240;

static Int  fullStride = 768;
static Int  fullWidth  = 720;
static Int  fullHeight = 480;

#define  VID_NUMBUFS 4

static Bool DummyCode  = False;	/* software workaround for hw bug 21217 
				 * Very ugly, if you have a tm1s1.1 or 
				 * better you don't want to know what the
				 * workaround is....
				 */

static Char *Header = 	"\nTriMedia Video-In to Video-Out "
			"Example Program Version 2.0\n";

static int         viNum = 0;
static int         mmNum = 0;
static int         voNum = 0;

static int         yFieldStride = 0;
static int         uvFieldStride = 0;
static int         overlayFieldStride = 0;

static int         yScanWidth = 0;
static int         uvScanWidth = 0;

static int         cpUsize = 0;

static Bool        capField = False;
static Bool        firstField = False;
static Bool        runningOverlay = False;

static int         loopCount = 1000;
static int         voISRCount = 0;

static UInt        videoStandard = vasNTSC;
static UInt        adapterType = vaaCVBS;

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

/***** Copy back a memory piece:  One big copyback slows down the compiler */
void
invalidateRange(void *ptr, unsigned long size)
{
	unsigned long i;
	char         *p = ptr;

	for (i = 0; i < size; i += CACHE_LINE_SIZE)
		INVALIDATE(p + i, 1);
}

void
copybackRange(void *ptr, unsigned long size)
{
	unsigned long i;
	char         *p = ptr;

	for (i = 0; i < size; i += CACHE_LINE_SIZE)
		COPYBACK(p + i, 1);
}

void 
voTestISR()
{
	unsigned long vo_status = MMIO(VO_STATUS);
	int           votmpNum;
	
#pragma TCS_handler

	voISRCount++;

	if (voYTR(vo_status))
		voAckYTR_ACK();
	if (voURUN(vo_status))
		voAckURUN_ACK();
	if (voHBE(vo_status))
		voAckHBE_ACK();
	if (voBUF2EMPTY(vo_status))
		voAckBFR2_ACK();
	if (voBUF1EMPTY(vo_status)) {	/* bfr1 empty */

		if (runningOverlay) {
			if (voFIELD2(vo_status)) {
				/* from f1 to f2 */
				voYUVChangeBuffer(voInst,
					bkBuf[0].Y + yFieldStride, 
					bkBuf[0].U + uvFieldStride, 
					bkBuf[0].V + uvFieldStride);
				voOverlayChangeBuffer(voInst, 
					genBuf[voNum].Y + overlayFieldStride);
			}
			else {
				votmpNum = (voNum + 1) % VID_NUMBUFS;
				if (genBuf[votmpNum].flag == VID_RDY_VO) {
					genBuf[voNum].flag = VID_RDY_VI;
					voNum = votmpNum;
				}
				voYUVChangeBuffer(voInst,
					bkBuf[0].Y, 
					bkBuf[0].U, 
					bkBuf[0].V);
				voOverlayChangeBuffer(voInst, 
					genBuf[voNum].Y);
			}
		}
		else {
			if (voFIELD2(vo_status)) {
				/* from f1 to f2 */
				voYUVChangeBuffer(voInst,
					(Char *)genBuf[voNum].Y + yFieldStride, 
					(Char *)genBuf[voNum].U + uvFieldStride, 
					(Char *)genBuf[voNum].V + uvFieldStride);
			}
			else {
				votmpNum = (voNum + 1) % VID_NUMBUFS;
				if (genBuf[votmpNum].flag == VID_RDY_VO) {
					genBuf[voNum].flag = VID_RDY_VI;
					voNum = votmpNum;
				}
				voYUVChangeBuffer(voInst,
					genBuf[voNum].Y, 
					genBuf[voNum].U, 
					genBuf[voNum].V);
			}
		}
		voAckBFR1_ACK();
		/*
		 * In the handler for a level-triggered interrupt,
		 * the interrupt acknowledge store must be issued at least
		 * two cycles before the ijmp which ends the handler;
		 * see section 3.4.3.3 of the Databook for details.
		 * The #pragma TCS_break_dtree here assures this,
		 * as the following dtree contains a minimum of three cycles.
		 */
		#pragma TCS_break_dtree	
		return;
	}
}


void 
viTestISR()
{
	unsigned long vi_status = MMIO(VI_STATUS);
	int           oddField;
	int           vitmpNum;


#pragma TCS_handler

	oddField = viExtractODD(vi_status);

	if ((vi_status & 0x1) == 0) {

		/*
		 * This is due to hardware bug 21390, a spurious interrupt
		 * may occur. Since we have only enabled capture_enable (0x1)
		 * we should not check on threshold_reached (0x2)
		 */
		return;
	}
	if (viHBE(vi_status)) {

		/*
		 * Highway banmdwidth, VI needs more bandwidth. You can play
		 * with the highway arbitration setting
		 */
		viAckHBE_ACK();
		return;
	}

	if (capField) {
		vitmpNum = (viNum + 1) % VID_NUMBUFS;
		if (oddField & (genBuf[vitmpNum].flag == VID_RDY_VI)) {
			if (DummyCode) {
				invalidateRange((void *)MMIO(DRAM_BASE), cpUsize);
				memcpy(genBuf[viNum].U, MMIO(DRAM_BASE), cpUsize);
				copybackRange((void *)genBuf[viNum].U, cpUsize);
			}
			genBuf[viNum].flag = VID_RDY_MM;
			viNum = vitmpNum;
			viYUVChangeBuffer(viInst,
				  genBuf[viNum].Y,
				  (DummyCode) ? (UInt32) MMIO(DRAM_BASE) : genBuf[viNum].U,
				  genBuf[viNum].V);
		}
		viAckCAP_ACK();
		/*
		 * In the handler for a level-triggered interrupt,
		 * the interrupt acknowledge store must be issued at least
		 * two cycles before the ijmp which ends the handler;
		 * see section 3.4.3.3 of the Databook for details.
		 * The #pragma TCS_break_dtree here assures this,
		 * as the following dtree contains a minimum of three cycles.
		 */
		#pragma TCS_break_dtree
		return;
	}

	/* 
	 *   !!!!!!!!!!!!!!!!!!NOTE!!!!!!!!!!!!!!!!
	 * This acknowledge really should be done at the end
	 * of the ISR just before the dtree_break. That will
	 * work on the tm1s1.1 and further, but due to the 
	 * hardware bug 21217 in combination with 3016 we are
	 * forced to acknowledge before we process the data.
	 * HW bug 21217 makes us copy the U-buffer from
	 * MMIO base into a real U-buffer. This takes a long
	 * time, which makes us hit hardware bug 3016. HW bug 3016
	 * says: acknowledge in the vertical blanking interval or
	 * you are hosed. So we need to acknowledge in time.
	 * For the HALFRES we are still fast enough to not hit this
	 * 3016 bug.
	 * 
	 * Now because we acknowledge too soon, the hardware 
	 * already starts with the next capture with the old 
	 * buffer pointers.  This results swapped fields and 
	 * therefore we swap the field (i.e. change from:
	 * if (!oddField) ---> if (oddField) to avoid interlace
	 * artifacts.
	 */
	if (DummyCode) 
		viAckCAP_ACK();

	if (firstField) {
		firstField = False;

	        if ( (DummyCode) && (oddField) ) {
			firstField = True;
		} else if ( (!DummyCode) && (!oddField) ) {
		        /* skip even field to get sync */
			firstField = True;
	        } else {
			/* always start with odd field */
			viYUVChangeBuffer(viInst,
				genBuf[viNum].Y + yScanWidth,
				(DummyCode) ? (UInt32) MMIO(DRAM_BASE) + uvScanWidth
					    : genBuf[viNum].U + uvScanWidth,
				genBuf[viNum].V + uvScanWidth);
		}
	}
	else {
		vitmpNum = (viNum + 1) % VID_NUMBUFS;
		if (genBuf[vitmpNum].flag == VID_RDY_VI) {
			if (DummyCode) {
				invalidateRange((void *)MMIO(DRAM_BASE), cpUsize);
				memcpy(genBuf[viNum].U, MMIO(DRAM_BASE), cpUsize);
				copybackRange((void *)genBuf[viNum].U, cpUsize);
			}
			genBuf[viNum].flag = VID_RDY_MM;
			viNum = vitmpNum;
		}
		viYUVChangeBuffer(viInst, 
			genBuf[viNum].Y,
			(DummyCode) ? (UInt32) MMIO(DRAM_BASE) 
			            : genBuf[viNum].U,
			genBuf[viNum].V);
		firstField = 1;
	}
	/* 
	 * Force two cycles between the ack and ending the ISR 
	 */
	if (!DummyCode) 
		viAckCAP_ACK();	/* read comments above on the acknowledge */
	/*
	 * In the handler for a level-triggered interrupt,
	 * the interrupt acknowledge store must be issued at least
	 * two cycles before the ijmp which ends the handler;
	 * see section 3.4.3.3 of the Databook for details.
	 * The #pragma TCS_break_dtree here assures this,
	 * as the following dtree contains a minimum of three cycles.
	 */
	#pragma TCS_break_dtree
	return;
}

void 
CIF422OVERLAY(unsigned long yP, unsigned long uP, unsigned long vP,
	      unsigned long ovP)
{
	unsigned char *pp;
	unsigned char *pY0;
	unsigned char *pY1;
	unsigned char *pU;
	unsigned char *pV;
	unsigned int *tmpPtr;
	int         i, j;

	pY0 = (unsigned char *) yP;
	pU = (unsigned char *) uP;
	pV = (unsigned char *) vP;
	pp = (unsigned char *) yP;
	pY1 = ++pp;

	tmpPtr = (unsigned int *) ovP;

	for (i = 0; i < cifHeight; i++) {
		for (j = 0; j < 176; j++) {
			*tmpPtr = ((*pY1++ & 0xff) << 24) | (*pV++ & 0xff) << 16 |
				  ((*pY0++ & 0xff) << 8)  | (*pU++ & 0xff) << 0;
			tmpPtr++;
			pY1++;
			pY0++;
		}
		for (j = 0; j < 16; j++) {
			pY0 += 2;
			pY1 += 2;
			pU++;
			pV++;
		}
	}
}

void 
mmBufUpdate()
{
	int  mmtmpNum;

	mmtmpNum = (mmNum + 1) % VID_NUMBUFS;
	if (genBuf[mmtmpNum].flag == VID_RDY_MM) {
		genBuf[mmNum].flag = VID_RDY_VO;
		mmNum = mmtmpNum;
	}
}

void 
mmOvlyBufUpdate()
{
	int  mmtmpNum;
	
	mmtmpNum = (mmNum + 1) % VID_NUMBUFS;
	if (genBuf[mmtmpNum].flag == VID_RDY_MM) {

		/*
		 * genBuf[mmtmpNum] has the newly captured image from
		 * video-in
		 *
		 * convert genBuf[mmtmpNum].YUV CIF422 to
		 * gebbuf[mmNum].Y-Overlay
		 *
		 * that is: convert them from Y U V planar to YVYU
		 *
		 * put the YVYU in genBuf[mmNum] and label it VO ready for
		 * display
		 *
		 * set mmNum=mmtmpNum 
		 */

		CIF422OVERLAY(genBuf[mmtmpNum].Y, genBuf[mmtmpNum].U,
			      genBuf[mmtmpNum].V, genBuf[mmNum].Y);
		genBuf[mmNum].flag = VID_RDY_VO;
		mmNum = mmtmpNum;
	}
}

UInt32 
allocSz(int bufSz)
{
	UInt32      temp;
	int         i;

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

	memset(temp, 0, bufSz);
	for (i = 0; i < bufSz; i += CACHE_LINE_SIZE)
		COPYBACK((void *) (temp + i), 1);

	return temp;
}

void 
allocCif422()
{
	int         i, szY, szUV;

	szY = (cifStride * (cifHeight + 4));
	szUV = ((cifStride >> 1) * (cifHeight + 4));
	for (i = 0; i < VID_NUMBUFS; i++) {
		cif422Buf[i].Y = allocSz(szY);
		cif422Buf[i].U = allocSz(szUV);
		cif422Buf[i].V = allocSz(szUV);
		cif422Buf[i].flag = VID_RDY_VI;
		DP(("Allocate CIF422Buf i %d Y %x U %x V %x\n",
		       i, cif422Buf[i].Y, cif422Buf[i].U, cif422Buf[i].V));
	}
}

void 
allocFullRes()
{
	int         i, szY, szUV;

	szY = (fullStride * (fullHeight + 4));
	szUV = ((fullStride >> 1) * (fullHeight + 4));
	for (i = 0; i < VID_NUMBUFS; i++) {
		fullResBuf[i].Y    = allocSz(szY);
		fullResBuf[i].U    = allocSz(szUV);
		fullResBuf[i].V    = allocSz(szUV);
		fullResBuf[i].flag = VID_RDY_VI;
		DP(("Allocate fullResBuf i %d Y %x U %x V %x\n",
		       i, fullResBuf[i].Y, fullResBuf[i].U, fullResBuf[i].V));
	}
}

void 
allocBkBuf()
{
	int         szY, szUV;

	szY = (768 * (576 + 4));
	szUV = ((768 >> 1) * (576 + 4));
	bkBuf[0].Y    = allocSz(szY);
	bkBuf[0].U    = allocSz(szUV);
	bkBuf[0].V    = allocSz(szUV);
	bkBuf[0].flag = VID_RDY_VI;
	DP(("Allocate bkBuf Y %x U %x V %x\n",
	       bkBuf[0].Y, bkBuf[0].U, bkBuf[0].V));
}

void 
cpGenBuf(vBuf * buf, int numBuf, int flag)
{
	vBuf       *pBuf;
	int         i;

	pBuf = buf;
	for (i = 0; i < numBuf; i++) {
		genBuf[i].Y    = pBuf[i].Y;
		genBuf[i].U    = pBuf[i].U;
		genBuf[i].V    = pBuf[i].V;
		genBuf[i].flag = flag;
	}
}

int 
readYUVFiles(char *baseName, int hsize, int vsize,
	     UInt32 ybuf, UInt32 ubuf, UInt32 vbuf)
{
	int         count, ySize, uvSize, row;
	char        fn[80];
	unsigned char *pb;
	FILE        *fp;

	printf("reading the overlay file...\n");
	/* get memory */
	ySize = hsize * vsize;
	uvSize = (ySize >> 1);

	/* just read Y file: binary */
	sprintf(fn, "%s.y", baseName);
	fp = fopen(fn, "rb");
	if (!fp)
		return (4);
	count = fread((char *) ybuf, 1, ySize, fp);
	fclose(fp);
	copybackRange((void*)ybuf, ySize);

	/* just read U file: binary */
	sprintf(fn, "%s.u", baseName);
	fp = fopen(fn, "rb");
	if (!fp)
		return (4);
	pb = (unsigned char *) ubuf;
	count = 0;
	for (row = 0; row < (vsize >> 1); row++) {
		count += fread(pb, 1, (hsize >> 1), fp);

⌨️ 快捷键说明

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