• 【SDK】控制PS侧GPIO ( 操作地址强制转换为指针 )


    #include <stdio.h>
    #include "platform.h"
    #include "xgpiops.h"
    #include "sleep.h"
    
    #define     LED_PinNumber    0 //LED D29 MIO管脚
    
    //void print(char *str);
    
    int main()
    {
        int Status;
        XGpioPs_Config *p_gpio_config;
        XGpioPs Gpio;
    
        init_platform();
    
        print("gpio mio test
    
    ");
    
        //初始化GPIO驱动
        p_gpio_config = XGpioPs_LookupConfig(XPAR_PS7_GPIO_0_DEVICE_ID);
        Status = XGpioPs_CfgInitialize(&Gpio, p_gpio_config,p_gpio_config->BaseAddr);
        if (Status != XST_SUCCESS) 
        {
            print("gpio_mio config error!
    ");
            return XST_FAILURE;
        }
    
        // LED_PinNumber gpio 设置
        XGpioPs_SetDirectionPin(&Gpio, LED_PinNumber, 1);
        XGpioPs_SetOutputEnablePin(&Gpio, LED_PinNumber, 1);
    
        while (1) 
        {
            XGpioPs_WritePin(&Gpio, LED_PinNumber, 0);
            sleep(1);//延时1s
            XGpioPs_WritePin(&Gpio, LED_PinNumber, 1);
            sleep(1);//延时1s
        }
    
        cleanup_platform();
    }

    封装函数位于bsp文件下xgpiops.h

    void XGpioPs_SetDirection(XGpioPs *InstancePtr, u8 Bank, u32 Direction);// 设置IO的in/out方向
    void XGpioPs_SetOutputEnable(XGpioPs *InstancePtr, u8 Bank, u32 OpEnable);// 设置out使能
    void XGpioPs_WritePin(XGpioPs *InstancePtr, u32 Pin, u32 Data);//管脚置0/1

    选XGpioPs_WritePin()函数分析(gpiops_v3_1srcxgpiops.c)

    void XGpioPs_WritePin(XGpioPs *InstancePtr, u32 Pin, u32 Data)
    {
        u32 RegOffset;
        u32 Value;
        u8 Bank;
        u8 PinNumber;
        u32 DataVar = Data;
    
        Xil_AssertVoid(InstancePtr != NULL);
        Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
        Xil_AssertVoid(Pin < InstancePtr->MaxPinNum);
    
        /* Get the Bank number and Pin number within the bank. */
        XGpioPs_GetBankPin((u8)Pin, &Bank, &PinNumber);
    
        if (PinNumber > 15U) {
            /* There are only 16 data bits in bit maskable register. */
            PinNumber -= (u8)16;
            RegOffset = XGPIOPS_DATA_MSW_OFFSET;
        } else {
            RegOffset = XGPIOPS_DATA_LSW_OFFSET;
        }
    
        /*
         * Get the 32 bit value to be written to the Mask/Data register where
         * the upper 16 bits is the mask and lower 16 bits is the data.
         */
        DataVar &= (u32)0x01;// 只取最后1bit
        Value = ~((u32)1 << (PinNumber + 16U)) & ((DataVar << PinNumber) | 0xFFFF0000U);// 修改设定的pin位 其他mask掉
        XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr,
                  ((u32)(Bank) * XGPIOPS_DATA_MASK_OFFSET) +
                  RegOffset, Value);// 最终写入 MASK_DATA_0_LSW 寄存器
    }

    选XGpioPs_WriteReg()分析(xgpiops_hw.h)。Xil_Out32()是基础共享的,具体化成Gpio专用的。

    #define XGpioPs_WriteReg(BaseAddr, RegOffset, Data)    
            Xil_Out32((BaseAddr) + (u32)(RegOffset), (u32)(Data))// 带参宏把功能映射到底层函数上

    分析Xil_Out32() (standalone_v5_5srcxil_io.c)

    void Xil_Out32(UINTPTR Addr, u32 Value)
    {
        volatile u32 *LocalAddr = (u32 *)Addr;// 强制类型转换 映射到地址
        *LocalAddr = Value;// 把数据写到该地址
    }

    //----------------------------------------------------------

    //初始化分析

     //----------------------------------------------------------

      先定义结构体变量

    // 定义struct变量
    XGpioPs_Config *p_gpio_config;
    XGpioPs Gpio;
    
    //struct声明
    typedef struct {
    	u16 DeviceId;		/**< Unique ID of device */
    	u32 BaseAddr;		/**< Register base address */
    } XGpioPs_Config;
    
    typedef struct {
    	XGpioPs_Config GpioConfig;	/**< Device configuration */
    	u32 IsReady;			/**< Device is initialized and ready */
    	XGpioPs_Handler Handler;	/**< Status handlers for all banks */
    	void *CallBackRef; 		/**< Callback ref for bank handlers */
    	u32 Platform;			/**< Platform data */
    	u32 MaxPinNum;			/**< Max pins in the GPIO device */
    	u8 MaxBanks;			/**< Max banks in a GPIO device */
    } XGpioPs;
    

      根据ID找到对应的结构体内容列表

    //
    p_gpio_config = XGpioPs_LookupConfig(XPAR_PS7_GPIO_0_DEVICE_ID);
    
    //
    XGpioPs_Config *XGpioPs_LookupConfig(u16 DeviceId)
    {
    	XGpioPs_Config *CfgPtr = NULL;
    	u32 Index;
         //定义结构体数组,存储多组id信息,这里只有一组
    	for (Index = 0U; Index < (u32)XPAR_XGPIOPS_NUM_INSTANCES; Index++) {
    		if (XGpioPs_ConfigTable[Index].DeviceId == DeviceId) {
    			CfgPtr = &XGpioPs_ConfigTable[Index];
    			break;
    		}
    	}
         //返回相同体指针
    	return (XGpioPs_Config *)CfgPtr;
    }
    
    //导入外部定义好的结构体内容
    extern XGpioPs_Config XGpioPs_ConfigTable[XPAR_XGPIOPS_NUM_INSTANCES];
    
    //该结构体下定义了一组信息。数组宽度1,即[0]
    XGpioPs_Config XGpioPs_ConfigTable[XPAR_XGPIOPS_NUM_INSTANCES] =
    {
    	{
    		XPAR_PS7_GPIO_0_DEVICE_ID,
    		XPAR_PS7_GPIO_0_BASEADDR
    	}
    };

    //
    #define XPAR_XGPIOPS_NUM_INSTANCES 1

      只要有config下的base信息,就能对其他内容进行定义,即initiaize

    //
    Status = XGpioPs_CfgInitialize(&Gpio, p_gpio_config,p_gpio_config->BaseAddr);
    
    //实际传入参数只有p_gpio_config,以此对Gpio子变量进行定义
    s32 XGpioPs_CfgInitialize(XGpioPs *InstancePtr, XGpioPs_Config *ConfigPtr,
    				u32 EffectiveAddr)
    {
    	s32 Status = XST_SUCCESS;
    	u8 i;
    	Xil_AssertNonvoid(InstancePtr != NULL);
    	Xil_AssertNonvoid(ConfigPtr != NULL);
    	Xil_AssertNonvoid(EffectiveAddr != (u32)0);
    	/*
    	 * Set some default values for instance data, don't indicate the device
    	 * is ready to use until everything has been initialized successfully.
    	 */
    	InstancePtr->IsReady = 0U;
    	InstancePtr->GpioConfig.BaseAddr = EffectiveAddr;
    	InstancePtr->GpioConfig.DeviceId = ConfigPtr->DeviceId;
    	InstancePtr->Handler = StubHandler;
    	InstancePtr->Platform = XGetPlatform_Info();
    
    	/* Initialize the Bank data based on platform */
    	if (InstancePtr->Platform == XPLAT_ZYNQ_ULTRA_MP) {
    		/*
    		 *	Max pins in the ZynqMP GPIO device
    		 *	0 - 25,  Bank 0
    		 *	26 - 51, Bank 1
    		 *	52 - 77, Bank 2
    		 *	78 - 109, Bank 3
    		 *	110 - 141, Bank 4
    		 *	142 - 173, Bank 5
    		 */
    		InstancePtr->MaxPinNum = (u32)174;
    		InstancePtr->MaxBanks = (u8)6;
    	} else {
    		/*
    		 *	Max pins in the GPIO device
    		 *	0 - 31,  Bank 0
    		 *	32 - 53, Bank 1
    		 *	54 - 85, Bank 2
    		 *	86 - 117, Bank 3
    		 */
    		InstancePtr->MaxPinNum = (u32)118;
    		InstancePtr->MaxBanks = (u8)4;
    	}
    
    	/*
    	 * By default, interrupts are not masked in GPIO. Disable
    	 * interrupts for all pins in all the 4 banks.
    	 */
    	for (i=0;i<InstancePtr->MaxBanks;i++) {
    		XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr,
    					  ((u32)(i) * XGPIOPS_REG_MASK_OFFSET) +
    					  XGPIOPS_INTDIS_OFFSET, 0xFFFFFFFFU);
    	}
    
    	/* Indicate the component is now ready to use. */
    	InstancePtr->IsReady = XIL_COMPONENT_IS_READY;
    
    	return Status;
    }
    

      

  • 相关阅读:
    WPF 之Converter
    silverlight中 ComboBox绑定数据库,并获取当前选定值
    ComboBox联动 (AJAX BS实现)
    [推荐]Silverlight 2 开发者海报
    非常精彩的Silverlight 2控件样式
    一步一步学Silverlight 2系列文章
    POSIX 线程详解(经典必看)
    嵌入式 vlc从接收到数据流到播放视频的过程分析(经典)
    OpenGL ES教程系列(经典合集)
    Audio Queue Services Programming Guide(音频队列服务编程指南)
  • 原文地址:https://www.cnblogs.com/kevinchase/p/7099215.html
Copyright © 2020-2023  润新知