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