Yes, it's a mistake....
Offset 0x067c is for PIORESET, and Offset 0x0680 for PIOSET... I probe now...
Be careful!!
Simple GPIO
- franki
- Posts: 7
- Joined: Wed Nov 05, 2014 2:31 pm
- Location: Usa
- Kampi
- Posts: 14
- Joined: Tue Nov 25, 2014 6:50 am
Re: Simple GPIO
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.
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 3754 times
- franki
- Posts: 7
- Joined: Wed Nov 05, 2014 2:31 pm
- Location: Usa
Re: Simple GPIO
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...
enjoy!!
- 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
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?
Can you tell me what to change to read 07?
- ArkEngr
- Posts: 38
- Joined: Tue Oct 20, 2015 1:58 pm
Re: Simple GPIO
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;
}
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;
}
Who is online
Users browsing this forum: No registered users and 57 guests