src/spi.c
author Tero Marttila <terom@paivola.fi>
Thu, 29 Jan 2015 23:11:44 +0200
changeset 107 05707929ff6f
parent 56 3b837eaf1b6d
permissions -rw-r--r--
qmsk.web.async: handle HTTPExceptions
55
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     1
#define SPI_DDR     DDRB
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     2
#define SPI_PORT    PORTB
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     3
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     4
#define SPI_SCK     PORTB5
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     5
#define SPI_MISO    PORTB4
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     6
#define SPI_MOSI    PORTB3
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     7
#define SPI_SS      PORTB2
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     8
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     9
/* State */
56
3b837eaf1b6d hello: expand to two led7seg displays
Tero Marttila <terom@paivola.fi>
parents: 55
diff changeset
    10
#define SPI_COUNT   2
55
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    11
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    12
static char spi_rx[SPI_COUNT], spi_tx[SPI_COUNT];
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    13
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    14
enum {
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    15
    SPI_DORD_MSB        = 0b0,
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    16
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    17
    SPI_DORD            = SPI_DORD_MSB
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    18
};
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    19
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    20
enum {
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    21
    SPI_CPOL_RISING     = 0b0,
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    22
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    23
    SPI_CPOL            = SPI_CPOL_RISING
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    24
};
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    25
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    26
enum {
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    27
    SPI_CPHA_SAMPLE     = 0b0,
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    28
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    29
    SPI_CPHA            = SPI_CPHA_SAMPLE
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    30
};
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    31
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    32
enum {
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    33
    SPI_CLOCK_4         = 0b000,
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    34
    SPI_CLOCK_16        = 0b001,
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    35
    SPI_CLOCK_64        = 0b010,
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    36
    SPI_CLOCK_128       = 0b011,
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    37
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    38
    SPI_CLOCK           = SPI_CLOCK_16
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    39
};
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    40
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    41
/*
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    42
 * Initialize in SPI master mode.
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    43
 */
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    44
void spi_init ()
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    45
{
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    46
    // set output modes
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    47
    sbi(&SPI_DDR, SPI_SCK);     // out
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    48
    sbi(&SPI_DDR, SPI_MOSI);    // out
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    49
    sbi(&SPI_DDR, SPI_SS);      // out
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    50
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    51
    // initialize bus
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    52
    sbi(&SPI_PORT, SPI_SS);     // high (off)
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    53
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    54
    // set mode
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    55
    SPCR = (
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    56
            // SPI Interrupt Enable
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    57
            (0b0 << SPIE) // disable
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    58
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    59
            // SPI Enable
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    60
        |   (0b1 << SPE) // enable
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    61
            
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    62
            // Data Order
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    63
        |   (SPI_DORD << DORD)
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    64
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    65
            // Master/Slave Select
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    66
        |   (0b1 << MSTR) // master
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    67
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    68
            // Clock Polarity
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    69
        |   (SPI_CPOL << CPOL)
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    70
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    71
            // Clock Phase
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    72
        |   (SPI_CPHA << CPHA)
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    73
            
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    74
            // SPI Clock Rate Select
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    75
        |   ((SPI_CLOCK & 0b11) << SPR0)
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    76
    );
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    77
    SPSR = (
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    78
            (((SPI_CLOCK & 0b100) >> 2) << SPI2X)
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    79
    );
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    80
}
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    81
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    82
/*
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    83
 * Perform an SPI bus update.
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    84
 */
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    85
void spi_update ()
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    86
{
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    87
    char i;
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    88
    char *rx = spi_rx + SPI_COUNT, *tx = spi_tx + SPI_COUNT;
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    89
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    90
    // start of packet
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    91
    cbi(&SPI_PORT, SPI_SS); // low
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    92
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    93
    for (i = SPI_COUNT; i > 0; i--) {
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    94
        // out
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    95
        SPDR = *--tx;
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    96
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    97
        // sync
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    98
        while (!tbi(&SPSR, SPIF))
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    99
            ;
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   100
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   101
        *--rx = SPDR;
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   102
    }
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   103
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   104
    // end of packet
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   105
    sbi(&SPI_PORT, SPI_SS); // high
04c625712e35 hello: trivial spi bits
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   106
}