Hello
We used Nuvoton Nu-Tiny Evaluation Board M051 V 2.0 (having on-board Nuvoton M0516LBN controller 'Cortex-M0' with 12 MHz external crystal) in our 8052-based project hardware. We interfaced 32K Battery-backed parallel SRAM (Cypress Make CY62256HLL-70PXC).
For accessing this parallel SRAM, we used the ARM EBI interface (8-bit) and matched the data lines, address lines, RD/, WR/, CS/, ALE as per the EBI requirements for Cortex-M0 Core.
For multiplexed address and data bus, we interfaced the latching device 74HC373 and connected ALE to its OE.
LEDs are used in the project, which are used as status indicators. They are directly interfaced to GPIOs.
Keil Project Settings:
Selected Nuvoton M0516LBN Controller; Set off-chip SRAM (IRAM1) at address 0x60000000; Used Scatter Loading in Keil Linker options; Checked 'Use Memory Layout from Target Dialog' in Linker options; As per the 'startup_M051Series.s' file, control jumps into SystemInit() before main() at startup.
The initialization routines are in this SystemInit() function routine.
Project code flow:
--> Unlock Protected Registers;
--> Enable External 12 MHz crystal and wait for clock stable;
--> GPIO Initializations: Port 0 as Quasi-Bidirectional (AD0 ~ AD7); Port 2 as Quasi-Bidirectional (A8 ~ A15); Remaining used port pins as per I/O requirement;
--> EBI Initializations:
#define M32(adr) (*((volatile unsigned long *) (adr))) #define EBI_MCLKDIV_4 0x2UL /* EBI output clock(MCLK) is HCLK/4 */ #define VAL 3 void DrvEBI_SetBusTiming(void) { EBI->EBICON.ExttALE = VAL; EBI->EBICON.MCLKDIV = EBI_MCLKDIV_4; EBI->EXTIME.ExttACC = VAL; EBI->EXTIME.ExttAHD = VAL; EBI->EXTIME.ExtIW2X = VAL; EBI->EXTIME.ExtIR2R = VAL; } void ebi_init(void) { /* Multiple Function Port 0 Control Register */ M32(&SYS->P0_MFP) |= 0x000000FF; M32(&SYS->P0_MFP) &= 0xFF0000FF; /* Multiple Function Port 1 Control Register */ M32(&SYS->P1_MFP) &= 0xFF000000; /* Multiple Function Port 2 Control Register */ M32(&SYS->P2_MFP) |= 0x000000FF; M32(&SYS->P2_MFP) &= 0xFF0000FF; /* Multiple Function Port 3 Control Register */ M32(&SYS->P3_MFP) &= 0xFF000000; M32(&SYS->P3_MFP) |= 0x000038C3;/* Enable nRD/nWR for EBI, MCLK for EBI */ //Multiple Function Port 4 Control Register M32(&SYS->P4_MFP) &= 0xFF000000; M32(&SYS->P4_MFP) |= 0x00000030; /* Enable ALE/nCS for EBI */ DrvEBI_SetBusTiming(); /* EBI function enable */ EBI->EBICON.ExtBW16 = 0; /* EBI data width is 8-bit */ /*EBI Controller Clock Enable Control */ SYSCLK->AHBCLK.EBI_EN = 1; /* Enable the EBI engine clock */ /* This bit is the functional enable bit for EBI */ EBI->EBICON.ExtEN = 1; /* EBI function is enabled */ }
--> Lock Protected Registers;
--> CY62256 SRAM Testing Routine (EBI_SRAM BSP code) Path: "C:\Nuvoton\BSP Library\M051_Series_BSP_CMSIS_Rev3.00.002\ SampleCode\RegBased\EBI_SRAM\KEIL\EBI_SRAM.uvproj"
RAM Test:
const uint32_t g_au32DataArrary[4] = {0x36363636, 0xFFFFFFFF, 0x5A5A5A5A, 0x70707070};/* RAM check pass for these values */ The SRAM testing code is modified as per 8-bit EBI; The 32-bit values in g_au32DataArrary[] are checked; LEDs are used to indicate the RAM test status; RAM test is OK with the array values provided in the BSP code; The SRAM test fails for some specific 32-bit values in combination with 0x00,0x01,0x02,0x03, 0x04,0x05,0x06,0x08, 0x09; So, patterns like 0x01010101, 0x50505050, 0x08080808, 0x00000000, etc fails.
--> main() starts after successful RAM Test. All headers are included in file containing main().
RAM test is just a basic RAM cross-checking operation. After the system comes into running mode with timely interrupts and other hardware-driven operations, some variables or flags stored in the external RAM fail in conditional checkings, as explained below:
unsigned char hook_state;/* = 0 at startup */ if(hook_state == 1)/* Inside the main() while{} superloop */ { hook_state = 0; //remaining code. } hook_state = 1; /* Inside the Timer ISR or any other function */
Eventhough the flag is set, the condition fails. So, non-logical changes made to the above code...
unsigned char hook_state;/* = 0x55 at startup */ if(hook_state == 0xAA)/* Inside the main() while{} superloop */ { hook_state = 0x55; //remaining code. } hook_state = 0xAA; /* Inside the Timer ISR or any other function */
Now, the condition is TRUE.
Any specific reason for above conditional failures?
Any suggestions for proper access to the external RAM when using Cortex Core.
It actually has nothing specifically to do with the Cortex core - it is all down to the particular vendor's EBI implementation.
So you need to carefully study the Manufacturer's documentation for the proper use of the specific EBI implementation in this particular Chip:
" href= "http://www.nuvoton.com/hq/products/microcontrollers/arm-cortex-m0-mcus/m051-base-series/?__locale=en"> www.nuvoton.com/.../
I believe some people think about "core" as similar to Intel's "Core", "CoreDuo", Core2Duo", ... and misses that companies buys parts of a processor and then glues on additional intellectual properties also bought from ARM or inhouse-developed or bought from other companies when they want to release Cortex-based chips.
Yes, a lot of people fail to understand ARM's business model and what, exactly, it is that they do & do not provide.
Witness frequent references to "ARM microcontroller" and "I want to learn ARM", etc...
Diagram (and text) here show what constitutes the Cortex-M0 Core:
www.arm.com/.../cortex-m0.php