How can I write to EEPROM using bootloader ?

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

How can I write to EEPROM using bootloader ?

Jump to solution
1,742 Views
jonathanchouina
Contributor I

(Sorry for my English)

 

Hello,

I'm using a MC9S12DJ128 MCU and I want to write in the 2k EEPROM. By searching a lot on the internet, I managed to do what I wanted, but not the way I wanted... I'm currently writing in the EEPROM by using theses commands in codewarrior (found in the UNSECURE command file):

 

reset

wb 0x03c 0x00       //disable cop

wait 20

wb 0x110 0x09      // set ECLKDV clock to 2Mhz

wb 0x114 0xFF      // EPROT all protection disabled

wb 0x115 0x30     // clear PVIOL and ACCERR in ESTAT register

wb 0x112 0x00     // clear the WRALL bit in FTSTMOD

wb 0x115 0x02

ww 0x118 0x002E   // write to EADDR eeprom address register

ww 0x11A 0x0000  // write to EDATA eeprom data register

wb 0x116 0x60       // write SECTOR MODIFY command in ECMD register

wb 0x115 0x80       // clear CBEIF in ESTAT register to execute the command

wait 20

 

Now, I want to do the same thing WITHOUT using the BDM port. I will run the code in a bootloader, and it needs to be in assembly. This is what I've done so far, but it's not working:

 

MOVB   #$00,$003C

MOVB   #$09,$0110

MOVB   #$FF,$0114

MOVB   #$30,$0115

MOVB   #$00,$0112

MOVB   #$02,$0115

MOVW  #$002E,$0118

MOVW  #$0000,$011A

MOVB   #$60,$0116

MOVB   #$80,$0115

 

I don't know how to do a reset in assembly, maybe that's the problem... Or maybe the timings are wrong...? (I'm a complete beginner in assembly). Please help me !

 

Thanks

Labels (1)
0 Kudos
1 Solution
1,324 Views
lama
NXP TechSupport
NXP TechSupport

hi,

Following example is for DP512. The principle is the same. Just placement and sizes are different.

You can check also principle in the C code project- attached.

Best regards, Ladislav

;_______________________________________________________________________________

; - Example present erase sector and write word to the EEPROM

; - Before write it checks:

;                    * alignment (2B)

;                    * whether sector is erased

; - Before sector erase it checks:

;                    * alignment (4B)

; - Variable err_code is used as a error return code

;

;_______________________________________________________________________________

;The Answer to the Ultimate Question of Life, the Universe, and Everything is: 42

;(Douglas Adams - The Hitchhiker's Guide to the Galaxy)

;_______________________________________________________________________________

; export symbols

            XDEF Entry            ; export 'Entry' symbol

            ABSENTRY Entry        ; for absolute assembly: mark this as application entry point

; include derivative specific macros

        INCLUDE 'derivative.inc'

;_______________________________________________________________________________

; definitions

;_______________________________________________________________________________

ROMStart         EQU   $C000            ; absolute address to place my code/constant data

ERR_OK:          EQU   $0               ; OK

ERR_RANGE:       EQU   $1               ; Parameter out of range. (not alligned sector 4B; data 2B))

ERR_BUSY:        EQU   $2               ; Device is busy.

ERR_NOTAVAIL:    EQU   $3               ; Requested value or method not available.

ERR_NOTERASED:   EQU   $4               ; Requested address is not erased

;_______________________________________________________________________________

; variable/data section

;_______________________________________________________________________________

            ORG RAMStart

;_______________________________________________________________________________

EE_address       DS.W  1                ; address for sector erase or data write

EE_data          DS.W  1                ; data to be written

err_code         DS.B  1                                 ; return value from flash erase/write functions

;_______________________________________________________________________________

; code section

;_______________________________________________________________________________

            ORG   ROMStart

;_______________________________________________________________________________

; main loop

;_______________________________________________________________________________

Entry:

    ;--- memory mapping ------------------

    ;- reset default memory mapping is: --

  ;INITRG = 0x00; Set the Reg map position     0x0000~0x03FF

  ;INITEE = 0x01; Set the EEPROM map position  0x0000~0x0FFF, EEON=1 => visible 0x0400~0x0FFF

  ;INITRM = 0x09; Set the RAM map position     0x0800~0x3FFF

  MOVB #$01,INITRM                      ; INITRM = 0x01; Set the RAM map position     0x0800~0x3FFF

  MOVB #$41,INITEE                      ; INITEE = 0x41; Set the EEPROM map position  0x4000~0x4FFF, EEON=1

  MOVB #$0 ,INITRG                      ; INITRG = 0x00; Set the Reg map position     0x0000~0x03FF

  NOP;                                  ; recommended

 

  ;--- Initialize stack ----------------

  LDS   #$4000                          ; initialize stack on the top of RAM

 

  ;--- EEPROM clock---------------------

;    MOVB  #$29,ECLKDIV                    ; ECLKDIV = 0x29, eeprom clock prescaler; OSCCLK = 8MHz BUSCLK=4MHz

    MOVB  #$4A,ECLKDIV                    ; ECLKDIV = 0x4A, eeprom clock prescaler; OSCCLK = 16MHz BUSCLK=8MHz

loop:

   

    ;--- Erase sector --------------------

  MOVW #$4000,EE_address                ; prepare address for write function

    JSR  EraseSector                      ; erase sector at address $4000

   

    ;--- Write word to eeprom ------------

  MOVW #$4000,EE_address                ; prepare address for write function

  MOVW #$1234,EE_data                   ; prepre data for write function

    JSR  WriteWord                        ; write word to the eeprom without checking address and EEPROM erased

    ;--- check error code and written data

    ;...

    ;...

    ;...

    ;--- Write word to eeprom ------------

  MOVW #$4002,EE_address                ; prepare address for write function

  MOVW #$5678,EE_data                   ; prepre data for write function

    JSR  WriteWord                        ; write word to the eeprom without checking address and EEPROM erased

    ;--- check error code and written data

    ;...

    ;...

    ;...

    ;--- loop forever---------------------

  JMP loop                              ; endless loop

;_______________________________________________________________________________

; WriteWord

; inputs: EE_address

;                  EE_data  

;    output: err_code    

;_______________________________________________________________________________

WriteWord:

    PSHD 

    PSHX 

    LDD   EE_address                ; check alignment (4B)

    LDX   #$2

    IDIV

    CPD   #$0                       ; if != $0 => error

    BEQ   WriteWord_LBL6

    MOVB  #ERR_RANGE,err_code       ;return ERR_RANGE;

    BRA   WriteWord_LBL2

WriteWord_LBL6:                     ; check whether word is errased

    LDX   EE_address                ;*(volatile word *) AddrRow = Data16; // Array address and program data  

    LDD   0,X

    CPD   #$FFFF                    ; if != $FFFF => error

    BEQ   WriteWord_LBL5

    MOVB  #ERR_NOTERASED,err_code   ;return ERR_BUSY;      // If yes then error

    BRA   WriteWord_LBL2

WriteWord_LBL5:

    BRSET ESTAT,#128,WriteWord_LBL1 ;if (ESTAT_CBEIF == 0) // Is command buffer full ?

    MOVB  #ERR_BUSY,err_code        ;return ERR_BUSY;      // If yes then error

    BRA   WriteWord_LBL2

   

WriteWord_LBL1:

    MOVB  #$30,ESTAT                ;ESTAT = 0x30;         // Clear error flags

    LDX   EE_address                ;*(volatile word *) AddrRow = Data16; // Array address and program data  

    LDD   EE_data

    STD   0,X

    MOVB  #$20,ECMD                 ;ECMD = 0x20;          // Word program command

    BSET  ESTAT,#$80                ;ESTAT_CBEIF = 1;      // Clear flag command buffer empty

    BRSET ESTAT,#$20,WriteWord_LBL3 ;if ((ESTAT_PVIOL == 1)||(ESTAT_ACCERR == 1)) // Is protection violation or acces error detected ?

    BRCLR ESTAT,#$10,WriteWord_LBL4

 

WriteWord_LBL3:

    MOVB  #ERR_NOTAVAIL,err_code    ;return ERR_NOTAVAIL;  // If yes then error

    BRA   WriteWord_LBL2

 

WriteWord_LBL4:

    LDAB  ESTAT                     ;while (EEPROM_BUSY);  // Wait for command completition

    ANDB  #192

    CMPB  #192

    BNE   WriteWord_LBL4

    MOVB  ERR_OK,err_code           ;return ERR_OK; 

WriteWord_LBL2:

    PULX 

    PULD 

    RTS  

;_______________________________________________________________________________

; EraseSector

; inputs: EE_address

;    output: err_code    

;_______________________________________________________________________________

EraseSector:

    PSHD 

    PSHX 

    LDD   EE_address                ; check alignment (4B)

    LDX   #$4

    IDIV

    CPD   #$0                       ; if != $0 => error

    BEQ   EraseSector_LBL5

    MOVB  #ERR_RANGE,err_code       ;return ERR_RANGE;

    BRA   EraseSector_LBL2

EraseSector_LBL5:

    BRSET ESTAT,#128,EraseSector_LBL1;if (ESTAT_CBEIF == 0) // Is command buffer full ?

    MOVB  #ERR_BUSY,err_code        ;return ERR_BUSY;      // If yes then error

    BRA   EraseSector_LBL2

   

EraseSector_LBL1:

    MOVB  #$30,ESTAT                ;ESTAT = 0x30;         // Clear error flags

    LDX   EE_address                ;*(volatile word *) AddrRow = Data16; // Array address and program data  

    LDD   #$FFFF                    ; dummy data

    STD   0,X

    MOVB  #$40,ECMD                 ;ECMD = 0x20;          // Word program command

    BSET  ESTAT,#$80                ;ESTAT_CBEIF = 1;      // Clear flag command buffer empty

    BRSET ESTAT,#$20,EraseSector_LBL3 ;if ((ESTAT_PVIOL == 1)||(ESTAT_ACCERR == 1)) // Is protection violation or acces error detected ?

    BRCLR ESTAT,#$10,EraseSector_LBL4

 

EraseSector_LBL3:

    MOVB  #ERR_NOTAVAIL,err_code    ;return ERR_NOTAVAIL;  // If yes then error

    BRA   EraseSector_LBL2

 

EraseSector_LBL4:

    LDAB  ESTAT                     ;while (EEPROM_BUSY);  // Wait for command completition

    ANDB  #192

    CMPB  #192

    BNE   EraseSector_LBL4

    MOVB  ERR_OK,err_code           ;return ERR_OK; 

EraseSector_LBL2:

    PULX                                      

    PULD 

    RTS  

;_______________________________________________________________________________

;**************************************************************

;*                 Interrupt Vectors                          *

;**************************************************************

            ORG   $FFFE

            DC.W  Entry           ; Reset Vector

View solution in original post

0 Kudos
6 Replies
1,323 Views
jonathanchouina
Contributor I

Ok, I think I understand now. I have not tested it yet, but this is the code I've came up with by following your advices:

;SET MEMORY MAP

       MOVB  #$01,INITRM      ;MAP RAM TO 0x0800~0x3FFF

       MOVB  #$0,INITRG        ;MAP REG TO 0x0000~0x03FF

       MOVB  #$41,INITEE       ;MAP EEPROM TO 0x4000~0x47FF

;SETUP

       MOVB  #$00,$003C        ;DISABLE COP

       MOVB  #$09,$0110         ;SET ECLKDIV TO 2MHz

       MOVB  #$FF,$0114         ;EPROT ALL PROTECTION DISABLED

;ERASE SECTOR

       MOVB  #$30,$0115         ;CLEAR PVIOL AND ACCERR IN ESTAT

       LDX  #$405C                   ;EEPROM BASE ADDRESS (0x4000) + DATA LOCATION (0x005C)

       LDD  #$FFFF                  ;DUMMY DATA

       STD  0,X                          ;WRITE DATA @ ADDRESS

       MOVB  #$40,ECMD        ;SECTOR ERASE COMMAND IN ECMD

       BSET ESTAT,#$80          ;LAUNCH COMMAND

;WRITE WORD

       MOVB  #$30,$0115         ;CLEAR PVIOL AND ACCERR IN ESTAT

       LDX  #$405C                   ;EEPROM BASE ADDRESS (0x4000) + DATA LOCATION (0x005C)

       LDD  #$0000                   ;DATA HERE

       STD  0,X                          ;WRITE DATA @ ADDRESS

       MOVB  #$20,ECMD        ;WORD PROGRAM COMMAND IN ECMD

       BSET ESTAT,#$80          ;LAUNCH COMMAND

Do you think I'm good with this ? I'm not quite sure about the ECLKDIV value I should use... =/

Thanks

0 Kudos
1,323 Views
lama
NXP TechSupport
NXP TechSupport

I have just returned from vacation. Do you still need a help or you have already solved your issue?

0 Kudos
1,323 Views
jonathanchouina
Contributor I

Yes it is, I forgot to mark it solved. Thank you !

0 Kudos
1,325 Views
lama
NXP TechSupport
NXP TechSupport

hi,

Following example is for DP512. The principle is the same. Just placement and sizes are different.

You can check also principle in the C code project- attached.

Best regards, Ladislav

;_______________________________________________________________________________

; - Example present erase sector and write word to the EEPROM

; - Before write it checks:

;                    * alignment (2B)

;                    * whether sector is erased

; - Before sector erase it checks:

;                    * alignment (4B)

; - Variable err_code is used as a error return code

;

;_______________________________________________________________________________

;The Answer to the Ultimate Question of Life, the Universe, and Everything is: 42

;(Douglas Adams - The Hitchhiker's Guide to the Galaxy)

;_______________________________________________________________________________

; export symbols

            XDEF Entry            ; export 'Entry' symbol

            ABSENTRY Entry        ; for absolute assembly: mark this as application entry point

; include derivative specific macros

        INCLUDE 'derivative.inc'

;_______________________________________________________________________________

; definitions

;_______________________________________________________________________________

ROMStart         EQU   $C000            ; absolute address to place my code/constant data

ERR_OK:          EQU   $0               ; OK

ERR_RANGE:       EQU   $1               ; Parameter out of range. (not alligned sector 4B; data 2B))

ERR_BUSY:        EQU   $2               ; Device is busy.

ERR_NOTAVAIL:    EQU   $3               ; Requested value or method not available.

ERR_NOTERASED:   EQU   $4               ; Requested address is not erased

;_______________________________________________________________________________

; variable/data section

;_______________________________________________________________________________

            ORG RAMStart

;_______________________________________________________________________________

EE_address       DS.W  1                ; address for sector erase or data write

EE_data          DS.W  1                ; data to be written

err_code         DS.B  1                                 ; return value from flash erase/write functions

;_______________________________________________________________________________

; code section

;_______________________________________________________________________________

            ORG   ROMStart

;_______________________________________________________________________________

; main loop

;_______________________________________________________________________________

Entry:

    ;--- memory mapping ------------------

    ;- reset default memory mapping is: --

  ;INITRG = 0x00; Set the Reg map position     0x0000~0x03FF

  ;INITEE = 0x01; Set the EEPROM map position  0x0000~0x0FFF, EEON=1 => visible 0x0400~0x0FFF

  ;INITRM = 0x09; Set the RAM map position     0x0800~0x3FFF

  MOVB #$01,INITRM                      ; INITRM = 0x01; Set the RAM map position     0x0800~0x3FFF

  MOVB #$41,INITEE                      ; INITEE = 0x41; Set the EEPROM map position  0x4000~0x4FFF, EEON=1

  MOVB #$0 ,INITRG                      ; INITRG = 0x00; Set the Reg map position     0x0000~0x03FF

  NOP;                                  ; recommended

 

  ;--- Initialize stack ----------------

  LDS   #$4000                          ; initialize stack on the top of RAM

 

  ;--- EEPROM clock---------------------

;    MOVB  #$29,ECLKDIV                    ; ECLKDIV = 0x29, eeprom clock prescaler; OSCCLK = 8MHz BUSCLK=4MHz

    MOVB  #$4A,ECLKDIV                    ; ECLKDIV = 0x4A, eeprom clock prescaler; OSCCLK = 16MHz BUSCLK=8MHz

loop:

   

    ;--- Erase sector --------------------

  MOVW #$4000,EE_address                ; prepare address for write function

    JSR  EraseSector                      ; erase sector at address $4000

   

    ;--- Write word to eeprom ------------

  MOVW #$4000,EE_address                ; prepare address for write function

  MOVW #$1234,EE_data                   ; prepre data for write function

    JSR  WriteWord                        ; write word to the eeprom without checking address and EEPROM erased

    ;--- check error code and written data

    ;...

    ;...

    ;...

    ;--- Write word to eeprom ------------

  MOVW #$4002,EE_address                ; prepare address for write function

  MOVW #$5678,EE_data                   ; prepre data for write function

    JSR  WriteWord                        ; write word to the eeprom without checking address and EEPROM erased

    ;--- check error code and written data

    ;...

    ;...

    ;...

    ;--- loop forever---------------------

  JMP loop                              ; endless loop

;_______________________________________________________________________________

; WriteWord

; inputs: EE_address

;                  EE_data  

;    output: err_code    

;_______________________________________________________________________________

WriteWord:

    PSHD 

    PSHX 

    LDD   EE_address                ; check alignment (4B)

    LDX   #$2

    IDIV

    CPD   #$0                       ; if != $0 => error

    BEQ   WriteWord_LBL6

    MOVB  #ERR_RANGE,err_code       ;return ERR_RANGE;

    BRA   WriteWord_LBL2

WriteWord_LBL6:                     ; check whether word is errased

    LDX   EE_address                ;*(volatile word *) AddrRow = Data16; // Array address and program data  

    LDD   0,X

    CPD   #$FFFF                    ; if != $FFFF => error

    BEQ   WriteWord_LBL5

    MOVB  #ERR_NOTERASED,err_code   ;return ERR_BUSY;      // If yes then error

    BRA   WriteWord_LBL2

WriteWord_LBL5:

    BRSET ESTAT,#128,WriteWord_LBL1 ;if (ESTAT_CBEIF == 0) // Is command buffer full ?

    MOVB  #ERR_BUSY,err_code        ;return ERR_BUSY;      // If yes then error

    BRA   WriteWord_LBL2

   

WriteWord_LBL1:

    MOVB  #$30,ESTAT                ;ESTAT = 0x30;         // Clear error flags

    LDX   EE_address                ;*(volatile word *) AddrRow = Data16; // Array address and program data  

    LDD   EE_data

    STD   0,X

    MOVB  #$20,ECMD                 ;ECMD = 0x20;          // Word program command

    BSET  ESTAT,#$80                ;ESTAT_CBEIF = 1;      // Clear flag command buffer empty

    BRSET ESTAT,#$20,WriteWord_LBL3 ;if ((ESTAT_PVIOL == 1)||(ESTAT_ACCERR == 1)) // Is protection violation or acces error detected ?

    BRCLR ESTAT,#$10,WriteWord_LBL4

 

WriteWord_LBL3:

    MOVB  #ERR_NOTAVAIL,err_code    ;return ERR_NOTAVAIL;  // If yes then error

    BRA   WriteWord_LBL2

 

WriteWord_LBL4:

    LDAB  ESTAT                     ;while (EEPROM_BUSY);  // Wait for command completition

    ANDB  #192

    CMPB  #192

    BNE   WriteWord_LBL4

    MOVB  ERR_OK,err_code           ;return ERR_OK; 

WriteWord_LBL2:

    PULX 

    PULD 

    RTS  

;_______________________________________________________________________________

; EraseSector

; inputs: EE_address

;    output: err_code    

;_______________________________________________________________________________

EraseSector:

    PSHD 

    PSHX 

    LDD   EE_address                ; check alignment (4B)

    LDX   #$4

    IDIV

    CPD   #$0                       ; if != $0 => error

    BEQ   EraseSector_LBL5

    MOVB  #ERR_RANGE,err_code       ;return ERR_RANGE;

    BRA   EraseSector_LBL2

EraseSector_LBL5:

    BRSET ESTAT,#128,EraseSector_LBL1;if (ESTAT_CBEIF == 0) // Is command buffer full ?

    MOVB  #ERR_BUSY,err_code        ;return ERR_BUSY;      // If yes then error

    BRA   EraseSector_LBL2

   

EraseSector_LBL1:

    MOVB  #$30,ESTAT                ;ESTAT = 0x30;         // Clear error flags

    LDX   EE_address                ;*(volatile word *) AddrRow = Data16; // Array address and program data  

    LDD   #$FFFF                    ; dummy data

    STD   0,X

    MOVB  #$40,ECMD                 ;ECMD = 0x20;          // Word program command

    BSET  ESTAT,#$80                ;ESTAT_CBEIF = 1;      // Clear flag command buffer empty

    BRSET ESTAT,#$20,EraseSector_LBL3 ;if ((ESTAT_PVIOL == 1)||(ESTAT_ACCERR == 1)) // Is protection violation or acces error detected ?

    BRCLR ESTAT,#$10,EraseSector_LBL4

 

EraseSector_LBL3:

    MOVB  #ERR_NOTAVAIL,err_code    ;return ERR_NOTAVAIL;  // If yes then error

    BRA   EraseSector_LBL2

 

EraseSector_LBL4:

    LDAB  ESTAT                     ;while (EEPROM_BUSY);  // Wait for command completition

    ANDB  #192

    CMPB  #192

    BNE   EraseSector_LBL4

    MOVB  ERR_OK,err_code           ;return ERR_OK; 

EraseSector_LBL2:

    PULX                                      

    PULD 

    RTS  

;_______________________________________________________________________________

;**************************************************************

;*                 Interrupt Vectors                          *

;**************************************************************

            ORG   $FFFE

            DC.W  Entry           ; Reset Vector

0 Kudos
1,323 Views
kef2
Senior Contributor IV

Program algorithm used by CW is only usable in special modes, which are not usable without BDM. EADDR and EDATA registers (0x118, 0x11A) are not working in normal modes. Instead you need to write your data directly to EEPROM array, you need to replace 

MOVW  #$002E,$0118  <-- 2E is EEPROM word number

MOVW  #$0000,$011A

with

;don't know where your EEPROM is mapped to in normal mode, say it is at 0x800, then

MOVW #$0000, $085C  ; <-- 5c is 2E*2, byte offset from start of EEPROM array

1,323 Views
jonathanchouina
Contributor I

Hi, thank you for your answer.

Do I need to keep all the MOVB instructions ? Also, according to the datasheet, my EEPROM is at 0x800 like you said, but is it normal I can't see the data in the Codewarior's Memory View tab at 0x800 ? Sometimes it appears at 0x2000 and 0x3000, but since it's RAM, I guess it's normal ? Thanks

0 Kudos