1 /*
2  * Copyright 2019-2023 NXP
3  * All rights reserved.
4  *
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 #include "fsl_smartdma.h"
10 
11 /* Component ID definition, used by tools. */
12 #ifndef FSL_COMPONENT_ID
13 #define FSL_COMPONENT_ID "platform.drivers.lpc_smartdma"
14 #endif
15 
16 /*******************************************************************************
17  * Definitions
18  ******************************************************************************/
19 
20 typedef void (*smartdma_func_t)(void);
21 
22 #define SMARTDMA_HANDSHAKE_EVENT  0U
23 #define SMARTDMA_HANDSHAKE_ENABLE 1U
24 #define SMARTDMA_MASK_RESP        2U
25 #define SMARTDMA_ENABLE_AHBBUF    3U
26 #define SMARTDMA_ENABLE_GPISYNCH  4U
27 
28 #if defined(SMARTDMA0) && !(defined(SMARTDMA))
29 #define SMARTDMA SMARTDMA0
30 #endif
31 
32 /*******************************************************************************
33  * Variables
34  ******************************************************************************/
35 static smartdma_func_t *s_smartdmaApiTable;
36 static smartdma_callback_t s_smartdmaCallback;
37 static void *s_smartdmaCallbackParam;
38 static smartdma_param_t s_smartdmaParam;
39 
40 /*******************************************************************************
41  * Prototypes
42  ******************************************************************************/
43 
44 /*******************************************************************************
45  * Codes
46  ******************************************************************************/
47 /*!
48  * brief Initialize the SMARTDMA.
49  *
50  * param apiMemAddr The address firmware will be copied to.
51  * param firmware The firmware to use.
52  * param firmwareSizeByte Size of firmware.
53  */
SMARTDMA_Init(uint32_t apiMemAddr,const void * firmware,uint32_t firmwareSizeByte)54 void SMARTDMA_Init(uint32_t apiMemAddr, const void *firmware, uint32_t firmwareSizeByte)
55 {
56     SMARTDMA_InitWithoutFirmware();
57     SMARTDMA_InstallFirmware(apiMemAddr, firmware, firmwareSizeByte);
58 }
59 
60 /*!
61  * brief Initialize the SMARTDMA.
62  *
63  * This function is similar with SMARTDMA_Init, the difference is this function
64  * does not install the firmware, the firmware could be installed using
65  * SMARTDMA_InstallFirmware.
66  */
SMARTDMA_InitWithoutFirmware(void)67 void SMARTDMA_InitWithoutFirmware(void)
68 {
69     /* Clear Smart DMA RAM */
70     RESET_PeripheralReset(kSMART_DMA_RST_SHIFT_RSTn);
71     CLOCK_EnableClock(kCLOCK_Smartdma);
72 }
73 
74 /*!
75  * @brief Install the firmware.
76  *
77  * param apiMemAddr The address firmware will be copied to.
78  * param firmware The firmware to use.
79  * param firmwareSizeByte Size of firmware.
80  */
SMARTDMA_InstallFirmware(uint32_t apiMemAddr,const void * firmware,uint32_t firmwareSizeByte)81 void SMARTDMA_InstallFirmware(uint32_t apiMemAddr, const void *firmware, uint32_t firmwareSizeByte)
82 {
83     (void)memcpy((void *)(uint8_t *)apiMemAddr, firmware, firmwareSizeByte);
84     SMARTDMA->CTRL     = (0xC0DE0000U | (1U << SMARTDMA_ENABLE_GPISYNCH));
85     s_smartdmaApiTable = (smartdma_func_t *)apiMemAddr;
86 }
87 
88 /*!
89  * brief Install the complete callback function..
90  *
91  * param callback The callback called when smartdma program finished.
92  */
SMARTDMA_InstallCallback(smartdma_callback_t callback,void * param)93 void SMARTDMA_InstallCallback(smartdma_callback_t callback, void *param)
94 {
95     s_smartdmaCallback      = callback;
96     s_smartdmaCallbackParam = param;
97 }
98 
99 /*!
100  * brief Boot the SMARTDMA to run program.
101  *
102  * param apiIndex Index of the API to call.
103  * param pParam Pointer to the parameter allocated by caller.
104  * param mask Value set to SMARTDMA_ARM2SMARTDMA[0:1].
105  */
SMARTDMA_Boot(uint32_t apiIndex,void * pParam,uint8_t mask)106 void SMARTDMA_Boot(uint32_t apiIndex, void *pParam, uint8_t mask)
107 {
108     SMARTDMA->ARM2EZH = (uint32_t)(uint8_t *)pParam | (uint32_t)mask;
109     SMARTDMA->BOOTADR = (uint32_t)(s_smartdmaApiTable[apiIndex]);
110     SMARTDMA->CTRL    = 0xC0DE0011U | (0U << SMARTDMA_MASK_RESP) | (0U << SMARTDMA_ENABLE_AHBBUF); /* BOOT */
111 };
112 
113 /*
114  * brief Copy SMARTDMA params and Boot to run program.
115  *
116  * This function is similar with SMARTDMA_Boot, the only difference
117  * is, this function copies the *pParam to a local variable, upper layer
118  * can free the pParam's memory before the SMARTDMA execution finished,
119  * for example, upper layer can define the param as a local variable.
120  *
121  * param apiIndex Index of the API to call.
122  * param pParam Pointer to the parameter.
123  * param mask Value set to SMARTDMA_ARM2SMARTDMA[0:1].
124  * note Only call this function when SMARTDMA is not busy.
125  */
SMARTDMA_Boot1(uint32_t apiIndex,const smartdma_param_t * pParam,uint8_t mask)126 void SMARTDMA_Boot1(uint32_t apiIndex, const smartdma_param_t *pParam, uint8_t mask)
127 {
128     (void)memcpy(&s_smartdmaParam, pParam, sizeof(smartdma_param_t));
129     SMARTDMA_Boot(apiIndex, &s_smartdmaParam, mask);
130 }
131 
132 /*!
133  * brief Deinitialize the SMARTDMA.
134  */
SMARTDMA_Deinit(void)135 void SMARTDMA_Deinit(void)
136 {
137     SMARTDMA->CTRL = 0xC0DE0000U;
138     CLOCK_DisableClock(kCLOCK_Smartdma);
139 }
140 
141 /*!
142  * brief Reset the SMARTDMA.
143  */
SMARTDMA_Reset(void)144 void SMARTDMA_Reset(void)
145 {
146     RESET_PeripheralReset(kSMART_DMA_RST_SHIFT_RSTn);
147     SMARTDMA->CTRL = (0xC0DE0000U | (1U << SMARTDMA_ENABLE_GPISYNCH));
148 }
149 
150 /*!
151  * brief SMARTDMA IRQ.
152  */
SMARTDMA_HandleIRQ(void)153 void SMARTDMA_HandleIRQ(void)
154 {
155     if (NULL != s_smartdmaCallback)
156     {
157         s_smartdmaCallback(s_smartdmaCallbackParam);
158     }
159 }
160