Fix RGB565 Inversion from camera

This commit is contained in:
Kwabena W. Agyeman 2020-10-21 06:39:01 -07:00
parent 4dcc74cd25
commit 785e943f05
8 changed files with 46 additions and 6 deletions

View File

@ -854,6 +854,7 @@ int ov2640_init(sensor_t *sensor)
SENSOR_HW_FLAGS_SET(sensor, SENSOR_HW_FLAGS_PIXCK, 1); SENSOR_HW_FLAGS_SET(sensor, SENSOR_HW_FLAGS_PIXCK, 1);
SENSOR_HW_FLAGS_SET(sensor, SENSOR_HW_FLAGS_FSYNC, 0); SENSOR_HW_FLAGS_SET(sensor, SENSOR_HW_FLAGS_FSYNC, 0);
SENSOR_HW_FLAGS_SET(sensor, SENSOR_HW_FLAGS_JPEGE, 1); SENSOR_HW_FLAGS_SET(sensor, SENSOR_HW_FLAGS_JPEGE, 1);
SENSOR_HW_FLAGS_SET(sensor, SWNSOR_HW_FLAGS_RGB565_REV, 0);
return 0; return 0;
} }

View File

@ -75,7 +75,7 @@
#define IMAGE_MODE_JPEG_EN 0x10 #define IMAGE_MODE_JPEG_EN 0x10
#define IMAGE_MODE_YUV422 0x00 #define IMAGE_MODE_YUV422 0x00
#define IMAGE_MODE_RAW10 0x04 #define IMAGE_MODE_RAW10 0x04
#define IMAGE_MODE_RGB565 0x08 #define IMAGE_MODE_RGB565 0x09
#define IMAGE_MODE_HREF_VSYNC 0x02 #define IMAGE_MODE_HREF_VSYNC 0x02
#define IMAGE_MODE_LBYTE_FIRST 0x01 #define IMAGE_MODE_LBYTE_FIRST 0x01
#define IMAGE_MODE_GET_FMT(x) ((x)&0xC) #define IMAGE_MODE_GET_FMT(x) ((x)&0xC)

View File

@ -483,7 +483,7 @@ static int set_pixformat(sensor_t *sensor, pixformat_t pixformat)
ret |= cambus_writeb2(&sensor->i2c, sensor->slv_addr, FORMAT_CONTROL_MUX, 0x00); ret |= cambus_writeb2(&sensor->i2c, sensor->slv_addr, FORMAT_CONTROL_MUX, 0x00);
break; break;
case PIXFORMAT_RGB565: case PIXFORMAT_RGB565:
ret |= cambus_writeb2(&sensor->i2c, sensor->slv_addr, FORMAT_CONTROL, 0x61); ret |= cambus_writeb2(&sensor->i2c, sensor->slv_addr, FORMAT_CONTROL, 0x6F);
ret |= cambus_writeb2(&sensor->i2c, sensor->slv_addr, FORMAT_CONTROL_MUX, 0x01); ret |= cambus_writeb2(&sensor->i2c, sensor->slv_addr, FORMAT_CONTROL_MUX, 0x01);
break; break;
case PIXFORMAT_YUV422: case PIXFORMAT_YUV422:
@ -1030,6 +1030,7 @@ int ov5640_init(sensor_t *sensor)
SENSOR_HW_FLAGS_SET(sensor, SENSOR_HW_FLAGS_PIXCK, 1); SENSOR_HW_FLAGS_SET(sensor, SENSOR_HW_FLAGS_PIXCK, 1);
SENSOR_HW_FLAGS_SET(sensor, SENSOR_HW_FLAGS_FSYNC, 0); SENSOR_HW_FLAGS_SET(sensor, SENSOR_HW_FLAGS_FSYNC, 0);
SENSOR_HW_FLAGS_SET(sensor, SENSOR_HW_FLAGS_JPEGE, 1); SENSOR_HW_FLAGS_SET(sensor, SENSOR_HW_FLAGS_JPEGE, 1);
SENSOR_HW_FLAGS_SET(sensor, SWNSOR_HW_FLAGS_RGB565_REV, 0);
return 0; return 0;
} }

View File

@ -622,6 +622,7 @@ int ov7690_init(sensor_t *sensor)
SENSOR_HW_FLAGS_SET(sensor, SENSOR_HW_FLAGS_PIXCK, 1); SENSOR_HW_FLAGS_SET(sensor, SENSOR_HW_FLAGS_PIXCK, 1);
SENSOR_HW_FLAGS_SET(sensor, SENSOR_HW_FLAGS_FSYNC, 0); SENSOR_HW_FLAGS_SET(sensor, SENSOR_HW_FLAGS_FSYNC, 0);
SENSOR_HW_FLAGS_SET(sensor, SENSOR_HW_FLAGS_JPEGE, 0); SENSOR_HW_FLAGS_SET(sensor, SENSOR_HW_FLAGS_JPEGE, 0);
SENSOR_HW_FLAGS_SET(sensor, SWNSOR_HW_FLAGS_RGB565_REV, 1);
return 0; return 0;
} }

View File

@ -622,6 +622,7 @@ int ov7725_init(sensor_t *sensor)
SENSOR_HW_FLAGS_SET(sensor, SENSOR_HW_FLAGS_PIXCK, 1); SENSOR_HW_FLAGS_SET(sensor, SENSOR_HW_FLAGS_PIXCK, 1);
SENSOR_HW_FLAGS_SET(sensor, SENSOR_HW_FLAGS_FSYNC, 0); SENSOR_HW_FLAGS_SET(sensor, SENSOR_HW_FLAGS_FSYNC, 0);
SENSOR_HW_FLAGS_SET(sensor, SENSOR_HW_FLAGS_JPEGE, 0); SENSOR_HW_FLAGS_SET(sensor, SENSOR_HW_FLAGS_JPEGE, 0);
SENSOR_HW_FLAGS_SET(sensor, SWNSOR_HW_FLAGS_RGB565_REV, 1);
return 0; return 0;
} }

View File

@ -538,6 +538,7 @@ int ov9650_init(sensor_t *sensor)
SENSOR_HW_FLAGS_SET(sensor, SENSOR_HW_FLAGS_PIXCK, 1); SENSOR_HW_FLAGS_SET(sensor, SENSOR_HW_FLAGS_PIXCK, 1);
SENSOR_HW_FLAGS_SET(sensor, SENSOR_HW_FLAGS_FSYNC, 0); SENSOR_HW_FLAGS_SET(sensor, SENSOR_HW_FLAGS_FSYNC, 0);
SENSOR_HW_FLAGS_SET(sensor, SENSOR_HW_FLAGS_JPEGE, 0); SENSOR_HW_FLAGS_SET(sensor, SENSOR_HW_FLAGS_JPEGE, 0);
SENSOR_HW_FLAGS_SET(sensor, SWNSOR_HW_FLAGS_RGB565_REV, 1);
return 0; return 0;
} }

View File

@ -1103,6 +1103,29 @@ void *unaligned_memcpy(void *dest, void *src, size_t n)
#endif #endif
} }
// ARM Cortex-M4/M7 Processors can access memory using unaligned 32-bit reads/writes.
void *unaligned_memcpy_rev16(void *dest, void *src, size_t n)
{
uint32_t *dest32 = (uint32_t *) dest;
uint32_t *src32 = (uint32_t *) src;
// TODO: Make this faster using only 32-bit aligned reads/writes with data shifting.
#if defined(MCU_SERIES_F4) || defined(MCU_SERIES_F7) || defined(MCU_SERIES_H7)
for (; n > 2; n -= 2) {
*dest32++ = __REV16(*src32++);
}
#endif
uint16_t *dest16 = (uint16_t *) dest32;
uint16_t *src16 = (uint16_t *) src32;
for (; n > 0; n -= 1) {
*dest16++ = __REV16(*src16++);
}
return dest;
}
// Stop allowing new data in on the end of the frame and let snapshot know that the frame has been // Stop allowing new data in on the end of the frame and let snapshot know that the frame has been
// received. Note that DCMI_DMAConvCpltUser() is called before DCMI_IT_FRAME is enabled by // received. Note that DCMI_DMAConvCpltUser() is called before DCMI_IT_FRAME is enabled by
// DCMI_DMAXferCplt() so this means that the last line of data is *always* transferred before // DCMI_DMAXferCplt() so this means that the last line of data is *always* transferred before
@ -1207,7 +1230,11 @@ void DCMI_DMAConvCpltUser(uint32_t addr)
case PIXFORMAT_RGB565: case PIXFORMAT_RGB565:
dst16 += (offset - MAIN_FB()->y) * MAIN_FB()->w; dst16 += (offset - MAIN_FB()->y) * MAIN_FB()->w;
src16 += MAIN_FB()->x; src16 += MAIN_FB()->x;
if (SENSOR_HW_FLAGS_GET(&sensor, SWNSOR_HW_FLAGS_RGB565_REV)) {
unaligned_memcpy_rev16(dst16, src16, MAIN_FB()->w);
} else {
unaligned_memcpy(dst16, src16, MAIN_FB()->w * sizeof(uint16_t)); unaligned_memcpy(dst16, src16, MAIN_FB()->w * sizeof(uint16_t));
}
break; break;
default: default:
break; break;
@ -1244,10 +1271,17 @@ void DCMI_DMAConvCpltUser(uint32_t addr)
case PIXFORMAT_RGB565: case PIXFORMAT_RGB565:
dst16 += offset - MAIN_FB()->y; dst16 += offset - MAIN_FB()->y;
src16 += MAIN_FB()->x; src16 += MAIN_FB()->x;
if (SENSOR_HW_FLAGS_GET(&sensor, SWNSOR_HW_FLAGS_RGB565_REV)) {
for (int i = MAIN_FB()->w, h = MAIN_FB()->h; i; i--) {
*dst16 = __REV16(*src16++);
dst16 += h;
}
} else {
for (int i = MAIN_FB()->w, h = MAIN_FB()->h; i; i--) { for (int i = MAIN_FB()->w, h = MAIN_FB()->h; i; i--) {
*dst16 = *src16++; *dst16 = *src16++;
dst16 += h; dst16 += h;
} }
}
break; break;
default: default:
break; break;

View File

@ -139,6 +139,7 @@ typedef enum {
#define SENSOR_HW_FLAGS_PIXCK (2) // pixel clock edge. #define SENSOR_HW_FLAGS_PIXCK (2) // pixel clock edge.
#define SENSOR_HW_FLAGS_FSYNC (3) // hardware frame sync. #define SENSOR_HW_FLAGS_FSYNC (3) // hardware frame sync.
#define SENSOR_HW_FLAGS_JPEGE (4) // hardware JPEG encoder. #define SENSOR_HW_FLAGS_JPEGE (4) // hardware JPEG encoder.
#define SWNSOR_HW_FLAGS_RGB565_REV (5) // byte reverse rgb565.
#define SENSOR_HW_FLAGS_GET(s, x) ((s)->hw_flags & (1<<x)) #define SENSOR_HW_FLAGS_GET(s, x) ((s)->hw_flags & (1<<x))
#define SENSOR_HW_FLAGS_SET(s, x, v) ((s)->hw_flags |= (v<<x)) #define SENSOR_HW_FLAGS_SET(s, x, v) ((s)->hw_flags |= (v<<x))
#define SENSOR_HW_FLAGS_CLR(s, x) ((s)->hw_flags &= ~(1<<x)) #define SENSOR_HW_FLAGS_CLR(s, x) ((s)->hw_flags &= ~(1<<x))