mirror of
https://github.com/openmv/openmv.git
synced 2025-09-26 23:09:13 +08:00
169 lines
6.2 KiB
C
169 lines
6.2 KiB
C
/* Copyright (C) 2023 Alif Semiconductor - All Rights Reserved.
|
|
* Use, distribution and modification of this code is permitted under the
|
|
* terms stated in the Alif Semiconductor Software License Agreement
|
|
*
|
|
* You should have received a copy of the Alif Semiconductor Software
|
|
* License Agreement with this file. If not, please write to:
|
|
* contact@alifsemi.com, or visit: https://alifsemi.com/license
|
|
*
|
|
*/
|
|
|
|
/**************************************************************************//**
|
|
* @file dma_ctrl.c
|
|
* @author Sudhir Sreedharan
|
|
* @email sudhir@alifsemi.com
|
|
* @version V1.0.0
|
|
* @date 28-Sep-2023
|
|
* @brief DMA control driver
|
|
* @bug None
|
|
* @Note None
|
|
******************************************************************************/
|
|
|
|
/* Includes ------------------------------------------------------------------*/
|
|
#include <dma_ctrl.h>
|
|
|
|
/**
|
|
\fn int8_t dma_allocate_channel(dma_config_info_t *dma_cfg)
|
|
\brief Allocate a channel if available
|
|
\param[in] dma_cfg Pointer to DMA Configuration resources
|
|
\return int8_t channel number or -1 if not available
|
|
*/
|
|
int8_t dma_allocate_channel(dma_config_info_t *dma_cfg)
|
|
{
|
|
dma_thread_info_t *channel_thread = &dma_cfg->channel_thread[0];
|
|
dma_channel_info_t *channel_info;
|
|
uint8_t channel_num;
|
|
|
|
for(channel_num = 0; channel_num < DMA_MAX_CHANNELS; channel_num++)
|
|
{
|
|
if(channel_thread[channel_num].in_use == false)
|
|
{
|
|
channel_thread[channel_num].in_use = true;
|
|
channel_thread[channel_num].user_mcode = (void *)0;
|
|
|
|
channel_info = &channel_thread[channel_num].channel_info;
|
|
channel_info->flags = 0;
|
|
|
|
return (int8_t)channel_num;
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
/**
|
|
\fn int8_t dma_allocate_event(dma_config_info_t *dma_cfg,
|
|
uint8_t channel_num)
|
|
\brief Allocate a event if available
|
|
\param[in] dma_cfg Pointer to DMA Configuration resources
|
|
\param[in] channel_num Channel Number
|
|
\return int8_t Event index number or -1 if not available
|
|
*/
|
|
int8_t dma_allocate_event(dma_config_info_t *dma_cfg, uint8_t channel_num)
|
|
{
|
|
dma_thread_info_t *thread_info = &dma_cfg->channel_thread[channel_num];
|
|
dma_channel_info_t *channel_info = &thread_info->channel_info;
|
|
uint8_t event_index;
|
|
|
|
for(event_index = 0; event_index < DMA_MAX_EVENTS; event_index++)
|
|
{
|
|
if(dma_cfg->event_map[event_index] == 0xFF)
|
|
{
|
|
dma_cfg->event_map[event_index] = channel_num;
|
|
channel_info->event_index = event_index;
|
|
return (int8_t)event_index;
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
/**
|
|
\fn void dma_copy_desc_info(dma_config_info_t *dma_cfg,
|
|
uint8_t channel_num,
|
|
dma_desc_info_t *desc_info)
|
|
\brief Update the channel descriptor Structure
|
|
\param[in] dma_cfg Pointer to DMA Configuration resources
|
|
\param[in] channel_num Channel Number
|
|
\param[in] desc_info Descriptor Information
|
|
\return None
|
|
*/
|
|
void dma_copy_desc_info(dma_config_info_t *dma_cfg,
|
|
uint8_t channel_num,
|
|
dma_desc_info_t *desc_info)
|
|
{
|
|
dma_thread_info_t *thread_info = &dma_cfg->channel_thread[channel_num];
|
|
dma_channel_info_t *channel_info = &thread_info->channel_info;
|
|
dma_desc_info_t *channel_desc_info = &channel_info->desc_info;
|
|
|
|
channel_desc_info->direction = desc_info->direction;
|
|
channel_desc_info->total_len = desc_info->total_len;
|
|
channel_desc_info->src_addr = desc_info->src_addr;
|
|
channel_desc_info->dst_addr0 = desc_info->dst_addr0;
|
|
channel_desc_info->src_bsize = desc_info->src_bsize;
|
|
channel_desc_info->dst_bsize = desc_info->dst_bsize;
|
|
channel_desc_info->src_blen = desc_info->src_blen;
|
|
channel_desc_info->dst_blen = desc_info->dst_blen;
|
|
channel_desc_info->periph_num = desc_info->periph_num;
|
|
|
|
if(channel_desc_info->direction == DMA_TRANSFER_MEM_TO_DEV)
|
|
{
|
|
channel_desc_info->dst_cache_ctrl = 0x0;
|
|
}
|
|
else if(channel_desc_info->direction == DMA_TRANSFER_DEV_TO_MEM)
|
|
{
|
|
channel_desc_info->src_cache_ctrl = 0x0;
|
|
}
|
|
}
|
|
|
|
/**
|
|
\fn dma_ccr_t dma_get_channel_ctrl_info(dma_config_info_t *dma_cfg,
|
|
uint8_t channel_num)
|
|
\brief Return the Channel Control Info from Descriptor info
|
|
\param[in] dma_cfg Pointer to DMA Configuration resources
|
|
\param[in] channel_num Channel Number
|
|
\return dma_ccr_t channel Control Info (CCR)
|
|
*/
|
|
dma_ccr_t dma_get_channel_ctrl_info(dma_config_info_t *dma_cfg,
|
|
uint8_t channel_num)
|
|
{
|
|
dma_thread_info_t *thread_info = &dma_cfg->channel_thread[channel_num];
|
|
dma_channel_info_t *channel_info = &thread_info->channel_info;
|
|
dma_desc_info_t *channel_desc_info = &channel_info->desc_info;
|
|
dma_ccr_t dma_ccr;
|
|
|
|
dma_ccr.value = 0;
|
|
|
|
dma_ccr.value_b.dst_burst_len = channel_desc_info->dst_blen - 1;
|
|
dma_ccr.value_b.src_burst_len = channel_desc_info->src_blen - 1;
|
|
|
|
dma_ccr.value_b.dst_burst_size = channel_desc_info->dst_bsize;
|
|
dma_ccr.value_b.src_burst_size = channel_desc_info->src_bsize;
|
|
|
|
dma_ccr.value_b.dst_cache_ctrl = channel_desc_info->dst_cache_ctrl;
|
|
dma_ccr.value_b.src_cache_ctrl = channel_desc_info->src_cache_ctrl;
|
|
|
|
dma_ccr.value_b.dst_prot_ctrl = channel_desc_info->dst_prot_ctrl;
|
|
dma_ccr.value_b.src_prot_ctrl = channel_desc_info->src_prot_ctrl;
|
|
|
|
dma_ccr.value_b.endian_swap_size = channel_desc_info->endian_swap_size;
|
|
|
|
if(channel_desc_info->direction == DMA_TRANSFER_MEM_TO_DEV)
|
|
{
|
|
dma_ccr.value_b.dst_inc = DMA_BURST_FIXED;
|
|
dma_ccr.value_b.src_inc = DMA_BURST_INCREMENTING;
|
|
}
|
|
else if(channel_desc_info->direction == DMA_TRANSFER_DEV_TO_MEM)
|
|
{
|
|
dma_ccr.value_b.dst_inc = DMA_BURST_INCREMENTING;
|
|
dma_ccr.value_b.src_inc = DMA_BURST_FIXED;
|
|
}
|
|
else
|
|
{
|
|
dma_ccr.value_b.dst_inc = DMA_BURST_INCREMENTING;
|
|
dma_ccr.value_b.src_inc = DMA_BURST_INCREMENTING;
|
|
}
|
|
|
|
return dma_ccr;
|
|
}
|