Skip to content

Instantly share code, notes, and snippets.

@andresv
Last active December 12, 2015 07:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save andresv/4739017 to your computer and use it in GitHub Desktop.
Save andresv/4739017 to your computer and use it in GitHub Desktop.
Demonstrates how to configure SYS/BIOS VPIF driver for RAW capture mode on C6748LCDK
#include "vpiftransfer.h"
// this must be defined here otherwise there will be Uint32 etc redefine errors
#define _TI_STD_TYPES
#include <cslr/soc_C6748.h>
#include <cslr/cslr_syscfg0_C6748.h>
#include <vpif/include/Fvid.h>
#include <vpif/include/Vpif.h>
/* ========================================================================== */
/* MACRO DEFINITIONS */
/* taken from vpif_evmInit.c */
/* ========================================================================== */
#define KICK0R (*((volatile Uint32 *)(0x01C14038u)))
#define KICK0R_VPIF_ENABLE 0x83E70B13u
#define KICK1R (*((volatile Uint32 *)(0x01C1403Cu)))
#define KICK1R_VPIF_ENABLE 0x95a4f1e0u
/* Mask and value of the pinmux registers for vpif 0 */
#define PINMUX14_VPIF0_CH0_MASK 0x000000F0u
#define PINMUX14_VPIF0_CH0_ENABLE 0x11111101u
#define PINMUX15_VPIF0_CH0_MASK 0xFFFFFF00u
#define PINMUX15_VPIF0_CH0_ENABLE 0x00000011u
#define PINMUX14_VPIF0_CH1_MASK 0xFFFFFF0Fu
#define PINMUX14_VPIF0_CH1_ENABLE 0x00000010u
#define PINMUX15_VPIF0_CH1_MASK 0x000000FFu
#define PINMUX15_VPIF0_CH1_ENABLE 0x11111100u
#define PINMUX16_VPIF0_CH1_MASK 0xFFFFFF00u
#define PINMUX16_VPIF0_CH1_ENABLE 0x00000011u
#define PINMUX16_VPIF0_CH2_MASK 0x000000FFu
#define PINMUX16_VPIF0_CH2_ENABLE 0x11111100u
#define PINMUX17_VPIF0_CH2_MASK 0xFFFFFF00u
#define PINMUX17_VPIF0_CH2_ENABLE 0x00000011u
#define PINMUX19_VPIF0_CH2_MASK 0xFFFF00FFu
#define PINMUX19_VPIF0_CH2_ENABLE 0x00001100u
#define PINMUX17_VPIF0_CH3_MASK 0x000000FFu
#define PINMUX17_VPIF0_CH3_ENABLE 0x11111100u
#define PINMUX18_VPIF0_CH3_MASK 0xFFFFFF00u
#define PINMUX18_VPIF0_CH3_ENABLE 0x00000011u
#define PINMUX19_VPIF0_CH3_MASK 0xFF00FFFFu
#define PINMUX19_VPIF0_CH3_ENABLE 0x00110000u
#define PINMUX14_VPIF0_BOTH_CAP_MASK 0x00000000u
#define PINMUX14_VPIF0_BOTH_CAP_ENABLE 0x11111111u
#define PINMUX15_VPIF0_BOTH_CAP_MASK 0x00000000u
#define PINMUX15_VPIF0_BOTH_CAP_ENABLE 0x11111111u
#define PINMUX16_VPIF0_BOTH_CAP_MASK 0xFFFFFF00u
#define PINMUX16_VPIF0_BOTH_CAP_ENABLE 0x00000011u
#define PINMUX16_VPIF0_BOTH_DISP_MASK 0x000000FFu
#define PINMUX16_VPIF0_BOTH_DISP_ENABLE 0x11111100u
#define PINMUX17_VPIF0_BOTH_DISP_MASK 0x00000000u
#define PINMUX17_VPIF0_BOTH_DISP_ENABLE 0x11111111u
#define PINMUX18_VPIF0_BOTH_DISP_MASK 0xFFFFFF00u
#define PINMUX18_VPIF0_BOTH_DISP_ENABLE 0x00000011u
#define PINMUX19_VPIF0_BOTH_DISP_MASK 0xFF0000FFu
#define PINMUX19_VPIF0_BOTH_DISP_ENABLE 0x00111100u
#define NUM_FRAME_BUFFERS (3u)
static Semaphore_Handle* SEM_picture_done;
typedef struct {
FVID_Handle chanHandle; // Channel handle
FVID_Frame *frame; // Current FVID frame buffer pointer
}ChannelInfo_t;
Vpif_Params vpifParams;
void VPIF_raw_capture_init() {
Int32 status = IOM_COMPLETED;
ChannelInfo_t capChInfo;
Char* vpifCapStrings = "/Vpif0/0/MT9M034";
Int32 framecount = 0;
Int32 bufCount;
Vpif_StdInfo capParams;
Vpif_CapChanParams vCapParamsChan;
Vpif_ConfigParams vCapParamsConfig = {Vpif_VideoMode_RAW_720P, 1280, 720, 39, Vpif_FrameFormat_PROGRESSIVE, Vpif_YCMuxed_NO, 0, 0, 0, 0, 0, 0, 0, 0, 0, Vpif_CaptureFormat_CCDC, FALSE, FALSE, 0, {0, 0, 0}, {0, 0, 0}};
Uint32 dispheight, dispwidth;
Uint32 sizeimage;
DEV_Params devParams;
Error_Block eb;
Error_init(&eb);
// we do not have to provide 24 MHz clock from C6748, because MT9M034 board has onboard 24 MHz clock generator
// so just enable VPIF
vpifConfig(EvmInit_VpifChannel_BOTHCAPCH); // RAW capture uses both channels
// Create and configure capture drivers
vCapParamsChan.capEdcTbl = NULL;
vCapParamsChan.capChannelIoMode = Vpif_IoMode_RAW_CAP;
vCapParamsChan.capFbParams.frmBufAlignment = 128u;
vCapParamsChan.capFbParams.frmBufHeapHandle = NULL;// Create frame buffer from system heap
// Vpif_VideoMode_NONE = 0,
// VPIF operation mode: NONE. Used when user wants to send the different
// video parameters and do not want to use internal look-up table.
vCapParamsChan.capStdMode = Vpif_VideoMode_RAW_720P; // Raw Mode - Bayer Pattern GrRBGb only
//vCapParamsChan.capStdMode = Vpif_VideoMode_NONE;
//vCapParamsChan.capVideoParams = &vCapParamsConfig;
vCapParamsChan.capVideoParams = NULL;
// < Indicates whether it is field or frame based storage mode. This is
// only applicable for interlaced mode of operation
//vCapParamsChan.capStorageMode = Vpif_SdramStorage_FRAME;
vCapParamsChan.capVbiService = Vpif_VbiServiceType_NONE; // no metadata
vCapParamsChan.capDataSize = Vpif_RawCaptureDataWidth_8BITS;
// or Vpif_RawCapturePinPol_INVERT
vCapParamsChan.capFieldPol = Vpif_RawCapturePinPol_SAME;
vCapParamsChan.capVPixPol = Vpif_RawCapturePinPol_SAME;
vCapParamsChan.capHPixPol = Vpif_RawCapturePinPol_SAME;
// create VPIF0 device
DEV_Params_init(&devParams);
devParams.deviceParams = (Ptr)&vpifParams;
devParams.devid = 0;
devParams.initFxn = &vpif_device_init_fxn;
DEV_create("/Vpif0", (Ptr)&Vpif_IOMFXNS, &devParams, &eb);
capChInfo.chanHandle = FVID_create(vpifCapStrings, GIO_INPUT, &status, &vCapParamsChan, NULL);
if ((IOM_COMPLETED != status) || (NULL == capChInfo.chanHandle)) {
System_printf("Failed to create capture channels");
BIOS_exit(0);
}
if (IOM_COMPLETED == status) {
status = FVID_control(capChInfo.chanHandle, Vpif_IOCTL_CMD_GET_CHANNEL_STD_INFO, &capParams);
if (IOM_COMPLETED != status) {
System_printf("Failed to get capture channel info\r\n");
BIOS_exit(0);
}
}
dispheight = capParams.activeLines; //height
dispwidth = capParams.activePixels; //width or bytesperline
sizeimage = dispheight * dispwidth; //sizeimage
for (bufCount = 0; bufCount < NUM_FRAME_BUFFERS; bufCount++) {
// Allocate Frame buffer for capture driver
status = FVID_allocBuffer(capChInfo.chanHandle, &(capChInfo.frame));
if (IOM_COMPLETED != status) {
System_printf("Failed to allocate buffer for capture\r\n");
BIOS_exit(0);
}
else {
System_printf("Cap: Alloc frame->frame.rpFrm = 0x%x\r\n", capChInfo.frame->frame.rpFrm);
System_printf("Cap: Alloc capChInfo.frame = 0x%x\r\n", capChInfo.frame);
// After mapping each buffer, it is a good idea to first "zero"
//memset((Char *)capChInfo.frame->frame.rpFrm, 0x00, sizeimage);
// Queue the frame buffers for capture
status = FVID_queue(capChInfo.chanHandle, &(capChInfo.frame));
if (IOM_COMPLETED != status) {
System_printf("Failed to Queue capture buffer\r\n");
BIOS_exit(0);
}
}
}
// start capture channel
status = FVID_control(capChInfo.chanHandle, Vpif_IOCTL_CMD_START, NULL);
if (IOM_COMPLETED != status) {
System_printf("Failed to start capture channel device\r\n");
BIOS_exit(0);
}
// Request a frame buffer from capture driver
if (IOM_COMPLETED == status) {
// Capture buffer will return the latest captured buffer
status = FVID_dequeue(capChInfo.chanHandle, &(capChInfo.frame));
if (IOM_COMPLETED != status) {
System_printf("Failed to dequeue capture channel device\r\n");
BIOS_exit(0);
}
System_printf("DQ Cap vpifFrm.rpFrm = 0x%x\r\n", capChInfo.frame->frame.rpFrm);
}
while (framecount < 10) {
framecount++;
// Invalidate the buffer before giving to capture driver
Cache_inv(capChInfo.frame->frame.rpFrm.buf, sizeimage, Cache_Type_ALL, TRUE);
// Give the old capture frame buffer back to driver and get the
// recently captured frame buffer
status = FVID_exchange(capChInfo.chanHandle, &(capChInfo.frame));
if (IOM_COMPLETED != status) {
System_printf("Error in exchanging capture buffer\r\n");
BIOS_exit(0);
}
else {
// Flush and invalidate the processed buffer so that the DMA
// reads the processed data
Cache_wbInv(capChInfo.frame->frame.rpFrm.buf, sizeimage, Cache_Type_ALL, TRUE);
}
}
// Stop capture
status = FVID_control(capChInfo.chanHandle, Vpif_IOCTL_CMD_STOP, NULL);
if (IOM_COMPLETED != status) {
System_printf("Error in stopping capture operation\r\n");
BIOS_exit(0);
}
status = FVID_freeBuffer(capChInfo.chanHandle, &(capChInfo.frame));
if(IOM_COMPLETED != status) {
System_printf("IOM_COMPLETED != status for free buff\r\n");
BIOS_exit(0);
}
// Dequeue buffers from driver and free them
for (bufCount = 0; bufCount < (NUM_FRAME_BUFFERS - 1u); bufCount++) {
status = FVID_dequeue(capChInfo.chanHandle, &(capChInfo.frame));
if (IOM_COMPLETED != status) {
System_printf("IOM_COMPLETED != status for DQ\r\n");
BIOS_exit(0);
}
System_printf("DQ vpifFrm.rpFrm = 0x%x\r\n", capChInfo.frame->frame.rpFrm);
status = FVID_freeBuffer(capChInfo.chanHandle, &(capChInfo.frame));
if(IOM_COMPLETED != status) {
System_printf("IOM_COMPLETED != status for free buff\r\n");
BIOS_exit(0);
}
}
status = FVID_delete(capChInfo.chanHandle);
if (IOM_COMPLETED != status) {
System_printf("Failed to delete capture channel\r\n");
}
}
void VPIF_enable_capture(Semaphore_Handle* picture_done) {
SEM_picture_done = picture_done;
}
// DEV_create(...) uses it to init VPIF
static void vpif_device_init_fxn() {
Vpif_init();
vpifParams = Vpif_PARAMS;
vpifParams.hwiNumber = 9u;
vpifParams.dmaReqSize = Vpif_DmaReqSize_256BYTE;
}
static void vpifConfig(EvmInit_VpifChannel channelNo) {
CSL_SyscfgRegsOvly vpifSysCfgRegs = (CSL_SyscfgRegsOvly)CSL_SYSCFG_0_REGS;
if (vpifSysCfgRegs == NULL) {
System_printf("vpifSysCfgRegs is NULLe\r\n");
BIOS_exit(0);
}
// Enable write access to PINMUX and CFG registers in KICK0R and KICK1R
KICK0R = KICK0R_VPIF_ENABLE;
KICK1R = KICK1R_VPIF_ENABLE;
// Enable the pinmux configuration for the VPIF device
switch (channelNo)
{
case EvmInit_VpifChannel_0:
vpifSysCfgRegs->PINMUX14 &= PINMUX14_VPIF0_CH0_MASK;
vpifSysCfgRegs->PINMUX14 |= PINMUX14_VPIF0_CH0_ENABLE;
vpifSysCfgRegs->PINMUX15 &= PINMUX15_VPIF0_CH0_MASK;
vpifSysCfgRegs->PINMUX15 |= PINMUX15_VPIF0_CH0_ENABLE;
break;
case EvmInit_VpifChannel_1:
vpifSysCfgRegs->PINMUX14 &= PINMUX14_VPIF0_CH1_MASK;
vpifSysCfgRegs->PINMUX14 |= PINMUX14_VPIF0_CH1_ENABLE;
vpifSysCfgRegs->PINMUX15 &= PINMUX15_VPIF0_CH1_MASK;
vpifSysCfgRegs->PINMUX15 |= PINMUX15_VPIF0_CH1_ENABLE;
vpifSysCfgRegs->PINMUX16 &= PINMUX16_VPIF0_CH1_MASK;
vpifSysCfgRegs->PINMUX16 |= PINMUX16_VPIF0_CH1_ENABLE;
break;
case EvmInit_VpifChannel_2:
vpifSysCfgRegs->PINMUX16 &= PINMUX16_VPIF0_CH2_MASK;
vpifSysCfgRegs->PINMUX16 |= PINMUX16_VPIF0_CH2_ENABLE;
vpifSysCfgRegs->PINMUX17 &= PINMUX17_VPIF0_CH2_MASK;
vpifSysCfgRegs->PINMUX17 |= PINMUX17_VPIF0_CH2_ENABLE;
vpifSysCfgRegs->PINMUX19 &= PINMUX19_VPIF0_CH2_MASK;
vpifSysCfgRegs->PINMUX19 |= PINMUX19_VPIF0_CH2_ENABLE;
break;
case EvmInit_VpifChannel_3:
vpifSysCfgRegs->PINMUX17 &= PINMUX17_VPIF0_CH3_MASK;
vpifSysCfgRegs->PINMUX17 |= PINMUX17_VPIF0_CH3_ENABLE;
vpifSysCfgRegs->PINMUX18 &= PINMUX18_VPIF0_CH3_MASK;
vpifSysCfgRegs->PINMUX18 |= PINMUX18_VPIF0_CH3_ENABLE;
vpifSysCfgRegs->PINMUX19 &= PINMUX19_VPIF0_CH3_MASK;
vpifSysCfgRegs->PINMUX19 |= PINMUX19_VPIF0_CH3_ENABLE;
break;
case EvmInit_VpifChannel_BOTHCAPCH:
vpifSysCfgRegs->PINMUX14 &= PINMUX14_VPIF0_BOTH_CAP_MASK;
vpifSysCfgRegs->PINMUX14 |= PINMUX14_VPIF0_BOTH_CAP_ENABLE;
vpifSysCfgRegs->PINMUX15 &= PINMUX15_VPIF0_BOTH_CAP_MASK;
vpifSysCfgRegs->PINMUX15 |= PINMUX15_VPIF0_BOTH_CAP_ENABLE;
vpifSysCfgRegs->PINMUX16 &= PINMUX16_VPIF0_BOTH_CAP_MASK;
vpifSysCfgRegs->PINMUX16 |= PINMUX16_VPIF0_BOTH_CAP_ENABLE;
break;
case EvmInit_VpifChannel_BOTHDISPCH:
vpifSysCfgRegs->PINMUX16 &= PINMUX16_VPIF0_BOTH_DISP_MASK;
vpifSysCfgRegs->PINMUX16 |= PINMUX16_VPIF0_BOTH_DISP_ENABLE;
vpifSysCfgRegs->PINMUX17 &= PINMUX17_VPIF0_BOTH_DISP_MASK;
vpifSysCfgRegs->PINMUX17 |= PINMUX17_VPIF0_BOTH_DISP_ENABLE;
vpifSysCfgRegs->PINMUX18 &= PINMUX18_VPIF0_BOTH_DISP_MASK;
vpifSysCfgRegs->PINMUX18 |= PINMUX18_VPIF0_BOTH_DISP_ENABLE;
vpifSysCfgRegs->PINMUX19 &= PINMUX19_VPIF0_BOTH_DISP_MASK;
vpifSysCfgRegs->PINMUX19 |= PINMUX19_VPIF0_BOTH_DISP_ENABLE;
break;
default:
System_printf("VPIF init: invalid case\r\n");
BIOS_exit(0);
break;
}
}
@andresv
Copy link
Author

andresv commented Feb 8, 2013

This version has a bug: FVID_create(...) returns with -10. It means it is called with wrong arguments.

@andresv
Copy link
Author

andresv commented Feb 27, 2013

Revision 2 is correct.

@xiaowenliu
Copy link

Andresv,

I am working on conf. the VPIF to capture the raw image data. The used DSP is OMAPl138, which is similar as C6748. I referenced you code, however, cannot get the correct data.

These is the value of the register. I was wondering, could you take a look whether the registers value is correct? Thanks in advance.
reg[0x 0]=0x4c080a01
reg[0x 4]=0x20011405 reg[0x 8]=0x 405 reg[0x c]=0x 0 reg[0x 10]=0x 0
reg[0x 14]=0x 0 reg[0x 18]=0x 0 reg[0x 1c]=0x 0 reg[0x 20]=0x 13
reg[0x 24]=0x 13 reg[0x 28]=0x 0 reg[0x 2c]=0x 0 reg[0x 30]=0x 0
reg[0x 34]=0x 1 reg[0x 38]=0x 100 reg[0x 3c]=0x 0 reg[0x 40]=0xc6400400
reg[0x 44]=0xc6400e00 reg[0x 48]=0xc6400400 reg[0x 4c]=0xc6400e00 reg[0x 50]=0x 0
reg[0x 54]=0x 0 reg[0x 58]=0x 0 reg[0x 5c]=0x 0 reg[0x 60]=0x 0
reg[0x 64]=0x a00 reg[0x 68]=0x 0 reg[0x 6c]=0x 640500 reg[0x 70]=0x 0
reg[0x 74]=0x 2d00000 reg[0x 78]=0x 0 reg[0x 7c]=0x 2d0 reg[0x 80]=0xc6400400
reg[0x 84]=0x 0 reg[0x 88]=0xc64e1400 reg[0x 8c]=0xc64e1e00 reg[0x 90]=0x 0
reg[0x 94]=0x 0 reg[0x 98]=0x 0 reg[0x 9c]=0x 0 reg[0x a0]=0x 0
reg[0x a4]=0x a00 reg[0x a8]=0x 0 reg[0x ac]=0x 0 reg[0x b0]=0x 0
reg[0x b4]=0x 0 reg[0x b8]=0x 0 reg[0x bc]=0x 2d0 reg[0x c0]=0x 0
reg[0x c4]=0x 0 reg[0x c8]=0x 0 reg[0x cc]=0x 0 reg[0x d0]=0x 0
reg[0x d4]=0x 0 reg[0x d8]=0x 0 reg[0x dc]=0x 0 reg[0x e0]=0x 0
reg[0x e4]=0x 0 reg[0x e8]=0x 0 reg[0x ec]=0x 0 reg[0x f0]=0x 0
reg[0x f4]=0x 0 reg[0x f8]=0x 0 reg[0x fc]=0x 0 reg[0x100]=0x 0
reg[0x104]=0x 0 reg[0x108]=0x 0 reg[0x10c]=0x 0 reg[0x110]=0x 0
reg[0x114]=0x 0 reg[0x118]=0x 0 reg[0x11c]=0x 0 reg[0x120]=0x 0
reg[0x124]=0x 0 reg[0x128]=0x 0 reg[0x12c]=0x 0 reg[0x130]=0x 0
reg[0x134]=0x 0 reg[0x138]=0x 0 reg[0x13c]=0x 0 reg[0x140]=0x 0
reg[0x144]=0x 0 reg[0x148]=0x 0 reg[0x14c]=0x 0 reg[0x150]=0x 0
reg[0x154]=0x 0 reg[0x158]=0x 0 reg[0x15c]=0x 0 reg[0x160]=0x 0
reg[0x164]=0x 0 reg[0x168]=0x 0 reg[0x16c]=0x 0 reg[0x170]=0x 0
reg[0x174]=0x 0 reg[0x178]=0x 0 reg[0x17c]=0x 0 reg[0x180]=0x 0
reg[0x184]=0x 0 reg[0x188]=0x 0 reg[0x18c]=0x 0 reg[0x190]=0x 0
reg[0x194]=0x 0 reg[0x198]=0x 0 reg[0x19c]=0x 0
root@omapl138-lcdk:/proc#

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment