Help using GPIOs

wanderer
Hello,

Currently for a college project, I'm developing an application that needs
read input from the GPIOs but I'm stuck with that!! I already know how to
use the UART ports but I have no idea of how to use the GPIOs. Currently
I'm coding in C#, but if any of you have any example for how to use the
GPIOs in c++, I could simply start again in c++!!

Please any help with this would be greatly appreciated!!

davef
Have you read the other posts on this site about GPIO?

mutzev
extern "C" BOOL VirtualCopy(LPVOID dest, LPVOID src, DWORD size, DWORD
flags);

typedef struct  {
    unsigned int  rGPACON;      // 00
    unsigned int  rGPADAT;
    unsigned int  rPAD1[2];
    
    unsigned int  rGPBCON;      // 10
    unsigned int  rGPBDAT;
    unsigned int  rGPBUP;
    unsigned int  rPAD2;
    
    unsigned int  rGPCCON;      // 20
    unsigned int  rGPCDAT;
    unsigned int  rGPCUP;
    unsigned int  rPAD3;
    
    unsigned int  rGPDCON;      // 30
    unsigned int  rGPDDAT;
      unsigned int  rGPDUP; 
      unsigned int  rPAD4;
    
    unsigned int  rGPECON;      // 40
    unsigned int  rGPEDAT;
    unsigned int  rGPEUP;
    unsigned int  rPAD5;
    
    unsigned int  rGPFCON;      // 50
    unsigned int  rGPFDAT;
    unsigned int  rGPFUP; 
    unsigned int  rPAD6;
    
    unsigned int  rGPGCON;      // 60
    unsigned int  rGPGDAT;
    unsigned int  rGPGUP; 
    unsigned int  rPAD7;
    
    unsigned int  rGPHCON;      // 70
    unsigned int  rGPHDAT;
    unsigned int  rGPHUP; 
    unsigned int  rPAD8;
    
    unsigned int  rMISCCR;      // 80
    unsigned int  rDCKCON;    
    unsigned int  rEXTINT0;
    unsigned int  rEXTINT1;    
    unsigned int  rEXTINT2;      // 90
    unsigned int  rEINTFLT0;
    unsigned int  rEINTFLT1;
    unsigned int  rEINTFLT2;
    unsigned int  rEINTFLT3;    // A0
    unsigned int  rEINTMASK;
    unsigned int  rEINTPEND;
    unsigned int  rGSTATUS0;    // AC
    unsigned int  rGSTATUS1;    // B0
    unsigned int  rGSTATUS2;    // B4 ;;; SHL
    unsigned int  rGSTATUS3;    // B8
    unsigned int  rGSTATUS4;    // BC
  
    unsigned int  rFLTOUT;      // C0
    unsigned int  rDSC0;
    unsigned int  rDSC1;
    unsigned int  rMSLCON;

    unsigned int  rGPJCON;      // D0
    unsigned int  rGPJDAT;
    unsigned int  rGPJUP;
    unsigned int  rPAD9;
}IOPreg;

typedef struct  {
     unsigned int rADCCON;  //ADC control
     unsigned int rADCTSC;  //ADC touch screen control
     unsigned int rADCDLY;  //ADC start or Interval Delay
     unsigned int rADCDAT0;  //ADC conversion data 0
     unsigned int rADCDAT1;  //ADC conversion data 1
     unsigned int rADCUPDN;  //Stylus Up/Down interrupt status
}ADCreg;

#define IOP_BASE   0xB1600000 // 0x56000000
#define ADC_BASE   0xB1800000 // 0x58000000

volatile IOPreg *m_p2440IOP;
volatile ADCreg *m_p2440ADC;

void CALLBACK RegInit(void)
{

 m_p2440IOP = (volatile IOPreg *)
VirtualAlloc(0,sizeof(IOPreg),MEM_RESERVE, PAGE_NOACCESS);
 VirtualCopy((PVOID)m_p2440IOP,(PVOID)(IOP_BASE),sizeof(IOPreg),PAGE_READWRITE|P
AGE_NOCACHE);
 
 m_p2440ADC = (volatile ADCreg *)
VirtualAlloc(0,sizeof(ADCreg),MEM_RESERVE, PAGE_NOACCESS);
 VirtualCopy((PVOID)m_p2440ADC,(PVOID)(ADC_BASE),sizeof(ADCreg),PAGE_READWRITE|P
AGE_NOCACHE);

}

int CALLBACK ReadAdc(int ch) 
{ 
 m_p2440ADC->rADCCON = (1<<14)|(20<<6)|(ch<<3); //setup channel 
 m_p2440ADC->rADCCON|=0x1;  //start ADC 
 while(m_p2440ADC->rADCCON&0x1); //check if Enable_start is low 
 while(!(m_p2440ADC->rADCCON&0x8000)); //check if EC(End of Conversion)
flag is high 
 return ((int)m_p2440ADC->rADCDAT0 & 0x3ff); 
}

int CALLBACK ReadKey(void)
{
int key=0;

if(m_p2440IOP->rGPGDAT&1) key|=1; 
if(m_p2440IOP->rGPGDAT&8) key|=2;
if(m_p2440IOP->rGPGDAT&32) key|=4;
if(m_p2440IOP->rGPGDAT&64) key|=8;
if(m_p2440IOP->rGPGDAT&128) key|=16;
if(m_p2440IOP->rGPGDAT&2048) key|=32;
key^=0x3f; 
return key;
}

matt_Damon
Hello Mutzev,

I tried to use the above example and modified little bit to use the GPF
(EINT0-EINT4) pins on GPIO but was not successful in toggling them. I tried
to configure them as output. Do you have any idea?

Thanks.

mutzev
Hello matt_Damon,

#define SetBit(x,y) (*(x)|=(1<<y))
#define ClrBit(x,y) *(x)=*(x)&~(1<<y)
#define ClrPin(x,y) (*(x)|=(1<<y))
#define SetPin(x,y) *(x)=*(x)&~(1<<y)

typedef struct  {
    unsigned int  rGPACON;      // 00
    unsigned int  rGPADAT;
    unsigned int  rPAD1[2];
    
    unsigned int  rGPBCON;      // 10
    unsigned int  rGPBDAT;
    unsigned int  rGPBUP;
    unsigned int  rPAD2;
    
    unsigned int  rGPCCON;      // 20
    unsigned int  rGPCDAT;
    unsigned int  rGPCUP;
    unsigned int  rPAD3;
    
    unsigned int  rGPDCON;      // 30
    unsigned int  rGPDDAT;
      unsigned int  rGPDUP; 
      unsigned int  rPAD4;
    
    unsigned int  rGPECON;      // 40
    unsigned int  rGPEDAT;
    unsigned int  rGPEUP;
    unsigned int  rPAD5;
    
    unsigned int  rGPFCON;      // 50
    unsigned int  rGPFDAT;
    unsigned int  rGPFUP; 
    unsigned int  rPAD6;
    
    unsigned int  rGPGCON;      // 60
    unsigned int  rGPGDAT;
    unsigned int  rGPGUP; 
    unsigned int  rPAD7;
    
    unsigned int  rGPHCON;      // 70
    unsigned int  rGPHDAT;
    unsigned int  rGPHUP; 
    unsigned int  rPAD8;
    
    unsigned int  rMISCCR;      // 80
    unsigned int  rDCKCON;    
    unsigned int  rEXTINT0;
    unsigned int  rEXTINT1;    
    unsigned int  rEXTINT2;      // 90
    unsigned int  rEINTFLT0;
    unsigned int  rEINTFLT1;
    unsigned int  rEINTFLT2;
    unsigned int  rEINTFLT3;    // A0
    unsigned int  rEINTMASK;
    unsigned int  rEINTPEND;
    unsigned int  rGSTATUS0;    // AC
    unsigned int  rGSTATUS1;    // B0
    unsigned int  rGSTATUS2;    // B4 ;;; SHL
    unsigned int  rGSTATUS3;    // B8
    unsigned int  rGSTATUS4;    // BC
  
    unsigned int  rFLTOUT;      // C0
    unsigned int  rDSC0;
    unsigned int  rDSC1;
    unsigned int  rMSLCON;

    unsigned int  rGPJCON;      // D0
    unsigned int  rGPJDAT;
    unsigned int  rGPJUP;
    unsigned int  rPAD9;
}IOPreg;

#define IOP_BASE   0xB1600000 // 0x56000000

volatile IOPreg *m_p2440IOP;

void CALLBACK Init(void)
{
// init GPIO
m_p2440IOP = (volatile IOPreg *) VirtualAlloc(0,sizeof(IOPreg),MEM_RESERVE,
PAGE_NOACCESS);
VirtualCopy((PVOID)m_p2440IOP,(PVOID)(IOP_BASE),sizeof(IOPreg),PAGE_READWRITE|PA
GE_NOCACHE);

// make led output 01
ClrBit(&m_p2440IOP->rGPBCON,17);
SetBit(&m_p2440IOP->rGPBCON,16);
ClrBit(&m_p2440IOP->rGPBCON,15);
SetBit(&m_p2440IOP->rGPBCON,14);
ClrBit(&m_p2440IOP->rGPBCON,13);
SetBit(&m_p2440IOP->rGPBCON,12);
ClrBit(&m_p2440IOP->rGPBCON,11);
SetBit(&m_p2440IOP->rGPBCON,10);
}

void CALLBACK SetLed(int xled)
{
 if(xled&1) SetPin(&m_p2440IOP->rGPBDAT,5); else
ClrPin(&m_p2440IOP->rGPBDAT,5); 
 if(xled&2) SetPin(&m_p2440IOP->rGPBDAT,6); else
ClrPin(&m_p2440IOP->rGPBDAT,6); 
 if(xled&4) SetPin(&m_p2440IOP->rGPBDAT,7); else
ClrPin(&m_p2440IOP->rGPBDAT,7); 
 if(xled&8) SetPin(&m_p2440IOP->rGPBDAT,8); else
ClrPin(&m_p2440IOP->rGPBDAT,8); 
 return;
}


void CALLBACK alabala(void)
{
 static int led=0;

 Init();

 led=1;
 SetLed(led);
 led=2;
 SetLed(led);
 led=4;
 SetLed(led);
 led=8;
 SetLed(led);
 led=0x0f;
 SetLed(led);
 led=0;
 SetLed(led);
 Sleep(1000);
}

matt_Damon
Hello Mutzev,

The above program works great for setting any pin.  However, how can we
configure them as input and read their values?  I believe we should use
Clrbit function instead of setbit to configure as input.  But how will we
read the value?  Do we need to disable pull-up resistor for pins?

Thanks.

matt_Damon
Hello Mutzev,

In the first example of Key Press,

int CALLBACK ReadKey(void)
{
int key=0;

if(m_p2440IOP->rGPGDAT&1) key|=1; 
if(m_p2440IOP->rGPGDAT&8) key|=2;
if(m_p2440IOP->rGPGDAT&32) key|=4;
if(m_p2440IOP->rGPGDAT&64) key|=8;
if(m_p2440IOP->rGPGDAT&128) key|=16;
if(m_p2440IOP->rGPGDAT&2048) key|=32;
key^=0x3f; 
return key;
}

I always receiving 16, indicating that KEY5 is pressed.  I verified this
using a multimeter.  Can we clear this pin so that it outputs 0 when no pin
is pressed?

Thanks.

matt_Damon
Hello Mutzev,

I tried to use the GPIO pins as input but some of the pis are allways High!
Can you please let me know what I am doing wrong??  Here is the modified
code which I am using:

#include <windows.h>


#define DLLEXPORT __declspec(dllexport)
#define EXTERNC    extern "C"

EXTERNC BOOL VirtualCopy(LPVOID dest, LPVOID src, DWORD size, DWORD flags);
#define ClrBit(x,y) *(x)=*(x)&~(1<<y)

typedef struct  {
    unsigned int  rGPACON;      // 00
    unsigned int  rGPADAT;
    unsigned int  rPAD1[2];
    
    unsigned int  rGPBCON;      // 10
    unsigned int  rGPBDAT;
    unsigned int  rGPBUP;
    unsigned int  rPAD2;
    
    unsigned int  rGPCCON;      // 20
    unsigned int  rGPCDAT;
    unsigned int  rGPCUP;
    unsigned int  rPAD3;
    
    unsigned int  rGPDCON;      // 30
    unsigned int  rGPDDAT;
      unsigned int  rGPDUP; 
      unsigned int  rPAD4;
    
    unsigned int  rGPECON;      // 40
    unsigned int  rGPEDAT;
    unsigned int  rGPEUP;
    unsigned int  rPAD5;
    
    unsigned int  rGPFCON;      // 50
    unsigned int  rGPFDAT;
    unsigned int  rGPFUP; 
    unsigned int  rPAD6;
    
    unsigned int  rGPGCON;      // 60
    unsigned int  rGPGDAT;
    unsigned int  rGPGUP; 
    unsigned int  rPAD7;
    
    unsigned int  rGPHCON;      // 70
    unsigned int  rGPHDAT;
    unsigned int  rGPHUP; 
    unsigned int  rPAD8;
    
    unsigned int  rMISCCR;      // 80
    unsigned int  rDCKCON;    
    unsigned int  rEXTINT0;
    unsigned int  rEXTINT1;    
    unsigned int  rEXTINT2;      // 90
    unsigned int  rEINTFLT0;
    unsigned int  rEINTFLT1;
    unsigned int  rEINTFLT2;
    unsigned int  rEINTFLT3;    // A0
    unsigned int  rEINTMASK;
    unsigned int  rEINTPEND;
    unsigned int  rGSTATUS0;    // AC
    unsigned int  rGSTATUS1;    // B0
    unsigned int  rGSTATUS2;    // B4 ;;; SHL
    unsigned int  rGSTATUS3;    // B8
    unsigned int  rGSTATUS4;    // BC
  
    unsigned int  rFLTOUT;      // C0
    unsigned int  rDSC0;
    unsigned int  rDSC1;
    unsigned int  rMSLCON;

    unsigned int  rGPJCON;      // D0
    unsigned int  rGPJDAT;
    unsigned int  rGPJUP;
    unsigned int  rPAD9;
}IOPreg;


#define IOP_BASE   0xB1600000 // 0x56000000

volatile IOPreg *m_p2440IOP;


EXTERNC DLLEXPORT void RegInit(void);
void RegInit(void)
{

 m_p2440IOP = (volatile IOPreg *)
VirtualAlloc(0,sizeof(IOPreg),MEM_RESERVE, PAGE_NOACCESS);
 VirtualCopy((PVOID)m_p2440IOP,(PVOID)(IOP_BASE),sizeof(IOPreg),PAGE_READWRITE|P
AGE_NOCACHE);
ClrBit(&m_p2440IOP->rGPFCON,0xF);
ClrBit(&m_p2440IOP->rGPFCON,0xE);
ClrBit(&m_p2440IOP->rGPFCON,0xD);
ClrBit(&m_p2440IOP->rGPFCON,0xC);
ClrBit(&m_p2440IOP->rGPFCON,0xB);
ClrBit(&m_p2440IOP->rGPFCON,0xA);
ClrBit(&m_p2440IOP->rGPFCON,9);
ClrBit(&m_p2440IOP->rGPFCON,8);
ClrBit(&m_p2440IOP->rGPFCON,7);
ClrBit(&m_p2440IOP->rGPFCON,6);
ClrBit(&m_p2440IOP->rGPFCON,5);
ClrBit(&m_p2440IOP->rGPFCON,4);
ClrBit(&m_p2440IOP->rGPFCON,3);
ClrBit(&m_p2440IOP->rGPFCON,2);
ClrBit(&m_p2440IOP->rGPFCON,1);
ClrBit(&m_p2440IOP->rGPFCON,0);
}

EXTERNC DLLEXPORT int ReadKey(void);
int ReadKey(void)
{
int key=0;

if(m_p2440IOP->rGPFDAT&1) key|=1; 
if(m_p2440IOP->rGPFDAT&2) key|=2;
if(m_p2440IOP->rGPFDAT&4) key|=3;
if(m_p2440IOP->rGPFDAT&8) key|=4;
if(m_p2440IOP->rGPFDAT&16) key|=5;
if(m_p2440IOP->rGPFDAT&32) key|=6;
if(m_p2440IOP->rGPFDAT&64) key|=7;
if(m_p2440IOP->rGPFDAT&128) key|=8;
key^=0xff; 
return key;
}

Thanks.

mutzev
Colleague, what you doing this?
...
ClrBit(&m_p2440IOP->rGPFCON,0xF);
ClrBit(&m_p2440IOP->rGPFCON,0xE);
ClrBit(&m_p2440IOP->rGPFCON,0xD);
ClrBit(&m_p2440IOP->rGPFCON,0xC);
ClrBit(&m_p2440IOP->rGPFCON,0xB);
ClrBit(&m_p2440IOP->rGPFCON,0xA);
ClrBit(&m_p2440IOP->rGPFCON,9);
ClrBit(&m_p2440IOP->rGPFCON,8);
ClrBit(&m_p2440IOP->rGPFCON,7);
ClrBit(&m_p2440IOP->rGPFCON,6);
ClrBit(&m_p2440IOP->rGPFCON,5);
ClrBit(&m_p2440IOP->rGPFCON,4);
ClrBit(&m_p2440IOP->rGPFCON,3);
ClrBit(&m_p2440IOP->rGPFCON,2);
ClrBit(&m_p2440IOP->rGPFCON,1);
ClrBit(&m_p2440IOP->rGPFCON,0);
....

mutzev
1. Must read guide to s3c2440. Page 263.
2. Misunderstanding what is the problem. When you configure ports as input
it in set to 1 and becomes 0 at press. If You want pressed key=1 use the
XOR (key ^ 0xff).

....
int key=0;
if(m_p2440IOP->rGPGDAT&1) key|=1; 
.....
if(m_p2440IOP->rGPGDAT&0x80) key|=0x80;
key^=0xff; 
 
3. If you want to do all of the pins as inputs GPF is not it easier instead
to use just above m_p2440IOP-> rGPFCON = 0, or if you want set to output
m_p2440IOP-> rGPFCON = 0haa;  aa (hex) = 10 10 10 10

4. Possibly due to bad my english misunderstood what you ask for which I
apologize.

matt_Damon
Hello Mutzev,

I was using Clrbit function to set GPFCON register to input on all pins.
Then I am using the GPFDAT function to read the values of respective pin
values on the GPIO port.  
The 6 Key press is working fine now.  But GPFDAT on the GPIO port are not
working.

mutzev
"The 6 Key press is working fine now.  But GPFDAT on the GPIO port are not
working."

if it works, what does not work?! See whether the F PORT was finally
correctly as input. See also register GPFUP

matt_Damon
Hello mutzev,

Here is the code which I am using.  The vale of "key" is 240.  I expected
it to be 0 when nothing is connected to the GPF pins.  I checked the GPFCON
and GPFUP values.  They are 0:

 m_p2440IOP = (volatile IOPreg *)
VirtualAlloc(0,sizeof(IOPreg),MEM_RESERVE, PAGE_NOACCESS);
VirtualCopy((PVOID)m_p2440IOP,(PVOID)(IOP_BASE),sizeof(IOPreg),PAGE_READWRITE|PA
GE_NOCACHE);
m_p2440IOP->rGPFCON = 0; //to set GPF to input
m_p2440IOP->rGPFUP = 0;  //disable pullups
}

EXTERNC DLLEXPORT int ReadKey(void);
int ReadKey(void)
{
int key=0;

//key=m_p2440IOP->rGPFUP;  This is to check GPFUP value
//key=m_p2440IOP->rGPFCON; This is to check GPFCON value

if(m_p2440IOP->rGPFDAT&1) key|=1; 
if(m_p2440IOP->rGPFDAT&2) key|=2;
if(m_p2440IOP->rGPFDAT&4) key|=3;
if(m_p2440IOP->rGPFDAT&8) key|=4;
if(m_p2440IOP->rGPFDAT&16) key|=5;
if(m_p2440IOP->rGPFDAT&32) key|=6;
if(m_p2440IOP->rGPFDAT&64) key|=7;
if(m_p2440IOP->rGPFDAT&128) key|=8;
key^=0xff; 
return key;
}

mutzev
// incorect
...
if(m_p2440IOP->rGPFDAT&1) key|=1; 
if(m_p2440IOP->rGPFDAT&2) key|=2;
if(m_p2440IOP->rGPFDAT&4) key|=3;
if(m_p2440IOP->rGPFDAT&8) key|=4;
if(m_p2440IOP->rGPFDAT&16) key|=5;
if(m_p2440IOP->rGPFDAT&32) key|=6;
if(m_p2440IOP->rGPFDAT&64) key|=7;
if(m_p2440IOP->rGPFDAT&128) key|=8;
....
// corect
...
if(m_p2440IOP->rGPFDAT&1) key|=1; 
if(m_p2440IOP->rGPFDAT&2) key|=2;
if(m_p2440IOP->rGPFDAT&4) key|=4;
if(m_p2440IOP->rGPFDAT&8) key|=8;
if(m_p2440IOP->rGPFDAT&16) key|=16;
if(m_p2440IOP->rGPFDAT&32) key|=32;
if(m_p2440IOP->rGPFDAT&64) key|=64;
if(m_p2440IOP->rGPFDAT&128) key|=128;
....
or try this

key = (m_p2440IOP->rGPFDAT)^0xff;

matt_Damon
Hello mutzev,

The following code works!  I am not sure what I was doing wrong before. 
Using this I was able to use GPIO pins as input and output:

//#include "stdafx.h"
//#include "Pkfuncs.h"
//#include "s2440.h"   //In some BSPs this file has a slightly different
name
#include <windows.h>
//#include <time.h>
//#include <ceddk.h>

void gpioInit();
void Virtual_Alloc();

#define DLLEXPORT __declspec(dllexport)
#define EXTERNC    extern "C"


EXTERNC BOOL VirtualCopy(LPVOID dest, LPVOID src, DWORD size, DWORD flags);

typedef struct  {
    unsigned int  rGPACON;      // 00
    unsigned int  rGPADAT;
    unsigned int  rPAD1[2];
    
    unsigned int  rGPBCON;      // 10
    unsigned int  rGPBDAT;
    unsigned int  rGPBUP;
    unsigned int  rPAD2;
    
    unsigned int  rGPCCON;      // 20
    unsigned int  rGPCDAT;
    unsigned int  rGPCUP;
    unsigned int  rPAD3;
    
    unsigned int  rGPDCON;      // 30
    unsigned int  rGPDDAT;
      unsigned int  rGPDUP; 
      unsigned int  rPAD4;
    
    unsigned int  rGPECON;      // 40
    unsigned int  rGPEDAT;
    unsigned int  rGPEUP;
    unsigned int  rPAD5;
    
    unsigned int  rGPFCON;      // 50
    unsigned int  rGPFDAT;
    unsigned int  rGPFUP; 
    unsigned int  rPAD6;
    
    unsigned int  rGPGCON;      // 60
    unsigned int  rGPGDAT;
    unsigned int  rGPGUP; 
    unsigned int  rPAD7;
    
    unsigned int  rGPHCON;      // 70
    unsigned int  rGPHDAT;
    unsigned int  rGPHUP; 
    unsigned int  rPAD8;
    
    unsigned int  rMISCCR;      // 80
    unsigned int  rDCKCON;    
    unsigned int  rEXTINT0;
    unsigned int  rEXTINT1;    
    unsigned int  rEXTINT2;      // 90
    unsigned int  rEINTFLT0;
    unsigned int  rEINTFLT1;
    unsigned int  rEINTFLT2;
    unsigned int  rEINTFLT3;    // A0
    unsigned int  rEINTMASK;
    unsigned int  rEINTPEND;
    unsigned int  rGSTATUS0;    // AC
    unsigned int  rGSTATUS1;    // B0
    unsigned int  rGSTATUS2;    // B4 ;;; SHL
    unsigned int  rGSTATUS3;    // B8
    unsigned int  rGSTATUS4;    // BC
  
    unsigned int  rFLTOUT;      // C0
    unsigned int  rDSC0;
    unsigned int  rDSC1;
    unsigned int  rMSLCON;

    unsigned int  rGPJCON;      // D0
    unsigned int  rGPJDAT;
    unsigned int  rGPJUP;
    unsigned int  rPAD9;
}IOPreg;


#define IOP_BASE   0xB1600000 // 0x56000000

bool memoryAlloced = false;

volatile IOPreg *s2440IOP = (IOPreg *)IOP_BASE;

EXTERNC DLLEXPORT bool DLLreadPin(int port, int pin);
bool DLLreadPin(int port, int pin)
{
  gpioInit();
  switch (port) {
  case 0:
    if (s2440IOP->rGPADAT & (0x1 << pin))
      return true;
    else
      return false;
    break;
  case 1:
    if (s2440IOP->rGPBDAT & (0x1 << pin))
      return true;
    else
      return false;
    break;
  case 2:
    if (s2440IOP->rGPCDAT & (0x1 << pin))
      return true;
    else
      return false;
    break;
  case 3:
    if (s2440IOP->rGPDDAT & (0x1 << pin))
      return true;
    else
      return false;
    break;
  case 4:
    if (s2440IOP->rGPEDAT & (0x1 << pin))
      return true;
    else
      return false;
    break;
  case 5:
    if (s2440IOP->rGPFDAT & (0x1 << pin))
      return true;
    else
      return false;
    break;
  case 6:
    if (s2440IOP->rGPGDAT & (0x1 << pin))
      return true;
    else
      return false;
    break;
  }
  return false;
}

EXTERNC DLLEXPORT int DLLmakeInputPin(int port, int pin); 
int DLLmakeInputPin(int port, int pin)
{
  gpioInit();
  switch (port) {
  case 0:
    s2440IOP->rGPACON = (s2440IOP->rGPACON &~ ( 3 << pin*2)) ;
    break;
  case 1:
    s2440IOP->rGPBCON = (s2440IOP->rGPBCON &~ ( 3 << pin*2)) ;
    break;
  case 2:
    s2440IOP->rGPCCON = (s2440IOP->rGPCCON &~ ( 3 << pin*2)) ;
    break;
  case 3:
    s2440IOP->rGPDCON = (s2440IOP->rGPDCON &~ ( 3 << pin*2)) ;
    break;
  case 4:
    s2440IOP->rGPECON = (s2440IOP->rGPECON &~ ( 3 << pin*2)) ;
    break;
  case 5:
    s2440IOP->rGPFCON = (s2440IOP->rGPFCON &~ ( 3 << pin*2)) ;
    break;
  case 6:
    s2440IOP->rGPGCON = (s2440IOP->rGPGCON &~ ( 3 << pin*2)) ;
    break;
  }
  return 0;
}

EXTERNC DLLEXPORT int DLLsetPin(int port, int pin, bool on); 
int DLLsetPin(int port, int pin, bool on)
{
  gpioInit();
  switch (port) {
  case 0:
    s2440IOP->rGPACON = (s2440IOP->rGPACON &~ ( 3 << pin*2)) | ( 1<< pin*2);  
    if (!on)
      s2440IOP->rGPADAT = (s2440IOP->rGPADAT &~ (0x1 << pin));
    else
      s2440IOP->rGPADAT = (s2440IOP->rGPADAT | (0x1 << pin));
    break;
  case 1:
    s2440IOP->rGPBCON = (s2440IOP->rGPBCON &~ ( 3 << pin*2)) | ( 1<< pin*2);  
    if (!on)
      s2440IOP->rGPBDAT = (s2440IOP->rGPBDAT &~ (0x1 << pin));
    else
      s2440IOP->rGPBDAT = (s2440IOP->rGPBDAT | (0x1 << pin));
    break;
  case 2:
    s2440IOP->rGPCCON = (s2440IOP->rGPCCON &~ ( 3 << pin*2)) | ( 1<< pin*2);  
    if (!on)
      s2440IOP->rGPCDAT = (s2440IOP->rGPCDAT &~ (0x1 << pin));
    else
      s2440IOP->rGPCDAT = (s2440IOP->rGPCDAT | (0x1 << pin));
    break;
  case 3:
    s2440IOP->rGPDCON = (s2440IOP->rGPDCON &~ ( 3 << pin*2)) | ( 1<< pin*2);  
    if (!on)
      s2440IOP->rGPDDAT = (s2440IOP->rGPDDAT &~ (0x1 << pin));
    else
      s2440IOP->rGPDDAT = (s2440IOP->rGPDDAT | (0x1 << pin));
    break;
  case 4:
    s2440IOP->rGPECON = (s2440IOP->rGPECON &~ ( 3 << pin*2)) | ( 1<< pin*2);  
    if (!on)
      s2440IOP->rGPEDAT = (s2440IOP->rGPEDAT &~ (0x1 << pin));
    else
      s2440IOP->rGPEDAT = (s2440IOP->rGPEDAT | (0x1 << pin));
    break;
    
  case 5:
    s2440IOP->rGPFCON = (s2440IOP->rGPFCON &~ ( 3 << pin*2)) | ( 1<< pin*2);  
    if (!on)
      s2440IOP->rGPFDAT = (s2440IOP->rGPFDAT &~ (0x1 << pin));
    else
      s2440IOP->rGPFDAT = (s2440IOP->rGPFDAT | (0x1 << pin));
    break;
  case 6:
  
    s2440IOP->rGPGCON = (s2440IOP->rGPGCON &~ ( 3 << pin*2)) | ( 1<< pin*2);  
    if (!on)
      s2440IOP->rGPGDAT = (s2440IOP->rGPGDAT &~ (0x1 << pin));
    else
      s2440IOP->rGPGDAT = (s2440IOP->rGPGDAT | (0x1 << pin));
    break;


  }
  
  return 0;
}

void Virtual_Alloc()
{

    // GPIO Virtual alloc
  s2440IOP = (volatile IOPreg *) VirtualAlloc(0,sizeof(IOPreg),MEM_RESERVE,
PAGE_NOACCESS);
  if(s2440IOP == NULL) 
  {
    RETAILMSG(1,(TEXT("For s2440IOP: VirtualAlloc faiLED!\r\n")));
    
  }
  else {
   
if(!VirtualCopy((PVOID)s2440IOP,(PVOID)(IOP_BASE),sizeof(IOPreg),PAGE_READWRITE
| PAGE_NOCACHE )) 
    {
      RETAILMSG(1,(TEXT("For s2440IOP: VirtualCopy faiLED!\r\n")));
    }
  }
 
  
}

void gpioInit() {
  if (!memoryAlloced) 
  {
    
    Virtual_Alloc();
    memoryAlloced = true;
    
  }

}

mutzev
|=OR   

1|2|3=3
1|2=3

1|2|3|4|5|6|7|8=15=0x0f... 0x0f^ff=240...
1|2|4|8|16|32|64|128=0xff ... 0xff^0xff=0....

Tommy
Is there any way of doing this in C, under Linux?

davef
I assume you meant . . . any other way of doing this in C.  There is
nothing special about "C, under Linux".

Have a look at these:

http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&...

http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewforum&...

Fortunately the same compiler (GCC) is used for both. What can make a
difference is the device architecture (Havard versus von Neumann).  The AVR
devices referred to here are Harvard.  Some macro definitions for ports, as
far as I understand, may not work for both. 

More investigation required!

Good luck.

Tommy
Well the reason I say this is because they are using the windows.h header.

Tommy
And by Linux, I meant in C targeted towards mini2440 running a Linux OS,
not using windows.h header.

Tommy
Anyone know of a way to do this without using the windows.h header?

Tom
You are in the wrong forum/topic (WinCE). Search in the Linux forum for
"GPIO". If you want direct access to the GPIO registers then its also
nearly the same under WinCE and Linux...

jeangr
I tried to compile this dll...
but I have this error:

Error  4  error LNK2019: unresolved external symbol _VirtualCopy referenced
in function "void __cdecl Virtual_Alloc(void)" (?Virtual_Alloc@@YAXXZ) 
gpio_arm.obj  


can someone send me the compiled DLL or upload it here (jeangr@alice.it)?

nack
I tried to compile this dll...
but I have this error:

Error  4  error LNK2019: unresolved external symbol _VirtualCopy referenced
in function "void __cdecl Virtual_Alloc(void)" (?Virtual_Alloc@@YAXXZ) 
gpio_arm.obj  


can someone send me the compiled DLL or upload it here
(info@edgsistemi.it)?

phamthaihoa
Does anyone convert this code to C# ?

domodom
You can find a Wince 6 GPIO driver on my website
(http://www.domodom.fr/spip/A-GPIO-driver-for-mini2440.html?lang=en), with
c++, c# and VB.net samples.
domodom

hgthan74
Hi everybody

I have been using S3C2440 Micro2440 for WINCE 5.0, but I can't find GPIO
driver in regedit of Board. How I can load GPIO driver into this board.
Please instruct me.
Thanks a lot

GuyThePie
If you're using CE5, there's no need to use DLLs specifically to access the
I/O pins from C#
It can be done directly from the C# code, without any need for P/Invoking
DLLs written in C.

e.g. ( a snippet)

           unchecked
            {

                unsafe
                {
                    IOP_BASE = new IntPtr((void*)0xB1600000UL);
                }
            }

            lpv = VirtualAlloc(IntPtr.Zero,
(UInt32)Marshal.SizeOf(Registers), MemUsageFlags.MEM_RESERVE,
PageAccessFlags.PAGE_NOACCESS);

            bRet = VirtualCopy(lpv, IOP_BASE,
(UInt32)Marshal.SizeOf(Registers), PageAccessFlags.PAGE_READWRITE |
PageAccessFlags.PAGE_NOCACHE);

            unsafe
            {
                GPIOReg = (IOPReg*)lpv;
            }

you can then just use it as you would a C structure. e.g.
unsafe
{
  GPIOReg->aregister = avalue;
}

Basically C# allows the use of pointers provided you use them in an unsafe
context.