This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

External Parallel SRAM EBI Interface in Cortex-M0

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.