mirror of
https://github.com/openmv/openmv.git
synced 2025-11-04 14:49:50 +08:00
Fix grayscale color and y filter
This commit is contained in:
parent
1b36b95521
commit
cd0372f1b3
@ -163,6 +163,7 @@
|
||||
#define WRITE_GPIO 0x82
|
||||
#define READ_GPIO 0x84
|
||||
#define WRITE_MULTIIC 0xb8
|
||||
#define WRITE_BLOCKMVC1 0x34
|
||||
|
||||
// Bit definitions
|
||||
#define VDCTRL1 0x2B
|
||||
@ -172,6 +173,7 @@
|
||||
#define VDCTRL2_LINECOUNT (1 << 0)
|
||||
#define VDCTRL2_PIXEL_WIDTH (1 << 10)
|
||||
#define VDCTRL2_ENABLE_VIDEO (1 << 15)
|
||||
#define BLOCKMVC1_PYF (1 << 4)
|
||||
|
||||
// VS23 video commands
|
||||
#define PROGRAM 0x30
|
||||
@ -245,9 +247,18 @@ static void SpiClearRam()
|
||||
OMV_SPI_LCD_CS_HIGH();
|
||||
}
|
||||
|
||||
static void SpiRamWriteProgram(int opcode, int data0, int data1, int data2, int data3)
|
||||
static void SpiRamWriteProgram(int data0, int data1, int data2, int data3)
|
||||
{
|
||||
uint8_t packet[5] = {opcode, data3, data2, data1, data0};
|
||||
uint8_t packet[5] = {PROGRAM, data3, data2, data1, data0};
|
||||
|
||||
OMV_SPI_LCD_CS_LOW();
|
||||
HAL_SPI_Transmit(OMV_SPI_LCD_CONTROLLER->spi, packet, sizeof(packet), HAL_MAX_DELAY);
|
||||
OMV_SPI_LCD_CS_HIGH();
|
||||
}
|
||||
|
||||
static void SpiRamWriteLowPassFilter(int data)
|
||||
{
|
||||
uint8_t packet[6] = {WRITE_BLOCKMVC1, 0, 0, 0, 0, data};
|
||||
|
||||
OMV_SPI_LCD_CS_LOW();
|
||||
HAL_SPI_Transmit(OMV_SPI_LCD_CONTROLLER->spi, packet, sizeof(packet), HAL_MAX_DELAY);
|
||||
@ -320,7 +331,7 @@ static void SpiRamVideoInit()
|
||||
SpiRamWriteWordRegister(LINELEN, PLLCLKS_PER_LINE);
|
||||
|
||||
// Set microcode program for picture lines
|
||||
SpiRamWriteProgram(PROGRAM, OP1, OP2, OP3, OP4);
|
||||
SpiRamWriteProgram(OP1, OP2, OP3, OP4);
|
||||
|
||||
// Define where Line Indexes are stored in memory
|
||||
SpiRamWriteWordRegister(INDEXSTART, INDEX_START_LONGWORDS);
|
||||
@ -370,6 +381,9 @@ static void SpiRamVideoInit()
|
||||
SpiRamWriteWordRegister(VDCTRL2, (VDCTRL2_LINECOUNT * (TOTAL_LINES - 1))
|
||||
| (VDCTRL2_PIXEL_WIDTH * (PLLCLKS_PER_PIXEL - 1))
|
||||
| (VDCTRL2_ENABLE_VIDEO));
|
||||
|
||||
// Enable the low-pass Y filter.
|
||||
SpiRamWriteLowPassFilter(BLOCKMVC1_PYF);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
@ -539,8 +553,20 @@ static void spi_tv_callback(SPI_HandleTypeDef *hspi)
|
||||
}
|
||||
}
|
||||
|
||||
// Convert a 16-bit RGB565 line of pixels to 12-bit YUV422 with padding.
|
||||
static void spi_tv_draw_image_cb_convert(uint16_t *row_pointer_i, uint8_t *row_pointer_o)
|
||||
// Convert a 8-bit Grayscale line of pixels to 12-bit YUV422 with padding (line is 16-bit per pixel).
|
||||
static void spi_tv_draw_image_cb_convert_grayscale(uint8_t *row_pointer_i, uint8_t *row_pointer_o)
|
||||
{
|
||||
for (int i = TV_WIDTH - 2, j = ((TV_WIDTH * 3) / 2) - 3; i >= 0; i -= 2, j -= 3) {
|
||||
int y0 = IMAGE_GET_GRAYSCALE_PIXEL_FAST(row_pointer_i, i);
|
||||
int y1 = IMAGE_GET_GRAYSCALE_PIXEL_FAST(row_pointer_i, i + 1);
|
||||
IMAGE_PUT_GRAYSCALE_PIXEL_FAST(row_pointer_o, j, 0);
|
||||
IMAGE_PUT_GRAYSCALE_PIXEL_FAST(row_pointer_o, j + 1, y0);
|
||||
IMAGE_PUT_GRAYSCALE_PIXEL_FAST(row_pointer_o, j + 2, y1);
|
||||
}
|
||||
}
|
||||
|
||||
// Convert a 16-bit RGB565 line of pixels to 12-bit YUV422 with padding (line is 16-bit per pixel).
|
||||
static void spi_tv_draw_image_cb_convert_rgb565(uint16_t *row_pointer_i, uint8_t *row_pointer_o)
|
||||
{
|
||||
for (int i = 0, j = 0; i < TV_WIDTH; i += 2, j += 3) {
|
||||
#if defined(MCU_SERIES_F4) || defined(MCU_SERIES_F7) || defined(MCU_SERIES_H7)
|
||||
@ -592,9 +618,15 @@ static void spi_tv_draw_image_cb_convert(uint16_t *row_pointer_i, uint8_t *row_p
|
||||
}
|
||||
}
|
||||
|
||||
static void spi_tv_draw_image_cb(int x_start, int x_end, int y_row, imlib_draw_row_data_t *data)
|
||||
static void spi_tv_draw_image_cb_grayscale(int x_start, int x_end, int y_row, imlib_draw_row_data_t *data)
|
||||
{
|
||||
spi_tv_draw_image_cb_convert((uint16_t *) data->dst_row_override, (uint8_t *) data->dst_row_override);
|
||||
spi_tv_draw_image_cb_convert_grayscale((uint8_t *) data->dst_row_override, (uint8_t *) data->dst_row_override);
|
||||
HAL_SPI_Transmit(OMV_SPI_LCD_CONTROLLER->spi, data->dst_row_override, PICLINE_LENGTH_BYTES, HAL_MAX_DELAY);
|
||||
}
|
||||
|
||||
static void spi_tv_draw_image_cb_rgb565(int x_start, int x_end, int y_row, imlib_draw_row_data_t *data)
|
||||
{
|
||||
spi_tv_draw_image_cb_convert_rgb565((uint16_t *) data->dst_row_override, (uint8_t *) data->dst_row_override);
|
||||
HAL_SPI_Transmit(OMV_SPI_LCD_CONTROLLER->spi, data->dst_row_override, PICLINE_LENGTH_BYTES, HAL_MAX_DELAY);
|
||||
}
|
||||
|
||||
@ -603,10 +635,13 @@ static void spi_tv_display(image_t *src_img, int dst_x_start, int dst_y_start, f
|
||||
const uint16_t *color_palette, const uint8_t *alpha_palette,
|
||||
image_hint_t hint)
|
||||
{
|
||||
bool rgb565 = src_img->bpp == IMAGE_BPP_RGB565;
|
||||
imlib_draw_row_callback_t cb = rgb565 ? spi_tv_draw_image_cb_rgb565 : spi_tv_draw_image_cb_grayscale;
|
||||
|
||||
image_t dst_img;
|
||||
dst_img.w = TV_WIDTH;
|
||||
dst_img.h = TV_HEIGHT;
|
||||
dst_img.bpp = IMAGE_BPP_RGB565;
|
||||
dst_img.bpp = rgb565 ? IMAGE_BPP_RGB565 : IMAGE_BPP_GRAYSCALE;
|
||||
|
||||
int x0, x1, y0, y1;
|
||||
bool black = !imlib_draw_image_rectangle(&dst_img, src_img, dst_x_start, dst_y_start, x_scale, y_scale,
|
||||
@ -631,7 +666,7 @@ static void spi_tv_display(image_t *src_img, int dst_x_start, int dst_y_start, f
|
||||
// Transmits left/right parts already zeroed...
|
||||
imlib_draw_image(&dst_img, src_img, dst_x_start, dst_y_start, x_scale, y_scale, roi,
|
||||
rgb_channel, alpha, color_palette, alpha_palette, hint | IMAGE_HINT_BLACK_BACKGROUND,
|
||||
spi_tv_draw_image_cb, dst_img.data);
|
||||
cb, dst_img.data);
|
||||
|
||||
// Zero the bottom rows
|
||||
if (y1 < TV_HEIGHT) {
|
||||
@ -655,41 +690,80 @@ static void spi_tv_display(image_t *src_img, int dst_x_start, int dst_y_start, f
|
||||
|
||||
dst_img.data = (uint8_t *) framebuffers[new_framebuffer_head];
|
||||
|
||||
if (black) { // zero the whole image
|
||||
memset(dst_img.data, 0, TV_WIDTH * TV_HEIGHT * sizeof(uint16_t));
|
||||
if (rgb565) {
|
||||
if (black) { // zero the whole image
|
||||
memset(dst_img.data, 0, TV_WIDTH * TV_HEIGHT * sizeof(uint16_t));
|
||||
} else {
|
||||
// Zero the top rows
|
||||
if (y0) {
|
||||
memset(dst_img.data, 0, TV_WIDTH * y0 * sizeof(uint16_t));
|
||||
}
|
||||
|
||||
if (x0) {
|
||||
for (int i = y0; i < y1; i++) { // Zero left
|
||||
memset(IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(&dst_img, i), 0, x0 * sizeof(uint16_t));
|
||||
}
|
||||
}
|
||||
|
||||
imlib_draw_image(&dst_img, src_img, dst_x_start, dst_y_start, x_scale, y_scale, roi,
|
||||
rgb_channel, alpha, color_palette, alpha_palette, hint | IMAGE_HINT_BLACK_BACKGROUND,
|
||||
NULL, NULL);
|
||||
|
||||
if (TV_WIDTH - x1) {
|
||||
for (int i = y0; i < y1; i++) { // Zero right
|
||||
memset(IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(&dst_img, i) + x1, 0,
|
||||
(TV_WIDTH - x1) * sizeof(uint16_t));
|
||||
}
|
||||
}
|
||||
|
||||
// Zero the bottom rows
|
||||
if (TV_HEIGHT - y1) {
|
||||
memset(IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(&dst_img, y1), 0,
|
||||
TV_WIDTH * (TV_HEIGHT - y1) * sizeof(uint16_t));
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < TV_HEIGHT; i++) { // Convert the image.
|
||||
spi_tv_draw_image_cb_convert_rgb565(IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(&dst_img, i),
|
||||
dst_img.data + (PICLINE_LENGTH_BYTES * i));
|
||||
}
|
||||
} else {
|
||||
// Zero the top rows
|
||||
if (y0) {
|
||||
memset(dst_img.data, 0, TV_WIDTH * y0 * sizeof(uint16_t));
|
||||
}
|
||||
if (black) { // zero the whole image
|
||||
memset(dst_img.data, 0, TV_WIDTH * TV_HEIGHT * sizeof(uint8_t));
|
||||
} else {
|
||||
// Zero the top rows
|
||||
if (y0) {
|
||||
memset(dst_img.data, 0, TV_WIDTH * y0 * sizeof(uint8_t));
|
||||
}
|
||||
|
||||
if (x0) {
|
||||
for (int i = y0; i < y1; i++) { // Zero left
|
||||
memset(IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(&dst_img, i), 0, x0 * sizeof(uint16_t));
|
||||
if (x0) {
|
||||
for (int i = y0; i < y1; i++) { // Zero left
|
||||
memset(IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(&dst_img, i), 0, x0 * sizeof(uint8_t));
|
||||
}
|
||||
}
|
||||
|
||||
imlib_draw_image(&dst_img, src_img, dst_x_start, dst_y_start, x_scale, y_scale, roi,
|
||||
rgb_channel, alpha, color_palette, alpha_palette, hint | IMAGE_HINT_BLACK_BACKGROUND,
|
||||
NULL, NULL);
|
||||
|
||||
if (TV_WIDTH - x1) {
|
||||
for (int i = y0; i < y1; i++) { // Zero right
|
||||
memset(IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(&dst_img, i) + x1, 0,
|
||||
(TV_WIDTH - x1) * sizeof(uint8_t));
|
||||
}
|
||||
}
|
||||
|
||||
// Zero the bottom rows
|
||||
if (TV_HEIGHT - y1) {
|
||||
memset(IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(&dst_img, y1), 0,
|
||||
TV_WIDTH * (TV_HEIGHT - y1) * sizeof(uint8_t));
|
||||
}
|
||||
}
|
||||
|
||||
imlib_draw_image(&dst_img, src_img, dst_x_start, dst_y_start, x_scale, y_scale, roi,
|
||||
rgb_channel, alpha, color_palette, alpha_palette, hint | IMAGE_HINT_BLACK_BACKGROUND,
|
||||
NULL, NULL);
|
||||
|
||||
if (TV_WIDTH - x1) {
|
||||
for (int i = y0; i < y1; i++) { // Zero right
|
||||
memset(IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(&dst_img, i) + x1, 0,
|
||||
(TV_WIDTH - x1) * sizeof(uint16_t));
|
||||
}
|
||||
for (int i = TV_HEIGHT - 1; i >= 0; i--) { // Convert the image.
|
||||
spi_tv_draw_image_cb_convert_grayscale(IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(&dst_img, i),
|
||||
dst_img.data + (PICLINE_LENGTH_BYTES * i));
|
||||
}
|
||||
|
||||
// Zero the bottom rows
|
||||
if (TV_HEIGHT - y1) {
|
||||
memset(IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(&dst_img, y1), 0,
|
||||
TV_WIDTH * (TV_HEIGHT - y1) * sizeof(uint16_t));
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < TV_HEIGHT; i++) { // Convert the iamge.
|
||||
spi_tv_draw_image_cb_convert(IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(&dst_img, i),
|
||||
dst_img.data + (PICLINE_LENGTH_BYTES * i));
|
||||
}
|
||||
|
||||
#ifdef __DCACHE_PRESENT
|
||||
|
||||
Loading…
Reference in New Issue
Block a user