- /** \name SPI SCK Polarity Configuration Masks */
- //@{
- /** SPI clock polarity mask for \c SPI_Init(). Indicates that the SCK should lead on the rising edge. */
- #define SPI_SCK_LEAD_RISING (0 << CPOL)
-
- /** SPI clock polarity mask for \c SPI_Init(). Indicates that the SCK should lead on the falling edge. */
- #define SPI_SCK_LEAD_FALLING (1 << CPOL)
- //@}
-
- /** \name SPI Sample Edge Configuration Masks */
- //@{
- /** SPI data sample mode mask for \c SPI_Init(). Indicates that the data should sampled on the leading edge. */
- #define SPI_SAMPLE_LEADING (0 << CPHA)
-
- /** SPI data sample mode mask for \c SPI_Init(). Indicates that the data should be sampled on the trailing edge. */
- #define SPI_SAMPLE_TRAILING (1 << CPHA)
- //@}
-
- /** \name SPI Data Ordering Configuration Masks */
- //@{
- /** SPI data order mask for \c SPI_Init(). Indicates that data should be shifted out MSB first. */
- #define SPI_ORDER_MSB_FIRST (0 << DORD)
-
- /** SPI data order mask for \c SPI_Init(). Indicates that data should be shifted out MSB first. */
- #define SPI_ORDER_LSB_FIRST (1 << DORD)
- //@}
-
- /** \name SPI Mode Configuration Masks */
- //@{
- /** SPI mode mask for \c SPI_Init(). Indicates that the SPI interface should be initialized into slave mode. */
- #define SPI_MODE_SLAVE (0 << MSTR)
-
- /** SPI mode mask for \c SPI_Init(). Indicates that the SPI interface should be initialized into master mode. */
- #define SPI_MODE_MASTER (1 << MSTR)
- //@}
-
- /* Inline Functions: */
- /** Initialises the SPI subsystem, ready for transfers. Must be called before calling any other
- * SPI routines.
- *
- * \param[in] SPIOptions SPI Options, a mask consisting of one of each of the \c SPI_SPEED_*,
- * \c SPI_SCK_*, \c SPI_SAMPLE_*, \c SPI_ORDER_* and \c SPI_MODE_* masks.
- */
- static inline void SPI_Init(const uint8_t SPIOptions)
- {
- DDRB |= ((1 << 1) | (1 << 2));
- DDRB &= ~((1 << 0) | (1 << 3));
- PORTB |= ((1 << 0) | (1 << 3));
-
- SPCR = ((1 << SPE) | SPIOptions);
-
- if (SPIOptions & SPI_USE_DOUBLESPEED)
- SPSR |= (1 << SPI2X);
- else
- SPSR &= ~(1 << SPI2X);
- }
-
- /** Turns off the SPI driver, disabling and returning used hardware to their default configuration. */
- static inline void SPI_Disable(void)
- {
- DDRB &= ~((1 << 1) | (1 << 2));
- PORTB &= ~((1 << 0) | (1 << 3));
-
- SPCR = 0;
- SPSR = 0;
- }
-
- /** Sends and receives a byte through the SPI interface, blocking until the transfer is complete.
- *
- * \param[in] Byte Byte to send through the SPI interface.
- *
- * \return Response byte from the attached SPI device.
- */
- static inline uint8_t SPI_TransferByte(const uint8_t Byte) ATTR_ALWAYS_INLINE;
- static inline uint8_t SPI_TransferByte(const uint8_t Byte)
- {
- SPDR = Byte;
- while (!(SPSR & (1 << SPIF)));
- return SPDR;
- }
-
- /** Sends a byte through the SPI interface, blocking until the transfer is complete. The response
- * byte sent to from the attached SPI device is ignored.
- *
- * \param[in] Byte Byte to send through the SPI interface.
- */
- static inline void SPI_SendByte(const uint8_t Byte) ATTR_ALWAYS_INLINE;
- static inline void SPI_SendByte(const uint8_t Byte)
- {
- SPDR = Byte;
- while (!(SPSR & (1 << SPIF)));
- }
-
- /** Sends a dummy byte through the SPI interface, blocking until the transfer is complete. The response
- * byte from the attached SPI device is returned.
- *
- * \return The response byte from the attached SPI device.
- */
- static inline uint8_t SPI_ReceiveByte(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT;
- static inline uint8_t SPI_ReceiveByte(void)
- {
- SPDR = 0x00;
- while (!(SPSR & (1 << SPIF)));
- return SPDR;
- }