• AVR Freaks

Hot!PIC18F Help needed Understanding WRITING TO PROGRAM FLASH MEMORY

Author
tonycarbon
New Member
  • Total Posts : 5
  • Reward points : 0
  • Joined: 2020/01/14 03:00:13
  • Location: 0
  • Status: offline
2020/01/25 15:04:35 (permalink)
0

PIC18F Help needed Understanding WRITING TO PROGRAM FLASH MEMORY

Hello
 
I am working on some Assembler code for a PIC18F27K42, which needs
to write to Program Flash Memory.
 
I have read, re-read, and read again the EXAMPLE 11-4 on PAGE 131 of the
PIC1827K42 data sheet, and just about understand the idea that data held in
a ram buffer, is stored in a TABLE, which is then writen to Program Flash Memory.
I understand the smallest block erase is 64 bytes, and I have this part working
ok in my code.
 
But I dont quite understand the example, where the data is written from the
TABLE to program memory.
The Branch "BRA    WRITE_WORD_TO_HREGS" that appears in the data read loop
before the label "PROGRAM_MEMORY" doesnt make sense to me, the label does not
exist anywhere in the code example.
 
Also how does the "PROGRAM_MEMORY" code section know the address to write, as
the TBLPTR address is not reset to the correct location after being incremented in
the "WRITE_BYTE_TO_HREGS" loop.
 
Any help greatly appreciated.
 
Here is a link to the data sheet
http://ww1.microchip.com/downloads/en/DeviceDoc/PIC18LF26-27-45-46-47-55-56-57K42-Data-Sheet-40001919E.pdf
Here is the code from the data-sheet [ painfully copied from the PDF ]
 

    MOVLW    D'64’                    ; number of bytes in erase block        
    MOVWF    COUNTER            
    MOVLW    BUFFER_ADDR_HIGH        ; point to buffer        
    MOVWF    FSR0H            
    MOVLW    BUFFER_ADDR_LOW            
    MOVWF    FSR0L            
    MOVLW    CODE_ADDR_UPPER            ; Load TBLPTR with the base        
    MOVWF    TBLPTRU                    ; address of the memory block        
    MOVLW    CODE_ADDR_HIGH            
    MOVWF    TBLPTRH            
    MOVLW    CODE_ADDR_LOW            
    MOVWF    TBLPTRL            

READ_BLOCK                    
    TBLRD*+                        ; read into TABLAT, and inc        
    MOVFTABLAT, W            ; get data        
    MOVWF    POSTINC0            ; store data        
    DECFSZ    COUNTER                ; done?        
    BRA         READ_BLOCK                ; repeat        
MODIFY_WORD                    
    MOVLW    BUFFER_ADDR_HIGH    ; point to buffer        
    MOVWF    FSR0H            
    MOVLW    BUFFER_ADDR_LOW            
    MOVWF    FSR0L            
    MOVLW    NEW_DATA_LOW        ; update buffer word        
    MOVWF    POSTINC0            
    MOVLW    NEW_DATA_HIGH            
    MOVWF    INDF0            
ERASE_BLOCK                    
    MOVLW    CODE_ADDR_UPPER        ; load TBLPTR with the base        
    MOVWF    TBLPTRU                ; address of the memory block        
    MOVLW    CODE_ADDR_HIGH            
    MOVWF    TBLPTRH            
    MOVLW    CODE_ADDR_LOW            
    MOVWF    TBLPTRL            
    BCF         NVMCON1, REG0        ; point to Program Flash        
    BSF         NVMCON1, REG1        ; point to Program Flash        
    BSF         NVMCON1, WREN        ; enable write to memory        
    BSF         NVMCON1, FREE        ; enable Erase operation        
    BCF         INTCON0, GIE        ; disable interrupts        
    MOVLW    55h                    ; next four instructions        
    MOVWF    NVMCON2                ; write 55h        
    MOVLW    AAh            
    MOVWF    NVMCON2                ; write 0AAh        
    BSF         NVMCON1, WR            ; start erase (CPU stall)        
    BSF         INTCON0, GIE        ; re-enable interrupts        
    TBLRD*-                        ; dummy read decrement        
    MOVLW    BUFFER_ADDR_HIGH    ; point to buffer        
    MOVWF    FSR0H            
    MOVLW    BUFFER_ADDR_LOW            
    MOVWF    FSR0L            
WRITE_BUFFER_BACK                    
    MOVLW    BlockSize            ; number of bytes in holding register        
    MOVWF    COUNTER            
    MOVLW    D’64’/BlockSize        ; number of write blocks in 64 bytes        
    MOVWF    COUNTER2
    
WRITE_BYTE_TO_HREGS                    
    MOVF       POSTINC0, W            ; get low byte of buffer data        
    MOVWF    TABLAT                ; present data to table latch        
    TBLWT+*                        ; write data, perform a short write        
                                ; to internal TBLWT holding register.        
    DECFSZ    COUNTER                ; loop until holding registers are full        
    BRA          WRITE_WORD_TO_HREGS            
PROGRAM_MEMORY                    
    BCF          NVMCON1, REG0        ; point to Program Flash Memory            
    BSF          NVMCON1, REG1        ; point to Program Flash Memory
    BSF          NVMCON1, WREN        ; enable write to memory
    BCF          NVMCON1, FREE        ; enable write to memory
    BCF          INTCON0, GIE
    MOVLW     55h                    ; write 55h
    MOVWF     NVMCON2
    MOVLW     0AAh                ; write 0AAh
    MOVWF     NVMCON2
    BSF          NVMCON1, WR            ; start program (CPU stall)
    DCFSZ      COUNTER2            ; repeat for remaining write blocks
    BRA          WRITE_BYTE_TO_HREGS
    BSF          INTCON0, GIE        ; re-enable interrupts
    BCF          NVMCON1, WREN        ; disable write to memory

 
 
 
#1

2 Replies Related Threads

    ric
    Super Member
    • Total Posts : 25592
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: PIC18F Help needed Understanding WRITING TO PROGRAM FLASH MEMORY 2020/01/25 16:22:37 (permalink)
    0
    tonycarbon
    ...
    The Branch "BRA    WRITE_WORD_TO_HREGS" that appears in the data read loop
    before the label "PROGRAM_MEMORY" doesnt make sense to me, the label does not
    exist anywhere in the code example.

    Must be a typo.
    It looks to me like that should branch back to WRITE_BYTE_TO_HREGS
     

    Also how does the "PROGRAM_MEMORY" code section know the address to write, as
    the TBLPTR address is not reset to the correct location after being incremented in
    the "WRITE_BYTE_TO_HREGS" loop.

    TBLPTR itself contains the address to write to. It always points to the last address to be written when the actual write operation happens.
     
    Note it is set to the first address in program memory of the block to erase during the erase operation,
    then it is pre-incremented before entering the program loop, which uses a "increment then write" form of the "table write" function (TBLWT+*)
     
    So, TBLPTR will increment through the correct program memory addresses to be written as you proceed through writing the blocks.
     

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #2
    tonycarbon
    New Member
    • Total Posts : 5
    • Reward points : 0
    • Joined: 2020/01/14 03:00:13
    • Location: 0
    • Status: offline
    Re: PIC18F Help needed Understanding WRITING TO PROGRAM FLASH MEMORY 2020/01/26 07:32:22 (permalink)
    0
    Hi Ric.
     
     
    Thanks very much for the reply.
     
    It makes sense that the 'BRA    WRITE_WORD_TO_HREGS' line is a type mistake, thanks for confirming that.
    Also another typo on the line "DCFSZ      COUNTER2 "
     
    Also thanks for explaining the TBLPTR address stuff, it makes a lot more sense know.
    I know see that the lower 5 LSBs are used for reading in the data, so do not affect the
    base address for the RAM write [ as the data is always in blocks of 64 bytes ]
    So no need to reset the address before the RAM write.
     
    Thanks again.
    TC
    #3
    Jump to:
    © 2020 APG vNext Commercial Version 4.5