mirror of
https://github.com/openmv/openmv.git
synced 2025-11-04 14:49:50 +08:00
ports: Fix accidental CPU cache invalidation.
This commit is contained in:
parent
df7df2ba82
commit
cc823e2fbb
@ -404,8 +404,10 @@ vbuffer_t *framebuffer_get_head(framebuffer_flags_t flags) {
|
|||||||
vbuffer_t *buffer = framebuffer_get_buffer(new_head);
|
vbuffer_t *buffer = framebuffer_get_buffer(new_head);
|
||||||
|
|
||||||
#ifdef __DCACHE_PRESENT
|
#ifdef __DCACHE_PRESENT
|
||||||
// Make sure any cached CPU reads are dropped before returning the buffer.
|
if (flags & FB_INVALIDATE) {
|
||||||
SCB_InvalidateDCache_by_Addr(buffer->data, framebuffer_get_buffer_size());
|
// Make sure any cached CPU reads are dropped before returning the buffer.
|
||||||
|
SCB_InvalidateDCache_by_Addr(buffer->data, framebuffer_get_buffer_size());
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return buffer;
|
return buffer;
|
||||||
|
|||||||
@ -40,8 +40,9 @@ typedef struct framebuffer {
|
|||||||
extern framebuffer_t *framebuffer;
|
extern framebuffer_t *framebuffer;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
FB_NO_FLAGS = (0 << 0),
|
FB_NO_FLAGS = (0 << 0),
|
||||||
FB_PEEK = (1 << 0), // If set, will not move the head/tail.
|
FB_PEEK = (1 << 0), // If set, will not move the head/tail.
|
||||||
|
FB_INVALIDATE = (1 << 1), // If set, invalidate the buffer on return.
|
||||||
} framebuffer_flags_t;
|
} framebuffer_flags_t;
|
||||||
|
|
||||||
typedef struct vbuffer {
|
typedef struct vbuffer {
|
||||||
|
|||||||
@ -26,6 +26,7 @@
|
|||||||
|
|
||||||
#define DMA_LENGTH_ALIGNMENT (8)
|
#define DMA_LENGTH_ALIGNMENT (8)
|
||||||
#define SENSOR_TIMEOUT_MS (3000)
|
#define SENSOR_TIMEOUT_MS (3000)
|
||||||
|
#define MIN_EDMA_DST_INC (4)
|
||||||
|
|
||||||
// Sensor struct.
|
// Sensor struct.
|
||||||
sensor_t sensor = {};
|
sensor_t sensor = {};
|
||||||
@ -156,6 +157,7 @@ int sensor_abort(bool fifo_flush, bool in_irq) {
|
|||||||
CSI_DisableInterrupts(CSI, CSI_IRQ_FLAGS);
|
CSI_DisableInterrupts(CSI, CSI_IRQ_FLAGS);
|
||||||
CSI_REG_CR3(CSI) &= ~CSI_CR3_DMA_REQ_EN_RFF_MASK;
|
CSI_REG_CR3(CSI) &= ~CSI_CR3_DMA_REQ_EN_RFF_MASK;
|
||||||
CSI_REG_CR18(CSI) &= ~CSI_CR18_CSI_ENABLE_MASK;
|
CSI_REG_CR18(CSI) &= ~CSI_CR18_CSI_ENABLE_MASK;
|
||||||
|
dest_inc_size = 0;
|
||||||
sensor.first_line = false;
|
sensor.first_line = false;
|
||||||
sensor.drop_frame = false;
|
sensor.drop_frame = false;
|
||||||
sensor.last_frame_ms = 0;
|
sensor.last_frame_ms = 0;
|
||||||
@ -208,7 +210,7 @@ int sensor_dma_memcpy(void *dma, void *dst, void *src, int bpp, bool transposed)
|
|||||||
// beats. Additionally, the CSI hardware lacks cropping so we cannot align the source address.
|
// beats. Additionally, the CSI hardware lacks cropping so we cannot align the source address.
|
||||||
// Given this, performance will be lacking on cropped images. So much so that we do not use
|
// Given this, performance will be lacking on cropped images. So much so that we do not use
|
||||||
// the EDMA for anything less than 4-byte transfers otherwise you get sensor timeout errors.
|
// the EDMA for anything less than 4-byte transfers otherwise you get sensor timeout errors.
|
||||||
if (dest_inc_size < 4) {
|
if (dest_inc_size < MIN_EDMA_DST_INC) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -468,7 +470,16 @@ int sensor_snapshot(sensor_t *sensor, image_t *image, uint32_t flags) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
vbuffer_t *buffer = framebuffer_get_head(FB_NO_FLAGS);
|
framebuffer_flags_t fb_flags = FB_NO_FLAGS;
|
||||||
|
|
||||||
|
#if defined(OMV_CSI_DMA)
|
||||||
|
// dest_inc_size will be less than MIN_EDMA_DST_INC if the EDMA is not initialized or unusable.
|
||||||
|
if (dest_inc_size >= MIN_EDMA_DST_INC) {
|
||||||
|
fb_flags = FB_INVALIDATE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
vbuffer_t *buffer = framebuffer_get_head(fb_flags);
|
||||||
// Wait for the DMA to finish the transfer.
|
// Wait for the DMA to finish the transfer.
|
||||||
for (mp_uint_t ticks = mp_hal_ticks_ms(); buffer == NULL;) {
|
for (mp_uint_t ticks = mp_hal_ticks_ms(); buffer == NULL;) {
|
||||||
MICROPY_EVENT_POLL_HOOK
|
MICROPY_EVENT_POLL_HOOK
|
||||||
@ -483,7 +494,7 @@ int sensor_snapshot(sensor_t *sensor, image_t *image, uint32_t flags) {
|
|||||||
|
|
||||||
return SENSOR_ERROR_CAPTURE_TIMEOUT;
|
return SENSOR_ERROR_CAPTURE_TIMEOUT;
|
||||||
}
|
}
|
||||||
buffer = framebuffer_get_head(FB_NO_FLAGS);
|
buffer = framebuffer_get_head(fb_flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
// We're done receiving data.
|
// We're done receiving data.
|
||||||
|
|||||||
@ -825,10 +825,19 @@ int sensor_snapshot(sensor_t *sensor, image_t *image, uint32_t flags) {
|
|||||||
__HAL_DCMI_ENABLE_IT(&DCMIHandle, DCMI_IT_FRAME);
|
__HAL_DCMI_ENABLE_IT(&DCMIHandle, DCMI_IT_FRAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
framebuffer_flags_t fb_flags = FB_NO_FLAGS;
|
||||||
|
|
||||||
|
#if defined(OMV_MDMA_CHANNEL_DCMI_0)
|
||||||
|
// DCMI_MDMA_Handle0.State will be HAL_MDMA_STATE_RESET if the MDMA is not initialized.
|
||||||
|
if (DCMI_MDMA_Handle0.State != HAL_MDMA_STATE_RESET) {
|
||||||
|
fb_flags = FB_INVALIDATE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
vbuffer_t *buffer = NULL;
|
vbuffer_t *buffer = NULL;
|
||||||
// Wait for the frame data. __WFI() below will exit right on time because of DCMI_IT_FRAME.
|
// Wait for the frame data. __WFI() below will exit right on time because of DCMI_IT_FRAME.
|
||||||
// While waiting SysTick will trigger allowing us to timeout.
|
// While waiting SysTick will trigger allowing us to timeout.
|
||||||
for (uint32_t tick_start = HAL_GetTick(); !(buffer = framebuffer_get_head(FB_NO_FLAGS)); ) {
|
for (uint32_t tick_start = HAL_GetTick(); !(buffer = framebuffer_get_head(fb_flags)); ) {
|
||||||
__WFI();
|
__WFI();
|
||||||
|
|
||||||
// If we haven't exited this loop before the timeout then we need to abort the transfer.
|
// If we haven't exited this loop before the timeout then we need to abort the transfer.
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user