SPI interface speed question (for P-ROC pinball controller)
bongk
Posts: 14
Hi all,
One pinball project done - "Trilogy Brewing" custom pinball machine using prop's to drive the sound and score displays took Solid State best in show at the Midwest Gaming Classic this spring.
Next project: I want to use a prop to drive the P-ROC pinball driver board. http://www.pinballcontrollers.com/docs/Driver_Board_specs/Master_Driver_Board_LLD.pdf The board would accept commands from the prop on a single pin using SPI. Here is what the P-ROC docs have to say:
"A transaction consists of 5 data bytes. There must be at least 10 IDLE cycles between transactions.
Between each byte of a transaction there must be between 1 and 5 IDLE cycles.
The data signal must be high during all IDLE cycles.
Data must be sent at 8 MHz, 125ns per bit."
They provide sample code for a 16MHz Arduino to send this data at 8Mhz.
http://www.pinballcontrollers.com/index.php/products/driver-boards/master/83
But looking at the code it looks to me like the Arduino is capable of sending a data bit each clock cycle.
Would I have any hope to drive this directly from the Prop? I read in an old forum post the assembly SPI driver tops out around 130KHz, and page 392 of the "Programing and Customizing..." book says the core would only be able to keep up with a 4Mhz SPI interface.
If not directly, any other suggestions? The board can also be driven with an RS485 master but would still need to be at that same speed.
Thanks in advance!
Kevin
One pinball project done - "Trilogy Brewing" custom pinball machine using prop's to drive the sound and score displays took Solid State best in show at the Midwest Gaming Classic this spring.
Next project: I want to use a prop to drive the P-ROC pinball driver board. http://www.pinballcontrollers.com/docs/Driver_Board_specs/Master_Driver_Board_LLD.pdf The board would accept commands from the prop on a single pin using SPI. Here is what the P-ROC docs have to say:
"A transaction consists of 5 data bytes. There must be at least 10 IDLE cycles between transactions.
Between each byte of a transaction there must be between 1 and 5 IDLE cycles.
The data signal must be high during all IDLE cycles.
Data must be sent at 8 MHz, 125ns per bit."
They provide sample code for a 16MHz Arduino to send this data at 8Mhz.
http://www.pinballcontrollers.com/index.php/products/driver-boards/master/83
But looking at the code it looks to me like the Arduino is capable of sending a data bit each clock cycle.
Would I have any hope to drive this directly from the Prop? I read in an old forum post the assembly SPI driver tops out around 130KHz, and page 392 of the "Programing and Customizing..." book says the core would only be able to keep up with a 4Mhz SPI interface.
If not directly, any other suggestions? The board can also be driven with an RS485 master but would still need to be at that same speed.
Thanks in advance!
Kevin
Comments
Leon, maybe you're thinking about I2C. SPI has (among clock and chip-select dependent on protocol) one output which can be shared with it's one input.
Yeah, I was confused about the 1-wire too. But the docs for their board makes it pretty clear you only connect two wires - one ground and one data, no clock.
It is only one way communication with no acknowledgement, so I guess its a matter of get the timing right, send the commands and pray.
Those are my driver boards. I hope you don't mind me coming here to respond to your thread.
The requirement for exactly 8 mbps is due to using a very simple RS-485 design without clock recovery on each driver board in the chain. Each board has a 32 MHz clock and samples each incoming data bit 4 times to detect valid data and offset the valid sample point.
The master driver board uses the same exact logic but simply looks for the data on the incoming data pin instead of the RS-485 bus.
If you can get your data out at 8 MHz (125ns per bit), great. If not, you could always change the clock source on each driver board in your chain. It simply needs to be 4x the frequency of your data source clock. The clocks are surface mount; so it's not something I would suggest for the average user, but if you're able to do that kind of work, it shouldn't be a big deal. For reference, this is the clock the boards come with: Abracon ASV-32.000MHZ-E-T. Obviously make sure your replacement is a 3.3v part in the same package/pinout.
You're always welcome to email me directly if you have questions about the boards.
- Gerry
http://www.pinballcontrollers.com
You'd want to run the Prop at 96MHz (if I did my math correctly).
Use a 6MHz crystal with x16PLL.
You get three instruction in 125ns.
Since there's just 5 data bytes just set these up ahead of time.
Use shift left while writing the c flag and then muxc with your output mask.
You still have one instruction left in the time slot. Use a nop if you don't need to do anything else.
I think you'd have time to do some loops to write the data but with just 40 bits of data, you could just have a long list of shifts and muxcs.
I think Leon is correct. This isn't SPI.
Duane
The first high-low transition after 10 IDLE cycles (high) is interpreted as the start of a transaction. The first bit (at least) of each byte is required to be 0. After each byte, a few IDLE cycles (high) are required so the first low transition represents the start of the next byte.
Originally designed for the P-ROC board, the protocol was originally a little more straight forward. However, a 16-MHz arduino can't send back-to-back bytes (@ 8MHz) without IDLEs. It's just too slow. So I modified the protocol to deal with that without increasing PLD logic complexity. The protocol is implemented on each driver board in a VERY small PLD.
I agree with everybody that this is not SPI. It's not advertised as SPI. It's just a simple custom protocol that the arduino can implement on its SPI data output. Hopefully a propeller can too.
For reference, the protocol is defined at the end of this document.
- Gerry
http://www.pinballcontrollers.com
The first high-low transition after 10 IDLE cycles (high) is interpreted as the start of a transaction. The first bit (at least) of each byte is required to be 0. After each byte, a few IDLE cycles (high) are required so the first low transition represents the start of the next byte.
Originally designed for the P-ROC board, the protocol was originally a little more straight forward. However, a 16-MHz arduino can't send back-to-back bytes without IDLEs. It's just too slow. So I modified the protocol to deal with that without increasing PLD logic complexity. The protocol is implemented on each driver board in a VERY small PLD.
I agree with everybody that this is not SPI. It's not advertised as SPI. It's just a simple custom protocol the P-ROC uses. The arduino can implement it on its SPI data output. Hopefully a propeller can too.
For reference, the protocol is defined near the end of this document.
- Gerry
http://www.pinballcontrollers.com
Heh - sorry... not quite ALL the way at the end. Scroll up one page.
- Gerry
http://www.pinballcontrollers.com
Duane is right about using a 6MHz crystal. We use that frequency all the time.
Receiving is harder because the Propeller doesn't have corresponding hardware to receive data this quickly. You would need to use external hardware. Maybe you could find a UART that runs that fast. The format you described is the same as the usual asynchronous serial with a 0 start bit, 8 data bits, and one or more stop bits.
Sorry, I'm not sure what you're asking. Each board's clock is not in sync with the incoming data. The data is edge detected with a 4x clock, and the sample point is moved 2 clocks after the edge. That offset is kept for the remainder of the transaction.
The protocol is tx only. It's used only to send data to the driver boards.
BTW - Once somebody implements and gets this protocol working in a propeller, I'll be happy to post the code (if shared) on my sight and link to it in my docs for future users.
- Gerry
http://www.pinballcontrollers.com
So... it's essentially asynchronous serial using bit0 (LSB) of each byte as the start bit?
A few Propeller wizards have used the counters for high-speed SPI (e.g., FSRW); I wonder if that's an option?
MSB (bit 7) is the 'start bit', but otherwise correct.
- Gerry
http://www.pinballcontrollers.com
No time to do this atm, but you are in good hands here.
At 8MHz xtal, each clock is 12.5ns, and most instructions are 4 clocks = 50ns per instruction. But the video generator to send the output stream.
Just to put you at ease, I (and others) have written code to sample prop pins at 12.5ns (burst) using 4 cogs by software alone (no counters). Remember, we don't have to worry about interrupts on the propeller
A the instruction itself referenced by $ (here)
In order to send something upset the byte array data[] and trigger the transaction by setting storage to non-zero. Transaction is finished when storage returns to zero. HTH
Update: Admittedly the way the transfer buffer is handled ATM is a bit awkward (fixed during init). It would also be possible to just use the buffer address as the transfer start indicator (it being officially 0 is rather unlikely). This means multiple packets can be prepared in advance and then just thrown at the transmitter. The file test.PDB.multi.transfer implements this new behaviour.
I continue to be astounded by the support on this forum.