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);
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