Example #1
0
/**
*
* Runs a self-test on the driver/device. The self-test is destructive in that
* a reset of the device is performed in order to check the reset values of
* the registers and to get the device into a known state. A simple loopback
* test is also performed to verify that transmit and receive are working
* properly. The device is changed to master mode for the loopback test, since
* only a master can initiate a data transfer.
*
* Upon successful return from the self-test, the device is reset.
*
* @param	InstancePtr is a pointer to the XSpi instance to be worked on.
*
* @return
* 		- XST_SUCCESS if successful.
*		- XST_REGISTER_ERROR indicates a register did not read or write
*		  correctly.
* 		- XST_LOOPBACK_ERROR if a loopback error occurred.
*
* @note		None.
*
******************************************************************************/
int XSpi_SelfTest(XSpi *InstancePtr)
{
	int Result;
	u32 Register;

	Xil_AssertNonvoid(InstancePtr != NULL);
	Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);


	/* Return Success if XIP Mode */
	if((InstancePtr->XipMode) == 1) {
		return XST_SUCCESS;
	}

	/*
	 * Reset the SPI device to leave it in a known good state.
	 */
	XSpi_Reset(InstancePtr);

	if(InstancePtr->XipMode)
	{
		Register = XSpi_GetControlReg(InstancePtr);
		if (Register != XSP_CR_RESET_STATE) {
			return XST_REGISTER_ERROR;
		}

		Register = XSpi_GetStatusReg(InstancePtr);
		if ((Register & XSP_SR_RESET_STATE) != XSP_SR_RESET_STATE) {
			return XST_REGISTER_ERROR;
		}
	}




	/*
	 * All the SPI registers should be in their default state right now.
	 */
	Register = XSpi_GetControlReg(InstancePtr);
	if (Register != XSP_CR_RESET_STATE) {
		return XST_REGISTER_ERROR;
	}

	Register = XSpi_GetStatusReg(InstancePtr);
	if ((Register & XSP_SR_RESET_STATE) != XSP_SR_RESET_STATE) {
		return XST_REGISTER_ERROR;
	}

	/*
	 * Each supported slave select bit should be set to 1.
	 */
	Register = XSpi_GetSlaveSelectReg(InstancePtr);
	if (Register != InstancePtr->SlaveSelectMask) {
		return XST_REGISTER_ERROR;
	}

	/*
	 * If configured with FIFOs, the occupancy values should be 0.
	 */
	if (InstancePtr->HasFifos) {
		Register = XSpi_ReadReg(InstancePtr->BaseAddr,
					 XSP_TFO_OFFSET);
		if (Register != 0) {
			return XST_REGISTER_ERROR;
		}
		Register = XSpi_ReadReg(InstancePtr->BaseAddr,
					 XSP_RFO_OFFSET);
		if (Register != 0) {
			return XST_REGISTER_ERROR;
		}
	}

	/*
	 * Run loopback test only in case of standard SPI mode.
	 */
	if (InstancePtr->SpiMode != XSP_STANDARD_MODE) {
		return XST_SUCCESS;
	}

	/*
	 * Run an internal loopback test on the SPI.
	 */
	Result = LoopbackTest(InstancePtr);
	if (Result != XST_SUCCESS) {
		return Result;
	}

	/*
	 * Reset the SPI device to leave it in a known good state.
	 */
	XSpi_Reset(InstancePtr);

	return XST_SUCCESS;
}
Example #2
0
/*
 * Change LO frequency in integer mode
 * frequency must be multiple of 40 (MHz)
 */
int trf3795changeFreqInt(XSpi *InstancePtr, u32 freq)
{
	u32 StatusReg;
	u32 ControlReg;
	u32 Index;
	u32 Delay;
	u32 Data;
	u32 NumSent = 0;
	u32 NumRecvd = 0;
	u32 RxData[] = {0,0,0};
	u32 reg1Val, reg2Val, reg6Val;
	u8  DataWidth;
	u8  j;
	int ctr;
    
    u8 loDivSel, loDiv;
    u8 pllDiv;
    u8 pllDivSel;
    u8 prscSel;
    u16 rDiv;
    u16 nInt;

    // Calculate parameter and register values
    
    freq = freq/2; // Output frequency is doubled
	if(freq>2400)
	{
		loDiv = 1;
		loDivSel = 0;

	}
	else if(freq>1200)
	{
		loDiv = 2;
		loDivSel = 1;

	}
	else if(freq>600)
	{
		loDiv = 4;
		loDivSel = 2;

	}
	else if(freq>300)
	{
		loDiv = 8;
		loDivSel = 3;

	}
    pllDiv = (u8)ceil((double)loDiv*freq/3000.0);
    //xil_printf("Pll Div %d\r\n", pllDiv);
    rDiv = 1;
    nInt = (u16)(loDiv*freq*rDiv/(10*pllDiv));
    
    if(pllDiv==1)
        pllDivSel = 0;
    else if(pllDiv==2)
        pllDivSel = 1;
    else if(pllDiv==4)
        pllDivSel = 2;    
    else
    {
        xil_printf("Invalid PLL_DIV!\r\n");
        return XST_FAILURE;
        
    }
    
    if(nInt>=72)
        prscSel = 1;
    else
        prscSel = 0;

    //xil_printf("NInt %d\r\n", nInt);
    //xil_printf("prscSel %d\r\n", prscSel);
    //xil_printf("loDiv %d\r\n", loDiv);
    
    reg1Val = XSP_REG1_WRITE_CF + (rDiv<<5);
    reg2Val = XSP_REG2_WRITE_CF + (nInt<<5) + (pllDivSel<<21) + (prscSel<<23);
    reg6Val = XSP_REG6_WRITE_CF + (loDivSel<<23);
    u32 write_trf_register[] = {reg1Val,reg6Val,reg2Val};
    u32 reg_list = {1,2,6};
    
    //xil_printf("reg1: %x", reg1Val);
    //xil_printf("reg2: %x", reg2Val);
    //xil_printf("reg6: %x", reg6Val);


    
    /*
	 * Setup the control reogister to enable master mode and
	 * to send least significant bit 1st
	 */
    
	ControlReg = XSpi_GetControlReg(InstancePtr);
	XSpi_SetControlReg(InstancePtr, ControlReg | XSP_CR_MASTER_MODE_MASK |
						XSP_CR_LSB_FIRST);

	//xil_printf("ctrl reg setup done\r\n");

	/*
	 * Set the slave select zero bit to active - low
	 */
//	XSpi_SetSlaveSelectReg(InstancePtr, 0xFFFE);

	/*
	 * We do not need interrupts for now
	 */
	XSpi_IntrGlobalDisable(InstancePtr);

	DataWidth = InstancePtr->DataWidth;

	/*****************************************************************************/

	/*
	 * perform a write to a TRF3765 register
	 */

	for (Index = 0; Index < 3; Index++) {	// for loop write to three registers
		Data = 0;
		xil_printf("start transfer %d\r\n", Index);
		/*
		 * Fill the transmit register.
		 */
		StatusReg = XSpi_GetStatusReg(InstancePtr);
		//xil_printf("got status reg\r\n");
//		while ((StatusReg & XSP_SR_TX_FULL_MASK) == 0) {	// no loop, do just a single transfer for now
			if (DataWidth == XSP_DATAWIDTH_BYTE) {
				/*
				 * Data Transfer Width is Byte (8 bit).
				 */
				Data = 0;
			} else if (DataWidth == XSP_DATAWIDTH_HALF_WORD) {
				/*
				 * Data Transfer Width is Half Word (16 bit).
				 */
				Data = XSP_HALF_WORD_TESTBYTE;
			} else if (DataWidth == XSP_DATAWIDTH_WORD){
				/*
				 * Data Transfer Width is Word (32 bit).
				 */
				Data = write_trf_register[Index];	// choose the register index 0 to 7 ************
				//xil_printf("selected register \r\n");
			}

			XSpi_WriteReg(InstancePtr->BaseAddr, XSP_DTR_OFFSET, Data);
			//xil_printf("wrote data \r\n");
			NumSent += (DataWidth >> 3);
			//xil_printf("Numsent %d\r\n", NumSent);
			StatusReg = XSpi_GetStatusReg(InstancePtr);
			//xil_printf("status reg %d \r\n", StatusReg);
//		}

		/*
		 * Start the transfer by not inhibiting the transmitter and
		 * enabling the device.
		 */
		ControlReg = XSpi_GetControlReg(InstancePtr) &
						 (~XSP_CR_TRANS_INHIBIT_MASK);
		XSpi_SetControlReg(InstancePtr, ControlReg |
				    XSP_CR_ENABLE_MASK);

		/*
		 * Wait for the transfer to be done by polling the transmit
		 * empty status bit.
		 */
		//xil_printf("start for loop\r\n");
		//xil_printf("status reg %d\r\n", XSpi_IntrGetStatus(InstancePtr));
		ctr = 0;
		do {
			StatusReg = XSpi_IntrGetStatus(InstancePtr);
			if(ctr > SPI_TIMEOUT)
				break;
			ctr++;
		} while ((StatusReg & XSP_INTR_TX_EMPTY_MASK) == 0);

		//xil_printf("done with while loop \r\n");

		XSpi_IntrClear(InstancePtr, XSP_INTR_TX_EMPTY_MASK);

		/*
		* To create a latch enable pulse and extra read clock pulse,
		* set the slave select one SS(1) bit low
		*/
		XSpi_SetSlaveSelectReg(InstancePtr, 0xFFFD); // creates read pulse and clock
		for (Delay = 0; Delay < 10; Delay++)	// more delay makes wider pulses
		{}
		XSpi_SetSlaveSelectReg(InstancePtr, 0xFFFF); // removes read pulse and clock


	/*
	* To create a latch enable pulse,
	* set the slave select one SS(0) bit low
	*/
//	XSpi_SetSlaveSelectReg(InstancePtr, 0xFFFE); // drives the latch enable
//	for (Delay = 0; Delay < 10; Delay++)	// more delay makes pulse wider
//	{}
//	XSpi_SetSlaveSelectReg(InstancePtr, 0xFFFF); // removes the latch enable

		/*
		 * Stop the transfer (hold off automatic sending) by inhibiting
		 * the transmitter and disabling the device.
		 */
		ControlReg |= XSP_CR_TRANS_INHIBIT_MASK;
		XSpi_SetControlReg(InstancePtr ,
				    ControlReg & ~ XSP_CR_ENABLE_MASK);

		//xil_printf("Done transfer %d\r\n", Index);
 
    }

	XSpi_Reset(InstancePtr);


	return XST_SUCCESS;

}    
Example #3
0
/**
*
* Runs a self-test on the driver/device. The self-test is destructive in that
* a reset of the device is performed in order to check the reset values of
* the registers and to get the device into a known state. A simple loopback
* test is also performed to verify that transmit and receive are working
* properly. The device is changed to master mode for the loopback test, since
* only a master can initiate a data transfer.
*
* Upon successful return from the self-test, the device is reset.
*
* @param	InstancePtr is a pointer to the XSpi instance to be worked on.
*
* @return
* 		- XST_SUCCESS if successful.
*		- XST_REGISTER_ERROR indicates a register did not read or write
*		  correctly.
* 		- XST_LOOPBACK_ERROR if a loopback error occurred.
*
* @note		None.
*
******************************************************************************/
int TrfXSpiSetup(XSpi *InstancePtr)
{
	int Result;
//	u32 Register;

	Xil_AssertNonvoid(InstancePtr != NULL);
	Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);

	/*
	 * Reset the SPI device to leave it in a known good state.
	 */
//	XSpi_Reset(InstancePtr);
//
//	if(InstancePtr->XipMode)
//	{
//		Register = XSpi_GetControlReg(InstancePtr);
//		if (Register != XSP_CR_RESET_STATE) {
//			return XST_REGISTER_ERROR;
//		}
//
//		Register = XSpi_GetStatusReg(InstancePtr);
//		if ((Register & XSP_SR_RESET_STATE) != XSP_SR_RESET_STATE) {
//			return XST_REGISTER_ERROR;
//		}
//	}
//
//	/*
//	 * All the SPI registers should be in their default state right now.
//	 */
//	Register = XSpi_GetControlReg(InstancePtr);
//	if (Register != XSP_CR_RESET_STATE) {
//		return XST_REGISTER_ERROR;
//	}
//
//	Register = XSpi_GetStatusReg(InstancePtr);
//	if ((Register & XSP_SR_RESET_STATE) != XSP_SR_RESET_STATE) {
//		return XST_REGISTER_ERROR;
//	}
//
//	/*
//	 * Each supported slave select bit should be set to 1.
//	 */
//	Register = XSpi_GetSlaveSelectReg(InstancePtr);
//	if (Register != InstancePtr->SlaveSelectMask) {
//		return XST_REGISTER_ERROR;
//	}
//
//	/*
//	 * If configured with FIFOs, the occupancy values should be 0.
//	 */
//	if (InstancePtr->HasFifos) {
//		Register = XSpi_ReadReg(InstancePtr->BaseAddr,
//					 XSP_TFO_OFFSET);
//		if (Register != 0) {
//			return XST_REGISTER_ERROR;
//		}
//		Register = XSpi_ReadReg(InstancePtr->BaseAddr,
//					 XSP_RFO_OFFSET);
//		if (Register != 0) {
//			return XST_REGISTER_ERROR;
//		}
//	}
//
//	/*
//	 * Run loopback test only in case of standard SPI mode.
//	 */
//	if (InstancePtr->SpiMode != XSP_STANDARD_MODE) {
//		return XST_SUCCESS;
//	}

	/*
	 * Run write and read on the SPI attached to RF LO.
	 */
	Result = trf3795WriteAndRead(InstancePtr);
	if (Result != XST_SUCCESS) {
		return Result;
	}

	/*
	 * Reset the SPI device to leave it in a known good state.
	 */
	XSpi_Reset(InstancePtr);

	return XST_SUCCESS;
}
Example #4
0
/*
 * Enables the fractional mode of the LO
 * LO must be initialized first
 */
int trf3795EnableInt(XSpi *InstancePtr)
{
	u32 StatusReg;
	u32 ControlReg;
	u32 Index;
	u32 Delay;
	u32 Data;
	u32 NumSent = 0;
	u32 NumRecvd = 0;
	u32 RxData[] = {0,0,0};
	u8  DataWidth;
	u8  j;
	int ctr;
	u32 write_trf_register[] = {XSP_REG0_WRITE,XSP_REG1_WRITE,XSP_REG2_WRITE,XSP_REG3_WRITE,
							 XSP_REG4_WRITE,XSP_REG5_WRITE,XSP_REG6_WRITE,XSP_REG7_WRITE};


	/*
	 * Setup the control reogister to enable master mode and
	 * to send least significant bit 1st
	 */
	ControlReg = XSpi_GetControlReg(InstancePtr);
	XSpi_SetControlReg(InstancePtr, ControlReg | XSP_CR_MASTER_MODE_MASK |
						XSP_CR_LSB_FIRST);

	/*
	 * Set the slave select zero bit to active - low
	 */
//	XSpi_SetSlaveSelectReg(InstancePtr, 0xFFFE);

	/*
	 * We do not need interrupts for now
	 */
	XSpi_IntrGlobalDisable(InstancePtr);

	DataWidth = InstancePtr->DataWidth;

	/*****************************************************************************/

	/*
	 * perform a write to a TRF3765 register
	 */

	for (Index = 0; Index < 8; Index++) {	// for loop write to all eight registers
		Data = 0;

		/*
		 * Fill the transmit register.
		 */
		StatusReg = XSpi_GetStatusReg(InstancePtr);
//		while ((StatusReg & XSP_SR_TX_FULL_MASK) == 0) {	// no loop, do just a single transfer for now
			if (DataWidth == XSP_DATAWIDTH_BYTE) {
				/*
				 * Data Transfer Width is Byte (8 bit).
				 */
				Data = 0;
			} else if (DataWidth == XSP_DATAWIDTH_HALF_WORD) {
				/*
				 * Data Transfer Width is Half Word (16 bit).
				 */
				Data = XSP_HALF_WORD_TESTBYTE;
			} else if (DataWidth == XSP_DATAWIDTH_WORD){
				/*
				 * Data Transfer Width is Word (32 bit).
				 */
				Data = write_trf_register[Index];	// choose the register index 0 to 7 ************
			}

			XSpi_WriteReg(InstancePtr->BaseAddr, XSP_DTR_OFFSET, Data);
			NumSent += (DataWidth >> 3);
			StatusReg = XSpi_GetStatusReg(InstancePtr);
//		}

		/*
		 * Start the transfer by not inhibiting the transmitter and
		 * enabling the device.
		 */
		ControlReg = XSpi_GetControlReg(InstancePtr) &
						 (~XSP_CR_TRANS_INHIBIT_MASK);
		XSpi_SetControlReg(InstancePtr, ControlReg |
				    XSP_CR_ENABLE_MASK);

		/*
		 * Wait for the transfer to be done by polling the transmit
		 * empty status bit.
		 */
		do {
			StatusReg = XSpi_IntrGetStatus(InstancePtr);
			if(ctr > SPI_TIMEOUT)
				break;
			ctr++;
		} while ((StatusReg & XSP_INTR_TX_EMPTY_MASK) == 0);

		XSpi_IntrClear(InstancePtr, XSP_INTR_TX_EMPTY_MASK);

		/*
		* To create a latch enable pulse and extra read clock pulse,
		* set the slave select one SS(1) bit low
		*/
		XSpi_SetSlaveSelectReg(InstancePtr, 0xFFFD); // creates read pulse and clock
		for (Delay = 0; Delay < 10; Delay++)	// more delay makes wider pulses
		{}
		XSpi_SetSlaveSelectReg(InstancePtr, 0xFFFF); // removes read pulse and clock


	/*
	* To create a latch enable pulse,
	* set the slave select one SS(0) bit low
	*/
//	XSpi_SetSlaveSelectReg(InstancePtr, 0xFFFE); // drives the latch enable
//	for (Delay = 0; Delay < 10; Delay++)	// more delay makes pulse wider
//	{}
//	XSpi_SetSlaveSelectReg(InstancePtr, 0xFFFF); // removes the latch enable

		/*
		 * Stop the transfer (hold off automatic sending) by inhibiting
		 * the transmitter and disabling the device.
		 */
		ControlReg |= XSP_CR_TRANS_INHIBIT_MASK;
		XSpi_SetControlReg(InstancePtr ,
				    ControlReg & ~ XSP_CR_ENABLE_MASK);

    }

	XSpi_Reset(InstancePtr);
	return XST_SUCCESS;


}
Example #5
0
/**
*
* Initializes a specific XSpi instance such that the driver is ready to use.
*
* The state of the device after initialization is:
*	- Device is disabled
*	- Slave mode
*	- Active high clock polarity
*	- Clock phase 0
*
* @param	InstancePtr is a pointer to the XSpi instance to be worked on.
* @param	Config is a reference to a structure containing information
*		about a specific SPI device. This function initializes an
*		InstancePtr object for a specific device specified by the
*		contents of Config. This function can initialize multiple
*		instance objects with the use of multiple calls giving different
*		Config information on each call.
* @param	EffectiveAddr is the device base address in the virtual memory
*		address space. The caller is responsible for keeping the address
*		mapping from EffectiveAddr to the device physical base address
*		unchanged once this function is invoked. Unexpected errors may
*		occur if the address mapping changes after this function is
*		called. If address translation is not used, use
*		Config->BaseAddress for this parameters, passing the physical
*		address instead.
*
* @return
*		- XST_SUCCESS if successful.
*		- XST_DEVICE_IS_STARTED if the device is started. It must be
*		  stopped to re-initialize.
*
* @note		None.
*
******************************************************************************/
int XSpi_CfgInitialize(XSpi *InstancePtr, XSpi_Config *Config,
			u32 EffectiveAddr)
{
	Xil_AssertNonvoid(InstancePtr != NULL);

	/*
	 * If the device is started, disallow the initialize and return a status
	 * indicating it is started.  This allows the user to stop the device
	 * and reinitialize, but prevents a user from inadvertently
	 * initializing.
	 */
	if (InstancePtr->IsStarted == XIL_COMPONENT_IS_STARTED) {
		return XST_DEVICE_IS_STARTED;
	}

	/*
	 * Set some default values.
	 */
	InstancePtr->IsStarted = 0;
	InstancePtr->IsBusy = FALSE;

	InstancePtr->StatusHandler = StubStatusHandler;

	InstancePtr->SendBufferPtr = NULL;
	InstancePtr->RecvBufferPtr = NULL;
	InstancePtr->RequestedBytes = 0;
	InstancePtr->RemainingBytes = 0;

	InstancePtr->BaseAddr = EffectiveAddr;
	InstancePtr->HasFifos = Config->HasFifos;
	InstancePtr->SlaveOnly = Config->SlaveOnly;
	InstancePtr->NumSlaveBits = Config->NumSlaveBits;
	if (Config->DataWidth == 0) {
		InstancePtr->DataWidth = XSP_DATAWIDTH_BYTE;
	} else {
		InstancePtr->DataWidth = Config->DataWidth;
	}

	InstancePtr->SpiMode = Config->SpiMode;
	InstancePtr->IsReady = XIL_COMPONENT_IS_READY;

	/*
	 * Create a slave select mask based on the number of bits that can
	 * be used to deselect all slaves, initialize the value to put into
	 * the slave select register to this value.
	 */
	InstancePtr->SlaveSelectMask = (1 << InstancePtr->NumSlaveBits) - 1;
	InstancePtr->SlaveSelectReg = InstancePtr->SlaveSelectMask;

	/*
	 * Clear the statistics for this driver.
	 */
	InstancePtr->Stats.ModeFaults = 0;
	InstancePtr->Stats.XmitUnderruns = 0;
	InstancePtr->Stats.RecvOverruns = 0;
	InstancePtr->Stats.SlaveModeFaults = 0;
	InstancePtr->Stats.BytesTransferred = 0;
	InstancePtr->Stats.NumInterrupts = 0;

	/*
	 * Reset the SPI device to get it into its initial state. It is expected
	 * that device configuration will take place after this initialization
	 * is done, but before the device is started.
	 */
	XSpi_Reset(InstancePtr);

	return XST_SUCCESS;
}