spihelper.h

Helper module for SPI communication.  Provides an asynchronous, interrupt-driven request-response API.  This API is master mode only, for the time being.

NOTE: To disable the asynchronous request-response API (see spihelper_request), define the macro SPI_NO_ASYNC_API.  Doing this means that this module won’t define or depend on the SPI_STC_vect ISR, and will use less memory.

CAUTION (ATmegaU): Port C is very small on the ATmegaU (only two pins), so if LIBAVR_ATMEGA_U is defined, the port called “C” in this module is actually hardware port F.

Summary
spihelper.hHelper module for SPI communication.
Macros
SPI_PINRReference to the I/O input register (PINx) for the pins used by the SPI peripheral.
SPI_DDRReference to the I/O direction register (DDRx) for the pins used by the SPI peripheral.
SPI_PORTReference to the I/O output register (PORTx) for the pins used by the SPI peripheral.
SPI_SSRegister bit number of the SS pin of the SPI peripheral.
SPI_MOSIRegister bit number of the MOSI pin of the SPI peripheral.
SPI_MISORegister bit number of the MISO pin of the SPI peripheral.
SPI_SCKRegister bit number of the SCK pin of the SPI peripheral.
SPI_SS_PULLUPAlias of the bit number of the MSTR bit in the SPCR register.
Enumerations
SPI Module State/Result CodesNOTE: The error codes are those with names starting with “SPI_E_”.
Variables
spi_stateThe type of state and result codes for the SPI module.
spi_task_catsTasks in the categories indicated by this sched_catflags value will be notified by the SPI module’s ISR when a request operation finishes (either successfully or with an error).
spi_request_stateContains a state code representing the current state of the SPI module.
Macros
SPI_IS_READYEvaluates to a true value if and only if the SPI module is initialized and ready to begin a new asynchronous operation.
SPI_IS_ACTIVEEvaluates to a true value if and only if the SPI module is busy with an ongoing asynchronous operation.
Functions
spihelper_async_mstr_initConfigures the SPI module for Master mode and sets task categories for notifications.
spihelper_mstr_initConfigures the SPI module for Master mode.
spihelper_initConfigures the SPI module for either Master or Slave mode, depending on the value of the Master/Slave Select (MSTR) bit in the ctrl argument.
spihelper_exchange_bytesSynchronously exchanges a single pair of bytes via the SPI peripheral.
spihelper_requestInitiates an SPI request operation consisting of a transmit phase followed by a receive phase.
spihelper_shutdownDisables the SPI module.

Macros

SPI_PINR

Reference to the I/O input register (PINx) for the pins used by the SPI peripheral.  Constant macro.

SPI_DDR

Reference to the I/O direction register (DDRx) for the pins used by the SPI peripheral.  Constant macro.

SPI_PORT

Reference to the I/O output register (PORTx) for the pins used by the SPI peripheral.  Constant macro.

SPI_SS

Register bit number of the SS pin of the SPI peripheral.  Constant macro.

SPI_MOSI

Register bit number of the MOSI pin of the SPI peripheral.  Constant macro.

SPI_MISO

Register bit number of the MISO pin of the SPI peripheral.  Constant macro.

SPI_SCK

Register bit number of the SCK pin of the SPI peripheral.  Constant macro.

SPI_SS_PULLUP

Alias of the bit number of the MSTR bit in the SPCR register.  May be used to clarify its use to enable the pull-up on the SS pin when set in the ctrl argument of spihelper_mstr_init or spihelper_async_mstr_init.  Constant macro.

Enumerations

SPI Module State/Result Codes

NOTE: The error codes are those with names starting with “SPI_E_”.  These all have numeric values greater than or equal to SPI_E_UNSPECIFIED.

SPI_DISABLEDmodule is disabled
SPI_SLAVEmodule is configured as a slave
SPI_READYmodule is idle as master and ready to begin a new operation
SPI_ACTIVEmodule is currently performing an operation
SPI_E_UNSPECIFIEDunspecified error
SPI_E_LENGTHSPI length error (bytes to transmit and receive both zero)
SPI_E_STATEattempted operation not allowed in current module state

Variables

spi_state

typedef uint8_t spi_state

The type of state and result codes for the SPI module.

spi_task_cats

extern volatile sched_catflags spi_task_cats

Tasks in the categories indicated by this sched_catflags value will be notified by the SPI module’s ISR when a request operation finishes (either successfully or with an error).

spi_request_state

extern volatile spi_state spi_request_state

Contains a state code representing the current state of the SPI module.

CAUTION: Do not update this variable in external code, unless you know what you’re doing.

Macros

SPI_IS_READY

Evaluates to a true value if and only if the SPI module is initialized and ready to begin a new asynchronous operation.  Expression macro.

SPI_IS_ACTIVE

Evaluates to a true value if and only if the SPI module is busy with an ongoing asynchronous operation.  Expression macro.

Functions

spihelper_async_mstr_init

void spihelper_async_mstr_init(uint8_t ss_b,
uint8_t ss_c,
uint8_t ss_d,
uint8_t ctrl,
sched_catflags task_cats)

Configures the SPI module for Master mode and sets task categories for notifications.

NOTE: This function invokes spihelper_mstr_init internally.  See that function for full details.

Parameters

ss_bBit flags specifying the pins in I/O port B that should be readied for use as SPI Slave Select output pins.
ss_cBit flags specifying the pins in I/O port C that should be readied for use as SPI Slave Select output pins.
ss_dBit flags specifying the pins in I/O port D that should be readied for use as SPI Slave Select output pins.
ctrlValue to assign to the SPI Control Register (SPCR).  If the MSTR bit in this parameter is set to one, then the Slave mode Slave Select pin will be made an input and have its pull-up enabled, to avoid accidental triggering of the slave-on-demand feature of the SPI peripheral.
task_catsA set of bit flags specifying task categories whose members should be notified when this module has finished an SPI transaction.  Used to initialize spi_task_cats.

spihelper_mstr_init

void spihelper_mstr_init(uint8_t ss_b,
uint8_t ss_c,
uint8_t ss_d,
uint8_t ctrl)

Configures the SPI module for Master mode.

I/O pins that are marked as Slave Select output pins via ss_x parameters will be configured as outputs and driven high by this function.  The output high / pull-up enable state will be set before the data direction is set to output.

NOTE: When this function returns, the SPI Enable (SPE) bit in the SPI Control Register (SPCR) will always be set to one, regardless of its value in the ctrl parameter.  The Master/Slave Select (MSTR) bit will likewise always be set to one.

NOTE: This function invokes spihelper_init internally.

Parameters

ss_bBit flags specifying the pins in I/O port B that should be readied for use as SPI Slave Select output pins.
ss_cBit flags specifying the pins in I/O port C that should be readied for use as SPI Slave Select output pins.
ss_dBit flags specifying the pins in I/O port D that should be readied for use as SPI Slave Select output pins.
ctrlValue to assign to the SPI Control Register (SPCR).  If the MSTR bit in this parameter is set to one, then the Slave mode Slave Select pin will be made an input and have its pull-up enabled, to avoid accidental triggering of the slave-on-demand feature of the SPI peripheral.

spihelper_init

void spihelper_init(uint8_t ctrl)

Configures the SPI module for either Master or Slave mode, depending on the value of the Master/Slave Select (MSTR) bit in the ctrl argument.

NOTE: When this function returns, the SPI Enable (SPE) bit in the SPI Control Register (SPCR) will always be set to one, regardless of its value in the ctrl parameter.

NOTE: This function does not deal with the SPI2X configuration bit in the SPI Status Register (SPSR).  If necessary, that bit SHOULD be set (or cleared) in application code before calling this function.

Parameters

ctrlValue to assign to the SPI Control Register (SPCR).  If the MSTR bit in this parameter is set to one, the SPI module will be configured for Master mode, otherwise, it will be configured for Slave mode.

spihelper_exchange_bytes

uint8_t spihelper_exchange_bytes(uint8_t data_out)

Synchronously exchanges a single pair of bytes via the SPI peripheral.

NOTE: This function does NOT manipulate any Slave Select pins.  Application developers MUST ensure that appropriate slave selection has been performed before this function is called.

CAUTION: This function does NOT check the current state of the SPI module and MUST NOT be called when the module is uninitialized or busy with an asynchronous operation.

Parameters

data_outData byte to transmit.

Returns

The received data byte.

spihelper_request

spi_state spihelper_request(uint8_t n_out,
volatile const uint8_t *bfr_out,
uint8_t n_in,
uint8_t offset_in,
volatile uint8_t *bfr_in)

Initiates an SPI request operation consisting of a transmit phase followed by a receive phase.  Either the transmit or the receive phase can be omitted, but not both.  This function only works if the SPI module has been configured for Master mode.

Completion of an SPI request initiated by this function can be detected by polling spi_request_state (e.g. via the SPI_IS_ACTIVE macro) and by specifying task categories to be notified via spi_task_cats.

NOTE: This function does NOT manipulate any Slave Select pins.  Application developers MUST ensure that appropriate slave selection has been performed before this function is called.

NOTE: The bfr_out and bfr_in arguments MAY point to the same buffer.  This function ensures that any byte to transmit from bfr_out[i] is transmitted before any received byte is stored at bfr_in[i].

NOTE: The default dummy byte transmitted by this function is zero.  A different dummy value can be specified by defining the macro SPI_DUMMY_BYTE as the desired dummy value.  (Make this a compile-time constant, please.)

Parameters

n_outNumber of data bytes to transmit.  If this argument is zero, the transmit phase will be omitted.  If offset_in+n_in is greater than n_out, the SPI module will begin transmitting dummy bytes after transmitting n_out bytes from bfr_out.
bfr_outPointer to the data bytes to transmit.  If n_out is zero, this MAY be a null pointer.
n_inNumber of data bytes to receive.  If this argument is zero, the receive phase will be omitted.
offset_inNumber of received bytes to discard before starting the receive phase.  The total number of bytes exchanged to perform the SPI request operation will be max(n_out, offset_in+n_in), unless n_in is zero.  If n_in is zero, this argument is ignored.
bfr_inPointer to memory to copy received data bytes into.  If n_in is zero, this MAY be a null pointer.

Returns

SPI_ACTIVE if and only if the request operation was successfully started, otherwise an error code.

spihelper_shutdown

void spihelper_shutdown(void)

Disables the SPI module.

typedef uint8_t spi_state
The type of state and result codes for the SPI module.
extern volatile sched_catflags spi_task_cats
Tasks in the categories indicated by this sched_catflags value will be notified by the SPI module’s ISR when a request operation finishes (either successfully or with an error).
typedef uint16_t sched_catflags
The type of fields containing sets of bit flags that correspond to task categories.
extern volatile spi_state spi_request_state
Contains a state code representing the current state of the SPI module.
void spihelper_async_mstr_init(uint8_t ss_b,
uint8_t ss_c,
uint8_t ss_d,
uint8_t ctrl,
sched_catflags task_cats)
Configures the SPI module for Master mode and sets task categories for notifications.
void spihelper_mstr_init(uint8_t ss_b,
uint8_t ss_c,
uint8_t ss_d,
uint8_t ctrl)
Configures the SPI module for Master mode.
void spihelper_init(uint8_t ctrl)
Configures the SPI module for either Master or Slave mode, depending on the value of the Master/Slave Select (MSTR) bit in the ctrl argument.
uint8_t spihelper_exchange_bytes(uint8_t data_out)
Synchronously exchanges a single pair of bytes via the SPI peripheral.
spi_state spihelper_request(uint8_t n_out,
volatile const uint8_t *bfr_out,
uint8_t n_in,
uint8_t offset_in,
volatile uint8_t *bfr_in)
Initiates an SPI request operation consisting of a transmit phase followed by a receive phase.
void spihelper_shutdown(void)
Disables the SPI module.
Evaluates to a true value if and only if the SPI module is busy with an ongoing asynchronous operation.
module is currently performing an operation
Close