Code examples for MRAM use with K60?

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Code examples for MRAM use with K60?

Jump to solution
2,064 Views
evgenik
Contributor IV

I bought TWR-MEM module. Are DVD contain code examples for MRAM use with K60? If No, where I can get code examples?

Labels (1)
1 Solution
1,265 Views
Carlos_Musich
NXP Employee
NXP Employee

Hi Evgeni,

it depends on what you want to do with Flexbus if you need to edit linker file or not.

- If you want to execute code from external MRAM or you need to reference specific data variables then you need to edit linker file.

- If you want just to save raw data it is not necessary to edit linker file.

You may find useful the following documents.

Relocating Code and Data Using the CW GCC Linker File for Kinetis

Relocating Code and Data Using the KDS GCC Linker File for Kinetis

Regarding the pinout. Please let me know where you find the different configurations. I did not get this part.


Best regards,
Carlos

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

View solution in original post

0 Kudos
12 Replies
1,266 Views
Carlos_Musich
NXP Employee
NXP Employee

Hello Evgeni,

please take a look on the Flexbus examples I attached to this post FlexBus in 16 bit mode and 8 bit access

They are usingK60 and K70 with CW and KDS. Some of the examples use TWR.MEM. They have also a document explaining the examples.

Regards,

Carlos

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

1,266 Views
evgenik
Contributor IV

Hi Carlos.

Thanks for your response.

In FlexBus code examples I can view that MEM FlexBus use is very simple. But from this view I have the next question:

Up to this time I used with Tower K60ND512 and K60FN MCUs. Are I need to use K60FX MCU for MEM FlexBus? If 'YES', how can I update MCU type into already worked project from ND or FN to FX type? There are any reference for change MCU type (from K40 to K60 for example) for Kinetis MCUs?

Are I need to change/update linker file?

Thanks.

Evgeni.

0 Kudos
1,266 Views
Carlos_Musich
NXP Employee
NXP Employee

Hi Evgeni,

regarding to the usage of of K60FN and K60FX. For this specific case you can use ony of them. K60FX features flex memory and K60FN does not, but this is a feature completely apart and it has no relation on using TWR-MEM with Flexbus.

Regarding to the porting form K40 to K60, I strongly recommend to create a brand new project for K60 and copy/add all your source files. This is the cleanest way to port a project and the way the experts recommend us to do it.

You can take this specific Flexbus configuration from K40 to K60 and it should work.


Best regards,

Carlos

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

1,266 Views
evgenik
Contributor IV

Hi Carlos.

Thanks for your answer.

1) Are I need to change/update K60 linker file for MRAM operations or enough only HW port and GPIO initialisation?

2) I see different pinout configuration in your link example (AN4393.pdf) and datasheet "Using FlexBus Interface for Kinetis Microcontrollers" (that described later). What condition for select one from them or use as described in "Using FlexBus Interface ..."?

"Using FlexBus Interface for Kinetis Microcontrollers" example:

// HW initialisation

// Enable the clock to the FlexBus

SIM_SCGC7 |= SIM_SCGC7_FLEXBUS_MASK; 

// FlexBus Clock not divided  
SIM_CLKDIV1 |= SIM_CLKDIV1_OUTDIV3(0x0);

// Set the GPIO ports clocks
SIM_SCGC5 = SIM_SCGC5_PORTA_MASK | SIM_SCGC5_PORTB_MASK | SIM_SCGC5_PORTC_MASK |
SIM_SCGC5_PORTD_MASK | SIM_SCGC5_PORTE_MASK;
PORTB_PCR11 = PORT_PCR_MUX(5); // fb_ad[18]
PORTB_PCR16 = PORT_PCR_MUX(5); // fb_ad[17]
PORTB_PCR17 = PORT_PCR_MUX(5); // fb_ad[16]
PORTB_PCR18 = PORT_PCR_MUX(5); // fb_ad[15]
PORTC_PCR0  = PORT_PCR_MUX(5); // fb_ad[14]

PORTC_PCR1  = PORT_PCR_MUX(5); // fb_ad[13]
PORTC_PCR2  = PORT_PCR_MUX(5); // fb_ad[12]
PORTC_PCR4  = PORT_PCR_MUX(5); // fb_ad[11]
PORTC_PCR5  = PORT_PCR_MUX(5); // fb_ad[10]
PORTC_PCR6  = PORT_PCR_MUX(5); // fb_ad[9]
PORTC_PCR7  = PORT_PCR_MUX(5); // fb_ad[8]
PORTC_PCR8  = PORT_PCR_MUX(5); // fb_ad[7]
PORTC_PCR9  = PORT_PCR_MUX(5); // fb_ad[6]
PORTC_PCR10 = PORT_PCR_MUX(5); // fb_ad[5]
PORTD_PCR2  = PORT_PCR_MUX(5); // fb_ad[4]
PORTD_PCR3  = PORT_PCR_MUX(5); // fb_ad[3]
PORTD_PCR4  = PORT_PCR_MUX(5); // fb_ad[2]
PORTD_PCR5  = PORT_PCR_MUX(5); // fb_ad[1]
PORTD_PCR6  = PORT_PCR_MUX(5); // fb_ad[0]
PORTB_PCR20 = PORT_PCR_MUX(5); // fb_ad[31] used as d[7]
PORTB_PCR21 = PORT_PCR_MUX(5); // fb_ad[30] used as d[6]
PORTB_PCR22 = PORT_PCR_MUX(5); // fb_ad[29] used as d[5]
PORTB_PCR23 = PORT_PCR_MUX(5); // fb_ad[28] used as d[4]
PORTC_PCR12 = PORT_PCR_MUX(5); // fb_ad[27] used as d[3]
PORTC_PCR13 = PORT_PCR_MUX(5); // fb_ad[26] used as d[2]
PORTC_PCR14 = PORT_PCR_MUX(5); // fb_ad[25] used as d[1]
PORTC_PCR15 = PORT_PCR_MUX(5); // fb_ad[24] used as d[0]
PORTB_PCR19 = PORT_PCR_MUX(5); // fb_oe_b
PORTC_PCR11 = PORT_PCR_MUX(5); // fb_rw_b
PORTD_PCR1  = PORT_PCR_MUX(5); // fb_cs0_b
PORTD_PCR0  = PORT_PCR_MUX(5); // fb_ale

#define MRAM_START_ADDRESS(*(volatile unsigned char*)(0x60000000))
FB_CSAR0 = (unsigned int)&MRAM_START_ADDRESS; //Set Base address

FB_CSCR0 = FB_CSCR_PS(1)       // 8-bit port
         | FB_CSCR_AA_MASK     // auto-acknowledge
         | FB_CSCR_WS(0x2)     // 2 wait states

FB_CSMR0 = FB_CSMR_BAM(0x7)    // Set base address mask for 512K address space
         | FB_CSMR_V_MASK;     // Enable cs valid signal

For read and write test:

uint8 wdata8 = 0x5A;           // data to write to mram
uint8 rdata8;                  // variable to read mram
for(n=0x00000;n<0x000F;n++)    // address offset
{
    *(vuint8*)(&MRAM_START_ADDRESS + n) = wdata8;
    rdata8 = 0x00;             // clear data variable
    rdata8 = (*(vuint8*)(&MRAM_START_ADDRESS + n));
}

Thanks.

Evgeni

0 Kudos
1,266 Views
Carlos_Musich
NXP Employee
NXP Employee

Hi Evgeni,

it depends on what you want to do with Flexbus if you need to edit linker file or not.

- If you want to execute code from external MRAM or you need to reference specific data variables then you need to edit linker file.

- If you want just to save raw data it is not necessary to edit linker file.

You may find useful the following documents.

Relocating Code and Data Using the CW GCC Linker File for Kinetis

Relocating Code and Data Using the KDS GCC Linker File for Kinetis

Regarding the pinout. Please let me know where you find the different configurations. I did not get this part.


Best regards,
Carlos

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos
1,266 Views
hardikdave
Contributor II

Hello I am trying to use MRAM module of towerk60f120m integrated on flexbus as extended RAM

what changes are required in linker file to use MRAM as extension of internal RAM(i.e. 128K).? compiler should able to store variable in MRAM automatically if internal SRAM goes out of memory

Best regards

Hardik Dave

0 Kudos
1,266 Views
Carlos_Musich
NXP Employee
NXP Employee

Hi Hardik,

the compiler is not the one who place variables in memory, it is the linker. Besides, the linker is used for many different processors with different memory sizes, and it is possible to have in your hardware any external memory and the linker is not aware of that. This is why it is used the linker file, here you can set the memory configurations that the linker must consider.

Regards,

Carlos

1,266 Views
bobpaddock
Senior Contributor III

There is no 'automatic' magic to do this.  'section' directives can be added to the linker script and things like large arrays could be placed in such sections leaving RAM for the more ordinary stuff, or everything gets moved to MRAM.  Compiler places variables in data or bss sections normally.

I designed MRAM out of my system when I found a Refrigerator Strength Magnet, used by a near by reed switch,would damage the MRAM.  It did not just change bits, it destroyed some underlying bias mechanism destroying the device, in the failure report I got back from Everspin. :-(  Pay attention to the Gauss ratings and distance now in the data sheets.

1,266 Views
hardikdave
Contributor II

Hello,

Thanks for your reply.

As you have suggested I am trying to locate all my variables to external MRAM on tower kit k60F120M module. I have changed linker file accordingly but I am getting hardfault while mqx init function execution.

can yo please look at attached linker file am I missing something? what else changes are required in mqx project to work with MRAM

Linker File

/****************************************************************************************************************************************************/

ENTRY(__boot)

/*

using both, gnulib & ewl symbols

_cfm - to keep vectors.c variables

__init_hardware - must be used from bsp.a, not from librt.a

*/

EXTERN(_cfm __init_hardware)

MEMORY

{

    vectorrom   (RX): ORIGIN = 0x00000000, LENGTH = 0x00000400

    cfmprotrom  (R): ORIGIN = 0x00000400, LENGTH = 0x00000020

    rom         (RX): ORIGIN = 0x00000420, LENGTH = 0x000FFBE0  /* Code + Const data */

    ram         (RWX): ORIGIN = 0x60000000, LENGTH = 0x00080000  /* DDR2 - RW data */

    sram        (RWX): ORIGIN = 0x1FFF0000, LENGTH = 0x00020000  /* SRAM - RW data */

    /* kernel space starts after RAM variables (Location of MQX Kernel data + MQX heap) */

    end_of_kd   (RW): ORIGIN = 0x6007FFF0, LENGTH = 0x00000000

    /* Boot stack reused by MQX Kernel data */

    bstack      (RW): ORIGIN = 0x2000FA00, LENGTH = 0x00000200  /* Boot stack */

    end_bstack  (RW): ORIGIN = 0x2000FC00, LENGTH = 0x00000000  /* Boot stack end address requires 4B alignment */

}

SECTIONS

{

    __INTERNAL_SRAM_BASE  = 0x1FFF0000;

    __INTERNAL_SRAM_SIZE  = 0x00020000;

    __INTERNAL_FLASH_BASE = 0x00000000;

    __INTERNAL_FLASH_SIZE = 0x00100000;

    __INTERNAL_FLEXNVM_BASE = 0;

    __INTERNAL_FLEXNVM_SIZE = 0;

    __UNCACHED_DATA_END      = 0x2000FFF0;

    __EXTERNAL_MRAM_BASE  = 0x60000000;

    __EXTERNAL_MRAM_SIZE  = 0x00080000;

    __EXTERNAL_MRAM_ROM_BASE = 0x60000000;

    __EXTERNAL_MRAM_ROM_SIZE = 0x00000000;

    __EXTERNAL_MRAM_RAM_BASE = 0x60000000;

    __EXTERNAL_MRAM_RAM_SIZE = 0x00080000;

    __EXTERNAL_DDR2_RAM_BASE = 0x00000000;

    __EXTERNAL_DDR2_RAM_SIZE = 0x00000000;

    __EXTERNAL_LCD_BASE = 0xA0000000;

    __EXTERNAL_LCD_SIZE = 0x1FFFF;

    __EXTERNAL_LCD_DC_BASE = 0xA0010000;

    /* MQX link time configurations */

    __DEFAULT_PROCESSOR_NUMBER = 1;

    __DEFAULT_INTERRUPT_STACK_SIZE = 1024;

    __KERNEL_DATA_VERIFY_ENABLE = 0;    /* Test SDRAM read/write */

    /* Flashx configurations */

    __FLASHX_SECT_SIZE = 0x1000;

    .vectors :

    {

        __vector_table = .;

        __VECTOR_TABLE_ROM_START = __vector_table;

        KEEP(*(.vectors_rom))

        . = ALIGN (0x4);

    } > vectorrom

    .cfmprotect :

    {

        KEEP(*(.cfmconfig))

        . = ALIGN (0x4);

    } > cfmprotrom

    .text :

    {

        *(KERNEL)

        *(S_BOOT)

        *(IPSUM)

        *(.text*)

        *(.eh_frame)

        KEEP (*(.init))

        KEEP (*(.fini))

        . = ALIGN(0x4);

        *(.rodata*)

        . = ALIGN(0x4);

        *(.rdata*)

        . = ALIGN(0x4);

        *(.exception)

        . = ALIGN(0x4);

        __exception_table_start__ = .;

        __exception_table_end__ = .;

        __sinit__ = .;

    } > rom

    .ARM.extab   : { *(.ARM.extab* .gnu.linkonce.armextab.*) } > rom

    .ARM : {

        __exidx_start = .;

        *(.ARM.exidx*)

        __exidx_end = .;

    } > rom

    .ctors :

    {

        __CTOR_LIST__ = .;

        /* gcc uses crtbegin.o to find the start of

        the constructors, so we make sure it is

        first.  Because this is a wildcard, it

        doesn't matter if the user does not

        actually link against crtbegin.o; the

        linker won't look for a file to match a

        wildcard.  The wildcard also means that it

        doesn't matter which directory crtbegin.o

        is in.  */

        KEEP (*crtbegin.o(.ctors))

        /* We don't want to include the .ctor section from

        from the crtend.o file until after the sorted ctors.

        The .ctor section from the crtend file contains the

        end of ctors marker and it must be last */

        KEEP (*(EXCLUDE_FILE (*crtend.o ) .ctors))

        KEEP (*(SORT(.ctors.*)))

        KEEP (*(.ctors))

        __CTOR_END__ = .;

    } > rom

    .dtors :

    {

        __DTOR_LIST__ = .;

        KEEP (*crtbegin.o(.dtors))

        KEEP (*(EXCLUDE_FILE (*crtend.o ) .dtors))

        KEEP (*(SORT(.dtors.*)))

        KEEP (*(.dtors))

        __DTOR_END__ = .;

    } > rom

    .preinit_array :

    {

        PROVIDE_HIDDEN (__preinit_array_start = .);

        KEEP (*(.preinit_array*))

        PROVIDE_HIDDEN (__preinit_array_end = .);

    } > rom

    .init_array :

    {

        PROVIDE_HIDDEN (__init_array_start = .);

        KEEP (*(SORT(.init_array.*)))

        KEEP (*(.init_array*))

        PROVIDE_HIDDEN (__init_array_end = .);

    } > rom

    .fini_array :

    {

        PROVIDE_HIDDEN (__fini_array_start = .);

        KEEP (*(SORT(.fini_array.*)))

        KEEP (*(.fini_array*))

        PROVIDE_HIDDEN (__fini_array_end = .);

    } > rom

    .data :

    {

        . = ALIGN(128);

        /* create _sdata symbol which keep

        relocation(execution) address of data start */

        _sdata = .;

        __VECTOR_TABLE_RAM_START = .;

        KEEP(*(.vectors_ram))

        __START_DATA = .;

        *(.data*)

        __END_DATA = .;

        . = ALIGN(0x4);

        __START_SDATA = .;

        *(.sdata*)

        __END_SDATA = .;

        . = ALIGN(0x4);

        __SDA_BASE  = .;

        __SDA_BASE_ = __SDA_BASE;

        . = ALIGN(0x4);

        /* create _edata symbol which keep

        relocation(execution) address of data end */

        _edata = .;

    } > ram AT> rom

    /* fill "__S_romp" table with memory region(s) to perform "rom to ram copy" */

    .romp :

    {

        __S_romp = .;

        LONG(LOADADDR(.data)); /* source (rom) address */

        LONG(_sdata); /* target (ram) address */

        LONG(_edata - _sdata); /* size */

        /* null terminated */

        LONG(0);

        LONG(0);

        LONG(0);

    } > rom

    .rom_end_data :

    {

        _rom_data_end = .;

    } > rom

    .bss :

    {

       . = ALIGN(0x10);

        __START_SBSS = .;

        *(.sbss*)

        *(SCOMMON)

        __END_SBSS = .;

        __START_BSS = .;

        __bss_start__ = __START_BSS;

        *(.bss*)

        *(COMMON)

        __END_BSS = .;

        __bss_end__ = __END_BSS;

        . = ALIGN(0x10);

    } > ram

    /* move "location counter" to next relocated address */

    . = ALIGN(0x10);

   .kernel_data :

    {

        __KERNEL_DATA_START = ALIGN(0x10);

    }

    .end_of_kernel_data :

    {

        __KERNEL_DATA_END = .;

        __KERNEL_AREA_END = .;

    } > end_of_kd

    .boot_stack :

    {

        _stack_end = .;

    } > bstack

    .end_of_boot_stack :

    {

        _stack_addr  = .;

        _estack = _stack_addr;

        __SP_INIT = _stack_addr;

        __BOOT_STACK_ADDRESS = .;

    } > end_bstack

    .sram_data :

    {        

        /* create _sdata symbol which keep

        relocation(execution) address of data start */

        . = ALIGN(512);

        __BDT_BASE = .;

        *(.usb_bdt)

        __BDT_END = .;

        __SRAM_POOL = .;

        __UNCACHED_DATA_START = .;       

    } > sram

    /* flashx working area spans across the whole rest of Flash memory */

    _flashx_start = _rom_data_end;

    __FLASHX_START_ADDR = ((_flashx_start + __FLASHX_SECT_SIZE - 1) / __FLASHX_SECT_SIZE) * __FLASHX_SECT_SIZE;

    __FLASHX_END_ADDR = __INTERNAL_FLASH_BASE + __INTERNAL_FLASH_SIZE;

}

/****************************************************************************************************************************************************/

Best Regards

Hardik

0 Kudos
1,266 Views
Carlos_Musich
NXP Employee
NXP Employee

On which line of initialization are you having the fault. Most linkely you are attempting to access MRAM before configuring Flexbus.

1,266 Views
hardikdave
Contributor II

Dear Carlos,

In our custom application we have requirement to add more RAM which has K60 controller.

I am currently evaluating MRAM option with the help of Tower kit K60F120M with MRAM module

1. flexbus is initialised in init_hw.c as available in mqx 4.2 (no changes)

2. linker is changed which is attached as above post

3. in mqx.c file at time of mqx_init system gets restarted (external mram is not accessible from mqx.c file).

Note:

1. with the default linker file we can able to access mram from TASK just like EEPROM

2. with attached linker file variables pointing to external mram is not accessible from mqx_init function due to which it restarts

3. it seems flexbus comes into running mode at time of task startup only.

Thanks and regards

Hardik Dave

0 Kudos
1,266 Views
evgenik
Contributor IV

Thanks for your help.

0 Kudos