drv_dcmi.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. /*
  2. * Copyright (c) 2006-2021, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2020-07-27 thread-liu the first version
  9. */
  10. #include "board.h"
  11. #if defined(BSP_USING_DCMI)
  12. #include "drv_dcmi.h"
  13. #define DRV_DEBUG
  14. #define LOG_TAG "drv.dcmi"
  15. #include <drv_log.h>
  16. struct stm32_dcmi
  17. {
  18. struct rt_device dev;
  19. };
  20. static struct stm32_dcmi rt_dcmi = {0};
  21. DCMI_HandleTypeDef dcmi = {0};
  22. DMA_HandleTypeDef hdma_dcmi = {0};
  23. extern void jpeg_data_process(void);
  24. static void rt_hw_dmci_dma_init(void)
  25. {
  26. __HAL_RCC_DMAMUX_CLK_ENABLE();
  27. __HAL_RCC_DMA1_CLK_ENABLE();
  28. hdma_dcmi.Instance = DMA1_Stream3;
  29. hdma_dcmi.Init.Request = DMA_REQUEST_DCMI;
  30. hdma_dcmi.Init.Direction = DMA_PERIPH_TO_MEMORY;
  31. hdma_dcmi.Init.PeriphInc = DMA_PINC_DISABLE;
  32. hdma_dcmi.Init.MemInc = DMA_MINC_ENABLE;
  33. hdma_dcmi.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
  34. hdma_dcmi.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
  35. hdma_dcmi.Init.Mode = DMA_CIRCULAR;
  36. hdma_dcmi.Init.Priority = DMA_PRIORITY_HIGH;
  37. hdma_dcmi.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
  38. hdma_dcmi.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
  39. hdma_dcmi.Init.MemBurst = DMA_MBURST_SINGLE;
  40. hdma_dcmi.Init.PeriphBurst = DMA_PBURST_SINGLE;
  41. HAL_DMA_Init(&hdma_dcmi);
  42. __HAL_LINKDMA(&dcmi, DMA_Handle, hdma_dcmi);
  43. HAL_NVIC_SetPriority(DMA1_Stream3_IRQn, 0x02, 0);
  44. HAL_NVIC_EnableIRQ(DMA1_Stream3_IRQn);
  45. }
  46. void rt_hw_dcmi_dma_config(rt_uint32_t dst_addr1, rt_uint32_t dst_addr2, rt_uint16_t len)
  47. {
  48. HAL_DMAEx_MultiBufferStart(&hdma_dcmi, (rt_uint32_t)&DCMI->DR, dst_addr1, dst_addr2, len);
  49. __HAL_DMA_ENABLE_IT(&hdma_dcmi, DMA_IT_TC);
  50. }
  51. static rt_err_t rt_hw_dcmi_init(DCMI_HandleTypeDef *device)
  52. {
  53. RT_ASSERT(device != RT_NULL);
  54. device->Instance = DCMI;
  55. device->Init.SynchroMode = DCMI_SYNCHRO_HARDWARE;
  56. device->Init.PCKPolarity = DCMI_PCKPOLARITY_RISING;
  57. device->Init.VSPolarity = DCMI_VSPOLARITY_LOW;
  58. device->Init.HSPolarity = DCMI_HSPOLARITY_LOW;
  59. device->Init.CaptureRate = DCMI_CR_ALL_FRAME;
  60. device->Init.ExtendedDataMode = DCMI_EXTEND_DATA_8B;
  61. device->Init.JPEGMode = DCMI_JPEG_DISABLE;
  62. device->Init.ByteSelectMode = DCMI_BSM_ALL;
  63. device->Init.ByteSelectStart = DCMI_OEBS_ODD;
  64. device->Init.LineSelectMode = DCMI_LSM_ALL;
  65. device->Init.LineSelectStart = DCMI_OELS_ODD;
  66. if (HAL_DCMI_Init(device) != HAL_OK)
  67. {
  68. LOG_E("dcmi init error!");
  69. return RT_ERROR;
  70. }
  71. DCMI->IER = 0x0;
  72. __HAL_DCMI_ENABLE_IT(device, DCMI_IT_FRAME);
  73. __HAL_DCMI_ENABLE(device);
  74. rt_hw_dmci_dma_init();
  75. return RT_EOK;
  76. }
  77. void DCMI_IRQHandler(void)
  78. {
  79. /* enter interrupt */
  80. rt_interrupt_enter();
  81. HAL_DCMI_IRQHandler(&dcmi);
  82. /* leave interrupt */
  83. rt_interrupt_leave();
  84. }
  85. /* Capture a frame of the image */
  86. void HAL_DCMI_FrameEventCallback(DCMI_HandleTypeDef *hdcmi)
  87. {
  88. /* enter interrupt */
  89. rt_interrupt_enter();
  90. jpeg_data_process();
  91. __HAL_DCMI_ENABLE_IT(&dcmi,DCMI_IT_FRAME);
  92. /* leave interrupt */
  93. rt_interrupt_leave();
  94. }
  95. void DMA1_Stream3_IRQHandler(void)
  96. {
  97. extern void rt_hw_camera_rx_callback(void);
  98. /* enter interrupt */
  99. rt_interrupt_enter();
  100. if(__HAL_DMA_GET_FLAG(&hdma_dcmi, DMA_FLAG_TCIF3_7)!=RESET)
  101. {
  102. __HAL_DMA_CLEAR_FLAG(&hdma_dcmi, DMA_FLAG_TCIF3_7);
  103. rt_hw_camera_rx_callback();
  104. }
  105. /* leave interrupt */
  106. rt_interrupt_leave();
  107. }
  108. static rt_err_t rt_dcmi_init(rt_device_t dev)
  109. {
  110. RT_ASSERT(dev != RT_NULL);
  111. rt_err_t result = RT_EOK;
  112. result = rt_hw_dcmi_init(&dcmi);
  113. if (result != RT_EOK)
  114. {
  115. return result;
  116. }
  117. return result;
  118. }
  119. static rt_err_t rt_dcmi_open(rt_device_t dev, rt_uint16_t oflag)
  120. {
  121. RT_ASSERT(dev != RT_NULL);
  122. return RT_EOK;
  123. }
  124. static rt_err_t rt_dcmi_close(rt_device_t dev)
  125. {
  126. RT_ASSERT(dev != RT_NULL);
  127. return RT_EOK;
  128. }
  129. static rt_err_t rt_dcmi_control(rt_device_t dev, int cmd, void *args)
  130. {
  131. RT_ASSERT(dev != RT_NULL);
  132. return RT_EOK;
  133. }
  134. static rt_size_t rt_dcmi_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
  135. {
  136. RT_ASSERT(dev != RT_NULL);
  137. return RT_EOK;
  138. }
  139. static rt_size_t rt_dcmi_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
  140. {
  141. RT_ASSERT(dev != RT_NULL);
  142. return RT_EOK;
  143. }
  144. int dcmi_init(void)
  145. {
  146. rt_dcmi.dev.type = RT_Device_Class_Miscellaneous;
  147. rt_dcmi.dev.init = rt_dcmi_init;
  148. rt_dcmi.dev.open = rt_dcmi_open;
  149. rt_dcmi.dev.close = rt_dcmi_close;
  150. rt_dcmi.dev.read = rt_dcmi_read;
  151. rt_dcmi.dev.write = rt_dcmi_write;
  152. rt_dcmi.dev.control = rt_dcmi_control;
  153. rt_dcmi.dev.user_data = RT_NULL;
  154. rt_device_register(&rt_dcmi.dev, "dcmi", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE);
  155. LOG_I("dcmi init success!");
  156. return RT_EOK;
  157. }
  158. INIT_BOARD_EXPORT(dcmi_init);
  159. #endif