Anyone who is interested in WinCE development is welcomed.
iWave Systems announced the World's first availability of WEC7 BSP on i.MX6 SOM Development Platform besides the existing Linux 3.0.15 & Android ICS 4.0 BSP versions.Please see the below links for more details.
http://imxcommunity.org/group/i-mx6-som-development-platform
GuruCE has developed a full-featured high performance Windows Embedded CE/Compact 7 driver for the FlexCAN module found in the Freescale iMX25, iMX28, iMX35 and iMX53 processors. The GuruCE High Performance FlexCAN driver is the fastest and most feature rich CAN driver available for the Freescale iMX processors. The driver supports every feature offered by the FlexCAN module (including hardware frame filters) and has been tested to receive more than 500 CAN frames per second without dropping any! More info here: http://guruce.com/content/products/windows-ce-embedded-compact-flexcan-driver-for-freescale-imx-proc...
Hi anybody, I'm a starter.
That I don't have knowledge about win ce, do you have a any tutorial or guide to make me build, run, and download win ce 7 to imx53 board (version 2 of freescale)?
Thanks for help.
Best regards.
Hi anybody, recently I am working with WinCE for MX51 platform, and try to add two I/O as keypad input with interrupt, but we found MX51 EVK enter the interrupt routine and can't walk out after power up MX51 EVK, following is our GPIO keypad program, could you anyone help comment it?
//------------------------------------------------------------------------------
//
// Copyright (C) 2008-2009, Freescale Semiconductor, Inc. All Rights Reserved.
// THIS SOURCE CODE, AND ITS USE AND DISTRIBUTION, IS SUBJECT TO THE TERMS
// AND CONDITIONS OF THE APPLICABLE LICENSE AGREEMENT
//
//------------------------------------------------------------------------------
//
// File: pwrbutton.c
//
// This file contains driver support for the power button.
//
//-----------------------------------------------------------------------------
#pragma warning(push)
#pragma warning(disable: 4115 4201 4204 4214)
#include <windows.h>
#include <ceddk.h>
#pragma warning(pop)
#include "bsp.h"
#include "pmic.h"
//-----------------------------------------------------------------------------
// External Functions
//-----------------------------------------------------------------------------
// External Variables
//-----------------------------------------------------------------------------
// Defines
// EVK power button is SW1. SW1 drives SYS_ON_OFF_REQ signal tied to EIM_A27.
// EIM_A27 can be muxed as GPIO2_21. Configure definitions to use GPIO2_21 for
// power button events.
#define BSP_PWRBTN_IOMUX_PIN DDK_IOMUX_PIN_EIM_A27
#define BSP_PWRBTN_IOMUX_PAD DDK_IOMUX_PAD_EIM_A27
#define BSP_PWRBTN_GPIO_PORT DDK_GPIO_PORT2
#define BSP_PWRBTN_GPIO_PIN 21
#define BSP_PWRBTN_GPIO_IRQ IRQ_GPIO2_PIN21
//GPIO3_2
#define BSP_BTN1_IOMUX_PIN DDK_IOMUX_PIN_DI1_PIN13
#define BSP_BTN1_IOMUX_PAD DDK_IOMUX_PAD_DI1_PIN13
#define BSP_BTN1_GPIO_PORT DDK_GPIO_PORT3
#define BSP_BTN1_GPIO_PIN 2
#define BSP_BTN1_GPIO_IRQ IRQ_GPIO3_PIN2
//GPIO4_9
#define BSP_BTN2_IOMUX_PIN DDK_IOMUX_PIN_CSI2_D12
#define BSP_BTN2_IOMUX_PAD DDK_IOMUX_PAD_CSI2_D12
#define BSP_BTN2_GPIO_PORT DDK_GPIO_PORT4
#define BSP_BTN2_GPIO_PIN 9
#define BSP_BTN2_GPIO_IRQ IRQ_GPIO4_PIN9
// BSP_PWRBTN_DEBOUNCE_SAMPLE_MSEC specifies the time between
// sampling of power button value.
#define BSP_PWRBTN_DEBOUNCE_SAMPLE_MSEC 10 // 10 msec
// BSP_PWRBTN_DEBOUNCE_SUSPEND_MSEC specifies the minimum
// assertion time for detecting that the user wants to suspend the system.
#define BSP_PWRBTN_DEBOUNCE_SUSPEND_MSEC 100 // 100 msec
// BSP_PWRBTN_DEBOUNCE_OFF_MSEC specifies the minimum
// assertion time for detecting that the user wants to power off the system.
#define BSP_PWRBTN_DEBOUNCE_OFF_MSEC 2000 // 2 sec
// BSP_PWRBTN_DEBOUNCE_IGNORE_MSEC specifies the minimum
// time for ignoring the power button after processing the previous
// button press.
#define BSP_PWRBTN_DEBOUNCE_IGNORE_MSEC 500 // 500 msec
#define BSP_PWRBTN_THREAD_PRIORITY 152
#define BSP_Btn1BTN_THREAD_PRIORITY 152
#define BSP_Btn2BTN_THREAD_PRIORITY 152
//-----------------------------------------------------------------------------
// Types
//-----------------------------------------------------------------------------
// Global Variables
//-----------------------------------------------------------------------------
// Local Variables
static HANDLE g_hPwrBtnThread;
static HANDLE g_hPwrBtnEvent;
static DWORD g_dwPwrBtnSysIntr = (DWORD)SYSINTR_UNDEFINED;
static HANDLE g_hBtn1Thread;
static HANDLE g_hBtn1Event;
static DWORD g_dwBtn1SysIntr = (DWORD)SYSINTR_UNDEFINED;
static HANDLE g_hBtn2Thread;
static HANDLE g_hBtn2Event;
static DWORD g_dwBtn2SysIntr = (DWORD)SYSINTR_UNDEFINED;
//-----------------------------------------------------------------------------
// Local Functions
static DWORD WINAPI PwrBtnThread (LPVOID lpParam);
static DWORD WINAPI Btn1Thread (LPVOID lpParam);
static DWORD WINAPI Btn2Thread (LPVOID lpParam);
//-----------------------------------------------------------------------------
//
// Function: DllEntry
//
// This function is an optional method of entry into a DLL. If the function
// is used, it is called by the system when processes and threads are
// initialized and terminated, or on calls to the LoadLibrary and
// FreeLibrary functions.
//
// Parameters:
// hinstDLL
// [in] Handle to the DLL. The value is the base address of the DLL.
//
// dwReason
// [in] Specifies a flag indicating why the DLL entry-point function
// is being called.
//
// lpvReserved
// [in] Specifies further aspects of DLL initialization and cleanup.
// If dwReason is DLL_PROCESS_ATTACH, lpvReserved is NULL for
// dynamic loads and nonnull for static loads. If dwReason is
// DLL_PROCESS_DETACH, lpvReserved is NULL if DllMain is called
// by using FreeLibrary and nonnull if DllMain is called during
// process termination.
//
// Returns:
// When the system calls the DllMain function with the
// DLL_PROCESS_ATTACH value, the function returns TRUE if it
// succeeds or FALSE if initialization fails.
//
// If the return value is FALSE when DllMain is called because the
// process uses the LoadLibrary function, LoadLibrary returns NULL.
//
// If the return value is FALSE when DllMain is called during
// process initialization, the process terminates with an error.
//
// When the system calls the DllMain function with a value other
// than DLL_PROCESS_ATTACH, the return value is ignored.
//
//-----------------------------------------------------------------------------
BOOL WINAPI DllEntry(HINSTANCE hDllHandle, DWORD dwReason,
LPVOID lpreserved)
{
// Remove-W4: Warning C4100 workaround
UNREFERENCED_PARAMETER(lpreserved);
switch (dwReason)
{
case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls((HMODULE) hDllHandle);
break;
case DLL_PROCESS_DETACH:
break;
default:
break;
}
return TRUE;
}
//-----------------------------------------------------------------------------
//
// Function: Init
//
// This function initializes the power button driver. Called by the Device Manager to
// initialize a device.
//
// Parameters:
// None.
//
// Returns:
// Returns TRUE if successful, otherwise returns FALSE.
//
//-----------------------------------------------------------------------------
BOOL Init(void)
{
BOOL rc = FALSE;
DWORD dwIrq;
// Configure GPIO signal for power button events
DDKIomuxSetPinMux(BSP_PWRBTN_IOMUX_PIN, DDK_IOMUX_PIN_MUXMODE_ALT1, DDK_IOMUX_PIN_SION_REGULAR);
DDKIomuxSetPadConfig(BSP_PWRBTN_IOMUX_PAD, DDK_IOMUX_PAD_SLEW_NULL, DDK_IOMUX_PAD_DRIVE_NULL, DDK_IOMUX_PAD_OPENDRAIN_NULL, DDK_IOMUX_PAD_PULL_NONE, DDK_IOMUX_PAD_HYSTERESIS_ENABLE, DDK_IOMUX_PAD_INMODE_NULL, DDK_IOMUX_PAD_OUTVOLT_NULL);
DDKGpioSetConfig(BSP_PWRBTN_GPIO_PORT, BSP_PWRBTN_GPIO_PIN, DDK_GPIO_DIR_IN, DDK_GPIO_INTR_HIGH_LEV);
DDKGpioClearIntrPin(BSP_PWRBTN_GPIO_PORT, BSP_PWRBTN_GPIO_PIN);
///gpio3_2
DDKIomuxSetPinMux(BSP_BTN1_IOMUX_PIN, DDK_IOMUX_PIN_MUXMODE_ALT1, DDK_IOMUX_PIN_SION_REGULAR);
DDKIomuxSetPadConfig(BSP_BTN1_IOMUX_PAD, DDK_IOMUX_PAD_SLEW_NULL, DDK_IOMUX_PAD_DRIVE_NULL, DDK_IOMUX_PAD_OPENDRAIN_NULL, DDK_IOMUX_PAD_PULL_NONE, DDK_IOMUX_PAD_HYSTERESIS_ENABLE, DDK_IOMUX_PAD_INMODE_NULL, DDK_IOMUX_PAD_OUTVOLT_NULL);
DDKGpioSetConfig(BSP_BTN1_GPIO_PORT, BSP_BTN1_GPIO_PIN, DDK_GPIO_DIR_IN, DDK_GPIO_INTR_FALL_EDGE);
DDKGpioClearIntrPin(BSP_BTN1_GPIO_PORT, BSP_BTN1_GPIO_PIN);
//gpio4_9
DDKIomuxSetPinMux(BSP_BTN2_IOMUX_PIN, DDK_IOMUX_PIN_MUXMODE_ALT1, DDK_IOMUX_PIN_SION_REGULAR);
DDKIomuxSetPadConfig(BSP_BTN2_IOMUX_PAD, DDK_IOMUX_PAD_SLEW_NULL, DDK_IOMUX_PAD_DRIVE_NULL, DDK_IOMUX_PAD_OPENDRAIN_NULL, DDK_IOMUX_PAD_PULL_NONE, DDK_IOMUX_PAD_HYSTERESIS_ENABLE, DDK_IOMUX_PAD_INMODE_NULL, DDK_IOMUX_PAD_OUTVOLT_NULL);
DDKGpioSetConfig(BSP_BTN2_GPIO_PORT, BSP_BTN2_GPIO_PIN, DDK_GPIO_DIR_IN, DDK_GPIO_INTR_FALL_EDGE);
DDKGpioClearIntrPin(BSP_BTN2_GPIO_PORT, BSP_BTN2_GPIO_PIN);
// Create event for IST signaling
g_hPwrBtnEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if(g_hPwrBtnEvent == NULL)
{
ERRORMSG(TRUE, (TEXT("%s(): failed to create IST event\r\n"), __WFUNCTION__));
goto cleanUp;
}
g_hBtn1Event = CreateEvent(NULL, FALSE, FALSE, NULL);
if(g_hBtn1Event == NULL)
{
ERRORMSG(TRUE, (TEXT("%s(): failed to create IST event\r\n"), __WFUNCTION__));
goto cleanUp;
}
g_hBtn2Event = CreateEvent(NULL, FALSE, FALSE, NULL);
if(g_hBtn2Event == NULL)
{
ERRORMSG(TRUE, (TEXT("%s(): failed to create IST event\r\n"), __WFUNCTION__));
goto cleanUp;
}
// Register the GPIO IRQ
dwIrq = BSP_PWRBTN_GPIO_IRQ;
if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &dwIrq, sizeof(dwIrq), &g_dwPwrBtnSysIntr, sizeof(g_dwPwrBtnSysIntr), NULL))
{
ERRORMSG(TRUE, (TEXT("%s(): failed to map irq into sys intr\r\n"), __WFUNCTION__));
goto cleanUp;
}
if (!InterruptInitialize(g_dwPwrBtnSysIntr, g_hPwrBtnEvent, NULL, 0)) {
ERRORMSG(TRUE, (TEXT("%s(): failed to register sys intr\r\n"), __WFUNCTION__));
goto cleanUp;
}
// Configure power button as wake source
if (!KernelIoControl(IOCTL_HAL_ENABLE_WAKE, &g_dwPwrBtnSysIntr, sizeof(g_dwPwrBtnSysIntr), NULL, 0, NULL))
{
ERRORMSG(TRUE, (TEXT("%s(): failed to register as wake source\r\n"), __WFUNCTION__));
goto cleanUp;
}
//gpio3_2
dwIrq = BSP_BTN1_GPIO_IRQ;
if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &dwIrq, sizeof(dwIrq), &g_dwBtn1SysIntr, sizeof(g_dwBtn1SysIntr), NULL))
{
ERRORMSG(TRUE, (TEXT("%s(): failed to map irq into sys intr\r\n"), __WFUNCTION__));
goto cleanUp;
}
if (!InterruptInitialize(g_dwBtn1SysIntr, g_hBtn1Event, NULL, 0)) {
ERRORMSG(TRUE, (TEXT("%s(): failed to register sys intr\r\n"), __WFUNCTION__));
goto cleanUp;
}
//gpio4_9
dwIrq = BSP_BTN2_GPIO_IRQ;
if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &dwIrq, sizeof(dwIrq), &g_dwBtn2SysIntr, sizeof(g_dwBtn2SysIntr), NULL))
{
ERRORMSG(TRUE, (TEXT("%s(): failed to map irq into sys intr\r\n"), __WFUNCTION__));
goto cleanUp;
}
if (!InterruptInitialize(g_dwBtn2SysIntr, g_hBtn2Event, NULL, 0)) {
ERRORMSG(TRUE, (TEXT("%s(): failed to register sys intr\r\n"), __WFUNCTION__));
goto cleanUp;
}
// Create IST for power button interrupts
g_hPwrBtnThread = CreateThread(NULL, 0, PwrBtnThread, NULL, 0, NULL);
if (!g_hPwrBtnThread)
{
ERRORMSG(TRUE, (_T("CreateThread failed for power button driver!\r\n")));
goto cleanUp;
}
else
{
CeSetThreadPriority(g_hPwrBtnThread, BSP_PWRBTN_THREAD_PRIORITY);
}
g_hBtn1Thread = CreateThread(NULL, 0, Btn1Thread, NULL, 0, NULL);
if (!g_hPwrBtnThread)
{
ERRORMSG(TRUE, (_T("CreateThread F6 failed!\r\n")));
goto cleanUp;
}
else
{
CeSetThreadPriority(g_hBtn1Thread, BSP_Btn1BTN_THREAD_PRIORITY);
}
g_hBtn2Thread = CreateThread(NULL, 0, Btn2Thread, NULL, 0, NULL);
if (!g_hPwrBtnThread)
{
ERRORMSG(TRUE, (_T("CreateThread F7 failed !\r\n")));
goto cleanUp;
}
else
{
CeSetThreadPriority(g_hBtn2Thread, BSP_Btn2BTN_THREAD_PRIORITY);
}
rc = TRUE;
cleanUp:
return rc;
}
//-----------------------------------------------------------------------------
//
// Function: Deinit
//
// This function deinitializes the power button driver. Called by the Device Manager to
// deinitialize a device.
//
// Parameters:
// None.
//
// Returns:
// Returns TRUE.
//
//-----------------------------------------------------------------------------
BOOL Deinit(void)
{
// Power button driver is never unloaded. This entry point is only defined
// to meet minum requirements of the stream interface.
return TRUE;
}
//-----------------------------------------------------------------------------
//
// Function: PwrBtnThread
//
// This is the interrupt service thread for the power button driver.
//
// Parameters:
// lpParam
// [in] Thread data passed to the function using the
// lpParameter parameter of the CreateThread function. Not used.
//
// Returns:
// Returns thread exit code.
//
//-----------------------------------------------------------------------------
static DWORD WINAPI PwrBtnThread (LPVOID lpParam)
{
UINT32 msec, start;
UINT32 pinVal;
WCHAR szState[MAX_PATH];
DWORD dwStateFlags = 0;
// Remove-W4: Warning C4100 workaround
UNREFERENCED_PARAMETER(lpParam);
// IST loop for servicing power button interrupts
while (WaitForSingleObject(g_hPwrBtnEvent, INFINITE) != WAIT_FAILED)
{
// Capture start time of button press
start = GetTickCount();
// Query current system power state to determine if we are resuming
// from suspend
GetSystemPowerState(szState, MAX_PATH, &dwStateFlags);
// Avoid requesting power state transition if the system is resuming from
// suspend. In such cases the POWER_STATE_SUSPEND flag will be set.
if (!(POWER_STATE(dwStateFlags) & POWER_STATE_SUSPEND))
{
// Keep track of how long button is pressed
msec = 0;
// Loop to sample power button pin
do
{
// Sleep between samples
Sleep(BSP_PWRBTN_DEBOUNCE_SAMPLE_MSEC);
// Read current power button pin
DDKGpioReadDataPin(BSP_PWRBTN_GPIO_PORT, BSP_PWRBTN_GPIO_PIN, &pinVal);
// Check if button is still pressed
if (pinVal)
{
// Update how long button is pressed
msec = GetTickCount() - start;
}
// Loop terminates if button is released or time to power off
// system is reached
} while (pinVal && (msec < BSP_PWRBTN_DEBOUNCE_OFF_MSEC));
// Check if button press indicates user wants to power off the
// system
if (msec >= BSP_PWRBTN_DEBOUNCE_OFF_MSEC)
{
// Powering off the system through hardware requires the
// two EVK SYS_ON_OFF_CTL signals to be deasserted. One of
// these signals is driven by the PMIC, the other by CPU.
// Request for the PMIC SYS_ON_OFF_CTL signal to be
// deasserted. During OEMPowerOff, the OAL will take
// care of the other SYS_ON_OFF_CTL to complete the
// power off.
PmicRegisterWrite(MC13892_PWR_MISC_ADDR,
CSP_BITFVAL(MC13892_REG_MISC_PWGT2SPIEN, 1),
CSP_BITFMASK(MC13892_REG_MISC_PWGT2SPIEN));
// Since we are powering off, disallow the power button from
// generating wake events that may disrupt powering off the
// system.
KernelIoControl(IOCTL_HAL_DISABLE_WAKE, &g_dwPwrBtnSysIntr, sizeof(g_dwPwrBtnSysIntr), NULL, 0, NULL);
// Note that we could use SetSystemPowerState to request
// POWER_STATE_OFF, but this state is not supported by
// the default Power Manager. Instead, we just let
// the code fall through to generate a POWER_STATE_SUSPEND
// request and allow the OAL power off the system
// in OEMPowerOff.
}
// Check if button press indicates user wants to suspend the
// system
if (msec >= BSP_PWRBTN_DEBOUNCE_SUSPEND_MSEC)
{
SetSystemPowerState(NULL, POWER_STATE_SUSPEND, POWER_FORCE);
}
}
// After handling the button press, delay before servicing new button
// interrupts to prevent from bouncing into suspend again
Sleep(BSP_PWRBTN_DEBOUNCE_IGNORE_MSEC);
// Clear and reenable button interrupts
DDKGpioClearIntrPin(BSP_PWRBTN_GPIO_PORT, BSP_PWRBTN_GPIO_PIN);
InterruptDone(g_dwPwrBtnSysIntr);
}
return 0;
}
static DWORD WINAPI Btn1Thread (LPVOID lpParam)
{
UINT32 pinVal;
// Remove-W4: Warning C4100 workaround
UNREFERENCED_PARAMETER(lpParam);
while (WaitForSingleObject(g_hPwrBtnEvent, INFINITE) != WAIT_FAILED)
{
Sleep(20);
// Read current power button pin
DDKGpioReadDataPin(BSP_BTN1_GPIO_PORT, BSP_BTN1_GPIO_PIN, &pinVal);
// Check if button is still pressed
if (!pinVal)
{
//send key message
keybd_event(VK_F6, 0, 0, 0);
}
for(;;)
{
DDKGpioReadDataPin(BSP_BTN1_GPIO_PORT, BSP_BTN1_GPIO_PIN, &pinVal);
if(pinVal)
{
keybd_event(VK_F6,0,KEYEVENTF_KEYUP,0);
break;
}
}
// Clear and reenable button interrupts
DDKGpioClearIntrPin(BSP_BTN1_GPIO_PORT, BSP_BTN1_GPIO_PIN);
InterruptDone(g_dwBtn1SysIntr);
}
return 0;
}
static DWORD WINAPI Btn2Thread (LPVOID lpParam)
{
UINT32 pinVal;
// Remove-W4: Warning C4100 workaround
UNREFERENCED_PARAMETER(lpParam);
while (WaitForSingleObject(g_hPwrBtnEvent, INFINITE) != WAIT_FAILED)
{
Sleep(20);
// Read current power button pin
DDKGpioReadDataPin(BSP_BTN2_GPIO_PORT, BSP_BTN2_GPIO_PIN, &pinVal);
// Check if button is still pressed
if (!pinVal)
{
//send key message
keybd_event(VK_F7, 0, 0, 0);
}
for(;;)
{
DDKGpioReadDataPin(BSP_BTN2_GPIO_PORT, BSP_BTN2_GPIO_PIN, &pinVal);
if(pinVal)
{
keybd_event(VK_F7,0,KEYEVENTF_KEYUP,0);
break;
}
}
// Clear and reenable button interrupts
DDKGpioClearIntrPin(BSP_PWRBTN_GPIO_PORT, BSP_PWRBTN_GPIO_PIN);
InterruptDone(g_dwBtn2SysIntr);
}
return 0;
}