TA的每日心情 | 开心 2017-1-11 04:03 |
---|
签到天数: 3 天 连续签到: 1 天 [LV.2]偶尔看看I
|
前言
承接上篇的2 写这个目的是就是分享过程。我觉得我自身的效率还是很差劲。
现在记录软件部分。杂谈
开始
首先创建一个BSP吧
这么创建能够设置BSP
设置完
打开这里看看
然后就有他
我看了 5分钟
熟悉一下GPIO然后等会要写NAV.H的文件。
然后同样 继续打开了SPI的这个网页说明文件。看了半天
就算是该,先看看示例代码吧。
创建个工程
选这个
然后选这个 工程
然后finish 发现 工程没有任何问题
然后继续 浏览代码5分钟
先看看GPIO的基本使用吧
/***************************** Include Files *********************************/#include "xparameters.h"#include "xgpio.h"/************************** Constant Definitions *****************************/#define LED 0x01 /* Assumes bit 0 of GPIO is connected to an LED *//* * The following constant maps to the name of the hardware instances that * were created in the EDK XPS system. */#define GPIO_EXAMPLE_DEVICE_ID XPAR_LEDS_POSITIONS_DEVICE_ID/* * The following constant is used to wait after an LED is turned on to make * sure that it is visible to the human eye. This constant might need to be * tuned for faster or slower processor speeds. */#define LED_DELAY 1000000/* * The following constant is used to determine which channel of the GPIO is * used for the LED if there are 2 channels supported. */#define LED_CHANNEL 1/**************************** Type Definitions *******************************//***************** Macros (Inline Functions) Definitions *********************/#ifdef PRE_2_00A_APPLICATION/* * The following macros are provided to allow an application to compile that * uses an older version of the driver (pre 2.00a) which did not have a channel * parameter. Note that the channel parameter is fixed as channel 1. */#define XGpio_SetDataDirection(InstancePtr, DirectionMask) \ XGpio_SetDataDirection(InstancePtr, LED_CHANNEL, DirectionMask)#define XGpio_DiscreteRead(InstancePtr) \ XGpio_DiscreteRead(InstancePtr, LED_CHANNEL)#define XGpio_DiscreteWrite(InstancePtr, Mask) \ XGpio_DiscreteWrite(InstancePtr, LED_CHANNEL, Mask)#define XGpio_DiscreteSet(InstancePtr, Mask) \ XGpio_DiscreteSet(InstancePtr, LED_CHANNEL, Mask)#endif/************************** Function Prototypes ******************************//************************** Variable Definitions *****************************//* * The following are declared globally so they are zeroed and so they are * easily accessible from a debugger */XGpio Gpio; /* The Instance of the GPIO Driver *//*****************************************************************************//**** The purpose of this function is to illustrate how to use the GPIO level 1* driver to turn on and off an LED.** @param None** @return XST_FAILURE to indicate that the GPIO Intialisation had failed.** @note This function will not return if the test is running.*******************************************************************************/int main(void){ u32 Data; int Status; volatile int Delay; /* * Initialize the GPIO driver */ Status = XGpio_Initialize(&Gpio, GPIO_EXAMPLE_DEVICE_ID); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Set the direction for all signals to be inputs except the * LED output */ XGpio_SetDataDirection(&Gpio, LED_CHANNEL, ~LED); /* Loop forever blinking the LED */ while (1) { /* * Read the state of the data so that only the LED state can be * modified */ Data = XGpio_DiscreteRead(&Gpio, LED_CHANNEL); /* * Set the LED to the opposite state such that it blinks using * the first method, two methods are used for illustration * purposes only */ if (Data & LED) { XGpio_DiscreteWrite(&Gpio, LED_CHANNEL, Data & ~LED); } else { XGpio_DiscreteWrite(&Gpio, LED_CHANNEL, Data | LED); } /* Wait a small amount of time so the LED is visible */ for (Delay = 0; Delay < LED_DELAY; Delay++); /* * Read the state of the data so that only the LED state can be * modified */ Data = XGpio_DiscreteRead(&Gpio, LED_CHANNEL); /* * Set the LED to the opposite state such that it blinks using * the other API functions */ if (Data & LED) { XGpio_DiscreteClear(&Gpio, LED_CHANNEL, LED); } else { XGpio_DiscreteSet(&Gpio, LED_CHANNEL, LED); } /* Wait a small amount of time so the LED is visible */ for (Delay = 0; Delay < LED_DELAY; Delay++); } return XST_SUCCESS;}再看看SPI吧
/***************************** Include Files *********************************/#include "xparameters.h" /* XPAR parameters */#include "xspi.h" /* SPI device driver */#include "xspi_l.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_DEVICE_ID XPAR_SPI_0_DEVICE_ID/* * This is the size of the buffer to be transmitted/received in this example. */#define BUFFER_SIZE 12/**************************** Type Definitions *******************************//* * The following data type is used to send and receive data on the SPI * interface. */typedef u8 DataBuffer[BUFFER_SIZE];/***************** Macros (Inline Functions) Definitions *********************//************************** Function Prototypes ******************************/int SpiPolledExample(XSpi *SpiInstancePtr, u16 SpiDeviceId);/************************** Variable Definitions *****************************//* * The instances to support the device drivers are global such that the * are initialized to zero each time the program runs. */static XSpi SpiInstance; /* The instance of the SPI device *//* * The following variables are used to read and write to the Spi device, they * are global to avoid having large buffers on the stack. */u8 ReadBuffer[BUFFER_SIZE];u8 WriteBuffer[BUFFER_SIZE];/*****************************************************************************//**** Main function to call the Spi Polled example.** @param None** @return XST_SUCCESS if successful, otherwise XST_FAILURE.** @note None*******************************************************************************/int main(void){ int Status; /* * Run the Spi Polled example. */ Status = SpiPolledExample(&SpiInstance, SPI_DEVICE_ID); if (Status != XST_SUCCESS) { return XST_FAILURE; } return XST_SUCCESS;}/*****************************************************************************//**** This function does a minimal test on the Spi device and driver as a* design example. The purpose of this function is to illustrate how to use* the XSpi component using the polled mode.** This function sends data and expects to receive the same data.*** @param SpiInstancePtr is a pointer to the instance of Spi component.* @param SpiDeviceId is the Device ID of the Spi Device and is the* XPAR_<SPI_instance>_DEVICE_ID value from xparameters.h.** @return XST_SUCCESS if successful, otherwise XST_FAILURE.** @note** This function contains an infinite loop such that if the Spi device is not* working it may never return.*******************************************************************************/int SpiPolledExample(XSpi *SpiInstancePtr, u16 SpiDeviceId){ int Status; u32 Count; u8 Test; XSpi_Config *ConfigPtr; /* Pointer to Configuration data */ /* * Initialize the SPI driver so that it is ready to use. */ ConfigPtr = XSpi_LookupConfig(SpiDeviceId); if (ConfigPtr == NULL) { return XST_DEVICE_NOT_FOUND; } Status = XSpi_CfgInitialize(SpiInstancePtr, ConfigPtr, ConfigPtr->BaseAddress); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Perform a self-test to ensure that the hardware was built correctly. */ Status = XSpi_SelfTest(SpiInstancePtr); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Run loopback test only in case of standard SPI mode. */ if (SpiInstancePtr->SpiMode != XSP_STANDARD_MODE) { return XST_SUCCESS; } /* * Set the Spi device as a master and in loopback mode. */ Status = XSpi_SetOptions(SpiInstancePtr, XSP_MASTER_OPTION | XSP_LOOPBACK_OPTION); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Start the SPI driver so that the device is enabled. */ XSpi_Start(SpiInstancePtr); /* * Disable Global interrupt to use polled mode operation */ XSpi_IntrGlobalDisable(SpiInstancePtr); /* * Initialize the write buffer with pattern to write, initialize the * read buffer to zero so it can be verified after the read, the * Test value that is added to the unique value allows the value to be * changed in a debug environment. */ Test = 0x10; for (Count = 0; Count < BUFFER_SIZE; Count++) { WriteBuffer[Count] = (u8)(Count + Test); ReadBuffer[Count] = 0; } /* * Transmit the data. */ XSpi_Transfer(SpiInstancePtr, WriteBuffer, ReadBuffer, BUFFER_SIZE); /* * Compare the data received with the data that was transmitted. */ for (Count = 0; Count < BUFFER_SIZE; Count++) { if (WriteBuffer[Count] != ReadBuffer[Count]) { return XST_FAILURE; } } return XST_SUCCESS;}这里有一些坑。就是这里 SPI工作模式使用的是LOOP模式。就是没有跟外部的chip通信。
所以要配置工作模式,配置SPI的寄存器。这个寄存器简单的low_level实现就是xil_regout(addr,reg_value);
要么就是使用xspi.h提供的函数,这算不上什么难度了。
使用这个
XSpi_SetOptions(&my_spi, XSP_MASTER_OPTION|XSP_MANUAL_SSELECT_OPTION|XSP_CLK_ACTIVE_LOW_OPTION|XSP_CLK_PHASE_1_OPTION);如果不这么配置的话,IP处于未知的状态。或者是使用在edk或者vivado中配置好的ip设置,这么做,要很熟悉这个qspi flash 的 ip。
还有就是
status =XSpi_SetSlaveSelect(&my_spi,0x01);这里一定要设置这个ss端口。即使你可能不会用到。(在使用xspi.h函数通信的情况下。使用low_level配置reg可以忽略)我就是在这里坑的, debug的时候发现的。
XSpi_IntrGlobalDisable(SpiInstancePtr); 还有这个。一般情况下,使用它spi的中断,我没有使用中断模式。我使用的polled模式、
因此要关闭。
最后初始化完成后。
XSpi_Start(SpiInstancePtr);这句也坑重要。
结语
。。。
整个过程中debug中有几个点。一是fpga在第一次下载download.bit后 debug mdm时候,第二次重新debug时候,这是后进行spi gpio的初始化会失败。
因为xspi.h的函数会检查spi是否启动。在第一次debug的时候,已经startspi一次了。所以这时候reset最好。
历史
v 0.1 2017.2.6创建
v 0.2 2017.2.8 修改代码license信息
v 0.3 20.17.2.9 修改结语 |
|