Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit c6eadbd

Browse files
iabdalkaderpennam
authored andcommitted
Update Camera driver.
* Add support for GS from YUV. * Fix frame capture logic. * Add a function to return the sensor color support.
1 parent 63f2cd0 commit c6eadbd

File tree

6 files changed

+46
-44
lines changed

6 files changed

+46
-44
lines changed

‎libraries/Camera/src/camera.cpp‎

Lines changed: 41 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#define DCMI_TIM_CLK_DISABLE() __TIM1_CLK_DISABLE()
4040
#define DCMI_TIM_PCLK_FREQ() HAL_RCC_GetPCLK2Freq()
4141
#define DCMI_TIM_FREQUENCY (6000000)
42+
#define DCMI_RESET_PIN (PC_13)
4243
arduino::MbedI2C CameraWire(I2C_SDA, I2C_SCL);
4344

4445
#elif defined(ARDUINO_NICLA_VISION)
@@ -65,6 +66,7 @@ arduino::MbedI2C CameraWire(I2C_SDA2, I2C_SCL2);
6566
#define DCMI_TIM_CLK_DISABLE() __TIM1_CLK_DISABLE()
6667
#define DCMI_TIM_PCLK_FREQ() HAL_RCC_GetPCLK2Freq()
6768
#define DCMI_TIM_FREQUENCY (6000000)
69+
#define DCMI_RESET_PIN (PA_1)
6870
arduino::MbedI2C CameraWire(I2C_SDA1, I2C_SCL1);
6971

7072
#endif
@@ -78,7 +80,7 @@ arduino::MbedI2C CameraWire(I2C_SDA1, I2C_SCL1);
7880

7981
// DCMI GPIO pins struct
8082
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)
8284
{GPIOA, GPIO_PIN_4 },
8385
{GPIOA, GPIO_PIN_6 },
8486
{GPIOI, GPIO_PIN_4 },
@@ -90,7 +92,7 @@ static const struct { GPIO_TypeDef *port; uint16_t pin; } dcmi_pins[] = {
9092
{GPIOH, GPIO_PIN_11 },
9193
{GPIOH, GPIO_PIN_12 },
9294
{GPIOH, GPIO_PIN_14 },
93-
#elif defined(ARDUINO_NICLA_VISION)
95+
#elif defined(ARDUINO_NICLA_VISION)
9496
{GPIOA, GPIO_PIN_4 },
9597
{GPIOA, GPIO_PIN_6 },
9698
{GPIOC, GPIO_PIN_6 },
@@ -102,7 +104,7 @@ static const struct { GPIO_TypeDef *port; uint16_t pin; } dcmi_pins[] = {
102104
{GPIOE, GPIO_PIN_5 },
103105
{GPIOE, GPIO_PIN_6 },
104106
{GPIOG, GPIO_PIN_9 },
105-
#elif defined(ARDUINO_GIGA)
107+
#elif defined(ARDUINO_GIGA)
106108
{GPIOH, GPIO_PIN_9 },
107109
{GPIOH, GPIO_PIN_10 },
108110
{GPIOH, GPIO_PIN_11 },
@@ -114,14 +116,13 @@ static const struct { GPIO_TypeDef *port; uint16_t pin; } dcmi_pins[] = {
114116
{GPIOA, GPIO_PIN_6 },
115117
{GPIOH, GPIO_PIN_8 },
116118
{GPIOI, GPIO_PIN_5 },
117-
#endif
119+
#endif
118120
};
119121
#define NUM_DCMI_PINS (sizeof(dcmi_pins)/sizeof(dcmi_pins[0]))
120122

121123
static TIM_HandleTypeDef htim = {0};
122124
static DMA_HandleTypeDef hdma = {0};
123125
static DCMI_HandleTypeDef hdcmi = {0};
124-
static volatile uint32_t frame_ready = 0;
125126

126127
const uint32_t pixtab[CAMERA_PMAX] = {
127128
1,
@@ -171,26 +172,27 @@ void HAL_DCMI_MspInit(DCMI_HandleTypeDef *hdcmi)
171172
hgpio.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
172173
hgpio.Alternate = GPIO_AF13_DCMI;
173174

174-
#if defined (ARDUINO_PORTENTA_H7_M7) || defined (ARDUINO_PORTENTA_H7_M4)
175+
#if defined (ARDUINO_PORTENTA_H7_M7) || defined (ARDUINO_PORTENTA_H7_M4)
175176
/* Enable GPIO clocks */
176177
__HAL_RCC_GPIOA_CLK_ENABLE();
177178
__HAL_RCC_GPIOH_CLK_ENABLE();
178179
__HAL_RCC_GPIOI_CLK_ENABLE();
179-
#elif defined(ARDUINO_NICLA_VISION)
180+
#elif defined(ARDUINO_NICLA_VISION)
180181
/* Enable GPIO clocks */
181182
__HAL_RCC_GPIOG_CLK_ENABLE();
182183
__HAL_RCC_GPIOE_CLK_ENABLE();
183184
__HAL_RCC_GPIOD_CLK_ENABLE();
184185
__HAL_RCC_GPIOC_CLK_ENABLE();
185186
__HAL_RCC_GPIOA_CLK_ENABLE();
186-
#elif defined(ARDUINO_GIGA)
187+
#elif defined(ARDUINO_GIGA)
187188
/* Enable GPIO clocks */
188189
__HAL_RCC_GPIOA_CLK_ENABLE();
189190
__HAL_RCC_GPIOG_CLK_ENABLE();
190191
__HAL_RCC_GPIOH_CLK_ENABLE();
191192
__HAL_RCC_GPIOI_CLK_ENABLE();
192193
__HAL_RCC_GPIOJ_CLK_ENABLE();
193-
#endif
194+
#endif
195+
194196
for (uint32_t i=0; i<NUM_DCMI_PINS; i++) {
195197
hgpio.Pin = dcmi_pins[i].pin;
196198
HAL_GPIO_Init(dcmi_pins[i].port, &hgpio);
@@ -262,7 +264,7 @@ __weak int camera_extclk_config(int frequency)
262264
return 0;
263265
}
264266

265-
uint8_t camera_dcmi_config()
267+
uint8_t camera_dcmi_config(bool bsm_skip)
266268
{
267269
// DMA Stream configuration
268270
hdma.Instance = DCMI_DMA_STREAM;
@@ -298,17 +300,16 @@ uint8_t camera_dcmi_config()
298300
hdcmi.Init.CaptureRate = DCMI_CR_ALL_FRAME;
299301
hdcmi.Init.ExtendedDataMode = DCMI_EXTEND_DATA_8B;
300302
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
305307

306308
// Link the DMA handle to the DCMI handle.
307309
__HAL_LINKDMA(&hdcmi, DMA_Handle, hdma);
308310

309311
// Initialize the DCMI
310312
HAL_DCMI_Init(&hdcmi);
311-
__HAL_DCMI_ENABLE_IT(&hdcmi, DCMI_IT_FRAME);
312313
__HAL_DCMI_DISABLE_IT(&hdcmi, DCMI_IT_LINE);
313314

314315
// Configure and enable DCMI IRQ Channel
@@ -327,15 +328,8 @@ void DMA2_Stream3_IRQHandler(void)
327328
HAL_DMA_IRQHandler(&hdma);
328329
}
329330

330-
void HAL_DCMI_FrameEventCallback(DCMI_HandleTypeDef *hdcmi)
331-
{
332-
frame_ready++;
333-
}
334-
335331
} // extern "C"
336332

337-
338-
339333
FrameBuffer::FrameBuffer(int32_t x, int32_t y, int32_t bpp) :
340334
_fb_size(x*y*bpp),
341335
_isAllocated(true)
@@ -397,14 +391,14 @@ Camera::Camera(ImageSensor &sensor) :
397391

398392
int Camera::reset()
399393
{
400-
#if defined (ARDUINO_PORTENTA_H7_M7) || defined (ARDUINO_PORTENTA_H7_M4)
401394
// Reset sensor.
402-
digitalWrite(PC_13, LOW);
395+
#if defined(DCMI_RESET_PIN)
396+
digitalWrite(DCMI_RESET_PIN, LOW);
403397
HAL_Delay(10);
404398

405-
digitalWrite(PC_13, HIGH);
406-
HAL_Delay(100);
407-
#endif
399+
digitalWrite(DCMI_RESET_PIN, HIGH);
400+
HAL_Delay(20);
401+
#endif
408402
return 0;
409403
}
410404

@@ -460,7 +454,11 @@ bool Camera::begin(int32_t resolution, int32_t pixformat, int32_t framerate)
460454
return false;
461455
}
462456

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) {
464462
return false;
465463
}
466464

@@ -518,7 +516,13 @@ int Camera::setResolution(int32_t resolution)
518516
* @param YSize DCMI Line number
519517
*/
520518
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+
}
522526
HAL_DCMI_ConfigCROP(&hdcmi, 0, 0, bpl - 1, restab[resolution][1] - 1);
523527

524528
if (this->sensor->setResolution(resolution) == 0) {
@@ -612,38 +616,31 @@ int Camera::grabFrame(FrameBuffer &fb, uint32_t timeout)
612616
return -1;
613617
}
614618

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-
623619
// 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) {
625622
if (_debug) {
626623
_debug->println("HAL_DCMI_Start_DMA FAILED!");
627624
}
628625
}
629626

630627
// 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);) {
632629
__WFI();
633630
if ((millis() - start) > timeout) {
634631
if (_debug) {
635632
_debug->println("Timeout expired!");
636633
}
637-
HAL_DMA_Abort(&hdma);
634+
HAL_DCMI_Stop(&hdcmi);
638635
return -1;
639636
}
640637
}
641638

642-
HAL_DCMI_Suspend(&hdcmi);
639+
HAL_DCMI_Stop(&hdcmi);
643640

644641
#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);
647644
#endif
648645
return 0;
649646
}
@@ -686,4 +683,4 @@ void Camera::debug(Stream &stream)
686683
{
687684
_debug = &stream;
688685
this->sensor->debug(stream);
689-
}
686+
}

‎libraries/Camera/src/camera.h‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ class ImageSensor {
6868
virtual int init() = 0;
6969
virtual int reset() = 0;
7070
virtual int getID() = 0;
71+
virtual bool getMono() = 0;
7172
virtual uint32_t getClockFrequency() = 0;
7273
virtual int setFrameRate(int32_t framerate) = 0;
7374
virtual int setResolution(int32_t resolution) = 0;

‎libraries/GC2145/gc2145.h‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ class GC2145: public ImageSensor {
3434
int init();
3535
int reset();
3636
int getID() { return GC2145_I2C_ADDR; };
37+
bool getMono() { return false; };
3738
uint32_t getClockFrequency() { return 12000000; };
3839
int setFrameRate(int32_t framerate);
3940
int setResolution(int32_t resolution);

‎libraries/Himax_HM01B0/himax.h‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ class HM01B0: public ImageSensor {
3737
int init();
3838
int reset();
3939
int getID() { return HM01B0_I2C_ADDR; };
40+
bool getMono() { return true; };
4041
uint32_t getClockFrequency() { return 6000000; };
4142
int setFrameRate(int32_t framerate);
4243
int setResolution(int32_t resolution);

‎libraries/Himax_HM0360/hm0360.h‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ class HM0360: public ImageSensor {
3737
int init();
3838
int reset();
3939
int getID() { return HM0360_I2C_ADDR; };
40+
bool getMono() { return true; };
4041
uint32_t getClockFrequency() { return 24000000; };
4142
int setFrameRate(int32_t framerate);
4243
int setResolution(int32_t resolution);

‎libraries/OV7670/ov7670.h‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ class OV7670: public ImageSensor {
3737
int init();
3838
int reset();
3939
int getID() { return 0x21; };
40+
bool getMono() { return false; };
4041
uint32_t getClockFrequency() { return 12000000; };
4142
int setFrameRate(int32_t framerate);
4243
int setResolution(int32_t resolution);

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /