Add configurable SPI pin mapping.
authorbernie <bernie@38d2e660-2303-0410-9eaa-f027e97ec537>
Wed, 13 Sep 2006 18:21:24 +0000 (18:21 +0000)
committerbernie <bernie@38d2e660-2303-0410-9eaa-f027e97ec537>
Wed, 13 Sep 2006 18:21:24 +0000 (18:21 +0000)
git-svn-id: https://src.develer.com/svnoss/bertos/trunk@682 38d2e660-2303-0410-9eaa-f027e97ec537

drv/ser.h
drv/ser_avr.c

index edc924d25732d492bdcf7044cda8bbe8a0b96ee1..27f022cd947b6ab532a8c57922e6e7b0a7edfc7f 100755 (executable)
--- a/drv/ser.h
+++ b/drv/ser.h
@@ -14,6 +14,9 @@
 
 /*#*
  *#* $Log$
+ *#* Revision 1.30  2006/09/13 18:21:23  bernie
+ *#* Add configurable SPI pin mapping.
+ *#*
  *#* Revision 1.29  2006/09/13 13:59:11  bernie
  *#* Documentation fixes.
  *#*
 #define SERRF_TX  (SERRF_TXTIMEOUT)
 /*\}*/
 
+/** LSB or MSB first data order, used with SPI AVR serial */
+ * \name LSB or MSB first data order, used with SPI AVR serial
+ * \{
+ */
+#define SER_MSB_FIRST 0
+#define SER_LSB_FIRST 1
+/*\}*/
 
 /**
  * \name Parity settings for ser_setparity().
index dba54b0c3d571fe4062d953b7f6b4f2639d51f48..02a3427e0ac185a3a7be92eac099b67c9ea20965 100755 (executable)
@@ -38,6 +38,9 @@
 
 /*#*
  *#* $Log$
+ *#* Revision 1.33  2006/09/13 18:21:24  bernie
+ *#* Add configurable SPI pin mapping.
+ *#*
  *#* Revision 1.32  2006/07/19 12:56:26  bernie
  *#* Convert to new Doxygen style.
  *#*
 #if CPU_AVR_ATMEGA64 || CPU_AVR_ATMEGA128 || CPU_AVR_ATMEGA103
        #define SPI_PORT      PORTB
        #define SPI_DDR       DDRB
+       #define SPI_SS_BIT    PB0
        #define SPI_SCK_BIT   PB1
        #define SPI_MOSI_BIT  PB2
        #define SPI_MISO_BIT  PB3
 #elif CPU_AVR_ATMEGA8
        #define SPI_PORT      PORTB
        #define SPI_DDR       DDRB
+       #define SPI_SS_BIT    PB2
        #define SPI_SCK_BIT   PB5
        #define SPI_MOSI_BIT  PB3
        #define SPI_MISO_BIT  PB4
@@ -535,11 +540,60 @@ static void spi_init(UNUSED_ARG(struct SerialHardware *, _hw), UNUSED_ARG(struct
         * with the KBus serial RX, and the transmitter of the slave boards
         * would be unable to drive the line.
         */
-       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;
@@ -552,7 +606,7 @@ static void spi_cleanup(UNUSED_ARG(struct SerialHardware *, _hw))
        SER_SPI_BUS_TXCLOSE;
 
        /* Set all pins as inputs */
-       SPI_DDR &= ~(BV(SPI_MISO_BIT) | BV(SPI_MOSI_BIT) | BV(SPI_SCK_BIT));
+       ATOMIC(SPI_DDR &= ~(BV(SPI_MISO_BIT) | BV(SPI_MOSI_BIT) | BV(SPI_SCK_BIT) | BV(SPI_SS_BIT)));
 }
 
 static void spi_starttx(struct SerialHardware *_hw)