EVM_3530的WinCE7 BSP包“BSP_WINCE_ARM_A8_02_00_00”默认的调试信息输出口为UART3,现在我们把这个输出口改为UART1。
一、修改C:\WINCE700\platform\EVM_OMAP3530\SRC\BSP_COMMON\BSPCFG\bspcfg.c
//------------------------------------------------------------------------------
// DEBUG UART
//------------------------------------------------------------------------------
// This constants are used to initialize serial debugger output UART.
// Serial debugger uses 115200-8-N-1
staticconst DEBUG_UART_CFG debugUartCfg={
OMAP_DEVICE_UART1, //OMAP_DEVICE_UART3-》OMAP_DEVICE_UART1
BSP_UART_LCR,
BSP_UART_DSIUDLL,
BSP_UART_DSIUDLH
} ;
二、在OSdesign中不使用UART1
三、修改C:\WINCE700\platform\EVM_OMAP3530\SRC\BOOTLOADER\XLDR\platform.c中的引脚配置PinMuxSetup(),使能UART1的引脚功能
//------------------------------------------------------------------------------
//
// Function: PinMuxSetup
//
// Initializes pin/pad mux settings.
//
static VOID PinMuxSetup()
{
staticconst PAD_INFO initialPinMux[] = {
SDRC_PADS
GPMC_PADS
UART1_PADS //UART3_PADS->UART1_PADS
MMC1_PADS
I2C1_PADS
I2C2_PADS
I2C3_PADS
WKUP_PAD_ENTRY(SYS_32K, INPUT_ENABLED | PULL_RESISTOR_DISABLED | MUXMODE(0))
GPIO_PADS
END_OF_PAD_ARRAY
};
ConfigurePadArray(initialPinMux);
}
四、修改C:\WINCE700\platform\EVM_OMAP3530\SRC\OAL\OALLIB\init.c,在OAL中使能UART PAD配置
//same thing for the UART3 (used for our OAL serial output
ConfigurePadArray(BSPGetDevicePadInfo(OMAP_DEVICE_UART1)); //OMAP_DEVICE_UART3-》OMAP_DEVICE_UART1
五、修改C:\WINCE700\platform\EVM_OMAP3530\SRC\BOOTLOADER\STUB\bsp_bootstubs.c,在EnableDeviceClocks() 中添加UART1支持
#ifdef BOOT_XLDR
//-----------------------------------------------------------------------------
BOOL
EnableDeviceClocks(
UINT devId,
BOOL bEnable
)
{
OMAP_CM_REGS* pCmRegs;
//-----------------------------------------------------------------------------
BOOL
EnableDeviceClocks(
UINT devId,
BOOL bEnable
)
{
OMAP_CM_REGS* pCmRegs;
switch (devId)
{
{
case OMAP_DEVICE_MMC1:
pCmRegs = OALPAtoUA(OMAP_PRCM_CORE_CM_REGS_PA);
pCmRegs = OALPAtoUA(OMAP_PRCM_CORE_CM_REGS_PA);
if (bEnable)
{
SETREG32(&pCmRegs->CM_FCLKEN1_xxx, CM_CLKEN_MMC1);
SETREG32(&pCmRegs->CM_ICLKEN1_xxx, CM_CLKEN_MMC1);
{
SETREG32(&pCmRegs->CM_FCLKEN1_xxx, CM_CLKEN_MMC1);
SETREG32(&pCmRegs->CM_ICLKEN1_xxx, CM_CLKEN_MMC1);
while (INREG32(&pCmRegs->CM_IDLEST1_xxx) & CM_IDLEST_ST_MMC1);
}
}
else
{
CLRREG32(&pCmRegs->CM_FCLKEN1_xxx, CM_CLKEN_MMC1);
CLRREG32(&pCmRegs->CM_ICLKEN1_xxx, CM_CLKEN_MMC1);
}
break;
case OMAP_DEVICE_I2C1:
pCmRegs = OALPAtoUA(OMAP_PRCM_CORE_CM_REGS_PA);
pCmRegs = OALPAtoUA(OMAP_PRCM_CORE_CM_REGS_PA);
if (bEnable)
{
SETREG32(&pCmRegs->CM_FCLKEN1_xxx, CM_CLKEN_I2C1);
SETREG32(&pCmRegs->CM_ICLKEN1_xxx, CM_CLKEN_I2C1);
{
SETREG32(&pCmRegs->CM_FCLKEN1_xxx, CM_CLKEN_I2C1);
SETREG32(&pCmRegs->CM_ICLKEN1_xxx, CM_CLKEN_I2C1);
while (INREG32(&pCmRegs->CM_IDLEST1_xxx) & CM_IDLEST_ST_I2C1);
}
}
else
{
CLRREG32(&pCmRegs->CM_FCLKEN1_xxx, CM_CLKEN_I2C1);
CLRREG32(&pCmRegs->CM_ICLKEN1_xxx, CM_CLKEN_I2C1);
}
break;
case OMAP_DEVICE_GPIO1:
pCmRegs = OALPAtoUA(OMAP_PRCM_WKUP_CM_REGS_PA);
pCmRegs = OALPAtoUA(OMAP_PRCM_WKUP_CM_REGS_PA);
if (bEnable)
{
SETREG32(&pCmRegs->CM_FCLKEN_xxx, CM_CLKEN_GPIO1);
SETREG32(&pCmRegs->CM_ICLKEN_xxx, CM_CLKEN_GPIO1);
{
SETREG32(&pCmRegs->CM_FCLKEN_xxx, CM_CLKEN_GPIO1);
SETREG32(&pCmRegs->CM_ICLKEN_xxx, CM_CLKEN_GPIO1);
while (INREG32(&pCmRegs->CM_IDLEST1_xxx) & CM_IDLEST_ST_GPIO1);
}
}
else
{
CLRREG32(&pCmRegs->CM_FCLKEN_xxx, CM_CLKEN_GPIO1);
CLRREG32(&pCmRegs->CM_ICLKEN_xxx, CM_CLKEN_GPIO1);
}
break;
case OMAP_DEVICE_UART1:
pCmRegs = OALPAtoUA(OMAP_PRCM_CORE_CM_REGS_PA);
if (bEnable)
{
SETREG32(&pCmRegs->CM_FCLKEN1_xxx, CM_CLKEN_UART1);
SETREG32(&pCmRegs->CM_ICLKEN1_xxx, CM_CLKEN_UART1);
while (INREG32(&pCmRegs->CM_IDLEST1_xxx) & CM_IDLEST_ST_UART1);
}
else
{
CLRREG32(&pCmRegs->CM_FCLKEN1_xxx, CM_CLKEN_UART1);
CLRREG32(&pCmRegs->CM_ICLKEN1_xxx, CM_CLKEN_UART1);
}
break;
pCmRegs = OALPAtoUA(OMAP_PRCM_CORE_CM_REGS_PA);
if (bEnable)
{
SETREG32(&pCmRegs->CM_FCLKEN1_xxx, CM_CLKEN_UART1);
SETREG32(&pCmRegs->CM_ICLKEN1_xxx, CM_CLKEN_UART1);
while (INREG32(&pCmRegs->CM_IDLEST1_xxx) & CM_IDLEST_ST_UART1);
}
else
{
CLRREG32(&pCmRegs->CM_FCLKEN1_xxx, CM_CLKEN_UART1);
CLRREG32(&pCmRegs->CM_ICLKEN1_xxx, CM_CLKEN_UART1);
}
break;
}
}
return TRUE;
}
#else
}
#else
六、使能UART1调试串口时钟
a. Enable clock in Eboot before launch the Kernel.(OEMLaunch() in main.c)
EnableDeviceClocks(BSPGetDebugUARTConfig()->dev, TRUE);
JumpTo(OALVAtoPA((UCHAR*)launch));
If debug serial is not used (Retail message is disabled from Eboot menu), then the clock for debug serial port will be disabled in Init.c.
b. Update function EnableDebugSerialClock() to support UART1. Code changes are as follows:
Changes in OAL\OALLIB\init.c
void EnableDebugSerialClock(UINT uart_id) { #define OMAP_PRCM_PER_CM_REGS_PA 0x48005000 OMAP_CM_REGS* pCmRegs; pCmRegs = (OMAP_CM_REGS*) (OMAP_PRCM_CORE_CM_REGS_PA); switch(uart_id) { case OMAP_DEVICE_UART1: SETREG32(&pCmRegs->CM_FCLKEN1_xxx, CM_CLKEN_UART1); SETREG32(&pCmRegs->CM_ICLKEN1_xxx, CM_CLKEN_UART1); while (INREG32(&pCmRegs->CM_IDLEST1_xxx) & CM_IDLEST_ST_UART1); break; case OMAP_DEVICE_UART2: SETREG32(&pCmRegs->CM_FCLKEN1_xxx, CM_CLKEN_UART2); SETREG32(&pCmRegs->CM_ICLKEN1_xxx, CM_CLKEN_UART2); while (INREG32(&pCmRegs->CM_IDLEST1_xxx) & CM_IDLEST_ST_UART2); break; case OMAP_DEVICE_UART3: pCmRegs = (OMAP_CM_REGS*) (OMAP_PRCM_PER_CM_REGS_PA); SETREG32(&pCmRegs->CM_FCLKEN_xxx, CM_CLKEN_UART3); SETREG32(&pCmRegs->CM_ICLKEN_xxx, CM_CLKEN_UART3); while (INREG32(&pCmRegs->CM_IDLEST1_xxx) & CM_IDLEST_ST_UART3); break; } }
Changes in OAL\OALLIB\startup.s
;================================================================================ ; ; File: startup.s ; INCLUDE kxarm.h INCLUDE bsp.inc IMPORT KernelStart IMPORT EnableDebugSerialClock IMPORT BSPGetDebugUARTConfig TEXTAREA ;------------------------------------------------------------------------------- ; ; Function: StartUp ; ; This function is entry point to Windows CE OS. ; ; LEAF_ENTRY StartUp ;--------------------------------------------------------------- ; Invalidate all caches ;--------------------------------------------------------------- ; Invalidate TLB and I cache mov r0, #0 ; setup up for MCR mcr p15, 0, r0, c8, c7, 0 ; invalidate TLB's mcr p15, 0, r0, c7, c5, 0 ; invalidate icache ; Flush D cache mrc p15, 1, r0, c0, c0, 1 ; read clidr ands r3, r0, #0x7000000 mov r3, r3, lsr #23 ; cache level value beq doneb mov r10, #0 ; start clean at cache level 0 loop1b add r2, r10, r10, lsr #1 ; work out 3x current cache level mov r1, r0, lsr r2 ; extract cache type bits from clidr and r1, r1, #7 ; mask of the bits for current cache only cmp r1, #2 ; see what cache we have at this level blt skipb ; skip if no cache, or just i-cache mcr p15, 2, r10, c0, c0, 0 ; select current cache level in cssr mov r1, #0 mcr p15, 0, r1, c7, c5, 4 ; prefetch flush to sync the change to the cachesize id reg mrc p15, 1, r1, c0, c0, 0 ; read the new csidr and r2, r1, #7 ; extract the length of the cache lines add r2, r2, #4 ; add 4 (line length offset) ldr r4, =0x3ff ands r4, r4, r1, lsr #3 ; r4 is maximum number on the way size clz r5, r4 ; r5 find bit position of way size increment ldr r7, =0x7fff ands r7, r7, r1, lsr #13 ; r7 extract max number of the index size loop2b mov r9, r4 ; r9 is working copy of max way size loop3b orr r11, r10, r9, lsl r5 ; factor way and cache number into r11 orr r11, r11, r7, lsl r2 ; factor index number into r11 mcr p15, 0, r11, c7, c14, 2 ; clean and invalidate by set/way subs r9, r9, #1 ; decrement the way bge loop3b subs r7, r7, #1 ; decrement the index bge loop2b skipb add r10, r10, #2 ; increment cache number cmp r3, r10 bgt loop1b doneb mov r10, #0 ; switch back to cache level 0 mcr p15, 2, r10, c0, c0, 0 ; select current cache level in cssr ;-------------------------------------------------------------- ; Enable clock for debug serial port ;-------------------------------------------------------------- bl BSPGetDebugUARTConfig ldr r0, [r0] bl EnableDebugSerialClock ;--------------------------------------------------------------- ; Jump to WinCE KernelStart ;---------------------------------------------------------------