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