1 /**
2  * \file
3  *
4  * \brief SPI master common service for SAM.
5  *
6  * Copyright (c) 2011-2016 Atmel Corporation. All rights reserved.
7  *
8  * \asf_license_start
9  *
10  * \page License
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions are met:
14  *
15  * 1. Redistributions of source code must retain the above copyright notice,
16  *    this list of conditions and the following disclaimer.
17  *
18  * 2. Redistributions in binary form must reproduce the above copyright notice,
19  *    this list of conditions and the following disclaimer in the documentation
20  *    and/or other materials provided with the distribution.
21  *
22  * 3. The name of Atmel may not be used to endorse or promote products derived
23  *    from this software without specific prior written permission.
24  *
25  * 4. This software may only be redistributed and used in connection with an
26  *    Atmel microcontroller product.
27  *
28  * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
29  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
30  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
31  * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
32  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
36  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
37  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38  * POSSIBILITY OF SUCH DAMAGE.
39  *
40  * \asf_license_stop
41  *
42  */
43 /*
44  * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
45  */
46 
47 #ifndef _SPI_MASTER_H_
48 #define _SPI_MASTER_H_
49 
50 #include "compiler.h"
51 #include "sysclk.h"
52 #include "status_codes.h"
53 #include "spi.h"
54 
55 /*! \name SPI Master Management Configuration */
56 //! @{
57 #include "conf_spi_master.h"
58 
59 /// @cond 0
60 /**INDENT-OFF**/
61 #ifdef __cplusplus
62 extern "C" {
63 #endif
64 /**INDENT-ON**/
65 /// @endcond
66 
67 //! Default Configuration of SPI Master Delay BCS
68 #ifndef CONFIG_SPI_MASTER_DELAY_BCS
69 #define CONFIG_SPI_MASTER_DELAY_BCS          0
70 #endif
71 
72 //! Default Configuration of SPI Master Bits per Transfer Definition
73 #ifndef CONFIG_SPI_MASTER_BITS_PER_TRANSFER
74 #define CONFIG_SPI_MASTER_BITS_PER_TRANSFER  SPI_CSR_BITS_8_BIT
75 #endif
76 
77 //! Default Configuration of SPI Master Delay BCT
78 #ifndef CONFIG_SPI_MASTER_DELAY_BCT
79 #define CONFIG_SPI_MASTER_DELAY_BCT          0
80 #endif
81 
82 //! Default Configuration of SPI Master Delay BS
83 #ifndef CONFIG_SPI_MASTER_DELAY_BS
84 #define CONFIG_SPI_MASTER_DELAY_BS           0
85 #endif
86 
87 //! Default Configuration of SPI Master Dummy Field
88 #ifndef CONFIG_SPI_MASTER_DUMMY
89 #define CONFIG_SPI_MASTER_DUMMY              0xFF
90 #endif
91 //! @}
92 
93 /**
94  * \brief Clock phase.
95  */
96 #define SPI_CPHA  (1 << 0)
97 
98 /**
99  * \brief Clock polarity.
100  */
101 #define SPI_CPOL  (1 << 1)
102 
103 /**
104  * \brief SPI mode 0.
105  */
106 #define SPI_MODE_0  0
107 /**
108  * \brief SPI mode 1.
109  */
110 #define SPI_MODE_1  (SPI_CPHA)
111 /**
112  * \brief SPI mode 2.
113  */
114 #define SPI_MODE_2  (SPI_CPOL)
115 /**
116  * \brief SPI mode 3.
117  */
118 #define SPI_MODE_3  (SPI_CPOL | SPI_CPHA)
119 
120 #ifndef SPI_TYPE_DEFS
121 #define SPI_TYPE_DEFS
122 //! SPI Flags Definition
123 typedef uint8_t spi_flags_t;
124 
125 //! Board SPI Select Id Definition
126 typedef uint32_t board_spi_select_id_t;
127 #endif
128 
129 //! \brief Polled SPI device definition.
130 struct spi_device {
131 	//! Board specific select id
132 	board_spi_select_id_t id;
133 };
134 
135 /** \brief Initialize the SPI in master mode.
136  *
137  * \param p_spi Base address of the SPI instance.
138  *
139  */
140 extern void spi_master_init(Spi *p_spi);
141 
142 /**
143  * \brief Set up an SPI device.
144  *
145  * The returned device descriptor structure must be passed to the driver
146  * whenever that device should be used as current slave device.
147  *
148  * \param p_spi     Base address of the SPI instance.
149  * \param device    Pointer to SPI device struct that should be initialized.
150  * \param flags     SPI configuration flags. Common flags for all
151  *                  implementations are the SPI modes SPI_MODE_0 ...
152  *                  SPI_MODE_3.
153  * \param baud_rate Baud rate for communication with slave device in Hz.
154  * \param sel_id    Board specific select id.
155  */
156 extern void spi_master_setup_device(Spi *p_spi, struct spi_device *device,
157 		spi_flags_t flags, uint32_t baud_rate, board_spi_select_id_t sel_id);
158 
159 /**
160  * \brief Select the given device on the SPI bus.
161  *
162  * Set device specific setting and call board chip select.
163  *
164  * \param p_spi  Base address of the SPI instance.
165  * \param device SPI device.
166  *
167  */
168 extern void spi_select_device(Spi *p_spi, struct spi_device *device);
169 
170 /**
171  * \brief Deselect the given device on the SPI bus.
172  *
173  * Call board chip deselect.
174  *
175  * \param p_spi  Base address of the SPI instance.
176  * \param device SPI device.
177  *
178  * \pre SPI device must be selected with spi_select_device() first.
179  */
180 extern void spi_deselect_device(Spi *p_spi, struct spi_device *device);
181 
182 
183 /** \brief Write one byte to an SPI device.
184  *
185  * \param p_spi     Base address of the SPI instance.
186  * \param data      Data to write.
187  *
188  */
spi_write_single(Spi * p_spi,uint8_t data)189 static inline void spi_write_single(Spi *p_spi, uint8_t data)
190 {
191 	spi_put(p_spi, (uint16_t)data);
192 }
193 
194 /**
195  * \brief Send a sequence of bytes to an SPI device.
196  *
197  * Received bytes on the SPI bus are discarded.
198  *
199  * \param p_spi     Base address of the SPI instance.
200  * \param data      Data buffer to write.
201  * \param len       Length of data to be written.
202  *
203  * \pre SPI device must be selected with spi_select_device() first.
204  */
205 extern status_code_t spi_write_packet(Spi *p_spi,
206 		const uint8_t *data, size_t len);
207 
208 /** \brief Receive one byte from an SPI device.
209  *
210  * \param p_spi     Base address of the SPI instance.
211  * \param data      Data to read.
212  *
213  */
spi_read_single(Spi * p_spi,uint8_t * data)214 static inline void spi_read_single(Spi *p_spi, uint8_t *data)
215 {
216 	*data = (uint8_t)spi_get(p_spi);
217 }
218 
219 /**
220  * \brief Receive a sequence of bytes from an SPI device.
221  *
222  * All bytes sent out on SPI bus are sent as value 0xff.
223  *
224  * \param p_spi     Base address of the SPI instance.
225  * \param data      Data buffer to read.
226  * \param len       Length of data to be read.
227  *
228  * \pre SPI device must be selected with spi_select_device() first.
229  */
230 extern status_code_t spi_read_packet(Spi *p_spi, uint8_t *data, size_t len);
231 
232 /**
233  * \brief Send and receive a sequence of bytes from an SPI device.
234  *
235  * \param p_spi     Base address of the SPI instance.
236  * \param tx_data   Data buffer to send.
237  * \param rx_data   Data buffer to read.
238  * \param len       Length of data to be read.
239  *
240  * \pre SPI device must be selected with spi_select_device() first.
241  */
242 extern status_code_t spi_transceive_packet(Spi *p_spi, uint8_t *tx_data, uint8_t *rx_data, size_t len);
243 
244 /// @cond 0
245 /**INDENT-OFF**/
246 #ifdef __cplusplus
247 }
248 #endif
249 /**INDENT-ON**/
250 /// @endcond
251 
252 #endif // _SPI_MASTER_H_
253