#ifndef _SPI_H #define _SPI_H #include "config_wrapper.h" #include "arduino.h" #include "pinio.h" #ifdef SPI /** Test configuration. */ #ifdef __ARMEL__ #error SPI (SD_CARD_SELECT_PIN, TEMP_MAX6675) not yet supported on ARM. #endif // Uncomment this to double SPI frequency from (F_CPU / 4) to (F_CPU / 2). //#define SPI_2X /** Initialise SPI subsystem. */ void spi_init(void); /** SPI device selection. Because out famous WRITE() macro works with constant pins, only, we define a (de)select function for each of them. In case you add another SPI device, you also have to define a pair of these functions. */ #ifdef SD static void spi_select_sd(void) __attribute__ ((always_inline)); inline void spi_select_sd(void) { WRITE(SD_CARD_SELECT_PIN, 0); } static void spi_deselect_sd(void) __attribute__ ((always_inline)); inline void spi_deselect_sd(void) { WRITE(SD_CARD_SELECT_PIN, 1); } #endif /* SD */ #ifdef TEMP_MAX6675 // Note: the pin choosen with DEFINE_TEMP_SENSOR() in the board configuration // should be used here. Currently it's a requirement that this device's // Chip Select pin is actually SS, while any other pin would work just // as fine. static void spi_select_max6675(void) __attribute__ ((always_inline)); inline void spi_select_max6675(void) { WRITE(SS, 0); } static void spi_deselect_max6675(void) __attribute__ ((always_inline)); inline void spi_deselect_max6675(void) { WRITE(SS, 1); } #endif /* TEMP_MAX6675 */ /** Set SPI clock speed to something between 100 and 400 kHz. This is needed for initialising SD cards. We set the whole SPCR register in one step, because this is faster than and'ing in bits. About dividers. We have: SPCR = 0x50; // normal mode: (F_CPU / 4), 2x mode: (F_CPU / 2) SPCR = 0x51; // normal mode: (F_CPU / 16), 2x mode: (F_CPU / 8) SPCR = 0x52; // normal mode: (F_CPU / 64), 2x mode: (F_CPU / 32) SPCR = 0x53; // normal mode: (F_CPU / 128), 2x mode: (F_CPU / 64) For now we always choose the /128 divider, because it fits nicely in all expected situations: F_CPU 16 MHz 20 MHz SPI clock normal mode 125 kHz 156 kHz SPI clock 2x mode 250 kHz 312 kHz About the other bits: 0x50 = (1 << SPE) | (1 << MSTR); This is Master SPI mode, SPI enabled, interrupts disabled, polarity mode 0 (right for SD cards). See ATmega164/324/644/1284 data sheet, section 18.5.1, page 164. */ static void spi_speed_100_400(void) __attribute__ ((always_inline)); inline void spi_speed_100_400(void) { SPCR = 0x53; } /** Set SPI clock speed to maximum. */ static void spi_speed_max(void) __attribute__ ((always_inline)); inline void spi_speed_max(void) { SPCR = 0x50; // See list at spi_speed_100_400(). } /** Exchange a byte over SPI. Yes, SPI is that simple and you can always only swap bytes. To retrieve a byte, simply send a dummy value, like: mybyte = spi_rw(0); As we operate in master mode, we don't have to fear to hang due to communications errors (e.g. missing a clock beat). Note: insisting on inlinig (attribute always_inline) costs about 80 bytes with the current SD card code. */ static uint8_t spi_rw(uint8_t) __attribute__ ((always_inline)); inline uint8_t spi_rw(uint8_t byte) { SPDR = byte; loop_until_bit_is_set(SPSR, SPIF); return SPDR; } #endif /* SPI */ #endif /* _SPI_H */