Introduction |
The PXA255 processor is one of the popular xscale processor other
then PXA270. Even though Intel is not promoting this product for the
future use, there are many development boards as well as devices
developed over this 200MHz chip. Microsoft has released the WindowsCE
4.20 BSP during the initial boom of this processor into the market.
After the introduction of the PXA270 processor by Intel Microsoft did
not put any effort to release WindowsCE BSP for the next release of its
pioneer Mobile operating system like Windows CE 5.0.
This
article introduces some easy as well interesting method to develop
PXA255 BSP for Windows CE 5.0. Instead of having the conventional
approach of porting PXA255 Windows CE 4.20 BSP to Windows CE 5.0 we are
following a different approach, take the PXA270 Windows CE 5.0 BSP and
modify it for PXA255 processor. |
|
Scope |
The scope of this document is limited to audience who are
interested in developing PXA255 BSP for Windows CE 5.0 or even 6.0. We
use Windows CE 5.0 BSP for Intel's PXA270 Developers board as the
reference BSP for our development. This BSP is commonly known as the
Mainstone-III Windows CE 5.0 BSP. The user is expected to have the
understanding of PXA255 processor register set and Mainstone III BSP
architecture. |
|
Porting the Cross Platform Low Level definitions (XLLP) |
The Cross Platform Low Level functions are the
processor initialization functions, and are closely bind to the
processor. PXA270 has few features those are not available for the
PXA255 processor. Most of the registers for the devices those are
common for PXA255 and PXA270 have same register set and bit definition.
So those features and its corresponding register set have to be removed
from the BSP. For example PXA27x contains 120 GPIO where as PXA255
contains 85 GPIO pins, PXA255 doesn't have the power I2C interface and
it contains only 15 DMA channels etc. The register set is defined in a
file located at wince500/(platform)/src/common/xllp/inc/xlli_bulverde_defs.inc |
|
|
Step 1: |
| Remove the following register definitions from the xlli_bulverde_defs.inc file. Gpio Registers: xlli_GPLR3_offset EQU (0x100) xlli_GPDR3_offset EQU (0x10C) xlli_GPSR3_offset EQU (0x118) xlli_GPCR3_offset EQU (0x124) xlli_GAFR3_L_offset EQU (0x06C) xlli_GAFR3_U_offset EQU (0x070)
Power Manager: xlli_PGSR3_offset EQU (0x2C) xlli_PSLR_offset EQU (0x34); Power Manager Sleep Mode Config Register xlli_PSTR_offset EQU (0x38); Power Manager Standby Mode Config Register xlli_PSNR_offset EQU (0x3C); Power Manager Sense Mode Config Register xlli_PVCR_offset EQU (0x40); Power Manager Voltage Change Control Register xlli_PKWR_offset EQU (0x50); Power Manager Keyboard Wake-up Enable Register xlli_PKSR_offset EQU (0x54); Power Manager Keyboard Edge-Detect Status Register xlli_PI2DBR_offset EQU (0x188); Power I2C Data Buffer Register xlli_PI2CR_offset EQU (0x190); Power I2C Control Register xlli_PI2SR_offset EQU (0x198); Power I2C Status Register xlli_PI2SAR_offset EQU (0x1A0); Power I2C Slave Address Register
Power Manager Register definition bit masks: xlli_PCFR_SYSEN_EN EQU (0x20); SYS_EN pin xlli_PCFR_DC_EN EQU (0x80); Deep-Sleep Mode
Memory Controller Registers: xlli_ARB_CNTL_offset
EQU (0x48) xlli_BSCNTR0_offset EQU (0x4C) xlli_BSCNTR1_offset EQU
(0x50) xlli_LCDBSCNTR_offset EQU (0x54) xlli_BSCNTR2_offset EQU (0x5C)
xlli_BSCNTR3_offset EQU (0x60)
Interrupt Controller: xlli_ICHP_offset EQU (0x18); Interrupt Controller Highest Priority Register xlli_ICMR2_offset EQU (0xA0); Interrupt Controller Mask Register 2 xlli_ICLR2_offset EQU (0xA4); Interrupt Controller Level Register 2 xlli_ICCR2_offset EQU (0xAC); Interrupt Controller Control Register 2
Clock Registers: xlli_CCSR_offset EQU (0x0C); Core Clock Status Register xlli_CCCR_A_Bit_Mask EQU (0x1 ? 25); "A" bit is bit 25 in CCCR
OS Timer Registers: xlli_OSCR4_offset EQU (0x40); OS Timer Count Register 4 xlli_OSCR5_offset EQU (0x44); OS Timer Count Register 5 xlli_OSCR6_offset EQU (0x48); OS Timer Count Register 6 xlli_OSCR7_offset EQU (0x4C); OS Timer Count Register 7 xlli_OSCR8_offset EQU (0x50); OS Timer Count Register 8 xlli_OSCR9_offset EQU (0x54); OS Timer Count Register 9 xlli_OSCR10_offset EQU (0x58); OS Timer Count Register 10 xlli_OSCR11_offset EQU (0x5C); OS Timer Count Register 11
xlli_OSMR4_offset EQU (0x80); OS Timer Match Register 4 xlli_OSMR5_offset EQU (0x84); OS Timer Match Register 5 xlli_OSMR6_offset EQU (0x88); OS Timer Match Register 6 xlli_OSMR7_offset EQU (0x8C); OS Timer Match Register 7 xlli_OSMR8_offset EQU (0x90); OS Timer Match Register 8 xlli_OSMR9_offset EQU (0x94); OS Timer Match Register 9 xlli_OSMR10_offset EQU (0x98); OS Timer Match Register 10 xlli_OSMR11_offset EQU (0x9C); OS Timer Match Register 11
xlli_OMCR4_offset EQU (0xC0); OS Timer Match Control Register 4 xlli_OMCR5_offset EQU (0xC4); OS Timer Match Control Register 5 xlli_OMCR6_offset EQU (0xC8); OS Timer Match Control Register 6 xlli_OMCR7_offset EQU (0xCC); OS Timer Match Control Register 7 xlli_OMCR8_offset EQU (0xD0); OS Timer Match Control Register 8 xlli_OMCR9_offset EQU (0xD4); OS Timer Match Control Register 9 xlli_OMCR10_offset EQU (0xD8); OS Timer Match Control Register 10 xlli_OMCR11_offset EQU (0xDC); OS Timer Match Control Register 11
RTC Registers: xlli_RDCR_offset EQU (0x10); RTC Day Counter Register xlli_RYCR_offset EQU (0x14); RTC Year Counter Register xlli_RDAR1_offset EQU (0x18); RTC Day Alarm Register 1 xlli_RYAR1_offset EQU (0x1C); RTC Year Alarm Register 2 xlli_RDAR2_offset EQU (0x20); RTC Day Alarm Register 2 xlli_RYAR2_offset EQU (0x24); RTC Year Alarm Register 2 xlli_SWCR_offset EQU (0x28); Stopwatch Counter Register xlli_SWAR1_offset EQU (0x2C); Stopwatch Alarm Register 1 xlli_SWAR2_offset EQU (0x30); Stopwatch Alarm Register 2 xlli_PICR_offset EQU (0x34); Periodic Interrupt Counter Register xlli_PIAR_offset EQU (0x38); Periodic Interrupt Alarm Register
Oscillator controller bit definitions: xlli_OSCC_TOUT_EN EQU (0x04); Timekeeping Output enable xlli_OSCC_PIO_EN EQU (0x08); Processor Oscillator Output Enable xlli_OSCC_CRI EQU (0x10); Processor Oscillator Output Enable
|
|
|
Step 2: |
|
Change the GPIO registers value and SDRAM register values based on new Platform (All values are defined in the wince500/(platform)/src/common/xllp/inc/xlli_ (Platform) _defs.inc).
|
| Also if you have any board specific registers
you can represent the values in this file and remove the GPIO registers
values which are irrelevant to PXA255 processor. The above two files
are used by the Startup code of both the EBOOT and KERNEL. |
|
Step 3: |
| Remove all the register definitions
which are not part of the PXA255 processors device specific register
set. These registers are defined in the header files in the directory,
wince500/platform/src/common/xllp/inc. Each header file name is of the
format xlli_(device).h. The register set is represented as structure
that contains all the registers related to devices. Also the bit
definitions for of each of those registers are defined in the same
header file. Remove the registers and also the bit definitions which
are not relevant to PXA255.
For example, to remove the GPIO
registers which are not available in the PXA255, comment out the lines
in the file wince500/(platform)/src/common/xllp/inc/xllp_gpio.h as
shown below. typedef struct {
…….. ……..
// Commented by econ for PXA255 Gpio configuration (pxa255 is having 85 GPIO)
// XLLP_VUINT32_T GAFR3_L; /* Alt. Function Select Reg.[ 96:111] */ // XLLP_VUINT32_T GAFR3_U; /* Alt. Function Select Reg.[112:120] */ // XLLP_VUINT32_T RESERVED1[35]; /* addr. offset 0x074-0x0fc */ // XLLP_VUINT32_T GPLR3; /* Level Detect Reg. Bank 3 */ // XLLP_VUINT32_T RESERVED2[2]; /* addr. offset 0x104-0x108 */ // XLLP_VUINT32_T GPDR3; /* Data Direction Reg. Bank 3 */ // XLLP_VUINT32_T RESERVED3[2]; /* addr. offset 0x110-0x114 */ // XLLP_VUINT32_T GPSR3; /* Pin Output Set Reg. Bank 3 */ // XLLP_VUINT32_T RESERVED4[2]; /* addr. offset 0x11c-0x120 */ // XLLP_VUINT32_T GPCR3; /* Pin Output Clr Reg. Bank 3 */ // XLLP_VUINT32_T RESERVED5[2]; /* addr. offset 0x128-0x12c */ // XLLP_VUINT32_T GRER3; /* Ris. Edge Detect Enable Reg. Bank 3 */ // XLLP_VUINT32_T RESERVED6[2]; /* addr. offset 0x134-0x138 */ // XLLP_VUINT32_T GFER3; /* Fal. Edge Detect Enable Reg. Bank 3 */ // XLLP_VUINT32_T RESERVED7[2]; /* addr. offset 0x140-0x144 */ // XLLP_VUINT32_T GEDR3; /* Edge Detect Status Reg. Bank 3 */
} XLLP_GPIO_T, *P_XLLP_GPIO_T;
Follow the same instructions for the remaining device files in the same directory.
1)
Since PXA255 CCLKCFG register contains only F and T bit definitions and
there is no B and H bits, related operations has to be removed from the
file. wince500/(platform)/src/common/xllp/src /xlli_lowlev_init.s file.
2)
The CCCR register for PXA255 and PXA27x is different. There is no 'A'
bit on PXA255, so remove the xlli_mem_Topt, xlli_mem_restart
subroutines from the xlli_lowlev_init.s file. In the xlli_setClocks
routine, the CCLKCFG Turbo mode bit and Fast bus Mode bit can be
assigned directly to the CCCR register.
3) Change the MDREFR K1DB2 bit value according to the memory clock frequency.
4)
I2C interface is a dedicated interface in PXA255 instead of GPIO
alternating functions PXA270 and also there is no power I2C interface
in PXA255. So remove the header file declarations in the corresponding
device header file.
|
|
|
Porting the Kernel |
There is no much difference in the processor dependent kernel
source of the BSP. But there are two important units which are highly
depended to processor, the Interrupt Unit and RTC. The interrupt
architecture bit different in PXA255 and PXA270. |
1) For PXA27x processor ICHP (Interrupt Higher priority register)
is used for detecting the interrupt and for PXA255 processor ICIP
(Interrupt Pending Register) is used. So the OEMInterruptHandler() has to be changed. Do the following changes in the OEMIntyerrupthandler().
In
PXA270 the IRQ values are defined as IDs that can be understandable by
the ICHP section of the processor. But in PXA255 interrupt are detected
with ICIP register bits. So the OEMInterruptHandler() has to be
rewritten in a from as given below. Since the Interrupt priority array g_intPriorities used by OEMIntyerrupthandler() ICHP remove it from the int.c file.
ULONG OEMInterruptHandler(ULONG ra) { UINT32 irq = OAL_INTR_IRQ_UNDEFINED; UINT32 sysIntr = SYSINTR_NOP;
if (!g_pICReg || !g_pOSTRegs || !g_pGPIORegs ) { return(SYSINTR_NOP); } irq = (g_pICReg->icip); if (irq & 0) { return(SYSINTR_NOP); } // System timer interrupt? if (irq & PXA_IRQ_OSMR0) { // The rest is up to the timer interrupt handler. // sysIntr = OALTimerIntrHandler(); } else if (irq & PXA_IRQ_STUART) { CLRREG32(&g_pICReg->icmr, PXA_IRQ_STUART); return(SYSINTR_IR); } else if (irq & PXA_IRQ_FFUART) { CLRREG32(&g_pICReg->icmr, PXA_IRQ_FFUART); return(SYSINTR_FFUART); } . . . . } Here PXA_IRQ_OSMR0, PXA_IRQ_STUART etc are ICIP bits.
|
2. PXA255 RTC contains only the RTTR, RTAR, RCNR, RTSR register
so day, month, year calculation are done by software or External RTC. The following are the RTC functions are used by the kernel which needs to be rewritten for PXA255. OEMGetRealTime() OEMSetRealTime() OEMSetCurrentTime() OEMSetAlarmTime() BOOL OALIoCtlHalInitRTC( UINT32 code, VOID *pInpBuffer, UINT32 inpSize, VOID *pOutBuffer, UINT32 outSize, UINT32 *pOutSize)
These functions has to be implemented in the \WINCE500\PLATFORM\(Platform name)\SRC\COMMON\RTC\rtc.c file |
|
3.PXA255 OS Timer is running at the frequency of 3.86 MHz where
as PXA27x OS Timer is Timer running at the frequency of 3.25 MHz. So
the Ticks per Microseconds definitions need to be changed. These OS
timer definitions are used by the kernel and are defined in the
\WINCE500\PLATFORM\(Platform name)\SRC\Bsp_cfg.h file.
Also
calculate the divisor value according to the OEMMintickdistance in the
OEMInit () function of init.c file. Make the followings changes in the
for OS Timer definitions in bsp_cfg.h.
#define OEM_CLOCK_FREQ
3686400 // 3.25M ticks/sec #define OEM_TICKS_1MS 3686 // 1ms in ticks
#define RESCHED_PERIOD 1 // Reschedule period in ms #define
RESCHED_INCREMENT (RESCHED_PERIOD * OEM_TICKS_1MS) #define
OEM_TICK_COUNT_MARGIN 0 |
4) Libraries for the sources KERN, KERNKITL, KERNKITLPROF are
the same which is already in the sources file used for PXA27x processor
except oal_cache_pxa27x.lib. Instead of the oal_cache_pxa27x.lib use
oal_cache_pxa250.lib for PXA255. The above three kernel related
directories are under the following tree. \WINCE500\PLATFORM\(platform
name) \SRC\KERNEL\ The sample KERN sources file changed for PXA255 is given below.
TARGETNAME=kern TARGETTYPE=PROGRAM RELEASETYPE=PLATFORM SYNCHRONIZE_DRAIN=1 EXEENTRY=StartUp LDEFINES=-subsystem:native /DEBUG /DEBUGTYPE:CV /FIXED:NO SOURCES= \ kitl.c
TARGETLIBS= \ $(_TARGETPLATROOT)\lib\$(_CPUDEPPATH)\oal.lib \ $(_COMMONOAKROOT)\lib\$(_CPUDEPPATH)\nk.lib \ $(_TARGETPLATROOT)\lib\$(_CPUINDPATH)\mainstoneii_freq.lib \ $(_TARGETPLATROOT)\lib\$(_CPUINDPATH)\mainstoneii_io.lib \ $(_TARGETPLATROOT)\lib\$(_CPUINDPATH)\mainstoneii_dbgserial.lib \ $(_TARGETPLATROOT)\lib\$(_CPUINDPATH)\pxa27x_xllp.lib \ $(_TARGETPLATROOT)\lib\$(_CPUINDPATH)\oal_startup_pxa27x.lib \ $(_PLATCOMMONLIB)\$(_CPUINDPATH)\oal_cache_pxa250.lib \ $(_TARGETPLATROOT)\lib\$(_CPUINDPATH)\oal_intr_pxa27x.lib \ $(_PLATCOMMONLIB)\$(_CPUINDPATH)\oal_memory_pxa27x.lib \ $(_PLATCOMMONLIB)\$(_CPUINDPATH)\oal_timer_pxa27x.lib \ $(_PLATCOMMONLIB)\$(_CPUINDPATH)\oal_timer_idle_stub.lib \ $(_PLATCOMMONLIB)\$(_CPUINDPATH)\oal_abort_pxa27x.lib \ $(_PLATCOMMONLIB)\$(_CPUINDPATH)\oal_power_pxa27x.lib \ $(_TARGETPLATROOT)\lib\$(_CPUINDPATH)\oal_rtc_pxa27x.lib \ $(_PLATCOMMONLIB)\$(_CPUINDPATH)\oal_misc_pxa27x.lib \ $(_TARGETPLATROOT)\lib\$(_CPUINDPATH)\oal_serial.lib \ $(_PLATCOMMONLIB)\$(_CPUDEPPATH)\oal_ioctl.lib \ $(_PLATCOMMONLIB)\$(_CPUDEPPATH)\oal_io.lib \ $(_PLATCOMMONLIB)\$(_CPUDEPPATH)\oal_kitl.lib \ $(_PLATCOMMONLIB)\$(_CPUDEPPATH)\oal_log.lib \ $(_PLATCOMMONLIB)\$(_CPUDEPPATH)\oal_other.lib \ $(_COMMONOAKROOT)\lib\$(_CPUDEPPATH)\vbridge.lib \ $(_COMMONOAKROOT)\lib\$(_CPUDEPPATH)\kitl.lib \ $(_COMMONOAKROOT)\lib\$(_CPUINDPATH)\fulllibc.lib
|
Porting the Drivers |
All PXA255 drivers can be copied from \WINCE500\PUBLIC\COMMON\OAK\CSP\ARM\INTEL\PXA25X\ folder to local platform. |
Conclusion |
KITL is one the important block in the BSP for doing any sort of
debugging. Most of the handheld device may not have Ethernet port on
the board; in that case KITL can be implemented over either USB or
Serial Port.
But there is no PDD level serial KITL driver for the Mainstone BSP. But this can be easily ported from X86 CSP.
Porting 6.0 to any cards and any questions on this article, please write to with the subject Porting Windows CE 5.0. |