Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 780323e

Browse files
committedJan 18, 2021
Update the camera drivers.
* Fix pixclk polarity. * Update himax registers. * Support QVGA and QQVGA. * add set_framerate() * add standby() for low-power mode.
1 parent 13b1372 commit 780323e

File tree

5 files changed

+257
-218
lines changed

5 files changed

+257
-218
lines changed
 

‎libraries/Himax_HM01B0/himax.cpp

Lines changed: 172 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ memory mounted on GAPUINO board.
5050

5151
/* Includes ------------------------------------------------------------------*/
5252
#include "himax.h"
53+
#include "camera.h"
5354

5455
/** @addtogroup BSP
5556
* @{
@@ -77,93 +78,122 @@ memory mounted on GAPUINO board.
7778
/** @defgroup GAPUINO_HIMAX_Private_Variables I2C Private Variables
7879
* @{
7980
*/
81+
#define HIMAX_LINE_LEN_PCK_QVGA 0x178
82+
#define HIMAX_FRAME_LENGTH_QVGA 0x104
83+
84+
#define HIMAX_LINE_LEN_PCK_QQVGA 0x178
85+
#define HIMAX_FRAME_LENGTH_QQVGA 0x084
86+
8087
static regval_list_t himax_default_regs[] = {
81-
{BLC_TGT, 0x08}, // BLC target :8 at 8 bit mode
82-
{BLC2_TGT, 0x08}, // BLI target :8 at 8 bit mode
83-
{0x3044, 0x0A}, // Increase CDS time for settling
84-
{0x3045, 0x00}, // Make symetric for cds_tg and rst_tg
85-
{0x3047, 0x0A}, // Increase CDS time for settling
86-
{0x3050, 0xC0}, // Make negative offset up to 4x
87-
{0x3051, 0x42},
88-
{0x3052, 0x50},
89-
{0x3053, 0x00},
90-
{0x3054, 0x03}, // tuning sf sig clamping as lowest
91-
{0x3055, 0xF7}, // tuning dsun
92-
{0x3056, 0xF8}, // increase adc nonoverlap clk
93-
{0x3057, 0x29}, // increase adc pwr for missing code
94-
{0x3058, 0x1F}, // turn on dsun
95-
{0x3059, 0x1E},
96-
{0x3064, 0x00},
97-
{0x3065, 0x04}, // pad pull 0
98-
99-
{BLC_CFG, 0x43}, // BLC_on, IIR
100-
101-
{0x1001, 0x43}, // BLC dithering en
102-
{0x1002, 0x43}, // blc_darkpixel_thd
103-
{0x0350, 0x00}, // Dgain Control
104-
{BLI_EN, 0x01}, // BLI enable
105-
{0x1003, 0x00}, // BLI Target [Def: 0x20]
106-
107-
{DPC_CTRL, 0x01}, // DPC option 0: DPC off 1 : mono 3 : bayer1 5 : bayer2
108-
{0x1009, 0xA0}, // cluster hot pixel th
109-
{0x100A, 0x60}, // cluster cold pixel th
110-
{SINGLE_THR_HOT, 0x90}, // single hot pixel th
111-
{SINGLE_THR_COLD, 0x40}, // single cold pixel th
112-
{0x1012, 0x00}, // Sync. shift disable
113-
{0x2000, 0x07},
114-
{0x2003, 0x00},
115-
{0x2004, 0x1C},
116-
{0x2007, 0x00},
117-
{0x2008, 0x58},
118-
{0x200B, 0x00},
119-
{0x200C, 0x7A},
120-
{0x200F, 0x00},
121-
{0x2010, 0xB8},
122-
{0x2013, 0x00},
123-
{0x2014, 0x58},
124-
{0x2017, 0x00},
125-
{0x2018, 0x9B},
126-
127-
{AE_CTRL, 0x01}, //Automatic Exposure
128-
{AE_TARGET_MEAN, 0x3C}, //AE target mean [Def: 0x3C]
129-
{AE_MIN_MEAN, 0x0A}, //AE min target mean [Def: 0x0A]
130-
131-
{INTEGRATION_H, 0x01}, //Integration H [Def: 0x01]
132-
{INTEGRATION_L, 0x08}, //Integration L [Def: 0x08]
133-
{ANALOG_GAIN, 0x00}, //Analog Global Gain [Def: 0x00]
134-
{DAMPING_FACTOR, 0x20}, //Damping Factor [Def: 0x20]
135-
{DIGITAL_GAIN_H, 0x01}, //Digital Gain High [Def: 0x01]
136-
{DIGITAL_GAIN_L, 0x00}, //Digital Gain Low [Def: 0x00]
137-
138-
{CONVERGE_IN_TH, 0x03}, //Converge in threshold [Def: 0x03]
139-
{CONVERGE_OUT_TH, 0x05}, //Converge out threshold [Def: 0x05]
140-
{MAX_INTG_H, 0x01}, //Maximum INTG High Byte [Def: 0x01]
141-
{MAX_INTG_L, 0x54}, //Maximum INTG Low Byte [Def: 0x54]
142-
{MAX_AGAIN_FULL, 0x03}, //Maximum Analog gain in full frame mode [Def: 0x03]
143-
{MAX_AGAIN_BIN2, 0x04}, //Maximum Analog gain in bin2 mode [Def: 0x04]
144-
145-
{0x210B, 0xC0},
146-
{0x210E, 0x00}, //Flicker Control
147-
{0x210F, 0x00},
148-
{0x2110, 0x3C},
149-
{0x2111, 0x00},
150-
{0x2112, 0x32},
151-
152-
{0x2150, 0x30},
153-
{0x0340, 0x02},
154-
{0x0341, 0x16},
155-
{0x0342, 0x01},
156-
{0x0343, 0x78},
157-
{0x3010, 0x01}, // 324 x 244 pixel
158-
{0x0383, 0x01},
159-
{0x0387, 0x01},
160-
{0x0390, 0x00},
161-
{0x3011, 0x70},
162-
{0x3059, 0x02},
163-
{0x3060, 0x00},
164-
//{0x0601, 0x01},
165-
{IMG_ORIENTATION, 0x00},
166-
{0x0104, 0x01}
88+
{BLC_TGT, 0x08}, // BLC target :8 at 8 bit mode
89+
{BLC2_TGT, 0x08}, // BLI target :8 at 8 bit mode
90+
{0x3044, 0x0A}, // Increase CDS time for settling
91+
{0x3045, 0x00}, // Make symetric for cds_tg and rst_tg
92+
{0x3047, 0x0A}, // Increase CDS time for settling
93+
{0x3050, 0xC0}, // Make negative offset up to 4x
94+
{0x3051, 0x42},
95+
{0x3052, 0x50},
96+
{0x3053, 0x00},
97+
{0x3054, 0x03}, // tuning sf sig clamping as lowest
98+
{0x3055, 0xF7}, // tuning dsun
99+
{0x3056, 0xF8}, // increase adc nonoverlap clk
100+
{0x3057, 0x29}, // increase adc pwr for missing code
101+
{0x3058, 0x1F}, // turn on dsun
102+
{0x3059, 0x1E},
103+
{0x3064, 0x00},
104+
{0x3065, 0x04}, // pad pull 0
105+
106+
{BLC_CFG, 0x43}, // BLC_on, IIR
107+
108+
{0x1001, 0x43}, // BLC dithering en
109+
{0x1002, 0x43}, // blc_darkpixel_thd
110+
{0x0350, 0x7F}, // Dgain Control
111+
{BLI_EN, 0x01}, // BLI enable
112+
{0x1003, 0x00}, // BLI Target [Def: 0x20]
113+
114+
{DPC_CTRL, 0x01}, // DPC option 0: DPC off 1 : mono 3 : bayer1 5 : bayer2
115+
{0x1009, 0xA0}, // cluster hot pixel th
116+
{0x100A, 0x60}, // cluster cold pixel th
117+
{SINGLE_THR_HOT, 0x90}, // single hot pixel th
118+
{SINGLE_THR_COLD, 0x40}, // single cold pixel th
119+
{0x1012, 0x00}, // Sync. shift disable
120+
{0x2000, 0x07},
121+
{0x2003, 0x00},
122+
{0x2004, 0x1C},
123+
{0x2007, 0x00},
124+
{0x2008, 0x58},
125+
{0x200B, 0x00},
126+
{0x200C, 0x7A},
127+
{0x200F, 0x00},
128+
{0x2010, 0xB8},
129+
{0x2013, 0x00},
130+
{0x2014, 0x58},
131+
{0x2017, 0x00},
132+
{0x2018, 0x9B},
133+
134+
{AE_CTRL, 0x01}, //Automatic Exposure
135+
{AE_TARGET_MEAN, 0x3C}, //AE target mean [Def: 0x3C]
136+
{AE_MIN_MEAN, 0x0A}, //AE min target mean [Def: 0x0A]
137+
{CONVERGE_IN_TH, 0x03}, //Converge in threshold [Def: 0x03]
138+
{CONVERGE_OUT_TH, 0x05}, //Converge out threshold [Def: 0x05]
139+
{MAX_INTG_H, (HIMAX_FRAME_LENGTH_QVGA-2)>>8}, //Maximum INTG High Byte [Def: 0x01]
140+
{MAX_INTG_L, (HIMAX_FRAME_LENGTH_QVGA-2)&0xFF}, //Maximum INTG Low Byte [Def: 0x54]
141+
{MAX_AGAIN_FULL, 0x03}, //Maximum Analog gain in full frame mode [Def: 0x03]
142+
{MAX_AGAIN_BIN2, 0x04}, //Maximum Analog gain in bin2 mode [Def: 0x04]
143+
{MAX_DGAIN, 0xC0},
144+
145+
{INTEGRATION_H, 0x01}, //Integration H [Def: 0x01]
146+
{INTEGRATION_L, 0x08}, //Integration L [Def: 0x08]
147+
{ANALOG_GAIN, 0x00}, //Analog Global Gain [Def: 0x00]
148+
{DAMPING_FACTOR, 0x20}, //Damping Factor [Def: 0x20]
149+
{DIGITAL_GAIN_H, 0x01}, //Digital Gain High [Def: 0x01]
150+
{DIGITAL_GAIN_L, 0x00}, //Digital Gain Low [Def: 0x00]
151+
152+
{FS_CTRL, 0x00}, //Flicker Control
153+
154+
{FS_60HZ_H, 0x00},
155+
{FS_60HZ_L, 0x3C},
156+
{FS_50HZ_H, 0x00},
157+
{FS_50HZ_L, 0x32},
158+
159+
{MD_CTRL, 0x30},
160+
{FRAME_LEN_LINES_H, HIMAX_FRAME_LENGTH_QVGA>>8},
161+
{FRAME_LEN_LINES_L, HIMAX_FRAME_LENGTH_QVGA&0xFF},
162+
{LINE_LEN_PCK_H, HIMAX_LINE_LEN_PCK_QVGA>>8},
163+
{LINE_LEN_PCK_L, HIMAX_LINE_LEN_PCK_QVGA&0xFF},
164+
{QVGA_WIN_EN, 0x01}, // Enable QVGA window readout
165+
{0x0383, 0x01},
166+
{0x0387, 0x01},
167+
{0x0390, 0x00},
168+
{0x3011, 0x70},
169+
{0x3059, 0x02},
170+
{OSC_CLK_DIV, 0x0B},
171+
{IMG_ORIENTATION, 0x00}, // change the orientation
172+
{0x0104, 0x01},
173+
};
174+
175+
static regval_list_t himax_qvga_regs[] = {
176+
{0x0383, 0x01},
177+
{0x0387, 0x01},
178+
{0x0390, 0x00},
179+
{MAX_INTG_H, (HIMAX_FRAME_LENGTH_QVGA-2)>>8},
180+
{MAX_INTG_L, (HIMAX_FRAME_LENGTH_QVGA-2)&0xFF},
181+
{FRAME_LEN_LINES_H, (HIMAX_FRAME_LENGTH_QVGA>>8)},
182+
{FRAME_LEN_LINES_L, (HIMAX_FRAME_LENGTH_QVGA&0xFF)},
183+
{LINE_LEN_PCK_H, (HIMAX_LINE_LEN_PCK_QVGA>>8)},
184+
{LINE_LEN_PCK_L, (HIMAX_LINE_LEN_PCK_QVGA&0xFF)},
185+
};
186+
187+
static regval_list_t himax_qqvga_regs[] = {
188+
{0x0383, 0x03},
189+
{0x0387, 0x03},
190+
{0x0390, 0x03},
191+
{MAX_INTG_H, (HIMAX_FRAME_LENGTH_QQVGA-2)>>8},
192+
{MAX_INTG_L, (HIMAX_FRAME_LENGTH_QQVGA-2)&0xFF},
193+
{FRAME_LEN_LINES_H, (HIMAX_FRAME_LENGTH_QQVGA>>8)},
194+
{FRAME_LEN_LINES_L, (HIMAX_FRAME_LENGTH_QQVGA&0xFF)},
195+
{LINE_LEN_PCK_H, (HIMAX_LINE_LEN_PCK_QQVGA>>8)},
196+
{LINE_LEN_PCK_L, (HIMAX_LINE_LEN_PCK_QQVGA&0xFF)},
167197
};
168198

169199
/* SPI transfer command sequence array */
@@ -212,6 +242,7 @@ uint8_t HIMAX_Open(void)
212242
}
213243

214244
HIMAX_Boot();
245+
215246
//For debugging camera Configuration
216247
//HIMAX_PrintReg();
217248
HAL_Delay(200);
@@ -223,9 +254,62 @@ uint8_t HIMAX_Open(void)
223254
* @brief This function selects HIMAX camera mode.
224255
* @retval None
225256
*/
226-
void HIMAX_Mode(uint8_t mode)
257+
int HIMAX_Mode(uint8_t mode)
258+
{
259+
return HIMAX_RegWrite(MODE_SELECT, mode);
260+
}
261+
262+
int HIMAX_SetResolution(uint32_t resolution)
263+
{
264+
int ret = 0;
265+
uint32_t regs_count = 0;
266+
regval_list_t *regs = NULL;
267+
268+
switch (resolution) {
269+
case CAMERA_R160x120:
270+
regs = himax_qqvga_regs;
271+
regs_count = sizeof(himax_qqvga_regs) / sizeof(regval_list_t);
272+
break;
273+
case CAMERA_R320x240:
274+
regs = himax_qvga_regs;
275+
regs_count = sizeof(himax_qvga_regs) / sizeof(regval_list_t);
276+
break;
277+
default:
278+
return -1;
279+
}
280+
281+
for(uint32_t i = 0; i < regs_count; i++) {
282+
ret |= HIMAX_RegWrite(regs[i].reg_num, regs[i].value);
283+
}
284+
285+
return ret;
286+
}
287+
288+
int HIMAX_SetFramerate(uint32_t framerate)
227289
{
228-
HIMAX_RegWrite(MODE_SELECT, mode);
290+
uint8_t osc_div = 0;
291+
// binning is enabled for QQVGA
292+
uint8_t binning = HIMAX_RegRead(BINNING_MODE) & 0x03;
293+
294+
switch (framerate) {
295+
case 15:
296+
osc_div = (binning) ? 0x00 : 0x01;
297+
break;
298+
case 30:
299+
osc_div = (binning) ? 0x01 : 0x02;
300+
break;
301+
case 60:
302+
osc_div = (binning) ? 0x02 : 0x03;
303+
break;
304+
case 120:
305+
// Set to max FPS for QVGA and QQVGA.
306+
osc_div = 0x03;
307+
break;
308+
default:
309+
return -1;
310+
}
311+
312+
return HIMAX_RegWrite(OSC_CLK_DIV, 0x08 | osc_div);
229313
}
230314

231315
/**

‎libraries/Himax_HM01B0/himax.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,12 +144,14 @@ typedef struct regval_list_ {
144144
} regval_list_t;
145145

146146
uint8_t HIMAX_Open(void);
147-
void HIMAX_Mode(uint8_t mode);
147+
int HIMAX_Mode(uint8_t mode);
148+
int HIMAX_SetResolution(uint32_t resolution);
149+
int HIMAX_SetFramerate(uint32_t framerate);
148150
void HIMAX_TestPattern(bool enable = true, bool walking = true);
149151

150152

151153
#ifdef __cplusplus
152154
}
153155
#endif
154156

155-
#endif /* __HIMAX_H */
157+
#endif /* __HIMAX_H */

‎libraries/Portenta_Camera/camera.cpp

Lines changed: 61 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -2,41 +2,26 @@
22
#include "himax.h"
33
#include "camera.h"
44
#include "stm32h7xx_hal_dcmi.h"
5-
#include "SDRAM.h"
65

7-
#define LCD_FRAME_BUFFER 0xC0000000 /* LCD Frame buffer of size 800x480 in ARGB8888 */
86
#define CAMERA_FRAME_BUFFER 0xC0200000
97

10-
#define QVGA_RES_X 320
11-
#define QVGA_RES_Y 240
12-
138
#define ARGB8888_BYTE_PER_PIXEL 4
149

15-
static uint32_t CameraResX = QVGA_RES_X;
16-
static uint32_t CameraResY = QVGA_RES_Y;
17-
static uint32_t LcdResX = 0;
18-
static uint32_t LcdResY = 0;
19-
static uint32_t *user_buffer = 0;
10+
static const int CamRes[][2] = {
11+
{160, 120},
12+
{320, 240},
13+
};
14+
static __IO uint32_t camera_frame_ready = 0;
2015

21-
__IO uint32_t camera_frame_ready = 0;
22-
__IO uint32_t lcd_frame_ready = 0;
23-
2416
/* DCMI DMA Stream definitions */
2517
#define CAMERA_DCMI_DMAx_CLK_ENABLE __HAL_RCC_DMA2_CLK_ENABLE
2618
#define CAMERA_DCMI_DMAx_STREAM DMA2_Stream3
2719
#define CAMERA_DCMI_DMAx_IRQ DMA2_Stream3_IRQn
2820

29-
#define CAMERA_R160x120 0x00 /* QQVGA Resolution */
30-
#define CAMERA_R320x240 0x01 /* QVGA Resolution */
31-
#define CAMERA_R480x272 0x02 /* 480x272 Resolution */
32-
#define CAMERA_R640x480 0x03 /* VGA Resolution */
33-
3421
extern "C" {
3522

3623
DCMI_HandleTypeDef hdcmi_discovery;
3724

38-
static uint32_t CameraCurrentResolution;
39-
4025
void BSP_CAMERA_PwrUp(void);
4126

4227
/**
@@ -142,10 +127,6 @@ void BSP_CAMERA_MspDeInit(DCMI_HandleTypeDef *hdcmi, void *Params)
142127
by surcharging this __weak function */
143128
}
144129

145-
/** @defgroup STM32H747I_DISCOVERY_CAMERA_Private_FunctionPrototypes Private FunctionPrototypes
146-
* @{
147-
*/
148-
static uint32_t GetSize(uint32_t Resolution);
149130
/**
150131
* @}
151132
*/
@@ -193,7 +174,7 @@ uint8_t BSP_CAMERA_Init(uint32_t Resolution)
193174
phdcmi->Init.SynchroMode = DCMI_SYNCHRO_HARDWARE;
194175
phdcmi->Init.VSPolarity = DCMI_VSPOLARITY_LOW;
195176
phdcmi->Init.ExtendedDataMode = DCMI_EXTEND_DATA_8B;
196-
phdcmi->Init.PCKPolarity = DCMI_PCKPOLARITY_RISING;
177+
phdcmi->Init.PCKPolarity = DCMI_PCKPOLARITY_FALLING;
197178
phdcmi->Init.ByteSelectMode = DCMI_BSM_ALL; // Capture all received bytes
198179
phdcmi->Init.ByteSelectStart = DCMI_OEBS_ODD; // Ignored
199180
phdcmi->Init.LineSelectMode = DCMI_LSM_ALL; // Capture all received lines
@@ -216,19 +197,16 @@ uint8_t BSP_CAMERA_Init(uint32_t Resolution)
216197
* @retval HAL status
217198
*/
218199
HAL_DCMI_EnableCROP(phdcmi);
219-
HAL_DCMI_ConfigCROP(phdcmi, (QVGA_RES_X - CameraResX) / 2, (QVGA_RES_Y - CameraResY) / 2, CameraResX-1, CameraResY-1);
200+
HAL_DCMI_ConfigCROP(phdcmi, 0, 0, CamRes[Resolution][0] - 1, CamRes[Resolution][1] - 1);
220201

221202
__HAL_DCMI_DISABLE_IT(&hdcmi_discovery, DCMI_IT_LINE);
222203

223-
CameraCurrentResolution = Resolution;
224-
225204
/* Return CAMERA_OK status */
226205
status = 0;
227206

228207
return status;
229208
}
230209

231-
232210
/**
233211
* @brief DeInitializes the camera.
234212
* @retval Camera status
@@ -247,14 +225,12 @@ uint8_t BSP_CAMERA_DeInit(void)
247225
* @param buff: pointer to the camera output buffer
248226
* @retval None
249227
*/
250-
void BSP_CAMERA_SnapshotStart(uint8_t *buff)
228+
void BSP_CAMERA_SnapshotStart(uint8_t *buff, uint32_t framesize)
251229
{
252-
user_buffer = (uint32_t*) buff;
253-
254230
__HAL_DCMI_ENABLE_IT(&hdcmi_discovery, DCMI_IT_FRAME);
255231

256232
/* Start the camera capture */
257-
HAL_DCMI_Start_DMA(&hdcmi_discovery, DCMI_MODE_SNAPSHOT, (uint32_t)buff, GetSize(CameraCurrentResolution)/4);
233+
HAL_DCMI_Start_DMA(&hdcmi_discovery, DCMI_MODE_SNAPSHOT, (uint32_t)buff, framesize / 4);
258234
}
259235

260236
/**
@@ -395,47 +371,6 @@ void BSP_CAMERA_PwrDown(void)
395371
digitalWrite(PC_13, LOW);
396372
}
397373

398-
/**
399-
* @brief Get the capture size in pixels unit.
400-
* @param Resolution: the current resolution.
401-
* @retval capture size in pixels unit.
402-
*/
403-
static uint32_t GetSize(uint32_t Resolution)
404-
{
405-
uint32_t size = 0;
406-
407-
/* Get capture size */
408-
switch (Resolution)
409-
{
410-
case CAMERA_R160x120:
411-
{
412-
size = 160 * 120;
413-
}
414-
break;
415-
case CAMERA_R320x240:
416-
{
417-
size = 320 * 240;
418-
}
419-
break;
420-
case CAMERA_R480x272:
421-
{
422-
size = 480 * 272;
423-
}
424-
break;
425-
case CAMERA_R640x480:
426-
{
427-
size = 640 * 480;
428-
}
429-
break;
430-
default:
431-
{
432-
break;
433-
}
434-
}
435-
436-
return size;
437-
}
438-
439374
/**
440375
* @brief Error callback.
441376
* @retval None
@@ -446,11 +381,9 @@ void BSP_CAMERA_ErrorCallback(void)
446381

447382
void BSP_CAMERA_FrameEventCallback(void)
448383
{
449-
camera_frame_ready++;
450-
SCB_InvalidateDCache_by_Addr((uint32_t*)user_buffer, GetSize(CameraCurrentResolution));
384+
camera_frame_ready++;
451385
}
452386

453-
454387
void DMA2_Stream3_IRQHandler(void)
455388
{
456389
HAL_DMA_IRQHandler(hdcmi_discovery.DMA_Handle);
@@ -519,34 +452,60 @@ void HAL_DCMI_ErrorCallback(DCMI_HandleTypeDef *hdcmi)
519452

520453
}
521454

522-
523-
int CameraClass::begin(int horizontalResolution, int verticalResolution)
455+
int CameraClass::begin(uint32_t resolution, uint32_t framerate)
524456
{
525-
CameraResX = horizontalResolution;
526-
CameraResY = verticalResolution;
527-
528-
SDRAM.begin(LCD_FRAME_BUFFER);
457+
if (resolution >= CAMERA_RMAX) {
458+
return -1;
459+
}
529460

530461
/*## Camera Initialization and capture start ############################*/
531462
/* Initialize the Camera in QVGA mode */
532-
if(BSP_CAMERA_Init(CAMERA_R320x240) != 0)
463+
if(BSP_CAMERA_Init(resolution) != 0)
533464
{
534465
return -1;
535466
}
536467

468+
if (HIMAX_SetResolution(resolution) != 0) {
469+
return -1;
470+
}
471+
472+
if (HIMAX_SetFramerate(framerate) != 0) {
473+
return -1;
474+
}
475+
476+
if (HIMAX_Mode(HIMAX_Streaming) != 0) {
477+
return -1;
478+
}
479+
480+
this->initialized = true;
481+
this->resolution = resolution;
537482
return 0;
538483
}
539484

485+
int CameraClass::framerate(uint32_t framerate)
486+
{
487+
if (this->initialized == false) {
488+
return -1;
489+
}
490+
return HIMAX_SetFramerate(framerate);
491+
}
492+
540493
int CameraClass::grab(uint8_t *buffer, uint32_t timeout)
541494
{
542-
HIMAX_Mode(HIMAX_Streaming);
495+
if (this->initialized == false) {
496+
return -1;
497+
}
543498

544499
BSP_CAMERA_Resume();
545500

546-
/* Start the Camera Snapshot Capture */
547-
BSP_CAMERA_SnapshotStart(buffer);
501+
/* Frame size from resolution. */
502+
uint32_t framesize = CamRes[this->resolution][0] * CamRes[this->resolution][1];
548503

549504
camera_frame_ready = 0;
505+
506+
/* Start the Camera Snapshot Capture */
507+
BSP_CAMERA_SnapshotStart(buffer, framesize);
508+
550509
/* Wait until camera frame is ready : DCMI Frame event */
551510
for (uint32_t start = millis(); camera_frame_ready == 0;) {
552511
__WFI();
@@ -556,46 +515,33 @@ int CameraClass::grab(uint8_t *buffer, uint32_t timeout)
556515
}
557516
}
558517

559-
HIMAX_Mode(HIMAX_Standby);
560-
561518
/* Stop the camera to avoid having the DMA2D work in parallel of Display */
562519
/* which cause perturbation of LTDC */
563520
BSP_CAMERA_Suspend();
564521

522+
/* Invalidate buffer after DMA transfer */
523+
SCB_InvalidateDCache_by_Addr((uint32_t*)buffer, framesize);
524+
565525
return 0;
566526
}
567527

568-
int CameraClass::skip_frames(uint8_t *buffer, uint32_t n_frames, uint32_t timeout)
528+
int CameraClass::standby(bool enable)
569529
{
570-
HIMAX_Mode(HIMAX_Streaming);
571-
572-
BSP_CAMERA_Resume();
573-
574-
/* Start the Camera Snapshot Capture */
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-
}
530+
if (this->initialized == false) {
531+
return -1;
532+
} else if (enable) {
533+
return HIMAX_Mode(HIMAX_Standby);
534+
} else {
535+
return HIMAX_Mode(HIMAX_Streaming);
587536
}
588-
589-
HIMAX_Mode(HIMAX_Standby);
590-
591-
/* Stop the camera to avoid having the DMA2D work in parallel of Display */
592-
/* which cause perturbation of LTDC */
593-
BSP_CAMERA_Suspend();
594-
return 0;
595537
}
596538

597-
void CameraClass::testPattern(bool walking)
539+
int CameraClass::testPattern(bool walking)
598540
{
541+
if (this->initialized == false) {
542+
return -1;
543+
}
599544
HIMAX_TestPattern(true, walking);
545+
return 0;
600546
}
601547
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

‎libraries/Portenta_Camera/camera.h

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,18 @@
1+
enum {
2+
CAMERA_R160x120 = 0x00, /* QQVGA Resolution */
3+
CAMERA_R320x240 = 0x01, /* QVGA Resolution */
4+
CAMERA_RMAX
5+
};
6+
17
class CameraClass {
2-
public:
3-
int begin(int horizontalResolution, int verticalResolution);
4-
int grab(uint8_t *buffer, uint32_t timeout=5000);
5-
void testPattern(bool walking);
6-
int skip_frames(uint8_t *buffer, uint32_t n_frames, uint32_t timeout=5000);
8+
private:
9+
uint32_t resolution;
10+
bool initialized;
11+
public:
12+
CameraClass(): initialized(false) {}
13+
int begin(uint32_t resolution = CAMERA_R320x240, uint32_t framerate = 30);
14+
int framerate(uint32_t framerate);
15+
int grab(uint8_t *buffer, uint32_t timeout=5000);
16+
int standby(bool enable);
17+
int testPattern(bool walking);
718
};
Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,22 @@
1-
21
#include "camera.h"
32

43
CameraClass cam;
5-
uint8_t fb[320*240] __attribute__((aligned(32)));
4+
uint8_t fb[320*240];
65

76
void setup() {
87

98
Serial.begin(921600);
109

11-
// Init the cam
12-
cam.begin(320, 240);
13-
14-
// Skip 60 frames
15-
cam.skip_frames(fb, 60);
10+
// Init the cam QVGA, 30FPS
11+
cam.begin(CAMERA_R320x240, 30);
1612
}
1713

1814
void loop() {
1915
// put your main code here, to run repeatedly:
2016
if (Serial) {
2117
// Grab frame and write to serial
2218
if (cam.grab(fb) == 0) {
23-
Serial.write(fb, 320*240);
19+
Serial.write(fb, 320*240);
2420
}
2521
}
2622
}

0 commit comments

Comments
 (0)
Please sign in to comment.