mpc8323e-rdb GPIO under Linux

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

mpc8323e-rdb GPIO under Linux

Jump to solution
3,106 Views
admin
Specialist II

How to drive GPIO on this board? There are 3 leds G Y R connected to GPIO ports 416,417,418... There is no driver for GPIO and there are no normal headers in cross-tools(Ltib cross tools, come with this kit) to do this...

0 Kudos
Reply
1 Solution
1,611 Views
admin
Specialist II

I've made it!!! If it would be usefull here working code:

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>

#define PIO_BASE 0xE0001400
#define MAP_SIZE 4096UL
#define MAP_MASK (MAP_SIZE-1)

volatile unsigned long *CPDATD; //PortD data register
volatile unsigned long *CPDIR2D; //PortD datadirection2 register
int main (void)
{
void *pio;
int fd, i;
if ((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1) {
printf("Failed to open /dev/mem \n");
return -1;
}
pio = mmap(0, MAP_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, PIO_BASE & ~MAP_MASK);
CPDATD = (volatile unsigned long *)(pio + ((PIO_BASE+0x4C) & MAP_MASK));
CPDIR2D = (volatile unsigned long *)(pio + ((PIO_BASE+0x54) & MAP_MASK));

*CPDIR2D &= ~(0xFF<<24);
*CPDIR2D |= (21UL<<26); //PD16 PD17 PD18 output
for (i=0; i<10; i++) {
*CPDATD ^= (15UL<<13); // turn ON Red Yellow Green LEDs (port D16,D17,D18)
sleep(1);
}
*CPDATD |= (15UL<<13);
if (munmap(pio, MAP_SIZE) == -1) {
printf("Memory unmap failed.\n");}

close(fd);
return 0;
}


View solution in original post

0 Kudos
Reply
3 Replies
1,611 Views
admin
Specialist II

Final code... All is right... But don't work...

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>

#define PIO_BASE 0xE0000000
#define MAP_SIZE 4096UL
#define MAP_MASK (MAP_SIZE-1)

volatile unsigned long *CPDATD; //PortD data register
volatile unsigned long *CPDIR2D; //PortD datadirection2 register
volatile unsigned long *CPODRD; //PortD OPENDRAIN register
volatile unsigned long *CPARD; //PortD Assigment register
volatile unsigned long *IMMR; //IMMR
int main (void)
{
void *pio, *virt_addr;
int fd;
if ((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1) {
printf("Failed to open /dev/mem \n");
return -1;
}
pio = mmap(0, MAP_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, PIO_BASE & ~MAP_MASK);
virt_addr = pio;
IMMR = (volatile unsigned long *)pio;
CPARD = (volatile unsigned long *)(pio + ((PIO_BASE+0x145C) & MAP_MASK));
CPODRD = (volatile unsigned long *)(pio + ((PIO_BASE+0x1448) & MAP_MASK));
CPDATD = (volatile unsigned long *)(pio + ((PIO_BASE+0x144C) & MAP_MASK));
CPDIR2D = (volatile unsigned long *)(pio + ((PIO_BASE+0x1454) & MAP_MASK));

printf("IMMR = 0x%08x\n", *IMMR); // IMMRBAR(0xE0000000) to ensure that it is a right page of memory
*CPARD &= ~3UL; // Assigment on GPO16,17,18
printf("CPARD = 0x%08x\n", *CPARD); //echo CPARD
*CPODRD =0; //reset open-drain register
printf("CPODRD = 0x%08x\n", *CPODRD); //echo CPODRD
*CPDIR2D &= ~3UL; //set output
*CPDIR2D |= 5; //PD16 and PD17 as output
printf("CPDIR2D = 0x%08x\n", *CPDIR2D); //echo CPDIR2D
*CPDATD &= ~3UL; // turn ON Red LED (port D16) andYellow LED (port D17);
printf("CPDATD = 0x%08x\n", *CPDATD); //echo CPDATD
sleep(1); //1 second pause
if (munmap(pio, MAP_SIZE) == -1) {
printf("Memory unmap failed.\n");}

close(fd);
return 0;
}
------------------------------

At the output:

/mnt/nfs/gpio # ./a.out
IMMR = 0xe0000000
CPARD = 0x00000000
CPODRD = 0x00000000
CPDIR2D = 0x00000000
CPDATD = 0x00000000

---------------------------------

IMMR is right... But other register not changed :smileysad: Why?

0 Kudos
Reply
1,612 Views
admin
Specialist II

I've made it!!! If it would be usefull here working code:

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>

#define PIO_BASE 0xE0001400
#define MAP_SIZE 4096UL
#define MAP_MASK (MAP_SIZE-1)

volatile unsigned long *CPDATD; //PortD data register
volatile unsigned long *CPDIR2D; //PortD datadirection2 register
int main (void)
{
void *pio;
int fd, i;
if ((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1) {
printf("Failed to open /dev/mem \n");
return -1;
}
pio = mmap(0, MAP_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, PIO_BASE & ~MAP_MASK);
CPDATD = (volatile unsigned long *)(pio + ((PIO_BASE+0x4C) & MAP_MASK));
CPDIR2D = (volatile unsigned long *)(pio + ((PIO_BASE+0x54) & MAP_MASK));

*CPDIR2D &= ~(0xFF<<24);
*CPDIR2D |= (21UL<<26); //PD16 PD17 PD18 output
for (i=0; i<10; i++) {
*CPDATD ^= (15UL<<13); // turn ON Red Yellow Green LEDs (port D16,D17,D18)
sleep(1);
}
*CPDATD |= (15UL<<13);
if (munmap(pio, MAP_SIZE) == -1) {
printf("Memory unmap failed.\n");}

close(fd);
return 0;
}


0 Kudos
Reply
1,611 Views
admin
Specialist II

 

After 2 days of searching I find that to drive gpio I should directly access to mem.

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>

#define PIO_BASE 0x0x00001400

volatile unsigned int *CPDATD; //PortD data register
volatile unsigned int *CPDIR2D; //PortD datadirection2 register

int main (void)
{
//long delay=128000, delay2=100;
unsigned char *gpio;
int fd;
fd = open("/dev/mem", O_RDWR);
if (fd < 0){
printf("Failed to open /dev/mem");
return fd;
}
gpio = mmap(0, getpagesize(), PROT_READ|PROT_WRITE, MAP_SHARED, fd, PIO_BASE);

CPDATD = (unsigned int *)(gpio + 0x4C); //data
CPDIR2D = (unsigned int *)(gpio + 0x54);

*CPDIR2D |= 0x02;//set output
*CPDATD ^= (1 << 16);// turn ON Red LED (port D16)

return 0;
}
I've read PIOaddress from datasheet...

0x00_1400–0x00_17FF QUICC Engine parallel I/O ports

Program give error: Segmentation fault

I think that PIOaddress is wrong... I searched it in kernel and didn't find it.

0 Kudos
Reply