39
39
#define DCMI_TIM_CLK_DISABLE () __TIM1_CLK_DISABLE()
40
40
#define DCMI_TIM_PCLK_FREQ () HAL_RCC_GetPCLK2Freq()
41
41
#define DCMI_TIM_FREQUENCY (6000000 )
42
+ #define DCMI_RESET_PIN (PC_13)
42
43
arduino::MbedI2C CameraWire (I2C_SDA, I2C_SCL);
43
44
44
45
#elif defined(ARDUINO_NICLA_VISION)
@@ -65,6 +66,7 @@ arduino::MbedI2C CameraWire(I2C_SDA2, I2C_SCL2);
65
66
#define DCMI_TIM_CLK_DISABLE () __TIM1_CLK_DISABLE()
66
67
#define DCMI_TIM_PCLK_FREQ () HAL_RCC_GetPCLK2Freq()
67
68
#define DCMI_TIM_FREQUENCY (6000000 )
69
+ #define DCMI_RESET_PIN (PA_1)
68
70
arduino::MbedI2C CameraWire (I2C_SDA1, I2C_SCL1);
69
71
70
72
#endif
@@ -78,7 +80,7 @@ arduino::MbedI2C CameraWire(I2C_SDA1, I2C_SCL1);
78
80
79
81
// DCMI GPIO pins struct
80
82
static const struct { GPIO_TypeDef *port; uint16_t pin; } dcmi_pins[] = {
81
- #if defined (ARDUINO_PORTENTA_H7_M7) || defined (ARDUINO_PORTENTA_H7_M4)
83
+ #if defined (ARDUINO_PORTENTA_H7_M7) || defined (ARDUINO_PORTENTA_H7_M4)
82
84
{GPIOA, GPIO_PIN_4 },
83
85
{GPIOA, GPIO_PIN_6 },
84
86
{GPIOI, GPIO_PIN_4 },
@@ -90,7 +92,7 @@ static const struct { GPIO_TypeDef *port; uint16_t pin; } dcmi_pins[] = {
90
92
{GPIOH, GPIO_PIN_11 },
91
93
{GPIOH, GPIO_PIN_12 },
92
94
{GPIOH, GPIO_PIN_14 },
93
- #elif defined(ARDUINO_NICLA_VISION)
95
+ #elif defined(ARDUINO_NICLA_VISION)
94
96
{GPIOA, GPIO_PIN_4 },
95
97
{GPIOA, GPIO_PIN_6 },
96
98
{GPIOC, GPIO_PIN_6 },
@@ -102,7 +104,7 @@ static const struct { GPIO_TypeDef *port; uint16_t pin; } dcmi_pins[] = {
102
104
{GPIOE, GPIO_PIN_5 },
103
105
{GPIOE, GPIO_PIN_6 },
104
106
{GPIOG, GPIO_PIN_9 },
105
- #elif defined(ARDUINO_GIGA)
107
+ #elif defined(ARDUINO_GIGA)
106
108
{GPIOH, GPIO_PIN_9 },
107
109
{GPIOH, GPIO_PIN_10 },
108
110
{GPIOH, GPIO_PIN_11 },
@@ -114,14 +116,13 @@ static const struct { GPIO_TypeDef *port; uint16_t pin; } dcmi_pins[] = {
114
116
{GPIOA, GPIO_PIN_6 },
115
117
{GPIOH, GPIO_PIN_8 },
116
118
{GPIOI, GPIO_PIN_5 },
117
- #endif
119
+ #endif
118
120
};
119
121
#define NUM_DCMI_PINS (sizeof (dcmi_pins)/sizeof (dcmi_pins[0 ]))
120
122
121
123
static TIM_HandleTypeDef htim = {0 };
122
124
static DMA_HandleTypeDef hdma = {0 };
123
125
static DCMI_HandleTypeDef hdcmi = {0 };
124
- static volatile uint32_t frame_ready = 0 ;
125
126
126
127
const uint32_t pixtab[CAMERA_PMAX] = {
127
128
1 ,
@@ -171,26 +172,27 @@ void HAL_DCMI_MspInit(DCMI_HandleTypeDef *hdcmi)
171
172
hgpio.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
172
173
hgpio.Alternate = GPIO_AF13_DCMI;
173
174
174
- #if defined (ARDUINO_PORTENTA_H7_M7) || defined (ARDUINO_PORTENTA_H7_M4)
175
+ #if defined (ARDUINO_PORTENTA_H7_M7) || defined (ARDUINO_PORTENTA_H7_M4)
175
176
/* Enable GPIO clocks */
176
177
__HAL_RCC_GPIOA_CLK_ENABLE ();
177
178
__HAL_RCC_GPIOH_CLK_ENABLE ();
178
179
__HAL_RCC_GPIOI_CLK_ENABLE ();
179
- #elif defined(ARDUINO_NICLA_VISION)
180
+ #elif defined(ARDUINO_NICLA_VISION)
180
181
/* Enable GPIO clocks */
181
182
__HAL_RCC_GPIOG_CLK_ENABLE ();
182
183
__HAL_RCC_GPIOE_CLK_ENABLE ();
183
184
__HAL_RCC_GPIOD_CLK_ENABLE ();
184
185
__HAL_RCC_GPIOC_CLK_ENABLE ();
185
186
__HAL_RCC_GPIOA_CLK_ENABLE ();
186
- #elif defined(ARDUINO_GIGA)
187
+ #elif defined(ARDUINO_GIGA)
187
188
/* Enable GPIO clocks */
188
189
__HAL_RCC_GPIOA_CLK_ENABLE ();
189
190
__HAL_RCC_GPIOG_CLK_ENABLE ();
190
191
__HAL_RCC_GPIOH_CLK_ENABLE ();
191
192
__HAL_RCC_GPIOI_CLK_ENABLE ();
192
193
__HAL_RCC_GPIOJ_CLK_ENABLE ();
193
- #endif
194
+ #endif
195
+
194
196
for (uint32_t i=0 ; i<NUM_DCMI_PINS; i++) {
195
197
hgpio.Pin = dcmi_pins[i].pin ;
196
198
HAL_GPIO_Init (dcmi_pins[i].port , &hgpio);
@@ -262,7 +264,7 @@ __weak int camera_extclk_config(int frequency)
262
264
return 0 ;
263
265
}
264
266
265
- uint8_t camera_dcmi_config ()
267
+ uint8_t camera_dcmi_config (bool bsm_skip )
266
268
{
267
269
// DMA Stream configuration
268
270
hdma.Instance = DCMI_DMA_STREAM;
@@ -298,17 +300,16 @@ uint8_t camera_dcmi_config()
298
300
hdcmi.Init .CaptureRate = DCMI_CR_ALL_FRAME;
299
301
hdcmi.Init .ExtendedDataMode = DCMI_EXTEND_DATA_8B;
300
302
hdcmi.Init .JPEGMode = DCMI_JPEG_DISABLE;
301
- hdcmi.Init .ByteSelectMode = DCMI_BSM_ALL; // Capture all received bytes
302
- hdcmi.Init .ByteSelectStart = DCMI_OEBS_ODD; // Ignored
303
- hdcmi.Init .LineSelectMode = DCMI_LSM_ALL; // Capture all received lines
304
- hdcmi.Init .LineSelectStart = DCMI_OELS_ODD; // Ignored
303
+ hdcmi.Init .ByteSelectMode = bsm_skip ? DCMI_BSM_OTHER : DCMI_BSM_ALL;
304
+ hdcmi.Init .ByteSelectStart = DCMI_OEBS_ODD; // Ignored unless BSM != ALL
305
+ hdcmi.Init .LineSelectMode = DCMI_LSM_ALL; // Capture all received lines
306
+ hdcmi.Init .LineSelectStart = DCMI_OELS_ODD; // Ignored, unless LSM != ALL
305
307
306
308
// Link the DMA handle to the DCMI handle.
307
309
__HAL_LINKDMA (&hdcmi, DMA_Handle, hdma);
308
310
309
311
// Initialize the DCMI
310
312
HAL_DCMI_Init (&hdcmi);
311
- __HAL_DCMI_ENABLE_IT (&hdcmi, DCMI_IT_FRAME);
312
313
__HAL_DCMI_DISABLE_IT (&hdcmi, DCMI_IT_LINE);
313
314
314
315
// Configure and enable DCMI IRQ Channel
@@ -327,15 +328,8 @@ void DMA2_Stream3_IRQHandler(void)
327
328
HAL_DMA_IRQHandler (&hdma);
328
329
}
329
330
330
- void HAL_DCMI_FrameEventCallback (DCMI_HandleTypeDef *hdcmi)
331
- {
332
- frame_ready++;
333
- }
334
-
335
331
} // extern "C"
336
332
337
-
338
-
339
333
FrameBuffer::FrameBuffer (int32_t x, int32_t y, int32_t bpp) :
340
334
_fb_size(x*y*bpp),
341
335
_isAllocated(true )
@@ -397,14 +391,14 @@ Camera::Camera(ImageSensor &sensor) :
397
391
398
392
int Camera::reset ()
399
393
{
400
- #if defined (ARDUINO_PORTENTA_H7_M7) || defined (ARDUINO_PORTENTA_H7_M4)
401
394
// Reset sensor.
402
- digitalWrite (PC_13, LOW);
395
+ #if defined(DCMI_RESET_PIN)
396
+ digitalWrite (DCMI_RESET_PIN, LOW);
403
397
HAL_Delay (10 );
404
398
405
- digitalWrite (PC_13 , HIGH);
406
- HAL_Delay (100 );
407
- #endif
399
+ digitalWrite (DCMI_RESET_PIN , HIGH);
400
+ HAL_Delay (20 );
401
+ #endif
408
402
return 0 ;
409
403
}
410
404
@@ -460,7 +454,11 @@ bool Camera::begin(int32_t resolution, int32_t pixformat, int32_t framerate)
460
454
return false ;
461
455
}
462
456
463
- if (camera_dcmi_config () != 0 ) {
457
+ // If the pixel format is Grayscale and sensor is Not monochrome, the
458
+ // actual pixel format will be YUV (i.e 2 bytes per pixel) and the DCMI
459
+ // needs to be configured to skip every other byte to extract the Y channel.
460
+ bool gs_from_yuv = (pixformat == CAMERA_GRAYSCALE) && !this ->sensor ->getMono ();
461
+ if (camera_dcmi_config (gs_from_yuv) != 0 ) {
464
462
return false ;
465
463
}
466
464
@@ -518,7 +516,13 @@ int Camera::setResolution(int32_t resolution)
518
516
* @param YSize DCMI Line number
519
517
*/
520
518
HAL_DCMI_EnableCROP (&hdcmi);
521
- uint32_t bpl = restab[resolution][0 ] * pixtab[pixformat];
519
+ uint32_t bpl = restab[resolution][0 ];
520
+ if (pixformat == CAMERA_RGB565 ||
521
+ (pixformat == CAMERA_GRAYSCALE && !this ->sensor ->getMono ())) {
522
+ // If the pixel format is Grayscale and sensor is Not monochrome,
523
+ // the actual pixel format will be YUV (i.e 2 bytes per pixel).
524
+ bpl *= 2 ;
525
+ }
522
526
HAL_DCMI_ConfigCROP (&hdcmi, 0 , 0 , bpl - 1 , restab[resolution][1 ] - 1 );
523
527
524
528
if (this ->sensor ->setResolution (resolution) == 0 ) {
@@ -612,38 +616,31 @@ int Camera::grabFrame(FrameBuffer &fb, uint32_t timeout)
612
616
return -1 ;
613
617
}
614
618
615
- frame_ready = 0 ;
616
-
617
- if (HAL_DCMI_Resume (&hdcmi) != HAL_OK) {
618
- if (_debug) {
619
- _debug->println (" HAL_DCMI_Resume FAILED!" );
620
- }
621
- }
622
-
623
619
// Start the Camera Snapshot Capture.
624
- if (HAL_DCMI_Start_DMA (&hdcmi, DCMI_MODE_SNAPSHOT, (uint32_t ) framebuffer, framesize / 4 ) != HAL_OK) {
620
+ if (HAL_DCMI_Start_DMA (&hdcmi, DCMI_MODE_SNAPSHOT,
621
+ (uint32_t ) framebuffer, framesize / 4 ) != HAL_OK) {
625
622
if (_debug) {
626
623
_debug->println (" HAL_DCMI_Start_DMA FAILED!" );
627
624
}
628
625
}
629
626
630
627
// Wait until camera frame is ready.
631
- for (uint32_t start = millis (); frame_ready == 0 ;) {
628
+ for (uint32_t start = millis (); (hdcmi. Instance -> CR & DCMI_CR_CAPTURE) ;) {
632
629
__WFI ();
633
630
if ((millis () - start) > timeout) {
634
631
if (_debug) {
635
632
_debug->println (" Timeout expired!" );
636
633
}
637
- HAL_DMA_Abort (&hdma );
634
+ HAL_DCMI_Stop (&hdcmi );
638
635
return -1 ;
639
636
}
640
637
}
641
638
642
- HAL_DCMI_Suspend (&hdcmi);
639
+ HAL_DCMI_Stop (&hdcmi);
643
640
644
641
#if defined(__CORTEX_M7) // only invalidate buffer for Cortex M7
645
- // Invalidate buffer after DMA transfer.
646
- SCB_InvalidateDCache_by_Addr ((uint32_t *) framebuffer, framesize);
642
+ // Invalidate buffer after DMA transfer.
643
+ SCB_InvalidateDCache_by_Addr ((uint32_t *) framebuffer, framesize);
647
644
#endif
648
645
return 0 ;
649
646
}
@@ -686,4 +683,4 @@ void Camera::debug(Stream &stream)
686
683
{
687
684
_debug = &stream;
688
685
this ->sensor ->debug (stream);
689
- }
686
+ }
0 commit comments