-
Notifications
You must be signed in to change notification settings - Fork 1.1k
/
vdma.c
289 lines (248 loc) · 9.01 KB
/
vdma.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
/******************************************************************************
* Copyright (C) 2014 - 2022 Xilinx, Inc. All rights reserved.
* Copyright (C) 2022 - 2023 Advanced Micro Devices, Inc. All rights reserved.
* SPDX-License-Identifier: MIT
******************************************************************************/
/*****************************************************************************/
/**
*
* @file vdma.c
*
* This file comprises sample application to usage of VDMA APi's in vdma_api.c.
* .
*
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 4.0 adk 11/26/15 First release
* 4.1 adk 01/07/16 Updated DDR base address for Ultrascale (CR 799532) and
* removed the defines for S6/V6.
* ms 04/05/17 Modified Comment lines in functions to
* recognize it as documentation block for doxygen
* generation of examples.
* 6.12 sa 08/12/22 Updated the example to use latest MIG cannoical define
* i.e XPAR_MIG_0_C0_DDR4_MEMORY_MAP_BASEADDR.
****************************************************************************/
/*** Include file ***/
#include "xparameters.h"
#include "xstatus.h"
#include "xintc.h"
#include "xil_exception.h"
#include "xil_assert.h"
#include "xaxivdma.h"
#include "xaxivdma_i.h"
#ifdef XPAR_AXI_7SDDR_0_S_AXI_BASEADDR
#define MEMORY_BASE XPAR_AXI_7SDDR_0_S_AXI_BASEADDR
#elif XPAR_MIG7SERIES_0_BASEADDR
#define MEMORY_BASE XPAR_MIG7SERIES_0_BASEADDR
#elif XPAR_MIG_0_C0_DDR4_MEMORY_MAP_BASEADDR
#define MEMORY_BASE XPAR_MIG_0_C0_DDR4_MEMORY_MAP_BASEADDR
#elif XPAR_PSU_DDR_0_S_AXI_BASEADDR
#define MEMORY_BASE XPAR_PSU_DDR_0_S_AXI_BASEADDR
#else
#warning CHECK FOR THE VALID DDR ADDRESS IN XPARAMETERS.H, \
DEFAULT SET TO 0x01000000
#define MEMORY_BASE 0x01000000
#endif
/*** Global Variables ***/
unsigned int srcBuffer = (MEMORY_BASE + 0x1000000);
/* Instance of the Interrupt Controller */
static XIntc Intc;
int run_triple_frame_buffer(XAxiVdma* InstancePtr, int DeviceId, int hsize,
int vsize, int buf_base_addr, int number_frame_count,
int enable_frm_cnt_intr);
static int SetupIntrSystem(XAxiVdma *AxiVdmaPtr, u16 ReadIntrId,
u16 WriteIntrId);
/*****************************************************************************/
/**
* Main function
*
* This is main entry point to demonstrate this example.
*
* @return None
*
******************************************************************************/
int main(){
int Status;
XAxiVdma InstancePtr;
XAxiVdma InstancePtr_1;
xil_printf("\n--- Entering main() --- \r\n");
xil_printf("Starting the first VDMA \n\r");
/* Calling the API to configure and start VDMA without frame counter interrupt */
Status = run_triple_frame_buffer(&InstancePtr, 0, 1920, 1080,
srcBuffer, 100, 0);
if (Status != XST_SUCCESS) {
xil_printf("Transfer of frames failed with error = %d\r\n",Status);
return XST_FAILURE;
} else {
xil_printf("Transfer of frames started \r\n");
}
xil_printf("Starting the second VDMA \r\n");
/* Calling the API to configure and start second VDMA with frame counter interrupt
* Please note source buffer pointer is being offset a bit */
Status = run_triple_frame_buffer(&InstancePtr_1, 1, 1920, 1080,
srcBuffer + 0x1000000, 100, 1);
if (Status != XST_SUCCESS){
xil_printf("Transfer of frames failed with error = %d\r\n",Status);
return XST_FAILURE;
} else {
xil_printf("Transfer of frames started \r\n");
}
/* Enabling the interrupt for second VDMA */
SetupIntrSystem(&InstancePtr_1, XPAR_INTC_0_AXIVDMA_1_MM2S_INTROUT_VEC_ID,
XPAR_INTC_0_AXIVDMA_1_S2MM_INTROUT_VEC_ID);
/* Infinite while loop to let it run */
while(1);
}
/*****************************************************************************/
/*
* Call back function for read channel
*
* The user can put his code that should get executed when this
* call back happens.
*
* @param CallbackRef is the call back reference pointer
* @param Mask is the interrupt mask passed in from the driver
*
* @return None
*
******************************************************************************/
static void ReadCallBack(void *CallbackRef, u32 Mask)
{
/* User can add his code in this call back function */
xil_printf("Read Call back function is called\r\n");
}
/*****************************************************************************/
/*
* The user can put his code that should get executed when this
* call back happens.
*
* @param CallbackRef is the call back reference pointer
* @param Mask is the interrupt mask passed in from the driver
*
* @return None
*
******************************************************************************/
static void ReadErrorCallBack(void *CallbackRef, u32 Mask)
{
/* User can add his code in this call back function */
xil_printf("Read Call back Error function is called\r\n");
}
/*****************************************************************************/
/*The user can put his code that should get executed when this
* call back happens.
*
*
* This callback only clears the interrupts and updates the transfer status.
*
* @param CallbackRef is the call back reference pointer
* @param Mask is the interrupt mask passed in from the driver
*
* @return None
*
******************************************************************************/
static void WriteCallBack(void *CallbackRef, u32 Mask)
{
/* User can add his code in this call back function */
xil_printf("Write Call back function is called\r\n");
}
/*****************************************************************************/
/*
* The user can put his code that should get executed when this
* call back happens.
*
* @param CallbackRef is the call back reference pointer
* @param Mask is the interrupt mask passed in from the driver
*
* @return None
*
******************************************************************************/
static void WriteErrorCallBack(void *CallbackRef, u32 Mask)
{
/* User can add his code in this call back function */
xil_printf("Write Call back Error function is called \r\n");
}
/*****************************************************************************/
/*
*
* This function setups the interrupt system so interrupts can occur for the
* DMA. This function assumes INTC component exists in the hardware system.
*
* @param AxiDmaPtr is a pointer to the instance of the DMA engine
* @param ReadIntrId is the read channel Interrupt ID.
* @param WriteIntrId is the write channel Interrupt ID.
*
* @return XST_SUCCESS if successful, otherwise XST_FAILURE.
*
* @note None.
*
******************************************************************************/
static int SetupIntrSystem(XAxiVdma *AxiVdmaPtr, u16 ReadIntrId,
u16 WriteIntrId)
{
int Status;
XIntc *IntcInstancePtr =&Intc;
/* Initialize the interrupt controller and connect the ISRs */
Status = XIntc_Initialize(IntcInstancePtr, XPAR_INTC_0_DEVICE_ID);
if (Status != XST_SUCCESS) {
xil_printf( "Failed init intc\r\n");
return XST_FAILURE;
}
Status = XIntc_Connect(IntcInstancePtr, ReadIntrId,
(XInterruptHandler)XAxiVdma_ReadIntrHandler, AxiVdmaPtr);
if (Status != XST_SUCCESS) {
xil_printf("Failed read channel connect intc %d\r\n", Status);
return XST_FAILURE;
}
Status = XIntc_Connect(IntcInstancePtr, WriteIntrId,
(XInterruptHandler)XAxiVdma_WriteIntrHandler, AxiVdmaPtr);
if (Status != XST_SUCCESS) {
xil_printf("Failed write channel connect intc %d\r\n", Status);
return XST_FAILURE;
}
/* Start the interrupt controller */
Status = XIntc_Start(IntcInstancePtr, XIN_REAL_MODE);
if (Status != XST_SUCCESS) {
xil_printf( "Failed to start intc\r\n");
return XST_FAILURE;
}
/* Enable interrupts from the hardware */
XIntc_Enable(IntcInstancePtr, ReadIntrId);
XIntc_Enable(IntcInstancePtr, WriteIntrId);
Xil_ExceptionInit();
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
(Xil_ExceptionHandler)XIntc_InterruptHandler,
(void *)IntcInstancePtr);
Xil_ExceptionEnable();
/* Register call-back functions
*/
XAxiVdma_SetCallBack(AxiVdmaPtr, XAXIVDMA_HANDLER_GENERAL, ReadCallBack,
(void *)AxiVdmaPtr, XAXIVDMA_READ);
XAxiVdma_SetCallBack(AxiVdmaPtr, XAXIVDMA_HANDLER_ERROR,
ReadErrorCallBack, (void *)AxiVdmaPtr, XAXIVDMA_READ);
XAxiVdma_SetCallBack(AxiVdmaPtr, XAXIVDMA_HANDLER_GENERAL,
WriteCallBack, (void *)AxiVdmaPtr, XAXIVDMA_WRITE);
XAxiVdma_SetCallBack(AxiVdmaPtr, XAXIVDMA_HANDLER_ERROR,
WriteErrorCallBack, (void *)AxiVdmaPtr, XAXIVDMA_WRITE);
return XST_SUCCESS;
}
/*****************************************************************************/
/**
*
* This function disables the interrupts
*
* @param ReadIntrId is interrupt ID associated w/ DMA read channel
* @param WriteIntrId is interrupt ID associated w/ DMA write channel
*
* @return None.
*
* @note None.
*
******************************************************************************/
static void DisableIntrSystem(u16 ReadIntrId, u16 WriteIntrId)
{
/* Disconnect the interrupts for the DMA TX and RX channels */
XIntc_Disconnect(&Intc, ReadIntrId);
XIntc_Disconnect(&Intc, WriteIntrId);
}