|
|
|
|
|
|
|
|
while (!(SPSR & _BV(SPIF))) ; // wait |
|
|
while (!(SPSR & _BV(SPIF))) ; // wait |
|
|
return SPDR; |
|
|
return SPDR; |
|
|
} |
|
|
} |
|
|
|
|
|
inline static uint16_t transfer16(uint16_t data) { |
|
|
|
|
|
union { uint16_t val; struct { uint8_t lsb; uint8_t msb; }; } in, out; |
|
|
|
|
|
in.val = data; |
|
|
|
|
|
if (!(SPCR & _BV(DORD))) { |
|
|
|
|
|
SPDR = in.msb; |
|
|
|
|
|
while (!(SPSR & _BV(SPIF))) ; |
|
|
|
|
|
out.msb = SPDR; |
|
|
|
|
|
SPDR = in.lsb; |
|
|
|
|
|
while (!(SPSR & _BV(SPIF))) ; |
|
|
|
|
|
out.lsb = SPDR; |
|
|
|
|
|
} else { |
|
|
|
|
|
SPDR = in.lsb; |
|
|
|
|
|
while (!(SPSR & _BV(SPIF))) ; |
|
|
|
|
|
out.lsb = SPDR; |
|
|
|
|
|
SPDR = in.msb; |
|
|
|
|
|
while (!(SPSR & _BV(SPIF))) ; |
|
|
|
|
|
out.msb = SPDR; |
|
|
|
|
|
} |
|
|
|
|
|
return out.val; |
|
|
|
|
|
} |
|
|
inline static void transfer(void *buf, size_t count) { |
|
|
inline static void transfer(void *buf, size_t count) { |
|
|
if (count == 0) return; |
|
|
if (count == 0) return; |
|
|
uint8_t *p = (uint8_t *)buf; |
|
|
uint8_t *p = (uint8_t *)buf; |
|
|
|
|
|
|
|
|
// Write to the SPI bus (MOSI pin) and also receive (MISO pin) |
|
|
// Write to the SPI bus (MOSI pin) and also receive (MISO pin) |
|
|
inline static uint8_t transfer(uint8_t data) { |
|
|
inline static uint8_t transfer(uint8_t data) { |
|
|
SPDR = data; |
|
|
SPDR = data; |
|
|
asm volatile("nop"); |
|
|
|
|
|
while (!(SPSR & _BV(SPIF))) ; // wait |
|
|
while (!(SPSR & _BV(SPIF))) ; // wait |
|
|
return SPDR; |
|
|
return SPDR; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
inline static void setSCK(uint8_t pin) __attribute__((always_inline)) { |
|
|
inline static void setSCK(uint8_t pin) __attribute__((always_inline)) { |
|
|
SPCR.setSCK(pin); |
|
|
SPCR.setSCK(pin); |
|
|
} |
|
|
} |
|
|
|
|
|
// return true if "pin" has special chip select capability |
|
|
|
|
|
static bool pinIsChipSelect(uint8_t pin); |
|
|
|
|
|
// return true if both pin1 and pin2 have independent chip select capability |
|
|
|
|
|
static bool pinIsChipSelect(uint8_t pin1, uint8_t pin2); |
|
|
|
|
|
// configure a pin for chip select and return its SPI_MCR_PCSIS bitmask |
|
|
|
|
|
static uint8_t setCS(uint8_t pin); |
|
|
|
|
|
|
|
|
private: |
|
|
private: |
|
|
static uint8_t interruptMode; // 0=none, 1=mask, 2=global |
|
|
static uint8_t interruptMode; // 0=none, 1=mask, 2=global |