Last active
December 12, 2015 07:48
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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#