Gpio doesn't work on HiFive1 rev B [SOLVED]


(Krists) #1

I have written simple program with crude delay (sleep() doesn’t work and cpu interupt is too complicated for quick testing) to toggle pin high and low to blink led:

#include <stdio.h>

//#include <unistd.h>
#include <time.h>
#include <metal/gpio.h>


void delay(int number_of_seconds) //not actually number of seconds
{

    // Converting time into milli_seconds
    int milli_seconds = 1000 * number_of_seconds;

    // Stroing start time
    clock_t start_time = clock();

    // looping till required time is not acheived
    while (clock() < start_time + milli_seconds);

}



int main (void)
{

	struct metal_gpio *gpio_device;

	gpio_device = metal_gpio_get_device(0);

	//I have tried these in all combinations, but it still doesn't work
	//metal_gpio_toggle_pin(gpio_device, 13); //13 is the pin
	//metal_gpio_disable_input(gpio_device, 13);
	//metal_gpio_enable_output(gpio_device, 13);
	printf("metal_gpio_set_pin \n");

	unsigned int d0 = 0;
	while (1)
	{
		metal_gpio_set_pin(gpio_device, 14, 1); //this line does absalutely nothing
		//sleep (1000);
		delay(10000); //10000 = 1 second
		metal_gpio_set_pin(gpio_device, 14, 0); //this line does absalutely nothing
		delay(10000);
		++d0;
		printf("debug: %u \n", d0);
	}

	//metal_gpio_set_pin(gpio_device, 15, 200); //pin device, pin, state

    return 0;
}

I am experiencing very weird behavior. 15. and 16. pins are permamently on, 14. pin is permamently off. 13. pin flashes 2 or 3 times fast at program start. I have no slightest clue, what I am doing wrong since there are exacly 0 sample programs for manipulating pins. There is absalute shortage of sample programs. Keep in mind, that I have spent hours trying different combinations and none of them work. I looked in Metal documentation about gpio (https://sifive.github.io/freedom-metal-docs/apiref/gpio.html).

I am using Ubuntu 19.04 and latest Freedom Studio (Version: 4.7.2.2019-03-4). I have HiFive1 Rev B board.

What I am doing wrong?

Edit: I was using the incorect pins. I should have used gpio pins (last page contains layout - https://sifive.cdn.prismic.io/sifive%2F8d7b8385-64e3-4914-8608-8568412c8aae_hifive1b-getting-started-guide.pdf)

I performed a test and there are list of pins that work: 2, 3, 4, 5, 6, 7, 9, 10, 16, 17, 18, 19
I hope, that someone finds this helpful. BTW gpio pins 19, 21, 22 are responsible for RGB led, but behaviour is weird, if you use more than 1 color at the time.


#2

Hey!
Be aware that the pin number is not equivalent to the gpio number.
You can find a diagram on the last page of the Getting Started Guide.
I get it working changing these lines of your code:

...
metal_gpio_enable_output(gpio_device, 16);
...
metal_gpio_set_pin(gpio_device, 16, 1);
...
metal_gpio_set_pin(gpio_device, 16, 0); 
...

I’m able to get a flashing led on pin 2 which corresponds to gpio 16.

Still I also see strange results when trying this for pin 13 (gpio 5). The same with some other pins.
I think it might be that there are io_function active on these pins like PWM, UART and so on.
I didn’t have time yet to test all pins and figure out how to disable the io_function, but I’ll try to later.

edit:
Indeed it was the io_functions leading to strange behavior of some gpios.
I couldn’t find a metal function to do this, but I managed to disable them with the following asm:

#define GPIOBASE	0x10012000
#define GPIO_IOF_EN     0x38
li t0, GPIOBASE
sw zero, GPIO_IOF_EN(t0)

still not under my control is pin 12 for whatever reason


(Adharsh s) #3

hello i have the issue.
I cant get an LED blinking connected o pin 2.
also random pins on my board(hifi 1 rev b) are always HIGH.
can you please help


#4

Are you talking about GPIO pin 2 (physical pin 10) or physical pin 2 (GPIO pin 18)?

I’ve just tested with some rust code and everything works for me for both pins. You need to make sure the pin is asserted into output mode only. If you want I can gist the code but as I said it’s in rust.


(Adharsh s) #5

physical pin 2 GPIO pin 18.

can you please share the test code with me. It’ll be of great help


#6

Here’s the code

It uses the hifive1 crate and others from the rust embedded-hal side.

Video of working LED

NOTE: the pin!(gpio, dig2) macro just translates to gpio.pin18

Also forgot to mention I’m using latest greatest with updates from @Disasm meaning if you want to get this to work using current crate versions you will need to use the older e310x-hal approach using Peripherals struct instead of the DeviceResources. Those aren’t published yet. Or you can check out the latest master branches and use a workspace :smiley:


(Adharsh s) #7

Thank You
I will look into it.