Topic : Unable to write to main program flash using ASM

Forum : ST7/STM8

Original Post
Post Information Post
July 16, 2013 - 4:06pm
Guest

Im attempting to write erase/write to main program memory in ASM. The problem i am having is i can seem to change the CR2 and NCR2 values, i have tries several bits i.e. block erase, block write, word write but all do not work. the CR2/NCR2 bits are not changing and the flash is not changing. I have posted to code i am using to perform this

please note
- i am executing from ram
- i have verified the FLASH_IAPSR.PUL is unlocked (set to 1)
- i do not get IAPSR.EOP or IAPSR.WR_PG_DIS set when i wait for last operation.

FLASH EQU 0505Ah
FLASH_CR1   EQU (FLASH+0)
FLASH_CR2   EQU (FLASH+1)
FLASH_NCR2  EQU (FLASH+2)
FLASH_FPR   EQU (FLASH+3)
FLASH_NFPR  EQU (FLASH+4)
FLASH_IAPSR EQU (FLASH+5)
FLASH_PUKR  EQU (FLASH+8)
FLASH_DUKR  EQU (FLASH+10)



QFirmwareWrite_data SEGMENT DATA
    RSEG QFirmwareWrite_data
    blockBuffer: DS 80h
  
        


PUBLIC ?upgradeApplication
    QFirmwareWrite_code SEGMENT CODE INRAM;TODO: allocate segment to fixed area
    RSEG QFirmwareWrite_code

?upgradeApplication:
    LDW X,#0000h
    LD A,#55h    
    LD (blockBuffer,X),A
    INCW X
    LD (blockBuffer,X),A
   
    CALL UnlockFlash
    CALL EraseBlock
    CALL WaitForLastOp
    CALL LockFlash
    RET


EraseBlock:
    LD A, FLASH_IAPSR
    LD A, FLASH_CR2
    OR A, #040h; Erase bit
    LD FLASH_CR2, A
   

    LD A, FLASH_NCR2
    AND A, #0BFh ; NOT 02h
    LD FLASH_NCR2, A
    LD A,FLASH_NCR2

    LD A,#055h
    LDW Y, #09000h
    LD (Y),A
    INCW Y
    LD (Y),A
    INCW Y
    LD (Y),A
    INCW Y
    LD (Y),A

    RET
    

UnlockFlash:
    MOV FLASH_PUKR,#056h ; unlock key 1
    MOV FLASH_PUKR,#0AEh ; unlock key 2
    RET


LockFlash:
    LD  A, FLASH_IAPSR
    AND A, #0FDh ;lock 
    LD FLASH_IAPSR, A
    RET


WaitForLastOp:
        LDW Y, #00F00h
_timerLoop:        
        LD A, FLASH_IAPSR
        AND A, #005h               ;only include op complete or write protect bits
        JRNE _returnWaitForLastOp ;return if result if either bit is set
        DECW Y
        JRNE _timerLoop
_returnWaitForLastOp:        
        RET
        

END

Replies
Post Information Post
+1
0
-1
July 17, 2013 - 6:28am
Guest

I found this in the STM8 Flash application notes

Quote:

FLASH_CR2 and FLASH_NCR2 must be written consecutively to be taken into account. If
only one register is set, both are forced to their reset values, causing the program operation
to be performed at byte level.

I have changed my program to load the two registers consecutively

 LDW Y #020DFh
 LDW FLASH_CR2,Y 

but found that results are inconsistent i.e. sometimes it does a block erase and sometimes it falls back to byte erase

+1
0
-1
July 17, 2013 - 7:55am
Guest

I have sorted the issue out now, it seems that in need to do simple move operations into the CR2, NCR2 registers for it to work.

EraseBlock:
    LD A, FLASH_IAPSR
    LDW X,(blockBuffer)
    LD A,#000h
    
    MOV FLASH_CR2,#020h
    MOV FLASH_NCR2,#0DFh

    LD (X),A
    INCW X
    LD (X),A
    INCW X
    LD (X),A
    INCW X
    LD (X),A
    RET