Simple GPIO

franki
 
Posts: 7
Joined: Wed Nov 05, 2014 2:31 pm

Re: Simple GPIO

Sun Dec 07, 2014 9:53 pm

Yes, it's a mistake....

Offset 0x067c is for PIORESET, and Offset 0x0680 for PIOSET... I probe now...

Be careful!!

Kampi
 
Posts: 14
Joined: Tue Nov 25, 2014 6:50 am

Re: Simple GPIO

Sun Dec 07, 2014 10:16 pm

No I mean the description.
You have to add 0x50 for each Low-Register to generate the address of the High-Register.
So you have Dir_Low = 0x24 and Dir_High 0x74.
So I think only the description is wrong, because they write for the Set-Register:
"... Writing a '1' clears the corrosponding.." :)

By the way...in the attachment you find a current version of my GPIO-Lib and a example + Makefile (you only have to change the path to the MIPS-Cross Compiler in the Makefile).
Reading, writing, toggling and changing of polarity works. Maybe some guys need something like that.
Attachments
IO.zip
(2.14 KiB) Downloaded 241 times

franki
 
Posts: 7
Joined: Wed Nov 05, 2014 2:31 pm

Re: Simple GPIO

Mon Dec 08, 2014 5:05 pm

Yes... i make too a sample code to drive de free-GPIO of Vocore... GPIO22 to GPIO26... Is a 1.0 Version, but is the start-point of another more avanced future code... if someone need it, is here...

Code: Select all
#include <sys/types.h>
#include <sys/mman.h>
#include <err.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <math.h>

#define BLOCK   4096
#define BASE   0x10000000

unsigned int* gpio;

void GPIO_Init(){   // Inicializa los GPIO 22-26... OK
   
   int Memory;
   
   Memory = open("/dev/mem", O_RDWR);

     if(Memory==-1)
      err(1, "Error abriendo /dev/mem\n\r");
        else {
      gpio = mmap(0, BLOCK, PROT_READ|PROT_WRITE,  MAP_SHARED, Memory, BASE);
      *(gpio + (0x674 >> 2)) = 0;
   }

   close(Memory);
}

void GPIO_Dir(int numero, char accion){      // Define los GPIO 22-26 como Entrada/Salida... OK

   int potencia = numero - 22;
   int GPIO_number = pow(2, potencia);

   // numero va desde 22 a 26, los GPIO libres...

   // accion: 
   //   'I' = GPIO definido como entrada
   //   'O' = GPIO definido como salida

   if ((numero>=22) && (numero<=26))
      switch(accion){
         case 'O': *(gpio + (0x674 >> 2)) = *(gpio + (0x674 >> 2)) | GPIO_number; break;
         case 'I': *(gpio + (0x674 >> 2)) = *(gpio + (0x674 >> 2)) & ~GPIO_number; break;
         default: err(1, "\nAccion no reconocida...\n\r"); break;
      }
   else err(1, "\nGPIO fuera de rango...\n\r");
}

void GPIO_Action(int numero, char accion){

   int potencia = numero - 22;
   int GPIO_number = pow(2, potencia);
   int base = 0;

   //numero va desde 22 a 26, los GPIO libres...
   //accion:
   //   'S' = GPIO a "set", la salida entrega 1 logico.
   //   'R' = GPIO a "reset", la salida entrega 0 logico.

   switch(accion){
      case 'S': base = 0x67c; break;   
      case 'R': base = 0x680; break;
      default: err(1, "\nAccion no reconocida...\n\r");break;
   }

   if ((numero>=22) && (numero<=26))
      *(gpio + (base >> 2)) = GPIO_number;
   else
      err(1, "\nGPIO fuera de rango...\n\r");

}

int GPIO_Read(int numero){

   int potencia = numero -22;
   int GPIO_number = pow(2, potencia);
   int lectura = 0;

   // numero va desde 22 a 26, los GPIO libres...
   // lectura entregara 1 si la entrada esta a "1" logico, correspondiente a un nivel de hasta 3.3 voltios.
   // lectura entregara 0 si la entrada esta a "0" logico, correspondiente a un nivel de 0 voltios.
   // por las caracteristicas de Vocore, no utilizar mas de 3.3 Voltios en la entrada o podria dañarse.
   // no conectar una entrada a 0, para despues entregar salida "1", podria dañar el Vocore.

   if((numero>=22) && (numero<=26))
      lectura = *(gpio + (0x670 >> 2)) & GPIO_number;
   else
      err(1, "\nGPIO fuera de rango...\n\r");

   if(lectura>0)
      lectura = 1;
   else
      lectura = 0;
   return lectura;
}

void GPIO_Toggle(int numero, char accion){
   
   int potencia = numero -22;
   int GPIO_number = pow(2, potencia);

   // numero va desde 22 a 26, los GPIO libres...
   // accion:
   //   'Y' = Toggle activado en el GPIO "numero"
   //   'N' = Toggle desactivado en el GPIO "numero"
   
   if ((numero>=22) && (numero<=26))
      switch(accion){
         case 'Y': *(gpio + (0x684 >> 2)) = *(gpio + (0x684 >> 2)) | GPIO_number; break;
         case 'N': *(gpio + (0x684 >> 2)) = *(gpio + (0x684 >> 2)) & ~GPIO_number; break;
         default: err(1, "\nAccion no reconocida...\n\r"); break;
      }
   else
      err(1, "\nGPIO fuera de rango...\n\r");
}


enjoy!!

Pyrofer
 
Posts: 61
Joined: Tue Oct 21, 2014 11:35 am

Re: Simple GPIO

Tue Jan 27, 2015 2:56 pm

Hi, I am trying to read GPIO 07, and your code obviously can't do this...

Can you tell me what to change to read 07?

ArkEngr
 
Posts: 29
Joined: Tue Oct 20, 2015 1:58 pm

Re: Simple GPIO

Sat Mar 26, 2016 6:15 pm

My expanded version (in english) to handle lower numbered I/O ports with sample main()
Tested main this morning.


#include <sys/types.h>
#include <sys/mman.h>
#include <err.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <math.h>

#define BLOCK 4096
#define BASE 0x10000000

void GPIO_Init(void);
void GPIO_Dir(int gpio_number, char action);
void GPIO_Action(int gpio_number, char action);
int GPIO_Read(int gpio_number);
void GPIO_Toggle(int gpio_number, char action);

unsigned int* gpio;

int main(int argc, char *argv[])
{
GPIO_Init();
GPIO_Dir(2, 'O');
GPIO_Dir(17, 'O');

while(1)
{
GPIO_Toggle(2, 'Y');
GPIO_Toggle(17, 'Y');
}
}


/* Initialize the GPIO pins 22-26... OK */
/* Expanded for the GPIO pins 0 - 21 */
void GPIO_Init(void)
{
int Memory;

Memory = open("/dev/mem", O_RDWR);

if(Memory == -1)
{
err(1, "Error opening /dev/mem\n\r");
}
else
{
gpio = mmap(0, BLOCK, PROT_READ|PROT_WRITE, MAP_SHARED, Memory, BASE);
*(gpio + (0x674 >> 2)) = 0; /* 74 is offset for GPIO 22 - 26 direction register, 0 sets all as inputs */
*(gpio + (0x624 >> 2)) = 0; /* 24 is offset for GPIO 00 - 21 direction register, 0 sets all as inputs */
}

close(Memory);

*(gpio + (0x060 >> 2)) |= 1; /* Deactive I2C */
}

/* Define the GPIO 22-26 pins as Inputs/Outputs... OK */
/* Define the GPIO 00-21 pins as Inputs/Outputs... OK */
void GPIO_Dir(int gpio_number, char action)
{
int power;
int GPIO_pin;

// gpio_number goes from 00 to 26

if((gpio_number >= 0) && (gpio_number <= 21))
{
power = gpio_number;
}
else if((gpio_number >= 22) && (gpio_number <= 26))
{
power = gpio_number - 22;
}
else
{
err(1, "\nGPIO number out of range...\n\r");
}

GPIO_pin = pow(2, power);

// action:
// 'I' = GPIO defined as input
// 'O' = GPIO defined as output

if((gpio_number >= 0) && (gpio_number <= 21))
{
switch(action)
{
case 'O': *(gpio + (0x624 >> 2)) = *(gpio + (0x624 >> 2)) | GPIO_pin; break;
case 'I': *(gpio + (0x624 >> 2)) = *(gpio + (0x624 >> 2)) & ~GPIO_pin; break;
default: err(1, "\naction not legal...\n\r"); break;
}
}
else if((gpio_number >= 22) && (gpio_number <= 26))
{
switch(action)
{
case 'O': *(gpio + (0x674 >> 2)) = *(gpio + (0x674 >> 2)) | GPIO_pin; break;
case 'I': *(gpio + (0x674 >> 2)) = *(gpio + (0x674 >> 2)) & ~GPIO_pin; break;
default: err(1, "\naction not legal...\n\r"); break;
}
}
else
{
err(1, "\nGPIO number out of range...\n\r");
}

return;
}

void GPIO_Action(int gpio_number, char action)
{
int power;
int GPIO_pin;
int base = 0;

// gpio_number goes from 00 to 26

if((gpio_number >= 0) && (gpio_number <= 21))
{
power = gpio_number;
}
else if((gpio_number >= 22) && (gpio_number <= 26))
{
power = gpio_number - 22;
}
else
{
err(1, "\nGPIO number out of range...\n\r");
}

GPIO_pin = pow(2, power);

//action:
// 'S' = GPIO a "set", configured value 1 logic.
// 'R' = GPIO a "reset", configured value 0 logic.

if((gpio_number >= 0) && (gpio_number <= 21))
{
switch(action)
{
case 'S': base = 0x62C; break;
case 'R': base = 0x630; break;
default: err(1, "\naction not legal...\n\r");break;
}
}
else if((gpio_number >= 22) && (gpio_number <= 26))
{
switch(action)
{
case 'S': base = 0x67C; break;
case 'R': base = 0x680; break;
default: err(1, "\naction not legal...\n\r");break;
}
}
else
{
err(1, "\nGPIO number out of range...\n\r");
}

*(gpio + (base >> 2)) = GPIO_pin;

return;
}

int GPIO_Read(int gpio_number)
{
int power;
int GPIO_pin;
int value_read = 0;

// gpio_number goes from 00 to 26

if((gpio_number >= 0) && (gpio_number <= 21))
{
power = gpio_number;
}
else if((gpio_number >= 22) && (gpio_number <= 26))
{
power = gpio_number - 22;
}
else
{
err(1, "\nGPIO number out of range...\n\r");
}

GPIO_pin = pow(2, power);

// value_read returns 1 if the value read is a "1" logic, corresponding to a voltage of 3.3 volts.
// value_read returns 0 if the value read is a "0" logic, corresponding to a voltage of 0.0 volts.
// The limitations of Vocore are defined not to use more than 3.3 volts at any gpio pin or it could be damaged.
// A gpio pin tied to ground with an output of "1" could damage the Vocore.

if((gpio_number >= 0) && (gpio_number <= 21))
{
value_read = *(gpio + (0x620 >> 2)) & GPIO_pin;
}
else if((gpio_number >= 22) && (gpio_number <= 26))
{
value_read = *(gpio + (0x670 >> 2)) & GPIO_pin;
}
else
{
err(1, "\nGPIO number out of range...\n\r");
}

if(value_read > 0)
{
value_read = 1;
}
else
{
value_read = 0;
}

return value_read;
}

void GPIO_Toggle(int gpio_number, char action)
{
int power;
int GPIO_pin;

// gpio_number goes from 00 to 26

if((gpio_number >= 0) && (gpio_number <= 21))
{
power = gpio_number;
}
else if((gpio_number >= 22) && (gpio_number <= 26))
{
power = gpio_number - 22;
}
else
{
err(1, "\nGPIO number out of range...\n\r");
}

GPIO_pin = pow(2, power);

// action:
// 'Y' = Toggle the GPIO pin defined as the "gpio_number"
// 'N' = Do nothing to the GPIO pin defined as the "gpio_number"

if((gpio_number >= 0) && (gpio_number <= 21))
{
switch(action)
{
case 'Y': *(gpio + (0x634 >> 2)) = *(gpio + (0x634 >> 2)) | GPIO_pin; break; /* This toggles the gpio pin */
case 'N': *(gpio + (0x634 >> 2)) = *(gpio + (0x634 >> 2)) & ~GPIO_pin; break; /* This has no affect on gpio pin */
default: err(1, "\naction not legal...\n\r"); break;
}
}
else if((gpio_number >= 22) && (gpio_number <= 26))
{
switch(action)
{
case 'Y': *(gpio + (0x684 >> 2)) = *(gpio + (0x684 >> 2)) | GPIO_pin; break; /* This toggles the gpio pin */
case 'N': *(gpio + (0x684 >> 2)) = *(gpio + (0x684 >> 2)) & ~GPIO_pin; break; /* This has no affect on gpio pin */
default: err(1, "\naction not legal...\n\r"); break;
}
}
else
{
err(1, "\nGPIO number out of range...\n\r");
}

return;
}

Previous
Return to VoCore & VoCore+Dock

Who is online

Users browsing this forum: No registered users and 2 guests