SPI Tutorial

From openPicus Wiki
Jump to: navigation, search

Contents

What you are going to learn

This tutorial shows you how to add and manage SPI communication on Flyport.
The SPI communication is not very simple, please read SPI Bus Wikipedia page.

FlyportPRO warning

This tutorial is made for Flyport modules but works on FlyportPRO as well. Just adapt the code since the pinout is slightly different.

Download

The SPI library is not a framework library. You can read more about this API, download it and how to import it in SPI library page.

Initiating an SPI session

Before using any of the SPI functions, a initialization of the pins is needed.

//SPI CLOCK pin	
IOInit(p8, SPICLKOUT);
//SPI OUT pin
IOInit(p10, SPI_OUT);
//SPI IN pin
IOInit(p12, SPI_IN);
//SPI CS-SS (Chip Select-Slave Select) pin
IOInit(p14, out);
IOPut(p14, on);
IOInit(p14, out);

After that, a SPIContext must be created in this way:

SPIContext mySPI

Now mySPI must be setted using the SPIConfig function.
The SPI configuration is not simple like the I2C configuration. All parameters, that you can set, are explained in the library page.

And once you have that, with

SPIContextRestore(&mySPI)

and with

SPIOpen()

the SPI connection is ready.

To close a connection

SPIClose()

can be used.

Writing and Reading

If you want to write

SPIWriteByte(BYTE data)

must be used. If you want to read

SPIReadByte(BYTE * res)

must be used. There are similar functions for WORD data type.

It's very important to read the SPI device datasheet. The frame and the frame sequence are described in datasheet and in general they are particular for every device.
For example: to set a percent of partitioning in MCP41100 digital potentiometer, a byte with the Write mode and the selection of output must be sent to the device and then it is possible to send a data with a partioning.

SPIWriteByte(0b00010001);   //command: write + output 1
SPIWriteByte(150);          //write byte that set the percentage of partitioning

There is a function that combine writing and reading in a lump sum

SPIWriteReadByte(BYTE data, BYTE * res);
SPIWriteReadWord(unsigned int data, unsigned int * res);

In fact, normally, when some device data must be read, the SPI module must send a Write command where the module says to the device to prapare the data to read and then it reads data.

Base frame

To write and to read with the SPI communication the following base frame must be used

vTaskSuspendAll();
SPIStart(&mySPI);
 
...
 
SPIStop(&mySPI);
xTaskResumeAll();

It's very important to use vTaskSuspendAll() and xTaskResumeAll(), these functions hold up the Task state machine to prevent errors while the module sending a message.

SPI example with MCP41100 digital potentiometer

The MCP41100 is a digital potentiometer produced by Microchip. When it receives some data, the MCP441100 processes the massage and converts the data in the percentage of the internal divider.
The Flyport is setted up like a SPI Master device with Chip Select on p14 pin. The speed of SPI is 250kHz and the mode (the combination of polarity and phase) is 0.
A led is connected between output 1 and ground.

Bill of Materials

  • 1x Flyport Module
  • 1x miniUSB programmer
  • 1x MCP41100
  • 1x Resistor (100 Ohm)
  • 1x Proto Nest Board
  • 1x Breadboard

Schematic

Spi tutor.jpg

Code example

// example with MCP41100 digital potentiometer (Microchip)
 
#include "taskFlyport.h"
#include "SPIHelper.h"
 
void FlyportTask()
{  
  UARTWrite(1,"set PIN and SPI");
 
  //SPI CLOCK pin	
  IOInit(p8, SPICLKOUT);
  //SPI OUT pin
  IOInit(p10, SPI_OUT);
  //SPI IN pin
  IOInit(p12, SPI_IN);
  //SPI CS-SS (Chip Select-Slave Select) pin
  IOInit(p14, out);
  IOPut(p14, on);
  IOInit(p14, out);
 
  //create a SPIContext	
  SPIContext mySPI;
 
  //mySPY is configured with SPI MASTER device, MODE 0, CS on p14 and speed: 250kHz 		
  SPIConfig(&mySPI, SPI_OPT_MASTER | SPI_OPT_MODE_0, p14, 250000);
  SPIContextRestore(&mySPI);
  SPIOpen();
 
  BYTE i=0;
 
  while(1)
  {
    IOPut(p21,on);
    for(i=240;i<255;i++)
    {
      //routine to send the percentage of partitioning
      //(the value is incremented by one each cycle)
      vTaskSuspendAll();
      SPIStart(&mySPI);
      SPIWriteByte(0b00010001);   //command: write + out1
      SPIWriteByte(i);            //write byte that set the percentage of partitioning
      SPIStop(&mySPI);
      xTaskResumeAll();
      vTaskDelay(25);
    }
    IOPut(p21,off);
    vTaskDelay(50);
  }
}
Personal tools
Namespaces

Variants
Actions
START HERE
DEVELOPMENT
HARDWARE INFO
RESOURCES
PHASED OUT
Toolbox