SPI Timeout

ylp88

Senior Member
I've been trying to interface a 28X1 to a VS1002 MP3 chip via the PICAXE's SPI port, but despite all my efforts, I've come up empty. My program runs fine (setting IO states etc) and gets though the HSPISETUP command (I've tried several configuration options for this command as well with no luck) but as soon as it hits the HSPIOUT command the program "dies". It appears that I am encountering the "error" timeout of the SPI port with the system resetting itself every couple of seconds.

What should the state of the serial input pin (SDI) be? I don't quite understand the concept of the SDO pin having to be "in the expected default state". The timing diagram in the 16F886 (Figure 13-2) seems to show a "mid-state" between high and low and upon power up, the VS1002 has a voltage of 1.64V on its SO (SPI output) pin, or roughly Vdd/2. Aside, would such a default state change depending on the SPI mode configuration?

I don't have a logic analyser or oscilloscope but as far as I can tell, there are no signals coming out from the SDO or SCLK pins. Disconnecting the VS1002 chip makes no difference either (with or without pull-up/down resistors).

Concerned that it may be due to the fact that I am running the PICAXE chip from a 3.3V supply in order to comply with the VS1002's input specifications (although Figure 17-1 suggests the PICAXE chip should be able to run on this voltage okay, plus I've got the DISABLEBOD at the top of my program), I've also tried disconnecting the connections to the VS1002 chip and running the (now completely standalone) PICAXE chip from a regulated 5V supply with no change in results - all works well until the HSPIOUT command.

I've also tried using another 28X1 chip with identical results. Firmware version "A.0".

Hopefully I've covered all that I've tried to do. Any and all help is appreciated in advance!

<b><i>ylp88 </b> </i>
 

Technical

Technical Support
Staff member
This issue arises from the internal operation of the microcontroller SPI port, which is beyond PICAXE control.

Basically we have found by experimentation that the the 'transmit' register of the internal PIC module will not actually output the SPI byte transferred to it if the SPI port is in an incorrect state (i.e. the module seems to assume an SPI error and refuses to transmit the byte until the error is corrected). This is not very well documented in the Microchip datasheets. The actual status of SDI, high or low, depends on the spimode selected.

We have not used the device you describe but here is some working code from an EEPROM which may give you some ideas

<code><pre><font size=2 face='Courier'>
; Hardware SPI with a 26LC160 EEPROM
; This test program demonstrates SPI interfacing to the EEPROM
; Two bytes are written and then read back to verify.

#picaxe 28x1
'#com 4

' Input / Output pin setup

'24LC160 pins
'1 = CS = PICAXE output7
'2 = SO = PICAXE input4 (SPI DI)
'3 = WP = +5V
'4 = Vss = 0V
'5 = SI = PICAXE input5 (SPI DO)
'6 = SCK = PICAXE input3 (SPI CLK)
'7 = HOLD = +5V
'8 = Vdd = +5V
'remember PICAXE input connects to EEPROM output and vice versa!

symbol cs = 7 ' chip select is connected to PICAXE output 7

' 25LC160 Commands
symbol WRSR = 1 ' write status register
symbol WR = 2 ' write
symbol RD = 3 ' read
symbol WRDI = 4 ' write disable
symbol RDSR = 5 ' read status register
symbol WREN = 6 ' write enable

'Variables
symbol add_low = b0 ' address low byte
symbol add_high = b1 ' address high byte
symbol test_data1 = b2 ' dummy test data 1
symbol test_data2 = b3 ' dummy test data 2
symbol SR_Value1 = b4 ' read status regsietr 1
symbol SR_Value2 = b5 ' read status register again
Symbol RD_Value1 = b6 ' read data byte 1
Symbol RD_Value2 = b7 ' read data byte 2


'set cs high and wait a while
init:
high cs 'chip select high

' setup spi mode - mode 1,1 with sample at end, medium speed
hspisetup spimode11e,spimedium

pause 50 ' wait a while

'load some test values
add_high = 0
add_low = 25
test_data1 = 55
test_data2 = 99

main:

; write enable
low cs
hspiout (WREN)
high cs

; write status register to 0 to remove block protect
low cs
hspiout (WRSR,0)
high cs
pause 5 ; wait write time

; write enable
low cs
hspiout (WREN)
high cs

; read status register to see if it has worked
; we expect this value to now be 2
low cs
hspiout (RDSR)
hspiin (SR_Value1)
high cs

; write
low cs
hspiout (WR,add_high,add_low,test_data1,test_data2)
high cs
pause 5 ; wait write time 5ms

;read
low cs
hspiout (RD,add_high,add_low)
hspiin (RD_Value1,RD_Value2)
high cs

; write enable
low cs
hspiout (WREN)
high cs

; read status register to see if it has worked
; we expect this value to now be 2
low cs
hspiout (RDSR)
hspiin (SR_Value2)
high cs

; write disable the chip
low cs
hspiout (WRDI)
high cs

'display values on screen and then loop
debug
pause 1000


'increment test data
inc test_data1
inc test_data2

goto main



</font></pre></code>

Edited by - Technical on 03/07/2007 10:13:49
 

ylp88

Senior Member
Thanks for the reply, Technical. It looks quite a bit like the communication protocol I have, although many devices probably follow a similar scheme - low CS, transmit data via SPI, high CS - and that is waht I think the VS1002 datasheet needs, although there is another pin for selecting between command and data modes.

<BLOCKQUOTE><font size=1 face=arial>quote:<hr height=1 noshade>The actual status of SDI, high or low, depends on the spimode selected. <hr height=1 noshade></BLOCKQUOTE></font><font face='Verdana, Arial, Helvetica' size=2>

Would a &quot;mid-value&quot; be valid? As I said, the VS1002 seems to idle the PICAXE's SDI line at around 1.64V. Either that or there is a very pulse stream on that line which my DMM's frequency meter picks up nothing on (0.000kHz).

<b><i>ylp88 </b> </i>
 

hippy

Technical Support
Staff member
I've only speed read the VS1002 datasheet and there's a lot to it. I read this <A href='http://www.vlsi.fi/datasheets/vs1002.pdf' Target=_Blank>External Web Link</a> in case it's a different one to what you have.

From figure 8 ( page 20 ) and text in 7.2.1 ( page 16 ), SO ( from VS1002 ) is set tri-state when XCS is high, and becomes a driven output when XCS is brought low. The tri-stating is probably what is causing SO and SDI ( to PICAXE ) to sit at Vdd/2 when idle.

Having brought XCS low before executing HSPIOUT I would expect the SO line to have gone high or low ( figures 7 and 8 ).

It then gets complicated because there are two SPI style transfers; SCI and SDI the first done with XCS low ( SO enabled and valid ), the second with XCS high ( SO tri-stated ).

In addition, 7.2.1 suggests SO will go tri-state whenever data is being written to the VS1002, although that is contradicted by figure 7 ( page 19 ).

If it's a problem that SO is tri-stating itself when the PICmicro SDI input hardware expects something else, that might be resolved by a suitably large ( 10K+ ? ) pull-up or pull-down.

There are two things you can try -

Manually toggling XCS to check SO/SDI goes from Vdd/2 to Vss or Vdd when XCS is low.

Disconnecting the SO/SDI link and keeping SDI pulled high or low to see if HSPIOUT still causes a reset.

It's always possible that the VS1002, the PICmicro SPI hardware or PICAXE firmware does not work as described or expected and there may be more than one issue involved. There's also the possibility of having misunderstood what is expected, and typo's and errors in implementing what is needed.

My approach would be to use software to bit-bang SPI to get comms with the VS1002 working. That will show up any anomalies in the VS1002 protocol and verify if the waveform figures and descriptions are correct or not. I would write a program which simply sets lines high/low when driven by a Terminal Emulator and reports the level on SDI line back. That way you can single-step through the SPI packet and see exactly what does happen; effectively creating your own waveform diagrams. A DMM on the SDI line will show when it's high, low or tri-stated.
From that you might be able to determine why PICmicro SPI hardware will not work, or what needs to be done.

You can either try and get HSPIOUT working then or get your control code working with bit-banged routines and convert to HSPIOUT later.

One thing which isn't clear, is whether you are controlling a standalone VS1002 or this is part of another unit ( VMUSIC2 ? ). If so there may be some other hardware configuration or interactions which have to be dealt with.

Finally, there shouldn't be any issues with running at 3.3V, although the 16F886 should not be operated at over 10MHz at that voltage.
 

ylp88

Senior Member
Thank you very much for your detailed analysis, Hippy. I was thinking of trying a more manual approach but since I won't have time to do that until tomorrow, I though I might just ask to see if anyone had any ideas first.

The PICAXE was running using the internal 8MHz oscillator (SETFREQ m8) but then I reverted back to 4MHz just to eliminate that as a problem. Curiously, how do you specify whether the chip uses the internal RC oscillator or the external resonator? I notice the chip has a &quot;failsafe&quot; oscillator feature. Does that mean it will usually use the external clock and fall back onto the internal RC if it detects an failure in the external clock?

Anyhow, I am using the VS1002D chip on essentially what is a bit of a &quot;souped-up&quot; breakout board. Souped up in the sense that it has pretty much everything on the board needed to run the chip - oscillator, microphone front-end, audio output stage. A header strip provides connectivity to the &quot;data&quot; portion of the chip to control its operation. Available here from Futurelec: <A href='http://www.futurlec.com.au/Mini_MP3.jsp' Target=_Blank>External Web Link</a>.

Anyhow, I'll have a go with some manual configuration and careful observation of the lines when I have the chance and I'll certainly let you know of my progress. Thanks again for your help.

<b><i>ylp88 </b> </i>
 

hippy

Technical Support
Staff member
SETFREQ selects the external oscillator ( EM16 etc ), and yes, if that's done and the crystal is pulled from the board it falls back to using the internal oscillator.
 

ylp88

Senior Member
Well, I've managed to interface a Vdrive module and my VS1002d breakout board to a PICAXE-28X1 with mixed results. I've saved a MP3 file on the drive an attempted to send that to the VS1002d board (MP3 file is MPEG2 Layer 3 at 32kbps CBR, 16kHz sample rate in stereo.)

With a very careful ear, one can make out the music coming out from the VS1002 but is is very heavily broken up and highly distorted with a lot of cracking and very loud scratching. I gather that this is probably due to one (or more) of several reasons:

- The data is not being read from the drive fast enough: I am reading as big a chunk of data I can without overflowing the scratchpad RAM in order to lower overheads. Communication with the Vdrive module is 230400 baud - I assume, using 8MHz oscillator and B115200_4 command which may be unreliable but it seems to work.

- Data is being corrupted from the drive: I tried using the B115200_8 command to achieve 115200 baud between the PICAXE and Vdrive but nothing in the audio output resembled what the audio should sound like. &quot;Cheating&quot; and trying the B115200_4 command at 8MHz works a lot better with a vague similarity in sound to what the audio should sound like, but at this speed, I'm not sure if all the data is being received correctly thus leading to data corruption and corrupted output audio.

- Data input processing overhead: I think it is very (computationally) expensive to be checking for the end of received data from the Vdrive. Every receive needs to be processed to find the end of the received string and then remove the &quot;D:\&gt;&quot; prompt from the end.

- Data transmission overhead: As per my original problem, it appears that I am only able to communicate with the VS1002d using the SPIMEDIUM speed - failure and SPI &quot;timeout&quot; occurs when I try SPIFAST. The slower speed (which is actually quite significantly slower) would increase the time spend sending data to the VS1002d, thus making it more clock cycle expensive than if I could get it running on SPIFAST.

- Coding: I've tried optimising my read/write loops a bit but there is not much I can see, albeit I'm sure that there are lots of little things that can be done. I've also removed a couple of subroutines and moved them into the main routine to save a jump which I know takes more clock cycles on a plain PIC, and although I was not sure what kind of impact or how much difference it has on a PICAXE, the change did seem to make a difference.

When I have time, I might try transcoding the audio file into 16kbps and see how much difference that makes but one would hope to find some optimisation to keep the bitrate up. Perhaps when I find the time I'll have to try using a plain PIC, but before that, I've got to try and use a 16MHz oscillator. I'm fairly sure I have one lying around somewhere but as luck would have it... I of course do not know where it is.

Anyhow, this has ended up sounding like a bit of a journal entry, but I hope you appreciate it. I'll let you know if I make any more significant progress.

<b><i>ylp88 </b> </i>
 
Top