WebbotLib AVR library
WebbotLib It just does it
  C++ documentation  C documentation

spi.h

Routines for handling communications with other devices by using the hardware SPI interface.
The SPI interface comes in two parts:
1. Decide how you want to implement the bus
2. Define the slave devices you want to be attached to that bus
The bus can be implemented using the SPI hardware interface built into the device by using the MISO, MOSI and SCLK pins by using the MAKE_SPI macro described later.
Sometimes the hardware SPI bus may not be suitable or available and so, for alternatives, then look at spisw.h and spiUart.h for other techniques. Note that a software SPI bus will always be the slowest solution at runtime.
When you define slave devices connected to the bus then the format will remain the same and so whichever technique you use for defining the SPI bus, via their respective MAKE commands, then the rest of the code remains the same.
Also note that if you are using the hardware SPI interface then this may also be used by an SPI programmer such as the AVRISP MKII. This means that it is possible to create problems on the SPI bus because it is used by the programmer and by your own program. So as a security measure then I would recommend fitting a pull up resistor (anything from 4.7k ohm to 10k ohm) on each slave device going from the chip select (CS) line to the +ve power supply.
Okay - so lets assume you have chosen an appropriate method to create the SPI bus. So the next thing we need to do is create the slave devices that are attached to the bus so that we can talk to them.
Some slave devices, like sdCards and eeproms, are supported directly by WebbotLib and have their own MAKE commands. However: you may have an unsupported device. In which case you can create a default driver for it using MAKE_SPI_GENERIC_DEVICE (see later).
Repeat the above step to create all of the devices controlled by SPI.
Now you need to group them all together into a list using an SPI_DEVICE_LIST.
Part of the reason for this list is to make sure that only one device on the same bus is 'active' at any one time. This stops things misbehaving or going 'pop'.
Example
So lets assume that we want to create a device that isn't directly supported by WebbotLib and that we use pin B1 to select the chip. We could do it as follows:-
#include "spi.h"
SPI_GENERIC_DEVICE device = MAKE_SPI_GENERIC_DEVICE( SPI_MODE_0, SPI_DATA_ORDER_MSB, B1, 0xFF);
// Now wrap all the devices into a list
SPI_DEVICE_LIST PROGMEM devices[] = { spiGetAbstractDevice(&device) };
SPI bus = MAKE_SPI(devices);
Then in your initialisation code you need to initialise the interface using spiBusInit.
When using the library to talk to a specific device then it will make sure that all other devices are disabled and the target device is enabled.
Since the hardware pins are dictated by your hardware then you may need to check your datasheets to see which pins provide the hardware bus - MISO, MOSI, and SCK.
Here are some examples:
Baby Orangutan168:
BabyOrangutan-Hardware-SPI.jpg
Axon and Axon II:
The bus is available on B3, B2 and B1 respectively. Unfortunately these pins have not been bought out to header pins other than the ISP programmer 3x2 pins. So you will need to use the pins from that connector. This will mean constantly swapping your cable with the hardware programmer cable. Life can be made easier by using the boot loader to program the device over the USB/UART1 connection which frees the ISP connector for your own use. Alternatively use software SPI on the I/O pins which suit you.
Generic 28 pin ATMega8 or ATMega168 board
* 1        28 *
* 2        27 *
* 3        26 *
* 4        25 *
* 5        24 *
* 6        23 *
* 7        22 *
* 8        21 *
* 9        20 *
* 10       19 * SCK/PB5
* 11       18 * MISO/PB4
* 12       17 * MOSI/PB3
* 13       16 *
* 14       15 *

 

Function

 


MAKE_SPI(SPI_DEVICE_LIST* devices)

Create a hardware SPI bus for the specified devices.

MAKE_SPI_GENERIC_DEVICE(SPI_MODE mode, SPI_DATA_ORDER order, const IOPin* chipSelect, uint8_t fillerByte)

Creates a generic SPI slave device.
If WebbotLib doesn't add direct support for your SPI device then use this call to create it. You will then be able to send / receive data to / from it.
The parameters allow you to select the communication protocol and you will need to check the data sheet for your device to find the best settings.
The chipSelect parameter allows you to specify the output pin used to select the device. This is normally connected to the Chip Select (CS) pin.
The 'fillerByte' parameter specifies the data byte that is sent - when only a response is required. The most common value for this parameter is 0xFF.

spiBusInit(SPI_ABSTRACT_BUS* spi, boolean master)

Initialise an SPI interface as a master or as a slave.
Set the 'master' parameter to TRUE for a master or 'FALSE' for a slave.

spiBusOff(SPI_ABSTRACT_BUS* bus)

Turns off the SPI interface.
Turning off the SPI interface may be done to save power. To turn it back on again later then you must issue another call to spiInit.

void spiDeviceSelect(SPI_DEVICE* device, boolean active)

Select, or de-select, the device you are communicating with.
The first parameter is the address of the device and the second parameter should be TRUE to select it, or FALSE to de-select it. Note that if you select a device using this call then it will automatically make sure that any other devices are de-selected first - thus ensuring that only one device can be active at a time.
All of the calls that send, receive or transfer data will automatically call this function to select the device.

void spiDeviceSendByte(const SPI_ABSTRACT_DEVICE* device, uint8_t data)

Sends a single byte.
This will send a byte and ignore the response.

void spiDeviceSendWord(const SPI_ABSTRACT_DEVICE* device, uint16_t data)

Sends a 16 bit (2 byte) number.
Note that this will send the most significant byte first followed by the least significant byte.

uint8_t spiDeviceXferByte(const SPI_ABSTRACT_DEVICE* device, uint8_t data)

Sends a byte over the SPI interface and returns a response.
This will send the data byte and return any response.

uint16_t spiDeviceXferWord(const SPI_ABSTRACT_DEVICE* device, uint16_t data)

Sends a 16 bit value and receives a 16 bit word from the SPI interface.
The values are assumed to be high byte then low byte.

uint8_t spiDeviceReceiveByte(const SPI_ABSTRACT_DEVICE* device)

Receives a byte from the SPI interface.
This will send the 'fillerByte' and return any response.

uint16_t spiDeviceReceiveWord(const SPI_ABSTRACT_DEVICE* device)

Receives a 16 bit word from the SPI interface.
This will send the 'fillerByte' twice. The returned value is assumed to be high byte then low byte.

void spiDeviceReceiveBytes(const SPI_ABSTRACT_DEVICE* device, void* buff, size_t size)

Receives a series of bytes from the SPI interface.
Read the specified number of bytes into a buffer.

void spiDeviceSendBytes(const SPI_ABSTRACT_DEVICE* device, const void* buff, size_t size)

Sends a series of bytes to the SPI interface.
Writes the specified number of bytes from a buffer.

spiBusSetMode(SPI_ABSTRACT_BUS* bus,SPI_MODE mode)

Set the operating mode of the SPI bus.
The mode parameter must be one of the following values:
SPI_MODE_0
SPI_MODE_1
SPI_MODE_2
SPI_MODE_3
NB When a slave device is activated then the mode of the bus will automatically be changed to the correct mode for the device. This means that the bus can contain slave devices that require different operating modes and the library automatically changes to the correct mode for the current device.

SPI_MODE spiBusGetMode(const SPI_ABSTRACT_BUS* bus)

Returns the current operating mode of the SPI bus.
The returned value will be one of the following values:
SPI_MODE_0
SPI_MODE_1
SPI_MODE_2
SPI_MODE_3

spiBusSetDataOrder(SPI_ABSTRACT_BUS* bus,SPI_DATA_ORDER order)

Sets the bit order that will be used to send bytes over the bus.
The 'order' parameter must be one of the following values:-
SPI_DATA_ORDER_MSB
SPI_DATA_ORDER_LSB
NB When a slave device is activated then the ordering of the bus will automatically be changed to the correct ordering for the device. This means that the bus can contain slave devices that require different bit ordering and the library automatically changes to the correct ordering for the current device.

SPI_DATA_ORDER spiBusGetDataOrder(const SPI_ABSTRACT_BUS* bus)

Returns the current bit ordering of the bus.
The returned value will be one of the following values:-
SPI_DATA_ORDER_MSB
SPI_DATA_ORDER_LSB

spiBusSetClock(SPI_ABSTRACT_BUS* bus,SPI_CLOCK clock)

Set the clock speed of the bus.
The 'clock' parameter must be one of the following values:
SPI_CLOCK_DIV2
SPI_CLOCK_DIV4
SPI_CLOCK_DIV8
SPI_CLOCK_DIV16
SPI_CLOCK_DIV32
SPI_CLOCK_DIV64
SPI_CLOCK_DIV128
The clock speed can be changed at any time but the preferred method is to set the required speed before initialising the bus with spiBusInit. Note that the same clock speed is used to talk to all of the slave devices - so you should set it to the speed required by the slowest device on the bus.

SPI_CLOCK spiBusGetClock(SPI_ABSTRACT_BUS* bus)

Returns the current clock speed of the bus.
The returned value will be one of the following values:
SPI_CLOCK_DIV2
SPI_CLOCK_DIV4
SPI_CLOCK_DIV8
SPI_CLOCK_DIV16
SPI_CLOCK_DIV32
SPI_CLOCK_DIV64
SPI_CLOCK_DIV128

Valid XHTML 1.0 Transitional