Page 2 of 3

Re: Simple GPIO

Posted: Thu Dec 04, 2014 11:43 am
by Kampi
*push*

Re: Simple GPIO

Posted: Thu Dec 04, 2014 6:15 pm
by Peter H
Was there a question? You have already been shown working code with an explanation of how it works.

Re: Simple GPIO

Posted: Thu Dec 04, 2014 8:43 pm
by Kampi
Sorry for confusion.
The Code doesn't work :(
I try to set a GPIO as an Outout, but if I run this Programm and read out the "direction" file of that GPIO he is already marked as an input.

This is my GPIO Lib (use a fix GPIO in the "Set_Dir" Function:
Code: Select all
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>

#define BLOCK_SIZE         4096
#define Bus_Base         0x10000000

struct RT5350_Peripherie {
   unsigned long Adresse;
   int Memory;
   void *Map;
   volatile unsigned int *Addr;
};

struct RT5350_Peripherie Bus = {Bus_Base};

int Wert = 0;

int RAM_Map(struct RT5350_Peripherie *Peripherie)
{
   Peripherie->Memory = open("/dev/mem", O_RDWR);

   if(Peripherie->Memory < 0)
   {
      printf("Kein Zugriff auf /dev/mem!\n\r");
      return -1;
   }

   Peripherie->Map = mmap(
      NULL,
      BLOCK_SIZE,
      PROT_READ | PROT_WRITE,
      MAP_SHARED,
      Peripherie->Memory,
      Peripherie->Adresse
   );

   if(Peripherie->Map < 0)
   {
      printf("Peripherie mappen fehlgeschlagen!\n\r");
      return -1;
   }

    Peripherie->Addr = (volatile unsigned int *)Peripherie->Map;

   return 0;
}

int GPIO_Init(void)
{
   if(RAM_Map(&Bus) == -1)
   {
      printf("GPIO Mappen fehlgeschlagen!\n\r");
      return -1;
   }

   return 0;
}

int Set_Dir(int IO, char *Dir)
{
   int Offset = 0;
   int Shift = 0;

   /*if(IO < 22)
   {
      Offset = (0x624>>2);
      Shift = IO;
   }
   else if((IO > 21) & (IO < 29))
   {
      Offset = (0x674>>2);
      Shift = IO - 22;
   }
   else
   {
      printf("Ungueltiger Wert fuer IO!\n\r");
      return -1;
   }

   if(Dir == "I")
   {
      *(Bus.Addr + Offset) |= (1 << Shift);
   }
   else if(Dir == "O")
   {
      *(Bus.Addr + Offset) &= ~(1 << Shift);
   }
   else
   {
      printf("Ungueltiger Wert fuer Dir!\n\r");
      return -1;
   }*/

   Wert = *(Bus.Addr + (0x67c >> 2));
   printf("Offset: %i\n\r", Wert);
   printf("IO: %i\n\r", (1 << Shift));

   return 0;
}

Re: Simple GPIO

Posted: Fri Dec 05, 2014 9:29 pm
by Greenwire-Elektronik
i just tried what you have done - set the direction in 0x624h to 1 for the corresponding pin and then toggled the pin (0x634h) - value changes as does the voltage do - it is just a problem with the OS which will still show IN as direction - i do not think that i will be updated because this would mean that the system polls the status of all GPIOs.
You should validate your code with the voltage meter, not with the direction file :)

Rgds,

Jonas

Re: Simple GPIO

Posted: Sat Dec 06, 2014 9:58 am
by Kampi
Great! Thanks for your response!
I will try it later with my oscilloscope :)

Re: Simple GPIO

Posted: Sat Dec 06, 2014 12:03 pm
by Kampi
Hey,

I try the same with this Code:

Code: Select all
   *(Bus.Addr + (0x624 >> 2)) = 1 << 2;
   *(Bus.Addr + (0x634 >> 2)) = 1 << 2;


This should toggle Pin 2, but nothing happens. I check it with my oscilloscope. :(

Re: Simple GPIO

Posted: Sat Dec 06, 2014 4:43 pm
by Greenwire-Elektronik
Kampi wrote:Hey,

I try the same with this Code:

Code: Select all
   *(Bus.Addr + (0x624 >> 2)) = 1 << 2;
   *(Bus.Addr + (0x634 >> 2)) = 1 << 2;


This should toggle Pin 2, but nothing happens. I check it with my oscilloscope. :(


No wonder - if you look up the directory /sys/class/gpio you find all gpios which are exported - means available in user space. gpio 2 is not available, i think this might be the reason for your problem. You can try it with e.g. gpio14.
On a second thought (without checking) it could also be a problem with the multiplexed function on that pin which might interfere here.

Rgds

Jonas

Re: Simple GPIO

Posted: Sun Dec 07, 2014 3:45 pm
by Vonger
First make sure GPIO 26 is able to be used as GPIO. It is not be taken be other protocol.
Then make sure export the GPIO first(if you directly write to register, that is not necessary)
If the two steps are all right, it should be OK to use.

Re: Simple GPIO

Posted: Sun Dec 07, 2014 5:38 pm
by franki
I have vocore mounted in a self-made board... to verify the GPIO out from GPIO22 to GPIO26, a LED with a 330 ohms resistor in every out pin.... and the code works for me, but a little change....

The registers for de GPIO22 to GPIO26 are offset 0x670 to 0x684....


Code: Select all
*(gpio + (0x674 >> 2)) = 31;
*(gpio + (0x684 >> 2)) = 31;


and this is the result for toggle is OK!!!

Image

Image

Re: Simple GPIO

Posted: Sun Dec 07, 2014 9:02 pm
by Kampi
Thanks it works now, but I think I found a misstake in the Datasheet (see attachment).
I think they swap the Description of Set and Clear....