UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Contributor
Contributor
535 Views
Registered: ‎09-13-2016

SDK hangs when run code with large number integer.

Jump to solution

Hello,

I'm implementing a Zynq 7020 project. Basically it has AXI QSPI IP and Processing System to take data from external device through SPI and store it into DDR by PS. So I've made bare metal code in SDK and it was working for small number(~100) of data read through SPI. When I try to read more numbers such as few thousands or millions, however, SDK hangs.

The code is based on example code from Xilinx for AXI Quad SPI IP.

 

/******************************************************************************
*
* Copyright (C) 2002 - 2014 Xilinx, Inc.  All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/******************************************************************************/
/**
* @file  xspi_low_level_example.c
*
* This file contains a design example using the low-level driver of the
* SPI driver (XSpi). These macros are found in xspi_l.h.  A simple loopback
* test is done within an SPI device in polled mode. This example works only with
* 8-bit wide data transfers.
*
* @note
* This example works only with 8-bit wide data transfers in standard SPI mode.
* This example will not work if the axi_qspi device is configured in dual/quad
* modes.
*
* To make this example work for 16 bit transfers change u8 Buffer[BUFFER_SIZE]
* to u16 Buffer[BUFFER_SIZE]. The SPI Core should also be configured for 16 bit
* access during the build time.
*
* To make this example work for 32 bit transfers change u8 Buffer[BUFFER_SIZE]
* to u32 Buffer[BUFFER_SIZE]. The SPI Core should also be configured for 32 bit
* access during the build time.
*
*
*<pre>
* MODIFICATION HISTORY:
*
* Ver   Who  Date     Changes
* ----- ---- -------- ----------------------------------------------------------
* 1.00b rpm  04/24/02 First release
* 1.00b jhl  09/10/02 Added code to ensure it works with a fast processor.
* 1.00b sv   05/16/05 Minor changes to comply to Doxygen and coding guidelines
* 3.00a ktn  10/28/09 Converted all register accesses to 32 bit access.
* 3.02a sdm  05/04/11 Added a note about dual/quad modes in axi_qspi.
* 4.2   ms   01/23/17 Added xil_printf statement in main function to
*                     ensure that "Successfully ran" and "Failed" strings
*                     are available in all examples. This is a fix for
*                     CR-965028.
*
*</pre>
*******************************************************************************/

/***************************** Include Files **********************************/
/*Common Headers*/
#include "xparameters.h"
#include "xstatus.h"
#include "xil_printf.h"
/*AXI Q SPI*/
#include "xspi_l.h"
#include "AXI_REG.h"
/*DDR*/
#include <stdio.h>
#include "xil_types.h"
#include "xil_testmem.h"
#include "platform.h"
#include "memory_config.h"


/************************** Constant Definitions ******************************/

/*
 * The following constants map to the XPAR parameters created in the
 * xparameters.h file. They are defined here such that a user can easily
 * change all the needed parameters in one place.
 */
#define SPI_BASEADDR		XPAR_SPI_0_BASEADDR

/**************************** Type Definitions ********************************/


/***************** Macros (Inline Functions) Definitions **********************/


/************************** Function Prototypes *******************************/

int XSpi_LowLevelExample(u32 BaseAddress);

/************************** Variable Definitions ******************************/


 //This is the size of the buffer to be transmitted/received in AXI SPI.
 #define BUFFER_SIZE			 32

//The buffer used for Transmission/Reception of the SPI test data
u16 Buffer_TX[BUFFER_SIZE];
u16 Buffer[BUFFER_SIZE];


int main(void)
{
	int Status;
	u32 AXI_baseaddr;
	int Val;
	// JL Custom code based on Xiilnx's from.
	AXI_baseaddr = 0x43c00000;
	xil_printf("AXI reg control...\n\r");
	////////////SPI STAGE//////////////////////////////////////
	//resetting SPI read done register.
	Val = 0x0;
	AXI_REG_mWriteReg (AXI_baseaddr, 1*4, Val);
	//Run next execution, read mode when write is done.
	Val = Val | 0b10;
	AXI_REG_mWriteReg (AXI_baseaddr, 1*4, Val); //MUX will set for PS
	xil_printf("\n\nSPI MUX is now read mode. PS is connected to the spi slave device\n");

	//Run the example, specify the Base Address that is generated in xparameters.h
	Status = XSpi_LowLevelExample(SPI_BASEADDR);
//	xil_printf("output: %x\r\n", Status);

	//execution over, make DONE high and back to write to mode
	Val = 0b01;
	AXI_REG_mWriteReg (AXI_baseaddr, 1*4, Val); //MUX will set for PS
	xil_printf("\n\nSPI MUX is now write mode. DONE is generated.\n");

	////////////////DDR stage///////////////////
	xil_printf("\n\n Start DDR function .\n");
    int i,j;
    init_platform();
    print("--Starting Memory Test Application--\n\r");
    Xil_Out16(0x00100000, 0xACDC);
    Xil_Out16(0x00100002, 0x4321);
    for(j=0;j<Status;j++){
    	if (j%4 == 1){
    		printf("What's at DDR 0x%8x, Reg38: %d\n\n", 0x00100000+j*2, Xil_In16(0x00100000+j*2));
    	}
    	else if (j%2 == 1){
			printf("What's at DDR 0x%8x, Reg37: %d\n\n", 0x00100000+j*2, Xil_In16(0x00100000+j*2));
		}
    	for(i=0;i<200;i++){};
    }
      //
//    printf("What's in DDR base addr: %x\n\n", Xil_In16(0x00100002));

//    cleanup_platform();
    print("--DDR Complete--\n\r");
}

//AXI Q SPI function
int XSpi_LowLevelExample(u32 BaseAddress)
{
	u32 Control;
	int NumBytesSent = 0;
	int NumBytesRcvd = 0;
	u32 Count;
	int numRead = 40; //number of addresses to read from the spi slave device
	int tempread;
	int i;
	int cycle;
	int cmd=1;  //0 write, 1 read

	/*
	 * Initialize the buffer with zeroes so that it can be used to receive
	 * data.
	 */
	for (Count = 0; Count < BUFFER_SIZE; Count++) {
		Buffer[Count] = 0x0;
	}
	//ADDR PUT
	for (Count = 0; Count < 4; Count++) {
		if 		(Count == 0) Buffer_TX[Count] = (38) | (cmd<<7);
		else if (Count == 2) Buffer_TX[Count] = (37) | (cmd<<7);
		else 			   	 Buffer_TX[Count] = 0x00;
	}
	/*
	 * Set up the device in loopback mode and enable master mode.
	 */
	XSpi_WriteReg(BaseAddress, XSP_SRR_OFFSET, 0x0000000a); //jl added for reset
	for (cycle=0; cycle<numRead; cycle++){
//	for (cycle=0; cycle<100; cycle++){

//		XSpi_WriteReg(BaseAddress, XSP_SRR_OFFSET, 0x0000000a); //jl added for reset
		for(i=0;i<200;i++){}// Manual delay not to lose data.
		Control = XSpi_ReadReg(BaseAddress, XSP_CR_OFFSET);
		Control |= (XSP_CR_MASTER_MODE_MASK);
//		Control &= ~XSP_CR_MANUAL_SS_MASK;

		XSpi_WriteReg(BaseAddress, XSP_CR_OFFSET, Control);
		XSpi_WriteReg(BaseAddress,XSP_SSR_OFFSET,0x0);  //ss
//		printf("Control1 is %x\n\n\n", Control);

		/*
		 * Fill up the transmitter with data, assuming the receiver can hold
		 * the same amount of data.
		 */

		for (i=0;i<2;i++){
			XSpi_WriteReg((BaseAddress), XSP_DTR_OFFSET,
					Buffer_TX[(NumBytesSent)%4]);
			NumBytesSent++;
		}

		/*
		 * Enable the device.
		 */

		Control = XSpi_ReadReg(BaseAddress, XSP_CR_OFFSET);
		Control |= XSP_CR_ENABLE_MASK;
		Control &= ~XSP_CR_TRANS_INHIBIT_MASK;
		XSpi_WriteReg(BaseAddress, XSP_CR_OFFSET, Control);


		/*
		 * Wait for the transmit FIFO to transition to empty before checking
		 * the receive FIFO, this prevents a fast processor from seeing the
		 * receive FIFO as empty
		 */
		while (!(XSpi_ReadReg(BaseAddress, XSP_SR_OFFSET) &
						XSP_SR_TX_EMPTY_MASK));
		for(i=0;i<200;i++){}// Manual delay not to lose data.
		/*
		 * Transmitter is full, now receive the data just looped back until
		 * the receiver is empty.
		 */
		while ((XSpi_ReadReg(BaseAddress, XSP_SR_OFFSET) &
				XSP_SR_RX_EMPTY_MASK) == 0) {
			Xil_Out16(0x00100000+(2*NumBytesRcvd++), XSpi_ReadReg((BaseAddress),XSP_DRR_OFFSET));
		}

		XSpi_WriteReg(BaseAddress,XSP_SSR_OFFSET,0x1);//ss


		for (i=0;i<1000;i++){

		}

	}

	printf("NumBytesRcvd: %d\n", NumBytesRcvd);
	return NumBytesRcvd;
}

 

The only parameter I changed was 'numRead' in XSpi_LowLevelExample(u32 BaseAddress) function. It worked fine with 100 but if I increase it to 200 SDK hung.

I alse ran debug to see which part causes the issue. The interesting thing is that the hanging point changed depending on 'numRead'. When I put 300, it was hanging at 

Xil_In16

parts which is after the SPI control. But if I increase 'numRead' it hung in the middle of SPI control and even before SPI control if I increase it to very large number.

By the way 'hang' doesn't mean a complete stop. When I was debugging it in SDK the hanging points took extremely long time(about a minute) at the hanging points and moved to the next lines. 

 

I wonder why this kind of issue happens and how to fix it.  Any suggestion will be appreciated.

 

Thanks in advance.

0 Kudos
1 Solution

Accepted Solutions
Contributor
Contributor
544 Views
Registered: ‎09-13-2016

Re: SDK hangs when run code with large number integer.

Jump to solution
Issue solved by using later DDR addresses.
0 Kudos
2 Replies
Contributor
Contributor
531 Views
Registered: ‎09-13-2016

Re: SDK hangs when run code with large number integer.

Jump to solution

SDK registers shows like this when it hangs.

 

Capture.PNG

0 Kudos
Contributor
Contributor
545 Views
Registered: ‎09-13-2016

Re: SDK hangs when run code with large number integer.

Jump to solution
Issue solved by using later DDR addresses.
0 Kudos