Add support for the Micropendous (Arduino-like) series of boards (revisions 1 and 2).
[pub/USBasp.git] / LUFA / Drivers / Peripheral / AVR8 / SPI_AVR8.h
index 634c544..2c0ca6e 100644 (file)
@@ -1,13 +1,13 @@
 /*
              LUFA Library
 /*
              LUFA Library
-     Copyright (C) Dean Camera, 2011.
+     Copyright (C) Dean Camera, 2012.
 
   dean [at] fourwalledcubicle [dot] com
            www.lufa-lib.org
 */
 
 /*
 
   dean [at] fourwalledcubicle [dot] com
            www.lufa-lib.org
 */
 
 /*
-  Copyright 2011  Dean Camera (dean [at] fourwalledcubicle [dot] com)
+  Copyright 2012  Dean Camera (dean [at] fourwalledcubicle [dot] com)
 
   Permission to use, copy, modify, distribute, and sell this
   software and its documentation for any purpose is hereby granted
 
   Permission to use, copy, modify, distribute, and sell this
   software and its documentation for any purpose is hereby granted
@@ -70,7 +70,7 @@
  *      // Send a byte, and store the received byte from the same transaction
  *      uint8_t ResponseByte = SPI_TransferByte(0xDC);
  *  \endcode
  *      // Send a byte, and store the received byte from the same transaction
  *      uint8_t ResponseByte = SPI_TransferByte(0xDC);
  *  \endcode
- * 
+ *
  *  @{
  */
 
  *  @{
  */
 
                        /** SPI data sample mode mask for \c SPI_Init(). Indicates that the data should be sampled on the trailing edge. */
                        #define SPI_SAMPLE_TRAILING            (1 << CPHA)
                        //@}
                        /** SPI data sample mode mask for \c SPI_Init(). Indicates that the data should be sampled on the trailing edge. */
                        #define SPI_SAMPLE_TRAILING            (1 << CPHA)
                        //@}
-                       
+
                        /** \name SPI Data Ordering Configuration Masks */
                        //@{
                        /** SPI data order mask for \c SPI_Init(). Indicates that data should be shifted out MSB first. */
                        #define SPI_ORDER_MSB_FIRST            (0 << DORD)
 
                        /** \name SPI Data Ordering Configuration Masks */
                        //@{
                        /** SPI data order mask for \c SPI_Init(). Indicates that data should be shifted out MSB first. */
                        #define SPI_ORDER_MSB_FIRST            (0 << DORD)
 
-                       /** SPI data order mask for \c SPI_Init(). Indicates that data should be shifted out MSB first. */
+                       /** SPI data order mask for \c SPI_Init(). Indicates that data should be shifted out LSB first. */
                        #define SPI_ORDER_LSB_FIRST            (1 << DORD)
                        //@}
                        #define SPI_ORDER_LSB_FIRST            (1 << DORD)
                        //@}
-                       
+
                        /** \name SPI Mode Configuration Masks */
                        //@{
                        /** SPI mode mask for \c SPI_Init(). Indicates that the SPI interface should be initialized into slave mode. */
                        /** \name SPI Mode Configuration Masks */
                        //@{
                        /** SPI mode mask for \c SPI_Init(). Indicates that the SPI interface should be initialized into slave mode. */
                        /** SPI mode mask for \c SPI_Init(). Indicates that the SPI interface should be initialized into master mode. */
                        #define SPI_MODE_MASTER                (1 << MSTR)
                        //@}
                        /** SPI mode mask for \c SPI_Init(). Indicates that the SPI interface should be initialized into master mode. */
                        #define SPI_MODE_MASTER                (1 << MSTR)
                        //@}
-                       
+
                /* Inline Functions: */
                        /** Initializes the SPI subsystem, ready for transfers. Must be called before calling any other
                         *  SPI routines.
                /* Inline Functions: */
                        /** Initializes the SPI subsystem, ready for transfers. Must be called before calling any other
                         *  SPI routines.
                         */
                        static inline void SPI_Init(const uint8_t SPIOptions)
                        {
                         */
                        static inline void SPI_Init(const uint8_t SPIOptions)
                        {
-                               DDRB  |=  ((1 << 1) | (1 << 2));
-                               DDRB  &= ~((1 << 0) | (1 << 3));
-                               PORTB |=  ((1 << 0) | (1 << 3));
+                               /* Prevent high rise times on PB.0 (/SS) from forcing a change to SPI slave mode */
+                               DDRB  |= (1 << 0);
+                               PORTB |= (1 << 0);
 
 
-                               SPCR   = ((1 << SPE) | SPIOptions);
+                               DDRB  |=  ((1 << 1) | (1 << 2));
+                               DDRB  &= ~(1 << 3);
+                               PORTB |=  (1 << 3);
 
                                if (SPIOptions & SPI_USE_DOUBLESPEED)
                                  SPSR |= (1 << SPI2X);
                                else
                                  SPSR &= ~(1 << SPI2X);
 
                                if (SPIOptions & SPI_USE_DOUBLESPEED)
                                  SPSR |= (1 << SPI2X);
                                else
                                  SPSR &= ~(1 << SPI2X);
+
+                               /* Switch /SS to input mode after configuration to allow for forced mode changes */
+                               DDRB &= ~(1 << 0);
+
+                               SPCR  = ((1 << SPE) | SPIOptions);
                        }
 
                        /** Turns off the SPI driver, disabling and returning used hardware to their default configuration. */
                        }
 
                        /** Turns off the SPI driver, disabling and returning used hardware to their default configuration. */
                                SPSR   = 0;
                        }
 
                                SPSR   = 0;
                        }
 
+                       /** Retrieves the currently selected SPI mode, once the SPI interface has been configured.
+                        *
+                        *  \return \ref SPI_MODE_MASTER if the interface is currently in SPI Master mode, \ref SPI_MODE_SLAVE otherwise
+                        */
+                       static inline uint8_t SPI_GetCurrentMode(void) ATTR_ALWAYS_INLINE;
+                       static inline uint8_t SPI_GetCurrentMode(void)
+                       {
+                               return (SPCR & SPI_MODE_MASTER);
+                       }
+
                        /** Sends and receives a byte through the SPI interface, blocking until the transfer is complete.
                         *
                         *  \param[in] Byte  Byte to send through the SPI interface.
                        /** Sends and receives a byte through the SPI interface, blocking until the transfer is complete.
                         *
                         *  \param[in] Byte  Byte to send through the SPI interface.