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~
/* 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