SAM9G20 NOR-Flash boot

Discussion around AT91RM9200 and SAM9 Series Products.

Moderator: nferre

rmueller
Posts: 4
Joined: Thu Nov 12, 2020 11:19 am

SAM9G20 NOR-Flash boot

Sat Nov 14, 2020 3:30 pm

Hi!

We are using a product which embedds a SAM9G20 chip and uses an external NOR-Flash chip connected via EBI NCS0 interface.

We are trying to implement a bootloader on the chip. However we have issues to get the DBGU peripheral working.

Some additional information:

Toolchain:
arm-none-eabi-gcc (xPack GNU Arm Embedded GCC, 64-bit) 9.2.1 20191025

Our project is based on the AT91 Bootsstrap project (not the one available on github, an older one). The code in the NOR-Flash appears to be executed, by inspection of the board LEDs. However, when using the DBGU unit to produce DEBUG output, the code appears to be stuck in the following function which contains permanent loops:

Code: Select all

void DBGU_PutChar(unsigned char c)
{
	/*
	 * US_TXEMPTY is not a blocking register. The UART shift register will shift
	 * the contents out regardless. No need to add watchdog kick. However, might
	 * be good idea to add a normal "for loop" timeout counter just to be safe.
	 *
	 * int timeout;
	 * for( timeout = 1000000; timeout != 0; timeout-- );
	 */

    // Wait for the transmitter to be ready
    while ((AT91C_BASE_DBGU->DBGU_CSR & AT91C_US_TXEMPTY) == 0) {
//    	WDT_kickEveryNcalls(40000);
    }

    // Send character
    AT91C_BASE_DBGU->DBGU_THR = c;

    // Wait for the transfer to complete
    while ((AT91C_BASE_DBGU->DBGU_CSR & AT91C_US_TXEMPTY) == 0) {
//    	WDT_kickEveryNcalls(40000);
    }
}

One thing I notices is that in the LowLevelInit function supplied by our product supplier is slightly changed:

Code: Select all

//------------------------------------------------------------------------------
//         Exported functions
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
/// Performs the low-level initialization of the chip. Initialisation depends
/// on where the application is executed:
/// - in sdram: it means that sdram has previously been initialized. No further
///             initialization is required.
/// - in sram:  PLL shall be initialized in LowLevelInit. Other initializations
///             can be done later by the application.
/// - in norflash: LowLevelInit can't be executed in norflash because SMC
///             settings can't be changed while executing in external flash.
///             LowLevelInit shall be executed in internal sram. It initializes
///             PLL and SMC.
/// This function also reset the AIC and disable RTT and PIT interrupts
//------------------------------------------------------------------------------
// The following four lines were added to  put the NOR-Flash function call into SRAM
#ifdef norflash
void LowLevelInit(void) __attribute__ ((section(".sramfunc"),optimize("O0")));
#else
void LowLevelInit(void) __attribute__ ((optimize("O0")));
#endif
void LowLevelInit(void)
{
// This part here is same at bootsstrap
    ...
    

// This part is not in the AT91 bootsstrap project
#ifndef sdram
    BOARD_ConfigureSdram(BOARD_SDRAM_BUSWIDTH);
#endif
}

In the AT91 bootsstrap project, the SDRAM configuration takes place in the main function. I sitll think its odd that the DBGU peripheral dooes noot appear to work, considering that the configuration is really similar to the AT91 bootsstrap provided for NOR-Flash boot.
Currently, the DBGU is configured to 115200 baud with

Code: Select all

TRACE_CONFIGURE(DBGU_STANDARD, 115200, BOARD_MCK);
When compiling and linking the application for SRAM (we also need to omitt FreeRTOS used in the NOR-Flash boootloader to get under 16kB), the DBGU unit works without issues. Same applies for an SDRAM image.
Is it possible that a special clock configuratioon is necessary for the NOR-Flash image? Right now, the clock is
provided by the PMC peripheral which is configured in the LowLevelInit function. The configuration parameters chosen appear to
be similar to the ones provided in the bootsstrap project.
Thanks a lot in advance!

Kind Regards
Robin
blue_z
Location: USA
Posts: 2131
Joined: Thu Apr 19, 2007 10:15 pm

Re: SAM9G20 NOR-Flash boot

Mon Nov 16, 2020 2:57 am

Your post is missing salient details.

rmueller wrote: We are using a product which embedds a SAM9G20 chip and uses an external NOR-Flash chip connected via EBI NCS0 interface.
How does this board use Boot Mode Select, BMS, and are you cognizant of the ramifications?

rmueller wrote: Our project is based on the AT91 Bootsstrap project (not the one available on github, an older one).
Specification by exclusion and/or vagueness are not acceptable.

rmueller wrote: Currently, the DBGU is configured to 115200 baud with

Code: Select all

TRACE_CONFIGURE(DBGU_STANDARD, 115200, BOARD_MCK);
What value is this to any reader when you are using an unspecified mystery boot program?
Have you investigated what this routine does and does not do?

Regards
rmueller
Posts: 4
Joined: Thu Nov 12, 2020 11:19 am

Re: SAM9G20 NOR-Flash boot

Mon Nov 16, 2020 10:50 am

Hi Blue,

Our board is the ISIS iOBC ( https://www.isispace.nl/product/on-board-computer/ .
The BMS is set to 0 to boot from the external NOR-Flash as specified on page 24 of the SAM9G20 datasheet.
I don't think it is possible to change this on the iOBC like we can on the AT91 with a Jumper.

Our AT91 library is based partly on sources provided by ISIS and on the softpack 1.5.
All of our software except proprietary libraries is public:
https://git.ksat-stuttgart.de/source/so ... m9g20/at91
https://git.ksat-stuttgart.de/source/so ... bootloader

The clock is configured in the LowLevelInit function( seen in https://git.ksat-stuttgart.de/source/so ... lowlevel.c )

I managed to stabilize the software by reordering some sections in the norflash linker script (at least it appears to run stable now).
This included mostly just keeping LowLevelInit und the memory initialization in the prerelocate section and
moving the rest of functions which shold be in SRAM to postrelocate as seen in
the linker skript https://git.ksat-stuttgart.de/source/so ... rflash.lds

The TRACE_CONFIGURE function was just taken over from the bootsstrap project and works without issues for SRAM
and SDRAM applications. It configures the DBGU pins and the DBGU peripheral as seen in
https://git.ksat-stuttgart.de/source/so ... ty/trace.h.

The DBGU appest to work now without issues now but I still have problems making external peripherals working.
However, I still need to look into that.

Kind Regards
Robin
blue_z
Location: USA
Posts: 2131
Joined: Thu Apr 19, 2007 10:15 pm

Re: SAM9G20 NOR-Flash boot

Tue Nov 17, 2020 4:56 am

rmueller wrote: The BMS is set to 0 to boot from the external NOR-Flash as specified on page 24 of the SAM9G20 datasheet.
Okay, and did you notice (and comprehend) the statement "The customer-programmed software must perform a complete configuration"?
Are you aware that your board, when it "boot[s] from the external NOR-Flash", is also not executing the built-in ROM code that (normally) initializes the SoC?
Of particular concern to you would be the fact that the ROM initialization includes Step #5, "Initialization of the DBGU serial port" (refer to Section 12, Boot Program).
In other words, if your code in NOR flash neglects to perform a full initialization of the DBGU device like the ROM code would, then you cannot expect that serial port to be functional.

rmueller wrote: Toolchain:
arm-none-eabi-gcc (xPack GNU Arm Embedded GCC, 64-bit) 9.2.1 20191025

Our project is based on the AT91 Bootsstrap project (not the one available on github, an older one).
rmueller wrote: Our AT91 library is based partly on sources provided by ISIS and on the softpack 1.5.
The boot programs that were available in the Softpacks (and/or Application Libraries) seem to be a different program from the original AT91Bootstrap, and are not "older".
The original AT91Bootstrap is copyrighted 2006 (I have a copy of v1.2 dated April 2006), supported only building with GNU gcc, and its updated versions are now available from GitHub.
The alternate boot programs in the Softpacks (confusingly) use the same program name, but were only available for a limited time, were copyrighted 2008, supported building with GNU, IAR and Keil toolchains, and apparently tried to be more than a "2nd level bootloader" for just AT91SAM9 boards. Softpacks released since 2011 seem to leave out this alternate boot program, e.g. the sam9g25_softpack_1.0_for_CodeSourcery_2010q1 zip (dated April 2011) does not have it.

Note that these alternate boot programs (including the variant you're using) reiterate in main.c information from the SoC datasheets regarding ROM code:
/// AT91 chips embed in ROM a program called "ROM code". It is started depending on BMS (Boot Mode Select)
/// pin state on reset.
...
/// -# The ROM startup code initializes the CPU and memory controller, performing
/// only minimal initialization of on-chip devices, such as the console serial port
/// to provide boot diagnostic messages. It also sets up the memory map for the
/// kernel to use in a format that is consistent across platforms, and then jumps

FWIW beware of using a toolchain that has not been proven to produce functional binaries.
Over the years there have been toolchains that produced boot programs that did not boot; for instance see https://www.at91.com/viewtopic.php?f=33 ... 102#p50096.

rmueller wrote: The clock is configured in the LowLevelInit function ...
FYI there is more than one clock involved in SoC initialization.
In fact the root of your problem is probably a peripheral clock.

rmueller wrote: The DBGU appest to work now without issues now but I still have problems making external peripherals working.
However, I still need to look into that.
You probably need to learn about peripheral clocks.

Regards
rmueller
Posts: 4
Joined: Thu Nov 12, 2020 11:19 am

Re: SAM9G20 NOR-Flash boot

Tue Nov 17, 2020 10:19 am

Hi blue,

I am aware that the ROM Boot program is not executed when executing from NOR-Flash. What I have deduced from the datasheet is that the DBGU is part of the System Controller Peripheral. Setting the Peripheral Clock Enable register for the System Controller bits (p.32 note) has not effect according to the datasheet and I am just assuming that the master clock configured in LowLevelInit (p.270 step 5 which specifies the programming sequence) is used. Also, the DBGU is now working for both the iOBC NOR-Flash bootloader and the AT91 NAND-Flash bootloader

I am really confused by the various versions of bootsstrap available. I was considering adapting the AT91Bootsstrap available on GitHub (Linux4SAM) for our purposes to test whether it fares better (it also contains the board), but of course my goal is to load our application directly instead of u-boot. The used AT91 libraries are also different to ours, but we still need the AT91 library supplied by ISIS because a precompiled library is using it. Also, there does not appear to be a configuration for NOR-Flash as seen in https://www.linux4sam.org/bin/view/Linu ... 1Bootstrap . If there is any other available publicly, I have not managed to find it yet.

I also need to retract the previous statement. It appears that the boot process on the iOBC AND the AT91SAM9G20-EK only works sometimes. On the AT91SAM9G20-EK, I copy the main application from the NAND-Flash to the SDRAM. The bootloader is very similar to the bootsstrap code from Softpack 1.5 to load a binary from NAND-Flash. The bootloader itself always runs without issues (this applies to the NOR-Flash bootloader and the NAND-Flash bootloader loaded by RomBOOT).

This process works sometimes, but I can't really determine when it will work and when it will not (appears to be a bit of a gamble). The weird thing is that the binary works without issues when being loaded directly into the SDRAM by either SAM-BA or by gdb with a SEGGER J-Link. This might also be related to the toolchain issue you already mentioned, so I will also try out another toolchain.

Is there any special steps necessary before I jump from the bootloader application to the main application?
Do I need to set some special registers, clear out memory or do anything else like clock configuration?
I currently put the ARM core into the supervisor mode and disable interrupts before jumping to the SDRAM with the following piece
of code:

Code: Select all

/* Jump to application and put the core into default power-on state */
	.globl jumpToSdramApplication
	.align 4
	.type jumpToSdramApplication, %function

jumpToSdramApplication:
	msr CPSR_c, #ARM_MODE_SVC | I_BIT | F_BIT
	ldr r0,=0x20000000
	mov pc,r0
What happens if it does not work? Something seems to go very wrong with the main application then. I set some LEDs in the startup startup assembler file to see whether any code gets executed and that was working, but at some point the application just appears to crash (for example when starting the FreeRTOS task scheduler, sometimes I manage to get out some DBGU output).

What really boggles my mind is that this is never an issue when flashing the SDRAM directly. Any help or hints on what might cause this are appreciated. Thanks a lot in advance!

Kind Regards
Robin
rmueller
Posts: 4
Joined: Thu Nov 12, 2020 11:19 am

Re: SAM9G20 NOR-Flash boot

Thu Nov 19, 2020 1:35 am

I propably found the issue.

I was using the sixth ARM vector to write the binary size (like it is used by the ROM Boot NAND-Flash) for the bootloader.
This is propably not a good idea. I still need to perform some tests to really confirm this was the issue but not messing
with the reserved vector appears to solve the mentioned issues for now.

I am just wondering why this is an issue because the vector is not used. But maybe I have overlooked something in the datasheet.
I just thought it would be a nice way way to put the binary size into the binary but apparently there are evil side effects when
doing that..

Kind Regards
Robin

Return to “SAM9 ARM9 MPU”

Who is online

Users browsing this forum: No registered users and 7 guests