DCMI on STM32F750 successfully capturing images, but won't generate interrupts
Hi,
I have a board that I designed using the STM32F750Z8. It transfers data from a Himax hm01b0 image sensor via the DCMI port to USB using DMA.
This is a stripped down version of my FreeRTOS thread that initializes and reads the image sensor. I've removed parts that I feel are irrelevant.
void camera_task(void const* args)
{
camera_frame_ready_semaphore = xSemaphoreCreateBinaryStatic(&camera_frame_ready_semaphore_buffer);
// ...
// initialize image sensor power supply and clock.
// image sensor does not start sending frames yet. pclk, vsync, and hsync are inactive.
// ...
// enable DMA clock
__HAL_RCC_DMA2_CLK_ENABLE();
__HAL_RCC_DCMI_CLK_ENABLE();
osDelay(1);
// setup DCMI
#if 0
DCMI->CWSIZER = (239 << 16) | (((320 * 2) - 1) << 0); // image is 640 x 240 (this is correct.)
DCMI->CWSTRTR = ( 2 << 16) | ( 4 << 0); // 2x4 pixel border around edge.
DCMI->CR |= (1 << 2); // enable crop feature
#endif
DCMI->IER = (1 << 3);
DCMI->CR |= (1 << 14);
// setup DMA2 Stream7 to read double-buffered from DCMI data reg
dma_setup_xfer();
// enable DCMI IRQs in NVIC
HAL_NVIC_SetPriority(DCMI_IRQn, 10, 0);
HAL_NVIC_EnableIRQ(DCMI_IRQn);
// enable DCMI capture
DCMI->CR |= (1 << 0);
osDelay(1);
// ...
// Configure and enable image sensor. Now vsync, hsync, and pixclk start.
// ...
while (1) {
// wait til DMA is finished
xSemaphoreTake(camera_frame_ready_semaphore, portMAX_DELAY);
// do some light processing on the image and enqueue the data for another thread
write_request_t req = {.buf = (void*)camera_packedbuf[backbuf_idx], .len = buflen};
(xQueueSendToBack(write_request_queue, (const void*)&req, 0);
}
With this code I have no problem reading images off my board. As far as I can tell, the board design is correct and it's been assembled correctly. pixclk, hsync, and vsync are all electrically connected to the MCU (I've tested it using regular GPIOs). If they weren't I wouldn't be getting video.
But I'm having 2 issues with the DCMI peripheral.
1. No matter what I do, all of the status bits are stuck at 0 (and so no interrupts are generated).
Even though the DCMI is reading camera data (and clearly must be reading vsync and hsync), the FNE, VSYNC, and HSYNC bits in the DCMI status register are always 0.
Furthermore, all of the raw interrupt status bits are stuck at 0 (except for a single "vsync_ris" that only appears on the very first frame. I've tried re-enabling "vsync_ris" after clearing it, but that doesn't do anything). I have no idea how the DCMI peripheral is working even though none of its status bits are doing anything, but it's working!
I need vsync and hsync interrupts for my application!
2. The crop function appears to be completely broken
If I uncomment the code that enables cropping (and I also adjust the DMA size appropriately), the DCMI peripheral shows no signs of life at all. This isn't a must-have - I can crop in software - but I have no idea why this isn't working. It seems simple enough, and my code does exactly what STM32Cube would've done.
I have 2 boards that I've tested this on, and the behavior is the same as far as I can tell.
I wonder if there's some undocumented errata or setup requirements with the DCMI peripheral. It shouldn't be this hard to use, and the issues I'm running into don't make any sense.
Thanks!
- John

