kopia lustrzana https://github.com/DL7AD/pecanpico10
Improvements to DMA SBM image capture...
- Additional TRACE output - DMA DBM now can be disabled through -D make define - Fix incorrect count of image size in DMA SBM operation - Rename some data structure members and move struct in ov5640.hwebcam_dev
rodzic
f553ac64bf
commit
9f1aff4e0a
|
|
@ -227,7 +227,7 @@
|
|||
* @note The default is @p TRUE.
|
||||
* @note Requires @p CH_CFG_USE_MUTEXES.
|
||||
*/
|
||||
#define CH_CFG_USE_CONDVARS TRUE
|
||||
#define CH_CFG_USE_CONDVARS FALSE
|
||||
|
||||
/**
|
||||
* @brief Conditional Variables APIs with timeout.
|
||||
|
|
|
|||
|
|
@ -84,20 +84,22 @@
|
|||
#define STM32_ADC_ADC1_DMA_IRQ_PRIORITY 6
|
||||
|
||||
/*
|
||||
* EXT driver system settings.
|
||||
* IRQ system settings.
|
||||
*/
|
||||
#define STM32_EXT_EXTI0_IRQ_PRIORITY 6
|
||||
#define STM32_EXT_EXTI1_IRQ_PRIORITY 6
|
||||
#define STM32_EXT_EXTI2_IRQ_PRIORITY 6
|
||||
#define STM32_EXT_EXTI3_IRQ_PRIORITY 6
|
||||
#define STM32_EXT_EXTI4_IRQ_PRIORITY 6
|
||||
#define STM32_EXT_EXTI5_9_IRQ_PRIORITY 6
|
||||
#define STM32_EXT_EXTI10_15_IRQ_PRIORITY 3
|
||||
#define STM32_EXT_EXTI16_IRQ_PRIORITY 6
|
||||
#define STM32_EXT_EXTI17_IRQ_PRIORITY 15
|
||||
#define STM32_EXT_EXTI18_IRQ_PRIORITY 6
|
||||
#define STM32_EXT_EXTI19_IRQ_PRIORITY 6
|
||||
#define STM32_EXT_EXTI22_IRQ_PRIORITY 15
|
||||
#define STM32_IRQ_EXTI0_PRIORITY 6
|
||||
#define STM32_IRQ_EXTI1_PRIORITY 6
|
||||
#define STM32_IRQ_EXTI2_PRIORITY 6
|
||||
#define STM32_IRQ_EXTI3_PRIORITY 6
|
||||
#define STM32_IRQ_EXTI4_PRIORITY 6
|
||||
#define STM32_IRQ_EXTI5_9_PRIORITY 6
|
||||
#define STM32_IRQ_EXTI10_15_PRIORITY 3
|
||||
#define STM32_IRQ_EXTI16_PRIORITY 6
|
||||
#define STM32_IRQ_EXTI17_PRIORITY 15
|
||||
#define STM32_IRQ_EXTI18_PRIORITY 6
|
||||
#define STM32_IRQ_EXTI19_PRIORITY 6
|
||||
#define STM32_IRQ_EXTI20_PRIORITY 6
|
||||
#define STM32_IRQ_EXTI21_PRIORITY 15
|
||||
#define STM32_IRQ_EXTI22_PRIORITY 15
|
||||
|
||||
/*
|
||||
* GPT driver system settings.
|
||||
|
|
|
|||
|
|
@ -227,7 +227,7 @@
|
|||
* @note The default is @p TRUE.
|
||||
* @note Requires @p CH_CFG_USE_MUTEXES.
|
||||
*/
|
||||
#define CH_CFG_USE_CONDVARS TRUE
|
||||
#define CH_CFG_USE_CONDVARS FALSE
|
||||
|
||||
/**
|
||||
* @brief Conditional Variables APIs with timeout.
|
||||
|
|
|
|||
|
|
@ -80,20 +80,22 @@
|
|||
#define STM32_ADC_ADC1_DMA_IRQ_PRIORITY 6
|
||||
|
||||
/*
|
||||
* EXT driver system settings.
|
||||
* IRQ system settings.
|
||||
*/
|
||||
#define STM32_EXT_EXTI0_IRQ_PRIORITY 6
|
||||
#define STM32_EXT_EXTI1_IRQ_PRIORITY 6
|
||||
#define STM32_EXT_EXTI2_IRQ_PRIORITY 6
|
||||
#define STM32_EXT_EXTI3_IRQ_PRIORITY 6
|
||||
#define STM32_EXT_EXTI4_IRQ_PRIORITY 6
|
||||
#define STM32_EXT_EXTI5_9_IRQ_PRIORITY 6
|
||||
#define STM32_EXT_EXTI10_15_IRQ_PRIORITY 3
|
||||
#define STM32_EXT_EXTI16_IRQ_PRIORITY 6
|
||||
#define STM32_EXT_EXTI17_IRQ_PRIORITY 15
|
||||
#define STM32_EXT_EXTI18_IRQ_PRIORITY 6
|
||||
#define STM32_EXT_EXTI19_IRQ_PRIORITY 6
|
||||
#define STM32_EXT_EXTI22_IRQ_PRIORITY 15
|
||||
#define STM32_IRQ_EXTI0_PRIORITY 6
|
||||
#define STM32_IRQ_EXTI1_PRIORITY 6
|
||||
#define STM32_IRQ_EXTI2_PRIORITY 6
|
||||
#define STM32_IRQ_EXTI3_PRIORITY 6
|
||||
#define STM32_IRQ_EXTI4_PRIORITY 6
|
||||
#define STM32_IRQ_EXTI5_9_PRIORITY 6
|
||||
#define STM32_IRQ_EXTI10_15_PRIORITY 3
|
||||
#define STM32_IRQ_EXTI16_PRIORITY 6
|
||||
#define STM32_IRQ_EXTI17_PRIORITY 15
|
||||
#define STM32_IRQ_EXTI18_PRIORITY 6
|
||||
#define STM32_IRQ_EXTI19_PRIORITY 6
|
||||
#define STM32_IRQ_EXTI20_PRIORITY 6
|
||||
#define STM32_IRQ_EXTI21_PRIORITY 15
|
||||
#define STM32_IRQ_EXTI22_PRIORITY 15
|
||||
|
||||
/*
|
||||
* GPT driver system settings.
|
||||
|
|
|
|||
|
|
@ -215,7 +215,7 @@ CPPWARN = -Wall -Wextra -Wundef
|
|||
|
||||
# List all user C define here, like -D_DEBUG=1
|
||||
UDEFS = -D_GNU_SOURCE -DARM_MATH_CM4 -DSHELL_CMD_TEST_ENABLED=0 \
|
||||
-DSHELL_CMD_EXIT_ENABLED=1 -DSET_TRACE_LEVEL=5 \
|
||||
-DSHELL_CMD_EXIT_ENABLED=1 -DSET_TRACE_LEVEL=5 -DPDCMI_USE_DMA_DBM=0 \
|
||||
-DSHELL_CMD_MEM_ENABLED=0
|
||||
# -DDISABLE_HW_WATCHDOG=1
|
||||
|
||||
|
|
|
|||
|
|
@ -215,7 +215,7 @@ CPPWARN = -Wall -Wextra -Wundef
|
|||
|
||||
# List all user C define here, like -D_DEBUG=1
|
||||
UDEFS = -D_GNU_SOURCE -DARM_MATH_CM4 -DSHELL_CMD_TEST_ENABLED=0 \
|
||||
-DSHELL_CMD_EXIT_ENABLED=1 -DSET_TRACE_LEVEL=5 \
|
||||
-DSHELL_CMD_EXIT_ENABLED=1 -DSET_TRACE_LEVEL=5 -DPDCMI_USE_DMA_DBM=0 \
|
||||
-DSHELL_CMD_MEM_ENABLED=0 -DDISABLE_HW_WATCHDOG=1
|
||||
|
||||
# Define ASM defines here
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ const conf_t conf_flash_default = {
|
|||
.img_sec = {
|
||||
.svc_conf = {
|
||||
.active = true,
|
||||
.cycle = TIME_S2I(60 * 2),
|
||||
.cycle = TIME_S2I(60 * 1),
|
||||
.init_delay = TIME_S2I(60),
|
||||
.send_spacing = TIME_S2I(0)
|
||||
},
|
||||
|
|
|
|||
|
|
@ -728,7 +728,7 @@ uint32_t OV5640_Snapshot2RAM(uint8_t* buffer,
|
|||
do {
|
||||
size_sampled = OV5640_Capture(buffer, size);
|
||||
if(size_sampled > 0) {
|
||||
TRACE_INFO("CAM > Image size: %d bytes", size_sampled);
|
||||
TRACE_INFO("CAM > Captured %d bytes", size_sampled);
|
||||
return size_sampled;
|
||||
}
|
||||
/* Allow time for other threads. */
|
||||
|
|
@ -762,10 +762,10 @@ uint32_t OV5640_Snapshot2RAM(uint8_t* buffer,
|
|||
#endif /* !defined(dmaStreamGetCurrentTarget) */
|
||||
#endif /* PDCMI_USE_DMA_DBM == TRUE */
|
||||
|
||||
inline void dma_start(const stm32_dma_stream_t *dmastp) {
|
||||
inline void dma_start(dma_capture_t *ppdcmi) {
|
||||
/* Clear any pending interrupts. */
|
||||
dmaStreamClearInterrupt(dmastp);
|
||||
dmaStreamEnable(dmastp);
|
||||
dmaStreamClearInterrupt(ppdcmi->dmastp);
|
||||
dmaStreamEnable(ppdcmi->dmastp);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -773,11 +773,11 @@ inline void dma_start(const stm32_dma_stream_t *dmastp) {
|
|||
* Note that any DMA FIFO transfer in progress will complete.
|
||||
* The Chibios DMAV2 driver waits for EN to clear before proceeding.
|
||||
*/
|
||||
inline uint16_t dma_stop(const stm32_dma_stream_t *dmastp) {
|
||||
dmaStreamDisable(dmastp);
|
||||
uint16_t transfer = dmaStreamGetTransactionSize(dmastp);
|
||||
dmaStreamRelease(dmastp);
|
||||
return (PDCMI_DMA_SEGMENT_SIZE - transfer);
|
||||
inline uint16_t dma_stop(dma_capture_t *ppdcmi) {
|
||||
dmaStreamDisable(ppdcmi->dmastp);
|
||||
uint16_t remaining = dmaStreamGetTransactionSize(ppdcmi->dmastp);
|
||||
dmaStreamRelease(ppdcmi->dmastp);
|
||||
return (ppdcmi->page_size - remaining);
|
||||
}
|
||||
|
||||
#if PDCMI_USE_DMA_DBM == TRUE
|
||||
|
|
@ -794,7 +794,7 @@ static void dma_interrupt(void *p, uint32_t flags) {
|
|||
/*
|
||||
* DMA has been terminated by initiating function.
|
||||
* DMA stop has already been executed.
|
||||
* We shouldn't be here...
|
||||
* If there was a pending interrupt can we get here?
|
||||
*/
|
||||
if(dma_control->terminate) {
|
||||
dmaStreamClearInterrupt(dmastp);
|
||||
|
|
@ -814,8 +814,8 @@ static void dma_interrupt(void *p, uint32_t flags) {
|
|||
*/
|
||||
dma_control->timer->DIER &= ~TIM_DIER_CC1DE;
|
||||
dma_control->timer->CCER &= ~TIM_CCER_CC1E;
|
||||
dma_control->dma_count += dma_stop(dmastp);
|
||||
dma_control->pdcmi_status = PDCMI_DMA_ERROR;
|
||||
dma_control->transfer_count += dma_stop(dmastp);
|
||||
dma_control->pdcmi_state = PDCMI_DMA_ERROR;
|
||||
palDisableLineEventI(dma_control->vsync_line);
|
||||
dmaStreamClearInterrupt(dmastp);
|
||||
dma_control->terminate = true;
|
||||
|
|
@ -836,12 +836,14 @@ static void dma_interrupt(void *p, uint32_t flags) {
|
|||
*
|
||||
* Since this is the last DMA buffer this may be treated as an error.
|
||||
* The DMA should normally be terminated by VSYNC before last buffer.
|
||||
* In the case that the buffer size was too small we can be here.
|
||||
*
|
||||
* Disable timer, DMA and flag fault.
|
||||
*/
|
||||
dma_control->timer->DIER &= ~TIM_DIER_CC1DE;
|
||||
dma_control->timer->CCER &= ~TIM_CCER_CC1E;
|
||||
dma_control->dma_count += dma_stop(dmastp);
|
||||
dma_control->pdcmi_status = PDCMI_DMA_END_BUFFER;
|
||||
dma_control->transfer_count += dma_stop(dmastp);
|
||||
dma_control->pdcmi_state = PDCMI_DMA_END_BUFFER;
|
||||
dma_control->terminate = true;
|
||||
palDisableLineEventI(dma_control->vsync_line);
|
||||
dmaStreamClearInterrupt(dmastp);
|
||||
|
|
@ -856,11 +858,11 @@ static void dma_interrupt(void *p, uint32_t flags) {
|
|||
* Checking state of CT at TCIF may be too late because of IRQ latency.
|
||||
* i.e. the DMA controller may have already changed CT before IRQ is serviced.
|
||||
*/
|
||||
dma_control->segment_address += PDCMI_DMA_SEGMENT_SIZE;
|
||||
dma_control->segment_address += PDCMI_DMA_DBM_PAGE_SIZE;
|
||||
if (dmaStreamGetCurrentTarget(dmastp) == 0) {
|
||||
dmaStreamSetMemory1(dmastp, dma_control->segment_address);
|
||||
dmaStreamSetMemory1(dmastp, dma_control->page_address);
|
||||
} else {
|
||||
dmaStreamSetMemory0(dmastp, dma_control->segment_address);
|
||||
dmaStreamSetMemory0(dmastp, dma_control->page_address);
|
||||
}
|
||||
dmaStreamClearInterrupt(dmastp);
|
||||
chSysUnlockFromISR();
|
||||
|
|
@ -871,7 +873,7 @@ static void dma_interrupt(void *p, uint32_t flags) {
|
|||
* Transfer complete for this segment.
|
||||
*/
|
||||
if(dma_control->terminate != true) {
|
||||
dma_control->dma_count += PDCMI_DMA_SEGMENT_SIZE;
|
||||
dma_control->page_adress += dma_control->page_size;
|
||||
}
|
||||
dmaStreamClearInterrupt(dmastp);
|
||||
chSysUnlockFromISR();
|
||||
|
|
@ -883,10 +885,10 @@ static void dma_interrupt(void *p, uint32_t flags) {
|
|||
*/
|
||||
dma_control->timer->DIER &= ~TIM_DIER_CC1DE;
|
||||
dma_control->timer->CCER &= ~TIM_CCER_CC1E;
|
||||
dma_control->pdcmi_status = PDCMI_DMA_UNKNOWN_IRQ;
|
||||
dma_control->pdcmi_state = PDCMI_DMA_UNKNOWN_IRQ;
|
||||
dma_control->terminate = true;
|
||||
dma_stop(dmastp);
|
||||
dma_control->dma_count = 0;
|
||||
dma_control->transfer_count = 0;
|
||||
palDisableLineEventI(dma_control->vsync_line);
|
||||
dmaStreamClearInterrupt(dmastp);
|
||||
chSysUnlockFromISR();
|
||||
|
|
@ -898,9 +900,22 @@ static void dma_interrupt(void *p, uint32_t flags) {
|
|||
static void dma_interrupt(void *p, uint32_t flags) {
|
||||
dma_capture_t *dma_control = p;
|
||||
|
||||
const stm32_dma_stream_t *dmastp = dma_control->dmastp;
|
||||
//const stm32_dma_stream_t *dmastp = dma_control->dmastp;
|
||||
chSysLockFromISR();
|
||||
|
||||
/*
|
||||
* DMA has been terminated by initiating function.
|
||||
* DMA stop has already been executed.
|
||||
* If there was a pending interrupt can we get here?
|
||||
*/
|
||||
if(dma_control->terminate) {
|
||||
dmaStreamClearInterrupt(dma_control->dmastp);
|
||||
chSysUnlockFromISR();
|
||||
return;
|
||||
}
|
||||
|
||||
dma_control->dma_flags = flags;
|
||||
|
||||
if(flags & (STM32_DMA_ISR_FEIF | STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) {
|
||||
/*
|
||||
* DMA transfer error, FIFO error or Direct mode error.
|
||||
|
|
@ -908,10 +923,10 @@ static void dma_interrupt(void *p, uint32_t flags) {
|
|||
*/
|
||||
dma_control->timer->DIER &= ~TIM_DIER_CC1DE;
|
||||
dma_control->timer->CCER &= ~TIM_CCER_CC1E;
|
||||
dma_control->dma_count += dma_stop(dmastp);
|
||||
dma_control->pdcmi_status = PDCMI_DMA_ERROR;
|
||||
dma_control->transfer_count = dma_stop(dma_control);
|
||||
dma_control->pdcmi_state = PDCMI_DMA_ERROR;
|
||||
palDisableLineEventI(dma_control->vsync_line);
|
||||
dmaStreamClearInterrupt(dmastp);
|
||||
dmaStreamClearInterrupt(dma_control->dmastp);
|
||||
chSysUnlockFromISR();
|
||||
return;
|
||||
}
|
||||
|
|
@ -927,11 +942,11 @@ static void dma_interrupt(void *p, uint32_t flags) {
|
|||
*/
|
||||
dma_control->timer->DIER &= ~TIM_DIER_CC1DE;
|
||||
dma_control->timer->CCER &= ~TIM_CCER_CC1E;
|
||||
dma_control->dma_count += dma_stop(dmastp);
|
||||
dma_stop(dma_control->dmastp);
|
||||
dma_control->pdcmi_status = PDCMI_DMA_COUNT_END;
|
||||
dma_control->transfer_count = dma_stop(dma_control);
|
||||
//dma_stop(dma_control->dmastp);
|
||||
dma_control->pdcmi_state = PDCMI_DMA_COUNT_END;
|
||||
palDisableLineEventI(dma_control->vsync_line);
|
||||
dmaStreamClearInterrupt(dmastp);
|
||||
dmaStreamClearInterrupt(dma_control->dmastp);
|
||||
dma_control->terminate = true;
|
||||
chSysUnlockFromISR();
|
||||
return;
|
||||
|
|
@ -942,10 +957,10 @@ static void dma_interrupt(void *p, uint32_t flags) {
|
|||
*/
|
||||
dma_control->timer->DIER &= ~TIM_DIER_CC1DE;
|
||||
dma_control->timer->CCER &= ~TIM_CCER_CC1E;
|
||||
dma_control->pdcmi_status = PDCMI_DMA_UNKNOWN_IRQ;
|
||||
dma_control->dma_count += dma_stop(dmastp);
|
||||
dma_control->pdcmi_state = PDCMI_DMA_UNKNOWN_IRQ;
|
||||
dma_control->transfer_count += dma_stop(dma_control);
|
||||
palDisableLineEventI(dma_control->vsync_line);
|
||||
dmaStreamClearInterrupt(dmastp);
|
||||
dmaStreamClearInterrupt(dma_control->dmastp);
|
||||
chSysUnlockFromISR();
|
||||
return;
|
||||
}
|
||||
|
|
@ -960,34 +975,36 @@ static void dma_interrupt(void *p, uint32_t flags) {
|
|||
void mode3_vsync_cb(void *arg) {
|
||||
dma_capture_t *dma_control = arg;
|
||||
|
||||
const stm32_dma_stream_t *dmastp = dma_control->dmastp;
|
||||
TIM_TypeDef *timer = dma_control->timer;
|
||||
//const stm32_dma_stream_t *dmastp = dma_control->dmastp;
|
||||
//TIM_TypeDef *timer = dma_control->timer;
|
||||
|
||||
chSysLockFromISR();
|
||||
if(palReadLine(LINE_CAM_VSYNC)) {
|
||||
if(palReadLine(LINE_CAM_VSYNC == PAL_HIGH)) {
|
||||
/* VSYNC leading edge. */
|
||||
if((timer->DIER & TIM_DIER_CC1DE) != 0) {
|
||||
if((dma_control->timer->DIER & TIM_DIER_CC1DE) != 0) {
|
||||
/* Timer is running so capture is enabled. */
|
||||
if(!dma_control->terminate) {
|
||||
/* Capture running so terminate. */
|
||||
dma_control->dma_count += dma_stop(dmastp);
|
||||
/* Capture not yet terminated so do it */
|
||||
dma_control->transfer_count += dma_stop(dma_control);
|
||||
dma_control->timer->DIER &= ~TIM_DIER_CC1DE;
|
||||
dma_control->timer->CCER &= ~TIM_CCER_CC1E;
|
||||
palDisableLineEventI(dma_control->vsync_line);
|
||||
/* If a DMA interrupt is pending then this will stop any activity. */
|
||||
dma_control->terminate = true;
|
||||
} /* Else DMA has terminated capture. This must be a nested interrupt. */
|
||||
} /* Else wait to arm timer on trailing edge. */
|
||||
chSysUnlockFromISR();
|
||||
return;
|
||||
} /* VSYNC trailing edge. */
|
||||
if((timer->DIER & TIM_DIER_CC1DE) == 0) {
|
||||
if((dma_control->timer->DIER & TIM_DIER_CC1DE) == 0) {
|
||||
/*
|
||||
* Timer not running.
|
||||
* Timer is not running.
|
||||
* Start DMA channel if termination not set.
|
||||
* Enable timer trigger of DMA.
|
||||
*/
|
||||
if(!dma_control->terminate) {
|
||||
dma_start(dma_control->dmastp);
|
||||
timer->DIER |= TIM_DIER_CC1DE;
|
||||
dma_start(dma_control);
|
||||
dma_control->timer->DIER |= TIM_DIER_CC1DE;
|
||||
}
|
||||
} /* Else wait to stop timer on leading edge. */
|
||||
chSysUnlockFromISR();
|
||||
|
|
@ -1063,7 +1080,7 @@ uint32_t OV5640_Capture(uint8_t* buffer, uint32_t size) {
|
|||
/*
|
||||
* Calculate the number of whole buffers.
|
||||
*/
|
||||
if((size / PDCMI_DMA_SEGMENT_SIZE) < 2) {
|
||||
if((size / PDCMI_DMA_DBM_PAGE_SIZE) < 2) {
|
||||
TRACE_ERROR("CAM > Capture buffer less than 2 DMA DBM segment segments");
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1122,16 +1139,19 @@ uint32_t OV5640_Capture(uint8_t* buffer, uint32_t size) {
|
|||
dmaStreamSetPeripheral(dma_control.dmastp, &GPIOA->IDR);
|
||||
|
||||
#if PDCMI_USE_DMA_DBM == TRUE
|
||||
dma_control.segment_address = buffer;
|
||||
dma_control.page_address = buffer;
|
||||
dma_control.base_buffer = buffer;
|
||||
dma_control.segment_count = (size / PDCMI_DMA_SEGMENT_SIZE);
|
||||
dma_control.page_count = (size / PDCMI_DMA_DBM_PAGE_SIZE);
|
||||
dma_control.page_size = PDCMI_DMA_DBM_PAGE_SIZE;
|
||||
/*
|
||||
* Set the initial buffer addresses.
|
||||
* The updating of DMA:MxAR is done in the the DMA interrupt function.
|
||||
*/
|
||||
dmaStreamSetMemory0(dma_control.dmastp, dma_control.segment_address);
|
||||
dmaStreamSetTransactionSize(dma_control.dmastp, PDCMI_DMA_SEGMENT_SIZE);
|
||||
dmaStreamSetMemory0(dma_control.dmastp, dma_control.page_address);
|
||||
dmaStreamSetTransactionSize(dma_control.dmastp, PDCMI_DMA_DBM_PAGE_SIZE);
|
||||
#else
|
||||
dma_control.page_size = size;
|
||||
dma_control.page_count = 1;
|
||||
dmaStreamSetMemory0(dma_control.dmastp, buffer);
|
||||
dmaStreamSetTransactionSize(dma_control.dmastp, size);
|
||||
#endif
|
||||
|
|
@ -1141,9 +1161,9 @@ uint32_t OV5640_Capture(uint8_t* buffer, uint32_t size) {
|
|||
| STM32_DMA_FCR_FEIE);
|
||||
dmaStreamClearInterrupt(dma_control.dmastp);
|
||||
|
||||
dma_control.pdcmi_status = PDCMI_NO_ERROR;
|
||||
dma_control.pdcmi_state = PDCMI_NO_ERROR;
|
||||
dma_control.dma_flags = 0;
|
||||
dma_control.dma_count = 0;
|
||||
dma_control.transfer_count = 0;
|
||||
dma_control.terminate = false;
|
||||
/*
|
||||
* Setup timer for PCLK
|
||||
|
|
@ -1158,7 +1178,8 @@ uint32_t OV5640_Capture(uint8_t* buffer, uint32_t size) {
|
|||
/* Setup VSNC event. */
|
||||
|
||||
dma_control.vsync_line = LINE_CAM_VSYNC;
|
||||
palSetLineCallback(LINE_CAM_VSYNC, (palcallback_t)mode3_vsync_cb, &dma_control);
|
||||
palSetLineCallback(LINE_CAM_VSYNC, (palcallback_t)mode3_vsync_cb,
|
||||
&dma_control);
|
||||
palEnableLineEvent(LINE_CAM_VSYNC, PAL_EVENT_MODE_BOTH_EDGES);
|
||||
|
||||
/*
|
||||
|
|
@ -1179,15 +1200,16 @@ uint32_t OV5640_Capture(uint8_t* buffer, uint32_t size) {
|
|||
|
||||
if(!timeout) {
|
||||
palDisableLineEventI(dma_control.vsync_line);
|
||||
dma_control.dma_count += dma_stop(dma_control.dmastp);
|
||||
dma_control.transfer_count += dma_stop(&dma_control);
|
||||
dma_control.timer->DIER &= ~TIM_DIER_CC1DE;
|
||||
dma_control.timer->CCER &= ~TIM_CCER_CC1E;
|
||||
dma_control.pdcmi_status = PDCMI_CAPTURE_TIMEOUT;
|
||||
dma_control.pdcmi_state = PDCMI_CAPTURE_TIMEOUT;
|
||||
}
|
||||
|
||||
OV5640_UnlockResourcesForCapture();
|
||||
|
||||
if(dma_control.pdcmi_status == PDCMI_DMA_ERROR) {
|
||||
switch(dma_control.pdcmi_state) {
|
||||
case PDCMI_DMA_ERROR: {
|
||||
if(dma_control.dma_flags & STM32_DMA_ISR_FEIF) {
|
||||
TRACE_ERROR("CAM > DMA FIFO error");
|
||||
error = 0x3;
|
||||
|
|
@ -1203,34 +1225,49 @@ uint32_t OV5640_Capture(uint8_t* buffer, uint32_t size) {
|
|||
error = 0x5;
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if(dma_control.pdcmi_status == PDCMI_DMA_END_BUFFER) {
|
||||
TRACE_ERROR("CAM > DMA ran out of buffer space");
|
||||
|
||||
case PDCMI_DMA_END_BUFFER: {
|
||||
TRACE_ERROR("CAM > DMA ran out of buffer space in DBM."
|
||||
" Image possibly useable");
|
||||
error = 0x6;
|
||||
return 0;
|
||||
return (dma_control.transfer_count);
|
||||
}
|
||||
if(dma_control.pdcmi_status == PDCMI_CAPTURE_TIMEOUT) {
|
||||
TRACE_ERROR("CAM > DMA image terminate timeout");
|
||||
|
||||
case PDCMI_CAPTURE_TIMEOUT: {
|
||||
TRACE_ERROR("CAM > DMA image capture timeout");
|
||||
error = 0x7;
|
||||
return 0;
|
||||
}
|
||||
if(dma_control.pdcmi_status == PDCMI_DMA_UNKNOWN_IRQ) {
|
||||
TRACE_ERROR("CAM > DMA unknown interrupt DMA I flags: %x",
|
||||
|
||||
case PDCMI_DMA_UNKNOWN_IRQ: {
|
||||
TRACE_ERROR("CAM > DMA unknown interrupt. DMA I flags: %x",
|
||||
dma_control.dma_flags);
|
||||
error = 0x8;
|
||||
return 0;
|
||||
}
|
||||
if(dma_control.pdcmi_status == PDCMI_DMA_COUNT_END) {
|
||||
TRACE_WARN("CAM > DMA count ended w/o VSYNC. DMA I flags: %x",
|
||||
|
||||
case PDCMI_DMA_COUNT_END: {
|
||||
TRACE_WARN("CAM > DMA count ended w/o VSYNC in SBM. DMA I flags: %x."
|
||||
" Image possibly useable.",
|
||||
dma_control.dma_flags);
|
||||
error = 0x9;
|
||||
return (dma_control.dma_count);
|
||||
return (dma_control.transfer_count);
|
||||
}
|
||||
|
||||
case PDCMI_NO_ERROR: {
|
||||
TRACE_INFO("CAM > Capture success");
|
||||
error = 0x0;
|
||||
return (dma_control.dma_count);
|
||||
}
|
||||
return (dma_control.transfer_count);
|
||||
}
|
||||
|
||||
default:
|
||||
TRACE_INFO("CAM > Unknown PDCMI state %d", dma_control->pdcmi_state);
|
||||
error = 0xA;
|
||||
return (dma_control.transfer_count);
|
||||
} /* End switch on PDCMI state. */
|
||||
} /* End OV5640_Capture(...) */
|
||||
|
||||
/**
|
||||
* Initializes GPIO for OV5640 pseudo DCMI
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@
|
|||
#define PDCMI_USE_DMA_DBM FALSE
|
||||
#endif
|
||||
|
||||
#define PDCMI_DMA_SEGMENT_SIZE 1024
|
||||
#define PDCMI_DMA_DBM_PAGE_SIZE 1024
|
||||
#define PDCMI_DMA_FIFO_BURST_ALIGN 16
|
||||
#define PDCMI_DMA_IRQ_PRIO 2
|
||||
|
||||
|
|
@ -43,18 +43,19 @@ typedef enum {
|
|||
PDCMI_DMA_END_BUFFER,
|
||||
PDCMI_DMA_COUNT_END,
|
||||
PDCMI_CAPTURE_TIMEOUT
|
||||
} pdcmi_err_code_t;
|
||||
} pdcmi_state_t;
|
||||
|
||||
typedef struct dmaControl {
|
||||
const stm32_dma_stream_t *dmastp;
|
||||
TIM_TypeDef *timer;
|
||||
uint8_t *segment_address;
|
||||
uint32_t page_size;
|
||||
uint8_t *page_address;
|
||||
uint8_t *base_buffer;
|
||||
uint16_t segment_count;
|
||||
uint16_t page_count;
|
||||
volatile bool terminate;
|
||||
uint32_t dma_flags;
|
||||
volatile pdcmi_err_code_t pdcmi_status;
|
||||
uint32_t dma_count;
|
||||
pdcmi_state_t pdcmi_state;
|
||||
uint32_t transfer_count;
|
||||
ioline_t vsync_line;
|
||||
} dma_capture_t;
|
||||
|
||||
|
|
|
|||
|
|
@ -1336,6 +1336,9 @@ void start_image_thread(img_app_conf_t *conf, const char *name)
|
|||
// Print startup error, do not start watchdog for this thread
|
||||
TRACE_ERROR("IMG > Could not startup thread"
|
||||
" (not enough memory available)");
|
||||
return;
|
||||
}
|
||||
TRACE_INFO("IMG > Image capture using DMA %s in thread %s",
|
||||
PDCMI_USE_DMA_DBM ? "DBM" : "SBM", name);
|
||||
}
|
||||
|
||||
|
|
|
|||
Ładowanie…
Reference in New Issue