From dbdf26d93c946a1048529c995bb34778d1d77cd3 Mon Sep 17 00:00:00 2001 From: "Kwabena W. Agyeman" Date: Mon, 20 Jul 2020 15:54:40 -0700 Subject: [PATCH] Frame buffer respects fb alloc now --- src/omv/fb_alloc.c | 5 +++++ src/omv/fb_alloc.h | 1 + src/omv/framebuffer.c | 32 +++++++++----------------------- src/omv/framebuffer.h | 3 ++- src/omv/lepton.c | 2 +- src/omv/sensor.c | 21 ++++++++++++--------- 6 files changed, 30 insertions(+), 34 deletions(-) diff --git a/src/omv/fb_alloc.c b/src/omv/fb_alloc.c index bcbdd8265..258616030 100644 --- a/src/omv/fb_alloc.c +++ b/src/omv/fb_alloc.c @@ -31,6 +31,11 @@ static char *fb_alloc_min_address() return (char *) (framebuffer_get_buffer() + framebuffer_get_frame_size()); } +char *fb_alloc_stack_pointer() +{ + return pointer; +} + __weak NORETURN void fb_alloc_fail() { nlr_raise(mp_obj_new_exception_msg(&mp_type_MemoryError, diff --git a/src/omv/fb_alloc.h b/src/omv/fb_alloc.h index ed8529783..68277813d 100644 --- a/src/omv/fb_alloc.h +++ b/src/omv/fb_alloc.h @@ -12,6 +12,7 @@ #define FB_ALLOC_NO_HINT 0 #define FB_ALLOC_PREFER_SPEED 1 #define FB_ALLOC_PREFER_SIZE 2 +char *fb_alloc_stack_pointer(); void fb_alloc_fail(); void fb_alloc_init0(); uint32_t fb_avail(); diff --git a/src/omv/framebuffer.c b/src/omv/framebuffer.c index ed2a32c4f..8e4cbdb76 100644 --- a/src/omv/framebuffer.c +++ b/src/omv/framebuffer.c @@ -16,7 +16,6 @@ #define CONSERVATIVE_JPEG_BUF_SIZE (OMV_JPEG_BUF_SIZE-64) extern char _fb_base; -extern char _fballoc; framebuffer_t *framebuffer = (framebuffer_t *) &_fb_base; extern char _jpeg_buf; @@ -200,32 +199,19 @@ int32_t framebuffer_get_depth() uint32_t framebuffer_get_frame_size() { - switch (framebuffer->bpp) { - case -1: { - // Invalid frame. - return 0; - } - case IMAGE_BPP_BINARY: { - return ((framebuffer->w + UINT32_T_MASK) >> UINT32_T_SHIFT) * framebuffer->h; - } - case IMAGE_BPP_GRAYSCALE: { - return (framebuffer->w * framebuffer->h) * sizeof(uint8_t); - } - case IMAGE_BPP_RGB565: { - return (framebuffer->w * framebuffer->h) * sizeof(uint16_t); - } - case IMAGE_BPP_BAYER: { - return framebuffer->w * framebuffer->h; - } - default: { // JPEG - return framebuffer->bpp; - } - } + image_t img; + framebuffer_initialize_image(&img); + return image_size(&img); } uint32_t framebuffer_get_buffer_size() { - return &_fballoc - (char *) framebuffer->pixels; + uint32_t size = (uint32_t) (fb_alloc_stack_pointer() - ((char *) framebuffer->pixels)); + // We don't want to give all of the frame buffer RAM to the frame buffer. So, we will limit the + // maximum amount of RAM we return. + size = IM_MIN(size, OMV_RAW_BUF_SIZE); + // Needs to be a multiple of 32 for DMA transfers... + return (size / 32) * 32; } uint8_t *framebuffer_get_buffer() diff --git a/src/omv/framebuffer.h b/src/omv/framebuffer.h index 459ea1f34..3ceabd5d8 100644 --- a/src/omv/framebuffer.h +++ b/src/omv/framebuffer.h @@ -64,7 +64,8 @@ int32_t framebuffer_get_depth(); // otherwise return 0 if the framebuffer is unintialized or invalid (e.g. first frame). uint32_t framebuffer_get_frame_size(); -// Return the max frame size that fits the framebuffer (i.e OMV_RAW_BUF_SIZE - sizeof(framebuffer_t)) +// Return the max frame size that fits the framebuffer +// (i.e OMV_RAW_BUF_SIZE - sizeof(framebuffer_t)) uint32_t framebuffer_get_buffer_size(); // Return the current buffer address. diff --git a/src/omv/lepton.c b/src/omv/lepton.c index 191615e95..14a471bd2 100644 --- a/src/omv/lepton.c +++ b/src/omv/lepton.c @@ -475,7 +475,7 @@ static int sensor_check_buffsize(sensor_t *sensor) break; } - if ((MAIN_FB()->w * MAIN_FB()->h * bpp) > OMV_RAW_BUF_SIZE) { + if ((MAIN_FB()->w * MAIN_FB()->h * bpp) > framebuffer_get_buffer_size()) { return -1; } diff --git a/src/omv/sensor.c b/src/omv/sensor.c index 6f391210d..fdb9c5e23 100644 --- a/src/omv/sensor.c +++ b/src/omv/sensor.c @@ -550,10 +550,11 @@ int sensor_set_pixformat(pixformat_t pixformat) // This code is explicitly here to allow users to set the resolution to RGB565 and have it // switch to BAYER only once even though they are setting the resolution to RGB565 repeatedly // in a loop. Only RGB565->BAYER has this problem and needs this fix because of sensor_check_buffsize(). + uint32_t size = framebuffer_get_buffer_size(); if ((sensor.pixformat == PIXFORMAT_BAYER) && (pixformat == PIXFORMAT_RGB565) - && (MAIN_FB()->u * MAIN_FB()->v * 2 > OMV_RAW_BUF_SIZE) - && (MAIN_FB()->u * MAIN_FB()->v * 1 <= OMV_RAW_BUF_SIZE)) { + && (MAIN_FB()->u * MAIN_FB()->v * 2 > size) + && (MAIN_FB()->u * MAIN_FB()->v * 1 <= size)) { // No change return 0; } @@ -921,6 +922,7 @@ void DCMI_VsyncExtiCallback() // within the RAM we have onboard the system. static void sensor_check_buffsize() { + uint32_t size = framebuffer_get_buffer_size(); uint32_t bpp; switch (sensor.pixformat) { @@ -938,7 +940,7 @@ static void sensor_check_buffsize() } // MAIN_FB() fits, we are done. - if ((MAIN_FB()->u * MAIN_FB()->v * bpp) <= OMV_RAW_BUF_SIZE) { + if ((MAIN_FB()->u * MAIN_FB()->v * bpp) <= size) { return; } @@ -948,7 +950,7 @@ static void sensor_check_buffsize() bpp = 1; // MAIN_FB() fits, we are done (bpp is 1). - if (MAIN_FB()->u * MAIN_FB()->v <= OMV_RAW_BUF_SIZE) { + if (MAIN_FB()->u * MAIN_FB()->v <= size) { return; } } @@ -995,7 +997,7 @@ static void sensor_check_buffsize() } // Crop the frame buffer while keeping the aspect ratio and keeping the width/height even. - while (((MAIN_FB()->u * MAIN_FB()->v * bpp) > OMV_RAW_BUF_SIZE) || (MAIN_FB()->u % 2) || (MAIN_FB()->v % 2)) { + while (((MAIN_FB()->u * MAIN_FB()->v * bpp) > size) || (MAIN_FB()->u % 2) || (MAIN_FB()->v % 2)) { MAIN_FB()->u -= u_sub; MAIN_FB()->v -= v_sub; } @@ -1109,7 +1111,7 @@ void DCMI_DMAConvCpltUser(uint32_t addr) // uint16_t size = __REV16(*src16); // Prevent a buffer overflow when writing the jpeg data. - if (offset + size > OMV_RAW_BUF_SIZE) { + if (offset + size > framebuffer_get_buffer_size()) { jpeg_buffer_overflow = true; return; } @@ -1301,7 +1303,7 @@ int sensor_snapshot(sensor_t *sensor, image_t *image, streaming_cb_t streaming_c } // If two frames fit in ram, use double buffering in streaming mode. - doublebuf = ((length*2) <= OMV_RAW_BUF_SIZE); + doublebuf = ((length*2) <= framebuffer_get_buffer_size()); #if OMV_ENABLE_HM01B0 HAL_DCMI_EnableCrop(&DCMIHandle); @@ -1471,8 +1473,9 @@ int sensor_snapshot(sensor_t *sensor, image_t *image, streaming_cb_t streaming_c // within a transfer we have to look at the DMA counter and see how much data was moved. MAIN_FB()->bpp = (offset * MAX_XFER_SIZE) + ((MAX_XFER_SIZE/4) - __HAL_DMA_GET_COUNTER(&DMAHandle))*4; + uint32_t size = framebuffer_get_buffer_size(); // DMA has most likely corrupted FB alloc state and or more. - if (MAIN_FB()->bpp > OMV_RAW_BUF_SIZE) { + if (MAIN_FB()->bpp > size) { __fatal_error("JPEG Overflow!"); } @@ -1480,7 +1483,7 @@ int sensor_snapshot(sensor_t *sensor, image_t *image, streaming_cb_t streaming_c // In JPEG mode, the DMA uses the frame buffer memory directly instead of the line buffer, which is // located in a cacheable region and therefore must be invalidated before the CPU can access it again. // Note: The frame buffer address is 32-byte aligned, and the size is a multiple of 32-bytes for all boards. - SCB_InvalidateDCache_by_Addr((uint32_t*)MAIN_FB()->pixels, OMV_RAW_BUF_SIZE); + SCB_InvalidateDCache_by_Addr((uint32_t*)MAIN_FB()->pixels, size); #endif } // Clean trailing data.