AVRly - AVR Development Resources
atmega_spi.c File Reference

Driver for SPI communication between the ATmega328P and other SPI compatible devices. More...

#include <avr/io.h>
#include <avr/interrupt.h>
#include "atmega_spi.h"
#include "pin_defines.h"

Go to the source code of this file.

Functions

void init_spi (spi_transfer_mode_t transfer_mode, spi_control_mode_t control_mode, spi_polarity_mode_t polarity_mode, spi_phase_mode_t phase_mode, spi_clk_rate_t clk_rate, spi_dbl_clk_mode_t dbl_clock)
 Initialisation routine to set up SPI comms. More...
 
uint8_t spi_trade_byte (uint8_t data)
 Sends out a byte of data over SPI and returns the byte it receives. More...
 
uint16_t spi_trade_word (uint16_t data)
 Sends out a 16bit word of data over spi (in two bytes) and returns the byte it receives. More...
 

Detailed Description

Driver for SPI communication between the ATmega328P and other SPI compatible devices.

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Author
Jason Duffy
Date
9th April 2022

This file provides the basic SPI comms setup and initialisation instructions. The following ports/pins must be defined in pin_defines.h: SPI_DDR, SPI_PORT, SPI_MOSI SPI_MISO, SPI_SCK, SPI_SS.

Definition in file atmega_spi.c.

Function Documentation

◆ init_spi()

void init_spi ( spi_transfer_mode_t  transfer_mode,
spi_control_mode_t  control_mode,
spi_polarity_mode_t  polarity_mode,
spi_phase_mode_t  phase_mode,
spi_clk_rate_t  clk_rate,
spi_dbl_clk_mode_t  dbl_clock 
)

Initialisation routine to set up SPI comms.

Must be called before any other functions in this file can be used.

Parameters
transfer_modelsb_first or msb_first.
control_modecontroller or peripheral.
polarity_moderising_edge or falling_edge.
phase_modelead_sample_rising_edge or lead_setup_rising_edge.
clk_rateSets the speed of the SPI clock - divided down from F_CPU speed.
dbl_clocksingle_speed or double_speed.

Definition at line 53 of file atmega_spi.c.

59{
60 SPI_DDR |= (1 << SPI_MOSI); // Set MOSI as output.
61 SPI_DDR |= (1 << SPI_SCK); // Set SCK as output.
62 SPI_DDR &= ~(1 << SPI_MISO); // Set MISO as input.
63 SPI_DDR &= ~(1 << SPI_SS); // Set SS as input.
64 SPI_PORT |= (1 << SPI_MISO); // Set pullup on MISO.
65 SPI_PORT |= (1 << SPI_SS); // Set pullup on SS.
66
67 cli(); // Clear interrupt enable flag.
68 SPCR |= (transfer_mode << DORD); // Set data order.
69 SPCR |= (control_mode << MSTR); // Controller/peripheral mode select.
70 SPCR |= (polarity_mode << CPOL); // Set polarity of SPI data.
71 SPCR |= (phase_mode << CPHA); // Set phase of SPI data.
72 SPCR |= (clk_rate); // Set speed
73
74 SPSR |= (dbl_clock << SPI2X); // Set double speed bit.
75
76 SPCR |= (1 << SPE); // Enable SPI.
77
78 sei(); // Set interrupt enable flag.
79}

◆ spi_trade_byte()

uint8_t spi_trade_byte ( uint8_t  data)

Sends out a byte of data over SPI and returns the byte it receives.

Parameters
uint8_tdata: The byte of data to be sent from the host MCU to the peripheral device.
Returns
The data received from the peripheral device is returned.

Definition at line 85 of file atmega_spi.c.

86{
87 SPDR = data; // Send out byte of data.
88 loop_until_bit_is_set(SPSR, SPIF); // Wait for flag to be set.
89 data = SPDR; // Store the data received.
90 return data;
91}

◆ spi_trade_word()

uint16_t spi_trade_word ( uint16_t  data)

Sends out a 16bit word of data over spi (in two bytes) and returns the byte it receives.

Parameters
uint16_tdata: The byte of data to be sent from the host MCU to the peripheral device.
Returns
The data received from the peripheral device is returned.

Definition at line 98 of file atmega_spi.c.

99{
100 uint8_t msb = 0;
101 uint8_t lsb = 0;
102
103 // Split word to send into 2 bytes and send the first one out.
104 msb |= (data >> 8U);
105 lsb |= (data);
106 SPDR = msb;
107 loop_until_bit_is_set(SPSR, SPIF);
108 msb = SPDR; // Store the byte received.
109
110 // Send the second byte out.
111 SPDR = lsb;
112 loop_until_bit_is_set(SPSR, SPIF);
113 lsb = SPDR; // Store the second byte received.
114
115 // Combine the bytes received into 1 word.
116 uint16_t received_data = 0;
117 received_data = (msb << 8U);
118 received_data |= (lsb);
119
120 return received_data;
121}