DJB-SpeakJet PSIM Interface

My first implementation of the SpeakJet was to interface the SpeakJet Rx input and Buffer Half Full signals to the PSIM J3 and use P7 as a serial output and P6 as a flow control input. This requires the use of the serial command which uses software-based timing. Accurate timing requires the interrupts to be disabled during the character transmission time of ~1 mS. MIDI inputs could be missed during this time and adding the appropriate enable and disable commands around individual character transfers is a programming hassle.

This photo shows my initial serial SpeakJet design with an active two pole filter and +5 volt regulator. I later added a +10 volt regulator to power my four CV controls.

 

I decided to use these same two pins for a synchronous interface which would not be impacted by interrupts. I chose the I2C protocol and did some testing with a Philips I2C peripheral part that I had.  I used a Tektronix DPO4000 with serial protocol analysis.  I noticed that there were peculiarities with the I2COut command and timing.

The command byte should specify the I2C address. The optional address byte is for specifying an extended address. If this optional address is not included, the control byte seems to be ignored and the first data byte is used as the I2C address. If this address is included then there is a repeated start bit and the control byte is used for the I2C address.  I found it easier to use a dummy byte for the control and include the I2C address as the first byte in the data field.

    i2cout p6, p7, $0, [$address<<1, data, data, ... data]

Here is a scope image of my I2C to serial bridge that I designed with an Atmel ATMEGA8. Channel 3 (magenta) is SDA (data) and channel 2 (cyan) is SCL (clock). These are single byte data packets so each pair of transfers consists of the I2C address ($48) followed by data. Channel 4 (green) is the 9600 baud serial data from the bridge to the SpeakJet.

 

I added a TTS256 text to speech chip to improve the SpeakJet functionality as it requires a lot of data.  The TTS256 will translate the text to SpeakJet codes upon receipt of an end-of-line ($0d). No more data can be sent to the TTS256 until the SpeakJet has finished talking. This scope image shows the latency between the $0d being sent to the TTS256 (yellow) and the SpeakJet speaking output (green). I had to add 12 mS of delay from the transfer of my end-of-line line character before reading the status of the SpeakJet speaking output.

 

I implemented a three line (256 characters per line) buffer in my I2C bridge. While I doubt that this amount of buffering will ever be needed, I needed to implement flow control back to the PSIM. I chose to disable I2C acks when the buffer is greater than 511 bytes. The I2COUT command will goto the optional error label if there is an error such as not receiving an ack. I used this error label to re-execute the I2COUT command. However, this will cause the entire command to be sent again. To make this work correctly, I do not disable I2C acks until after a stop bit has been sent. This will synchronize the buffer with the retransmission of the I2C packet. Again, channels 2 and 3 show the I2C data. Channel 1 (yellow) shows the serial data transmission to the TTS256. Channel 4 (green) shows the buffer greater than 511 bytes. Nacks are show on the I2C bus as red. You can see the delay from the yellow cursor line (a & b) to the I2C nacks (red) which is the completion of the I2COUT data packet. Nacks continue until the green signals drops momentarily which causes another complete data packet to be transferred. Receipt of the first byte again takes the buffer greater than 511 bytes which the green signal indicates. It all works great.

 

The TTS256 will pass non-text characters through to the SpeakJet. This allows you to embed sound effects in with text. The two byte commands (volume, pitch, etc.) will only pass through correctly if the second byte is a non-text character.  Otherwise the TTS256 will process the second byte as text and incorrect data will be sent to the SpeakJet.

These two byte commands can be sent to the SpeakJet by placing the TTS256 in pass through mode. This is accomplished by sending the text "passthruon" and an end-of-line. All characters sent to the TTS256 will be sent directly to the SpeakJet. An "X" ($58) will terminate the pass through mode.  Note that this character cannot be used as the second byte of a two byte command as it will terminate the pass through mode.  An "X" is also used to terminate the SCP mode for communication directly with the SpeakJet internal registers.  An alternate \A may be used to terminate SCP mode and not pass through.

Here's a photo of my PSIM with the additional daughterboard for the I2C bridge and TTS256 making a very 'tight' module.

 

Schematic for the I2C and TTS256 daughterboard

 

back