This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

OMAP-L138 LCDK VPIF raw data capture mode problem

Other Parts Discussed in Thread: OMAPL138, OMAP-L138

Hi

I have reference the sample code( vpif_lcd_loopback project)from
OMAPL138_StarterWare_1_10_04_01, and It's work. Then I try to do
raw data capture mode via camera sensor on my board
(OMAP-L138 LCDK ),but it doesn't work.

1.Is this OMAP-L138 LCDK board support VPIF raw data capture mode?
Technical Reference Manual (Literature Number: SPRUH77A) say
OMAP-L138 does support this mode,but i use the kite board, so i am not really sure.
or it i need do something on my board?

2.I attach the c file. I follow the concept and register setting from the
sample code, but i can't get any frame or line interrupt.


environment:
http://processors.wiki.ti.com/index.php/L138/C6748_Development_Kit_(LCDK)
CCS 5.5.0.00077

Thanks~

3782.vpif_raw.c
/* page tables start must be aligned in 16K boundary */
#ifdef __TMS470__
#pragma DATA_ALIGN(pageTable, 16384);
//static volatile unsigned int pageTable[4*1024];
#elif defined(__IAR_SYSTEMS_ICC__)
#pragma data_alignment=16384
static volatile unsigned int pageTable[4*1024];
#elif _TMS320C6X
#else
static volatile unsigned int pageTable[4*1024] __attribute__((aligned(16*1024)));
#endif

unsigned int            buffcount=0, buffcount2;
volatile unsigned int   captured=0, changed=0, updated=0, processed=1;
unsigned char           *buff_luma[2], *buff_chroma[2];
unsigned char           *videoTopY, *videoTopC;

void main(void)
{
    init_VPIF();

    SetUpVPIFRx();

    enable_VPIF();
    
    while(1)
    {
        VPIF_DMA_read(DISPLAY_IMAGE_HEIGHT);
    
    }
	
}

void init_VPIF(void)
{
#ifndef _TMS320C6X
    unsigned int index;
#endif

    /* Setting the Master priority for the VPIF and LCD DMA controllers to highest level */
    //HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_MSTPRI1) &= 0x00FFFFFF;
    //HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_MSTPRI2) &= 0x0FFFFFFF;

#ifdef _TMS320C6X
    /* Set MAR bits and configure L1 cache */
    CacheEnableMAR((unsigned int)0xC0000000, (unsigned int)0x10000000);
    CacheEnable(L1PCFG_L1PMODE_32K | L1DCFG_L1DMODE_32K );
#else

    /* Sets up 'Level 1" page table entries.
     * The page table entry consists of the base address of the page
     * and the attributes for the page. The following operation is to
     * setup one-to-one mapping page table for DDR memeory range and set
     * the attributes for the same. The DDR memory range is from 0xC0000000
     * to 0xCFFFFFFF. Thus the base of the page table ranges from 0xC00 to
     * 0xCFF. Cache(C bit) and Write Buffer(B bit) are enabled  only for
     * those page table entries which maps to DDR RAM and internal RAM.
     * All the pages in the DDR range are provided with R/W permissions */
    for(index = 0; index < (4*1024); index++)
    {
         if((index >= 0xC00 && index < 0xD00)|| (index == 0x800))
         {
              pageTable[index] = (index << 20) | 0x00000C1E;
         }
         else
         {
              pageTable[index] = (index << 20) | 0x00000C12;
         }
    }

    /* Configures translation table base register
     * with pagetable base address. */
    CP15TtbSet((unsigned int )pageTable);

    /* Enables MMU */
    CP15MMUEnable();

    /* Enable Cache */
    CacheEnable (CACHE_ALL);

#endif

    /* Power on VPIF */
    PSCModuleControl(SOC_PSC_1_REGS, HW_PSC_VPIF, PSC_POWERDOMAIN_ALWAYS_ON,
            PSC_MDCTL_NEXT_ENABLE);
    /* Setup VPIF pinmux */
    VPIFPinMuxSetup();

}

void VPIF_DMA_read(unsigned int line_num)
{

    /* Wait here till a new frame is not captured */
    while (!captured);

#ifdef _TMS320C6X
    CacheWBInv((unsigned int) Rgb_buffer0, DISPLAY_IMAGE_WIDTH * DISPLAY_IMAGE_HEIGHT * 2);
    CacheWBInv((unsigned int) Rgb_buffer1, DISPLAY_IMAGE_WIDTH * DISPLAY_IMAGE_HEIGHT * 2);
#else
    CacheDataCleanInvalidateBuff ( (unsigned int) Rgb_buffer1,
            DISPLAY_IMAGE_WIDTH * DISPLAY_IMAGE_HEIGHT * 2);
#endif

    captured = 0;
    processed = 1;
}

void enable_VPIF(void)
{
    VPIFDMARequestSizeConfig(SOC_VPIF_0_REGS, VPIF_REQSIZE_ONE_TWENTY_EIGHT);// DMA transfer size 128
    VPIFEmulationControlSet(SOC_VPIF_0_REGS, VPIF_HALT);

    /* Initialize buffer addresses for a new frame*/
    VPIFCaptureFBConfig(SOC_VPIF_0_REGS, VPIF_CHANNEL_0, VPIF_TOP_FIELD,
            VPIF_LUMA, (unsigned int) buff_luma[0], DISPLAY_IMAGE_WIDTH*2);
    VPIFCaptureFBConfig(SOC_VPIF_0_REGS, VPIF_CHANNEL_1, VPIF_TOP_FIELD,
    		VPIF_LUMA, (unsigned int) buff_luma1[0], DISPLAY_IMAGE_WIDTH*2);

    /* Enable capture */
    VPIFCaptureChanenEnable(SOC_VPIF_0_REGS, VPIF_CHANNEL_0);
    VPIFCaptureChanenEnable(SOC_VPIF_0_REGS, VPIF_CHANNEL_1);

    /* Enable VPIF interrupt */
    VPIFInterruptEnable(SOC_VPIF_0_REGS, VPIF_FRAMEINT_CH0);
    VPIFInterruptEnable(SOC_VPIF_0_REGS, VPIF_FRAMEINT_CH1);
    VPIFInterruptEnableSet(SOC_VPIF_0_REGS, VPIF_FRAMEINT_CH0);
    VPIFInterruptEnableSet(SOC_VPIF_0_REGS, VPIF_FRAMEINT_CH1);

    buffcount++;
    buffcount2 = buffcount - 1;
}

/*
 * Initialize capture
 */
void SetUpVPIFRx(void)
{

    /* Disable interrupts */
    VPIFInterruptDisable(SOC_VPIF_0_REGS, VPIF_FRAMEINT_CH1);
    VPIFInterruptDisable(SOC_VPIF_0_REGS, VPIF_FRAMEINT_CH0);

    /* Disable capture ports */
    VPIFCaptureChanenDisable(SOC_VPIF_0_REGS, VPIF_CHANNEL_1);
    VPIFCaptureChanenDisable(SOC_VPIF_0_REGS, VPIF_CHANNEL_0);

    /* Interrupt after capturing the bottom field of every frame */
    VPIFCaptureIntframeConfig(SOC_VPIF_0_REGS, VPIF_CHANNEL_0, VPIF_FRAME_INTERRUPT_TOP);

    /* Capture RAW data */
    VPIFCaptureModeConfig(SOC_VPIF_0_REGS, VPIF_RAW, VPIF_CHANNEL_0, 0, (struct vbufParam *) 0);

    VPIFCaptureRawDatawidthConfig(SOC_VPIF_0_REGS, VPIF_RAW_TWELVE_BPS); // 12-bit mode

    VPIFCaptureRawIntlineConfig(SOC_VPIF_0_REGS, 3);

    VPIFCaptureIntrprogModeSelect(SOC_VPIF_0_REGS, VPIF_CHANNEL_0, VPIF_CAPTURE_PROGRESSIVE);

    VPIFCaptureCapmodeModeSelect(SOC_VPIF_0_REGS, VPIF_CHANNEL_0, VPIF_CAPTURE_RAW);

    VPIFCaptureClkedgeModeSelect(SOC_VPIF_0_REGS, VPIF_CHANNEL_0, VPIF_CLKEDGE_RISING);

    /* Y/C interleaved capture over 8-bit bus */
    VPIFCaptureYcmuxModeSelect(SOC_VPIF_0_REGS, VPIF_CHANNEL_0, VPIF_YC_NONMUXED);

    /* Interrupt after capturing the bottom field of every frame */
    VPIFCaptureIntframeConfig(SOC_VPIF_0_REGS, VPIF_CHANNEL_1, VPIF_FRAME_INTERRUPT_TOP);

    /* Capture RAW data */
    VPIFCaptureModeConfig(SOC_VPIF_0_REGS, VPIF_RAW, VPIF_CHANNEL_1, 0, (struct vbufParam *) 0);

    VPIFCaptureIntrprogModeSelect(SOC_VPIF_0_REGS, VPIF_CHANNEL_1, VPIF_CAPTURE_PROGRESSIVE);

    VPIFCaptureCapmodeModeSelect(SOC_VPIF_0_REGS, VPIF_CHANNEL_1, VPIF_CAPTURE_RAW);

    VPIFCaptureClkedgeModeSelect(SOC_VPIF_0_REGS, VPIF_CHANNEL_1, VPIF_CLKEDGE_RISING);

    /* Y/C interleaved capture over 8-bit bus */
    VPIFCaptureYcmuxModeSelect(SOC_VPIF_0_REGS, VPIF_CHANNEL_1, VPIF_YC_NONMUXED);
}

/*
** VPIF Interrupt service routine.
*/
void VPIFIsr(void)
{
#ifdef _TMS320C6X
    IntEventClear(SYS_INT_VPIF_INT);
#else
    IntSystemStatusClear(SYS_INT_VPIF);
#endif

    /* If previously captured frame not processed, clear this interrupt and return */
    if (!processed)
    {
        VPIFInterruptStatusClear(SOC_VPIF_0_REGS, VPIF_FRAMEINT_CH0);
        VPIFInterruptStatusClear(SOC_VPIF_0_REGS, VPIF_FRAMEINT_CH1);
        return;
    }

    /* buffcount represents buffer to be given to capture driver and
     * buffcount2 represents the newly captured buffer to be processed */
    processed = 0;
    captured = 0;
    buffcount++;
    buffcount2 = buffcount - 1;
    /* Currently only two buffers are being used for capture */
    if (buffcount == 2)
        buffcount = 0;

     /* Invalidate the buffers before giving to capture driver*/
#ifdef _TMS320C6X
    CacheInv((unsigned int) buff_luma[buffcount],
    		DISPLAY_IMAGE_WIDTH * DISPLAY_IMAGE_HEIGHT * 2);
    CacheInv((unsigned int) buff_chroma[buffcount],
    		DISPLAY_IMAGE_WIDTH * DISPLAY_IMAGE_HEIGHT * 2);
#else

    CacheDataInvalidateBuff (
            (unsigned int) buff_luma[buffcount],
            DISPLAY_IMAGE_WIDTH * DISPLAY_IMAGE_HEIGHT * 2);
    CacheDataInvalidateBuff (
            (unsigned int) buff_chroma[buffcount],
            DISPLAY_IMAGE_WIDTH * DISPLAY_IMAGE_HEIGHT * 2);

#endif

    /* Initialize buffer addresses for a new frame*/
    VPIFCaptureFBConfig(SOC_VPIF_0_REGS, VPIF_CHANNEL_0, VPIF_TOP_FIELD,
            VPIF_LUMA, (unsigned int) buff_luma[buffcount], DISPLAY_IMAGE_WIDTH*2);
    VPIFCaptureFBConfig(SOC_VPIF_0_REGS, VPIF_CHANNEL_1, VPIF_TOP_FIELD,
    		VPIF_LUMA, (unsigned int) buff_luma1[buffcount], DISPLAY_IMAGE_WIDTH*2);

    /* Initialize buffer addresses with the captured frame ready to be processed */
    videoTopC = buff_chroma[buffcount2];
    videoTopY = buff_luma[buffcount2];
    captured = 1;

    /* clear interrupt */
    VPIFInterruptStatusClear(SOC_VPIF_0_REGS, VPIF_FRAMEINT_CH0);
    VPIFInterruptStatusClear(SOC_VPIF_0_REGS, VPIF_FRAMEINT_CH1);
}

Bill

  • Hi Bill,

    Thanks for your post.

    Actually LCDK board has HW support for RAW capture device, because it has connector for LeopardImaging camera boards. VPIF configuration is based on vpifloopback demo and you need to modify the code to support RAW capture from CMOS sensor.

    Here is the configuration: https://gist.github.com/andresv/4739017

    You can use the example from the ~\OMAPL138_StarterWare_1_10_03_03\examples\evmOMAPL138\vpif_loopback_sd\vpifLoopbackSD.c and use this source as reference and modify the sequence in the initialize capture function SetUpVPIFRx() to work for raw capture mode. Please see the attached source file for reference and compare vpifLoopbackSD.c & vpiftransfer.c (attached file). Actually vpiftransfer.c is the source file modified for raw data capture and kindly review the attached file.

    static void SetUpVPIFRx(void) {
        // Disable interrupts
        VPIFInterruptDisable(SOC_VPIF_0_REGS, VPIF_FRAMEINT_CH1);
        VPIFInterruptDisable(SOC_VPIF_0_REGS, VPIF_FRAMEINT_CH0);
        // Disable capture ports
        VPIFCaptureChanenDisable(SOC_VPIF_0_REGS, VPIF_CHANNEL_1);
        VPIFCaptureChanenDisable(SOC_VPIF_0_REGS, VPIF_CHANNEL_0);
        // Interrupt after capturing the bottom field of every frame
        VPIFCaptureIntframeConfig(SOC_VPIF_0_REGS, VPIF_CHANNEL_0, VPIF_FRAME_INTERRUPT_BOTTOM);

        // RAW mode
        VPIFCaptureCapmodeModeSelect(SOC_VPIF_0_REGS, VPIF_CHANNEL_0, VPIF_CAPTURE_RAW);
        VPIFCaptureModeConfig(SOC_VPIF_0_REGS, VPIF_RAW, VPIF_CHANNEL_0, 0, (VPIFVbufParam*) 0);

        // 12 bit data
        VPIFCaptureRawDatawidthConfig(SOC_VPIF_0_REGS, VPIF_RAW_TWELVE_BPS);

        // Progressive capture
        VPIFCaptureIntrprogModeSelect(SOC_VPIF_0_REGS, VPIF_CHANNEL_0, VPIF_CAPTURE_PROGRESSIVE);
    }

    7624.vpiftransfer.c
    /*
     *  Created on: 29.11.2012
     *      Author: Andres Vahter
     */
    
    #include "psc.h"
    #include "vpif.h"
    #include "interrupt.h"
    #include "evmC6748.h"
    #include "soc_C6748.h"
    #include "hw_psc_C6748.h"
    
    #include "vpiftransfer.h"
    
    #define HORIZONTAL_PIXEL_COUNT 	1280
    #define VERTICAL_PIXEL_COUNT 	960
    
    #define VBUF_SIZE	(HORIZONTAL_PIXEL_COUNT * VERTICAL_PIXEL_COUNT)
    #define VBUF_ALIGN  (8)
    
    unsigned char chromaTop[VBUF_SIZE]__attribute__((aligned(VBUF_ALIGN)));
    unsigned char chromaBottom[VBUF_SIZE]__attribute__((aligned(VBUF_ALIGN)));
    unsigned char lumaTop[VBUF_SIZE]__attribute__((aligned(VBUF_ALIGN)));
    unsigned char lumaBottom[VBUF_SIZE]__attribute__((aligned(VBUF_ALIGN)));
    
    
    void VPIF_init(void) {
    	// Power on VPIF
    	PSCModuleControl(SOC_PSC_1_REGS, HW_PSC_VPIF, PSC_POWERDOMAIN_ALWAYS_ON, PSC_MDCTL_NEXT_ENABLE);
    
    	// Initializing DSP INTC
    	SetupIntc();
    
        // Setup VPIF pinmux & Initialize VPIF
        VPIFPinMuxSetup();
    
        SetUpVPIFRx();
    
        VPIFDMARequestSizeConfig(SOC_VPIF_0_REGS, VPIF_REQSIZE_ONE_TWENTY_EIGHT);
        VPIFEmulationControlSet(SOC_VPIF_0_REGS, VPIF_FREE);
    
        // Initialize buffer address for 1st frame
        VPIFCaptureFBConfig(SOC_VPIF_0_REGS, VPIF_CHANNEL_0, VPIF_TOP_FIELD, VPIF_LUMA, (unsigned int)&lumaTop[0], HORIZONTAL_PIXEL_COUNT);
        VPIFCaptureFBConfig(SOC_VPIF_0_REGS, VPIF_CHANNEL_0, VPIF_TOP_FIELD, VPIF_CHROMA, (unsigned int)&chromaTop[0], HORIZONTAL_PIXEL_COUNT);
        VPIFCaptureFBConfig(SOC_VPIF_0_REGS, VPIF_CHANNEL_0, VPIF_BOTTOM_FIELD, VPIF_LUMA, (unsigned int)&lumaBottom[0], HORIZONTAL_PIXEL_COUNT);
        VPIFCaptureFBConfig(SOC_VPIF_0_REGS, VPIF_CHANNEL_0, VPIF_BOTTOM_FIELD, VPIF_CHROMA, (unsigned int)&chromaBottom[0], HORIZONTAL_PIXEL_COUNT);
    }
    
    void VPIF_enable_capture(void) {
        // Enable capture
        VPIFCaptureChanenEnable(SOC_VPIF_0_REGS, VPIF_CHANNEL_0);
        VPIFInterruptEnable(SOC_VPIF_0_REGS, VPIF_FRAMEINT_CH0);
        VPIFInterruptEnableSet(SOC_VPIF_0_REGS, VPIF_FRAMEINT_CH0);
    }
    
    // Initialize capture
    static void SetUpVPIFRx(void) {
        // Disable interrupts
        VPIFInterruptDisable(SOC_VPIF_0_REGS, VPIF_FRAMEINT_CH1);
        VPIFInterruptDisable(SOC_VPIF_0_REGS, VPIF_FRAMEINT_CH0);
        // Disable capture ports
        VPIFCaptureChanenDisable(SOC_VPIF_0_REGS, VPIF_CHANNEL_1);
        VPIFCaptureChanenDisable(SOC_VPIF_0_REGS, VPIF_CHANNEL_0);
        // Interrupt after capturing the bottom field of every frame
        VPIFCaptureIntframeConfig(SOC_VPIF_0_REGS, VPIF_CHANNEL_0, VPIF_FRAME_INTERRUPT_BOTTOM);
    
        // RAW mode
        VPIFCaptureCapmodeModeSelect(SOC_VPIF_0_REGS, VPIF_CHANNEL_0, VPIF_CAPTURE_RAW);
        VPIFCaptureModeConfig(SOC_VPIF_0_REGS, VPIF_RAW, VPIF_CHANNEL_0, 0, (VPIFVbufParam*) 0);
    
        // 12 bit data
        VPIFCaptureRawDatawidthConfig(SOC_VPIF_0_REGS, VPIF_RAW_TWELVE_BPS);
    
        // Progressive capture
        VPIFCaptureIntrprogModeSelect(SOC_VPIF_0_REGS, VPIF_CHANNEL_0, VPIF_CAPTURE_PROGRESSIVE);
    }
    
    // Configures DSP interrupt controller to generate frame interrupt
    static void SetupIntc(void) {
        // Initialize the DSP interrupt controller
        IntDSPINTCInit();
    
        // Register ISR to vector table
        IntRegister(C674X_MASK_INT5, VPIFIsr);
    
        // Map system interrupt to DSP maskable interrupt
        IntEventMap(C674X_MASK_INT5, SYS_INT_VPIF_INT);
    
        // Enable DSP maskable interrupt
        IntEnable(C674X_MASK_INT5);
    
        // Enable DSP interrupts
        IntGlobalEnable();
    }
    
    // Interrupt service routine.
    static void VPIFIsr(void) {
        unsigned int status;
    
        IntEventClear(SYS_INT_VPIF_INT);
    
        status = VPIFInterruptStatus(SOC_VPIF_0_REGS, VPIF_ERROR_INT | VPIF_FRAMEINT_CH1 | VPIF_FRAMEINT_CH0);
    
    	VPIFCaptureFBConfig(SOC_VPIF_0_REGS, VPIF_CHANNEL_0, VPIF_TOP_FIELD, VPIF_LUMA, (unsigned int)&lumaTop[0], HORIZONTAL_PIXEL_COUNT);
    	VPIFCaptureFBConfig(SOC_VPIF_0_REGS, VPIF_CHANNEL_0, VPIF_TOP_FIELD, VPIF_CHROMA, (unsigned int)&chromaTop[0], HORIZONTAL_PIXEL_COUNT);
    	VPIFCaptureFBConfig(SOC_VPIF_0_REGS, VPIF_CHANNEL_0, VPIF_BOTTOM_FIELD, VPIF_LUMA, (unsigned int)&lumaBottom[0], HORIZONTAL_PIXEL_COUNT);
    	VPIFCaptureFBConfig(SOC_VPIF_0_REGS, VPIF_CHANNEL_0, VPIF_BOTTOM_FIELD, VPIF_CHROMA, (unsigned int)&chromaBottom[0], HORIZONTAL_PIXEL_COUNT);
    
        // clear interrupt
        VPIFInterruptStatusClear(SOC_VPIF_0_REGS, VPIF_FRAMEINT_CH0);
    
        // if error interrupt occurs, report error
        if ((status & VPIF_ERROR_INT)) {
            // what to do?
        }
    }
    

    Note: In general, VPIF will issue line-interval triggered interrupts using the field/frame interrupt signals. The line-interval is programmable in the C0CTRL register, and it uses the FRAME1 interrupt signal.

    So to get interrupt for each line you need to set the line-interval INTLINE to 1. Please check the C0CTRL register value of VPIF. For more details to get the line interrupts, please refer the below E2E post:

    http://e2e.ti.com/support/dsp/omap_applications_processors/f/42/t/327167.aspx

    Thanks & regards,

    Sivaraj K

    -------------------------------------------------------------------------------------------------------
    Please click the Verify Answer button on this post if it answers your question.
    -------------------------------------------------------------------------------------------------------
  • Hi Sivaraj K

    Thank for your reply,

    I reference vpiftransfer.c  to modify my code, i have a little confuse,

    I have read the document of Technical Reference Manual (Literature Number: SPRUH77A),

     

    1.In  VPIF part, It mention that if i use raw data capture 12- bit, i need to use channel 0 and channel 1 to

    receive data, but vpiftransfer.c only configure channel 0 register,is it right!? and enable just 

    channel 0 !? (I get the interrupt only if I enable both channel 0 and 1)

    2.According to the document description, progressive video must use the Frame storage mode,

    and data only in Top field,  and vpiftransfer.c also configure the Button file register. Is it right !?

    3.I also try the line interrupt function, i get the correct line number if line-interval INTLINE set 1,

     

    Bill

     

  • Hi, sam

    I encountered a problem as you.

    I have configured kernel as ti's wiki.

    when i use vpif capture raw video from ov2715, i can not reveive any interrupt.  interrupt enable bits has been actived, and ov2715 has output Vsync/Hsync signal

    environment is :

    OMAPL138 LCDK board

    MCSDK

    could you give some tips please ?

    looking forward to your reply!

     

  • Hi Quote

    First, i think you can check your camera line which connect to the OMAPL138 and ov2715 device.

    Can you find Vsync/Hsync signal on your OMAPL138 device.(It means that signal certainty pass to your device)

    Second, in my experience, you should enable two channel of VPIF to get the interrupt, then data will occur in channel 0.

    you can try~

    or you can attach your vpif code, then i can give you suggestion more specific.

      

  • Hi Hu,

    I have the problem to config VPIF for raw image capture. The code attached. Could you check them. Thanks.

  • Hi Quote

    Sorry~ i can't see your code.Do you really attached!?

    Sam

  • Hi Sum,

    This is the link for my question.
    e2e.ti.com/.../397431
    Could you reply that? Thanks.