News:

;) This forum is the property of Proton software developers

Main Menu

Accessing the High Endurance Flash Memory on a 12F1501

Started by kcsl, Jul 03, 2024, 09:31 PM

Previous topic - Next topic

kcsl

How do I access the HEF on the 12F1501 ?

The datasheet says the device has 128 bytes of HEF and if I'm reading the datasheet correctly, it runs from memory address 0380h to 03FFh.
Does this mean I can use CREAD and CWRITE within that address range to access it ?

I just want to check I can actually access this area and it works as NVR before I order a few chips to play with.

Regards,
Joe
There's no room for optimism in software or hardware engineering.

Stephen Moss

I don't know as I have never used it, as I recall the consensus of opinion is that it is difficult to use but a quick forum search for "HEF" revealed this little trick that may prove helpful. As it was written by Les it should work.

trastikata

I've never tried HEF specifically but since it is part of the common FLASH memory addressing it should be addressable and writable like the rest of the memory, except this addressing space will endure 100k instead of 10k or so write/erase cycles.

TimB

Unfortunately Cwrite will not work with this new type of memory (as far as I am aware)
I'm sure that Cread and Cdata has no issues though

However it's not too hard to code a routine to read and write to it yourself

Basics

Memory access is done by loading the address of the data you want into the PMADRH & PMADRL register pair. Then you set a few bits and the data for that memory location ends up in PMDATH & PMDATL

I wrote some code for a Pic12F1572 yesterday Its not properly commented but you are welcome to work off it


    ' Alais the reges as  vars for the address and Data
    Dim rPMAddress as Word at PMADRL
    Dim rPMData as word at PMdat





'---------------------------------------------------------------------------------------------------
' Unlock_Flash
' Input    : none
' Output    : None
' Notes    : TUnluck routine

    ' Routine to initiate reading / writting
    Proc Unlock_Flash()
        PMCON2 = 0x55
        PMCON2 = 0xAA
        PMCON1bits_WR = 1
        NOP
        NOP

    ENdProc


'---------------------------------------------------------------------------------------------------
' EraseFlashRow (the address as a word)
' Input    : Address
' Output    : None
' Notes    : The address needs to be at the start of the line

    Proc EraseFlashRow(pAddress as word)

        PMCON1bits_CFGS = 0
        PMCON1bits_FREE = 1
        PMCON1bits_WREN = 1
        rPMADDRESS = pAddress
        Unlock_Flash()

        PMCON1bits_WREN = 0

    EndProc



'---------------------------------------------------------------------------------------------------
' WriteWord (the address as a word, the data as a 14bit word)
' Input    : Address, Data
' Output    : None
' Notes    : The whole row is erased and 1 word (14bits)
'          : is saved, Address needs to be the start of a line

    Proc WriteWord(pAddress as word, pData as word)

        ' Erase the whole line first

        EraseFlashRow(pAddress)

        ' Tell the regs that data is to be saved
        PMCON1bits_CFGS = 0
        PMCON1bits_FREE = 0                                                    '
        PMCON1bits_WREN = 1

        PMCON1bits_LWLO = 1

        rPMAddress = pAddress
        rPMData = pData

        Unlock_Flash()

        ' This exact sequence may be not be 100% correct but it works
        PMCON1bits_LWLO = 0

        Unlock_Flash()
        PMCON1Bits_WREN = 0



    EndProc


'---------------------------------------------------------------------------------------------------
' ReadFlashWord (the address as a word 14bits), word
' Input    : Address
' Output    : The data as a word
' Notes    : The address can be anywhere in memory ( I think)

    Proc ReadFlashWord(pAddress), word
        PMCON1Bits_CFGS = 0
        rPMAddress = pAddress
        PMCON1Bits_RD = 1
        NOP
        NOP
        Result = rPMData
    endProc


TimB


Just a note

I think that CErase and CWrite may work

I looked at the code it produces and it looks right

As trastikata said use the section that is HEF if you are going to be writing to it a lot

JonW

I think the HEF is the same as the other stupid flash devices like the 16F153xx series.  See here for a 16F15376 library, which I think is a similar procedure but has 32 rows instead of 16 on the 1501..

To read, it's pretty straightforward, but for single-byte writes, you need to calculate the boundary, copy the entire row, erase the row, write to the latches and then initiate the flash write hardware.
 
You will need to adjust the boundary calls for 16 and the register names to access the latches and the addresses for the 1501.  It at least shows you the basic flow of what to do and should be quite simple to convert over.

TimB


In my code for a 12F1572 when I write to a location I write to one address. I am only interested in the 1 14bit word though
Reading the word back I just make one read

    Proc WriteThreshold(pThesholdVal as word)

        EraseFlashRow(cCurrentThrsholdAddrs)                                    ' Erase the rown the threshold is on

        PMCON1bits_CFGS = 0
        PMCON1bits_FREE = 0
        PMCON1bits_WREN = 1

        PMCON1bits_LWLO = 1

        rPMAddress = cCurrentThrsholdAddrs
        rPMData = pThesholdVal

        Unlock_Flash()

        PMCON1bits_LWLO = 0
        Unlock_Flash()
        PMCON1Bits_WREN = 0

    EndProc




    Proc GetCurrentThreshold(), word
        PMCON1Bits_CFGS = 0
        rPMAddress = cCurrentThrsholdAddrs
        PMCON1Bits_RD = 1
        NOP
        NOP
        Result = rPMData
    endProc