programming steps for PPAGE in assembly

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

programming steps for PPAGE in assembly

1,582 Views
Learner_z31_zma
Contributor I

Hi,

I am trying to write and read the high page of HCSQE128 flash, I have attempted to use the Processor Expert to set those pages i.e. PPAGE4,PPAGE5,PPAGE6,PPAGE7 as BANKED pages. As well as set ting the compiler and assembler into BANKED mode as oppose to the default setting i.e SMALL.

 

I have also gone through AN3730 Understanding Memory Paging in 9S08 Devices, the application sheet does not mention the need to enable the LAP register.

 

Can anyone clarify what are the steps to read and write into high page flash?

 

I can write values into the LAP registers but not LB register.

 

Thanks!

Labels (1)
0 Kudos
8 Replies

619 Views
kef
Specialist I

Did you read chapter 4.6 Flash of QE128 Reference manual?

 

LAP registers allow to read and write from/to flash memory only. When you write to LB you latch address and data in flash memory controller only. Flash contents won't change after write to LB, unless you complete whole flash erase/program procedure described in chapter 4.6 or RM.

LAP registers contain linear address of flash memory. Byte at CPU address 0x2080 has linear address 0x002080. Byte at CPU address 0x4000 has linear address 0x004000. Byte at CPU address 0xC000 has linear address 0x00C000. That's simple to convert.

Now paged memory window, CPU address 0x8000:

page 0  - linear address 0x000000

page 1 -  -"- 0x004000

page 2 -  -"- 0x008000

page 3 -  -"- 0x00C000

page 4 -  -"- 0x010000

page 5 -  -"- 0x014000

page 6 -  -"- 0x018000

page 7 -  -"- 0x01C000

 

Registers and RAM can't be accessed via LAP+LB. Reading linear address 0x000000-0x00207F you are reading page0 of flash. You can read the same at CPU addresses 0x8000..0xA07F when PPAGE=0.

 

BTW, flash memory is not readable while it is being programmed/erased. Part of your flash program/erase routines should execute from RAM, also interrupts have to be disabled. Please search the forum, it was discussed many times.

 

Hope this helps

0 Kudos

619 Views
Learner_z31_zma
Contributor I

Hi Kef,

 

Thanks for the advise, I have gone away and tried your suggestions however without sucess and I am not sure where I have gone wrong........ I basically followed the Flash program structure in chapter 4.6 Flash page 81 Figure 4-17 of QE128 Reference manual.

 

I am attempting to write to PPAGE 4, the value in

 

  • FDIV = $C9 which was set up using Processor Initialization.
  • FOPT = $42

KEYEN = Disabled and Flash UNSECURED

 

  • FSTAT = $C0, before and after

    ;/* set FCBEF flag in the FSTAT*/
    ;/* clear FACCERR and FPVIOL flags in the FSTAT*/

 

Which is

 

FCBEF       = 1, Command buffers are ready to accept a new command.

FCCF          = 1, All commands are completed.

FPVIOL       = 0, No protection violation detected.

FACCERR = 0 No access error detected.

 

  • Write Flash program command to Flash Command Register

The Memory map in the debugger does not update with the Program command $20, not sure what I've done wrong here....

 

  • writing a 1 to FCBEF to launch the command

Has no effect....

 

I have attached my code for the routine, please advise....

 

Thanks in advance!

 

 

;*************************           
;=====<< MAIN code >>=====
;*************************

;         =============
;<*=====*<  Write_LAP  >*=====*>
;         =============
 
    ;/* Write Linear Address Pointer Registers 2:0 (LAP2:LAP0)*/

        mov     #1,LAP2            ;PPAGE 4 = 0x10000
        clra
        sta     LAP1           
        sta     LAP0
        sta     Counter     ;clear counter
       
    ;/* increment Linear Address Pointer Registers value */

        lda     #1
        sta     LAPAB;<------ Memory map in Debugger does not update
       
    ;/* No protection for Flash */
       
        lda     #$7f
        sta     FPROT
       
main_loop:     

;         ==============
;<*=====*<  Flash write >*=====*>
;         ==============

    ;/* FDIV = C9 */
    ;/* set FCBEF flag in the FSTAT*/
    ;/* clear FACCERR and FPVIOL flags in the FSTAT*/

        lda     #$f0
        sta     FSTAT;<--- Memory map in Debugger does not update
                     ; value = C0
                      
    ;/* Write to Linear Byte Register (LB)*/

        lda     Counter
        sta     LB

    ;/* Write Flash program command to Flash Command Register */
       
        lda     #$20
        sta     FCMD;<--- Memory map in Debugger does not update
                    ; value = 00
                   
    ;/* writing a 1 to FCBEF to launch the command */
   
        lda     #$80
        sta     FSTAT
 
;<*============================*>

        inc     Counter

        jmp     main_loop

 

 

0 Kudos

619 Views
kef
Specialist I

At least some QE's have flash protection related erratas. With 0x7F in FPROT and without errata workaround I was unable to program data at 0x1_0000. PVIOL was set.

 

 

        lda     #1
        sta     LAPAB;<------ Memory map in Debugger does not update

 

Do you mean here that LAP address doesn't increment? I see LAP is incremented. Are you using simulator?

 

 

Your code has some problems

 

1)

        lda     #$f0
        sta     FSTAT;<--- Memory map in Debugger does not update
                     ; value = C0
 

It is not clear why are you trying simultaneously to clear flash errors and launch new flash command. FCMD is not written yet.

 

 

 

 

2)          lda     #$80
              sta FSTAT

 

After launching flash command and before latching any new data to flash, you should wait either for FCBEF=1 or FCCF=1

 

 

 

 

Hiwave debugger by default caches contents of flash and doesn't update it from MCU memory. To see changes go MultilinkCyclonePro -> Debugging Memory Map..., then select banked, click Modify/Details and check "refresh memory when halting".

 

"linear" flash address space seems being refreshed by default when halting. To few linear flash address space you can right mouse click in memory window, then check Address Space->Flash. Then you can go to 0x10000 address and see if write succeeded or no.

0 Kudos

619 Views
Learner_z31_zma
Contributor I


kef wrote:

At least some QE's have flash protection related erratas. With 0x7F in FPROT and without errata workaround I was unable to program data at 0x1_0000. PVIOL was set.

 

 

        lda     #1
        sta     LAPAB;<------ Memory map in Debugger does not update

 

Do you mean here that LAP address doesn't increment? I see LAP is incremented. Are you using simulator?

 


 

 

 

No,  What I meant is in the Debugger MEMORY MAP window, the LAPAB value remains 00. Which I expect to be 1 after stepping through the 

 

        sta     LAPAB

 

instruction.

 


kef wrote:

 

Your code has some problems

 

1)

        lda     #$f0
        sta     FSTAT;<--- Memory map in Debugger does not update
                     ; value = C0

It is not clear why are you trying simultaneously to clear flash errors and launch new flash command. FCMD is not written yet.

 

 

 

 


 

 

What I am doing with

 

        lda     #$f0
        sta     FSTAT

 

is simply combining these 2 steps together following the Figure 4-17. Example Program Command Flow on page 81 of the QE128RM

 

     ________|__________

    |  Read: FSTAT register  |

    ___________________

                       |

                       ^

       ______/    \______

      /                                  \

   <       FCBEF set?        >

     \______        _____ /

                     \    /

                       v

                       |

                       |

                       ^

     _______/    \______

    / FACCERR/FPVIOL  \

 <               set?                 >

    \_______      ______ /

                     \    /

                       v

 

 

 

which is also stated on page 78.

 

4.6.3.1.2 Command Write Sequence

 

"Before starting a command write sequence, the FACCERR and FPVIOL flags in the FSTAT register must be clear and the FCBEF flag must be set (see Section 4.6.2.5)."

 

I have tested the code again with all the suggestions you've mentioned, still without sucess. Here is the code, please advise.....

 

 

 

;*************************           
;=====<< MAIN code >>=====
;*************************

;         =============
;<*=====*<  Write_LAP  >*=====*>
;         =============
 
    ;/* Write Linear Address Pointer Registers 2:0 (LAP2:LAP0)*/

        mov     #1,LAP2            ;PPAGE 4 = 0x10000
        clra
        sta     LAP1           
        sta     LAP0
        sta     Counter           ;clear counter
       
    ;/* increment Linear Address Pointer Registers value */

        lda     #1
        sta     LAPAB;<------ Memory map in Debugger does not update
       
    ;/* No protection for Flash */
       
        lda     #$7f
        sta     FPROT
       
main_loop:     

;         ==============
;<*=====*<  Flash write >*=====*>
;         ==============

    ;/* FDIV = C9 */
    ;/* clear FACCERR and FPVIOL flags in the FSTAT*/

        lda     #$30
        sta     FSTAT;<--- Memory map in Debugger does not update
                     ; value = C0
                      
    ;/* Write to Linear Byte Register (LB)*/

        lda     Counter
        sta     LB

    ;/* Write Flash program command to Flash Command Register */
       
        lda     #$20
        sta     FCMD;<--- Memory map in Debugger does not update
                    ; value = 00
                   
    ;/* writing a 1 to FCBEF to launch the command */
   
        lda     #$80
        sta     FSTAT
 
;<*============================*>

    ;/* test for FCCF in the FSTAT*/

again:
        lda     #$40
        bit     FSTAT
        bne     next
        bra     again
next:


        inc     Counter

        jmp     main_loop

 

When I traced the code, the  /* test for FCCF in the FSTAT*/  loop exits straight away, I can not help suspecting that the Flash PROGRAM command was never launched...... Therefore value in FSTAT register remained unchanged....

 

 

Thoughts!?

0 Kudos

619 Views
kef
Specialist I

   

      No,  What I meant is in the Debugger MEMORY MAP window, the LAPAB value remains 00. Which I expect to be 

      after stepping through the 

 

Reference manual clearly states reads from LAPAB return 0. Check out Figure 4-9. R - read, all bits are "0".

 

 

 

 

    What I am doing with

 

            lda     #$f0
            sta     FSTAT

 

    is simply combining these 2 steps together following the Figure 4-17. Example Program Command Flow on page 81

    of    the QE128RM

 

 

That's not right. To clear errors bits you should write $30 to FSTAT. Writing "1" to FCBEF while data is not latched, or when FCMD is not yet written - should immediately set ACCER error flag.

 

 

    4.6.3.1.2 Command Write Sequence

 

   "Before starting a command write sequence, the FACCERR and FPVIOL flags in the FSTAT register must be clear and

   the FCBEF flag must be set (see Section 4.6.2.5)."

 

Yes, but writing $F0 to FSTAT not only write ones to FACCERR and FPVIOL flags, but also to FCBEF. That's wrong.

 

 

 

 Code looks right now. Did you verify your MCU maskset doesn't have flash protection errata? Try not writing non $FF value to FPROT.

 

It's not true FCBEF bit doesn't change. I guess debugger delays are longer that time FCBEF stays low.

0 Kudos

619 Views
Learner_z31_zma
Contributor I

OK, I have added a read routine using LB after writting to it. It verifies that the PPAGE4 was indeed written into, here is the working code

 

 

;*************************           
;=====<< MAIN code >>=====
;*************************

;         =============
;<*=====*<  Write_LAP  >*=====*>
;         =============
 
    ;/* Write Linear Address Pointer Registers 2:0 (LAP2:LAP0)*/


        mov     #1,LAP2            ; PPAGE 4 = 0x10000
        clra
        sta     LAP1           
        sta     LAP0
        sta     Counter     ; init Counter
        
;         ==============
;<*=====*<  Flash_write >*=====*>
;         ==============

main_loop:

    ;/* FDIV = C9, set by Device Initialization.(150khz < FDIV < 200khz)*/
    ;/* clear FACCERR and FPVIOL flags in the FSTAT*/

        lda     #$30
        sta     FSTAT
       
    ;/* Write to Linear Byte Register (LB)*/

        lda     Counter
        sta     LB

    ;/* Write Flash program command to Flash Command Register */
       
        lda     #$20
        sta     FCMD
                           
    ;/* writing a 1 to FCBEF to launch the command */
   
        lda     #$80
        sta     FSTAT
 
    ;/* test for FCCF in the FSTAT*/

again:
        lda     #$40
        bit     FSTAT
        bne     next
        bra     again
next:

    ;/* increment Linear Address Pointer Registers value */

        mov     #1,LAPAB

    ;/* set number of loops to write number of addresses in Flash */
   
        inc     Counter   ; Counter counts the number of loop
        lda     #21   ; set 20 loops to write value into 20 addresses
        cmp     Counter
        bne     main_loop

;//*========================*

    ;/* Flash_write loop completed */
    ;/* read Flash using LB */
   
        clrx      
        clrh

read_LB:

        stx     LAP0
        lda     LB
        incx
        cpx     #21
        bne     read_LB
       
;//*========================*
     
     ;/* repeat whole routine again */
            
        mov     #0,Counter
        jmp     main_loop

 

 

I guess the RT-Debugger MEMORY MAP does not display the value in PPAGE which is what I have been relying on all this time as an indication for my write routine....... All it shows is _ _

 

Is there anyway to make the MEMORY MAP in the debugger to show what I have written for convenient so I dont have to STEP the code to check each value written? REFRESH the MEMORY MAP does not do this......

0 Kudos

619 Views
Learner_z31_zma
Contributor I

Hi Kef,

Just want to say thank you very much for your help to get me this far, however I have encountered another problem which is; I would like to repeatedly write to PPAGE flash but it appears that I can only write the flash once. Unless I reprogram the ucontroller with the debugger again.

 

I get the impression that I can only write to PPAGE when the address content is FF? and once written with some value I can not write to that location again unless it has been erased first to FF?

 

This is my current code, it attemps to rewrite 5 PPAGE address repeatedly but the Flash_Read loop shows that it only retains the value of the first attempt thats written. What do I need to do to rewrite the address content once it has been written?

 

 

;*************************           
;=====<< MAIN code >>=====
;*************************

;         =============
;<*=====*<  Write_LAP  >*=====*>
;         =============
 
    ;/* Write Linear Address Pointer Registers 2:0 (LAP2:LAP0)*/


        mov     #1,LAP2            ; PPAGE 4 = 0x10000
        clra
        sta     LAP1           
        sta     LAP0
        sta     Counter     ; init loop Counter
        sta     Value     ; init value Counter
        
;         ==============
;<*=====*<  Flash_write >*=====*>
;         ==============

main_loop:

    ;/* FDIV = C9, set by Device Initialization.(150khz < FDIV < 200khz)*/
    ;/* clear FACCERR and FPVIOL flags in the FSTAT*/

        lda     #$30
        sta     FSTAT
       
    ;/* Write to Linear Byte Register (LB)*/

        lda     Value
        sta     LBP

    ;/* Write Flash program command to Flash Command Register */
       
        lda     #$20
        sta     FCMD
                           
    ;/* writing a 1 to FCBEF to launch the command */
   
        lda     #$80
        sta     FSTAT
 
    ;/* test for FCCF in the FSTAT*/

again:
        lda     #$40
        bit     FSTAT
        bne     next
        bra     again
next:


    ;/* set number of loops to write number of addresses in Flash */
   
        inc     value
  inc     Counter  ; Counter counts the number of loop
        lda     #5   ; set 5 loops to write value
        cmp     Counter
        bne     main_loop

;         ==============
;<*=====*<  Flash_Read >*=====*>
;         ==============

    ;/* Flash_write loop completed */
    ;/* read Flash using LBP */
    ;/* reset LBP pointer */
   
        clrx      

    ;/* read_LBP loop */

read_LBP:

        stx     LAP0
        lda     LBP
        incx
        cpx     #5
        bne     read_LBP
       
;//*========================*
     
     ;/* reset counter and repeat whole routine */
            
        mov     #0,Counter

        jmp     main_loop

 

 

0 Kudos

619 Views
kef
Specialist I

Quote from reference manual:

 

CAUTION

A flash block address must be in the erased state before being programmed.

Cumulative programming of bits within a flash block address is not allowed

except for status field updates required in EEPROM emulation applications.

 

So yes, you have to erase flash, before writing to it again.

 

Also, since you want to "repeatedly write to" flash, please consider if specified minimum of 10000 program/erase cycles will be enough for the life time of your device. This figure is specified in QE128 datasheet.

0 Kudos