赞
踩
api
XScuTimer Timer; //定时器驱动
XScuTimer_Config *timer_cfg_ptr; //定时器的配置
XScuTimer_LookupConfig(XPAR_XSCUTIMER_0_DEVICE_ID); //定时器查找表
XScuTimer_CfgInitialize(timer_ptr, timer_cfg_ptr, timer_cfg_ptr->BaseAddr); //定时器初始化
XScuTimer_LoadTimer(timer_ptr, TIMER_LOAD_VALUE); //加载计数周期,频率为CPU时钟频率(666MHz)一半大小
XScuTimer_EnableAutoReload(timer_ptr); //设置自动装载模式,从而循环来产生定时器
XScuTimer_EnableInterrupt(timer_ptr); //使能定时器中断
XScuTimer_Start(&Timer); //启动定时器
XScuTimer_ClearInterruptStatus(timer_ptr); //清除定时器中断标志
中断处理函数
- //初始化中断控制器
- XScuGic_Config *intc_cfg_ptr;
- intc_cfg_ptr = XScuGic_LookupConfig(INTC_DEVICE_ID);
- XScuGic_CfgInitialize(intc_ptr, intc_cfg_ptr, intc_cfg_ptr->CpuBaseAddress);
-
- //设置并打开中断异常功能
- Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT, (Xil_ExceptionHandler)XScuGic_InterruptHandler, intc_ptr);
- Xil_ExceptionEnable();
-
- //设置定时器中断,TIMER_IRPT_INTR是定时器中断ID
- XScuGic_Connect(intc_ptr, TIMER_IRPT_INTR, (Xil_ExceptionHandler)timer_intr_handler,(void*)timer_ptr);
-
- XScuGic_Enable(intc_ptr, TIMER_IRPT_INTR); //使能GIC中的定时器中断
-
- XScuTimer_EnableInterrupt(timer_ptr); //使能定时器中断
下面是全部代码,实现了一个每200ms的PS的LED灯闪烁一次的效果。
- #include "xparameters.h"
- #include "xscutimer.h"
- #include "xscugic.h"
- #include "xgpiops.h"
- #include "xil_exception.h"
- #include "xil_printf.h"
-
- #define TIMER_DEVICE_ID XPAR_XSCUTIMER_0_DEVICE_ID //定时器ID
- #define INTC_DEVICE_ID XPAR_SCUGIC_SINGLE_DEVICE_ID //中断ID
- #define TIMER_IRPT_INTR XPAR_SCUTIMER_INTR //定时器中断ID
- #define GPIO_DEVICE_ID XPAR_XGPIOPS_0_DEVICE_ID //宏定义GPIO_PS ID
- #define MIO_LED 0 //led连接到MIO0
-
- //私有定时器的时钟频率 = CPU时钟频率/2 = 333MHz
- // 0.2s闪烁一次,0.2/1000_000_00/(1000/333) - 1 = 3F83C3F
- #define TIMER_LOAD_VALUE 0x3F83C3F //定时器装载数值
-
- XScuGic Intc; //中断控制器驱动程序实例
- XScuTimer Timer; //定时器驱动程序实例
- XGpioPs Gpio; //GPIO设备的驱动程序实例
-
- //MIO引脚初始化
- int mio_init(XGpioPs *mio_ptr)
- {
- int status;
-
- XGpioPs_Config *mio_cfg_ptr;
- mio_cfg_ptr = XGpioPs_LookupConfig(GPIO_DEVICE_ID);
- if (mio_cfg_ptr == NULL)
- return XST_FAILURE;
- status = XGpioPs_CfgInitialize(mio_ptr, mio_cfg_ptr, mio_cfg_ptr->BaseAddr);
- if (status != XST_SUCCESS)
- return XST_FAILURE;
-
- //设置指定引脚的方向 0是输入,1是输出
- XGpioPs_SetDirectionPin(&Gpio,MIO_LED, 1);
- //使能指定引脚输出,0 禁止输出使能 1使能输出
- XGpioPs_SetOutputEnablePin(&Gpio, MIO_LED, 1);
- return XST_SUCCESS;
- }
-
- //定时器初始化程序
- int timer_init(XScuTimer *timer_ptr)
- {
- int status;
- //私有定时器初始化
- XScuTimer_Config *timer_cfg_ptr;
- timer_cfg_ptr = XScuTimer_LookupConfig(TIMER_DEVICE_ID);
- if (NULL == timer_cfg_ptr)
- {
- return XST_FAILURE;
- }
- status = XScuTimer_CfgInitialize(timer_ptr, timer_cfg_ptr, timer_cfg_ptr->BaseAddr);\
- if(status != XST_SUCCESS)
- return XST_FAILURE;
-
- XScuTimer_LoadTimer(timer_ptr, TIMER_LOAD_VALUE); //加载计数周期
- XScuTimer_EnableAutoReload(timer_ptr); //设置自动装载模式,从而循环来产生定时器
-
- return XST_SUCCESS;
- }
-
- //定时器中断处理函数
- void timer_intr_handler(void *CallBackRef)
- {
- //LED 状态,用于控制LED灯状态翻转
- static int led_state = 0;
- XScuTimer* timer_ptr = (XScuTimer *)CallBackRef;
- if(led_state == 0)
- led_state = 1;
- else
- led_state = 0;
- //向指定引脚写入数据:0 或者1
- XGpioPs_WritePin(&Gpio, MIO_LED, led_state);
- //清除定时器中断标志
- XScuTimer_ClearInterruptStatus(timer_ptr);
- }
-
- //定时器中断初始化
- void timer_intr_init(XScuGic *intc_ptr, XScuTimer * timer_ptr)
- {
- //初始化中断控制器
- XScuGic_Config *intc_cfg_ptr;
- intc_cfg_ptr = XScuGic_LookupConfig(INTC_DEVICE_ID);
- XScuGic_CfgInitialize(intc_ptr, intc_cfg_ptr, intc_cfg_ptr->CpuBaseAddress);
-
- //设置并打开中断异常功能
- Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT, (Xil_ExceptionHandler)XScuGic_InterruptHandler, intc_ptr);
- Xil_ExceptionEnable();
-
- //设置定时器中断,TIMER_IRPT_INTR是定时器中断ID
- XScuGic_Connect(intc_ptr, TIMER_IRPT_INTR, (Xil_ExceptionHandler)timer_intr_handler,(void*)timer_ptr);
-
- XScuGic_Enable(intc_ptr, TIMER_IRPT_INTR); //使能GIC中的定时器中断
-
- XScuTimer_EnableInterrupt(timer_ptr); //使能定时器中断
- }
-
- int main()
- {
- int status;
- xil_printf("SCU Timer Interrupt Test \r\n");
-
- mio_init(&Gpio); //MIO引脚初始化
- status = timer_init(&Timer); //定时器初始化
- if (status != XST_SUCCESS) {
- xil_printf("Timer Initial Failed \r\n");
- return XST_FAILURE;
- }
- timer_intr_init(&Intc, &Timer); //定时器中断初始化
- XScuTimer_Start(&Timer); //启动定时器
-
- while(1);
- return 0;
- }

ps的xadc可以读取板子上的实时电压以及温度
api
XAdcPs xadc_inst; //XADC实例以及初始化
ConfigPtr = XAdcPs_LookupConfig(XPAR_XADCPS_0_DEVICE_ID);
XAdcPs_CfgInitialize(&xadc_inst, ConfigPtr, ConfigPtr->BaseAddrss);
XAdcPs_SetSequencerMode(&xadc_inst, XADCPS_SEQ_MODE_SAFE); //设置为安全模式
u32 temp_rawdata = XAdcPs_GetAdcData(&xadc_inst, XADCPS_CH_TEMP); //读取原始数据
XAdcPs_RawToVoltage() XAdcPs_RawToTemperature() //原始数据转换为电压(v)以及温度(摄氏度)
下面是全部代码,实现了一个循环5s读取一次XADC上面的电压以及温度信号
- #include "xparameters.h"
- #include "xadcps.h"
- #include "stdio.h"
- #include "xil_printf.h"
- #include "sleep.h"
-
- #define XADC_DEVICE_ID XPAR_XADCPS_0_DEVICE_ID //PS的XADC器件
-
- static XAdcPs xadc_inst;
-
- int main(void)
- {
- XAdcPs_Config *ConfigPtr; //XADC配置指针
-
- //原始数据
- u32 temp_rawdata; //温度
- u32 vcc_pint_rawdata; //ps内核电压
- u32 vcc_paux_rawdata; //ps辅助电压
- u32 vcc_pddr_rawdata; //ps的ddr电压
- u32 vcc_int_rawdata; //pl内核电压
- u32 vcc_aux_rawdata; //pl辅助电压
- u32 vcc_bram_rawdata; //pl的bram电压
-
-
- float temp; //温度
- float vcc_pint; //ps内核电压
- float vcc_paux; //ps辅助电压
- float vcc_pddr; //ps的ddr电压
- float vcc_int; //pl内核电压
- float vcc_aux; //pl辅助电压
- float vcc_bram; //pl的bram电压
-
- //初始化xadc驱动
- ConfigPtr = XAdcPs_LookupConfig(XADC_DEVICE_ID);
- XAdcPs_CfgInitialize(&xadc_inst, ConfigPtr, ConfigPtr->BaseAddrss);
-
- // 设置xadc操作模式为 默认安全模式
- // XADC 会自动监测片上温度和电压传感器的数据,并将结果保存在状态寄存器中,此时 XADC
- // 的操作与其他任何控制寄存器的设置无关
- XAdcPs_SetSequencerMode(&xadc_inst, XADCPS_SEQ_MODE_SAFE);
-
- while(1) {
- //获取原始温度传感器数据
- temp_rawdata = XAdcPs_GetAdcData(&xadc_inst, XADCPS_CH_TEMP);
- //转换成温度信息
- temp = XAdcPs_RawToTemperature(temp_rawdata);
-
- //获取VCCPINT传感器数据
- vcc_pint_rawdata = XAdcPs_GetAdcData(&xadc_inst, XADCPS_CH_VCCPINT);
- vcc_pint = XAdcPs_RawToVoltage(vcc_pint_rawdata);
-
- //获取VCCPAUX传感器数据
- vcc_paux_rawdata = XAdcPs_GetAdcData(&xadc_inst, XADCPS_CH_VCCPAUX);
- vcc_paux = XAdcPs_RawToVoltage(vcc_paux_rawdata);
-
- //获取VCCPDRO传感器数据
- vcc_pddr_rawdata = XAdcPs_GetAdcData(&xadc_inst, XADCPS_CH_VCCPDRO);
- vcc_pddr = XAdcPs_RawToVoltage(vcc_pddr_rawdata);
-
- //获取VCCINT传感器数据
- vcc_int_rawdata = XAdcPs_GetAdcData(&xadc_inst, XADCPS_CH_VCCINT);
- vcc_int = XAdcPs_RawToVoltage(vcc_int_rawdata);
-
- //获取VCCPAUX传感器数据
- vcc_aux_rawdata = XAdcPs_GetAdcData(&xadc_inst, XADCPS_CH_VCCAUX);
- vcc_aux = XAdcPs_RawToVoltage(vcc_aux_rawdata);
-
- //获取VCCPDRO传感器数据
- vcc_bram_rawdata = XAdcPs_GetAdcData(&xadc_inst, XADCPS_CH_VBRAM);
- vcc_bram = XAdcPs_RawToVoltage(vcc_bram_rawdata);
-
- //打印温度、电压信息
- printf("Raw Temp %lu, Real Temp %fC \n", temp_rawdata, temp);
- printf("Raw VccPInt %lu, Real VccPInt %fV \n", vcc_pint_rawdata, vcc_pint);
- printf("Raw VccPAux %lu, Real VccPAux %fV \n", vcc_paux_rawdata, vcc_paux);
- printf("Raw VccPDDR %lu, Real VccPDDR %fV \n", vcc_pddr_rawdata, vcc_pddr);
- printf("Raw VccInt %lu, Real VccInt %fV \n", vcc_int_rawdata, vcc_int);
- printf("Raw VccAux %lu, Real VccAux %fV \n", vcc_aux_rawdata, vcc_aux);
- printf("Raw VccBram %lu, Real VccBram %fV \n\r", vcc_bram_rawdata, vcc_bram);
-
- //延时 5s
- sleep(5);
- }
- }

下面实现了使用XADC读取外界输入的模拟信号转换成的数字信号
- // XADC 模块也集成了模数转换器,可以将外部输入的模拟电压转换成数字
- // 信号,实现通过 PS XADC 接口,读取外部模拟电压信号
-
- // XADC 内部的两块 ADC 分别为 ADC A 与 ADC B, ADC A 是可以接收左侧包括所有片上
- // 传感器(温度温度传感器信息、电源传感器信息)、 VP/VN 模拟电压信息以及 16 路辅助模拟输入的;而
- // ADC B 只能接收 VP/VN 模拟电压信息以及 16 路辅助模拟输入。 VP/VN 与 16 路辅助模拟输入的不同在于
- // VP/VN 是专用的支持差分输入的模拟通道输入引脚,而 16 路辅助模拟输入是模拟数字/数字复用引脚,其
- // 中某个引脚用作模拟输入,该引脚的数字 IO 功能就不可以再使用
-
- // VP/VN单端输入时候电压范围为0-1.0v, 如果是双端输入时电压范围则是-0.5v-0.5v的范围内
-
- #include "xparameters.h"
- #include "xadcps.h"
- #include "stdio.h"
- #include "xil_printf.h"
- #include "sleep.h"
-
- #define XADC_DEVICE_ID XPAR_XADCPS_0_DEVICE_ID //PS的XADC器件
-
- static XAdcPs xadc_inst;
-
- int main(void)
- {
- XAdcPs_Config *ConfigPtr; //XADC配置指针
-
- //原始数据
- u32 vcc_vpvn_rawdata; //VpVn原始数据
-
- float vcc_vpvn; //vpvn电压
-
- //初始化xadc驱动
- ConfigPtr = XAdcPs_LookupConfig(XADC_DEVICE_ID);
- XAdcPs_CfgInitialize(&xadc_inst, ConfigPtr, ConfigPtr->BaseAddress);
-
- // 设置xadc操作模式为 默认安全模式
- // XADC 会自动监测片上温度和电压传感器的数据,并将结果保存在状态寄存器中,此时 XADC
- // 的操作与其他任何控制寄存器的设置无关
- XAdcPs_SetSequencerMode(&xadc_inst, XADCPS_SEQ_MODE_SAFE);
- // 使能相应的通道
- XAdcPs_SetSeqChEnables(&xadc_inst, XADCPS_SEQ_CH_VPVN);
-
- //设置为循环模式
- XAdcPs_SetSequencerMode(&xadc_inst, XADCPS_SEQ_MODE_CONTINPASS);
-
- while(1) {
- //获取原始温度传感器数据
- vcc_vpvn_rawdata = XAdcPs_GetAdcData(&xadc_inst, XADCPS_CH_VPVN);
- //转换成温度信息
- vcc_vpvn = XAdcPs_RawToVoltage(vcc_vpvn_rawdata)/3;
-
- //打印温度、电压信息
- printf("Raw vpvn %lu, Real vpvn %fv \n", vcc_vpvn_rawdata, vcc_vpvn);
-
- //延时 1s
- sleep(1);
- }
- }

下面实现了QSPI的读写测试
- #include "xparameters.h"
- #include "xqspips.h"
- #include "xil_printf.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 QSPI_DEVICE_ID XPAR_XQSPIPS_0_DEVICE_ID
-
- /*
- * The following constants define the commands which may be sent to the FLASH
- * device.
- */
- #define WRITE_STATUS_CMD 0x01
- #define WRITE_CMD 0x02
- #define READ_CMD 0x03
- #define WRITE_DISABLE_CMD 0x04
- #define READ_STATUS_CMD 0x05
- #define WRITE_ENABLE_CMD 0x06
- #define FAST_READ_CMD 0x0B
- #define DUAL_READ_CMD 0x3B
- #define QUAD_READ_CMD 0x6B
- #define BULK_ERASE_CMD 0xC7
- #define SEC_ERASE_CMD 0xD8
- #define READ_ID 0x9F
-
- /*
- * The following constants define the offsets within a FlashBuffer data
- * type for each kind of data. Note that the read data offset is not the
- * same as the write data because the QSPI driver is designed to allow full
- * duplex transfers such that the number of bytes received is the number
- * sent and received.
- */
- #define COMMAND_OFFSET 0 /* FLASH instruction */
- #define ADDRESS_1_OFFSET 1 /* MSB byte of address to read or write */
- #define ADDRESS_2_OFFSET 2 /* Middle byte of address to read or write */
- #define ADDRESS_3_OFFSET 3 /* LSB byte of address to read or write */
- #define DATA_OFFSET 4 /* Start of Data for Read/Write */
- #define DUMMY_OFFSET 4 /* Dummy byte offset for fast, dual and quad \
- * reads \
- */
- #define DUMMY_SIZE 1 /* Number of dummy bytes for fast, dual and \
- * quad reads \
- */
- #define RD_ID_SIZE 4 /* Read ID command + 3 bytes ID response */
- #define BULK_ERASE_SIZE 1 /* Bulk Erase command size */
- #define SEC_ERASE_SIZE 4 /* Sector Erase command + Sector address */
-
- /*
- * The following constants specify the extra bytes which are sent to the
- * FLASH on the QSPI interface, that are not data, but control information
- * which includes the command and address
- */
- #define OVERHEAD_SIZE 4
-
- /*
- * The following constants specify the page size, sector size, and number of
- * pages and sectors for the FLASH. The page size specifies a max number of
- * bytes that can be written to the FLASH with a single transfer.
- */
- #define SECTOR_SIZE 0x10000
- #define NUM_SECTORS 0x100
- #define NUM_PAGES 0x10000
- #define PAGE_SIZE 256
-
- /* Number of flash pages to be written.*/
- #define PAGE_COUNT 16
-
- /* Flash address to which data is ot be written.*/
- #define TEST_ADDRESS 0x00055000
- #define UNIQUE_VALUE 0x05
- /*
- * The following constants specify the max amount of data and the size of the
- * the buffer required to hold the data and overhead to transfer the data to
- * and from the FLASH.
- */
- #define MAX_DATA (PAGE_COUNT * PAGE_SIZE)
-
- /**************************** Type Definitions *******************************/
-
- /***************** Macros (Inline Functions) Definitions *********************/
-
- /************************** Function Prototypes ******************************/
-
- void FlashErase(XQspiPs *QspiPtr, u32 Address, u32 ByteCount);
-
- void FlashWrite(XQspiPs *QspiPtr, u32 Address, u32 ByteCount, u8 Command);
-
- void FlashRead(XQspiPs *QspiPtr, u32 Address, u32 ByteCount, u8 Command);
-
- int FlashReadID(void);
-
- void FlashQuadEnable(XQspiPs *QspiPtr);
-
- int QspiFlashPolledExample(XQspiPs *QspiInstancePtr, u16 QspiDeviceId);
-
- /************************** Variable Definitions *****************************/
-
- /*
- * The instances to support the device drivers are global such that they
- * are initialized to zero each time the program runs. They could be local
- * but should at least be static so they are zeroed.
- */
- static XQspiPs QspiInstance;
-
- /*
- * The following variable allows a test value to be added to the values that
- * are written to the FLASH such that unique values can be generated to
- * guarantee the writes to the FLASH were successful
- */
- int Test = 5;
-
- /*
- * The following variables are used to read and write to the flash and they
- * are global to avoid having large buffers on the stack
- */
- u8 ReadBuffer[MAX_DATA + DATA_OFFSET + DUMMY_SIZE];
- u8 WriteBuffer[PAGE_SIZE + DATA_OFFSET];
-
- /*****************************************************************************/
- /**
- *
- * Main function to call the QSPI Flash example.
- *
- * @param None
- *
- * @return XST_SUCCESS if successful, otherwise XST_FAILURE.
- *
- * @note None
- *
- ******************************************************************************/
- int main(void)
- {
- int Status;
-
- xil_printf("QSPI FLASH Polled Example Test \r\n");
-
- /* Run the Qspi Interrupt example.*/
- Status = QspiFlashPolledExample(&QspiInstance, QSPI_DEVICE_ID);
- if (Status != XST_SUCCESS)
- {
- xil_printf("QSPI FLASH Polled Example Test Failed\r\n");
- return XST_FAILURE;
- }
-
- xil_printf("Successfully ran QSPI FLASH Polled Example Test\r\n");
- return XST_SUCCESS;
- }
-
- /*****************************************************************************/
- /**
- *
- * The purpose of this function is to illustrate how to use the XQspiPs
- * device driver in polled mode. This function writes and reads data
- * from a serial FLASH.
- *
- * @param None.
- *
- * @return XST_SUCCESS if successful, else XST_FAILURE.
- *
- * @note None.
- *
- *****************************************************************************/
- int QspiFlashPolledExample(XQspiPs *QspiInstancePtr, u16 QspiDeviceId)
- {
- int Status;
- u8 *BufferPtr;
- u8 UniqueValue;
- int Count;
- int Page;
- XQspiPs_Config *QspiConfig;
-
- //初始化 QSPI 驱动
- QspiConfig = XQspiPs_LookupConfig(QspiDeviceId);
- XQspiPs_CfgInitialize(QspiInstancePtr, QspiConfig, QspiConfig->BaseAddress);
- //初始化读写 BUFFER
- for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < PAGE_SIZE;
- Count++, UniqueValue++)
- {
- WriteBuffer[DATA_OFFSET + Count] = (u8)(UniqueValue + Test);
- /* WriteBuffer[4] = (5+5) = 10
- WriteBuffer[5] = (6+5) = 11
- WriteBuffer[6] = (7+5) = 12
- WriteBuffer[7] = (8+5) = 13
- ......
- WriteBuffer[259] = (260+5) = 265
- */
- }
- memset(ReadBuffer, 0x00, sizeof(ReadBuffer));
-
- //设置手动启动和手动片选模式
- XQspiPs_SetOptions(QspiInstancePtr, XQSPIPS_MANUAL_START_OPTION |
- XQSPIPS_FORCE_SSELECT_OPTION |
- XQSPIPS_HOLD_B_DRIVE_OPTION);
- //设置 QSPI 时钟的分频系数
- XQspiPs_SetClkPrescaler(QspiInstancePtr, XQSPIPS_CLK_PRESCALE_8);
- //片选信号置为有效
- XQspiPs_SetSlaveSelect(QspiInstancePtr);
-
- //读 Flash ID
- FlashReadID();
- //使能 Flash Quad 模式
- FlashQuadEnable(QspiInstancePtr);
- //擦除 Flash
- FlashErase(QspiInstancePtr, TEST_ADDRESS, MAX_DATA);
- //向 Flash 中写入数据
- for (Page = 0; Page < PAGE_COUNT; Page++)
- {
- FlashWrite(QspiInstancePtr, (Page * PAGE_SIZE) + TEST_ADDRESS,
- PAGE_SIZE, WRITE_CMD);
- }
- //使用 QUAD 模式从 Flash 中读出数据
- FlashRead(QspiInstancePtr, TEST_ADDRESS, MAX_DATA, QUAD_READ_CMD);
-
- //对比写入 Flash 与从 Flash 中读出的数据
- BufferPtr = &ReadBuffer[DATA_OFFSET + DUMMY_SIZE];
- for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MAX_DATA;
- Count++, UniqueValue++)
- {
- if (BufferPtr[Count] != (u8)(UniqueValue + Test))
- {
- return XST_FAILURE;
- }
- }
-
- return XST_SUCCESS;
- }
- /*****************************************************************************/
- /**
- *
- * This function writes to the serial FLASH connected to the QSPI interface.
- * All the data put into the buffer must be in the same page of the device with
- * page boundaries being on 256 byte boundaries.
- *
- * @param QspiPtr is a pointer to the QSPI driver component to use.
- * @param Address contains the address to write data to in the FLASH.
- * @param ByteCount contains the number of bytes to write.
- * @param Command is the command used to write data to the flash. QSPI
- * device supports only Page Program command to write data to the
- * flash.
- *
- * @return None.
- *
- * @note None.
- *
- ******************************************************************************/
- void FlashWrite(XQspiPs *QspiPtr, u32 Address, u32 ByteCount, u8 Command)
- {
- u8 WriteEnableCmd = {WRITE_ENABLE_CMD};
- u8 ReadStatusCmd[] = {READ_STATUS_CMD, 0}; /* must send 2 bytes */
- u8 FlashStatus[2];
-
- /*
- * Send the write enable command to the FLASH so that it can be
- * written to, this needs to be sent as a separate transfer before
- * the write
- */
- XQspiPs_PolledTransfer(QspiPtr, &WriteEnableCmd, NULL,
- sizeof(WriteEnableCmd));
-
- /*
- * Setup the write command with the specified address and data for the
- * FLASH
- */
- WriteBuffer[COMMAND_OFFSET] = Command;
- WriteBuffer[ADDRESS_1_OFFSET] = (u8)((Address & 0xFF0000) >> 16);
- WriteBuffer[ADDRESS_2_OFFSET] = (u8)((Address & 0xFF00) >> 8);
- WriteBuffer[ADDRESS_3_OFFSET] = (u8)(Address & 0xFF);
-
- /*
- * Send the write command, address, and data to the FLASH to be
- * written, no receive buffer is specified since there is nothing to
- * receive
- */
- XQspiPs_PolledTransfer(QspiPtr, WriteBuffer, NULL,
- ByteCount + OVERHEAD_SIZE);
-
- /*
- * Wait for the write command to the FLASH to be completed, it takes
- * some time for the data to be written
- */
- while (1)
- {
- /*
- * Poll the status register of the FLASH to determine when it
- * completes, by sending a read status command and receiving the
- * status byte
- */
- XQspiPs_PolledTransfer(QspiPtr, ReadStatusCmd, FlashStatus,
- sizeof(ReadStatusCmd));
-
- /*
- * If the status indicates the write is done, then stop waiting,
- * if a value of 0xFF in the status byte is read from the
- * device and this loop never exits, the device slave select is
- * possibly incorrect such that the device status is not being
- * read
- */
- FlashStatus[1] |= FlashStatus[0];
- if ((FlashStatus[1] & 0x01) == 0)
- {
- break;
- }
- }
- }
-
- /*****************************************************************************/
- /**
- *
- * This function reads from the serial FLASH connected to the
- * QSPI interface.
- *
- * @param QspiPtr is a pointer to the QSPI driver component to use.
- * @param Address contains the address to read data from in the FLASH.
- * @param ByteCount contains the number of bytes to read.
- * @param Command is the command used to read data from the flash. QSPI
- * device supports one of the Read, Fast Read, Dual Read and Fast
- * Read commands to read data from the flash.
- *
- * @return None.
- *
- * @note None.
- *
- ******************************************************************************/
- void FlashRead(XQspiPs *QspiPtr, u32 Address, u32 ByteCount, u8 Command)
- {
- /*
- * Setup the write command with the specified address and data for the
- * FLASH
- */
- WriteBuffer[COMMAND_OFFSET] = Command;
- WriteBuffer[ADDRESS_1_OFFSET] = (u8)((Address & 0xFF0000) >> 16);
- WriteBuffer[ADDRESS_2_OFFSET] = (u8)((Address & 0xFF00) >> 8);
- WriteBuffer[ADDRESS_3_OFFSET] = (u8)(Address & 0xFF);
-
- if ((Command == FAST_READ_CMD) || (Command == DUAL_READ_CMD) ||
- (Command == QUAD_READ_CMD))
- {
- ByteCount += DUMMY_SIZE;
- }
- /*
- * Send the read command to the FLASH to read the specified number
- * of bytes from the FLASH, send the read command and address and
- * receive the specified number of bytes of data in the data buffer
- */
- XQspiPs_PolledTransfer(QspiPtr, WriteBuffer, ReadBuffer,
- ByteCount + OVERHEAD_SIZE);
- }
-
- /*****************************************************************************/
- /**
- *
- * This function erases the sectors in the serial FLASH connected to the
- * QSPI interface.
- *
- * @param QspiPtr is a pointer to the QSPI driver component to use.
- * @param Address contains the address of the first sector which needs to
- * be erased.
- * @param ByteCount contains the total size to be erased.
- *
- * @return None.
- *
- * @note None.
- *
- ******************************************************************************/
- void FlashErase(XQspiPs *QspiPtr, u32 Address, u32 ByteCount)
- {
- u8 WriteEnableCmd = {WRITE_ENABLE_CMD};
- u8 ReadStatusCmd[] = {READ_STATUS_CMD, 0}; /* must send 2 bytes */
- u8 FlashStatus[2];
- int Sector;
-
- /*
- * If erase size is same as the total size of the flash, use bulk erase
- * command
- */
- if (ByteCount == (NUM_SECTORS * SECTOR_SIZE))
- {
- /*
- * Send the write enable command to the FLASH so that it can be
- * written to, this needs to be sent as a separate transfer
- * before the erase
- */
- XQspiPs_PolledTransfer(QspiPtr, &WriteEnableCmd, NULL,
- sizeof(WriteEnableCmd));
-
- /* Setup the bulk erase command*/
- WriteBuffer[COMMAND_OFFSET] = BULK_ERASE_CMD;
-
- /*
- * Send the bulk erase command; no receive buffer is specified
- * since there is nothing to receive
- */
- XQspiPs_PolledTransfer(QspiPtr, WriteBuffer, NULL,
- BULK_ERASE_SIZE);
-
- /* Wait for the erase command to the FLASH to be completed*/
- while (1)
- {
- /*
- * Poll the status register of the device to determine
- * when it completes, by sending a read status command
- * and receiving the status byte
- */
- XQspiPs_PolledTransfer(QspiPtr, ReadStatusCmd,
- FlashStatus,
- sizeof(ReadStatusCmd));
-
- /*
- * If the status indicates the write is done, then stop
- * waiting; if a value of 0xFF in the status byte is
- * read from the device and this loop never exits, the
- * device slave select is possibly incorrect such that
- * the device status is not being read
- */
- FlashStatus[1] |= FlashStatus[0];
- if ((FlashStatus[1] & 0x01) == 0)
- {
- break;
- }
- }
-
- return;
- }
-
- /*
- * If the erase size is less than the total size of the flash, use
- * sector erase command
- */
- for (Sector = 0; Sector < ((ByteCount / SECTOR_SIZE) + 1); Sector++)
- {
- /*
- * Send the write enable command to the SEEPOM so that it can be
- * written to, this needs to be sent as a separate transfer
- * before the write
- */
- XQspiPs_PolledTransfer(QspiPtr, &WriteEnableCmd, NULL,
- sizeof(WriteEnableCmd));
-
- /*
- * Setup the write command with the specified address and data
- * for the FLASH
- */
- WriteBuffer[COMMAND_OFFSET] = SEC_ERASE_CMD;
- WriteBuffer[ADDRESS_1_OFFSET] = (u8)(Address >> 16);
- WriteBuffer[ADDRESS_2_OFFSET] = (u8)(Address >> 8);
- WriteBuffer[ADDRESS_3_OFFSET] = (u8)(Address & 0xFF);
-
- /*
- * Send the sector erase command and address; no receive buffer
- * is specified since there is nothing to receive
- */
- XQspiPs_PolledTransfer(QspiPtr, WriteBuffer, NULL,
- SEC_ERASE_SIZE);
-
- /*
- * Wait for the sector erse command to the
- * FLASH to be completed
- */
- while (1)
- {
- /*
- * Poll the status register of the device to determine
- * when it completes, by sending a read status command
- * and receiving the status byte
- */
- XQspiPs_PolledTransfer(QspiPtr, ReadStatusCmd,
- FlashStatus,
- sizeof(ReadStatusCmd));
-
- /*
- * If the status indicates the write is done, then stop
- * waiting, if a value of 0xFF in the status byte is
- * read from the device and this loop never exits, the
- * device slave select is possibly incorrect such that
- * the device status is not being read
- */
- FlashStatus[1] |= FlashStatus[0];
- if ((FlashStatus[1] & 0x01) == 0)
- {
- break;
- }
- }
-
- Address += SECTOR_SIZE;
- }
- }
-
- /*****************************************************************************/
- /**
- *
- * This function reads serial FLASH ID connected to the SPI interface.
- *
- * @param None.
- *
- * @return XST_SUCCESS if read id, otherwise XST_FAILURE.
- *
- * @note None.
- *
- ******************************************************************************/
- int FlashReadID(void)
- {
- int Status;
-
- /* Read ID in Auto mode.*/
- WriteBuffer[COMMAND_OFFSET] = READ_ID;
- WriteBuffer[ADDRESS_1_OFFSET] = 0x23; /* 3 dummy bytes */
- WriteBuffer[ADDRESS_2_OFFSET] = 0x08;
- WriteBuffer[ADDRESS_3_OFFSET] = 0x09;
-
- Status = XQspiPs_PolledTransfer(&QspiInstance, WriteBuffer, ReadBuffer,
- RD_ID_SIZE);
- if (Status != XST_SUCCESS)
- {
- return XST_FAILURE;
- }
-
- xil_printf("FlashID=0x%x 0x%x 0x%x\n\r", ReadBuffer[1], ReadBuffer[2],
- ReadBuffer[3]);
-
- return XST_SUCCESS;
- }
-
- /*****************************************************************************/
-
- /**
- *
- * This function enables quad mode in the serial flash connected to the
- * SPI interface.
- *
- * @param QspiPtr is a pointer to the QSPI driver component to use.
- *
- * @return None.
- *
- * @note None.
- *
- ******************************************************************************/
- void FlashQuadEnable(XQspiPs *QspiPtr)
- {
- u8 WriteEnableCmd = {WRITE_ENABLE_CMD};
- u8 ReadStatusCmd[] = {READ_STATUS_CMD, 0};
- u8 QuadEnableCmd[] = {WRITE_STATUS_CMD, 0};
- u8 FlashStatus[2];
-
- if (ReadBuffer[1] == 0x9D)
- {
-
- XQspiPs_PolledTransfer(QspiPtr, ReadStatusCmd,
- FlashStatus,
- sizeof(ReadStatusCmd));
-
- QuadEnableCmd[1] = FlashStatus[1] | 1 << 6;
-
- XQspiPs_PolledTransfer(QspiPtr, &WriteEnableCmd, NULL,
- sizeof(WriteEnableCmd));
-
- XQspiPs_PolledTransfer(QspiPtr, QuadEnableCmd, NULL,
- sizeof(QuadEnableCmd));
- while (1)
- {
- /*
- * Poll the status register of the FLASH to determine when
- * Quad Mode is enabled and the device is ready, by sending
- * a read status command and receiving the status byte
- */
- XQspiPs_PolledTransfer(QspiPtr, ReadStatusCmd, FlashStatus,
- sizeof(ReadStatusCmd));
- /*
- * If 6th bit is set & 0th bit is reset, then Quad is Enabled
- * and device is ready.
- */
- if ((FlashStatus[0] == 0x40) && (FlashStatus[1] == 0x40))
- {
- break;
- }
- }
- }
- }
-
-
-
- /* 运行结果
- QSPI FLASH Polled Example Test
-
- FlashID=0xEF 0x40 0x19
-
- Successfully ran QSPI FLASH Polled Example Test
- */

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。