12 #include "stm32/stm32f4xx_misc.h"
15 #define MAX_RETRY_COUNT 5
21 uint32_t current_base;
22 uint32_t current_size;
23 uint32_t current_element_size;
25 void *(*next_handler)(
const struct camera_t *cam);
31 uint32_t one_shot_running;
37 static void xfer_update(
volatile struct dma_xfer_t *xfer)
39 xfer->current_base += xfer->current_element_size;
40 xfer->current_size -= xfer->current_element_size;
45 uint32_t target = DMA_GetCurrentMemoryTarget(DMA2_Stream1);
50 target = DMA_Memory_1;
53 target = DMA_Memory_0;
60 DMA_MemoryTargetConfig(DMA2_Stream1, xfer->current_base, target);
67 static uint32_t xfer_size(uint32_t size)
69 while (size > UINT16_MAX)
79 const struct camera_t *cam = xfer->cam;
81 xfer->current_base = (uint32_t)xfer->buffer_base;
83 if (xfer->current_size > xfer->buffer_size)
87 xfer->current_element_size = xfer_size(xfer->current_size);
97 DMA_DeInit(DMA2_Stream1);
98 DMA_ITConfig(DMA2_Stream1, DMA_IT_HT | DMA_IT_TC | DMA_IT_TE | DMA_IT_FE, ENABLE);
99 status = xfer_setup(xfer);
108 config.
DMA_DIR = DMA_DIR_PeripheralToMemory;
121 if (xfer->current_size > UINT16_MAX)
123 config.
DMA_Mode = DMA_Mode_Circular;
127 DMA_Init(DMA2_Stream1, &config);
131 if (xfer->current_size > UINT16_MAX)
133 DMA_DoubleBufferModeConfig(DMA2_Stream1, xfer->current_base, DMA_Memory_0);
134 DMA_DoubleBufferModeCmd(DMA2_Stream1, ENABLE);
137 DMA_Cmd(DMA2_Stream1, ENABLE);
150 if (DMA_GetFlagStatus(DMA2_Stream1, DMA_FLAG_FEIF1) != RESET)
158 DMA_ClearFlag(DMA2_Stream1, DMA_FLAG_FEIF1);
162 if (DMA_GetFlagStatus(DMA2_Stream1, DMA_FLAG_TEIF1) != RESET)
167 DMA_ITConfig(DMA2_Stream1, DMA_IT_TC | DMA_IT_HT | DMA_IT_TE | DMA_IT_FE, DISABLE);
169 if (xfer.dma_error > MAX_RETRY_COUNT || xfer.one_shot_running)
175 xfer.one_shot_running = 0;
178 DMA_ClearFlag(DMA2_Stream1, DMA_FLAG_TEIF1 | DMA_FLAG_DMEIF1);
182 if (DMA_GetFlagStatus(DMA2_Stream1, DMA_FLAG_HTIF1) != RESET)
186 if (xfer.current_size)
193 xfer.buffer_base = NULL;
194 if (xfer.next_handler != NULL)
196 xfer.buffer_base = xfer.next_handler(xfer.cam);
199 if (!(xfer.buffer_base == NULL))
208 DMA_ClearFlag(DMA2_Stream1, DMA_FLAG_HTIF1);
212 if (DMA_GetFlagStatus(DMA2_Stream1, DMA_FLAG_TCIF1) != RESET)
220 if (xfer.done_handler)
222 xfer.done_handler(
NO_ERROR, xfer.cam);
224 xfer.one_shot_running = 0;
226 if (!xfer.continuous)
228 DMA_Cmd(DMA2_Stream1, DISABLE);
234 DMA_ClearFlag(DMA2_Stream1, DMA_FLAG_TCIF1);
238 static void Camera_DCMI_IRQ_Handler(
void)
240 uint32_t misr = DCMI->MISR;
246 if (misr & DCMI_MISR_OVF_MIS)
253 if ((uint32_t)xfer.buffer_base+xfer.current_element_size != xfer.current_base)
262 if (xfer.restart == 1)
266 else if (xfer.restart == 2)
290 if (cam->mco_frequency != 0)
303 RCC_MCO1Config(RCC_MCO1Source_HSI, RCC_MCO1Div_2);
307 RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_DCMI, ENABLE);
308 RCC_AHB2PeriphResetCmd(RCC_AHB2Periph_DCMI, ENABLE);
309 RCC_AHB2PeriphResetCmd(RCC_AHB2Periph_DCMI, DISABLE);
311 DCMI->CR &= ~((uint32_t)DCMI_CR_CM | DCMI_CR_ESS | DCMI_CR_PCKPOL |
312 DCMI_CR_HSPOL | DCMI_CR_VSPOL | DCMI_CR_FCRC_0 |
313 DCMI_CR_FCRC_1 | DCMI_CR_EDM_0 | DCMI_CR_EDM_1);
315 DCMI->CR = DCMI_CR_ENABLE;
319 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
329 NVIC_Init(&NVIC_InitStructure);
336 NVIC_InitStructure.NVIC_Handler = Camera_DCMI_IRQ_Handler;
337 NVIC_Init(&NVIC_InitStructure);
339 return cam->funcs->init(cam);
345 uint32_t continuous_was = xfer.continuous;
346 void *(*next_was)(
const struct camera_t *cam) = xfer.next_handler;
347 void (*done_was)(
status_e status,
const struct camera_t *cam) = xfer.done_handler;
355 *cam->image_options = *new_options;
356 if (cam->funcs->setup)
358 status = cam->funcs->setup(cam);
378 DCMI->IER &= ~DCMI_IER_FRAME_IE;
381 while (! (DCMI->RISR & DCMI_RISR_FRAME_RIS))
389 DCMI->ICR = DCMI_ICR_FRAME_ISC;
391 DCMI->CR &= ~DCMI_CR_CAPTURE;
394 xfer.next_handler = NULL;
395 xfer.done_handler = NULL;
397 if (cam->funcs->pause)
399 status = cam->funcs->pause(cam);
413 if (!next_handler || !done_handler)
418 if (cam->funcs->start)
420 status = cam->funcs->start(cam, 0);
427 memset(&xfer, 0x0,
sizeof(xfer));
431 xfer.next_handler = next_handler;
432 xfer.done_handler = done_handler;
433 xfer.buffer_base = next_handler(cam);
434 xfer.buffer_size = size;
435 status = xfer_start(&xfer);
441 DCMI->CR &= ~DCMI_CR_CM;
442 DCMI->CR |= DCMI_CR_CAPTURE;
443 DCMI->IER = DCMI_IER_FRAME_IE | DCMI_IER_OVF_IE;
449 static void default_done_handler(
status_e status,
const struct camera_t *cam)
452 xfer.one_shot_status = status;
461 while (xfer.one_shot_running)
469 return xfer.one_shot_status;
476 if (xfer.one_shot_running)
481 return xfer.one_shot_status;
489 if (cam->funcs->start)
491 status = cam->funcs->start(cam, 0);
498 memset(&xfer, 0x0,
sizeof(xfer));
501 xfer.one_shot_running = 1;
502 xfer.next_handler = NULL;
505 done_handler = default_done_handler;
507 xfer.done_handler = done_handler;
508 xfer.buffer_base = dst;
509 xfer.buffer_size = size;
510 status = xfer_start(&xfer);
516 DCMI->CR |= DCMI_CR_CM;
517 DCMI->CR |= DCMI_CR_CAPTURE;
518 DCMI->IER = DCMI_IER_FRAME_IE | DCMI_IER_OVF_IE;
523 static uint32_t noverify_camera_get_image_size(
const struct camera_t *cam)
525 switch (cam->image_options->format)
527 case IMAGE_FORMAT_RGB565:
528 return cam->image_options->xres * cam->image_options->yres * 2;
538 uint32_t size = noverify_camera_get_image_size(cam);
This file contains all the functions prototypes for the RCC firmware library.
void(* done)(const void *)
Handler called at the end of Audio_DMA_Play.
status_e camera_continuous_start(const struct camera_t *cam, void *(*next_handler)(const struct camera_t *), void(*done_handler)(status_e status, const struct camera_t *), size_t size)
Start continuous capture of camera images.
DMA Init structure definition.
status_e camera_one_shot_status(const struct camera_t *cam)
Camera wait one shot status.
Camera interface for stm32 processors.
void * memset(void *dest, int n, size_t n)
uint32_t DMA_MemoryDataSize
status_e camera_one_shot_wait(const struct camera_t *cam)
Camera wait one shot finished.
uint8_t NVIC_IRQChannelSubPriority
status_e camera_one_shot_start(const struct camera_t *cam, void(*done_handler)(status_e, const struct camera_t *), void *dst, size_t size)
Camera take one shot.
uint32_t DMA_PeripheralInc
NVIC Init Structure definition.
static uint32_t time_elapsed(timeout_t timeout)
Is this time passed?
Function called at bad time.
uint32_t DMA_PeripheralDataSize
uint32_t DMA_PeripheralBurst
status_e camera_init(const struct camera_t *cam)
Initialize camera.
This file contains all the functions prototypes for the DMA firmware library.
uint32_t DMA_PeripheralBaseAddr
uint32_t DMA_Memory0BaseAddr
uint32_t DMA_FIFOThreshold
FunctionalState NVIC_IRQChannelCmd
This file contains all the functions prototypes for the DCMI firmware library.
status_e camera_continuous_stop(const struct camera_t *cam)
Camera stop continous capture.
uint8_t NVIC_IRQChannelPreemptionPriority
status_e camera_setup(const struct camera_t *cam, const struct camera_image_options_t *new_options)
Camera setup.
static void Camera_DMA_IRQ_Handler(void)
This function handles DMA2_Stream1 interrupt.
timeout_t time_set_timeout_ms(uint32_t ms)
Set an obscure time at least ms milliseconds in the future.
uint32_t camera_get_image_size(const struct camera_t *cam)
Compute image byte size using current parameters.
status_e gpio_setup_list(const struct gpio_t gpio[], size_t len)
Setup an array of gpio.
status_e gpio_setup(const struct gpio_t *gpio)
Setup a gpio.
Description of a DMA transfer.