I am wondering if it is possible on the GIGA to use any of the Arducam Cameras supported on the GIGA in any of the resolutions > QVGA. That is the following resolutions are defined:
// CAMERA_R160x120 = 0, /* QQVGA Resolution */
// CAMERA_R320x240 = 1, /* QVGA Resolution */
// CAMERA_R320x320 = 2, /* 320x320 Resolution */
// CAMERA_R640x480 = 3, /* VGA */
// CAMERA_R800x600 = 5, /* SVGA */
// CAMERA_R1600x1200 = 6, /* UXGA */
// CAMERA_RMAX /* Sentinel value */
Right now I am trying with the GC2145 that hardware wise goes up to 1600x1200.
I have it currently mounted using a simple Adapter I did a while ago for another board to rotate the camera 90 degrees, like:
I have a simple sketch, that striped down the sample sketch to only have one framebuffer object and display it on the screen. If image size with is <=480, simply swap the bytes. If > 480, I compress the image down to 480x480 to display it.
#include "arducam_dvp.h"
#include "Arduino_H7_Video.h"
#include "dsi.h"
#include "SDRAM.h"
// This example only works with Greyscale cameras (due to the palette + resize&rotate algo)
#define ARDUCAM_CAMERA_GC2145
#ifdef ARDUCAM_CAMERA_HM01B0
#include "Himax_HM01B0/himax.h"
HM01B0 himax;
Camera cam(himax);
#define IMAGE_MODE CAMERA_GRAYSCALE
#elif defined(ARDUCAM_CAMERA_HM0360)
#include "Himax_HM0360/hm0360.h"
HM0360 himax;
Camera cam(himax);
#define IMAGE_MODE CAMERA_GRAYSCALE
#elif defined(ARDUCAM_CAMERA_OV767X)
#include "OV7670/ov767x.h"
// OV7670 ov767x;
OV7675 ov767x;
Camera cam(ov767x);
#define IMAGE_MODE CAMERA_RGB565
#elif defined(ARDUCAM_CAMERA_GC2145)
#include "GC2145/gc2145.h"
GC2145 galaxyCore;
Camera cam(galaxyCore);
#define IMAGE_MODE CAMERA_RGB565
#endif
// The buffer used to capture the frame
FrameBuffer fb;
// The buffer used to rotate and resize the frame
Arduino_H7_Video Display(800, 480, GigaDisplayShield);
void blinkLED(uint32_t count = 0xFFFFFFFF) {
pinMode(LED_BUILTIN, OUTPUT);
while (count--) {
digitalWrite(LED_BUILTIN, LOW); // turn the LED on (HIGH is the voltage level)
delay(50); // wait for a second
digitalWrite(LED_BUILTIN, HIGH); // turn the LED off by making the voltage LOW
delay(50); // wait for a second
}
}
uint32_t palette[256];
void setup() {
// Init the cam QVGA, 30FPS
while (!Serial && millis() < 4000) {}
Serial.begin(115200);
galaxyCore.debug(Serial);
// CAMERA_R160x120 = 0, /* QQVGA Resolution */
// CAMERA_R320x240 = 1, /* QVGA Resolution */
// CAMERA_R320x320 = 2, /* 320x320 Resolution */
// CAMERA_R640x480 = 3, /* VGA */
// CAMERA_R800x600 = 5, /* SVGA */
// CAMERA_R1600x1200 = 6, /* UXGA */
// CAMERA_RMAX /* Sentinel value */
#define CAMERA_WIDTH 640
#define CAMERA_HEIGHT 480
if (!cam.begin(CAMERA_R640x480, IMAGE_MODE, 30)) {
blinkLED();
}
galaxyCore.printRegs();
// Setup the palette to convert 8 bit greyscale to 32bit greyscale
for (int i = 0; i < 256; i++) {
palette[i] = 0xFF000000 | (i << 16) | (i << 8) | i;
}
Display.begin();
if (IMAGE_MODE == CAMERA_GRAYSCALE) {
dsi_configueCLUT((uint32_t *)palette);
}
// big enough for full screen.
#if CAMERA_WIDTH > 320
uint8_t *fb_buf = (uint8_t *)((((uint32_t)SDRAM.malloc(CAMERA_WIDTH * CAMERA_HEIGHT * 2 + 31)) + 31) & 0xfffffff0l);
memset(fb_buf, 0, CAMERA_WIDTH * CAMERA_HEIGHT * 2);
fb.setBuffer(fb_buf);
#endif
Serial.print("FB Buffer: ");
// clear the display (gives a nice black background)
dsi_lcdClear(0);
dsi_drawCurrentFrameBuffer();
dsi_lcdClear(0);
dsi_drawCurrentFrameBuffer();
}
inline uint16_t HTONS(uint16_t x) {
return (((x >> 8) & 0x00FF) | ((x << 8) & 0xFF00));
}
void loop() {
// Grab frame and write to another framebuffer
SCB_CleanInvalidateDCache();
if (cam.grabFrame(fb, 3000) == 0) {
// double the resolution and transpose (rotate by 90 degrees) in the same step
// this only works if the camera feed is 320x240 and the area where we want to display is 640x480
uint16_t *frame_in = (uint16_t *)fb.getBuffer();
SCB_CleanInvalidateDCache();
//for (int ii = 0; ii < (1600 * 1200); ii++) frame_in[ii] = HTONS(frame_in[ii]);
// lets clip the image to 480x480
#if CAMERA_WIDTH < 480
for (int ii = 0; ii < (CAMERA_WIDTH * CAMERA_HEIGHT); ii++) frame_in[ii] = HTONS(frame_in[ii]);
SCB_CleanInvalidateDCache();
dsi_lcdDrawImage((void *)fb.getBuffer(), (void *)dsi_getCurrentFrameBuffer(), CAMERA_WIDTH, CAMERA_HEIGHT, IMAGE_MODE == CAMERA_GRAYSCALE ? DMA2D_INPUT_L8 : DMA2D_INPUT_RGB565);
#else
for (int y = 0; y < 480; y++) {
for (int x = 0; x < 480; x++) {
frame_in[y * 480 + x] = HTONS(frame_in[y * CAMERA_WIDTH + x]);
}
}
dsi_lcdDrawImage((void *)fb.getBuffer(), (void *)dsi_getCurrentFrameBuffer(), 480, 480, IMAGE_MODE == CAMERA_GRAYSCALE ? DMA2D_INPUT_L8 : DMA2D_INPUT_RGB565);
#endif
dsi_drawCurrentFrameBuffer();
} else {
blinkLED(20);
}
}
Note: currently I only have it setup for GC2145 camera will try one or more others soon.
First issue: SDRAM - can it be used for camera frame buffer? That is when I was testing the GC2145 at 320x240 but was still using the SDRAM, I would get strange frames: It would go from normal looking one like:

To ones that were screwed up like:

Note: could be issue with camera and how it is dealing with brighter light around it, but I saw a lot less of an effect when I put in the #if:
#if CAMERA_WIDTH > 320
uint8_t *fb_buf = (uint8_t *)((((uint32_t)SDRAM.malloc(CAMERA_WIDTH * CAMERA_HEIGHT * 2 + 31)) + 31) & 0xfffffff0l);
memset(fb_buf, 0, CAMERA_WIDTH * CAMERA_HEIGHT * 2);
fb.setBuffer(fb_buf);
#endif
To leave the frame buffer into normal memory. There is still camera effects where the images alternate from lower intensity to higher... Probably some of the auto... settings.
So again wondering if there is an issue with SDRAM? I did see this open issue:
SDRAM memory write corruption · Issue #797 · arduino/ArduinoCore-mbed (github.com)
Camera code: Assuming that the memory works, have any of these camera code bases been tested on any higher resolutions like VGA?
There looks like there may be a few other code bases for these cameras where the camera register settings are different, including:
Also wondering if there needs to be more control over the speed of the capture. For example on these cameras code base it ignores the setting of frame rate. Maybe would work better when in SDRAM if one could slow it down...
Better place to ask questions?
Is there a better place to ask questions about, these different questions and their integration with the GIGA?
Thanks
Kurt






