Well, after much thought, pondering, and discussion with David, I finally implemented a working byte-sync routine to my SX software.
I don’t have it fully working with the PC side software yet, because this requires semi-major surgery on that side.
I added it to the transfer routine, aka fram -> usb, and here’s how I did it:
Basically did a
for loop = 1 to 14 (sectors)
findsync()
for insideloop=1 to 1088(bytes in a sector)
recvfram()
sendusb()
next insideloop
next outsideloop
where findsync() looks for a $4489, and when it finds one, it returns with the fram properly aligned to start recv’ing bytes, I send 1088 bytes, and then I look for another sync.
This has a downside of eating the AAAA AAAA 4489, so each sector starts with just a “4489” but who cares?
I ran some quick numbers and the time penalty for doing this MIGHT be 1/2 second per disk! So it’s really quite reasonable in terms of time. 380ns per bit avg, 500ns worst case. And this is only on NON-sync’d data. So only something like 1000 or 1100 bytes per disk. Data at beginning of read + gap. So minimum 830 bytes, maximum of 830+1087 bytes. OK, so maybe around 1800.
This really drops the PC requirement as far as software. I can get rid of all those damn bitshifting routines, searching for sectors, retrieving data properly shifted, etc. All bytes will arrive properly shifted. This means much smaller code, easier to read/write, and so on.
I have other plans in the back of my head, too. DOWN THE ROAD, I want to start looking at semi-realtime transparent reads. Eliminate the buffer…
Note that this still needs fine-tuned. While the data is properly aligned, I’m reading/writing too far.
I think its 1088 with the 8-byte sync, so I should only be writing out maybe 1082 bytes or something.
Adjusted the read/write length so that I’m transmitting exactly 1088 bytes per sector. I also re-attached the “AAAA AAAA 4489” that got lost during the findsync() method.
I transmit 14 sectors worth of data, 15232 bytes. plus checksums and delimiters. I think there are ALWAYS 14 sectors per 16384 bytes that I read.
The version of SX code that now aligns everything perfectly, and the PC-side code is reading it directly.
It’s refreshing seeing 14 perfect “AAAA AAAA 4489 4489” SYNCs, followed by the data perfectly aligned.
Oh, and yes, this has another nice side effect. No gap! The PC doesn’t see the gap, because it searches past it for the next sync!
I can’t tell you how much easier the parsing routines will be for this. No more bitshi*t stuff to worry about. 🙂 Everything will be handled at the byte level, no need to shift anything.
Coolness.
I’m happy it’s working.
I assume you send the “fake” 4489 sync word immediately before the findsync(), so that they can be streaming through the SX-to-PC at the same time that findsync() is working its magic, finding the “real” 4489 sync word.
Sending bytes before they have been read — some people would say that is impossible.
Nice.
Thanks David.
I actually send the sync word immediately after the findsync(). But I’m not sure it really matters.
My USB to PC routines are bit-banged, there are no interrupts. And findsync is entirely bit-banged too.
What this means is that nothing happens while something else is occurring — no multitasking, interrupts, or anything (for strictly THIS portion of the SX to PC transfer)
However, there is a practically a zero performance penalty. I did ROUGH calculations and worst case is like 1/2 second across the entire disk. Findsync() runs about 14+/- times per track. On MOST sectors, that are back-back, findsync() almost returns immediately. On the first sector, it can take up to 1087 bytes*8 iterations and the gap calls for 830 bytes * 8 iterations. When each iteration is taking hundreds of nanoseconds, this is really not bad performance.
Doing it on the FRAM to USB on the fly was really the right choice. There is no need to read and write at the same time(or in close proximity) to memory, which was a limitation. Also, the real-time performance hit of doing it drive->fram was too much. And while I think I could have optimized anything I had tried, there is basically “unlimited” time to do it FRAM to USB. Obviously, not so much as to destroy my overall times, but there are no crucial bit->bit delay issues.
Thanks for your comments on that. Really helped me work through the issues.
[…] It takes approximately 1.7us to read 1 byte, and then 5us to transmit that byte. The 5us is 500ns (1/2mbps) * 10 bits (8 start + 1 start + 1 stop). So 6.7us per byte. This doesn’t include the time it takes to findsync(). […]