Function to set up HC11 Serial Peripheral Interface


#include <hc11.h>
#include "spi.h"

void setup_spi(unsigned int spi_control)
/* Function to set up HC11 Serial Peripheral Interface using bits defined in 
 * spi.h
 */
{
    unsigned char temp;

    if (spi_control &  SPI_ENABLE)
    {
        SPCR |= SPI_ENABLE_BIT;
    }
    if (spi_control & SPI_DISABLE)
    {   
        SPCR &= ~SPI_ENABLE_BIT;
    }
    if (spi_control & SPI_INT_ENABLE)
    {   
        SPCR |= SPI_INT_ENABLE_BIT;
    }
    if (spi_control & SPI_INT_DISABLE)
    {   
        SPCR &= ~SPI_INT_ENABLE_BIT;
    }
    if (spi_control & SPI_MASTER)
    {
        DDRD |= 0x38;               /* MOSI, SCK and SS are outputs */
        SPCR |= SPI_MASTER_BIT;
    }
    if (spi_control & SPI_SLAVE)
    {
        DDRD |= 0x04;               /* MISO is output */
        SPCR &= ~SPI_MASTER_BIT;
    }
    if (spi_control & SPI_CPOL_ZERO)
    {
        SPCR &= ~SPI_CPOL_BIT;
    }
    if (spi_control & SPI_CPOL_ONE)
    {
        SPCR |= SPI_CPOL_BIT;
    }
    if (spi_control & SPI_CPHASE_ZERO)
    {
        SPCR &= ~SPI_CPHASE_BIT;
    }
    if (spi_control & SPI_CPHASE_ONE)
    {
        SPCR |= SPI_CPHASE_BIT;
    }
    switch (spi_control & SPI_CSPEED_MASK)
    {
        case SPI_CLOCK_E_DIV2:   SPCR = (SPCR & ~SPI_SPR1_BIT) & ~SPI_SPR0_BIT;
                                 break;
        case SPI_CLOCK_E_DIV4:   SPCR = (SPCR & ~SPI_SPR1_BIT) |  SPI_SPR0_BIT;
                                 break;
        case SPI_CLOCK_E_DIV16:  SPCR = (SPCR |  SPI_SPR1_BIT) & ~SPI_SPR0_BIT;
                                 break;
        case SPI_CLOCK_E_DIV32:  SPCR = (SPCR |  SPI_SPR1_BIT) |  SPI_SPR0_BIT;
                                 break;
        /* No unique speed given:  set for fastest */
        default:                 SPCR = (SPCR & ~SPI_SPR1_BIT) & ~SPI_SPR0_BIT;
    }
    temp = SPSR;
    temp = SPDR;
}

void spi_putchar(unsigned char c)
/*
 * Routine for master to send character c to the SPI.  To send character
 * 1) Select slave
 * 2) spi_putchar(c);
 * 3) Deselect slave
 */
{
    unsigned char temp;

    temp = SPSR;            /* First step in clearing SPIF */
    SPDR = c;               /* Send data to SPI data register -- clears SPIF */
    while (!(SPSR & SPI_FLAG_BIT)) ;  /* Wait for transfer to finish */
}

unsigned char spi_getchar(void)
/*
 * Routine for master to read character c from the SPI.  To read character:
 * 1) Select slave
 * 2) c = spi_getchar();
 * 3) Deselect slave
 */
{
    unsigned char temp;

    temp = SPSR;            /* First step in clearing SPIF */
    SPDR = 0x00;            /* Send data to SPI data register -- clears SPIF */
    while (!(SPSR & SPI_FLAG_BIT)) ;    /* Wait for transfer to finish */
    return SPDR;            /* Read char sent by slave */
}

void spi_put_bytes(unsigned char *s, int n)
/*
 * Routine for master to send a string of characters to the SPI.  
 * To send n chars, with first char at addr ptr, to slave:
 * 1) Select slave
 * 2) putstr_spi(ptr,n);
 * 3) Deselect slave
 */
{
    unsigned char temp;

    temp = SPSR;            /* First step in clearing SPIF */
    for (; n > 0; n--)
    {
        SPDR = *s++;
        while (!(SPSR & SPI_FLAG_BIT)) ;    /* Wait for transfer to finish */
    }
}

void spi_get_bytes(unsigned char *s,int n)
/*
 * Routine for master to read a string of characters from the SPI.  
 * To read string of n chars, with first char to be put at ptr, from slave:
 * 1) Select slave
 * 2) spi_get_bytes(ptr,n);
 * 3) Deselect slave
 */
{
    unsigned char temp;

    temp = SPSR;            /* First step in clearing SPIF */
    for (; n > 0; n--)
    {
        SPDR = 0x00;        /* Send dummy byte to activate SCK */
        while (!(SPSR & SPI_FLAG_BIT)) ;    /* Wait for transfer to finish */
        *s++ = SPDR;        /* Read data from slave into string */
    }
}