- SPI_DDR |= BV(SPI_MOSI_BIT) | BV(SPI_SCK_BIT);
- SPI_DDR &= ~BV(SPI_MISO_BIT);
- /* Enable SPI, IRQ on, Master, CPU_CLOCK/16 */
- SPCR = BV(SPE) | BV(SPIE) | BV(MSTR) | BV(SPR0);
+ ATOMIC(SPI_DDR |= (BV(SPI_MOSI_BIT) | BV(SPI_SCK_BIT)));
+
+ /*
+ * If the SPI master mode is activated and the SS pin is in input and tied low,
+ * the SPI hardware will automatically switch to slave mode!
+ * For proper communication this pins should therefore be:
+ * - as output
+ * - as input but tied high forever!
+ * This driver set the pin as output.
+ */
+ #warning SPI SS pin set as output for proper operation, check schematics for possible conflicts.
+ ATOMIC(SPI_DDR |= BV(SPI_SS_BIT));
+
+ ATOMIC(SPI_DDR &= ~BV(SPI_MISO_BIT));
+ /* Enable SPI, IRQ on, Master */
+ SPCR = BV(SPE) | BV(SPIE) | BV(MSTR);
+
+ /* Set data order */
+ #if CONFIG_SPI_DATA_ORDER == SER_LSB_FIRST
+ SPCR |= BV(DORD);
+ #endif
+
+ /* Set SPI clock rate */
+ #if CONFIG_SPI_CLOCK_DIV == 128
+ SPCR |= (BV(SPR1) | BV(SPR0));
+ #elif (CONFIG_SPI_CLOCK_DIV == 64 || CONFIG_SPI_CLOCK_DIV == 32)
+ SPCR |= BV(SPR1);
+ #elif (CONFIG_SPI_CLOCK_DIV == 16 || CONFIG_SPI_CLOCK_DIV == 8)
+ SPCR |= BV(SPR0);
+ #elif (CONFIG_SPI_CLOCK_DIV == 4 || CONFIG_SPI_CLOCK_DIV == 2)
+ // SPR0 & SDPR1 both at 0
+ #else
+ #error Unsupported SPI clock division factor.
+ #endif
+
+ /* Set SPI2X bit (spi double frequency) */
+ #if (CONFIG_SPI_CLOCK_DIV == 128 || CONFIG_SPI_CLOCK_DIV == 64 \
+ || CONFIG_SPI_CLOCK_DIV == 16 || CONFIG_SPI_CLOCK_DIV == 4)
+ SPSR &= ~BV(SPI2X);
+ #elif (CONFIG_SPI_CLOCK_DIV == 32 || CONFIG_SPI_CLOCK_DIV == 8 || CONFIG_SPI_CLOCK_DIV == 2)
+ SPSR |= BV(SPI2X);
+ #else
+ #error Unsupported SPI clock division factor.
+ #endif
+
+ /* Set clock polarity */
+ #if CONFIG_SPI_CLOCK_POL == 1
+ SPCR |= BV(CPOL);
+ #endif
+
+ /* Set clock phase */
+ #if CONFIG_SPI_CLOCK_PHASE == 1
+ SPCR |= BV(CPHA);
+ #endif
+ SER_SPI_BUS_TXINIT;
+
+ SER_STROBE_INIT;