MAXREFDES71# Code Documentation  V01.00
MAXREFDES71# 2-Channel Analog Input/Analog Output
 All Data Structures Files Functions Variables Macros Pages
maximDeviceSpecificUtilities.c
Go to the documentation of this file.
1 
31 /*
32  * Copyright (C) 2012 Maxim Integrated Products, Inc., All Rights Reserved.
33  *
34  * Permission is hereby granted, free of charge, to any person obtaining a
35  * copy of this software and associated documentation files (the "Software"),
36  * to deal in the Software without restriction, including without limitation
37  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
38  * and/or sell copies of the Software, and to permit persons to whom the
39  * Software is furnished to do so, subject to the following conditions:
40  *
41  * The above copyright notice and this permission notice shall be included
42  * in all copies or substantial portions of the Software.
43  *
44  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
45  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
46  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
47  * IN NO EVENT SHALL MAXIM INTEGRATED PRODUCTS BE LIABLE FOR ANY CLAIM, DAMAGES
48  * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
49  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
50  * OTHER DEALINGS IN THE SOFTWARE.
51  *
52  * Except as contained in this notice, the name of Maxim Integrated Products
53  * shall not be used except as stated in the Maxim Integrated Products
54  * Branding Policy.
55  *
56  * The mere transfer of this software does not imply any licenses
57  * of trade secrets, proprietary technology, copyrights, patents,
58  * trademarks, maskwork rights, or any other form of intellectual
59  * property whatsoever. Maxim Integrated Products retains all ownership rights.
60  *
61  ***************************************************************************/
62 
63 #include "xbasic_types.h"
64 #include "stdio.h"
65 #include "xscugic.h"
66 #include "axi_millbrae.h" //AXI_MILLBRAE custom ip core driver
67 
68 #include "utilities.h"
69 
70 #define INTC_DEVICE_INT_ID 91 //interrupt ID for the AXI_MILLBRAE IP core defined in the XPS
71 
72 static void ReadADCHandler(void *CallBackRef);
73 int SetupInterruptSystem(XScuGic *IntcInstancePtr);
74 
75 u32 g_unCount=0;
76 u16 *g_auSamplesCh1; //a pointer that stores the sampled data
77 u16 *g_auSamplesCh2; //a pointer that stores the sampled data
78 u32 g_unSampleSize; //requested sample size
79 u8 g_uchReadADCHandlerStop=1; //a status bit that shows whether the sampling is done
80 
81 u32 start_sampling(u32 unSampleSize, int nSampleRate, u16 *auSamplesCh1, u16 *auSamplesCh2)
96 {
97  u32 unTimer;
98 
99  //sampling rate = 50000000/(unTimer+1)
100 
101  if(nSampleRate==5) //sample rate = 400ksps
102  unTimer=124;
103  else if(nSampleRate==4) //sample rate = 100ksps
104  unTimer=499;
105  else if(nSampleRate==3) //sample rate = 50ksps
106  unTimer=999;
107  else if(nSampleRate==2) //sample rate = 20ksps
108  unTimer=2499;
109  else if(nSampleRate==1) //sample rate = 10ksps
110  unTimer=4999;
111  else if(nSampleRate==0) //sample rate = 1ksps
112  unTimer=49999;
113 
114  g_unCount=0;
115  g_auSamplesCh1=auSamplesCh1;
116  g_auSamplesCh2=auSamplesCh2;
117  g_unSampleSize=unSampleSize;
118 
119  XScuGic InterruptController;
120 
121  /*
122  * ADC configuration
123  * - use external reference
124  * - use offset binary format
125  * - use acquisition mode 1
126  */
127  AXI_MILLBRAE_Config_ADC(XPAR_AXI_MILLBRAE_0_BASEADDR, 0x10);
128 
129  /*
130  * Set up interrupt handler for the AXI_MILLBRAE IP Core
131  */
132  SetupInterruptSystem(&InterruptController);
133 
134  /*
135  * Enable the interrupt for AXI_MILLBRAE IP Core
136  */
137  XScuGic_Enable(&InterruptController, INTC_DEVICE_INT_ID);
138 
139  g_uchReadADCHandlerStop=0; //this signal goes high when the sampling is done
140 
141 
142  /*
143  * Enable AXI_MILLBRAE IP core interrupt
144  */
145  AXI_MILLBRAE_Interrupt_Enable(XPAR_AXI_MILLBRAE_0_BASEADDR);
146 
147  /*
148  * Write to the delay register
149  * the sampling rate = 50000000/(unTimer+1)
150  */
151  AXI_MILLBRAE_Write_Timer_Reg(XPAR_AXI_MILLBRAE_0_BASEADDR, unTimer);
152 
153  /*
154  * Start the ADC conversion at the rate defined above
155  * When a sample is available, AXI_MILLBRAE raises an interrupt
156  * the interrupt handler (ReadADCHandler) reads/stores the sampled data
157  *
158  * The AXI_MILLBRAE stops sampling when AXI_MILLBRAE_Stop_Conversion() is called
159  */
160  AXI_MILLBRAE_Start_Conversion(XPAR_AXI_MILLBRAE_0_BASEADDR);
161 
162  /*
163  * wait until the sampling is done
164  */
165  while(g_uchReadADCHandlerStop==0);
166 
167  /*
168  * return the number of samples collected
169  */
170  return g_unCount;
171 }
172 
173 void signal_replication(int nRepRate)
184 {
185  u8 uchInput;
186 
187  AXI_MILLBRAE_Stop_Operation(XPAR_AXI_MILLBRAE_0_BASEADDR);
188 
189  /*
190  * ADC configuration
191  * - external reference
192  * - CS mode, no-busy indicator
193  * - SHDN = 0
194  */
195  AXI_MILLBRAE_Config_ADC(XPAR_AXI_MILLBRAE_0_BASEADDR, 0x10);
196  if(nRepRate==0)
197  AXI_MILLBRAE_Write_Timer_Reg(XPAR_AXI_MILLBRAE_0_BASEADDR, 49999); //1kHz
198  else if(nRepRate==1)
199  AXI_MILLBRAE_Write_Timer_Reg(XPAR_AXI_MILLBRAE_0_BASEADDR, 9999); //5kHz
200  else if(nRepRate==2)
201  AXI_MILLBRAE_Write_Timer_Reg(XPAR_AXI_MILLBRAE_0_BASEADDR, 4999); //10kHz
202  else if(nRepRate==3)
203  AXI_MILLBRAE_Write_Timer_Reg(XPAR_AXI_MILLBRAE_0_BASEADDR, 832); //60.024kHz
204 
205  /*
206  * DAC configuration
207  * - Normal mode
208  * - SPI bus hold enabled
209  * - BUSY is active
210  * - DOUT = diabled
211  */
212  AXI_MILLBRAE_Config_DAC(XPAR_AXI_MILLBRAE_0_BASEADDR, 0x420000);
213 
214  AXI_MILLBRAE_Start_Replication(XPAR_AXI_MILLBRAE_0_BASEADDR);
215 
216  printf("Press the ESC key to stop the process\n\n");
217 
218  while(uchInput!=0x1B)
219  {
220  uchInput = Xil_In32(XPAR_PS7_UART_1_BASEADDR+0x30);
221  }
222  AXI_MILLBRAE_Stop_Operation(XPAR_AXI_MILLBRAE_0_BASEADDR);
223 }
224 
225 void continuous_sampling(int nChannel)
236 {
237  u16 uSample[8];
238  u8 uchInput;
239 
240  printf("Press the ESC key to stop sampling\n\n");
241 
242 
244 
245  if(nChannel < 2)
246  printf("Channel %i\n",nChannel);
247  else
248  printf("Ch 1, Ch 2\n");
249 
250  /*
251  * ADC configuration
252  * - external reference
253  * - CS mode, no-busy indicator
254  * - SHDN = 0
255  */
256  AXI_MILLBRAE_Config_ADC(XPAR_AXI_MILLBRAE_0_BASEADDR, 0x10);
257 
258  while(uchInput!=0x1B)
259  {
260  if(nChannel<2)
261  {
262  AXI_MILLBRAE_Single_Convert(XPAR_AXI_MILLBRAE_0_BASEADDR, nChannel, uSample);
263 
264  printf("%i\n", uSample[0]);
265 
267 
268  if((Xil_In32(XPAR_PS7_UART_1_BASEADDR+0x2C) & 0x02) == 0)
269  uchInput = Xil_In32(XPAR_PS7_UART_1_BASEADDR+0x30); // read the FIFO (only the LSB is valid).
270  }
271  else
272  {
273  AXI_MILLBRAE_Single_Convert(XPAR_AXI_MILLBRAE_0_BASEADDR, 2, uSample);
274 
275  printf("%i, %i\n", uSample[0], uSample[1]);
276 
278 
279  if((Xil_In32(XPAR_PS7_UART_1_BASEADDR+0x2C) & 0x02) == 0)
280  uchInput = Xil_In32(XPAR_PS7_UART_1_BASEADDR+0x30); // read the FIFO (only the LSB is valid).
281  }
282  }
283 }
284 
285 int SetupInterruptSystem(XScuGic *IntcInstancePtr)
295 {
296  int nStatus;
297  XScuGic_Config *GicConfig;
298 
299  GicConfig = XScuGic_LookupConfig(XPAR_SCUGIC_SINGLE_DEVICE_ID);
300  if (NULL == GicConfig) {
301  return XST_FAILURE;
302  }
303 
304  nStatus = XScuGic_CfgInitialize(IntcInstancePtr, GicConfig,
305  GicConfig->CpuBaseAddress);
306  if (nStatus != XST_SUCCESS) {
307  return XST_FAILURE;
308  }
309 
310  /*
311  * Perform a self-test to ensure that the hardware was built
312  * correctly
313  */
314  nStatus = XScuGic_SelfTest(IntcInstancePtr);
315  if (nStatus != XST_SUCCESS) {
316  return XST_FAILURE;
317  }
318 
319  /*
320  * Connect the interrupt controller interrupt handler to the hardware
321  * interrupt handling logic in the ARM processor.
322  */
323  Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
324  (Xil_ExceptionHandler) XScuGic_InterruptHandler,
325  IntcInstancePtr);
326 
327  /*
328  * Enable interrupts in the ARM
329  */
330  Xil_ExceptionEnable();
331 
332  /*
333  * Connect a device driver handler that will be called when an
334  * interrupt for the device occurs, the device driver handler performs
335  * the specific interrupt processing for the device
336  */
337  nStatus = XScuGic_Connect(IntcInstancePtr, INTC_DEVICE_INT_ID,
338  (Xil_ExceptionHandler)ReadADCHandler,
339  (void *)IntcInstancePtr);
340 
341  return nStatus;
342 }
343 
344 void ReadADCHandler(void *CallBackRef)
360 {
361  u32 nStatus;
362 
363  /*
364  * Read the interrupt status register to clear the interrupt
365  */
366  nStatus=AXI_MILLBRAE_Read_Interrupt_Status(XPAR_AXI_MILLBRAE_0_BASEADDR);
367 
368  /*
369  * Read the sampled data and store it in the *g_suSamples array
370  */
371  g_auSamplesCh1[g_unCount]=AXI_MILLBRAE_Read_Data(XPAR_AXI_MILLBRAE_0_BASEADDR,0);
372  g_auSamplesCh2[g_unCount]=AXI_MILLBRAE_Read_Data(XPAR_AXI_MILLBRAE_0_BASEADDR,1);
373  if(g_unCount==5)
375  g_unCount++;
376 
377  /*
378  * Stop sampling when enough samples are collected
379  */
381  {
382  /*
383  * stops sampling
384  */
385  AXI_MILLBRAE_Stop_Operation(XPAR_AXI_MILLBRAE_0_BASEADDR);
386 
387  /*
388  * Disable AXI_MILLBRAE IP core interrupt
389  */
390  AXI_MILLBRAE_Interrupt_Disable(XPAR_AXI_MILLBRAE_0_BASEADDR);
391 
393  }
394 
395  /*
396  * End sampling if the ESC key is pressed
397  */
398  if((Xil_In32(XPAR_PS7_UART_1_BASEADDR+0x2C) & 0x02) == 0) //if UART Rx buffer is not empty
399  {
400  u8 uchInput = Xil_In32(XPAR_PS7_UART_1_BASEADDR+0x30); // read the FIFO (only the LSB is valid).
401  if(uchInput==0x1B)
402  {
403  AXI_MILLBRAE_Stop_Operation(XPAR_AXI_MILLBRAE_0_BASEADDR);
404 
405  /*
406  * Disable AXI_MILLBRAE IP core interrupt
407  */
408  AXI_MILLBRAE_Interrupt_Disable(XPAR_AXI_MILLBRAE_0_BASEADDR);
409 
411  }
412  }
413 }