1 /** 2 * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 * 15 * Description: Provides DMA driver api \n 16 * 17 * History: \n 18 * 2022-10-16, Create file. \n 19 */ 20 21 #ifndef DMA_H 22 #define DMA_H 23 24 #include <stdint.h> 25 #include "errcode.h" 26 27 #ifdef __cplusplus 28 #if __cplusplus 29 extern "C" { 30 #endif /* __cplusplus */ 31 #endif /* __cplusplus */ 32 33 /** 34 * @defgroup drivers_driver_dma DMA 35 * @ingroup drivers_driver 36 * @{ 37 */ 38 39 /** 40 * @if Eng 41 * @brief Memory-to-memory type of DMA channel user configuration. 42 * @else 43 * @brief 内存到内存类型的DMA通道用户配置。 44 * @endif 45 */ 46 typedef struct dma_ch_user_memory_config { 47 /** @if Eng The source address of this transfer. 48 * @else 传输源地址。 49 * @endif */ 50 uint32_t src; 51 /** @if Eng The destination address of this transfer. 52 * @else 传输目的地址。 53 * @endif */ 54 uint32_t dest; 55 /** @if Eng Transfer number. 56 * @else 传输数据量。 57 * @endif */ 58 uint16_t transfer_num; 59 /** @if Eng Transfer priority of channel(Lowest: 0 and Highest: 3). 60 * @else 传输通道优先级(最低为0以及最高为3)。 61 * @endif */ 62 uint8_t priority; 63 /** @if Eng Transfer data width: 64 * - 0: 1byte 65 * - 1: 2byte 66 * - 2: 4byte 67 * @else 传输数据宽度: 68 * - 0: 1字节 69 * - 1: 2字节 70 * - 2: 4字节 71 * @endif */ 72 uint8_t width; 73 } dma_ch_user_memory_config_t; 74 75 /** 76 * @if Eng 77 * @brief Memory-to-periph or periph-to-memory type of DMA channel user configuration. 78 * @else 79 * @brief 内存到外设或外设到内存类型的DMA通道用户配置。 80 * @endif 81 */ 82 typedef struct dma_ch_user_peripheral_config { 83 /** @if Eng The source address of this transfer. 84 * @else 传输源地址。 85 * @endif */ 86 uint32_t src; 87 /** @if Eng The destination address of this transfer. 88 * @else 传输目的地址。 89 * @endif */ 90 uint32_t dest; 91 /** @if Eng Transfer number. 92 * @else 传输数据量。 93 * @endif */ 94 uint16_t transfer_num; 95 /** @if Eng Hardware handshaking ID of the source. see @ref hal_dma_handshaking_source_t. 96 * @else 源端硬件握手号。 参考 @ref hal_dma_handshaking_source_t 。 97 * @endif */ 98 uint16_t src_handshaking; 99 /** @if Eng Hardware handshaking ID of the destination. see @ref hal_dma_handshaking_source_t. 100 * @else 目的端硬件握手号。 参考 @ref hal_dma_handshaking_source_t 。 101 * @endif */ 102 uint16_t dest_handshaking; 103 /** @if Eng Transfer type: 104 * - 0: memory to memory and DMA is flow controller 105 * - 1: memory to periph and DMA is flow controller 106 * - 2: periph to memory and DMA is flow controller 107 * - 3: periph to periph and DMA is flow controller 108 * - 4: periph to memory and periph is flow controller 109 * - 5: periph to periph and source periph is flow controller 110 * - 6: memory to periph and periph is flow controller 111 * - 7: periph to periph and destination periph is flow controller 112 * @else 传输类型: 113 * - 0: 内存到内存并且由DMA流控 114 * - 1: 内存到外设并且由DMA流控 115 * - 2: 外设到内存并且由DMA流控 116 * - 3: 外设到外设并且由DMA流控 117 * - 4: 外设到内存并且由外设流控 118 * - 5: 外设到外设并且由源端外设流控 119 * - 6: 内存到外设并且由外设流控 120 * - 7: 外设到外设并且由目的端外设流控 121 * @endif */ 122 uint8_t trans_type; 123 /** @if Eng Transfer direction: 124 * - 0: memory to periph 125 * - 1: periph to memory 126 * - 2: periph to periph 127 * @else 传输方向: 128 * - 0: 内存到外设 129 * - 1: 外设到内存 130 * - 2: 外设到外设 131 * @endif */ 132 uint8_t trans_dir; 133 /** @if Eng Transfer priority of channel(Lowest: 0 and Highest: 3). 134 * @else 传输通道优先级(最低为0以及最高为3)。 135 * @endif */ 136 uint8_t priority; 137 /** @if Eng Transfer data width of the source: 138 * - 0: 1byte 139 * - 1: 2byte 140 * - 2: 4byte 141 * @else 源端传输数据宽度: 142 * - 0: 1字节 143 * - 1: 2字节 144 * - 2: 4字节 145 * @endif */ 146 uint8_t src_width; 147 /** @if Eng Transfer data width of the destination: 148 * - 0: 1byte 149 * - 1: 2byte 150 * - 2: 4byte 151 * @else 目的端传输数据宽度: 152 * - 0: 1字节 153 * - 1: 2字节 154 * - 2: 4字节 155 * @endif */ 156 uint8_t dest_width; 157 /** @if Eng Transfer burst length: 158 * - 0: burst length is 1 159 * - 1: burst length is 4 160 * - 2: burst length is 8 161 * - 3: burst length is 16 162 * @else 传输burst长度: 163 * - 0: burst长度是1 164 * - 1: burst长度是4 165 * - 2: burst长度是8 166 * - 3: burst长度是16 167 * @endif */ 168 uint8_t burst_length; 169 /** @if Eng Source address incremental mode: 170 * - 0: increment 171 * - 1: decrement 172 * - 2: no change 173 * @else 源端地址增量模式: 174 * - 0: 递增 175 * - 1: 递减 176 * - 2: 不变 177 * @endif */ 178 uint8_t src_increment; 179 /** @if Eng Destination address incremental mode: 180 * - 0: increment 181 * - 1: decrement 182 * - 2: no change 183 * @else 目的端地址增量模式: 184 * - 0: 递增 185 * - 1: 递减 186 * - 2: 不变 187 * @endif */ 188 uint8_t dest_increment; 189 /** @if Eng DMA protection control bits used to drive the AHB HPROT[3:1] bus: 190 * - 0: HPROT[1] 191 * - 1: HPROT[2] 192 * - 2: HPROT[3] 193 * @else 保护控制位,用于驱动AHB HPRO[3:1]总线: 194 * - 0: HPROT[1] 195 * - 1: HPROT[2] 196 * - 2: HPROT[3] 197 * @endif */ 198 uint8_t protection; 199 } dma_ch_user_peripheral_config_t; 200 201 /** 202 * @if Eng 203 * @brief Pointer to the DMA channel transfer done/error callback function. 204 * @param [in] intr DMA interrupt type. 205 * @param [in] channel DMA channel. 206 * @param [in] arg DMA private param pointer passed by DMA caller. 207 * @else 208 * @brief DMA通道传输完成/错误所触发的回调函数指针。 209 * @param [in] intr DMA中断类型。 210 * @param [in] channel DMA通道。 211 * @param [in] arg 调用DMA传输时传递的私有参数指针。 212 * @endif 213 */ 214 typedef void (*dma_transfer_cb_t)(uint8_t intr, uint8_t channel, uintptr_t arg); 215 216 /** 217 * @if Eng 218 * @brief Initialize the DMA module. 219 * @retval ERRCODE_SUCC Success. 220 * @retval Other Failure. For details, see @ref errcode_t. 221 * @else 222 * @brief 初始化DMA模块。 223 * @retval ERRCODE_SUCC 成功。 224 * @retval Other 失败 参考 @ref errcode_t 。 225 * @endif 226 */ 227 errcode_t uapi_dma_init(void); 228 229 /** 230 * @if Eng 231 * @brief Deinitialize the DMA module. 232 * @else 233 * @brief 去初始化DMA模块。 234 * @endif 235 */ 236 void uapi_dma_deinit(void); 237 238 /** 239 * @if Eng 240 * @brief Open the DMA module. 241 * @retval ERRCODE_SUCC Success. 242 * @retval Other Failure. For details, see @ref errcode_t. 243 * @else 244 * @brief 开启DMA模块。 245 * @retval ERRCODE_SUCC 成功。 246 * @retval Other 失败 参考 @ref errcode_t 。 247 * @endif 248 */ 249 errcode_t uapi_dma_open(void); 250 251 /** 252 * @if Eng 253 * @brief Close the DMA module. 254 * @else 255 * @brief 关闭DMA模块。 256 * @endif 257 */ 258 void uapi_dma_close(void); 259 260 /** 261 * @if Eng 262 * @brief Start DMA transfer of specific Channel. 263 * @param [in] channel DMA channel. 264 * @retval ERRCODE_SUCC Success. 265 * @retval Other Failure. For details, see @ref errcode_t. 266 * @else 267 * @brief 启动指定通道的DMA传输。 268 * @param [in] channel DMA通道。 269 * @retval ERRCODE_SUCC 成功。 270 * @retval Other 失败 参考 @ref errcode_t 。 271 * @endif 272 */ 273 errcode_t uapi_dma_start_transfer(uint8_t channel); 274 275 /** 276 * @if Eng 277 * @brief Stop DMA transfer of specific Channel. 278 * @param [in] channel DMA channel. 279 * @retval ERRCODE_SUCC Success. 280 * @retval Other Failure. For details, see @ref errcode_t. 281 * @else 282 * @brief 停止指定通道的DMA传输。 283 * @param [in] channel DMA通道。 284 * @retval ERRCODE_SUCC 成功。 285 * @retval Other 失败 参考 @ref errcode_t 。 286 * @endif 287 */ 288 errcode_t uapi_dma_end_transfer(uint8_t channel); 289 290 /** 291 * @if Eng 292 * @brief Get the number of data transferred by the DMA. 293 * @param [in] channel DMA channel. 294 * @retval The number of data transferred by the DMA. 295 * @else 296 * @brief 获取DMA传输的数据量。 297 * @param [in] channel DMA通道。 298 * @retval 获取DMA传输的数据量。 299 * @endif 300 */ 301 uint32_t uapi_dma_get_block_ts(uint8_t channel); 302 303 /** 304 * @if Eng 305 * @brief Transfer type memory-to-memory through DMA channel. 306 * @param [in] user_cfg DMA channel transfer configuration of user. For details, see @ref dma_ch_user_memory_config_t. 307 * @param [in] callback Channel transfer done/error callback function. For details, see @ref dma_transfer_cb_t. 308 * @param [in] arg Private param pointer for storing self information, which can be passed to DMA callback 309 * @ref dma_transfer_cb_t when transfer completed. 310 * @retval ERRCODE_SUCC Success. 311 * @retval Other Failure. For details, see @ref errcode_t. 312 * @else 313 * @brief 通过DMA通道传输类型为内存到内存的数据。 314 * @param [in] user_cfg 用户的DMA通道传输配置 For details, see @ref dma_ch_user_memory_config_t 。 315 * @param [in] callback 通道传输完成/错误回调函数 For details, see @ref dma_transfer_cb_t 。 316 * @param [in] arg 用于存储自定义信息的私有参数指针,传输完成时回传给dma回调函数 @ref dma_transfer_cb_t 。 317 * @retval ERRCODE_SUCC 成功。 318 * @retval Other 失败 参考 @ref errcode_t 。 319 * @endif 320 */ 321 errcode_t uapi_dma_transfer_memory_single(const dma_ch_user_memory_config_t *user_cfg, 322 dma_transfer_cb_t callback, uintptr_t arg); 323 324 /** 325 * @if Eng 326 * @brief Transfer type memory-periph or periph-memory through DMA channel. 327 * @param [in] user_cfg DMA channel transfer configuration of user. 328 * For details, see @ref dma_ch_user_peripheral_config_t. 329 * @param [out] channel DMA channel selected. 330 * @param [in] callback Channel transfer done/error callback function. For details, see @ref dma_transfer_cb_t. 331 * @param [in] arg Private param pointer for storing self information, which can be passed to DMA callback 332 * @ref dma_transfer_cb_t when transfer completed. 333 * @retval ERRCODE_SUCC Success. 334 * @retval Other Failure. For details, see @ref errcode_t. 335 * @else 336 * @brief 通过DMA通道传输类型为内存到外设或外设到内存的数据。 337 * @param [in] user_cfg 用户的DMA通道传输配置 For details, see @ref dma_ch_user_peripheral_config_t 。 338 * @param [out] channel 获取被选择的通道。 339 * @param [in] callback 通道传输完成/错误回调函数 For details, see @ref dma_transfer_cb_t 。 340 * @param [in] arg 用于存储自定义信息的私有参数指针,传输完成时回传给DMA回调函数 @ref dma_transfer_cb_t 。 341 * @retval ERRCODE_SUCC 成功。 342 * @retval Other 失败 参考 @ref errcode_t 。 343 * @endif 344 */ 345 errcode_t uapi_dma_configure_peripheral_transfer_single(const dma_ch_user_peripheral_config_t *user_cfg, 346 uint8_t *channel, dma_transfer_cb_t callback, uintptr_t arg); 347 348 #if defined(CONFIG_DMA_SUPPORT_LLI) 349 /** 350 * @if Eng 351 * @brief Get DMA linked list channel. 352 * @param [in] burst_length Dma burst transfer length. 353 * @param [in] handshaking Dma Transfer periph. 354 * @retval ERRCODE_SUCC Success. 355 * @retval The DMA channel. 356 * @else 357 * @brief 获取DMA链表传输通道。 358 * @param [in] burst_length DMA的burst传输长度。 359 * @param [in] handshaking DMA传输外设种类。 360 * @retval DMA通道 361 * @endif 362 */ 363 uint8_t uapi_dma_get_lli_channel(uint8_t burst_length, uint8_t handshaking); 364 365 /** 366 * @if Eng 367 * @brief Transfer type memory-to-memory in linked list mode through DMA channel. 368 * @param [in] channel DMA channel. 369 * @param [in] user_cfg DMA channel transfer configuration of user. For details, see @ref dma_ch_user_memory_config_t. 370 * @param [in] callback Channel transfer done/error callback function. For details, see @ref dma_transfer_cb_t. 371 * @retval ERRCODE_SUCC Success. 372 * @retval Other Failure. For details, see @ref errcode_t. 373 * @else 374 * @brief 通过DMA通道以链表模式传输类型为内存到内存的数据。 375 * @param [in] channel DMA通道。 376 * @param [in] user_cfg 用户的DMA通道传输配置 For details, see @ref dma_ch_user_memory_config_t 。 377 * @param [in] callback 通道传输完成/错误回调函数 For details, see @ref dma_transfer_cb_t 。 378 * @retval ERRCODE_SUCC 成功。 379 * @retval Other 失败 参考 @ref errcode_t 。 380 * @endif 381 */ 382 errcode_t uapi_dma_transfer_memory_lli(uint8_t channel, const dma_ch_user_memory_config_t *user_cfg, 383 dma_transfer_cb_t callback); 384 385 /** 386 * @if Eng 387 * @brief Transfer type memory-periph or periph-memory in linked list mode through DMA channel. 388 * @param [in] channel DMA channel. 389 * @param [in] user_cfg DMA channel transfer configuration of user. 390 * For details, see @ref dma_ch_user_peripheral_config_t. 391 * @param [in] callback Channel transfer done/error callback function. For details, see @ref dma_transfer_cb_t. 392 * @retval ERRCODE_SUCC Success. 393 * @retval Other Failure. For details, see @ref errcode_t. 394 * @else 395 * @brief 通过DMA通道以链表模式传输类型为内存到外设或外设到内存的数据。 396 * @param [in] channel DMA通道。 397 * @param [in] user_cfg 用户的DMA通道传输配置 For details, see @ref dma_ch_user_peripheral_config_t 。 398 * @param [in] callback 通道传输完成/错误回调函数 For details, see @ref dma_transfer_cb_t 。 399 * @retval ERRCODE_SUCC 成功。 400 * @retval Other 失败 参考 @ref errcode_t 。 401 * @endif 402 */ 403 errcode_t uapi_dma_configure_peripheral_transfer_lli(uint8_t channel, const dma_ch_user_peripheral_config_t *user_cfg, 404 dma_transfer_cb_t callback); 405 406 /** 407 * @if Eng 408 * @brief Enable DMA linked list transfer. 409 * @param [in] channel DMA channel. 410 * @param [in] callback Channel transfer done/error callback function. For details, see @ref dma_transfer_cb_t. 411 * @param [in] arg Private param pointer for storing self information, which can be passed to DMA callback 412 * @ref dma_transfer_cb_t when transfer completed. 413 * @retval ERRCODE_SUCC Success. 414 * @retval Other Failure. For details, see @ref errcode_t. 415 * @else 416 * @brief 启用DMA链表传输。 417 * @param [in] channel DMA通道。 418 * @param [in] callback 通道传输完成/错误回调函数 For details, see @ref dma_transfer_cb_t 。 419 * @param [in] arg 用于存储自定义信息的私有参数指针,传输完成时回传给dma回调函数 @ref dma_transfer_cb_t 。 420 * @retval ERRCODE_SUCC 成功。 421 * @retval Other 失败 参考 @ref errcode_t 。 422 * @endif 423 */ 424 errcode_t uapi_dma_enable_lli(uint8_t channel, dma_transfer_cb_t callback, uintptr_t arg); 425 #endif /* CONFIG_DMA_SUPPORT_LLI */ 426 427 #ifdef CONFIG_DMA_SUPPORT_LPM 428 /** 429 * @if Eng 430 * @brief Resume the DMA module. 431 * @param [in] arg Argument for resume. 432 * @retval ERRCODE_SUCC Success. 433 * @retval Other Failure. For details, see @ref errcode_t. 434 * @else 435 * @brief 恢复DMA模块。 436 * @retval ERRCODE_SUCC 成功。 437 * @retval Other 失败 参考 @ref errcode_t 438 * @endif 439 */ 440 errcode_t uapi_dma_resume(uintptr_t arg); 441 442 /** 443 * @if Eng 444 * @brief suspend the DMA module. 445 * @param [in] arg Argument for suspend. 446 * @retval ERRCODE_SUCC Success. 447 * @retval Other Failure. For details, see @ref errcode_t 448 * @else 449 * @brief 挂起DMA模块。 450 * @retval ERRCODE_SUCC 成功。 451 * @retval Other 失败,参考 @ref errcode_t 。 452 * @endif 453 */ 454 errcode_t uapi_dma_suspend(uintptr_t arg); 455 #endif 456 /** 457 * @} 458 */ 459 460 #ifdef __cplusplus 461 #if __cplusplus 462 } 463 #endif /* __cplusplus */ 464 #endif /* __cplusplus */ 465 466 #endif 467