I was looking over my reading and writing routines.
Minimums for the fram are
Clock high min. 28ns
Clock low min. 28ns
Data setup min 5ns
I write in two places:
First, when bits are coming in from the drive, and the ISR writes it out bit by bit. I doublechecked that routine. Clock low time is 60ns, data setup time is 20ns, and high time is a lot longer.
Second, in the subroutine SENDFRAM, we are low for 80ns, datasetup time is 20ns, and high time is 60ns.
The fram reads the serial input on the rising edge of SCK.
I only have one read routine, called RECVFRAM
This routine was screwed up but still seemed to work OK. I was reading the data after doing a SETB SCK and a single NOP, but “outputs are driven from the falling edge of SCK.” So I was actually one bit behind, with the first bit being unknown.
I was doing this:
SETB SCK
READ THE PORT
CLRB SCK
REPEAT
But instead, I should be doing:
SETB SCK (and wait for 40ns high)
CLRB SCK (and wait 40ns, so Todv aka Output Data Valid Time is satisfied)
READ THE PORT
REPEAT
Off the top of my head, I’m not sure how exactly this would affect me, besides the first bit being garbage.
So I fixed my RECVFRAM routine, slightly different from above.
Turns out that the read FRAM opcode puts the first bit on the wire, so you have to do this:
read the port
setb sck (and wait)
clrb sck (and wait)
repeat
Easy enough, I tested it, and while I haven’t seen any results with the improvement — this section of code is now properly written and works the way I have intended it to.
I also put a small checksum (using ADDB instruction) on the memory writes and compared them to the memory reads. They are matching, so my write and read memory routines are working perfectly. I also have a checksum on the memory to PC link, so there are no errors occuring there.