Analog I/O in WinCE

Xgrunt
Has anyone done any work with analog I/O in CE.  I am particularly
interested in how to access using eVC but any info would be helpful.

Anton Gildebrand
Bump!

Im also interest in knowing how to do this 8)

matt_Damon
Hello,

Does anyone have ADC driver similar to LED driver?

Thanks.

mutzev
http://www.friendlyarm.net/forum/topic/123?lang=en

matt_Damon
Hello,

Thanks for the file.  I have modified it little bit, can you please check
if it is correct!  Do we need to add it to the build? I am getting a error
during execution process.  Do we need to add it to the kernel?? --Thanks.

#include <windows.h>
#include <ceddk.h>
#include <nkintr.h>
#include <pm.h>
#include "pmplatform.h"
#include "Pkfuncs.h"
#include "s2440.h"

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

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

volatile IOPreg *m_p2440IOP;
volatile ADCreg *m_p2440ADC;
volatile IOPreg   *s2440IOP = (IOPreg *)IOP_BASE;
volatile INTreg   *s2440INT = (INTreg *)INT_BASE;

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")));
    }
  }
 
  
}


BOOL WINAPI  
DllEntry(HANDLE  hinstDLL, 
      DWORD dwReason, 
      LPVOID /* lpvReserved */)
{
  switch(dwReason)
  {
  case DLL_PROCESS_ATTACH:
    DEBUGREGISTER((HINSTANCE)hinstDLL);
    return TRUE;
  case DLL_THREAD_ATTACH:
    break;
  case DLL_THREAD_DETACH:
    break;
  case DLL_PROCESS_DETACH:
    break;
#ifdef UNDER_CE
  case DLL_PROCESS_EXITING:
    break;
  case DLL_SYSTEM_STARTED:
    break;
#endif
  }

  return TRUE;
}


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



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;
}

mutzev
Sorry for bad English. In this source d't use a DLL and what you add is not
necessary. Maybe must first call RegInit();


int WINAPI WinMain(  HINSTANCE hInstance,HINSTANCE  PrevInstance,LPTSTR   
lpCmdLine,int  nCmdShow)
{
....

 RegInit();
.....
 int key=ReadKey();
 int iAdc1,iAdc2,iAdc3,iAdc4;
 iAdc1=ReadAdc(0);
 iAdc2=ReadAdc(1);
 iAdc3=ReadAdc(2);
 iAdc4=ReadAdc(3);
....
}


If so did not work, put the code here will think

mutzev
Here is code that is everything you need. I tested it and it works.

#include <windows.h>

HWND bhWnd,ghWnd,thWnd;
HBRUSH BlackBr;

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

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 ADC_BASE   0xB1800000 // 0x58000000
volatile ADCreg *m_p2440ADC;

void RegInit(void);
int CALLBACK ReadAdc(int ch);

void CALLBACK RegInit(void)
{
 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); 
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM
lParam)
{
  switch (message) 
  { 
  case WM_TIMER:
    {
  TCHAR tAdc[64];
  int iAdc1,iAdc2,iAdc3,iAdc4;
  iAdc1=ReadAdc(0);
  iAdc2=ReadAdc(1);
  iAdc3=ReadAdc(2);
  iAdc4=ReadAdc(3);
  swprintf(tAdc,L"%d %d %d %d",iAdc1,iAdc2,iAdc3,iAdc4);
    SetWindowText(thWnd,tAdc);
    }
    break;
  case WM_CREATE:
    SetTimer(hWnd,100,100,(TIMERPROC)WndProc);
    break;
  case WM_COMMAND:
    switch(wParam){
      case 100:
        DeleteObject(BlackBr);
        DestroyWindow(ghWnd);
        PostQuitMessage(0);
        break;
    }
    default:
      return DefWindowProc(hWnd, message, wParam, lParam);
   }
   return 0;
}

int WINAPI WinMain(  HINSTANCE hInstance,HINSTANCE hPrevInstance,LPTSTR   
lpCmdLine,int  nCmdShow)
{
 MSG msg;
 WNDCLASS  wc;
 memset(&wc,0,sizeof(wc));

 BlackBr=CreateSolidBrush(RGB(0,0,0));

 wc.style      = CS_HREDRAW | CS_VREDRAW | CS_PARENTDC | CS_DBLCLKS |
CS_SAVEBITS;
 wc.lpfnWndProc    = (WNDPROC) WndProc;
 wc.hInstance    = hInstance;
 wc.hbrBackground  =  BlackBr;
 wc.lpszClassName  = L"test";
 RegisterClass(&wc);

 RegInit();

 ghWnd = CreateWindow(L"test", L"test", WS_EX_TOPMOST|WS_VISIBLE,  0, 0,
800, 480, NULL, NULL, hInstance, NULL);
 bhWnd = CreateWindow(L"BUTTON", L"Exit", WS_VISIBLE,  692, 393, 103, 85,
ghWnd, (HMENU)100, hInstance, NULL);
 thWnd = CreateWindow(L"STATIC", L"ADC", WS_VISIBLE,  100, 100, 300, 24,
ghWnd, NULL, hInstance, NULL);

 ShowWindow(ghWnd, SW_SHOW) ;
 UpdateWindow(ghWnd);

 while(GetMessage(&msg, NULL, 0, 0)) {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
 }

 return msg.wParam; 

}

matt_Damon
Hello Mutzev,

Thanks for the code!  It may be very basic but I am still learning to use
embedded VC++.  How do we use this code in WINCE?  Do we need to create WCE
DLL using this code?

Thanks.

mutzev
Attachment: demo.rar (694.78 KB)
1. Perhaps you should read a little. 
2. Install Microsoft eMbedded C + + 4.0. 
3. Create file test.cpp Copy/Past code below. 
4. In VC create empty project. 
5. Add test.cpp in project. 
6. Compile. Will receive the program test.exe. 
7. Copy it to mini2440/residentflash. 
8. Start it...

Here is the entire projec. If one of the administrators want, you can post
it on the &#1076;&#1086;&#1074;&#1085;&#1083;&#1086;&#1072;&#1076; section.
Look there and asked.

matt_Damon
Hello mutzev,

Thanks for the file!!  It works great.  Actually I was using a program
known as LabVIEW to run on MINI2440 and use this to read ADC.  I created a
DLL using EmbVC++ and then Stub Dll using VC++2008 and then used this stub
dll in my LabVIEW application.

Its was a big help!:)

mutzev
The idea is not use any external libraries to govern a regional directly
from the program. &#1058;his principle can easy read input or write output
registry ;)

matt_Damon
Can you please let me know what these &#1076, &#1085 are...

mutzev
@matt_Damon Can you please let me know what these &#1076, &#1085 are...

Sorry, this is cyrilic letter...

Killerwatt
>@matt_Damon Can you please let me know what these &#1076, &#1085 are...

>Sorry, this is cyrilic letter...

If an admin is interested, he may be happy to publish here in the download.

Tom
Hi Matt,

Any chance you could post your dll here? I'm also using LabVIEW.

Thanks,
Tom

Omar
Hi Matt it would very helpfull if you put your labview vi and the stub dll
because i want to do the same but i still have some errors.
Thans, Omar :)

icaro600
Hi matt, I,m going to use labview also,but I never used VC,C#,etc,and I,m
bit lost with this. It could help me alot if you can show me or share how i
can read ADC and control GPIO in Labview. Have you tried to access to
serial ports and ethernet?,i need to try it.

Thanks in advance

kubra
sorry for my English firstly, I want to ask that does Labview has any good
effect while programming. I am new on the arm so &#305; really want to know
if there is a simlify while using it .

Omar
Icaro600 use the serial compatibility VI and for ethernet are the same VIs
i tried UDP and TCP/IP and both work very well.