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.

OV7670 with tiva c tm4c1294



120MHz speed of c tive tm4c1294 is unable to capture the image of a OV7670, I need help with this as Use the DMA and interrupts but not e able to achieve see the picture well I use a resolution of 160 x 120

  • Hello Emmanuel,

    How are you interfacing the devices?

    Regards
    Amit
  • I use k as input port, use the port E to read VSYNC, PCLK, port E has the interrupt on rising edge on pin E1 reading PCLK, the interrupt active when VSYNC = 1 to capture the byte image in the K port HREF not use it because registration COM10 configure the camera so the value 0x22
  • Hello Emmanuel,

    The Interrupt context takes time to switch the CPU from application code mode to Interrupt Mode. If the camera sensor is too fast, then by the time the CPU reads the GPIO, multiple data bytes may have gone by. That is the case for DMA as well, since the DMA has to load the channel table and it takes finite number of clocks. if the ratio of System Clock / Camera Clock > 6 then I don;t think DMA will be able to capture the data.

    Regards
    Amit
  • Hello Amit.

    the frequency of pixels is 2 MHz bone I have 250ns to capture a byte you think this is possible

    the most you are able to capture and 34777 bytes for a total of 38400 bytes, but the picture when I try to reconstruct an image does not show itself I think is not capturing the bytes when it should be, which is at the leading edge the PCLK

    regards
  • Hello Emmanuel,

    The DMA can work with that speed. However the DMA will only transfer the data when it finds the bus free (CPU is another master on the bus) and it does not know anything about the phase relation of the clock to the data.

    1. So make sure that the data is stable within 4 system clock (!20MHz) of the rising edge of the PCLK.
    2. The HSYNC and VSYNC information is required for the DMA to transfer "valid" bytes. However with the PXCLK approach valid and invalid bytes are both being transferred. How are you addressing this issue?

    Regards
    Amit
  • Hello Amit.
    configures the DMA shot with GPIO E1 is the PXCLK, after checaba software if VSYNC = 0 if so, INTERRUPTION active in E1, then a
    while (VSYNC == 1); the interruption used the dma
  • Hello Emmanuel,

    I am sorry but your message does not make any sense to me. Is it that you are using a Language Translator?

    May be a code post could help!!!

    Regards
    Amit
  • Hello amit

    excuse me, I'm using a translator

    regards
  • I will copy the code in the forum so you can check
  • void confInterrupE()
    {
    //GPIOE_AHB->DIR &= ~0x04; // (c) make PF4 in (built-in button)
    //GPIOE_AHB->AFSEL &= ~0x04; // disable alt funct on PF4
    GPIOE_AHB->DEN |= 0x04; // enable digital I/O on PF4
    //GPIOE_AHB->PCTL &= ~0xF0000000; // configure PF4 as GPIO
    GPIOE_AHB->AMSEL &= ~0x04; // disable analog functionality on PF4

    GPIOE_AHB->IS &= ~0x04; // (d) PF4 is edge-sensitive
    //GPIOE_AHB->IS |= 0x04;
    GPIOE_AHB->IBE &= ~0x04; // PF4 is not both edges


    GPIOE_AHB->IEV |= 0x04; // rising

    GPIOE_AHB->ICR |= 0x04; // (e) clear flag4

    //GPIOE_AHB->DMACTL |=0x04;//activar como disparado de dma

    GPIOE_AHB->IM |= 0x04; // (f) arm interrupt on PF4

    //enable interrupt in NVIC and set priority to 3
    NVIC_EnableIRQ(GPIOE_IRQn);
    NVIC->IP[3]=2<<9;//set interrupt ´priority to 3

    }

    extern "C" void GPIOE_Handler(void)//interrupcionVSYNC
    {
    //buffer[pp]=GPIOK->DATA;
    DMA_Transfer(&GPIOK->DATA,&buffer[pp]);
    pp++;
    GPIOE_AHB->ICR |=0x04;//clear the interrupt flag
    readback = GPIOE_AHB->ICR;
    }

    void initUdma()
    {
    SYSCTL->RCGCDMA =0x01; //habilitar el clock del udma
    UDMA->CFG=0x01; //habilitar el controlador udma
    UDMA->CTLBASE=(uint32_t)ucControlTable; //direccion control de la tabla;

    UDMA->CHMAP1= (UDMA->CHMAP1 &0xF0FFFFFF)|0x03000000;//GPIO D

    UDMA->PRIOCLR = BIT14; //baja prioridad de interrupcion
    UDMA->ALTCLR = BIT14;
    UDMA->USEBURSTCLR = BIT14;
    UDMA->REQMASKCLR = BIT14;


    //GPIOD->DMACTL=0x80;//dispara la udma
    }

    void DMA_Transfer(volatile uint32_t *source, uint8_t *destination){
    static unsigned int i=0;
    ucControlTable[CH14] = (uint32_t)source; // first and last address
    ucControlTable[CH14+1] = (uint32_t)destination;
    ucControlTable[CH14+2] = 0xCC000011;//0x0C000001+((count-1)<<4); // DMA Channel Control Word (DMACHCTL)

    //buffer[count]= ucControlTable[0];


    UDMA->ENASET=BIT14; //

    }

    void ov7670_readframe(void)
    {
    pp=0;
    flagStart=0;
    NVIC_EnableIRQ(GPIOE_IRQn);
    __enable_irq();
    while(VSYNC==1);
    while(VSYNC==0);
    while(VSYNC==1)
    {

    }
    NVIC_DisableIRQ(GPIOE_IRQn);
    flagStart=1;
    }
  • hello amit

    I copy my code in the forum but apparently not appeared anything I can do?
  • Hello Emmanuel

    When DMA is programmed for 0xCC000011, it would mean

    1. The transfer size is 1 and hence DMA needs to be re-init every time wasting a lot of precious clock cycles.
    Suggestion, make the size of the transfer equal to the number of bytes received in 1 line.
    2. Change the Destination Increment to the correct value.

    Regards
    Amit
  • Hello Amit

    but if I do that it will not be synchronized with the PCLK

    regards
  • Hello Emmanuel,

    The trick is to wait for the VSYNC and enable the DMA Trigger generation from the GPIO.

    Regards
    Amit