News:

Let's find out together what makes a PIC Tick!

Main Menu

Still trying to use the HEF locations in 16F1705

Started by JohnB, Oct 02, 2023, 05:57 PM

Previous topic - Next topic

JohnB

I cannot find a way to get HEF access working with Positron.  What I have found so far...

Whilst HEData is a recognised keyword it isn't implemented at all, i.e HEData x,x,x just gets skipped when loading the program via Pickit as it thinks it is writing to non existent eeprom.

If I try and treat it like CData I cannot use the Org statement to set start location of the HEF area as I am using procedures and procedures need the compiler to be in control of memory.

Don't really know where to turn now, any suggestions?  Is the only way to revert to ASM?


JohnB

trastikata

Quote from: JohnB on Oct 02, 2023, 05:57 PMIf I try and treat it like CData I cannot use the Org statement to set start location of the HEF area as I am using procedures and procedures need the compiler to be in control of memory.

Don't really know where to turn now, any suggestions?  Is the only way to revert to ASM?

Hello John, I've re-posted somewhere how to use Org with procedures, I am not sure who but it was somebody here who gave me the correct solution. Try searching Procedures + Org.

JohnB

JohnB

JonW

Here is an include that I did for the 16F15376 on DIA and  DFM access.   It computes the page boundary for you to access an individual location.   It could easily be modified for other devices.  Can read from the DIA and write to any address in DFM, copying erasing etc

' P16F15376NVM.INC
'
'---------------
' CAN READ AND WRITE TO ANY SINGLE REGISTER IN THE DFM
' CAN READ THE DIA FOR CONSTANTS ETC
' EXAMPLE OF USE

' DATA = FLASHREAD(ADDRESS)          ' READS THE DFM AREA
' DATA = FLASHREADCFG(ADDRESS)       ' READS THE DIA AREA
' FLASHWRITE(ADDRESS, DATA)          ' WRITES TO A SINGLE LOCATION IN DFM

'----------------------------------------------------------------------------------------------
'----------------------------------------------------------------------------------------------
'NVMCONTROL

SYMBOL  NVMREGS    = NVMCON1.6            ' 1 = DIA, 0 = PFM
SYMBOL  NVMLWLO    = NVMCON1.5            ' LOAD WRITE LATCHES ONLY
SYMBOL  NVMFREE    = NVMCON1.4            ' PROGRAM FLASH MEMORY ERASE ENABLE
SYMBOL  NVMWRERR    = NVMCON1.3            ' PROGRAM/ERASE ERROR FLAG
SYMBOL  NVMWREN    = NVMCON1.2            ' PROGRAM/ERASE ENABLE BIT
SYMBOL  NVMWR      = NVMCON1.1            ' 1 = INITIATES A WRITE
SYMBOL  NVMRD      = NVMCON1.0            ' 1 = INITIATES A READ ON THE NEXT CYCLE

'NVM PROCS FOR 16F15376

(********************************************************************************************
* Title    :  FLASHREADMEM                                                                *
* Input    :  FLASH ADDRESS                                                                *
* Output    :  FLASH CONTENT                                                                *
* Notes    :  READS FLASH MEM                                                              *
********************************************************************************************)
Proc FLASHREAD(ADDR As WORD),WORD
      NVMREGS = 0                            ' POINT TO FLASH
      NVMADRL = ADDR.Byte0                    ' LOAD THE POINTERS
      NVMADRH = ADDR.Byte1
      NVMRD = 1                              ' START THE READ
      NOP
      RESULT.HIGHBYTE = NVMDATH              ' RETURN THE DATA
      RESULT.LOWBYTE = NVMDATL
      RESULT = RESULT & %0011111111111111
EndProc

(********************************************************************************************
* Title    :  READFLASHCFG  MMMMMM                                                        *
* Input    :  FLASH ADDRESS                                                                *
* Output    :  FLASH CONTENT                                                                *
* Notes    :  READS DIA (CONFIG) AREA                                                      *
********************************************************************************************)
Proc FLASHREADCFG(ADDR As WORD),WORD
      NVMREGS = 1                            ' POINT TO CONFIG
      NVMADRL = ADDR.Byte0                    ' LOAD THE POINTERS
      NVMADRH = ADDR.Byte1
      NVMRD = 1                              ' START THE READ
      NOP
      RESULT.HIGHBYTE = NVMDATH              ' RETURN THE DATA
      RESULT.LOWBYTE = NVMDATL
EndProc

(********************************************************************************************
* Title    :  UNLOCKDFM (UNLOCK THE DATA FLASH)                                            *
* Input    :  FLASH ADDRESS                                                                *
* Output    :  FLASH CONTENT                                                                *
* Notes    :  26/27K42                                                                    *
********************************************************************************************)
Proc UNLOCKDFM()
        NVMCON2 = $55                        ' Required Writes
        NVMCON2 = $AA                        ' Required Wrtits
        NVMWR = 1                            ' Set WRITE CONTROL BIT
        NOP
        NOP
EndProc

(********************************************************************************************
* Title    :  FLASHWRITE                                                                  *
* Input    :  FLASH ADDRESS, BYTE TO WRITE                                                *
* Output    :  NONE                                                                        *
* Notes    :  UPDATE 1 BYTE IN DFM (CAN WRITE TO ANY LOCATION)                            *
*********************************************************************************************)
Proc FLASHWRITE(ADDR As WORD, B2LOAD As WORD)

    Dim b_ROWs          As word              ' NEED A TEMPORY BYTE TO STORE THE ADDR.BYTE0
    DIM b_BYTE          as byte
    DIM b_LDL1          as byte
    Dim b_FLASH[32]    as word

    B_ROWs = (ADDR/32)                      ' GET THE 32 BYTE BOUNDARY ROW
    b_rows = b_rows * 32                    ' GET START ADDRESS
    b_byte = addr - (b_rows)                ' GET BYTE INDEX TO REPLACE


    FOR B_LDL1 = 0 to 31                    ' READ FLASH INTO RAM
        B_FLASH[B_LDL1] = FLASHREAD(B_ROWs + B_LDL1)
    Next

    B_FLASH[B_BYTE] = B2LOAD                ' UPDATE THE BYTE TO CHANGE

    ERASEROW(B_ROWs)                        ' ERASE THE 32 BYTE BLOCK (ROW)

    FOR B_LDL1 = 0 to 30                    ' RELOAD LATCHES
        LOADLATCH(B_ROWS,B_FLASH[B_LDL1],1)
        INC B_ROWS
    Next
        LOADLATCH(B_ROWS,B_FLASH[31],0)      ' FINAL LATCH AND WRITE
    WHILE NVMWR = 1:Wend                    ' WAIT FOR WRITE TO OCCUR IF IN A FAST LOOP
    NVMWREN = 0                              ' DISABLE WRITES
EndProc

(********************************************************************************************
* Title    :  LOADLATCH                                                                    *
* Input    :  FLASH ADDRESS, WORD TO LOAD, LATCH OR WRITE                                  *
* Output    :  NONE                                                                        *
* Notes    :  UPDATE 1 BYTE IN DFM (CAN WRITE TO ANY LOCATION)                            *
*********************************************************************************************)
proc LOADLATCH(ADDR AS WORD,DATA AS WORD, LATCH AS BIT)
        dim  b_GIESTORE AS BIT

        b_GIESTORE = INTCON.7
        NVMDATH = DATA.HIGHBYTE
        NVMDATL = DATA.LOWBYTE
        NVMADRH = ADDR.HIGHBYTE
        NVMADRL = ADDR.LOWBYTE

        NVMREGS = 0
        NVMLWLO = LATCH
        NVMFREE = 0
        NVMWREN = 1
        NOP
        UNLOCKDFM()
        INTCON.7 = b_GIESTORE    ' RETURN INT STATUS
EndProc

(********************************************************************************************
* Title    :  ERASEROW                                                                    *
* Input    :  FLASH ADDRESS                                                                *
* Output    :  NONE                                                                        *
* Notes    :  ERASES 32BYTE ROW AT ADDR                                                    *
*********************************************************************************************)
Proc  ERASEROW(ADDR As word)  ' KEEP THIS PROC SEPERATE SO WE CAN ERASE ANY 64-BYTE BLOCK

      NVMADRL = ADDR.Byte0
      NVMADRH = ADDR.Byte1

      NVMREGS = 0              ' ACCESS FLASH MEMORY
      NVMWREN = 1              ' ENABLE WRITE TO MEM
      NVMFREE = 1              ' ERASE BLOCK
      UNLOCKDFM()              ' UNLOCK DFM
      Nop                      ' REQUIRED
      WHILE NVMFREE = 1:WEND
      NVMWREN = 0              ' DISABLE WRITE TO MEM

EndProc


To use just add the include and one of the following.  Remember that this is using 14bits so is good for ADC or PWM storage. 


Include "DFM.inc"

Dim DATA as Word                  '  Can access the full 14 bit contents
DIM ADDRESS as Word           '  Address to read or write from


DATA = FLASHREAD(ADDRESS)               ' READS THE DFM AREA
DATA = FLASHREADCFG(ADDRESS)        ' READS THE DIA AREA
FLASHWRITE(ADDRESS, DATA)               ' WRITES TO A SINGLE LOCATION IN DFM

just noticed that I have b_xxx and should have been w_xxx in a word var.  Still compiles ok

for some reason with the new update DATA is not allowed so rename DAT or something similar

JohnB

JohnB

top204

#5
I gave up making the HEF flash memory area into commands for the compiler because microchip could not make their mind up as to how it works, and their block erase and writes is utter stupidity when you compare it to the original flash memory devices of 20 years ago, where an individual word (14-bit or 16-bit) could be erased or written, as can be done with EEPROM, which is still a flash memory mechanism.

I did post a thread about using the EData mechanism as HEF data, and then the compiler's EEPROM commmands can be adapted, but each device has different methods and sizes, so it is just as silly as the erasing and writing with normal flash memory. There is no fixed size or mechanism and some require a large lump of RAM just to store a block when a single word is being written!

This should have all taken place inside the microcontroller's core, so a single piece of data could be erased or written and the microcontroller contain scratch RAM for it, invisibly. It was intended to replace on-board EEPROM, but that has failed dismally, and a lot of newer device now have EEPROM again.


GaryC

EEprom was easy and worked well, as the old saying goes "Just because you can do it doesn't mean you should".

I am glad to see it back again.
Gary