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.
Analog I/O in WinCE
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; }
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
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; }
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.
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 довнлоад section. Look there and asked.
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!:)
The idea is not use any external libraries to govern a regional directly from the program. Тhis principle can easy read input or write output registry ;)
@matt_Damon Can you please let me know what these д, н are... Sorry, this is cyrilic letter...
>@matt_Damon Can you please let me know what these д, н are... >Sorry, this is cyrilic letter... If an admin is interested, he may be happy to publish here in the download.
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 :)
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
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 ı really want to know if there is a simlify while using it .
Icaro600 use the serial compatibility VI and for ethernet are the same VIs i tried UDP and TCP/IP and both work very well.