Re: Simple GPIO
Posted: Sun Dec 07, 2014 9:53 pm
by franki
Yes, it's a mistake....
Offset 0x067c is for PIORESET, and Offset 0x0680 for PIOSET... I probe now...
Be careful!!
Re: Simple GPIO
Posted: Sun Dec 07, 2014 10:16 pm
by Kampi
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.
Re: Simple GPIO
Posted: Mon Dec 08, 2014 5:05 pm
by franki
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!!
Re: Simple GPIO
Posted: Tue Jan 27, 2015 2:56 pm
by Pyrofer
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?
Re: Simple GPIO
Posted: Sat Mar 26, 2016 6:15 pm
by ArkEngr
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;
}