Main Site Documentation

FEZ Raptor SPI Clock Range


#1

What is the overall specified range for setting the SPI clock rate on the Raptor? I have need for a low rate (~200kHz), but anything lower than about 525 kHz seems to break the interface.

Here’s the code I’m using to test:


using System;
using System.Collections;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Presentation;
using Microsoft.SPOT.Presentation.Controls;
using Microsoft.SPOT.Presentation.Media;
using Microsoft.SPOT.Presentation.Shapes;
using Microsoft.SPOT.Touch;

using Gadgeteer.Networking;
using GT = Gadgeteer;
using GTM = Gadgeteer.Modules;
using Gadgeteer.Modules.GHIElectronics;

using Gadgeteer.Interfaces;
using GTI = Gadgeteer.Interfaces;

namespace SPITest
{
	public partial class Program
	{
		private GT.Socket SPI_socket;
		private GT.Socket IO_socket;

		private GTI.SPI mySPI;	// Syncport Module A

		// Define the SPI Configuration object
		private static SPI.Configuration spi_configuration = new SPI.Configuration(
			false,	//Chip Select Active State
			0,		//Chip Select Setup Time
			0,		//Chip Select Hold Time
			false,	//Clock Idle State
			true,	//Clock Edge
			525);	//Clock Rate (kHz)

		// Define Module BUS Read Signal
		private static DigitalOutput Trigger;

		public static byte[] spidata;
		const int bufferLength = 32;

		// This method is run when the mainboard is powered up or reset.   
		void ProgramStarted()
		{
			/*******************************************************************************************
			Modules added in the Program.gadgeteer designer view are used by typing 
			their name followed by a period, e.g.  button.  or  camera.
            
			Many modules generate useful events. Type +=<tab><tab> to add a handler to an event, e.g.:
				button.ButtonPressed +=<tab><tab>
            
			If you want to do something periodically, use a GT.Timer and handle its Tick event, e.g.:
				GT.Timer timer = new GT.Timer(1000); // every second (1000ms)
				timer.Tick +=<tab><tab>
				timer.Start();
			*******************************************************************************************/

			// Define the SPI Interface
			SPI_socket = GT.Socket.GetSocket(1, true, null, null);
			mySPI = new SPI(SPI_socket, spi_configuration, SPI.Sharing.Shared, SPI_socket, GT.Socket.Pin.Six, null);

			// create and fill the SPI data buffer
			spidata = new byte[bufferLength];
			for (int i = 0; i < spidata.Length; i++)
				spidata[i] = (byte)i;


			// Define Module BUS Read Signal
			Trigger = new DigitalOutput(SPI_socket, GT.Socket.Pin.Five, false, null);



				GT.Timer timer = new GT.Timer(1000); // every second (1000ms)
				timer.Tick += timer_Tick;
				timer.Start();

			// Use Debug.Print to show messages in Visual Studio's "Output" window during debugging.
			Debug.Print("Program Started");
		}

		void timer_Tick(GT.Timer timer)
		{
			Trigger.Write(true);       // Fire Trigger pulse
			mySPI.Write(spidata);		// send the SPI buffer
			Trigger.Write(false);       // Reset trigger
		}



	}
}



#2

Are you writting to a Gadgeteer module or to a third party device??

First of all, SPI is a synchronous protocol so it requires some sort of let’s say…, handshake among the devices involved in the communication process or maybe it doesn’t require any. Let’s say, if your master device wants to write to the slave device, it first asserts the CS line, waits some time (or maybe doesn’t wait at all) and starts to write over MOSI. In another variant, it asserts the CS line to request permission to write and waits, then the slave device assert another line (IRQ line maybe) and then the master writes through MOSI line and maybe the slave replies back through the MISO line. Then CS is released so the IRQ line as well.

I don’t understand what the purpose is for the “Trigger” object labeled as “Define Module BUS Read Signal”…, are you using this as CS or maybe CE (chip enable) to allow the slave device to read on the MOSI line??

SPI is a high speed bus so it makes no sense for me to use it at that low speed. Why don’t you just use UART or even I2C?

About your configuration settings for SPI, I can see the following:

private static SPI.Configuration spi_configuration = new SPI.Configuration(
false, //Chip Select Active State
0, //Chip Select Setup Time
0, //Chip Select Hold Time
false, //Clock Idle State
true, //Clock Edge
525); //Clock Rate (kHz)

As I don’t really know what device are you trying to connect to, so check if it does require some extra time to prepare its input shift registers for receiving the serial data through MOSI. This is the purpose for the “Chip select setup time”, to give the slave device some time to get ready for data acquisition. you set it as “0” so SPI won’t wait at all after CS assertation. It will write right away on the MOSI line!

:slight_smile:


#3

Hi Habot, thanks for the response.The device I will ultimately be connecting to is a custom PCB I designed for a client company to be used in an existing product. During the design phase, I used an Arduino Mega based “test fixture” to emulate the product backplane, and that worked fine.

But at this point I’m only connecting a Logic16 Analyzer to the SPI socket to observe the signals. The Trigger output is just that: a “trigger” to the Logic16 to initiate the trace.The “Define Module Bus Read Signal” comment was copied over from the code for the above product, but doesn’t apply to this test case.

The trace I get from the Logic16 at 525 kHz and above is exactly what is expected, no problems at all. It’s only when I attempt to go lower that the interface goes to crap. I suspect there is a lower limit on the clock rate with the default interface, but I hope there’s a work-around.


#4

I should add, I “can” use a faster rate with the board in question, but academically I’d like to know why the interface fails at a lower rate :slight_smile: