Guidance for using counters to build an SPI bus interface
Mike G
Posts: 2,702
Im asking for guidance on building a higher speed SPI driver using counters. Here's what I have done so far.
I am working with a WizNet W5200 that has a 80MHz SPI interface. I built two SPI drivers; one gleamed from AN012: Interfacing the Propeller to External SRAM with SPI and the other is a PASM version of the application note. The drivers work great. The PASM driver can deliver bust data at ~5M bits/sec up and down.
I studied several SPI counter drivers in the OBEX that implement similar schemes. CTRA/B is use as the clock while CTRB/A and PHSB/A IO data on the bus. The concept seems loose because the counter starts and deterministic timing synchronizes the clock to the IO data. I tried the concept and got it working for small amounts of data. 1 to 18 bytes tested without errors. For larger data blocks, I believe, the clock counter becomes out of sync with the data. Probably during the HUB write cycle since the counter is turned off (mov ctra, zero) between writing a byte to HUB memory and reading the next byte. I'm a little worried about the bus IO state at this point too.
A logic bug is not out of the question.
Attached are both versions of the code; SpiPasm works fine and SpiCounterPasm works for small amounts of data.
I am working with a WizNet W5200 that has a 80MHz SPI interface. I built two SPI drivers; one gleamed from AN012: Interfacing the Propeller to External SRAM with SPI and the other is a PASM version of the application note. The drivers work great. The PASM driver can deliver bust data at ~5M bits/sec up and down.
I studied several SPI counter drivers in the OBEX that implement similar schemes. CTRA/B is use as the clock while CTRB/A and PHSB/A IO data on the bus. The concept seems loose because the counter starts and deterministic timing synchronizes the clock to the IO data. I tried the concept and got it working for small amounts of data. 1 to 18 bytes tested without errors. For larger data blocks, I believe, the clock counter becomes out of sync with the data. Probably during the HUB write cycle since the counter is turned off (mov ctra, zero) between writing a byte to HUB memory and reading the next byte. I'm a little worried about the bus IO state at this point too.
A logic bug is not out of the question.
Attached are both versions of the code; SpiPasm works fine and SpiCounterPasm works for small amounts of data.
Comments
You could check this by buffering as much as practical in the COG, to confirm it really is a HUB effect ?
Another approach would be to keep the clock running, to avoid any enable glitch issues, and gate the CS - but that is more target dependent.
However, given that outa[mosi] is never set high in the counter driver this shouldn't really be an issue. That said, ctrb is still driving the mosi bit with the last command bit when the read function is entered (clearing outa[mosi] doesn't affect this).