Accessing Registers from USERLAND! (C/C++)

SeppBauer
have fun:
##################################


#include "ports.h"
 
 
extern "C" {
 
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <errno.h>
    #include <signal.h>
    #include <fcntl.h>
    #include <ctype.h>
    #include <termios.h>
    #include <sys/types.h>
    #include <sys/mman.h>
 
    #define FATAL do { fprintf(stderr, "Error at line %d, file %s
(%d)[%s]\n", __LINE__, __FILE__, errno, strerror(errno)); exit(1); }
while(0)
 
 
 
    #define MAP_SIZE 4096UL //1000000000000UL
    #define MAP_MASK (MAP_SIZE - 1) //111111111111UL
 
    int setPin(off_t control, int shift, int state) {
        int fd;
        void *map_base, *virt_addr;
        off_t target;
 
        //################################################### SET PIN
###################################################
        //control=rGPGDAT;
 
 
        if((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1) FATAL;
        map_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED,
fd,control & ~MAP_MASK);
        if(map_base == (void *) -1) FATAL;
 
        virt_addr = (char*)map_base + (control & MAP_MASK);
        unsigned long tmp=*(unsigned long *)virt_addr;
 
        if(state==1)tmp |= (1<<shift);  //set bit "shift"
        else tmp &= ~(1<<shift); //erase bit "shift"
        unsigned long *va=(unsigned long *)virt_addr;
        *va = tmp;//the write operation
 
        if(munmap(map_base, MAP_SIZE) == -1) FATAL;
        close(fd);
 
 
        return true;
    }
 
 
 
    unsigned long readReg(off_t control) {//read whole register
        int fd;
        void *map_base, *virt_addr;
        off_t target;
 
 
        if((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1) FATAL;
        map_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED,
fd,control & ~MAP_MASK);
        if(map_base == (void *) -1) FATAL;
 
        virt_addr = (char*)map_base + (control & MAP_MASK);
        unsigned long tmp=*(unsigned long *)virt_addr;
 
        if(munmap(map_base, MAP_SIZE) == -1) FATAL;
        close(fd);
 
        //read_result = *((unsigned long *) virt_addr);
 
        return tmp;
    }
 
 
    int readPin(off_t control,int shift) {//read PIN
        int fd;
        void *map_base, *virt_addr;
        off_t target;
 
        unsigned long mask=0;
 
 
        if((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1) FATAL;
        map_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED,
fd,control & ~MAP_MASK);
        if(map_base == (void *) -1) FATAL;
 
        virt_addr = (char*)map_base + (control & MAP_MASK);
        unsigned long tmp=*(unsigned long *)virt_addr;
 
        if(munmap(map_base, MAP_SIZE) == -1) FATAL;
        close(fd);
 
        mask |= (1<<shift);
 
        if(tmp&mask) return 1;
        else return 0;
    }
 
 
 
}
 
 
###########################
 
ports.h
 
 
#ifndef __2440ADDR_H__
#define __2440ADDR_H__
 
// UART
#define rULCON0     0x50000000  //UART 0 Line control
#define rUCON0      0x50000004  //UART 0 Control
#define rUFCON0     0x50000008  //UART 0 FIFO control
#define rUMCON0     0x5000000c  //UART 0 Modem control
#define rUTRSTAT0   0x50000010  //UART 0 Tx/Rx status
#define rUERSTAT0   0x50000014  //UART 0 Rx error status
#define rUFSTAT0    0x50000018  //UART 0 FIFO status
#define rUMSTAT0    0x5000001c  //UART 0 Modem status
#define rUBRDIV0    0x50000028  //UART 0 Baud rate divisor
 
#define rULCON1     0x50004000  //UART 1 Line control
#define rUCON1      0x50004004  //UART 1 Control
#define rUFCON1     0x50004008  //UART 1 FIFO control
#define rUMCON1     0x5000400c  //UART 1 Modem control
#define rUTRSTAT1   0x50004010  //UART 1 Tx/Rx status
#define rUERSTAT1   0x50004014  //UART 1 Rx error status
#define rUFSTAT1    0x50004018  //UART 1 FIFO status
#define rUMSTAT1    0x5000401c  //UART 1 Modem status
#define rUBRDIV1    0x50004028  //UART 1 Baud rate divisor
#define rULCON2     0x50008000  //UART 2 Line control
#define rUCON2      0x50008004  //UART 2 Control
#define rUFCON2     0x50008008  //UART 2 FIFO control
#define rUMCON2     0x5000800c  //UART 2 Modem control
#define rUTRSTAT2   0x50008010  //UART 2 Tx/Rx status
#define rUERSTAT2   0x50008014  //UART 2 Rx error status
#define rUFSTAT2    0x50008018  //UART 2 FIFO status
#define rUMSTAT2    0x5000801c  //UART 2 Modem status
#define rUBRDIV2    0x50008028  //UART 2 Baud rate divisor
 
 
// I/O PORT 
#define rGPACON    0x56000000   //Port A control
#define rGPADAT    0x56000004   //Port A data
 
#define rGPBCON    0x56000010   //Port B control
#define rGPBDAT    0x56000014   //Port B data
#define rGPBUP     0x56000018   //Pull-up control B
 
#define rGPCCON    0x56000020   //Port C control
#define rGPCDAT    0x56000024   //Port C data
#define rGPCUP     0x56000028   //Pull-up control C
 
#define rGPDCON    0x56000030   //Port D control
#define rGPDDAT    0x56000034   //Port D data
#define rGPDUP     0x56000038   //Pull-up control D
 
#define rGPECON    0x56000040   //Port E control
#define rGPEDAT    0x56000044   //Port E data
#define rGPEUP     0x56000048   //Pull-up control E
 
#define rGPFCON    0x56000050   //Port F control
#define rGPFDAT    0x56000054   //Port F data
#define rGPFUP     0x56000058   //Pull-up control F
 
#define rGPGCON    0x56000060   //Port G control
#define rGPGDAT    0x56000064   //Port G data
#define rGPGUP     0x56000068   //Pull-up control G
 
#define rGPHCON    0x56000070   //Port H control
#define rGPHDAT    0x56000074   //Port H data
#define rGPHUP     0x56000078   //Pull-up control H
 
#define rGPJCON    0x560000d0   //Port J control
#define rGPJDAT    0x560000d4   //Port J data
#define rGPJUP     0x560000d8   //Pull-up control J
 
#endif  //__2440ADDR_H__

Sergey
What board is it for?

I tried similar access to registers at Mini6410, there are no errors, but
the values are written through /dev/mem, reading back gives the old ones.

I'm using the Samsung kernel 2.6.38.

Thanks for ideas.

davef
I don't think the 6410 was available back then.

#ifndef __2440ADDR_H__

tends to suggest the mini2440

Reggie
define __2440ADDR_H__

Looks like a mini2440 to me :-)

davef
:) I grabbed the first reference to 2440 I saw!

Reggie
We must've been looking at it at the same time :-D