2021-12-04 03:51 AM
Hello there.
On my board I've setup DCMI to read some arbitrary data from ADC. I've planed to use JPEG mode to just capture all the raw data from ADC while HSYNC is in LOW state. There is my timing diagram:The thing is I do not get FRAME interrupt nor any data in my destination buffer. The LINE and VSYNC Interrupts got triggered, but FRAME and ERROR or any of the DMA interrupts just never happening. For me it looks like pixclk is just ignored somehow, but is definately there. I've tryed setup DCMI by bare registers or by CUBEide.
Is there some common thing I've missed?
Initialization code:
static void MX_DMA_Init(void)
{
/* DMA controller clock enable */
__HAL_RCC_DMA1_CLK_ENABLE();
/* DMA interrupt init */
/* DMA1_Stream3_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Stream3_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream3_IRQn);
}
static void MX_DCMI_Init(void)
{
hdcmi.Instance = DCMI;
hdcmi.Init.SynchroMode = DCMI_SYNCHRO_HARDWARE;
hdcmi.Init.PCKPolarity = DCMI_PCKPOLARITY_FALLING;
hdcmi.Init.VSPolarity = DCMI_VSPOLARITY_LOW;
hdcmi.Init.HSPolarity = DCMI_HSPOLARITY_LOW;
hdcmi.Init.CaptureRate = DCMI_CR_ALL_FRAME;
hdcmi.Init.ExtendedDataMode = DCMI_EXTEND_DATA_14B;
hdcmi.Init.JPEGMode = DCMI_JPEG_ENABLE;
hdcmi.Init.ByteSelectMode = DCMI_BSM_ALL;
hdcmi.Init.ByteSelectStart = DCMI_OEBS_ODD;
hdcmi.Init.LineSelectMode = DCMI_LSM_ALL;
hdcmi.Init.LineSelectStart = DCMI_OELS_ODD;
if (HAL_DCMI_Init(&hdcmi) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN DCMI_Init 2 */
HAL_DCMI_RegisterCallback(&hdcmi, HAL_DCMI_FRAME_EVENT_CB_ID, dcmi_callback);
HAL_DCMI_RegisterCallback(&hdcmi, HAL_DCMI_ERROR_CB_ID, dcmi_callback_err);
/* USER CODE END DCMI_Init 2 */
}
void HAL_DCMI_MspInit(DCMI_HandleTypeDef* hdcmi)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(hdcmi->Instance==DCMI)
{
/* USER CODE BEGIN DCMI_MspInit 0 */
/* USER CODE END DCMI_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_DCMI_CLK_ENABLE();
__HAL_RCC_GPIOI_CLK_ENABLE();
__HAL_RCC_GPIOG_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOE_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOH_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/**DCMI GPIO Configuration
PI6 ------> DCMI_D6
PI5 ------> DCMI_VSYNC
PI4 ------> DCMI_D5
PG10 ------> DCMI_D2
PC10 ------> DCMI_D8
PI0 ------> DCMI_D13
PI7 ------> DCMI_D7
PE1 ------> DCMI_D3
PD6 ------> DCMI_D10
PC11 ------> DCMI_D4
PI2 ------> DCMI_D9
PH15 ------> DCMI_D11
PA10 ------> DCMI_D1
PA9 ------> DCMI_D0
PG6 ------> DCMI_D12
PA6 ------> DCMI_PIXCLK
PH8 ------> DCMI_HSYNC
*/
//Pin setup ommited//
/* DCMI DMA Init */
/* DCMI Init */
hdma_dcmi.Instance = DMA1_Stream3;
hdma_dcmi.Init.Request = DMA_REQUEST_DCMI;
hdma_dcmi.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_dcmi.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_dcmi.Init.MemInc = DMA_MINC_ENABLE;
hdma_dcmi.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
hdma_dcmi.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
hdma_dcmi.Init.Mode = DMA_NORMAL;
hdma_dcmi.Init.Priority = DMA_PRIORITY_VERY_HIGH;
hdma_dcmi.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
if (HAL_DMA_Init(&hdma_dcmi) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(hdcmi,DMA_Handle,hdma_dcmi);
/* DCMI interrupt Init */
HAL_NVIC_SetPriority(DCMI_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(DCMI_IRQn);
/* USER CODE BEGIN DCMI_MspInit 1 */
/* USER CODE END DCMI_MspInit 1 */
}
}
// Start DMA
HAL_DCMI_Start_DMA(&hdcmi, DCMI_MODE_SNAPSHOT, (uint32_t)(ADCData), 64);
Thanks
UPD:
Found in HAL Init() function flowing line:
/* Enable the Line, Vsync, Error and Overrun interrupts */
__HAL_DCMI_ENABLE_IT(hdcmi, DCMI_IT_LINE | DCMI_IT_VSYNC | DCMI_IT_ERR | DCMI_IT_OVR);
For some reason FRAME_IF is simply not enabled. Hmm.... okay. Anyway, DMA is still does not seem to work.
UPD:
I've disconnected PIXCLK from MCU, but kept V/HSYNC signal inplace. LINE/VSYNC Interrupts stopped generation. Looks like PIXCLK going through DCMI.
UPD:
Tried to poll FNE bit of DCMI->SR register. It always stays at zero. This is all very stange. PIXCLK seems to work, but no data captured.