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