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.

CC3220SF-LAUNCHXL: Camera Peripheral Bringup Issues

Part Number: CC3220SF-LAUNCHXL
Other Parts Discussed in Thread: CC3200, , CC3220SF

Hello,

For the past few weeks, I have been trying to get the CC3220 parallel camera interface to work with an OV9655 camera sensor. So far, I have not been able to get the camera peripheral to capture any sort of data from the camera. As this peripheral does not have example code, I did not have anything to base my code off of besides the older CC3200 camera example code. Below is my relevant setup code which I believe is correct based off of other peripherals. This code successfully runs, however the camera callback function never gets called. In addition, I also print out the status of all the camera interrupts and they are never asserted. The only indication that the code is actually doing something is that the CC3220 begins to output the XCLK signal. Beyond this, the peripheral fails to latch any sort of data.

CC3220SF-LAUNCHXL.h

typedef enum CC3220SF_LAUNCHXL_CameraName {
    CC3220SF_LAUNCHXL_CAMERA0 = 0,

    CC3220SF_LAUNCHXL_CAMERACOUNT
} CC3220SF_LAUNCHXL_CameraName;

CC3220SF_LAUNCHXL.c

#include <ti/drivers/Camera.h>
#include <ti/drivers/camera/CameraCC32XXDMA.h>

CameraCC32XXDMA_Object cameraCC3220SFObjects[CC3220SF_LAUNCHXL_CAMERACOUNT];

const CameraCC32XXDMA_HWAttrs CameraCC32XXDMAHWAttrs[CC3220SF_LAUNCHXL_CAMERACOUNT] = {
       {
           .baseAddr = CAMERA_BASE,
           .intNum = INT_CAMERA,
           .intPriority = (~0),
           .channelIndex = UDMA_CH22_CAMERA
       }
};

const Camera_Config Camera_config[CC3220SF_LAUNCHXL_CAMERACOUNT] = {
    {
         .fxnTablePtr = &CameraCC32XXDMA_fxnTable,
         .object = &cameraCC3220SFObjects[CC3220SF_LAUNCHXL_CAMERA0],
         .hwAttrs = &CameraCC32XXDMAHWAttrs[CC3220SF_LAUNCHXL_CAMERA0],
    }
};

ov9655.c

void camera_pins_init(void)
{
    MAP_PRCMPeripheralClkEnable(PRCM_CAMERA, PRCM_RUN_MODE_CLK);
    MAP_PRCMCameraFreqSet(4, 2);

    MAP_PinTypeCamera(PIN_02, PIN_MODE_4); // Output Camera Clock
    MAP_PinTypeCamera(PIN_55, PIN_MODE_4); // Input Pixel Clock
    MAP_PinTypeCamera(PIN_04, PIN_MODE_4); // HSYNC Input
    MAP_PinTypeCamera(PIN_03, PIN_MODE_4); // VSYNC Input
    MAP_PinTypeCamera(PIN_61, PIN_MODE_4); // DATA0
    MAP_PinTypeCamera(PIN_60, PIN_MODE_4); // DATA1
    MAP_PinTypeCamera(PIN_59, PIN_MODE_4); // DATA2
    MAP_PinTypeCamera(PIN_58, PIN_MODE_4); // DATA3
    MAP_PinTypeCamera(PIN_05, PIN_MODE_4); // DATA4
    MAP_PinTypeCamera(PIN_06, PIN_MODE_4); // DATA5
    MAP_PinTypeCamera(PIN_07, PIN_MODE_4); // DATA6
    MAP_PinTypeCamera(PIN_08, PIN_MODE_4); // DATA7
}

int camera_peripheral_init(void)
{
    Camera_Params camera_params;

    camera_pins_init();
    Camera_Params_init(&camera_params);

    camera_params.captureMode = Camera_MODE_CALLBACK;
    camera_params.outputClock = 10000000;                           
    camera_params.hsyncPolarity = Camera_HSYNC_POLARITY_HIGH;
    camera_params.vsyncPolarity = Camera_VSYNC_POLARITY_LOW;
    camera_params.pixelClkConfig = Camera_PCLK_CONFIG_RISING_EDGE;
    camera_params.byteOrder = Camera_BYTE_ORDER_NORMAL;
    camera_params.interfaceSync = Camera_INTERFACE_SYNC_OFF;
    camera_params.stopConfig = Camera_STOP_CAPTURE_IMMEDIATE;
    camera_params.startConfig = Camera_START_CAPTURE_FRAME_START;
    camera_params.captureTimeout = Camera_WAIT_FOREVER;
    camera_params.captureCallback = &camera_callback;

    Camera_init();
    camera = Camera_open(0, &camera_params);

    if (camera == NULL)
        return 1;
    else
        return 0;
}

int ov9655_init(void)
{
    uint16_t i;
    int_fast16_t return_val = 0;
    uint8_t *dma_buffer;
    size_t frame_len = 0;

    dma_buffer = pvPortMalloc(sizeof(uint8_t) * BUFFER_LEN);
    for (i = 0; i < BUFFER_LEN; i++)
        *(dma_buffer + i) = 0;

    camera_peripheral_init();

    camera_print_interrupts();

    return_val = Camera_capture(camera, dma_buffer, BUFFER_LEN, &frame_len);

    if (return_val == CAMERA_STATUS_ERROR)
        Display_printf(display, 0, 0, "CAMERA_STATUS_ERROR");

    while(1)
        camera_print_interrupts();

    return 0;
}

void camera_print_interrupts(void)
{
    unsigned long interrupt_val = 0;

    interrupt_val = CameraIntStatus(CAMERA_BASE);

    if (interrupt_val & CAM_INT_FS)
    {
        Display_printf(display, 0, 0, "Frame Start Interrupt");
        CameraIntClear(CAMERA_BASE, CAM_INT_FS);
    }

    if (interrupt_val & CAM_INT_LE)
    {
        Display_printf(display, 0, 0, "Line End Interrupt");
        CameraIntClear(CAMERA_BASE, CAM_INT_LE);
    }

    if (interrupt_val & CAM_INT_LS)
    {
        Display_printf(display, 0, 0, "Line Start Interrupt");
        CameraIntClear(CAMERA_BASE, CAM_INT_LS);
    }

    if (interrupt_val & CAM_INT_FSP_ERR)
    {
        Display_printf(display, 0, 0, "FSP Code Error Interrupt");
        CameraIntClear(CAMERA_BASE, CAM_INT_FSP_ERR);
    }

    if (interrupt_val & CAM_INT_FW_ERR)
    {
        Display_printf(display, 0, 0, "Frame Height Error Interrupt");
        CameraIntClear(CAMERA_BASE, CAM_INT_FW_ERR);
    }

    if (interrupt_val & CAM_INT_FSC_ERR)
    {
        Display_printf(display, 0, 0, "False Synch Error Interrupt");
        CameraIntClear(CAMERA_BASE, CAM_INT_FSC_ERR);
    }
    if (interrupt_val & CAM_INT_SSC_ERR)
    {
        Display_printf(display, 0, 0, "Shifted Synch Error Interrupt");
        CameraIntClear(CAMERA_BASE, CAM_INT_SSC_ERR);
    }

    if (interrupt_val & CAM_INT_FIFO_NOEMPTY)
    {
        Display_printf(display, 0, 0, "FIFO Not Empty Interrupt");
        CameraIntClear(CAMERA_BASE, CAM_INT_FIFO_NOEMPTY);
    }

    if (interrupt_val & CAM_INT_FIFO_FULL)
    {
        Display_printf(display, 0, 0, "FIFO Full Interrupt");
        CameraIntClear(CAMERA_BASE, CAM_INT_FIFO_FULL);
    }

    if (interrupt_val & CAM_INT_FIFO_THR)
    {
        Display_printf(display, 0, 0, "FIFO Threshold Interrupt");
        CameraIntClear(CAMERA_BASE, CAM_INT_FIFO_THR);
    }

    if (interrupt_val & CAM_INT_FIFO_OF)
    {
        Display_printf(display, 0, 0, "FIFO Overflow Interrupt");
        CameraIntClear(CAMERA_BASE, CAM_INT_FIFO_OF);
    }

    if (interrupt_val & CAM_INT_FIFO_UR)
    {
        Display_printf(display, 0, 0, "FIFO Underflow Interrupt");
        CameraIntClear(CAMERA_BASE, CAM_INT_FIFO_UR);
    }
}

At this point, I am starting to run out of ideas. I have looked at all the reference material online but there is no official example code for the CC3220 camera peripheral that I have found. The main reason we chose the CC3220 is due to the parallel camera interface but the peripheral does not seem to be well fleshed out with examples or others using the peripheral online. Any support would be greatly appreciated!

Thanks,

Nicholas Kimball

  • Hi Nicholas,

    Are you seeing any issue with the return values from the camera related function calls above? Have you tried probing the relevant pins for data with a logic analyzer or oscilloscope to verify data on the lines?

    It may also be useful to refer to the reference on using the parallel camera interface.

  • Hi Austin,

    Thank you for your hasty response, your urgency on this topic is greatly appreciated! I am working on this project with Nicholas Kimball who originally asked the question above.

    We have spent quite a few hours trying to determine if the functions are all returning expected, positive values and they area. We have also probed all of our pins and verified that the signals all look appropriate and that we can see camera data on the camera data pins. Like Nicholas pointed out above, we have code to print out all of the camera interrupt states repeatedly. Unfortunately, none of the interrupts are being set at any time and it almost appears as though the camera peripheral of the CC3220 doesn't recognize that a camera is connected - perhaps the camera peripheral inside of the CC3220 isn't being powered on??

    The CC3200 camera application that you link is something that we looked at a few months back when we first started this project. Unfortunately, it isn't very useful as the CC3200 and the CC3220 vary quite heavily in their applicable resources, reference materials, and examples.

    Any further information on this subject would be greatly appreciated!

    Best,
    Shane
  • Hi Shane,

    Are any interrupts getting triggered--even those not related to the camera peripheral?

    The example code related to the camera peripheral should be similarly applicable for the CC3220 device.
  • Hi Shane and Nicholas,

    I haven't received a response on the questions above, so I'm assuming you were able to resolve your issue. I'll go ahead and close this thread, but if you have additional questions please create a new thread with a link to this original thread.
  • I believe the problem was with the DMA not being properly initialized. The camera peripheral would fail to start as a result.
  • Hi Nicholas,

    This reference design below might be of help to you. There is CC3220 example program included.

    www.ti.com/.../TIDC-CC3200-VIDEO

    -kel
  • Thanks for sharing the root cause for this issue Nicholas!