/** * * 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; }
/* * 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; }
/** * * 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; }
/* * 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; }
/** * * 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; }