예제 #1
0
/******************************************************************************
**                      INTERNAL FUNCTION DEFINITIONS
*******************************************************************************/
int main(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 atributes 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 Instruction Cache */
    CP15ICacheEnable();

    /* Enable Data Cache */
    CP15DCacheEnable();
#endif

    /* Allocate pointers to buffers */
    buff_luma[0] = buff_luma1;
    buff_luma[1] = buff_luma2;
    buff_chroma[0] = buff_chroma1;
    buff_chroma[1] = buff_chroma2;

    /* Initializing palette for first buffer */
    Rgb_buffer1[0] = 0x4000;
    for (i = 1; i < 16; i++)
        Rgb_buffer1[i] = 0x0000;
    videoTopRgb1 = Rgb_buffer1 + i;

    /* Initializing palette for second buffer */
    Rgb_buffer2[0] = 0x4000;
    for (i = 1; i < 16; i++)
        Rgb_buffer2[i] = 0x0000;
    videoTopRgb2 = Rgb_buffer2 + i;

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

    /* Initializing ARM/DSP INTC */
    SetupIntc();

    /* Initialize I2C and program UI GPIO expander, TVP5147, and ADV7343 via I2C */
    I2CPinMuxSetup(0);

    /* enable video via gpio expander to ensure we have exclusive access to the bus */
    I2CCodecIfInit(SOC_I2C_0_REGS, INT_CHANNEL_I2C, I2C_SLAVE_UI_EXPANDER);
    I2CGPIOInit(SOC_I2C_0_REGS);
    I2CGPIOSetOutput(SOC_I2C_0_REGS);

    /*Initialize the TVP5147 to accept composite video */
    I2CCodecIfInit(SOC_I2C_0_REGS, INT_CHANNEL_I2C,
            I2C_SLAVE_CODEC_TVP5147_2_COMPOSITE);
    TVP5147CompositeInit(SOC_I2C_0_REGS);

    /* Setup VPIF pinmux */
    VPIFPinMuxSetup();

    /* Setup LCD */
    SetUpLCD();

    /* Initialize VPIF */
    SetUpVPIFRx();
    VPIFDMARequestSizeConfig(SOC_VPIF_0_REGS, VPIF_REQSIZE_ONE_TWENTY_EIGHT);
    VPIFEmulationControlSet(SOC_VPIF_0_REGS, VPIF_HALT);

    /* Initialize buffer addresses for 1st frame*/
    VPIFCaptureFBConfig(SOC_VPIF_0_REGS, VPIF_CHANNEL_0, VPIF_TOP_FIELD,
            VPIF_LUMA, (unsigned int) buff_luma[0], CAPTURE_IMAGE_WIDTH*2);
    VPIFCaptureFBConfig(SOC_VPIF_0_REGS, VPIF_CHANNEL_0, VPIF_TOP_FIELD,
            VPIF_CHROMA, (unsigned int) buff_chroma[0], CAPTURE_IMAGE_WIDTH*2);
    VPIFCaptureFBConfig(SOC_VPIF_0_REGS, VPIF_CHANNEL_0, VPIF_BOTTOM_FIELD,
            VPIF_LUMA, (unsigned int) (buff_luma[0] + CAPTURE_IMAGE_WIDTH), CAPTURE_IMAGE_WIDTH*2);
    VPIFCaptureFBConfig(SOC_VPIF_0_REGS, VPIF_CHANNEL_0, VPIF_BOTTOM_FIELD,
            VPIF_CHROMA, (unsigned int) (buff_chroma[0] + CAPTURE_IMAGE_WIDTH), CAPTURE_IMAGE_WIDTH*2);

    /* configuring the base ceiling */
    RasterDMAFBConfig(SOC_LCDC_0_REGS, (unsigned int) Rgb_buffer2,
            (unsigned int) (Rgb_buffer2 + DISPLAY_IMAGE_WIDTH * DISPLAY_IMAGE_HEIGHT + 15), 0);
    RasterDMAFBConfig(SOC_LCDC_0_REGS, (unsigned int) Rgb_buffer2,
            (unsigned int) (Rgb_buffer2 + DISPLAY_IMAGE_WIDTH * DISPLAY_IMAGE_HEIGHT + 15), 1);

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

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

    /* enable End of frame interrupt */
    RasterEndOfFrameIntEnable(SOC_LCDC_0_REGS);

    /* enable raster */
    RasterEnable(SOC_LCDC_0_REGS);

    buffcount++;
    buffcount2 = buffcount - 1;

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

        /* Process the next buffer only when both the raster buffers
         * are pointing to the current buffer to avoid jitter effect */
        if (updated == 3)
        {
            processed = 0;
            changed = 0;
            updated = 0;

         /* Convert the buffer from CBCR422 semi-planar to RGB565,
          *  Flush and invalidate the processed buffer so that the DMA reads the processed data,
          *  set the flag for the buffer to be displayed on the LCD (which would be the processed buffer)
          *  and notify the LCD of availability of a processed buffer.
          *  The output buffers are ping-ponged each time. */
            if (pingpong)
            {
                cbcr422sp_to_rgb565_c(
                        (const unsigned char *) (videoTopC + OFFSET),
                        DISPLAY_IMAGE_HEIGHT, CAPTURE_IMAGE_WIDTH, ccCoeff,
                        (const unsigned char *) (videoTopY + OFFSET),
                        CAPTURE_IMAGE_WIDTH, videoTopRgb1, DISPLAY_IMAGE_WIDTH, DISPLAY_IMAGE_WIDTH);
            #ifdef _TMS320C6X
                CacheWBInv((unsigned int) videoTopRgb1, DISPLAY_IMAGE_WIDTH * DISPLAY_IMAGE_HEIGHT * 2);
            #else
                CP15DCacheCleanBuff((unsigned int) videoTopRgb1,DISPLAY_IMAGE_WIDTH * DISPLAY_IMAGE_HEIGHT * 2);
            #endif
                display_buff_1 = 1;
                changed = 1;
            }
            else
            {
                cbcr422sp_to_rgb565_c(
                        (const unsigned char *) (videoTopC + OFFSET),
                        DISPLAY_IMAGE_HEIGHT, CAPTURE_IMAGE_WIDTH, ccCoeff,
                        (const unsigned char *) (videoTopY + OFFSET),
                        CAPTURE_IMAGE_WIDTH, videoTopRgb2, DISPLAY_IMAGE_WIDTH, DISPLAY_IMAGE_WIDTH);
            #ifdef _TMS320C6X
                CacheWBInv((unsigned int) videoTopRgb2, DISPLAY_IMAGE_WIDTH * DISPLAY_IMAGE_HEIGHT * 2);
            #else
                CP15DCacheCleanBuff((unsigned int) videoTopRgb2, DISPLAY_IMAGE_WIDTH * DISPLAY_IMAGE_HEIGHT * 2);
            #endif
                display_buff_1 = 0;
                changed = 1;
            }

            pingpong = !pingpong;
            captured = 0;
            processed = 1;
        }
    }
}
예제 #2
0
/*
** The main function. Application starts here.
*/
int main(void)
{
    unsigned short parToSend;
    unsigned short parToLink;

    /* Set up pin mux for I2C module 0 */
    I2CPinMuxSetup(0);
    McASPPinMuxSetup();

    /* Power up the McASP module */
    PSCModuleControl(SOC_PSC_1_REGS, HW_PSC_MCASP0, PSC_POWERDOMAIN_ALWAYS_ON,
                     PSC_MDCTL_NEXT_ENABLE);

    /* Power up EDMA3CC_0 and EDMA3TC_0 */
    PSCModuleControl(SOC_PSC_0_REGS, HW_PSC_CC0, PSC_POWERDOMAIN_ALWAYS_ON,
                     PSC_MDCTL_NEXT_ENABLE);
    PSCModuleControl(SOC_PSC_0_REGS, HW_PSC_TC0, PSC_POWERDOMAIN_ALWAYS_ON,
                     PSC_MDCTL_NEXT_ENABLE);

#ifdef _TMS320C6X
    // Initialize the DSP interrupt controller
    IntDSPINTCInit();
#else
    /* Initialize the ARM Interrupt Controller.*/
    IntAINTCInit();
#endif

    /* Initialize the I2C 0 interface for the codec AIC31 */
    I2CCodecIfInit(SOC_I2C_0_REGS, INT_CHANNEL_I2C, I2C_SLAVE_CODEC_AIC31);

    EDMA3Init(SOC_EDMA30CC_0_REGS, 0);
    EDMA3IntSetup();

    McASPErrorIntSetup();

#ifdef _TMS320C6X
    IntGlobalEnable();
#else
    /* Enable the interrupts generation at global level */
    IntMasterIRQEnable();
    IntGlobalEnable();
    IntIRQEnable();
#endif

    /*
    ** Request EDMA channels. Channel 0 is used for reception and
    ** Channel 1 is used for transmission
    */
    EDMA3RequestChannel(SOC_EDMA30CC_0_REGS, EDMA3_CHANNEL_TYPE_DMA,
                        EDMA3_CHA_MCASP0_TX, EDMA3_CHA_MCASP0_TX, 0);
    EDMA3RequestChannel(SOC_EDMA30CC_0_REGS, EDMA3_CHANNEL_TYPE_DMA,
                        EDMA3_CHA_MCASP0_RX, EDMA3_CHA_MCASP0_RX, 0);

    /* Initialize the DMA parameters */
    I2SDMAParamInit();

    /* Configure the Codec for I2S mode */
    AIC31I2SConfigure();

    /* Configure the McASP for I2S */
    McASPI2SConfigure();

    /* Activate the audio transmission and reception */
    I2SDataTxRxActivate();

    /*
    ** Looop forever. if a new buffer is received, the lastFullRxBuf will be
    ** updated in the rx completion ISR. if it is not the lastSentTxBuf,
    ** buffer is to be sent. This has to be mapped to proper paRAM set.
    */
    while(1)
    {
        if(lastFullRxBuf != lastSentTxBuf)
        {
            /*
            ** Start the transmission from the link paramset. The param set
            ** 1 will be linked to param set at PAR_TX_START. So do not
            ** update paRAM set1.
            */
            parToSend =  PAR_TX_START + (parOffTxToSend % NUM_PAR);
            parOffTxToSend = (parOffTxToSend + 1) % NUM_PAR;
            parToLink  = PAR_TX_START + parOffTxToSend;

            lastSentTxBuf = (lastSentTxBuf + 1) % NUM_BUF;

            ByteBuftoFloatBuf(rxBufPtr[lastFullRxBuf]);

            /* Copy the buffer */
            memcpy((void *)txBufPtr[lastSentTxBuf],
                   (void *)rxBufPtr[lastFullRxBuf],
                   AUDIO_BUF_SIZE);

            /*
            ** Send the buffer by setting the DMA params accordingly.
            ** Here the buffer to send and number of samples are passed as
            ** parameters. This is important, if only transmit section
            ** is to be used.
            */
            BufferTxDMAActivate(lastSentTxBuf, NUM_SAMPLES_PER_AUDIO_BUF,
                                (unsigned short)parToSend,
                                (unsigned short)parToLink);
        }
    }
}