Aversive/Modules/comm/spi
De Wikidroids
This module enable the use of the SPI hardware on some AVRs. For now, only MASTER mode is available. You can have as many slaves as you want, as long as you don't confuse them by trying to speak to several at the same time.
BIG WARNING: If you use /SS as a slave selector, always register it using spi_register_ss_line() *before* calling spi_init(). Read carrefully the datasheet, especially the paragraph "SS Pin Functionnality" in SPI section. In master mode, the SS pin must be configured as an output OR driven high by an external circuitry.
Usage
So you have one (or several) device(s) that want to speak to your shiny AVR over SPI ? This is fairly easy. First, summon this module with spi_init().You can configure :
- the FORMAT of the link (sample on rising or falling edge, ...)
- the RATE of the connection (you set the prescaler dividing the CPU clock)
You can also set the data order (MSB or LSB first on the link). After that you can register your devices using spi_register_ss_line(); This returns you a device identifier you can use with spi_slave_[de]select(); Remember to ALWAYS select your slave before talking to it, and deselect if once your are done.
API
void spi_set_data_order(uint8_t order); Sets the SPI data order. order can be SPI_MSB_FIRST or SPI_LSB_FIRST. void spi_init(spi_mode_t mode, spi_format_t format, spi_clk_rate_t clk_rate); Starts the SPI module & hardware. For now mode can only be SPI_MODE_MASTER. For the format, see spi.h. The rate param can be SPI_CLK_RATE_X, where X is the prescaler of the SPI clock (2,4,8,16,32,64,128).
int8_t spi_register_ss_line(volatile uint8_t *port, uint8_t bitnum); Register a new slave. port is the adress of the port (Ex : &PORTB) and bitnum is the bit on the port. Returns the slave reference for later use.
uint8_t spi_send_and_receive_byte(uint8_t byte); Sends and receive a byte in full-duplex mode. byte is the byte to send. Returns the received byte.
void spi_send_byte(uint8_t byte); Sends a byte and discards the received value.
uint8_t spi_receive_byte(void); Receives a byte (sends a NULL).
uint8_t spi_slave_select(uint8_t slave); Select the SS line The SPI standard defines that only ONE slave can be selected at any time. An internal mecanism prevents the selection of several slaves at the same time, but this is not completely foolproof. /!\ Behavior is NOT ASSURED if you mess with SS lines outside of this module, so PLEASE use these setters. /!\ This function returns EBUSY if there is already a selected slave.
uint8_t spi_slave_deselect(uint8_t slave); Deselect the SS line.
void spi_display_ss_lines(void); Display all registered SS lines.