2.7.1 Common Functionalities

The functionalities of the AVR Dx SPI peripheral in Host/Client mode are similar to ATmega128 when Normal mode is used, but the register names and bit order can be different. The following table shows the mapping of the megaAVR SPI configuration bits into the AVR Dx SPI register structure:

megaAVR®AVR® DxDescription
SPCR.DORDSPI.CTRLA.DORDSPI Data order
SPCR.MSTRSPI.CTRLA.MASTERHost/Client Select
SPCR.CPOLSPI.CTRLB.MODE[1:0]SPI Mode Select
SPCR.CPHA
SPCR.SPR1SPI.CTRLA.PRESC[1:0]SPI Clock Prescaler (divider)
SPCR.SPR0
SPSR.SPI2XSPI.CTRLA.CLK2XClock Double
SPCR.SPESPI.CTRLA.ENABLESPI Enable
SPCR.SPIESPI.INTCTRL.IESPI Interrupt Enable
SPSR.SPIFSPI.INTFLAGS.IFSPI Interrupt Flag
SPSR.WCOLSPI.INTFLAGS.WRCOLWrite Collision Flag
SPDRSPI.DATASPI Data Register

Another difference between families is the I/O pin configuration for use with the SPI peripheral. The megaAVR needs a proper configuration of used pins, while AVR Dx devices overwrite the I/O pin functionality when the pin is used by the SPI peripheral. Refer to the Pin Override section for details.

The following code snippets show initialization of the SPI peripheral in Host mode:

megaAVR® - SPI Initialization in Host Mode

void SPI_MasterInit(void)
{
    /* Set MOSI and SCK output, all others input */  
    DDR_SPI = (1<<DD_MOSI)|(1<<DD_SCK);
    /* Enable SPI, Master, set clock rate fck/16 */
    SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);
}

void SPI_MasterTransmit(char cData)  
{
    /* Start transmission */
    SPDR = cData;
    /* Wait for transmission complete */
    while(!(SPSR & (1<<SPIF)))
    ;
}

AVR® Dx - SPI Initialization in Host Mode

void SPI0_init(void)
{
    PORTA.DIR &= ~PIN4_bm;          /* Set MOSI pin direction to input */
    PORTA.DIR |= PIN5_bm;           /* Set MISO pin direction to output */
    PORTA.DIR &= ~PIN6_bm;          /* Set SCK pin direction to input */
    PORTA.DIR &= ~PIN7_bm;          /* Set SS pin direction to input */
    SPI0.CTRLA = SPI_DORD_bm        /* LSB is transmitted first */
                | SPI_ENABLE_bm     /* Enable module */
                & (~SPI_MASTER_bm); /* SPI module in Client mode */
}

uint8_t SPI0_exchangeData(uint8_t data)
{
    SPI0.DATA = data;
    while (!(SPI0.INTFLAGS & SPI_IF_bm)) /* waits until data is exchanged*/
    {
    ;
    }
    return SPI0.DATA;
}