So I decided that I’d like to add a real-time clock (RTC) to the Zolatron project because … why not?
Should be easy, I thought. Lots of people have done it. All I need is the right chip. Maybe that’s where I made my mistake.
As it turned out, for some reason, I already own three copies of the Microchip MCP795W20. Why I have these and how long I’ve had them are mysteries to me, but there you are. I must have had this idea a while back and then put it on the back burner. I say that because these chips use an SPI interface, whereas I’d normally choose I2C devices for use with microcontrollers.
SPI has the advantage over I2C of being much easier to bit-bang.
Initially, I figured I’d be talking to the RTC chip through a 6522 VIA I/O chip. But it turns out there’s an easier way. Daryl Rictor’s 65SPI project lets you use a CPLD to make interfacing with devices even easier and less taxing on CPU resources.
So far so good.
However, I was facing a slightly complex situation. I’d be using a CPLD device for the first time, an RTC chip for the first time and my own new 6502 assembly code. What could go wrong? Everything – and in impossible-to-diagnose ways. So I chose to tackle this in steps.
To the breadboards!
Breadboards were invented for a reason, and that reason is prototyping. The MCP795 chip isn’t exactly breadboard-friendly, being in SOIC-14 format SMD. So I soldered it to a converter board that effectively turned it into a DIP-14 format.
I figured I’d control the thing from a microcontroller (a Teensy 3.2 in this case) because that’s a familiar environment for me. And as the idea was to learn how to use this chip with the ultimate aim of converting to 6502 assembly, I chose not to use any libraries for the SPI routines, but to bit-bang all the code.
The chip requires a couple of supporting components. First it needs a 32.768KHz crystal, which gets attached across the X1 and X2 pins. Each of these pins is also connected to GND via low-value capacitors – the typical values I found were 12pF and 10pF. And for basic use there’s not much else to do. Connect the relevant pins to the clock (SCK), PICO (Peripheral In Controller Out, formerly known as MOSI and SI on the MCP795 chip), POCI (aka MISO/SO) and chip select (/CS) pins on the microcontroller and you’re up and running. I tied the /WDO and /IRQ lines on the MCP798 to VCC as I’m not using them. I ignored the CLKOUT, EVHS and EVLS pins as these are outputs for functions of the chip I’m not currently exploiting.
Then I wrote some code and … well, it worked up to a point.
I found I could write to registers and the values would be suitably stored. And I could read from registers and get values I sort-of expected. Except when it came to the time functions – which is unfortunate as that’s the chip’s one job as far as I’m concerned.
I could read a time from the counter registers, but they never incremented. The clock wasn’t ticking.
RTFM
Okay, when things don’t go according to plan, read the datasheet. I found that there’s a ‘Start Timer’ bit that needs to be set in order to kickstart the counters. So I did that. No joy.
Fine. Register 0x04 (the ‘Day’ register) includes a bit set by the chip that tells you if the oscillator is running. And no it wasn’t. But the datasheet is unhelpful as to why that might be. That meant it was time for the last resort of all tinkerers – to the interwebs!
And while I couldn’t find much about the MCP795 that was helpful – and nothing about this specific problem, I did find a forum thread about RTCs that talked about how oscillators are reluctant to start if there’s too much capacitance.
Well, the one thing we all know about breadboards is that they are awash with stray capacitance. On a whim, I removed the two capacitors connected to the crystal – and the clock started running! Yay!
And, you know, it sort of seems to be working okay, Except…
Battery power
I want this to be a battery-backed RTC, so that I don’t have to set the time and date each time I boot the machine (remember that, early PC fans?).
The MCP795 is very clever. It allows you to attach a backup battery (typically 3V) and will not only switch to it if the main VCC supply goes away, but will also keep a note of this having happened and even a timestamp of when it happened.
So I connected a CR2032 cell to the VBAT pin and… the clock started running fast. Very fast. About twice the speed it should. If I remove the battery it goes back to normal. But with the battery connected, something weird is happening. The chip has registers that allow you to calibrate the timekeeping, but even at maximum values this isn’t enough to slow the real-time clock to real time.
Where next?
And that’s where I’m at right now – with the MCP795W20 kicking my ass.
The chip is obviously very sensitive and needs exactly the right circuit conditions. The datasheet, for example, says that the crystal should have a capacitance of 6-9pF, and that bad things might happen if you use a 12.5pF device. But my crystal was bought via eBay with very little in the way of specs. (I’ve since ordered a 7pF device from Mouser).
Then there’s the matter of the capacitors that should connect the crystal to ground. The datasheet basically tells you to work out what values to use, but the calculation involves values I don’t know, such as the stray capacitance. Putting back the 10pF and 12pF caps I originally used still stops the clock. So I’m thinking capacitance is a big issue here. Maybe I could play with lower values.
I’m going to make up a stripboard version of the circuit, to see if that’s a more stable environment than the breadboard. And I’ve already designed a PCB and – funds allowing – may spin that up.
In the meantime, I’ve ordered two more RTC chips to see if they are any easier to deploy.
It’s not that I need an RTC. I’m just having fun playing.
If you want more info on how to use the registers of the MCP795, or more info on bit-banging SPI on microcontrollers, let me know.
[UPDATE 27/07/2023]: A small, nagging voice in my brain has been on at me to check the values of the load capacitors I’d tried attaching to the crystal. I’d partly made up this breadboard circuit some time ago, apparently, and the ‘today’ me just assumed that the ‘then’ me had chosen the right values.
That voice got louder when I was taking a look at my box of THT caps and found I only had 22pF caps in the pico range. Uh-oh.
So I looked at the caps and … well, it turned out they had ‘106’ printed on them, which meant they were 10µF caps. That’s six orders of magnitude too large. No wonder I was having a problem with excess capacitance. FFS.
I’ve ordered some suitable caps and will update, or make a new post, when I’ve tested them.
In the meantime, I’ve used 22pF caps (because I have them). These are out of spec, but at least within spitting range of it. With no calibration set and the battery plugged in, the damn thing seems to be keeping reasonable time now. I’ve set it to the current time and will check how much it drifts.
So, my apologies to the MCP795 for calling it finicky.
Lesson learned: Check your own work. Don’t make assumptions.
Excuse: I’ve had a bit of a break from electronics and my processes are rusty.
[UPDATE Later the same day]: I spoke too soon. It’s back to the previous behaviour – running too fast. –=sigh=– One of the reasons I like the MCP795W20 is that it’s (if you’ll pardon me) cheap as chips. I’m starting to understand why.
Changes:
s/Micrcship/Microchip/
s/I2C/I²C/g
s/MOSI/COPI/g s/MISO/CIPO/g
Comments: I would have thought mounting the crystal and its two caps actually on the SMD to DIP breakout board would be a more reliable, robust, and low noise solution. Obviously you would have to cut the tracks to the DIP pins as well.
Maybe consider using the DS3231 module instead. Much simpler and completely self contained.
Cheers, Brian.
I have a DS3234 on order. As for the changes – I made the first one. The I2C one is, I think, a tad pedantic and I2C is easier to type. Are COPI and CIPO now standardised? I think they can be confusing as there are so many devices and datasheets out there still using the old (though admittedly problematic) MOSI and MISO.
Hmm, it seems the Open Source Hardware Association has changed its mind about SPI signal names. It now recommends SDO instead of MOSI and SDI in place of MISO. Personally, I think that’s confusing as whether the data is coming in or going out depends on which device you’re looking at. For example, with the RTC chip here, you’d connect the SDO line to the DI pin. (I guess we already have this kind of deal with TX and RX serial signals, but we all know that causes endless heartaches.) It also suggests POCI for MISO and PICO for MOSI where devices can be controller or peripheral. I don’t know why it ditched COPI and CIPO which are far more sensible IMHO, as they match the patterns of the originals. But anyway, PICO and POCI it’s going to be.