parent
51ea651205
commit
312adbe56c
@ -0,0 +1,62 @@ |
|||||||
|
#include <avr/io.h> |
||||||
|
#include <stdint.h> |
||||||
|
#include <stdbool.h> |
||||||
|
|
||||||
|
#include "iopins.h" |
||||||
|
#include "spi.h" |
||||||
|
|
||||||
|
|
||||||
|
/** Init SPI (for SD card communication) */ |
||||||
|
void spi_init_master(enum SPI_order order, enum SPI_cpol cpol, enum SPI_cpha cpha, enum SPI_clk_div clkdiv) |
||||||
|
{ |
||||||
|
as_output(PIN_SS); // SS output - we control slave
|
||||||
|
as_output(PIN_MOSI); // MOSI output - we talk to slave
|
||||||
|
as_output(PIN_SCK); // SCK output - we're generating clock
|
||||||
|
// MISO is configured automatically as input
|
||||||
|
|
||||||
|
SPCR = 0; |
||||||
|
SPCR |= (1 << MSTR); |
||||||
|
SPCR |= (order << DORD); |
||||||
|
SPCR |= (cpol << CPOL); |
||||||
|
SPCR |= (cpha << CPHA); |
||||||
|
|
||||||
|
// speed
|
||||||
|
SPCR |= (clkdiv & 0b11); |
||||||
|
SPSR = (bool)(clkdiv & 0b100); // write SPI2X flag
|
||||||
|
|
||||||
|
// enable SPI
|
||||||
|
SPCR |= (1 << SPE); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** Init SPI (for SD card communication) */ |
||||||
|
void spi_init_slave(enum SPI_order order, enum SPI_cpol cpol, enum SPI_cpha cpha) |
||||||
|
{ |
||||||
|
as_output(PIN_MISO); // we're listening to master
|
||||||
|
// MOSI, SS, SCK are configured automatically
|
||||||
|
|
||||||
|
SPCR = 0; |
||||||
|
SPCR |= (order << DORD); |
||||||
|
SPCR |= (cpol << CPOL); |
||||||
|
SPCR |= (cpha << CPHA); |
||||||
|
|
||||||
|
// enable SPI
|
||||||
|
SPCR |= (1 << SPE); |
||||||
|
} |
||||||
|
|
||||||
|
/** Write a byte to SPI. Returns received byte. */ |
||||||
|
uint8_t spi_send(uint8_t byte) |
||||||
|
{ |
||||||
|
SPDR = byte; |
||||||
|
while (bit_is_low(SPSR, SPIF)); |
||||||
|
|
||||||
|
return SPDR; |
||||||
|
} |
||||||
|
|
||||||
|
/** Receive (as slave). Blocking. */ |
||||||
|
uint8_t spi_receive(uint8_t reply) |
||||||
|
{ |
||||||
|
SPDR = reply; |
||||||
|
while (bit_is_low(SPSR, SPIF)); |
||||||
|
return SPDR; |
||||||
|
} |
@ -0,0 +1,69 @@ |
|||||||
|
#pragma once |
||||||
|
|
||||||
|
#include <avr/io.h> |
||||||
|
#include <stdint.h> |
||||||
|
|
||||||
|
#include "calc.h" |
||||||
|
#include "iopins.h" |
||||||
|
|
||||||
|
#define PIN_MISO 12 |
||||||
|
#define PIN_MOSI 11 |
||||||
|
#define PIN_SCK 13 |
||||||
|
#define PIN_SS 10 |
||||||
|
|
||||||
|
/** Bit order */ |
||||||
|
enum SPI_order { |
||||||
|
SPI_LSB_FIRST = 0, |
||||||
|
SPI_MSB_FIRST = 1 |
||||||
|
}; |
||||||
|
|
||||||
|
/** Clock polarity */ |
||||||
|
enum SPI_cpol { |
||||||
|
CPOL_0 = 0, |
||||||
|
CPOL_1 = 1 |
||||||
|
}; |
||||||
|
|
||||||
|
/** Clock phase */ |
||||||
|
enum SPI_cpha { |
||||||
|
CPHA_0 = 0, |
||||||
|
CPHA_1 = 1 |
||||||
|
}; |
||||||
|
|
||||||
|
/** Clock prescaller <SPI2X><SPR1><SPR0> */ |
||||||
|
enum SPI_clk_div { |
||||||
|
SPI_DIV_2 = 0b100, // 2x (master only, can't receive at this speed)
|
||||||
|
SPI_DIV_4 = 0b000, |
||||||
|
SPI_DIV_8 = 0b101, // 2x
|
||||||
|
SPI_DIV_16 = 0b001, |
||||||
|
SPI_DIV_32 = 0b110, // 2x
|
||||||
|
SPI_DIV_64 = 0b010, |
||||||
|
SPI_DIV_128 = 0b011 |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
/** Set SS to active state (LOW) */ |
||||||
|
#define spi_ss_enable() pin_down(PIN_SS) |
||||||
|
|
||||||
|
|
||||||
|
/** Set SS to disabled state (HIGH) */ |
||||||
|
#define spi_ss_disable() pin_up(PIN_SS) |
||||||
|
|
||||||
|
|
||||||
|
/** Enable SPI ISR */ |
||||||
|
#define spi_isr_enable(yes) set_bit(SPCR, SPIE, yes) |
||||||
|
|
||||||
|
|
||||||
|
/** Init SPI (for SD card communication) */ |
||||||
|
void spi_init_master(enum SPI_order order, enum SPI_cpol cpol, enum SPI_cpha cpha, enum SPI_clk_div clkdiv); |
||||||
|
|
||||||
|
|
||||||
|
/** Init SPI (for SD card communication) */ |
||||||
|
void spi_init_slave(enum SPI_order order, enum SPI_cpol cpol, enum SPI_cpha cpha); |
||||||
|
|
||||||
|
|
||||||
|
/** Write a byte to SPI. Returns received byte. */ |
||||||
|
uint8_t spi_send(uint8_t byte); |
||||||
|
|
||||||
|
|
||||||
|
/** Receive (as slave). Blocking. */ |
||||||
|
uint8_t spi_receive(uint8_t reply); |
Loading…
Reference in new issue