<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: Writing to eeprom with a hard-coded value. in LPC Microcontrollers</title>
    <link>https://community.nxp.com/t5/LPC-Microcontrollers/Writing-to-eeprom-with-a-hard-coded-value/m-p/1175445#M42747</link>
    <description>&lt;P&gt;&lt;SPAN&gt;You asked:&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;EM&gt;My question is why does the compiler use the &lt;U&gt;strb&lt;/U&gt; instruction 4 times instead of 1 &lt;U&gt;str&lt;/U&gt; instruction.&lt;/EM&gt;&lt;/P&gt;&lt;P&gt;Answer:&lt;/P&gt;&lt;P&gt;To write a 4 byte value in a single write, it MUST be 4-byte aligned, and the compiler must KNOW that it is guaranteed to be 4-byte aligned. You can do this by declaring a value as&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;int x __attribute__ ((aligned (4))) = 0;&lt;/PRE&gt;</description>
    <pubDate>Thu, 29 Oct 2020 17:14:56 GMT</pubDate>
    <dc:creator>converse</dc:creator>
    <dc:date>2020-10-29T17:14:56Z</dc:date>
    <item>
      <title>Writing to eeprom with a hard-coded value.</title>
      <link>https://community.nxp.com/t5/LPC-Microcontrollers/Writing-to-eeprom-with-a-hard-coded-value/m-p/1175421#M42746</link>
      <description>&lt;P&gt;Hello,&lt;/P&gt;&lt;P&gt;I am working on a project which uses the eeporm of the LPC1837JET100.&lt;/P&gt;&lt;P&gt;At some point our code has stopped working.&lt;BR /&gt;I have check our version control and could not find a change.&lt;BR /&gt;So I started experimenting and found a problem when writing to the eeprom with a hard-coded value.&lt;/P&gt;&lt;LI-CODE lang="cpp"&gt;#include "board.h"

typedef struct
{
    volatile unsigned value_a;
    volatile unsigned value_b;
    volatile unsigned value_c;
    volatile unsigned value_d;
    volatile unsigned value_e;
} __attribute__((aligned(1),packed)) TMemory_structure;

int main(void)
{
    //init eeprom
    Chip_Clock_Enable(CLK_MX_EEPROM);
    Chip_EEPROM_Init(LPC_EEPROM);
    Chip_EEPROM_SetAutoProg(LPC_EEPROM, EEPROM_AUTOPROG_AFT_1WORDWRITTEN);

    //get pointer to eeprom
    volatile TMemory_structure* data = (TMemory_structure*)EEPROM_ADDRESS(0,0);

    //prepare values
    static const unsigned value_in_program = 0x12345678;
    unsigned value_in_ram = 0x87654321;

    //write value in ram to eeprom
    data-&amp;gt;value_d = value_in_ram;

    //wait for operation to compete
    while( (LPC_EEPROM-&amp;gt;INTSTAT &amp;amp; EEPROM_INT_ENDOFPROG) == 0);
    LPC_EEPROM-&amp;gt;INTSTATCLR = EEPROM_INT_ENDOFPROG;

    //write value in program to eeprom
    data-&amp;gt;value_d = value_in_program;


    volatile static int i = 0 ;
    while(1) {
        i++ ;
    }
    return 0 ;
}&lt;/LI-CODE&gt;&lt;P&gt;In this example line 34 will not write data to the eeprom.&lt;BR /&gt;For this to fail you have to have the following situation.&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;If you have the current compiler. (I am convinced the code has worked a year ago.)&lt;/LI&gt;&lt;LI&gt;Do not have the compiler set to optimize. (For debugging)&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;If you have this situation the compiler will generate 4 &lt;U&gt;strb&lt;/U&gt; instructions to write to the eeprom.&lt;BR /&gt;Instead of a single &lt;U&gt;str&lt;/U&gt; instruction.&lt;/P&gt;&lt;LI-CODE lang="cpp"&gt;24            unsigned value_in_ram = 0x87654321;
1a00042a:   ldr     r3, [pc, #104]  ; (0x1a000494 &amp;lt;main()+136&amp;gt;)
1a00042c:   str     r3, [r7, #0]
27            data-&amp;gt;value_d = value_in_ram;
1a00042e:   ldr     r3, [r7, #4]
1a000430:   ldr     r2, [r7, #0]
1a000432:   str     r2, [r3, #12]

// skip some lines //

34            data-&amp;gt;value_d = value_in_program;
1a000456:   ldr     r3, [r7, #4]
1a000458:   ldrb    r2, [r3, #12]
1a00045a:   movs    r2, #0
1a00045c:   orr.w   r2, r2, #120    ; 0x78
1a000460:   strb    r2, [r3, #12]
1a000462:   ldrb    r2, [r3, #13]
1a000464:   movs    r2, #0
1a000466:   orr.w   r2, r2, #86     ; 0x56
1a00046a:   strb    r2, [r3, #13]
1a00046c:   ldrb    r2, [r3, #14]
1a00046e:   movs    r2, #0
1a000470:   orr.w   r2, r2, #52     ; 0x34
1a000474:   strb    r2, [r3, #14]
1a000476:   ldrb    r2, [r3, #15]
1a000478:   movs    r2, #0
1a00047a:   orr.w   r2, r2, #18
1a00047e:   strb    r2, [r3, #15]&lt;/LI-CODE&gt;&lt;P&gt;While the assembly will write the value to the address of the eeprom. The eeprom will not save the data.&lt;/P&gt;&lt;P&gt;In the user manual of the LPC18xx I found the reason this would not work.&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;EM&gt;The &lt;/EM&gt;&lt;EM&gt;first step is writing a minimum of 1 word (4 bytes) to a maximum of 32 words (128 bytes)&lt;/EM&gt;&lt;BR /&gt;&lt;EM&gt;to the desired page in the 16 kB EEPROM address space at address 0x2004 0000.&lt;/EM&gt;&lt;/P&gt;&lt;P&gt;I assume writing a byte at a time does not count.&lt;/P&gt;&lt;P&gt;My question is why does the compiler use the &lt;U&gt;strb&lt;/U&gt; instruction 4 times instead of 1 &lt;U&gt;str&lt;/U&gt; instruction.&lt;BR /&gt;There are 5 asm instructions to copy a value from program to ram to eeprom.&lt;BR /&gt;And 17 instructions to copy a value from program to eeprom.&lt;BR /&gt;Skipping ram uses 12 instructions more.&lt;BR /&gt;It could have loaded the value from program in r2 and then stored it in eeprom, using 2 instructions. (3 instructions if we include loading r3 with a pointer to the eeprom.)&lt;BR /&gt;&lt;BR /&gt;While I do not mind using a few instructions more while optimization is turned off for debugging.&lt;BR /&gt;In this case the eeprom peripheral will not save the data because it needs a write of 4 bytes instead of 4 writes of a byte.&lt;/P&gt;&lt;P&gt;I found a few way to get the code to work.&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;Coping a value to ram and then writing to eeprom.&lt;BR /&gt;This would add an extra step which could easily be forgotten why it is required.&lt;/LI&gt;&lt;LI&gt;Or enabling optimization.&lt;BR /&gt;This would make debugging a large project very difficult.&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;However I would like to know if there is a way to make sure the &lt;U&gt;str&lt;/U&gt; instruction is used.&lt;BR /&gt;Because the ways I have found feel like they should not be needed.&lt;/P&gt;</description>
      <pubDate>Thu, 29 Oct 2020 16:03:34 GMT</pubDate>
      <guid>https://community.nxp.com/t5/LPC-Microcontrollers/Writing-to-eeprom-with-a-hard-coded-value/m-p/1175421#M42746</guid>
      <dc:creator>gvisser</dc:creator>
      <dc:date>2020-10-29T16:03:34Z</dc:date>
    </item>
    <item>
      <title>Re: Writing to eeprom with a hard-coded value.</title>
      <link>https://community.nxp.com/t5/LPC-Microcontrollers/Writing-to-eeprom-with-a-hard-coded-value/m-p/1175445#M42747</link>
      <description>&lt;P&gt;&lt;SPAN&gt;You asked:&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;EM&gt;My question is why does the compiler use the &lt;U&gt;strb&lt;/U&gt; instruction 4 times instead of 1 &lt;U&gt;str&lt;/U&gt; instruction.&lt;/EM&gt;&lt;/P&gt;&lt;P&gt;Answer:&lt;/P&gt;&lt;P&gt;To write a 4 byte value in a single write, it MUST be 4-byte aligned, and the compiler must KNOW that it is guaranteed to be 4-byte aligned. You can do this by declaring a value as&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;int x __attribute__ ((aligned (4))) = 0;&lt;/PRE&gt;</description>
      <pubDate>Thu, 29 Oct 2020 17:14:56 GMT</pubDate>
      <guid>https://community.nxp.com/t5/LPC-Microcontrollers/Writing-to-eeprom-with-a-hard-coded-value/m-p/1175445#M42747</guid>
      <dc:creator>converse</dc:creator>
      <dc:date>2020-10-29T17:14:56Z</dc:date>
    </item>
  </channel>
</rss>

