1 /** 2 * \file 3 * 4 * \brief SPI Master Mode management 5 * 6 * Copyright (c) 2010-2015 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 #ifndef SPI_MASTER_H_INCLUDED 47 #define SPI_MASTER_H_INCLUDED 48 49 #include <parts.h> 50 51 #if XMEGA 52 # include "xmega_spi/spi_master.h" 53 #elif MEGA_RF 54 # include "megarf_spi/spi_master.h" 55 #elif UC3 56 # include "uc3_spi/spi_master.h" 57 #elif SAM 58 # include "sam_spi/spi_master.h" 59 #else 60 # error Unsupported chip type 61 #endif 62 63 /** 64 * 65 * \defgroup spi_group Serial Peripheral Interface (SPI) 66 * 67 * This is the common API for SPI interface. Additional features are available 68 * in the documentation of the specific modules. 69 * 70 * \section spi_group_platform Platform Dependencies 71 * 72 * The SPI API is partially chip- or platform-specific. While all 73 * platforms provide mostly the same functionality, there are some 74 * variations around how different bus types and clock tree structures 75 * are handled. 76 * 77 * The following functions are available on all platforms, but there may 78 * be variations in the function signature (i.e. parameters) and 79 * behavior. These functions are typically called by platform-specific 80 * parts of drivers, and applications that aren't intended to be 81 * portable: 82 * - spi_master_init() 83 * - spi_master_setup_device() 84 * - spi_select_device() 85 * - spi_deselect_device() 86 * - spi_write_single() 87 * - spi_write_packet() 88 * - spi_read_single() 89 * - spi_read_packet() 90 * - spi_is_tx_empty() 91 * - spi_is_tx_ready() 92 * - spi_is_rx_full() 93 * - spi_is_rx_ready() 94 * - spi_enable() 95 * - spi_disable() 96 * - spi_is_enabled() 97 * 98 * \section spi_master_quickstart_section Quick Start Guide 99 * See \ref common_spi_master_quickstart 100 * @{ 101 */ 102 103 //! @} 104 105 /** 106 * \page common_spi_master_quickstart Quick Start Guide for the SPI Master Driver 107 * 108 * This is the quick start guide for the \ref spi_group "SPI Driver", with 109 * step-by-step instructions on how to configure and use the driver for a 110 * specific use case. 111 * 112 * The use case contain several code fragments. The code fragments in the 113 * steps for setup can be copied into a custom initialization function, while 114 * the steps for usage can be copied into, e.g., the main application function. 115 * 116 * The steps for setting up the SPI master for XMEGA and UC3 use exactly the 117 * same approach, but note that there are different names on the peripherals. So 118 * to use this Quick Start for UC3 please make sure that all the peripheral 119 * names are updated according to the UC3 datasheet. 120 * - \subpage spi_master_xmega 121 * 122 */ 123 /** 124 * \page spi_master_xmega Basic setup for SPI master on XMEGA devices 125 * 126 * \section spi_master_xmega_basic Basic setup for XMEGA devices 127 * The SPI module will be set up as master: 128 * - SPI on PORTD 129 * - 1MHz SPI clock speed 130 * - Slave Chip Select connected on PORTD pin 1 131 * - SPI mode 0 (data on rising clock edge) 132 * 133 * \section spi_master_xmega_basic_setup Setup steps 134 * \subsection spi_master_xmega_basic_setup_code Example code 135 * Add to application C-file (e.g. main.c): 136 * \code 137 void spi_init_pins(void) 138 { 139 ioport_configure_port_pin(&PORTD, PIN1_bm, IOPORT_INIT_HIGH | IOPORT_DIR_OUTPUT); 140 141 ioport_configure_port_pin(&PORTD, PIN4_bm, IOPORT_PULL_UP | IOPORT_DIR_INPUT); 142 ioport_configure_port_pin(&PORTD, PIN5_bm, IOPORT_INIT_HIGH | IOPORT_DIR_OUTPUT); 143 ioport_configure_port_pin(&PORTD, PIN6_bm, IOPORT_DIR_INPUT); 144 ioport_configure_port_pin(&PORTD, PIN7_bm, IOPORT_INIT_HIGH | IOPORT_DIR_OUTPUT); 145 } 146 147 void spi_init_module(void) 148 { 149 struct spi_device spi_device_conf = { 150 .id = IOPORT_CREATE_PIN(PORTD, 1) 151 }; 152 153 spi_master_init(&SPID); 154 spi_master_setup_device(&SPID, &spi_device_conf, SPI_MODE_0, 1000000, 0); 155 spi_enable(&SPID); 156 } 157 \endcode 158 * 159 * \subsection spi_master_xmega_basic_setup Workflow 160 * -# Ensure that \ref conf_spi_master.h is present for the driver. 161 * - \note This file is only for the driver and should not be included by the 162 * user. In this example the file can be left empty. 163 * -# Initialize the pins used by the SPI interface (this initialization is for 164 * the ATxmega32A4U device). 165 * -# Set the pin used for slave select as output high: 166 * \code 167 ioport_configure_port_pin(&PORTD, PIN1_bm, IOPORT_INIT_HIGH | IOPORT_DIR_OUTPUT); 168 \endcode 169 * -# Enable pull-up on own chip select (SS): 170 * \code 171 ioport_configure_port_pin(&PORTD, PIN4_bm, IOPORT_PULL_UP | IOPORT_DIR_INPUT); 172 \endcode 173 * \attention If this pin is pulled low the SPI module will go into slave mode. 174 * -# Set MOSI and SCL as output high, and set MISO as input: 175 * \code 176 ioport_configure_port_pin(&PORTD, PIN5_bm, IOPORT_INIT_HIGH | IOPORT_DIR_OUTPUT); 177 ioport_configure_port_pin(&PORTD, PIN6_bm, IOPORT_DIR_INPUT); 178 ioport_configure_port_pin(&PORTD, PIN7_bm, IOPORT_INIT_HIGH | IOPORT_DIR_OUTPUT); 179 \endcode 180 * -# Define the SPI device configuration struct to describe which pin the 181 * slave select (slave chip select) is connected to, in this case the slave 182 * select pin has been connected to PORTD pin 1 (PD1): 183 * - \code 184 struct spi_device spi_device_conf = { 185 .id = IOPORT_CREATE_PIN(PORTD, 1) 186 }; 187 \endcode 188 * -# Initialize the SPI module, in this case SPI on PORTD has been chosen: 189 * - \code 190 spi_master_init(&SPID); 191 \endcode 192 * -# Setup the SPI master module for a specific device: 193 * - \code 194 spi_master_setup_device(&SPID, &spi_device_conf, SPI_MODE_0, 1000000, 0); 195 \endcode 196 * - \note The last argument, which is zero in this case, can be ignored and is 197 * only included for compatibility purposes. 198 * -# Then enable the SPI: 199 * - \code 200 spi_enable(&SPID); 201 \endcode 202 * 203 * \section spi_master_xmega_basic_usage Usage steps 204 * \subsection spi_master_xmega_basic_usage_code Example code 205 * Add to, e.g., the main loop in the application C-file: 206 * \code 207 uint8_t data_buffer[1] = {0xAA}; 208 209 struct spi_device spi_device_conf = { 210 .id = IOPORT_CREATE_PIN(PORTD, 1) 211 }; 212 213 spi_select_device(&SPID, &spi_device_conf); 214 215 spi_write_packet(&SPID, data_buffer, 1); 216 spi_read_packet(&SPID, data_buffer, 1); 217 218 spi_deselect_device(&SPID, &spi_device_conf); 219 \endcode 220 * 221 * \subsection spi_master_xmega_basic_usage_flow Workflow 222 * -# Create a buffer for data to be sent/received on the SPI bus, in this case 223 * a single byte buffer is used. The buffer can be of arbitrary size as long as 224 * there is space left in SRAM: 225 * - \code 226 uint8_t data_buffer[1] = {0xAA}; 227 \endcode 228 * -# Define the SPI device configuration struct to describe which pin the 229 * slave select (slave chip select) is connected to, in this case the slave 230 * select pin has been connected to PORTD pin 1 (PD1): 231 * - \code 232 struct spi_device spi_device_conf = { 233 .id = IOPORT_CREATE_PIN(PORTD, 1) 234 }; 235 \endcode 236 * - \note As this struct is the same for both the initializing part and the usage 237 * part it could be a good idea to make the struct global, and hence accessible 238 * for both the initializing part and usage part. Another solution could be to 239 * create the struct in the main function and pass the address of the struct to 240 * the spi_init_module() function, e.g.: 241 * \code 242 void spi_init_module(struct spi_device *spi_device_conf) 243 { 244 ... 245 246 spi_master_setup_device(&SPID, spi_device_conf, SPI_MODE_0, 1000000, 0); 247 248 ... 249 } 250 \endcode 251 * -# Write data to the SPI slave device, in this case write one byte from the 252 * data_buffer: 253 * - \code 254 spi_write_packet(&SPID, data_buffer, 1); 255 \endcode 256 * -# Read data from the SPI slave device, in this case read one byte and put it 257 * into the data_buffer: 258 * - \code 259 spi_read_packet(&SPID, data_buffer, 1); 260 \endcode 261 * - \attention As the SPI works as a shift register so that data is shifted in at 262 * the same time as data is shifted out a read operation will mean that a dummy 263 * byte \ref CONFIG_SPI_MASTER_DUMMY is written to the SPI bus. \ref CONFIG_SPI_MASTER_DUMMY 264 * defaults to 0xFF, but can be changed by defining it inside the \ref conf_spi_master.h 265 * file. 266 * -# When read and write operations is done de-select the slave: 267 * - \code 268 spi_deselect_device(&SPID, &spi_device_conf); 269 \endcode 270 * 271 */ 272 273 #endif /* SPI_MASTER_H_INCLUDED */ 274