Statistics
| Branch: | Tag: | Revision:

root / LUFA / Drivers / Peripheral / AVR8 / SPI_AVR8.h @ 978b99e5

History | View | Annotate | Download (9.31 KB)

1
/*
2
             LUFA Library
3
     Copyright (C) Dean Camera, 2011.
4

5
  dean [at] fourwalledcubicle [dot] com
6
           www.lufa-lib.org
7
*/
8

    
9
/*
10
  Copyright 2011  Dean Camera (dean [at] fourwalledcubicle [dot] com)
11

12
  Permission to use, copy, modify, distribute, and sell this
13
  software and its documentation for any purpose is hereby granted
14
  without fee, provided that the above copyright notice appear in
15
  all copies and that both that the copyright notice and this
16
  permission notice and warranty disclaimer appear in supporting
17
  documentation, and that the name of the author not be used in
18
  advertising or publicity pertaining to distribution of the
19
  software without specific, written prior permission.
20

21
  The author disclaim all warranties with regard to this
22
  software, including all implied warranties of merchantability
23
  and fitness.  In no event shall the author be liable for any
24
  special, indirect or consequential damages or any damages
25
  whatsoever resulting from loss of use, data or profits, whether
26
  in an action of contract, negligence or other tortious action,
27
  arising out of or in connection with the use or performance of
28
  this software.
29
*/
30

    
31
/** \file
32
 *  \brief SPI Peripheral Driver (AVR8)
33
 *
34
 *  On-chip SPI driver for the 8-bit AVR microcontrollers.
35
 *
36
 *  \note This file should not be included directly. It is automatically included as needed by the SPI driver
37
 *        dispatch header located in LUFA/Drivers/Peripheral/SPI.h.
38
 */
39

    
40
/** \ingroup Group_SPI
41
 *  \defgroup Group_SPI_AVR8 SPI Peripheral Driver (AVR8)
42
 *
43
 *  \section Sec_ModDescription Module Description
44
 *  Driver for the hardware SPI port available on most 8-bit AVR microcontroller models. This
45
 *  module provides an easy to use driver for the setup and transfer of data over the
46
 *  AVR's SPI port.
47
 *
48
 *  \note This file should not be included directly. It is automatically included as needed by the SPI driver
49
 *        dispatch header located in LUFA/Drivers/Peripheral/SPI.h.
50
 *
51
 *  \section Sec_ExampleUsage Example Usage
52
 *  The following snippet is an example of how this module may be used within a typical
53
 *  application.
54
 *
55
 *  \code
56
 *      // Initialize the SPI driver before first use
57
 *      SPI_Init(SPI_SPEED_FCPU_DIV_2 | SPI_ORDER_MSB_FIRST | SPI_SCK_LEAD_FALLING |
58
 *               SPI_SAMPLE_TRAILING | SPI_MODE_MASTER);
59
 *
60
 *      // Send several bytes, ignoring the returned data
61
 *      SPI_SendByte(0x01);
62
 *      SPI_SendByte(0x02);
63
 *      SPI_SendByte(0x03);
64
 *
65
 *      // Receive several bytes, sending a dummy 0x00 byte each time
66
 *      uint8_t Byte1 = SPI_ReceiveByte();
67
 *      uint8_t Byte2 = SPI_ReceiveByte();
68
 *      uint8_t Byte3 = SPI_ReceiveByte();
69
 *
70
 *      // Send a byte, and store the received byte from the same transaction
71
 *      uint8_t ResponseByte = SPI_TransferByte(0xDC);
72
 *  \endcode
73
 * 
74
 *  @{
75
 */
76

    
77
#ifndef __SPI_AVR8_H__
78
#define __SPI_AVR8_H__
79

    
80
        /* Includes: */
81
                #include "../../../Common/Common.h"
82

    
83
        /* Enable C linkage for C++ Compilers: */
84
                #if defined(__cplusplus)
85
                        extern "C" {
86
                #endif
87

    
88
        /* Preprocessor Checks: */
89
                #if !defined(__INCLUDE_FROM_SPI_H)
90
                        #error Do not include this file directly. Include LUFA/Drivers/Peripheral/SPI.h instead.
91
                #endif
92

    
93
        /* Private Interface - For use in library only: */
94
        #if !defined(__DOXYGEN__)
95
                /* Macros: */
96
                        #define SPI_USE_DOUBLESPEED            (1 << SPE)
97
        #endif
98

    
99
        /* Public Interface - May be used in end-application: */
100
                /* Macros: */
101
                        /** \name SPI Prescaler Configuration Masks */
102
                        //@{
103
                        /** SPI prescaler mask for \c SPI_Init(). Divides the system clock by a factor of 2. */
104
                        #define SPI_SPEED_FCPU_DIV_2           SPI_USE_DOUBLESPEED
105

    
106
                        /** SPI prescaler mask for \c SPI_Init(). Divides the system clock by a factor of 4. */
107
                        #define SPI_SPEED_FCPU_DIV_4           0
108

    
109
                        /** SPI prescaler mask for \c SPI_Init(). Divides the system clock by a factor of 8. */
110
                        #define SPI_SPEED_FCPU_DIV_8           (SPI_USE_DOUBLESPEED | (1 << SPR0))
111

    
112
                        /** SPI prescaler mask for \c SPI_Init(). Divides the system clock by a factor of 16. */
113
                        #define SPI_SPEED_FCPU_DIV_16          (1 << SPR0)
114

    
115
                        /** SPI prescaler mask for \c SPI_Init(). Divides the system clock by a factor of 32. */
116
                        #define SPI_SPEED_FCPU_DIV_32          (SPI_USE_DOUBLESPEED | (1 << SPR1))
117

    
118
                        /** SPI prescaler mask for \c SPI_Init(). Divides the system clock by a factor of 64. */
119
                        #define SPI_SPEED_FCPU_DIV_64          (SPI_USE_DOUBLESPEED | (1 << SPR1) | (1 << SPR0))
120

    
121
                        /** SPI prescaler mask for \c SPI_Init(). Divides the system clock by a factor of 128. */
122
                        #define SPI_SPEED_FCPU_DIV_128         ((1 << SPR1) | (1 << SPR0))
123
                        //@}
124

    
125
                        /** \name SPI SCK Polarity Configuration Masks */
126
                        //@{
127
                        /** SPI clock polarity mask for \c SPI_Init(). Indicates that the SCK should lead on the rising edge. */
128
                        #define SPI_SCK_LEAD_RISING            (0 << CPOL)
129

    
130
                        /** SPI clock polarity mask for \c SPI_Init(). Indicates that the SCK should lead on the falling edge. */
131
                        #define SPI_SCK_LEAD_FALLING           (1 << CPOL)
132
                        //@}
133

    
134
                        /** \name SPI Sample Edge Configuration Masks */
135
                        //@{
136
                        /** SPI data sample mode mask for \c SPI_Init(). Indicates that the data should sampled on the leading edge. */
137
                        #define SPI_SAMPLE_LEADING             (0 << CPHA)
138

    
139
                        /** SPI data sample mode mask for \c SPI_Init(). Indicates that the data should be sampled on the trailing edge. */
140
                        #define SPI_SAMPLE_TRAILING            (1 << CPHA)
141
                        //@}
142
                        
143
                        /** \name SPI Data Ordering Configuration Masks */
144
                        //@{
145
                        /** SPI data order mask for \c SPI_Init(). Indicates that data should be shifted out MSB first. */
146
                        #define SPI_ORDER_MSB_FIRST            (0 << DORD)
147

    
148
                        /** SPI data order mask for \c SPI_Init(). Indicates that data should be shifted out LSB first. */
149
                        #define SPI_ORDER_LSB_FIRST            (1 << DORD)
150
                        //@}
151
                        
152
                        /** \name SPI Mode Configuration Masks */
153
                        //@{
154
                        /** SPI mode mask for \c SPI_Init(). Indicates that the SPI interface should be initialized into slave mode. */
155
                        #define SPI_MODE_SLAVE                 (0 << MSTR)
156

    
157
                        /** SPI mode mask for \c SPI_Init(). Indicates that the SPI interface should be initialized into master mode. */
158
                        #define SPI_MODE_MASTER                (1 << MSTR)
159
                        //@}
160
                        
161
                /* Inline Functions: */
162
                        /** Initializes the SPI subsystem, ready for transfers. Must be called before calling any other
163
                         *  SPI routines.
164
                         *
165
                         *  \param[in] SPIOptions  SPI Options, a mask consisting of one of each of the \c SPI_SPEED_*,
166
                         *                         \c SPI_SCK_*, \c SPI_SAMPLE_*, \c SPI_ORDER_* and \c SPI_MODE_* masks.
167
                         */
168
                        static inline void SPI_Init(const uint8_t SPIOptions)
169
                        {
170
                                /* Prevent high rise times on PB.0 (/SS) from forcing a change to SPI slave mode */
171
                                DDRB  |= (1 << 0);
172
                                PORTB |= (1 << 0);
173

    
174
                                DDRB  |=  ((1 << 1) | (1 << 2));
175
                                DDRB  &= ~(1 << 3);
176
                                PORTB |=  (1 << 3);
177

    
178
                                if (SPIOptions & SPI_USE_DOUBLESPEED)
179
                                  SPSR |= (1 << SPI2X);
180
                                else
181
                                  SPSR &= ~(1 << SPI2X);
182

    
183
                                /* Switch /SS to input mode after configuration to allow for forced mode changes */
184
                                DDRB &= ~(1 << 0);
185

    
186
                                SPCR  = ((1 << SPE) | SPIOptions);
187
                        }
188

    
189
                        /** Turns off the SPI driver, disabling and returning used hardware to their default configuration. */
190
                        static inline void SPI_Disable(void)
191
                        {
192
                                DDRB  &= ~((1 << 1) | (1 << 2));
193
                                PORTB &= ~((1 << 0) | (1 << 3));
194

    
195
                                SPCR   = 0;
196
                                SPSR   = 0;
197
                        }
198
                        
199
                        /** Retrieves the currently selected SPI mode, once the SPI interface has been configured.
200
                         *
201
                         *  \return \ref SPI_MODE_MASTER if the interface is currently in SPI Master mode, \ref SPI_MODE_SLAVE otherwise
202
                         */
203
                        static inline uint8_t SPI_GetCurrentMode(void) ATTR_ALWAYS_INLINE;
204
                        static inline uint8_t SPI_GetCurrentMode(void)
205
                        {
206
                                return (SPCR & SPI_MODE_MASTER);
207
                        }
208

    
209
                        /** Sends and receives a byte through the SPI interface, blocking until the transfer is complete.
210
                         *
211
                         *  \param[in] Byte  Byte to send through the SPI interface.
212
                         *
213
                         *  \return Response byte from the attached SPI device.
214
                         */
215
                        static inline uint8_t SPI_TransferByte(const uint8_t Byte) ATTR_ALWAYS_INLINE;
216
                        static inline uint8_t SPI_TransferByte(const uint8_t Byte)
217
                        {
218
                                SPDR = Byte;
219
                                while (!(SPSR & (1 << SPIF)));
220
                                return SPDR;
221
                        }
222

    
223
                        /** Sends a byte through the SPI interface, blocking until the transfer is complete. The response
224
                         *  byte sent to from the attached SPI device is ignored.
225
                         *
226
                         *  \param[in] Byte  Byte to send through the SPI interface.
227
                         */
228
                        static inline void SPI_SendByte(const uint8_t Byte) ATTR_ALWAYS_INLINE;
229
                        static inline void SPI_SendByte(const uint8_t Byte)
230
                        {
231
                                SPDR = Byte;
232
                                while (!(SPSR & (1 << SPIF)));
233
                        }
234

    
235
                        /** Sends a dummy byte through the SPI interface, blocking until the transfer is complete. The response
236
                         *  byte from the attached SPI device is returned.
237
                         *
238
                         *  \return The response byte from the attached SPI device.
239
                         */
240
                        static inline uint8_t SPI_ReceiveByte(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT;
241
                        static inline uint8_t SPI_ReceiveByte(void)
242
                        {
243
                                SPDR = 0x00;
244
                                while (!(SPSR & (1 << SPIF)));
245
                                return SPDR;
246
                        }
247

    
248
        /* Disable C linkage for C++ Compilers: */
249
                #if defined(__cplusplus)
250
                        }
251
                #endif
252

    
253
#endif
254

    
255
/** @} */
256