I cleaned up some of the CRC generation design but was still testing as of the end of lunch today. I first have to reconcile what I am seeing - to generate the same CRC value as I am retrieving from the disk - before I am sure that the generation logic is sound.
After quite a bit of struggling, I realized that somehow they injected the sync byte into the CRC generator. If I start with just the header fields (two bytes of cylinder number and one of combined head/sector) the CRC comes out wrong, but if I start with the 0xFF sync byte before the three header bytes, I come up with the same CRC value as was stored on the disk.
The therefore don't really check for a sync byte, the controller treats the first non-zero bit as the start of the sync byte and just stuffs that all into the CRC generator. If it was a spurious one bit inside the preamble, the CRC won't match thus this is not risky, but it makes my synchronizing logic wrong or I would need to go inject a pseudo sync byte into the generator myself.
However, I did come up with a solution that is simple - I can change my CRC generator module so that a master reset sets up the register values equivalent to having processed the sync byte, rather than to all zeroes. That way, my existing logic can feed the three header bytes through and get to the same CRC value. This is what I did. Interestingly, that is a value of 0x4040.
Test setup for disk controller (center) and drive (on left) |
Oh man... that sucks. Doesn't the disk drive know this is 2015 and head crashes almost never happen any more? Grr....
ReplyDelete(The drive probably wears really wide ties too....)
ReplyDeleteIf you initialize a CRC check with all zeros, you don't detect leading zeros, or the lack of leading zeros. Many initialize to all 1's to avoid that, but it looks like yours has a different solution.
ReplyDeleteThe logic starts in a state that is skipping over a continual string of zeroes, until the first 1 bit arrives. The CRC was initialized to zeroes so that the generator ignores all the preamble bits until the first 1 bit hits. That is the sync bit, although to set up byte boundaries, there is a whole byte of 1s recorded. The CRC begins right where the 0xFF arrives and continues for the known number of bytes. This is how it deals with leading zeroes - an initial state that requires some minimum number of zero bits in a row.
ReplyDelete