Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Valued Contributor III
1,939 Views

HPS GPIO's ouputs stuck in high impedence?

I have an issue regarding a custom board the GPIOs where all the HPS IO’s are set to high impedance no matter to how they are set. 

 

I have tested the following: 

  • GPIO system on linux enabling each of the GPIOs as an output through the controller... and writing values to them... (findings it changes to output state but the value doesn’t alter and reads back high - unchanged) 

  • GPIO controller address read/write (findings values don’t change) 

  • Pre-Linux Hardware GPIO Loaning Pins driving a value change on preloader startup to enable a LED (findings no value on GPIO changes value) 

 

 

So overall the pin mux is there just the GPIO is always set to high... no matter if the gpio output is enabled and values are written to it. All three methods work on our development board with or without Linux drivers included for the LEDs “gpio-leds” simple driver, but not on the custom board. Our PCB has the HPS GPIO LEDs that do not light or even the unconnected header pin doesn’t change value (in your experience does a open gpio pin change value (we think it should still be driven) – this would mean that it is not a driver issue) 

 

The LED output schematic and just applying a 1 or 0 would change this state no problem. It is a different type of Led than the one used on the development board. It uses a power driven led that has a dual red and green operation so should work. 

 

With the open gpio pins not changing state this points to high impedance for all gpio’s, which I am trying to see the differences. 

 

1) Our GPIO Controller has 67 I/O pins connected but none of the 14 input ony pins. (I will try searching for this configurable through u-boot?) – states if not connected need to be weak pull-up. 

 

2) Device Tree can be set without LED driver on the sockit to drive the simple LED’s or can be set accordingly without setting the GPIO through the altera software. 

With our leds requiring a power-supply are there special flags to use in the driver but the power is already been supplied, but even the open pin doesn’t drive a signal so I doubt this is the issue. 

 

3) Current Drive or signal circuitry? 

 

Please Advise on what could make the GPIO's not change state and become driven always at the 3.3V outputted voltage? 

 

Thanks 

 

Kyle
0 Kudos
31 Replies
Highlighted
Valued Contributor III
56 Views

Hi Kyle, 

 

even I was trying to access GPIO using DEO nano but faced issues...did you get any answer??..should we change the high impedance state in Linux boot if so how?? 

 

--Ravi
0 Kudos
Highlighted
Valued Contributor III
56 Views

Hi Ravi, 

 

I've Fixed this issue for both the GPIO and LOAN IO.  

 

GPIO 

Just make sure when you enable the GPIO's in the peripheral pins in Qsys... that you update the Assignment editor page to include your linked pin  

eg. 

hps_io_hps_io_gpio_inst_GPIO49 => HPS_GPIO49 -- loans out to the Top level Port HPS_GPIO49 so add this to Assigments > Assignment editor 

To [HPS_GPIO49] Assignment Name [I/O Standard] Value [Voltage value of output] 

Recompile the project and the GPIO should be available. 

 

LOAN pins are different you need make sure from your Qsys design you export the loanio pins back into your top level design. 

hps_0_h2f_loan_io_in : out std_logic_vector(66 downto 0); 

hps_0_h2f_loan_io_out : in std_logic_vector(66 downto 0) := (others => '0'); 

hps_0_h2f_loan_io_oe : in std_logic_vector(66 downto 0) := (others => '0'); 

the inputs are assigned to the in... and the outputs to outputs... (when they are output make the oe vector for that pin 1 to enable it as an output) 

 

This is pretty much it... happy to help the documentation is brief but pretty much it works well once you do this. 

 

Good Luck 

 

Kyle
0 Kudos
Highlighted
Valued Contributor III
56 Views

" Hi kyle, 

 

when you go to Assignment Editor there are 2 rows you see for each pins 

GPIO_1[0] Location( This is changed to HPS_IO) and select Enable(Yes) 

GPIO_1[1] I/O standard 3.3 V LVTTL  

 

Once I did this and compiled and flashed the .SOF then Pin 2 of GPIO_1 cannot be accessed. I have a C file which changes the Set bits and Clr bits..But I am not able to take control of the GPIO_1 pin.Is there any jumper which we need to change.also are my configurations correct. 

Once I get one pin I can map for others. 

Kindly let me know." 

 

regards 

Ravi
0 Kudos
Highlighted
Valued Contributor III
56 Views

Hi Kyle, 

 

Thanks for your support...also would like to know if there are any configurations in the Assignments->Device->Deviceandpinoptions->Unused pins (An input Tristated) to access the pin and see the output. I am using a C file which has hps.h through which I assign GPIO1_SWPORTA_DR_ADDR and configuring these registers to get the output. 

eg: 

# include <stdio.h> 

# include <unistd.h> 

# include <fcntl.h> 

# include <sys/mman.h> 

# include "hwlib.h" 

# include "soc_cv_av/socal/socal.h" 

# include "soc_cv_av/socal/hps.h" 

# include "soc_cv_av/socal/alt_gpio.h" 

 

# define HW_REGS_BASE ( ALT_STM_OFST ) 

# define HW_REGS_SPAN ( 0x04000000 ) 

# define HW_REGS_MASK ( HW_REGS_SPAN - 1 ) 

 

# define USER_IO_DIR (0x01000008) 

# define BIT_LED (0x01000008) 

# define BUTTON_MASK (0x02000000) 

 

int main(int argc, char **argv) { 

 

void *virtual_base; 

int fd; 

uint32_t scan_input; 

int i;  

// map the address space for the LED registers into user space so we can interact with them. 

// we'll actually map in the entire CSR span of the HPS since we want to access various registers within that span 

if( ( fd = open( "/dev/mem", ( O_RDWR | O_SYNC ) ) ) == -1 ) { 

printf( "ERROR: could not open \"/dev/mem\"...\n" ); 

return( 1 ); 

 

virtual_base = mmap( NULL, HW_REGS_SPAN, ( PROT_READ | PROT_WRITE ), MAP_SHARED, fd, HW_REGS_BASE ); 

 

if( virtual_base == MAP_FAILED ) { 

printf( "ERROR: mmap() failed...\n" ); 

close( fd ); 

return( 1 ); 

// initialize the pio controller 

// led: set the direction of the HPS GPIO1 bits attached to LEDs to output 

alt_clrbits_word( ( virtual_base + ( ( uint32_t )( ALT_GPIO1_SWPORTA_DR_ADDR) & ( uint32_t )( HW_REGS_MASK ) ) ), BIT_LED ); 

alt_setbits_word( ( virtual_base + ( ( uint32_t )( ALT_GPIO1_SWPORTA_DR_ADDR) & ( uint32_t )( HW_REGS_MASK ) ) ), USER_IO_DIR ); 

 

 

so this should work..Let me know get some idea 

 

--Ravi
0 Kudos
Highlighted
Valued Contributor III
56 Views

Ravi, 

 

The Assignment editor needs to be set to Assignment Name [I/O Standard] this is a must is shouldn't be a "location" on the FPGA as there is no location it goes through into the preloader and is linked there. 

The Value is instead set to the Voltage level [3.3-V LVCMOS] your maybe less depending on the hps powered IO's it could be 2.5V or lower please check this. Enabled is yes too so that would be correct. 

 

Please try the linux commands from the HPS command line first (before memory mapping) to make sure that the GPIO's can be set... follow this tutorial for setting the GPIO's  

If there are LED's then you should be just write a active low or high signal to them from the command line.... 

 

Follow this tutorial and see if the LED's light on the gpio then you can start to progress into the memory mapping application code.. 

http://falsinsoft.blogspot.co.uk/2012/11/access-gpio-from-linux-user-space.html 

 

It looks like your code is correct but you need to just make sure that the GPIO is controllable from the drivers in linux the following echo commands will help you enable an GPIO output (number is significant please find out the number of the GPIO from linux and cyclone V handbook for specifying the correct GPIO) here 192 is used as this is from the GPIO controller 2 and is the 1st one your number will be different please check for your correct one. 

 

echo 192 > /sys/class/gpio/export  

echo "out" > /sys/class/gpio/gpio192/direction 

echo 1 > /sys/class/gpio/gpio192/value 

echo 0 > /sys/class/gpio/gpio192/value 

 

The first echo line enables the gpio.... if you get problems here the gpio is already attached to a linux driver and will need removing (look into removing a driver) 

The second enables that channel to become an output as all gpio's are either in or output the default is always input so this enables you send the gpio as high or low...etc 

The next 2 lines will write a high or low value to that gpio you should see the light move on and off if it is correctly enabled. 

 

Best of luck 

 

Kyle 

 

Without finding problems you never learn.
0 Kudos
Highlighted
Valued Contributor III
56 Views

Hi kyle, 

 

Not able to get the GPIO toggle working for GPIO_1 any suggestions from your side where in assignment editor changes need to be made so that we can toggle the switch??.will really help if you reply.waiting for your response 

 

regards 

Ravi chandran
0 Kudos
Highlighted
Valued Contributor III
56 Views

Hi kyle, 

 

thanks for your reply.I tried the way you told using the Linux but this did not work.The GPIO was not accessible.so from linux itself I am not able to control.if we solve this then user space code will work. 

 

My Assignment editor looks like this the 2 rows for each pin 

original 

To:GPIO_1[1] Assignment name-> Location PIN_Name(value) Enabled(yes) 

GPIO_1[1] Assignment name-> I/O standard 3.3V LVTTL(value) Enabled(yes) 

 

My changed version 

To:GPIO_1[1] Assignment name-> HPS_IO ON(value) Enabled(yes) 

GPIO_1[1] Assignment name-> I/O standard 3.3V LVTTL(value) Enabled(yes) 

 

Is this correct ??.. Like this I need to enable for all other pins.Is there any thing I missed assigning here???..Let me know.Any configuration changes. 

In the device option also I have chooseb UNUSED pin as INPUT state TRIGERRED. 

 

created the .SOF and programmed and ran the linux command but did not work..Kindly let me know if you see any errors here 

 

thanks in advance 

 

--Ravi 

 

 

 

 

 

 

--- Quote Start ---  

Ravi, 

 

The Assignment editor needs to be set to Assignment Name [I/O Standard] this is a must is shouldn't be a "location" on the FPGA as there is no location it goes through into the preloader and is linked there. 

The Value is instead set to the Voltage level [3.3-V LVCMOS] your maybe less depending on the hps powered IO's it could be 2.5V or lower please check this. Enabled is yes too so that would be correct. 

 

Please try the linux commands from the HPS command line first (before memory mapping) to make sure that the GPIO's can be set... follow this tutorial for setting the GPIO's  

If there are LED's then you should be just write a active low or high signal to them from the command line.... 

 

Follow this tutorial and see if the LED's light on the gpio then you can start to progress into the memory mapping application code.. 

http://falsinsoft.blogspot.co.uk/2012/11/access-gpio-from-linux-user-space.html 

 

It looks like your code is correct but you need to just make sure that the GPIO is controllable from the drivers in linux the following echo commands will help you enable an GPIO output (number is significant please find out the number of the GPIO from linux and cyclone V handbook for specifying the correct GPIO) here 192 is used as this is from the GPIO controller 2 and is the 1st one your number will be different please check for your correct one. 

 

echo 192 > /sys/class/gpio/export  

echo "out" > /sys/class/gpio/gpio192/direction 

echo 1 > /sys/class/gpio/gpio192/value 

echo 0 > /sys/class/gpio/gpio192/value 

 

The first echo line enables the gpio.... if you get problems here the gpio is already attached to a linux driver and will need removing (look into removing a driver) 

The second enables that channel to become an output as all gpio's are either in or output the default is always input so this enables you send the gpio as high or low...etc 

The next 2 lines will write a high or low value to that gpio you should see the light move on and off if it is correctly enabled. 

 

Best of luck 

 

Kyle 

 

Without finding problems you never learn. 

--- Quote End ---  

0 Kudos
Highlighted
Valued Contributor III
56 Views

Hi kyle, 

 

thanks for your reply.I tried the way you told using the Linux but this did not work.The GPIO was not accessible.so from linux itself I am not able to control.if we solve this then user space code will work. 

 

My Assignment editor looks like this the 2 rows for each pin 

original 

To:GPIO_1[1] Assignment name-> Location PIN_Name(value) Enabled(yes) 

GPIO_1[1] Assignment name-> I/O standard 3.3V LVTTL(value) Enabled(yes) 

 

My changed version 

To:GPIO_1[1] Assignment name-> HPS_IO ON(value) Enabled(yes) 

GPIO_1[1] Assignment name-> I/O standard 3.3V LVTTL(value) Enabled(yes) 

 

Is this correct ??.. Like this I need to enable for all other pins.Is there any thing I missed assigning here???..Let me know.Any configuration changes. 

In the device option also I have chooseb UNUSED pin as INPUT state TRIGERRED. 

 

created the .SOF and programmed and ran the linux command but did not work..Kindly let me know if you see any errors here 

 

thanks in advance 

 

--Ravi
0 Kudos
Highlighted
Valued Contributor III
56 Views

Hey Ravi, 

 

Looks like you have too many assignments.... please remove all... 

For the HPS pin outs... from the GPIO you need to make sure they are selected in the peripheral pin outs as exported GPIO (which you look to have done with GPIO_1). 

This is then built into the top level file with your pin as GPIO_1: INOUT STD_LOGIC in the port declarations and then mapped to the port map for the qsys ip. (part of the tutorial). 

Now this map is to hps_io_hps_io_gpio_inst_GPIO1 => GPIO_1 in your case... so the system is linked to the top level pin (specified as INOUT as this is normal for a GPIO). 

 

Now in order for the preloader to know you want that top level pin [GPIO_1] enabled you need set it once in the assignment editor... 

GPIO_1 Assignment name-> I/O standard 3.3V LVTTL(value) Enabled(yes) <- this is the only one you need... i think you might of named it in a vector or something but just trial one first to make sure your doing it right. 

 

I cannot help you any more than this. If it still not works out it may still be a hardware failure but unlikely. 

 

Best of luck  

 

Kyle
0 Kudos
Highlighted
Valued Contributor III
56 Views

Hi kyle , 

 

Really thankful to you.Just tell me where in the tool we can see the peripheral pin outs and top leve file as mentioned and then the mapping. 

If I get all three then I may get some hint......I cannot see the mapping if I get I might get some idea.. 

 

regards 

Ravi 

 

 

--- Quote Start ---  

Hey Ravi, 

 

 

 

Looks like you have too many assignments.... please remove all... 

For the HPS pin outs... from the GPIO you need to make sure they are selected in the peripheral pin outs as exported GPIO (which you look to have done with GPIO_1). 

This is then built into the top level file with your pin as GPIO_1: INOUT STD_LOGIC in the port declarations and then mapped to the port map for the qsys ip. (part of the tutorial). 

Now this map is to hps_io_hps_io_gpio_inst_GPIO1 => GPIO_1 in your case... so the system is linked to the top level pin (specified as INOUT as this is normal for a GPIO). 

 

Now in order for the preloader to know you want that top level pin [GPIO_1] enabled you need set it once in the assignment editor... 

GPIO_1 Assignment name-> I/O standard 3.3V LVTTL(value) Enabled(yes) <- this is the only one you need... i think you might of named it in a vector or something but just trial one first to make sure your doing it right. 

 

I cannot help you any more than this. If it still not works out it may still be a hardware failure but unlikely. 

 

Best of luck  

 

Kyle 

--- Quote End ---  

0 Kudos
Highlighted
Valued Contributor III
56 Views

Ravi, 

 

I am sorry you need to start with the basics... it involves creating a simple system with your cyclone v soc process (or other processor of your board) with Qsys within quartus, generate the design and create a top level design in either Verilog or VHDL hardware languages. You can then get to grips with it all. 

 

Please if you require further help follow the tutorials within this website. Although might not be available for your board you will be able to follow the process accordingly. 

https://rocketboards.org/ 

 

Best Regards 

 

Kyle
0 Kudos
Highlighted
Valued Contributor III
56 Views

Hi kyle, 

 

Thanks for your reply.I am just a starter in deo nano SOC board.My req is very simple I just wanted to access all the GPIO pins GPIO1 and GPIO0 .since I did it using the C code with HPS_LED and HPS_key I thought I just have to use the existing .SOF.But then since this did not work I generated own .SOF using system builder.But since this said no driver found I had to use qsys tool.This is where I got stuck.I just need a .sof where I can confiure the register and do the toggling and clearing.thats the requirement.so can I use the existing HPS_LED.sof and in that modify the .V file and add the  

.hps_0_hps_io_hps_io_gpio_inst_GPIO01 ( HPS_GPIO_1 ), // .hps_io_gpio_inst_GPIO01 

 

will this eneble the GPIO1 and can I access the register from the linux user space.?? 

 

Need to generate .sof to create this 

 

Kindly let me know. 

Thanks and regards 

Ravi chandran
0 Kudos
Highlighted
Valued Contributor III
56 Views

Hi Kyle, 

 

For the exisiting .v files if I has .hps_io_....GPIO01 ==>GPIO_1 and then compile with qsys and then create .sof then I will be able to access the GPIO1 

If I get an example file which has this I can add the same later I can extend this to other pins and repeat the same for GPIO0. 

 

regards 

Ravi
0 Kudos
Highlighted
Valued Contributor III
56 Views

Hi Kyle, 

 

The issue what I am facing in accessing the GPIO is more to do on the linux side.If I do an echo for 222 which is HPS led 53 then I am able to access.But the same is not possible for GPIO 29 to 34 ...this is GPIO1 or GPIO 0(1 to 8).My .SOF is fine and I am able to link to the top level. 

so what is the change in linux on the board needed to as to access the GPIO??..Kindly help us . 

 

regards 

Ravi chandran 

 

 

--- Quote Start ---  

Ravi, 

 

The Assignment editor needs to be set to Assignment Name [I/O Standard] this is a must is shouldn't be a "location" on the FPGA as there is no location it goes through into the preloader and is linked there. 

The Value is instead set to the Voltage level [3.3-V LVCMOS] your maybe less depending on the hps powered IO's it could be 2.5V or lower please check this. Enabled is yes too so that would be correct. 

 

Please try the linux commands from the HPS command line first (before memory mapping) to make sure that the GPIO's can be set... follow this tutorial for setting the GPIO's  

If there are LED's then you should be just write a active low or high signal to them from the command line.... 

 

Follow this tutorial and see if the LED's light on the gpio then you can start to progress into the memory mapping application code.. 

http://falsinsoft.blogspot.co.uk/2012/11/access-gpio-from-linux-user-space.html 

 

It looks like your code is correct but you need to just make sure that the GPIO is controllable from the drivers in linux the following echo commands will help you enable an GPIO output (number is significant please find out the number of the GPIO from linux and cyclone V handbook for specifying the correct GPIO) here 192 is used as this is from the GPIO controller 2 and is the 1st one your number will be different please check for your correct one. 

 

echo 192 > /sys/class/gpio/export  

echo "out" > /sys/class/gpio/gpio192/direction 

echo 1 > /sys/class/gpio/gpio192/value 

echo 0 > /sys/class/gpio/gpio192/value 

 

The first echo line enables the gpio.... if you get problems here the gpio is already attached to a linux driver and will need removing (look into removing a driver) 

The second enables that channel to become an output as all gpio's are either in or output the default is always input so this enables you send the gpio as high or low...etc 

The next 2 lines will write a high or low value to that gpio you should see the light move on and off if it is correctly enabled. 

 

Best of luck 

 

Kyle 

 

Without finding problems you never learn. 

--- Quote End ---  

0 Kudos
Highlighted
Valued Contributor III
56 Views

Hi Ravi, 

 

It seems you have setup the GPIO's correctly in the .SOF file and are able to access them through linux, so if the GPIO 29 to 34 are linked correctly (or not connected to any HPS controller i.e. SPI, UART etc) and you have doubled checked this. Then your right to assume its a Linux resolution. 

 

What I suggest is you perform the following sequence within linux to correctly make sure no other drivers are linked to the device. To see how the GPIO's are setup for the working pins and also duplicate this driver for the non-working pins. These are the steps: 

 

cat /sys/kernel/debug/gpio 

The above command in Linux performs a category display of the kernel gpio pins... if you have any drivers linked to the gpio numbers it will say here. 

So from this information you need to see if any drivers are linked to the working pins? (e.g. GPIO 222 / HPS_LED 53) - If they are you will need to duplicate this driver by binding it to the correct driver.  

You can do this in Linux or via the Linux Device Tree for a custom built development it suggest just copy the other GPIOs to to a driver and they are linked. 

 

Alternatively if this suggest no drivers are connected to the pins and they are all GPIO output enabled then you need to see if the non-working ones are binded to a driver such as "led-gpio" or alternate drivers dependable on your system configuration. 

If they are this means they are uncontrollable from this point as they are attached direct to a specific driver and need to be un-binded first. (This can be again done in the linux device tree look at where the GPIO's are set up remove and create a new device tree). Or an alternate method would be just to unbind it from Linux itself using the following command syntax below: 

 

echo "leds-gpio" > /sys/bus/platform/drivers/leds-gpio/unbind 

 

Please note where it says leds-gpio for both the echo and driver you need to alter for exactly the same driver that is linked to you system you should then be able to read and write to these GPIO's.. 

 

Does this makes sense? 

 

Best of Luck  

 

Kyle
0 Kudos
Highlighted
Valued Contributor III
56 Views

Hi kyle, 

 

yes this path really make sense.Now to answer your points I have following observations 

 

 

1.when I do cat /sys/kernel/debug/gpio I see the following things 

 

GPIOs 171-197, /soc/gpio@ff70a000: 

GPIOs 198-226, /soc/gpio@ff709000: 

gpio-199 (sysfs ) out hi 

gpio-222 (sysfs ) out hi 

 

GPIOs 227-255, /soc/gpio@ff708000: 

 

when I configure for pin 222 ->HPS_53 and 199->GPIO30 following is oberserved 

 

 

GPIOs 198-226, /soc/gpio@ff709000: 

gpio-199 (sysfs ) out hi 

gpio-222 (sysfs ) out hi 

 

The gpio-222 is linked to HPS_53 and I am able to control through the linux command. value says "hi" here for both but gpio-199 is not seen glowing. 

 

2. while I tried executing your command for unbind  

echo "leds-gpio" > /sys/bus/platform/drivers/leds-gpio/unbind 

 

following error observed:-sh: echo: write error: No such device 

 

Any pointers to get over these errors and accessing the pins??? 

 

Thanks  

Ravi
0 Kudos
Highlighted
Valued Contributor III
56 Views

Hi ravi, 

 

It seems that there isn't anything bound from your debug list.... only the gpio's are set to the 3 controllers of the GPIO core which is as expected. 

 

So from the GPIO point of view...  

GPIOs 227 to 255 would be linked to GPIOs 0 to 28 

GPIOs 198 to 226 would be linked to GPIOs 29 to 57 

GPIOs 171 to 197 would be linked to GPIOs 58 to 66 

 

so GPIO 226 = GPIO 57 ---> from your design pin 

so GPIO 222 = GPIO 53 ---> from your design pin 

so GPIO 199 = GPIO 30 ---> from your design pin (I think this is not the correct GPIO number from what you have said) 

 

So this is the mix up.... 

your not connected to the correctly controller GPIO number.... 

 

So if from your design pin when you want GPIO 0 you need GPIO 227 to be exported... 

 

Hope this helps you 

 

Many Thanks 

 

Kyle
0 Kudos
Highlighted
Valued Contributor III
56 Views

Hi kyle , 

 

even if I export 227 the pin is not glowing this is more to do with unbinding from linux as suggested by you last time 

 

while I tried executing your command for unbind  

echo "leds-gpio" > /sys/bus/platform/drivers/leds-gpio/unbind 

 

following error observed:-sh: echo: write error: No such device 

 

Any pointers to get over these errors and accessing the pins??? 

 

Let me know how I can make the pins unbind....then all the pins shall be accessed. 

 

regards 

Ravi chandran
0 Kudos
Highlighted
Valued Contributor III
56 Views

Hi kyle , 

 

with respect to GPIO 0 also this is what is seen when I do cat /sys/kernel/debug/gpio 

 

GPIOs 171-197, /soc/gpio@ff70a000: 

 

 

GPIOs 198-226, /soc/gpio@ff709000: 

 

GPIOs 227-255, /soc/gpio@ff708000: 

gpio-227 (sysfs ) out hi 

gpio-228 (sysfs ) out lo 

 

but 227 and 228 which corresponds to GPIO 0[0] and GPIO_0[1] does not glow....Linux is binding I think ..if I do unbind 

 

echo "leds-gpio" > /sys/bus/platform/drivers/leds-gpio/unbind 

-sh: echo: write error: No such device 

 

so I need to get over this problem so as to access GPIO's..what is the way to do this??..any idea. 

 

regards 

Ravi
0 Kudos