Sunday 9 July 2023

Enabling the Super-Cap on the MEGA65 R4 PCB

The MEGA65 R4 PCB uses a different RTC chip than on the old R3A board.  The R4 uses a newer chip, the RTC-RV-3032-C7. This chip uses less power, so a battery will last longer.  Also, it supports the use of a "super capacitor", if you don't have a battery, and the MEGA65 R4 board is designed to use such an arrangement (it also has a socket for a CR2032 battery as well).


 

We already have the new RTC chip working on the R4, and you can set the time and date on it, without problem. But what we have not yet implemented is enabling the super capacitor.  This requires setting an EEPROM register that enables the charge pump to the super capacitor, and selecting the voltage and current for this.

This is all done using the Power Management Unit (PMU), which is configured in register $C0.  We have this accessible via $FFD71D0 on the R4 board.  The only problem is, writing to it doesn't seem to have any effect. So I need to investigate this.

The datasheet can be found here.

Page 72 of the datasheet explains the correct process for changing this register:

Edit the Configuration settings (example, when write protection is enabled (EEPWE = 255)):
1. Enter the correct password PW (PW = EEPW) to unlock write protection
2. Disable automatic refresh by setting EERD = 1
3. Edit Configuration settings in registers C0h to C5h (RAM)
4. Update EEPROM (all Configuration RAM EEPROM) by setting EECMD = 11h
5. Enable automatic refresh by setting EERD = 0
6. Enter an incorrect password PW (PW ≠ EEPW) to lock the device

We don't have write protection enabled, so far as I am aware. So we need to set the EERD bit, which is in bit 2 of register $10, which is mapped at $FFD7120, update the value, then write $11 into the EECMD register, which is register $3F, which is mapped at $FFD714F.

So let's try that.

Hmm... Setting $FFD7120 doesn't seem to work.  I've just double-checked the VHDL, and it looks like all the registers should be writeable. But now that I am testing it, I am finding that none of the registers are writeable. But I'm pretty sure I had them writeable in the past -- at least the ones for the time and date.  I did have to adjust the register writing code when I added support for writing to higher-numbered registers, so it's possible I have messed something up.

Now I need to go back in time and find where this problem came in, so that I can confirm this theory. This requires doing some POKE and PEEKs using about 100 different bitstream versions.  So I really want to automate this.  So here's the crazy shell script I wrote to do this for me:

#!/bin/tcsh -fx

foreach bit ( `ls -1t bin/mega65r4*.bit` )
  echo $bit
  m65 -b $bit
  sleep 4
  m65 -r rtctest.prg
  sleep 2
  monitor_save -a 0800:0802 foop
  hexdump -C foop | cut -c11-18 > foop2
  set len=`gzip < foop2 | wc -c`
  if ( $len != 27 ) then
    echo "Bingo! $bit"
    set userinput=$<
  endif
end

This basically loads each bitstream, then loads a little BASIC program that tries to set and read back the seconds value of the RTC in $FFD7110.  It also copies the initial value from $FFD7110 to $0800, and then the PEEK of $FFD7110 after writing to different values to it to $0801 and $0802.  If the RTC register writing is working, then at least two of those results will be different.  I couldn't be bothered writing a program to compare those three numbers, so I just used a fun hack I know: Check if the compressed size is different to if it contains 3 identical numbers. 

So with this ugly little script, I have it automatically testing a bunch of bitstreams while I write this blog.  Hopefully it will pick one up soon. If it doesn't, then I have to assume that writing to the RTC has never worked -- or that it is write-protected or something like that.

Hmm.. it's tried bitstreams all the way back to mid-March (its late-June now), with no luck. So I am beginning to suspect that I might have enabled some write-protect kind of thing.

The process of unlocking the write-protect is listed here on page 114 of the datasheet:

4.22.1. ENABLE/DISABLE WRITE PROTECTION
If the write protection function is enabled by writing 255 in register EEPWE (EEPROM CAh), it remains possible to
read all the registers except the EEPROM registers. The EEPROM registers cannot be read because it cannot be
written to the EE Address and EE Command registers. If the function is not enabled, read and write are possible for
all corresponding registers.
If the write protection function is enabled, it is necessary to first write the correct 32-Bit Password PW (PW = EEPW)
(Unlock), before any attempt to write in the RAM registers and to read and write in the EEPROM registers.
Once the user is finished with the write access and subsequently the write protection is still enabled or enabled again
(by writing 255 in EEPROM register EEPWE), it is necessary to write an incorrect password (PW ≠ EEPW) into the
Password PW registers in order to write-protect (Lock) the registers. See program sequences below and
FLOWCHART.
Enable write protection:
1. Initial state (POR): WP-Registers are Not write-protected (EEPWE ≠ 255)
Reference password is stored in the RAM mirror of EEPW (addrs C6h to C9h)
2. Disable automatic refresh by setting EERD = 1
3. Enable password function by entering EEPWE = 255 (RAM mirror address CAh)
4. Enter the correct password PW (PW = EEPW) to unlock write protection (RAM addresses 39h to 3Ch)
5. Update EEPROM (all Configuration RAM  EEPROM) by writing 11h to EECMD
6. Enable automatic refresh by setting EERD = 0
7. Enter an incorrect password PW (PW ≠ EEPW) to lock the device (RAM addresses 39h to 3Ch)
8. Final state: WP-Registers are Write-protected by password (EEPWE = 255)

Disable write protection:
1. Initial state (POR): WP-Registers are Write-protected by password (EEPWE = 255)
Reference password is stored in the RAM mirror of EEPW (addrs C6h to C9h)
2. Enter the correct password PW (PW = EEPW) to unlock write protection (RAM addresses 39h to 3Ch)
3. Disable automatic refresh by setting EERD = 1
4. Disable password function by entering EEPWE ≠ 255) (RAM mirror address CAh)
5. Update EEPROM (all Configuration RAM  EEPROM) by writing 11h to EECMD
6. Enable automatic refresh by setting EERD = 0
7. Final state: WP-Registers are Not write-protected (EEPWE ≠ 255)

This sounds quite feasible to be the issue here.

After rebuilding a bitstream that fixed an unrelated bug preventing writing to registers on the RTC, I have been able to confirm that this procedure for un-write-protecting the RTC registers works:

10 A=$FFD7110
20 POKE A + $39, ASC("E")
30 POKE A + $3A, ASC("E")
40 POKE A + $3B, ASC("P")
50 POKE A + $3C, ASC("W")

Does indeed disable write-protection of the registers temporarily, allowing me to set the RTC time and date registers. (I believe I probably accidentally enabled write protection at some point.)

So next step is to update the EEPROM configuration registers. After some fiddling about, the following program seems to be able to set the PMU register for me:

   5 W=0.01
   10 A=$FFD7110
   15 SLEEP W
   20 POKEA+$39,ASC("E")
   25 SLEEP W
   30 POKEA+$3A,ASC("E")
   35 SLEEP W
   40 POKEA+$3B,ASC("P")
   45 SLEEP W
   50 POKEA+$3C,ASC("W")
   55 SLEEP W
   60 POKEA+$10,4:REM DISABLE EEPROM SHADOW RAM AUTO-REFRESH
   65 SLEEP W
   70 POKEA+$CA,0:REM DISABLE WRITE-PROTECT
   75 SLEEP W
   80 POKEA+$C0,$13:REM ENABLE TRICKLE-CHARGE OF SUPER CAP
   85 SLEEP W
   90 POKEA+$3F,$11: REM UPDATE EEPROM FROM SHADOW RAM
   95 SLEEP W
  110 POKEA+$10,0:REM RE-ENABLE EEPROM SHADOW RAM AUTO-REFRESH
  115 SLEEP W
  120 IFPEEK(A+$C0)=$13THEN PRINT "SUPER CAP CHARGING ENABLED"
  130 IFPEEK(A+$C0)<>$13THEN PRINT "SUPER CAP NOT ENABLED"

The SLEEP statements are to ensure the I2C memory mapping system of the MEGA65 has time to commit each write, before attempting the next. So if you ignore those, we see that I enter the default RTC password of EEPW, then stop the EEPROM shadow ram reading, so that I can modify the shadow RAM contents for the EEPROM registers, then I set the trickle-charge settings in the PMU register ($13 into register $C0), write it to the EEPROM, and then tidy up after ourselves.  Finally, I read from the EEPROM shadow RAM to confirm that our setting has taken effect.

Running it takes only a second or so, and then we see something like this:


Great -- so assuming I have correctly understood the settings to charge the super-capacitor, and that it all actually works, my super capacitor should now be being charged. This means, I should be able to turn the power off to the MEGA65 R4 board for a while (I purposely have no battery installed), and it should still retain the time and date. 

What I don't know, is how long it will take for the super-cap to charge up enough to work. Also, I don't know if I have really put the right settings into the PMU register to use the super-cap.  So while I give the super-cap some time to charge up, let's take a look at the PMU register bits and related things.

First, you can tell if the RTC lost power on boot, by checking bit 1 of $FFD711D. If set, then the RTC didn't have power. This can be cleared by writing to it, e.g., POKE $FFD711D,0.  

Okay, so I have done that. Let's power cycle, and see if it gets asserted still. But first, I think I'll flash this fixed bitstream for the MEGA65 R4 board, so that I don't have to keep loading it on power on.

Done. I've also read through the datasheet for the RTC, and it looks like putting either $13 or $23 into the PMU register should work. The difference between the two values affects only the way that it detects when to switch to backup power (level switching or direct switching modes). So far, neither seems to be effective, which makes me think that something is not allowing the capacitor to charge. I might need to pull the board out of the case, so that I can get to the pins of the super capacitor, and see what the voltage there is doing. 

Looking at the schematic, there are no components between the super capacitor and the RTC, so there doesn't seem to be any possibility for something outside of the RTC or super capacitor to be the problem. The RTC is ticking, so I am assuming either the super capacitor is dead (unlikely) or that I am somehow not programming it correctly (more likely).  So let's see if it is charging, then...

I've pulled the board out, and see 0.39V on the super capacitor. After a minute or so, it climbed to 0.40V. It's climbing by about 0.02V per minute. So this means that I probably do have it all setup correctly, and that it will just take a lot longer than I had originally anticipated for the super cap to get to a usable voltage (about 2V).  It should take about another 1 - 2 hours to climb to that level, so I'll leave it charging for a while and do some other stuff, and then come back to it and see if it has charged enough to keep time.

Yes, that was all it needed -- enough time to charge the capacitor enough to reach the voltage required by the RTC chip.  Based on this, I'd recommend leaving a MEGA65 R4 on all day or over-night to put enough initial charge into the super capacitor to allow the RTC to keep time.  

The next logical question is how long it can hold the time for when powered off.  To get an idea of this, I've just turned the machine off, and recorded 2.45V on the super capacitor at 14:15.  I'll check the voltage again in a couple of hours, and see how much it as dropped. From that, we should be able to come up with a fairly decent estimate of the RTC retention time when using just the super capacitor. After 121 minutes, it is down to 2.32V. This means ~(2.54 - 2.32 / 2) V / hour, i.e., about 0.11V / hour. Assuming fully charged will be around 4.5V, and the minimum viable voltage is 2V, 2.5V / 0.11V/hour = ~20 hours -- assuming that the charge consumption is constant regardless of voltage, which may not be the case.

Anyway, I'll set it charging overnight, so that I can see what the actual maximum voltage is, and then see how long that voltage takes to decay. The datasheet suggests "days to weeks" when using a super capacitor -- but without indicating the capacity of super capacitor that this range corresponds to.  My gut feeling is that the super capacitor will provide at most a few days, based on the data so far -- but we will see when I have fully charged it ...

So overnight it charged up to 4.40V. I am now going to let it discharge for a while, and see if it still drops at 0.11V / hour from full, or if its a bit slower.  Power turned off to the MEGA65 R4 board at 12:41 on Sunday. I'll take some measurments whenever I come by my office and remember:

Sunday 13:21 - 4.39V

Sunday 14:31 - 4.38V

Sunday 15:36 - 4.37V

Sunday 16:54 - 4.35V

Sunday 05:48 - 4.27V

Monday 17:23 - 4.22V

Tuesday 17:21 - 4.14V

At this rage, 0.08V/day, and a critical voltage of 2V, this suggests it might last 30 days.  Will keep an eye on it over coming days...

Friday 21:02 -- 3.94V

Well, its still continuing at 0.08V per day, which is pretty good.  It's now close to a week since I turned it off, and it has a lot more time to go before it goes flat.

Tuesday 20:29 -- 3.74V

Yup, continuing at about that rate. After 9.5 days, it's gone from 4.40V to 3.74V = ~0.07V/day average over the full time.  I'll leave it running a few more days yet...

Sunday 19:20 - 3.55V

So that's just over 15 days, with a drop of 4.40V - 3.35V = 0.06V / day on average. Given the critival voltage of ~2V, this is pointing to a maximum retension without power of 4.4V - 2V = 2.4V / 0.06V / day = 40 days. I'd allow some safety margin on that, and say that 3 to 4 weeks should be a reasonable bet.  

Anyway, that's more than enough to confirm that the supercap works.

No comments:

Post a Comment