77#define LCD_FRAME_BUFFER 0xC0000000 /* LCD Frame buffer of size 800x480 in ARGB8888 */
88#define CAMERA_FRAME_BUFFER 0xC0200000
99
10- #define QVGA_RES_X 324
11- #define QVGA_RES_Y 244
10+ #define QVGA_RES_X 320
11+ #define QVGA_RES_Y 240
1212
1313#define ARGB8888_BYTE_PER_PIXEL 4
1414
1515static uint32_t CameraResX = QVGA_RES_X;
1616static uint32_t CameraResY = QVGA_RES_Y;
1717static uint32_t LcdResX = 0 ;
1818static uint32_t LcdResY = 0 ;
19+ static uint32_t *user_buffer = 0 ;
1920
2021__IO uint32_t camera_frame_ready = 0 ;
2122__IO uint32_t lcd_frame_ready = 0 ;
@@ -92,11 +93,11 @@ void BSP_CAMERA_MspInit(DCMI_HandleTypeDef *hdcmi, void *Params)
9293 hdma_handler.Init .MemInc = DMA_MINC_ENABLE;
9394 hdma_handler.Init .PeriphDataAlignment = DMA_PDATAALIGN_WORD;
9495 hdma_handler.Init .MemDataAlignment = DMA_MDATAALIGN_WORD;
95- hdma_handler.Init .Mode = DMA_CIRCULAR ;
96+ hdma_handler.Init .Mode = DMA_NORMAL ;
9697 hdma_handler.Init .Priority = DMA_PRIORITY_HIGH;
9798 hdma_handler.Init .FIFOMode = DMA_FIFOMODE_DISABLE;
9899 hdma_handler.Init .FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
99- hdma_handler.Init .MemBurst = DMA_MBURST_SINGLE ;
100+ hdma_handler.Init .MemBurst = DMA_MBURST_INC4 ;
100101 hdma_handler.Init .PeriphBurst = DMA_PBURST_SINGLE;
101102
102103 hdma_handler.Instance = CAMERA_DCMI_DMAx_STREAM;
@@ -193,6 +194,10 @@ uint8_t BSP_CAMERA_Init(uint32_t Resolution)
193194 phdcmi->Init .VSPolarity = DCMI_VSPOLARITY_LOW;
194195 phdcmi->Init .ExtendedDataMode = DCMI_EXTEND_DATA_8B;
195196 phdcmi->Init .PCKPolarity = DCMI_PCKPOLARITY_RISING;
197+ phdcmi->Init .ByteSelectMode = DCMI_BSM_ALL; // Capture all received bytes
198+ phdcmi->Init .ByteSelectStart = DCMI_OEBS_ODD; // Ignored
199+ phdcmi->Init .LineSelectMode = DCMI_LSM_ALL; // Capture all received lines
200+ phdcmi->Init .LineSelectStart = DCMI_OELS_ODD; // Ignored
196201 phdcmi->Instance = DCMI;
197202
198203 /* Power up camera */
@@ -204,18 +209,16 @@ uint8_t BSP_CAMERA_Init(uint32_t Resolution)
204209 HAL_DCMI_Init (phdcmi);
205210
206211 /*
207- * @param YSize DCMI Line number
208- * @param XSize DCMI Pixel per line
209212 * @param X0 DCMI window X offset
210213 * @param Y0 DCMI window Y offset
214+ * @param XSize DCMI Pixel per line
215+ * @param YSize DCMI Line number
211216 * @retval HAL status
212217 */
213- // HAL_StatusTypeDef HAL_DCMI_ConfigCrop(DCMI_HandleTypeDef *hdcmi, uint32_t X0, uint32_t Y0, uint32_t XSize, uint32_t YSize)
214-
215- HAL_DCMI_ConfigCROP (phdcmi, (QVGA_RES_X - CameraResX) / 2 , (QVGA_RES_Y - CameraResY / 2 ), CameraResX-1 , CameraResY-1 );
216218 HAL_DCMI_EnableCROP (phdcmi);
219+ HAL_DCMI_ConfigCROP (phdcmi, (QVGA_RES_X - CameraResX) / 2 , (QVGA_RES_Y - CameraResY) / 2 , CameraResX-1 , CameraResY-1 );
217220
218- // HAL_DCMI_DisableCROP(phdcmi );
221+ __HAL_DCMI_DISABLE_IT (&hdcmi_discovery, DCMI_IT_LINE );
219222
220223 CameraCurrentResolution = Resolution;
221224
@@ -239,26 +242,19 @@ uint8_t BSP_CAMERA_DeInit(void)
239242 return 1 ;
240243}
241244
242- /* *
243- * @brief Starts the camera capture in continuous mode.
244- * @param buff: pointer to the camera output buffer
245- * @retval None
246- */
247- void BSP_CAMERA_ContinuousStart (uint8_t *buff)
248- {
249- /* Start the camera capture */
250- HAL_DCMI_Start_DMA (&hdcmi_discovery, DCMI_MODE_CONTINUOUS, (uint32_t )buff, GetSize (CameraCurrentResolution));
251- }
252-
253245/* *
254246 * @brief Starts the camera capture in snapshot mode.
255247 * @param buff: pointer to the camera output buffer
256248 * @retval None
257249 */
258250void BSP_CAMERA_SnapshotStart (uint8_t *buff)
259251{
252+ user_buffer = (uint32_t *) buff;
253+
254+ __HAL_DCMI_ENABLE_IT (&hdcmi_discovery, DCMI_IT_FRAME);
255+
260256 /* Start the camera capture */
261- HAL_DCMI_Start_DMA (&hdcmi_discovery, DCMI_MODE_SNAPSHOT, (uint32_t )buff, GetSize (CameraCurrentResolution));
257+ HAL_DCMI_Start_DMA (&hdcmi_discovery, DCMI_MODE_SNAPSHOT, (uint32_t )buff, GetSize (CameraCurrentResolution)/ 4 );
262258}
263259
264260/* *
@@ -333,8 +329,8 @@ void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim)
333329
334330static int extclk_config (int frequency)
335331{
336- /* TCLK (PCLK * 2 ) */
337- int tclk = DCMI_TIM_PCLK_FREQ () * 2 ;
332+ /* TCLK (PCLK) */
333+ int tclk = DCMI_TIM_PCLK_FREQ ();
338334
339335 /* Period should be even */
340336 int period = (tclk / frequency) - 1 ;
@@ -418,7 +414,7 @@ static uint32_t GetSize(uint32_t Resolution)
418414 break ;
419415 case CAMERA_R320x240:
420416 {
421- size = 324 * 244 ;
417+ size = 320 * 240 ;
422418 }
423419 break ;
424420 case CAMERA_R480x272:
@@ -450,7 +446,8 @@ void BSP_CAMERA_ErrorCallback(void)
450446
451447void BSP_CAMERA_FrameEventCallback (void )
452448{
453- camera_frame_ready++;
449+ camera_frame_ready++;
450+ SCB_InvalidateDCache_by_Addr ((uint32_t *)user_buffer, GetSize (CameraCurrentResolution));
454451}
455452
456453
@@ -536,59 +533,65 @@ int CameraClass::begin(int horizontalResolution, int verticalResolution)
536533 {
537534 return -1 ;
538535 }
536+
539537 return 0 ;
540538}
541539
542- int CameraClass::start ( uint32_t timeout)
540+ int CameraClass::grab ( uint8_t *buffer, uint32_t timeout)
543541{
544542 HIMAX_Mode (HIMAX_Streaming);
545543
544+ BSP_CAMERA_Resume ();
545+
546546 /* Start the Camera Snapshot Capture */
547- BSP_CAMERA_ContinuousStart ((uint8_t *)LCD_FRAME_BUFFER);
548- uint32_t time =millis ();
547+ BSP_CAMERA_SnapshotStart (buffer);
549548
549+ camera_frame_ready = 0 ;
550550 /* Wait until camera frame is ready : DCMI Frame event */
551- while ((camera_frame_ready == 0 ) && ((timeout+time)>millis ()))
552- {
551+ for (uint32_t start = millis (); camera_frame_ready == 0 ;) {
552+ __WFI ();
553+ if ((millis () - start) > timeout) {
554+ HAL_DMA_Abort (hdcmi_discovery.DMA_Handle );
555+ return -1 ;
556+ }
553557 }
554- return camera_frame_ready ? 0 : -1 ;
555- }
556558
557- uint8_t * CameraClass::grab (void )
558- {
559- // HIMAX_Mode(HIMAX_Streaming);
559+ HIMAX_Mode (HIMAX_Standby);
560560
561- /* Start the Camera Snapshot Capture */
562- // BSP_CAMERA_ContinuousStart((uint8_t *)LCD_FRAME_BUFFER);
561+ /* Stop the camera to avoid having the DMA2D work in parallel of Display */
562+ /* which cause perturbation of LTDC */
563+ BSP_CAMERA_Suspend ();
563564
564- /* Wait until camera frame is ready : DCMI Frame event */
565- while (camera_frame_ready == 0 )
566- {
567- }
568- return (uint8_t *)LCD_FRAME_BUFFER;
565+ return 0 ;
569566}
570567
571- uint8_t * CameraClass::snapshot ( void )
568+ int CameraClass::skip_frames ( uint8_t *buffer, uint32_t n_frames, uint32_t timeout )
572569{
573570 HIMAX_Mode (HIMAX_Streaming);
574571
575572 BSP_CAMERA_Resume ();
576573
577574 /* Start the Camera Snapshot Capture */
578- BSP_CAMERA_SnapshotStart ((uint8_t *)LCD_FRAME_BUFFER);
579-
580- /* Wait until camera frame is ready : DCMI Frame event */
581- while (camera_frame_ready == 0 )
582- {
575+ BSP_CAMERA_SnapshotStart (buffer);
576+
577+ while (n_frames--) {
578+ camera_frame_ready = 0 ;
579+ /* Wait until camera frame is ready : DCMI Frame event */
580+ for (uint32_t start = millis (); camera_frame_ready == 0 ;) {
581+ __WFI ();
582+ if ((millis () - start) > timeout) {
583+ HAL_DMA_Abort (hdcmi_discovery.DMA_Handle );
584+ return -1 ;
585+ }
586+ }
583587 }
584588
585589 HIMAX_Mode (HIMAX_Standby);
586590
587591 /* Stop the camera to avoid having the DMA2D work in parallel of Display */
588592 /* which cause perturbation of LTDC */
589593 BSP_CAMERA_Suspend ();
590-
591- return (uint8_t *)LCD_FRAME_BUFFER;
594+ return 0 ;
592595}
593596
594597void CameraClass::testPattern (bool walking)
0 commit comments