Skip to content

Commit 029b8f6

Browse files
committed
Update camera driver.
* Fix broken DMA transfer. * Fix timer frequency (was running at 3MHz). * Fix cache issues. * Update API as requested. * Add skip_frames function.
1 parent efaeb1c commit 029b8f6

File tree

2 files changed

+57
-55
lines changed

2 files changed

+57
-55
lines changed

libraries/Portenta_Camera/camera.cpp

Lines changed: 54 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,16 @@
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

1515
static uint32_t CameraResX = QVGA_RES_X;
1616
static uint32_t CameraResY = QVGA_RES_Y;
1717
static uint32_t LcdResX = 0;
1818
static 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
*/
258250
void 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

334330
static 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

451447
void 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

594597
void CameraClass::testPattern(bool walking)

libraries/Portenta_Camera/camera.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
class CameraClass {
22
public:
33
int begin(int horizontalResolution, int verticalResolution);
4-
uint8_t* snapshot();
5-
int start(uint32_t timeout);
6-
uint8_t* grab(void);
4+
int grab(uint8_t *buffer, uint32_t timeout=5000);
75
void testPattern(bool walking);
8-
};
6+
int skip_frames(uint8_t *buffer, uint32_t n_frames, uint32_t timeout=5000);
7+
};

0 commit comments

Comments
 (0)