Preserving data for after a RESET command

hippy

Technical Support
Staff member
Here's an early Christmas present.

A neat trick for preserving data when a RESET command is executed and resetting that data to a known initial value when an actual power-cycle reset occurs. All without using EEPROM storage -

Code:
#Picaxe 08M2
#Terminal 4800
#No_Data

Symbol ADRESL = $3B ; $09B
Symbol ADRESH = $3C ; $09C

Symbol BORCON = $56 ; $116

PowerOnReset:
  Gosub LoadW0
  SerTxd( "Restarted: w0 = ", #w0, CR, LF )
  w0 = w0 + 1
  Gosub SaveW0
  Pause 1000
  Reset

LoadW0:
  PeekSfr BORCON, b0
  If bit6 = 0 Then
    SerTxd( "Power-On Reset", CR, LF )
    w0 = 0
  Else
    PeekSfr ADRESL, b0
    PeekSfr ADRESH, b1
    PokeSfr BORCON, $81
  End If
  Return

SaveW0:
  PokeSfr ADRESL, b0
  PokeSfr ADRESH, b1
  PokeSfr BORCON, $C1
  Return
Works for an 08M2, probably works for other M2's, and can likely be made to work with X2's with some changes. It has to be run on a physical chip as simulation does not fully simulate SFR registers.

It will likely start with a random value after a download but turning it off and on will get it doing what it's meant to.
 

PhilHornby

Senior Member
How does it work

A little explanation please...

I can see how the ADC result registers are being used to save data across a RESET, but how does the BORCON stuff work?

Specifically, how is it used to distinguish between a Power-On and a RESET ... I can't figure it out from the datasheet.

BORCON.png
 

hippy

Technical Support
Staff member
Specifically, how is it used to distinguish between a Power-On and a RESET ... I can't figure it out from the datasheet.
It was more serendipity than anything else.

What is needed is an SFR which has a readable and writeable bit guaranteed to be set or cleared at power-on, which isn't set or cleared when a RESET command is executed. Those bits are the ones labelled as "RW-1/u" and "RW-0/u".

BORCON is one of the few SFR's which has bits with those attributes and I couldn't predict any obvious misbehaviour caused in setting or clearing bit 6.

I put a "PEEKSFR BORCON,b0" in the code and looked at what its value was after a power-on which gave 129 ($81). I then poked $C1 to see if I could set bit 6 and have it persist past RESET and it worked, job done; so bit6 can distinguish between power-on or RESET command.

If it hadn't worked I would have had to experiment with other bits and it might have been 'game over' for the idea.

Interestingly, on the 28X2, it appears ADRESL and ADRESH are cleared to zero on a power-on, but not with a physical reset or a RESET command. I haven't exhaustively tested it but it seems the following does work ...

Code:
#Picaxe 28X2
#Terminal 9600
#No_Data

Symbol ADRESL = $C3
Symbol ADRESH = $C4

PowerOnReset:
  Gosub LoadW0
  SerTxd( "Restarted: w0 = ", #w0, CR, LF )
  w0 = w0 + 1
  Gosub SaveW0
  Pause 1000
  Reset

LoadW0:
  PeekSfr ADRESL, b0
  PeekSfr ADRESH, b1
  Return

SaveW0:
  PokeSfr ADRESL, b0
  PokeSfr ADRESH, b1
  Return
That should work on a 40X2 but have not tested it, nor on a 20X2.
 

geezer88

Senior Member
Are those registers subject to "wear out" like flash memory is? If not, this would be a simpler way to save data each cycle through a routine, instead of trying to get it saved before power is lost, along with the storage capacitors and the circuit complication that that brings.

tom
 

hippy

Technical Support
Staff member
Are those registers subject to "wear out" like flash memory is?
No; there's no wear out which is its big advantage over saving into EEPROM.

The data saved is not guaranteed to be there after a power-off. The need for being able to distinguish a power-on from a RESET is to get the data into an initial state rather than be something random.

If data needs to be saved for after a power-off, that will still need to be written to EEPROM and restored at power-on. However, the life of the EEPROM can be extended by only writing if the value hasn't been changed for a few seconds.

That's the sort of trick used to remember volume control settings on TV so you can wind volume up and down but it will only write to EPROM when you have stopped changing volume. Using an active high push button on C.3 -

Code:
#Picaxe 08M2
#Terminal 4800

Eeprom 0, (0,0)

Symbol ADRESL = $3B ; $09B
Symbol ADRESH = $3C ; $09C

Symbol BORCON = $56 ; $116

PowerOnReset:
  Gosub LoadW0
  SerTxd( "Restarted: w0 = ", #w0, CR, LF )
  time = 0

MainLoop:
  Do
    If pinC.3 = 1 Then
      w0 = w0 + 1
      Gosub SaveW0
      Do : Loop Until pinC.3 = 0
      Reset
    End If
    If time >= 5 Then
      Gosub SaveW0_ToEeprom
      time = 0
    End If
  Loop

LoadW0:
  PeekSfr BORCON, b0
  If bit6 = 0 Then
    SerTxd( "Power-On Reset", CR, LF )
    Gosub LoadW0_FromEeprom
  Else
    PeekSfr ADRESL, b0
    PeekSfr ADRESH, b1
    PokeSfr BORCON, $81
  End If
  Return

SaveW0:
  PokeSfr ADRESL, b0
  PokeSfr ADRESH, b1
  PokeSfr BORCON, $C1
  Return

LoadW0_FromEeprom:
  Read 0, b0
  Read 1, b1
  SerTxd( "Loaded from EEPROM = ", #w0, CR,LF )
  Return

SaveW0_ToEeprom:
  Read 0, b2
  Read 1, b3 
  If w1 <> w0 Then
    Write 0,b0
    Write 1,b1
    SerTxd( "Saved to EEPROM = ", #w0, CR,LF )
  End If
  Return
 
Top