SAM4s SPI Mode 3 - Use ASF or Bit-bang the interface?

Go To Last Post
11 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello All,

It's been going on 3 weeks now trying to communicate with an external device using SPI Mode 3 and the ASF SPI routines.  I have studied the datasheets of both the processor and the external ADC, searched the web and this forum, started a forum discussion here that Rx'd 0 responses and entered tech requests at both Microchip/Atmel and Analog Devices.  

Should I give up on the ASF solution and simply bit bang the SPI interface?  The ASF solution showed much promise since I could, theoretically, communicate with several different SPI devices using Variable Peripheral Select Mode and also changing the SPI Mode to suit the various devices.

Comms look good on a logic analyzer, but are not Rx'd into the buffer consistently or in the order in which I see them on the logic analyzer. 

I would appreciate any help at all, suggestions and the like from others who have dealt with SPI on the SAM4S device.

Please?

This topic has a solution.

The great thing about multitasking is that several things can go wrong at once..

Last Edited: Mon. Oct 23, 2017 - 12:27 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Since you got 0 responses last time, all I can do is say I feel your pain.  I have SPI working on a SAMG55 using ASF4/START but found that it doesn't generate slave selects automatically.

Since you say you are getting inconsistent results, maybe check that there are no runt pulses or glitching on the spiclk signal.  I don't know if there is slew rate control on the IO of the SAM4S.  Does the clk line only go to one device and if so did you put a series resistor near the output to terminate the line and limit reflections if the trace/route is more than an inch or so?  It might be worth a try anyway.  If you are going to mulitple devices and termination is a problem then you may need thevenin termination at the end of the chain.

 

Oh, also when working with SPI on the G55 I found that during reads I had to pre-flush the read buffer (before the read) else it did strange things.  Maybe that will help.  I found a function named _spi_m_async_read_one() that does the job. 

uint16_t _spi_m_async_read_one(struct _spi_m_async_dev *dev)

{

ASSERT(dev && dev->prvt);

 

return hri_spi_read_RDR_reg(dev->prvt);

}

 

 

 

 

 

Last Edited: Thu. Oct 12, 2017 - 01:00 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Tarribred,

Thank you, so much, for your reply. 

I will switch from logic analyzer to the scope and inspect the integrity of the signals at the ADC ( far end of the SPI traces). 

There is slew rate control on the SAM4S, not sure if it is enabled when using the SPI, rather than GPIO for a given pin.

The clock line does, indeed, go to 3 devices and a connector.  I have no series resistors on the SPI lines for impedance matching.  I am using the SPI at only 1MHz, but do realize the high frequencies are in the edges.

Thanks again for your input - some things to check out.   

The great thing about multitasking is that several things can go wrong at once..

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

In that case, you may want to try an RC termination on the spiclk signal at the end device.  First try values are typically about 100 ohm and 47pF.  That should prevent any reflections back at the other devices.  Also, you responded while I was editing my prior response.  So you should check on the RX buffer flush before reading.  That helped my problem reading data on spi about a month ago.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have probed the SPI CLK (which is 3.1" of 6mil trace over a ground plane) at the ADC device, with a very short ground lead.  The clock signal looks good, aside from some over/undershoot at the transitions.  I see no reflections or ringing going through the Vih or Vil points.  The SPI chip select looks real clean with minimum undershoot. SPI MOSI signal looks fine and MISO as a bit of damped ringing of a peak magnitude of 0.7v.

It doesn't seem to be signal integrity that is an issue. 

The great thing about multitasking is that several things can go wrong at once..

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Whether there is a runt pulse there or not will depend on where on the 3.1" trace you put the scope probe.  There may be only over/undershoot at the end but there might be a tiny runt pulse at the mid-point.  Worse, if you put a scope probe (10pf cap) in the middle, it might be reduced or go away.  SPI MOSI or SPI MISO and slave select should not be much of a concern as these are sampled on the clock.

 

If it is not too difficult, you might try adding the 100ohm resistor and 47pF cap connected in series at the end of the trace run and see if it changes the behavior.  I don't know how sensitive the ADC you are using is to these sorts of things.  If it is easier, you might instead try something like, cut the trace on the clock line so the ADC you are trying to use becomes the last and only device on the clock line.  Pull up the cut trace to the other devices so they don't get clocked by a floating signal.  Then only debug the single spi device.

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

But I suppose it depends a bit on whether the ADC is truly early or mid-way in the 3 inch run or if it is very near the end point.  If all the spi clock loads (devices) are at the end point and appear as a single lumped load then you may be ok with the signal integrity and can look elsewhere for the problem.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

FWIW I basically daisy chained 3 devices on the SPI bus.  Tried to minimize stubs.  The ADC is the last device on the bus.  I think if there were a signal integrity issue, I would not Tx and Rx any correct bytes between the M4 and the ADC.  I do get good bytes, just not consistent on Rx'ing the second of two bytes.

The great thing about multitasking is that several things can go wrong at once..

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have found that it was necessary to perform a :

    spi_get(SPI); // remove existing SPI data

before sending a command/reading register to the external analog to digital converter.

This simple act enabled to to have consistent reads of the ADC and in the byte order I expect.

 

The great thing about multitasking is that several things can go wrong at once..

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I've seen similar problems with reading ADC devices on the I2C bus with a SAME70 - flush the receiver before reading real data bytes to get reliable readings.  The odd part is the frequency of this spurious garbage data already in the receiver changes when enabling/disabling the ICACHE and DCACHE.  With both caches disabled it fails a lot.  One or the other cached enabled reduces the amount of garbage data tremendously.  I'm suspecting activity on external buses is causing noise on the I2C bus in my case.

Try playing with the caches to see if it affects your SPI results.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

For SPI devices, there is the separate MISO and MOSI signals so I think the MISO is taking data even when master writes to slave.  So the receive buffer gets filled regardless of whether you want it or not.  As a result it needs to be cleared out prior to trying to receive something you really do want.  Else, it probably triggers a receive event as soon as it is enabled.  I mentioned this in my previous reply.  I was getting some strange results otherwise.  I wouldn't think I2C would have the same problem but it is probably a good idea on any peripheral that is receiving to make sure its receive buffers are cleared before trying to enable a reception.  This probably includes the USB peripheral in some of the ARM MCUs too.

 

The Microchip/Atmel examples for the explained boards might be improved by doing some loopback examples that both send and receive for I2C and SPI.