Hello.
I apologize for the long message, but it's a difficult problem :(
I'm running a custom OMAP-L138 board that's in production.
They run flawlessly after hitting the reset button.
The boards won't run from power on without a strategicly placed
delay of around 10 milliseconds.
They fail in the UBL after outputting a small (and variable number)
of characters to uart 0.
This problem was encountered last september and addressed by experimently
determining that a 10ms delay worked (on a small sample). Could not
determine the reason. Production needs arose, and I increased
the delay by x10 to 100ms and shipped.
In the next batch of boards, a small percentage failed to boot with
the 100ms delay and I set out to find the root cause.
We are running UBL from OMAP-L138_FlashAndBootUtils_2_31.tar.gz.
[Version 2.40 is currently published, but I diffed the relevant
pieces and saw no applicable differences]
Here's the code flow:
device.c:DEVICE_init()
DEVICE_PSCInit() ;
status |= DEVICE_PLL0Init(0, 24, 0, 1, 0, 11, 5);
status |= DEVICE_PLL1Init(24, 1, 0, 1, 2);
REQUIRED 100ms delay
status |= DEVICE_ExternalMemInit(0x000000C4, 0x08174632,
0x3A4A2A21, 0x7C1FC722,
0x00000492, 0x00000000);
ubl.c:
DEVICE_UARTInit(DEVICE_UART_PERIPHNUM);
hUartInfo = UART_open(DEVICE_UART_PERIPHNUM, hDEVICE_UART_config);
DEBUG_printString("OMAP-L138 initialization passed!"
Without the delay, it dies after a few characters of the OMAP-L138
It seems to just quit executing at >>>>> in:
uart.c:UART_sendString()
do
{
write_led( /*led#=*/ 0, /*value=*/1) ; //##################
>>>>>>> status = (UART->LSR)&(0x20);
timerStatus = DEVICE_TIMER0Status();
write_led(0,0) ; // #######################################
}
while (!status && timerStatus);
DEVICE_TIMER0Status() is {return 1}. It stops with led#0 high.
I've made a variety of changes to try and fix it:
1. there were various delays marked FIXME in DEVICE_PLL<n>Init()
I calibrated the wait loops, squinted at specs, bumped the
waits to 5x required. No effect.
2. I squinted at uart.c:LOCAL_setupMode() and made changes to
conform to manual and common sense (not using receiver and
no ISR was set up for xmitter):
do NOT enable interrupts
set dmamode1 bit in FCR
enable transmitter only, change PWREMU_MGMT settings
No effect.
3. I looked at clock going into DMR and saw no changes at
time of interest. I've concluded (perhaps erroneously)
that processor memory is not falling out from under me. All
the code (including the required 100ms wait loop) is
running out of RAM. I compared the AIS signature memory
settings to what is used in DEVICE_ExternalMemInit() and
they appear to be the same.
So... I have a couple of specific questions:
1. How does processor behave if it trys to access a
UART register and UART is powered off?
2. With uart interrupts off, what would keep the
processor from getting past reading UART->LSR?
And in general, I'd appreciate any help/guidance/insight.
There are a variety of workarounds:
1. up the delay until it "works", but 5 enough.. 7 too many?
2. Make hardware change to issue a reset pulse
after poweron (how long after?)
but I'd rather get to the root cause.
I've attached the relevant code as a tar file: (omap-wont-boot-code.tar)
ubl.c
device.{c,h}
uart.c
thanks in advance
tom campbell