openmv/lib/alif/drivers/include/dma.h
iabdalkader daf2bb30da misc: Restructure repo.
Signed-off-by: iabdalkader <i.abdalkader@gmail.com>
2025-04-13 08:28:34 +02:00

378 lines
18 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.h
* @author Sudhir Sreedharan
* @email sudhir@alifsemi.com
* @version V1.0.0
* @date 11-08-2023
* @brief Low Level Header file for DMA
* @bug None.
* @Note None
******************************************************************************/
#ifndef DMA_H_
#define DMA_H_
#include <stdint.h>
#ifdef __cplusplus
}
#endif
/**
* @brief DMA_DMA_CHANNEL_RT_INFO_Type [DMA_CHANNEL_RT_INFO] ([0..7])
*/
typedef struct {
volatile const uint32_t DMA_CSR; /*!< (@ 0x00000000) Channel Status for DMA Channel (n) Register */
volatile const uint32_t DMA_CPC; /*!< (@ 0x00000004) Channel PC for DMA Channel (n) Register */
} DMA_DMA_CHANNEL_RT_INFO_Type; /*!< Size = 8 (0x8) */
/**
* @brief DMA_DMA_RT_CHANNEL_CFG_Type [DMA_RT_CHANNEL_CFG] ([0..7])
*/
typedef struct {
volatile const uint32_t DMA_SAR; /*!< (@ 0x00000000) Source Address for DMA Channel (n) Register */
volatile const uint32_t DMA_DAR; /*!< (@ 0x00000004) Destination Address for DMA Channel (n) Register */
volatile const uint32_t DMA_CCR; /*!< (@ 0x00000008) Channel Control for DMA Channel (n) Register */
volatile const uint32_t DMA_LC0; /*!< (@ 0x0000000C) Loop Counter 0 for DMA Channel (n) Register */
volatile const uint32_t DMA_LC1; /*!< (@ 0x00000010) Loop Counter 1 for DMA Channel (n) Register */
volatile const uint32_t RESERVED[3];
} DMA_DMA_RT_CHANNEL_CFG_Type; /*!< Size = 32 (0x20) */
/**
* @brief DMA (DMA)
*/
typedef struct { /*!< (@ 0x00000000) DMA Structure */
volatile const uint32_t DMA_DSR; /*!< (@ 0x00000000) DMA Manager Status Register */
volatile const uint32_t DMA_DPC; /*!< (@ 0x00000004) DMA Program Counter Register */
volatile const uint32_t RESERVED[6];
volatile uint32_t DMA_INTEN; /*!< (@ 0x00000020) Interrupt Enable Register */
volatile const uint32_t DMA_INT_EVENT_RIS; /*!< (@ 0x00000024) Event-Interrupt Raw Status Register */
volatile const uint32_t DMA_INTMIS; /*!< (@ 0x00000028) Interrupt Status Register */
volatile uint32_t DMA_INTCLR; /*!< (@ 0x0000002C) Interrupt Clear Register */
volatile const uint32_t DMA_FSRD; /*!< (@ 0x00000030) Fault Status DMA Manager Register */
volatile const uint32_t DMA_FSRC; /*!< (@ 0x00000034) Fault Status DMA Channel Register */
volatile const uint32_t DMA_FTRD; /*!< (@ 0x00000038) Fault Type DMA Manager Register */
volatile const uint32_t RESERVED1;
volatile const uint32_t DMA_FTR[8]; /*!< (@ 0x00000040) Fault Type for DMA Channel (n) Register */
volatile const uint32_t RESERVED2[40];
volatile DMA_DMA_CHANNEL_RT_INFO_Type DMA_CHANNEL_RT_INFO[8];/*!< (@ 0x00000100) [0..7] */
volatile const uint32_t RESERVED3[176];
volatile DMA_DMA_RT_CHANNEL_CFG_Type DMA_RT_CHANNEL_CFG[8];/*!< (@ 0x00000400) [0..7] */
volatile const uint32_t RESERVED4[512];
volatile const uint32_t DMA_DBGSTATUS; /*!< (@ 0x00000D00) Debug Status Register */
volatile uint32_t DMA_DBGCMD; /*!< (@ 0x00000D04) Debug Command Register */
volatile uint32_t DMA_DBGINST0; /*!< (@ 0x00000D08) Debug Instruction Register 0 */
volatile uint32_t DMA_DBGINST1; /*!< (@ 0x00000D0C) Debug Instruction Register 1 */
volatile const uint32_t RESERVED5[60];
volatile const uint32_t DMA_CR0; /*!< (@ 0x00000E00) Configuration Register 0 */
volatile const uint32_t DMA_CR1; /*!< (@ 0x00000E04) Configuration Register 1 */
volatile const uint32_t DMA_CR2; /*!< (@ 0x00000E08) Configuration Register 2 */
volatile const uint32_t DMA_CR3; /*!< (@ 0x00000E0C) Configuration Register 3 */
volatile const uint32_t DMA_CR4; /*!< (@ 0x00000E10) Configuration Register 4 */
volatile const uint32_t DMA_CRD; /*!< (@ 0x00000E14) DMA Configuration Register */
volatile const uint32_t RESERVED6[26];
volatile uint32_t DMA_WD; /*!< (@ 0x00000E80) Watchdog Register */
} DMA_Type; /*!< Size = 3716 (0xe84) */
/* Register fields and masks */
/* DMA DSR: Status of Manager thread */
#define DMA_DSR_DMA_STATUS_Pos 0U
#define DMA_DSR_DMA_STATUS_Msk (0xFUL << DMA_DSR_DMA_STATUS_Pos)
#define DMA_DSR_WAKEUP_EVENT_Pos 4U
#define DMA_DSR_WAKEUP_EVENT_Msk (0x1FUL << DMA_DSR_WAKEUP_EVENT_Pos)
#define DMA_DSR_DNS_Pos 9U
#define DMA_DSR_DNS_Msk (0x1UL << DMA_DSR_DNS_Pos)
/* DMA FSRD: Fault Status of Manager */
#define DMA_FSRD_FS_MGR_Pos 0U
#define DMA_FSRD_FS_MGR_Msk (0x1UL << DMA_FSRD_FS_MGR_Pos)
/* DMA FSRC: Fault Status of Channels */
#define DMA_FSRC_FAULT_STATUS_Pos 0U
#define DMA_FSRC_FAULT_STATUS_Msk (0xFFUL << DMA_FSRC_FAULT_STATUS_Pos)
/* DMA CSR: Channel Status */
#define DMA_CSR_CHANNEL_STATUS_Pos 0U
#define DMA_CSR_CHANNEL_STATUS_Msk (0xFUL << DMA_CSR_CHANNEL_STATUS_Pos)
#define DMA_CSR_WAKEUP_NUMBER_Pos 4U
#define DMA_CSR_WAKEUP_NUMBER_Msk (0x1FUL << DMA_CSR_WAKEUP_NUMBER_Pos)
#define DMA_CSR_DMAWFP_B_NS_Pos 14U
#define DMA_CSR_DMAWFP_B_NS_Msk (0x1UL << DMA_CSR_DMAWFP_B_NS_Pos)
#define DMA_CSR_DMAWFP_PERIPH_Pos 15U
#define DMA_CSR_DMAWFP_PERIPH_Msk (0x1UL << DMA_CSR_DMAWFP_PERIPH_Pos)
#define DMA_CSR_CNS_Pos 21U
#define DMA_CSR_CNS_Msk (0x1UL << DMA_CSR_CNS_Pos)
/* DMA DBGSTATUS: Debug Status */
#define DMA_DBGSTATUS_DBGSTATUS_Pos 0U
#define DMA_DBGSTATUS_DBGSTATUS_Msk (0x1UL << DMA_DBGSTATUS_DBGSTATUS_Pos)
/* DMA WD.IRQ.ONLY: Watchdog IRQ Only */
#define DMA_WD_IRQ_ONLY_Pos 0U
#define DMA_WD_IRQ_ONLY_Msk (0x1UL << DMA_WD_IRQ_ONLY_Pos)
#define DMA_MAX_CHANNELS 8 /*!< Max 8 channels supported */
#define DMA_MAX_PERIPH_REQ 32 /*!< Max 32 peripheral requests supported */
#define DMA_MAX_EVENTS 32 /*!< Max 32 events supported */
#define DMA_MAX_IRQ 32 /*!< Max 32 irqs supported */
#define DMA_MAX_BURST_LEN 16 /*!< Max 16 xfers are supported */
#define DMA_MAX_BURST_SIZE 8 /*!< Max 8bytes(DATA_WIDTH/8) */
#define DMA_MAX_BUFF_DEPTH 128 /*!< 32lines * 4bytes for each FIFO */
#define DMA_IRQ_ABORT_OFFSET 32 /*!< Abort irq offset */
/**
* enum DMA_THREAD
* DMA Thread: Manager and Channel Thread
*/
typedef enum _DMA_THREAD {
DMA_THREAD_MANAGER = 0, /*!< DMA Manager thread */
DMA_THREAD_CHANNEL, /*!< DMA Channel thread */
} DMA_THREAD;
/**
* enum DMA_THREAD_STATUS
* DMA Thread Status: Covers both Manager and Channel Thread Status.
*/
typedef enum _DMA_THREAD_STATUS {
DMA_THREAD_STATUS_STOPPED = 0, /*!< MGR/CHNL Thread is Stopped */
DMA_THREAD_STATUS_EXECUTING, /*!< MGR/CHNL Thread is executing */
DMA_THREAD_STATUS_CACHE_MISS, /*!< MGR/CHNL Cache miss occurred */
DMA_THREAD_STATUS_UPDATING_PC, /*!< MGR/CHNL Thread is updating the program counter */
DMA_THREAD_STATUS_WAITING_FOR_EVENT, /*!< MGR/CHNL Thread is waiting for an event */
DMA_THREAD_STATUS_AT_BARRIER, /*!< CHNL Thread is waiting at an barrier */
DMA_THREAD_STATUS_WAITING_FOR_PERIPHERAL = 7, /*!< CHNL Thread is waiting for a peripheral */
DMA_THREAD_STATUS_KILLING, /*!< CHNL Thread is at killing state */
DMA_THREAD_STATUS_COMPLETING, /*!< CHNL Thread is at completing state */
DMA_THREAD_STATUS_FAULTING_COMPLETING = 14, /*!< CHNL Thread is in faulting completing state */
DMA_THREAD_STATUS_FAULTING = 15, /*!< MGR/CHNL Thread is in Faulting State */
} DMA_THREAD_STATUS;
/* Fault Type DMA Manager Register */
typedef union _dma_ftrd_t {
uint32_t ftrd;
struct {
uint32_t undef_instr : 1; /*!< Undefined Instruction */
uint32_t operand_invalid : 1; /*!< Invalid arguments passed */
uint32_t RESERVED1 : 2; /*!< Reserved */
uint32_t dmago_err : 1; /*!< Security aspect while executing DMAGO */
uint32_t mgr_evnt_err : 1; /*!< security aspect while executing DMAWFE or DMASEV */
uint32_t RESERVED2 : 10; /*!< Reserved */
uint32_t instr_fetch_err : 1; /*!< Instr fetch error on AXI */
uint32_t RESERVED3 : 13; /*!< Reserved */
uint32_t dbg_instr : 1; /*!< Instr read from system or debug interface */
} ftrd_b;
} dma_ftrd_t;
/* Fault Type DMA Channel Register */
typedef union _dma_ftr {
uint32_t ftr;
struct {
uint32_t undef_instr : 1; /*!< Undefined Instruction */
uint32_t operand_invalid : 1; /*!< Invalid arguments passed */
uint32_t reserved1 : 3; /*!< Reserved */
uint32_t ch_evnt_err : 1; /*!< security aspect while executing DMAWFE or DMASEV */
uint32_t ch_periph_err : 1; /*!< security aspect while executing DMAWFP/DMALDP/DMASTP/DMAFLUSHP */
uint32_t ch_rdwr_err : 1; /*!< security aspect while programming CCRn */
uint32_t reserved2 : 4; /*!< Reserved */
uint32_t mfifo_err : 1; /*!< mfifo prevented channel from executing DMALD/DMAST */
uint32_t no_st_data : 1; /*!< mfifo didn't contain data to perform DMAST */
uint32_t reserved3 : 2; /*!< Reserved */
uint32_t instr_fetch_err : 1; /*!< AXI response on inst fetch */
uint32_t data_write_err : 1; /*!< AXI response on data write */
uint32_t data_read_err : 1; /*!< AXI response on data read */
uint32_t reserved4 : 11; /*!< Reserved */
uint32_t dbg_instr : 1; /*!< Instr read from system or debug interface */
uint32_t lockup_err : 1; /*!< channel lockedup due to resource starvation */
} ftr_b;
} dma_ftr;
/* DMA Instruction0 Register */
typedef union _dma_dbginst0_t {
uint32_t dbginst0;
struct {
uint32_t dbg_thrd : 1; /*!< Debug Manager/Channel Thread */
uint32_t reserved1 : 7; /*!< Reserved */
uint32_t chn_num : 3; /*!< Channel number */
uint32_t reserved2 : 5; /*!< Reserved */
uint32_t ins_byte0 : 8; /*!< Instruction byte 0 */
uint32_t ins_byte1 : 8; /*!< Instruction byte 1 */
} dbginst0_b;
} dma_dbginst0_t;
/* DMA Instruction1 Register */
typedef union _dma_dbginst1_t {
uint32_t dbginst1;
struct {
uint32_t ins_byte2 : 8; /*!< Instruction byte 2 */
uint32_t ins_byte3 : 8; /*!< Instruction byte 3 */
uint32_t ins_byte4 : 8; /*!< Instruction byte 4 */
uint32_t ins_byte5 : 8; /*!< Instruction byte 5 */
} dbginst1_b;
} dma_dbginst1_t;
/**
\fn void dma_enable_interrupt(DMA_Type *dma,
uint8_t event_irq_select_index)
\brief Enable the interrupt for the requested interrupt line
\param[in] dma Pointer to DMA register map
\param[in] event_irq_select_index Index of the interrupt to be enabled
*/
static inline void dma_enable_interrupt(DMA_Type *dma,
uint8_t event_irq_select_index)
{
dma->DMA_INTEN |= (1U << event_irq_select_index);
}
/**
\fn void dma_disable_interrupt(DMA_Type *dma,
uint8_t event_irq_select_index)
\brief Disable the interrupt for the requested interrupt line
\param[in] dma Pointer to DMA register map
\param[in] event_irq_select_index Index of the interrupt to be disabled
*/
static inline void dma_disable_interrupt(DMA_Type *dma,
uint8_t event_irq_select_index)
{
dma->DMA_INTEN &= ~(1U << event_irq_select_index);
}
/**
\fn void dma_clear_interrupt(DMA_Type *dma, uint8_t irq_clr_index)
\brief Clear the interrupt for the requested interrupt line
\param[in] dma Pointer to DMA register map
\param[in] irq_clr_index Index of the interrupt to be cleared
*/
static inline void dma_clear_interrupt(DMA_Type *dma, uint8_t irq_clr_index)
{
dma->DMA_INTCLR = (1U << irq_clr_index);
}
/**
\fn bool dma_manager_is_nonsecure(DMA_Type *dma)
\brief Get Security status of the Manager thread
\param[in] dma Pointer to DMA register map
\return bool True if Non-Secure
*/
static inline bool dma_manager_is_nonsecure(DMA_Type *dma)
{
return (dma->DMA_DSR & DMA_DSR_DNS_Msk);
}
/**
\fn bool dma_manager_is_faulting(DMA_Type *dma)
\brief Get fault status of the Manager thread
\param[in] dma Pointer to DMA register map
\return bool True if Manager thread is faulting
*/
static inline bool dma_manager_is_faulting(DMA_Type *dma)
{
return (dma->DMA_FSRD & DMA_FSRD_FS_MGR_Msk);
}
/**
\fn bool dma_get_channel_fault_status(DMA_Type *dma,
uint8_t channel_num)
\brief Get Fault status of the requested channel
\param[in] dma Pointer to DMA register map
\param[in] channel_num Channel Number
\return bool True if channel is faulted
*/
static inline bool dma_get_channel_fault_status(DMA_Type *dma,
uint8_t channel_num)
{
return (dma->DMA_FSRC & (1 << channel_num));
}
/**
\fn DMA_THREAD_STATUS dma_get_channel_status(DMA_Type *dma,
uint8_t channel_num)
\brief Get Current status of the Channel
\param[in] dma Pointer to DMA register map
\param[in] channel_num Channel Number
\return DMA_THREAD_STATUS channel status
*/
static inline DMA_THREAD_STATUS dma_get_channel_status(DMA_Type *dma,
uint8_t channel_num)
{
return (DMA_THREAD_STATUS)(dma->DMA_CHANNEL_RT_INFO[channel_num].DMA_CSR
& DMA_CSR_CHANNEL_STATUS_Msk);
}
/**
\fn uint32_t dma_get_channel_src_addr(DMA_Type *dma,
uint8_t channel_num)
\brief Get Source Address of the Channel
\param[in] dma Pointer to DMA register map
\param[in] channel_num Channel Number
\return uint32_t Current Source Address
*/
static inline uint32_t dma_get_channel_src_addr(DMA_Type *dma,
uint8_t channel_num)
{
return dma->DMA_RT_CHANNEL_CFG[channel_num].DMA_SAR;
}
/**
\fn uint32_t dma_get_channel_dest_addr(DMA_Type *dma,
uint8_t channel_num)
\brief Get Destination Address of the Channel
\param[in] dma Pointer to DMA register map
\param[in] channel_num Channel Number
\return uint32_t Current Destination Address
*/
static inline uint32_t dma_get_channel_dest_addr(DMA_Type *dma,
uint8_t channel_num)
{
return dma->DMA_RT_CHANNEL_CFG[channel_num].DMA_DAR;
}
/**
\fn bool dma_debug_is_busy(DMA_Type *dma)
\brief Get Debug Status of DMAC
\param[in] dma Pointer to DMA register map
\return bool True if DMAC is busy in executing debug CMDS
*/
static inline bool dma_debug_is_busy(DMA_Type *dma)
{
return (dma->DMA_DBGSTATUS & DMA_DBGSTATUS_DBGSTATUS_Msk);
}
/**
\fn void dma_execute(DMA_Type *dma,
uint32_t dbginst0,
uint32_t dbginst1)
\brief Execute command in DBGINST register
\param[in] dma Pointer to DMA register map
\param[in] dbginst0 DBGINST0
\param[in] dbginst1 DBGINST1
\return void
*/
static inline void dma_execute(DMA_Type *dma,
uint32_t dbginst0,
uint32_t dbginst1)
{
dma->DMA_DBGINST0 = dbginst0;
dma->DMA_DBGINST1 = dbginst1;
dma->DMA_DBGCMD = 0;
}
#ifdef __cplusplus
}
#endif
#endif /* DMA_H_ */