ports/mimxrt: Move CSI state to csi struct.

Signed-off-by: iabdalkader <i.abdalkader@gmail.com>
This commit is contained in:
iabdalkader 2024-11-25 20:59:08 +01:00
parent 336873dd2d
commit 14cbbb22d0
2 changed files with 27 additions and 27 deletions

View File

@ -47,18 +47,12 @@
#include "unaligned_memcpy.h"
#define DMA_LENGTH_ALIGNMENT (8)
#define CSI_TIMEOUT_MS (3000)
#define MIN_EDMA_DST_INC (4)
// Sensor struct.
omv_csi_t csi = {};
extern uint8_t _line_buf[OMV_LINE_BUF_SIZE];
#if defined(OMV_CSI_DMA)
static edma_handle_t CSI_EDMA_Handle[OMV_CSI_DMA_CHANNEL_COUNT];
static int src_inc, src_size, dest_inc_size;
#endif
#define CSI_IRQ_FLAGS (CSI_CR1_SOF_INTEN_MASK \
| CSI_CR1_FB2_DMA_DONE_INTEN_MASK \
| CSI_CR1_FB1_DMA_DONE_INTEN_MASK)
@ -179,7 +173,7 @@ int omv_csi_abort(bool fifo_flush, bool in_irq) {
CSI_DisableInterrupts(CSI, CSI_IRQ_FLAGS);
CSI_REG_CR3(CSI) &= ~CSI_CR3_DMA_REQ_EN_RFF_MASK;
CSI_REG_CR18(CSI) &= ~CSI_CR18_CSI_ENABLE_MASK;
dest_inc_size = 0;
csi.dest_inc = 0;
csi.first_line = false;
csi.drop_frame = false;
csi.last_frame_ms = 0;
@ -232,7 +226,7 @@ int omv_csi_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.
// 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.
if (dest_inc_size < MIN_EDMA_DST_INC) {
if (csi.dest_inc < MIN_EDMA_DST_INC) {
return -1;
}
@ -240,11 +234,11 @@ int omv_csi_dma_memcpy(void *dma, void *dst, void *src, int bpp, bool transposed
edma_transfer_config_t config;
EDMA_PrepareTransferConfig(&config,
src, // srcAddr
src_size, // srcWidth
src_inc, // srcOffset
csi.src_size, // srcWidth
csi.src_inc, // srcOffset
dst, // destAddr
transposed ? bpp : dest_inc_size, // destWidth
transposed ? (MAIN_FB()->v * bpp) : dest_inc_size, // destOffset
transposed ? bpp : csi.dest_inc, // destWidth
transposed ? (MAIN_FB()->v * bpp) : csi.dest_inc, // destOffset
MAIN_FB()->u * bpp, // bytesEachRequest
MAIN_FB()->u * bpp); // transferBytes
@ -356,7 +350,7 @@ void omv_csi_line_callback(uint32_t addr) {
// We're using multiple handles to give each channel the maximum amount of time possible to do the line
// transfer. In most situations only one channel will be running at a time. However, if SDRAM is
// backedup we don't have to disable the channel if it is flushing trailing data to SDRAM.
omv_csi_copy_line(&CSI_EDMA_Handle[buffer->offset % OMV_CSI_DMA_CHANNEL_COUNT], src, dst);
omv_csi_copy_line(&csi.dma_channels[buffer->offset % OMV_CSI_DMA_CHANNEL_COUNT], src, dst);
#else
omv_csi_copy_line(NULL, src, dst);
#endif
@ -390,24 +384,24 @@ static void edma_config(omv_csi_t *csi, uint32_t bytes_per_pixel) {
for (int j = i; j >= 0; j--) {
// 16-byte burst is not supported.
if ((j != 4) && (!(line_offset_bytes % (1 << j)))) {
src_inc = src_size = 1 << j;
csi->src_inc = csi->src_size = 1 << j;
break;
}
}
dest_inc_size = 1 << i;
csi->dest_inc = 1 << i;
break;
}
}
if (csi->transpose) {
dest_inc_size = bytes_per_pixel;
csi->dest_inc = bytes_per_pixel;
}
// YUV422 Source -> Y Destination
if ((csi->pixformat == PIXFORMAT_GRAYSCALE) && (csi->mono_bpp == 2)) {
src_inc = 2;
src_size = 1;
csi->src_inc = 2;
csi->src_size = 1;
}
}
#endif
@ -435,12 +429,10 @@ int omv_csi_snapshot(omv_csi_t *csi, image_t *image, uint32_t flags) {
// Free the current FB head.
framebuffer_free_current_buffer();
// If the DMA is Not currently transferring a new buffer,
// reconfigure and restart the CSI transfer.
// If the DMA is not active, reconfigure and restart the CSI transfer.
if (!(CSI->CR18 & CSI_CR18_CSI_ENABLE_MASK)) {
framebuffer_setup_buffers();
// Re/configure and re/start the CSI.
uint32_t bytes_per_pixel = omv_csi_get_src_bpp();
uint32_t dma_line_bytes = resolution[csi->framesize][0] * bytes_per_pixel;
uint32_t length = dma_line_bytes * h;
@ -459,7 +451,7 @@ int omv_csi_snapshot(omv_csi_t *csi, image_t *image, uint32_t flags) {
if (csi->pixformat != PIXFORMAT_JPEG) {
edma_config(csi, bytes_per_pixel);
for (int i = 0; i < OMV_CSI_DMA_CHANNEL_COUNT; i++) {
EDMA_CreateHandle(&CSI_EDMA_Handle[i], OMV_CSI_DMA, OMV_CSI_DMA_CHANNEL_START + i);
EDMA_CreateHandle(&csi->dma_channels[i], OMV_CSI_DMA, OMV_CSI_DMA_CHANNEL_START + i);
EDMA_DisableChannelInterrupts(OMV_CSI_DMA, OMV_CSI_DMA_CHANNEL_START + i, kEDMA_MajorInterruptEnable);
}
}
@ -494,8 +486,8 @@ int omv_csi_snapshot(omv_csi_t *csi, image_t *image, uint32_t 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) {
// dest_inc will be less than MIN_EDMA_DST_INC if the EDMA is not initialized or unusable.
if (csi->dest_inc >= MIN_EDMA_DST_INC) {
fb_flags = FB_INVALIDATE;
}
#endif
@ -504,7 +496,7 @@ int omv_csi_snapshot(omv_csi_t *csi, image_t *image, uint32_t flags) {
// Wait for the DMA to finish the transfer.
for (mp_uint_t ticks = mp_hal_ticks_ms(); buffer == NULL;) {
MICROPY_EVENT_POLL_HOOK
if ((mp_hal_ticks_ms() - ticks) > CSI_TIMEOUT_MS) {
if ((mp_hal_ticks_ms() - ticks) > OMV_CSI_TIMEOUT_MS) {
omv_csi_abort(true, false);
#if defined(OMV_CSI_FSYNC_PIN)

View File

@ -100,6 +100,8 @@ typedef const imxrt_gpio_t *omv_gpio_t;
// omv_i2c_t definitions
typedef LPI2C_Type *omv_i2c_dev_t;
#define OMV_I2C_MAX_8BIT_XFER (1024U)
#define OMV_I2C_MAX_16BIT_XFER (512U)
// omv_spi_t definitions
#define OMV_SPI_MODE_SLAVE (0)
@ -142,6 +144,12 @@ struct { \
lpspi_transfer_t xfer_descr; \
};
#define OMV_I2C_MAX_8BIT_XFER (1024U)
#define OMV_I2C_MAX_16BIT_XFER (512U)
// omv_csi_t port-specific fields.
#define OMV_CSI_PORT_BITS \
struct { \
int src_inc; \
int src_size; \
int dest_inc; \
edma_handle_t dma_channels[OMV_CSI_DMA_CHANNEL_COUNT]; \
};
#endif // __OMV_PORTCONFIG_H__