Defines | Functions

spi.h File Reference

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

Detailed Description

SPI access.


Define Documentation

#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


Function Documentation

void spi_do_select ( uint8_t  ss_enable  )  [inline]

control of SS

Parameters:
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

Parameters:
div SPI speed divider (see chip datasheet)
void spi_set_speed ( uint8_t  div  ) 

set SPI speed divider

Parameters:
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

Parameters:
b byte to write
wait true when we are not sure the previous transfer has already completed
read caller is interested in read byte
Returns:
byte read from SPI slave

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;
  }
}