SPI access. More...
#include <stdint.h>
#include <avr/io.h>
#include <util/delay.h>
Go to the source code of this file.
Defines | |
#define | spi_write(b) spi_transfer ((b), 1, 0) |
write a single byte to SPI | |
#define | spi_read(b) spi_transfer (b, 1, 1) |
read a single byte from SPI | |
#define | spi_select() spi_do_select (1) |
select SPI slave | |
#define | spi_deselect() spi_do_select (0) |
deselect SPI slave | |
Functions | |
void | spi_init (uint8_t div) |
initialize SPI interface | |
void | spi_set_speed (uint8_t div) |
set SPI speed divider | |
uint8_t | spi_transfer (uint8_t b, uint8_t wait, uint8_t read) |
transfer one byte via SPI | |
void | spi_do_select (uint8_t ss_enable) |
control of SS |
SPI access.
#define spi_read | ( | b | ) | spi_transfer (b, 1, 1) |
read a single byte from SPI
Write byte b to SPI, return byte read
#define spi_write | ( | b | ) | spi_transfer ((b), 1, 0) |
write a single byte to SPI
Write a single byte to SPI without waiting for completion
void spi_do_select | ( | uint8_t | ss_enable | ) | [inline] |
control of SS
ss_enable | true when SS should be active (=low) |
Control SPI SS line. When selecting it is assumed that no transmission was ongoing. When deselecting the function waits for the last transmission to complete.
{ if (!ss_enable) /* when selecting, we expect the previous transmission to * be complete (we already waited at de-select time) */ while (0 && !(SPSR & _BV(SPIF))); if (ss_enable) { PORT_SPI &= ~_BV(PORT_SPI_SS); } else PORT_SPI |= _BV(PORT_SPI_SS); }
void spi_init | ( | uint8_t | div | ) |
initialize SPI interface
div | SPI speed divider (see chip datasheet) |
void spi_set_speed | ( | uint8_t | div | ) |
set SPI speed divider
div,: | divider for SPI clock possible values: 2 4 8 16 32 64 128 gets rounded up to next possible value |
uint8_t spi_transfer | ( | uint8_t | b, | |
uint8_t | wait, | |||
uint8_t | read | |||
) | [inline] |
transfer one byte via SPI
b | byte to write | |
wait | true when we are not sure the previous transfer has already completed | |
read | caller is interested in read byte |
it is expected that wait and read are constants so the compiler can optimize out the loop and the register read when not needed
{ uint8_t spsr; SPDR = b; if (wait && (spsr = SPSR) & _BV(WCOL)) { /* after write collision just wait for SPIF */ while (!(spsr & _BV(SPIF))) spsr = SPSR; SPDR = b; } /* at this point, we started the transfer */ if (read) { /* wait for completion */ if (!wait) spsr = SPSR; while (!(spsr & _BV(SPIF))) spsr = SPSR; return SPDR; } else { /* we don't care when the transfer finishes */ return 0xff; } }