1#include "stm32_adc_gpdma.hpp"
3#if defined(LIBXR_STM32_ADC_GPDMA) && defined(HAL_ADC_MODULE_ENABLED)
7#include "libxr_def.hpp"
8#include "stm32_dcache.hpp"
14 uint32_t* buffer, uint32_t sample_count,
17 ASSERT(adc_handle !=
nullptr);
18 ASSERT(adc_handle->DMA_Handle !=
nullptr);
19 ASSERT(buffer !=
nullptr);
20 ASSERT(sample_count > 0U);
21 ASSERT(sample_count <= std::numeric_limits<size_t>::max() /
sizeof(uint16_t));
22 ASSERT(buffer_size >=
static_cast<size_t>(sample_count) *
sizeof(uint16_t));
23 DMA_HandleTypeDef*
const dma_handle = adc_handle->DMA_Handle;
24 ASSERT(dma_handle->Parent == adc_handle);
25 ASSERT(IS_GPDMA_INSTANCE(dma_handle->Instance) != 0U);
26 ASSERT(dma_handle->Mode == DMA_LINKEDLIST_CIRCULAR);
27 ASSERT(dma_handle->InitLinkedList.LinkedListMode == DMA_LINKEDLIST_CIRCULAR);
28 ASSERT(dma_handle->InitLinkedList.LinkStepMode == DMA_LSM_FULL_EXECUTION);
29 ASSERT((dma_handle->Instance->CCR & DMA_CCR_LSM) == DMA_LSM_FULL_EXECUTION);
31 if (state_.original_queue ==
nullptr)
33 BuildAndAttach(adc_handle, buffer, sample_count, buffer_size);
37 DEV_ASSERT(dma_handle->LinkedListQueue == &state_.queue);
38 DEV_ASSERT(state_.queue.Head == &state_.node);
39 DEV_ASSERT(state_.queue.FirstCircularNode == &state_.node);
40 DEV_ASSERT(state_.queue.NodeNumber == 1U);
43 FinalizeStopped(dma_handle);
48 return HAL_ADC_Start_DMA(adc_handle, buffer, sample_count);
53 ASSERT(adc_handle !=
nullptr);
54 ASSERT(adc_handle->DMA_Handle !=
nullptr);
55 DMA_HandleTypeDef*
const dma_handle = adc_handle->DMA_Handle;
56 ASSERT(dma_handle->Parent == adc_handle);
58 const HAL_StatusTypeDef stop_status = HAL_ADC_Stop_DMA(adc_handle);
59 if (stop_status != HAL_OK)
64 if (state_.original_queue ==
nullptr)
69 FinalizeStopped(dma_handle);
70 DEV_ASSERT(dma_handle->LinkedListQueue == &state_.queue);
71 DEV_ASSERT(state_.queue.State == HAL_DMA_QUEUE_STATE_READY);
72 DMA_QListTypeDef*
const original_queue = state_.original_queue;
73 [[maybe_unused]]
const auto dma_ex_list_un_linkq_result =
74 HAL_DMAEx_List_UnLinkQ(dma_handle);
75 DEV_ASSERT(dma_ex_list_un_linkq_result == HAL_OK);
76 [[maybe_unused]]
const auto dma_ex_list_linkq_result =
77 HAL_DMAEx_List_LinkQ(dma_handle, original_queue);
78 DEV_ASSERT(dma_ex_list_linkq_result == HAL_OK);
79 DEV_ASSERT(dma_handle->LinkedListQueue == original_queue);
80 state_.original_queue =
nullptr;
84void STM32GpdmaAdcAdapter::FinalizeStopped(DMA_HandleTypeDef* dma_handle)
86 DEV_ASSERT(dma_handle->State == HAL_DMA_STATE_READY);
87 DEV_ASSERT(dma_handle->Lock == HAL_UNLOCKED);
88 DEV_ASSERT((dma_handle->Instance->CCR & DMA_CCR_EN) == 0U);
89 DEV_ASSERT(dma_handle->LinkedListQueue !=
nullptr);
90 DEV_ASSERT(dma_handle->LinkedListQueue->State == HAL_DMA_QUEUE_STATE_READY);
95 __HAL_DMA_DISABLE_IT(dma_handle, DMA_IT_TC | DMA_IT_HT | DMA_IT_DTE | DMA_IT_ULE |
96 DMA_IT_USE | DMA_IT_SUSP | DMA_IT_TO);
97 dma_handle->Instance->CBR1 = 0U;
98 __HAL_DMA_CLEAR_FLAG(dma_handle, DMA_FLAG_TC | DMA_FLAG_HT | DMA_FLAG_DTE |
99 DMA_FLAG_ULE | DMA_FLAG_USE | DMA_FLAG_SUSP |
104void STM32GpdmaAdcAdapter::BuildAndAttach(ADC_HandleTypeDef* adc_handle, uint32_t* buffer,
105 uint32_t sample_count,
size_t buffer_size)
107 DMA_HandleTypeDef*
const dma_handle = adc_handle->DMA_Handle;
108 ASSERT(dma_handle->State == HAL_DMA_STATE_READY);
109 ASSERT((dma_handle->Instance->CCR & DMA_CCR_EN) == 0U);
110 ASSERT(dma_handle->LinkedListQueue !=
nullptr);
111 ASSERT(dma_handle->LinkedListQueue->Head !=
nullptr);
112 ASSERT(dma_handle->LinkedListQueue->FirstCircularNode !=
nullptr);
113 ASSERT(dma_handle->LinkedListQueue->State == HAL_DMA_QUEUE_STATE_READY);
115 DMA_NodeConfTypeDef node_config{};
116 [[maybe_unused]]
const auto dma_ex_list_get_node_config_result =
117 HAL_DMAEx_List_GetNodeConfig(&node_config, dma_handle->LinkedListQueue->Head);
118 DEV_ASSERT(dma_ex_list_get_node_config_result == HAL_OK);
119 ASSERT(node_config.Init.Direction == DMA_PERIPH_TO_MEMORY);
120 ASSERT(node_config.Init.SrcInc == DMA_SINC_FIXED);
121 ASSERT(node_config.Init.DestInc == DMA_DINC_INCREMENTED);
122 ASSERT(node_config.Init.SrcDataWidth == DMA_SRC_DATAWIDTH_HALFWORD);
123 ASSERT(node_config.Init.DestDataWidth == DMA_DEST_DATAWIDTH_HALFWORD);
124 ASSERT(node_config.Init.SrcBurstLength == 1U);
125 ASSERT(node_config.Init.DestBurstLength == 1U);
126 ASSERT(node_config.Init.BlkHWRequest == DMA_BREQ_SINGLE_BURST);
127 ASSERT(node_config.Init.Mode == DMA_NORMAL);
128 ASSERT(node_config.TriggerConfig.TriggerPolarity == DMA_TRIG_POLARITY_MASKED);
129 ASSERT(node_config.DataHandlingConfig.DataExchange == DMA_EXCHANGE_NONE);
130 ASSERT(sample_count <= std::numeric_limits<uint32_t>::max() /
sizeof(uint16_t));
132 const uint32_t transfer_size = sample_count *
sizeof(uint16_t);
133 ASSERT(buffer_size >= transfer_size);
134 ASSERT(IS_DMA_BLOCK_SIZE(transfer_size) != 0U);
136 node_config.NodeType = DMA_GPDMA_LINEAR_NODE;
137 node_config.SrcAddress =
138 static_cast<uint32_t
>(
reinterpret_cast<uintptr_t
>(&adc_handle->Instance->DR));
139 node_config.DstAddress =
static_cast<uint32_t
>(
reinterpret_cast<uintptr_t
>(buffer));
140 node_config.DataSize = transfer_size;
142 DEV_ASSERT(state_.queue.Head ==
nullptr);
143 DEV_ASSERT(state_.queue.NodeNumber == 0U);
144 [[maybe_unused]]
const auto dma_ex_list_build_node_result =
145 HAL_DMAEx_List_BuildNode(&node_config, &state_.node);
146 DEV_ASSERT(dma_ex_list_build_node_result == HAL_OK);
147 [[maybe_unused]]
const auto dma_ex_list_insert_node_tail_result =
148 HAL_DMAEx_List_InsertNode_Tail(&state_.queue, &state_.node);
149 DEV_ASSERT(dma_ex_list_insert_node_tail_result == HAL_OK);
150 [[maybe_unused]]
const auto dma_ex_list_set_circular_mode_result =
151 HAL_DMAEx_List_SetCircularMode(&state_.queue);
152 DEV_ASSERT(dma_ex_list_set_circular_mode_result == HAL_OK);
153 DEV_ASSERT(state_.queue.Head == &state_.node);
154 DEV_ASSERT(state_.queue.FirstCircularNode == &state_.node);
155 DEV_ASSERT(state_.queue.NodeNumber == 1U);
156 DEV_ASSERT(state_.queue.State == HAL_DMA_QUEUE_STATE_READY);
158 state_.original_queue = dma_handle->LinkedListQueue;
159 [[maybe_unused]]
const auto dma_ex_list_un_linkq_result =
160 HAL_DMAEx_List_UnLinkQ(dma_handle);
161 DEV_ASSERT(dma_ex_list_un_linkq_result == HAL_OK);
162 [[maybe_unused]]
const auto dma_ex_list_linkq_result =
163 HAL_DMAEx_List_LinkQ(dma_handle, &state_.queue);
164 DEV_ASSERT(dma_ex_list_linkq_result == HAL_OK);
165 DEV_ASSERT(dma_handle->LinkedListQueue == &state_.queue);
HAL_StatusTypeDef Start(ADC_HandleTypeDef *adc_handle, uint32_t *buffer, uint32_t sample_count, size_t buffer_size)
挂接循环链表并启动 ADC DMA / Attach the circular list and start ADC DMA.
HAL_StatusTypeDef Stop(ADC_HandleTypeDef *adc_handle)
停止 ADC DMA 并恢复 BSP 链表 / Stop ADC DMA and restore the BSP list.
LibXR 命名空间 / LibXR namespace.
void STM32_InvalidateDCacheByAddr(const void *addr, size_t size)
失效指定内存范围覆盖的 D-Cache cache line Invalidates D-Cache lines covering the specified memory range
void STM32_CleanDCacheByAddr(const void *addr, size_t size)
清理指定内存范围覆盖的 D-Cache cache line Cleans D-Cache lines covering the specified memory range