Platform drivers for Mbed.
Dependents: EVAL-CN0535-FMCZ EVAL-CN0535-FMCZ EVAL-AD568x-AD569x EVAL-AD7606 ... more
spi.cpp
00001 /***************************************************************************//** 00002 * @file spi.cpp 00003 * @brief Implementation of SPI Mbed platform driver interfaces 00004 ******************************************************************************** 00005 * Copyright (c) 2019-2021 Analog Devices, Inc. 00006 * All rights reserved. 00007 * 00008 * This software is proprietary to Analog Devices, Inc. and its licensors. 00009 * By using this software you agree to the terms of the associated 00010 * Analog Devices Software License Agreement. 00011 *******************************************************************************/ 00012 00013 /******************************************************************************/ 00014 /***************************** Include Files **********************************/ 00015 /******************************************************************************/ 00016 00017 #include <stdio.h> 00018 #include <mbed.h> 00019 00020 // Platform drivers needs to be C-compatible to work with other drivers 00021 #ifdef __cplusplus 00022 extern "C" 00023 { 00024 #endif // _cplusplus 00025 00026 #include "error.h" 00027 #include "spi.h " 00028 #include "gpio.h" 00029 #include "spi_extra.h" 00030 00031 /******************************************************************************/ 00032 /********************** Macros and Constants Definitions **********************/ 00033 /******************************************************************************/ 00034 00035 #define SPI_8_BIT_FRAME 8 // SPI 8-bit frame size 00036 00037 /******************************************************************************/ 00038 /********************** Variables and User defined data types *****************/ 00039 /******************************************************************************/ 00040 00041 /******************************************************************************/ 00042 /************************ Functions Declarations ******************************/ 00043 /******************************************************************************/ 00044 00045 /******************************************************************************/ 00046 /************************ Functions Definitions *******************************/ 00047 /******************************************************************************/ 00048 00049 /** 00050 * @brief Initialize the SPI communication peripheral. 00051 * @param desc - The SPI descriptor. 00052 * @param init_param - The structure that contains the SPI parameters. 00053 * @return SUCCESS in case of success, FAILURE otherwise. 00054 */ 00055 int32_t spi_init_noos(struct spi_desc **desc, 00056 const struct spi_init_param *param) 00057 { 00058 mbed::SPI *spi; // Pointer to new spi instance 00059 DigitalOut *csb; // pointer to new CSB gpio instance 00060 mbed_spi_desc *mbed_desc; // Pointer to mbed spi descriptor 00061 use_gpio_ssel_t use_gpio_ssel; // For CSB hardware (implicit) control 00062 spi_desc *new_desc; 00063 00064 if ((desc) && (param) && (param->extra)) { 00065 // Create the spi description object for the device 00066 new_desc = (spi_desc *)malloc(sizeof(spi_desc)); 00067 if (!new_desc) { 00068 goto err_new_desc; 00069 } 00070 00071 new_desc->chip_select = param->chip_select; 00072 new_desc->mode = param->mode; 00073 new_desc->max_speed_hz = param->max_speed_hz; 00074 00075 // Create the SPI extra descriptor object to store new SPI instances 00076 mbed_desc = (mbed_spi_desc *)malloc(sizeof(mbed_spi_desc)); 00077 if (!mbed_desc) { 00078 goto err_mbed_desc; 00079 } 00080 00081 // Configure and instantiate SPI protocol 00082 if (((mbed_spi_init_param *)param->extra)->use_sw_csb) { 00083 /* CSB pin toggled explicitly (s/w controlled) during SPI transaction */ 00084 spi = new SPI( 00085 (PinName)(((mbed_spi_init_param *)param->extra)->spi_mosi_pin), 00086 (PinName)(((mbed_spi_init_param *)param->extra)->spi_miso_pin), 00087 (PinName)(((mbed_spi_init_param *)param->extra)->spi_clk_pin)); 00088 00089 if (spi) { 00090 /* Configure and instantiate chip select pin */ 00091 csb = new DigitalOut((PinName)(new_desc->chip_select)); 00092 if (csb) { 00093 mbed_desc->use_sw_csb = true; 00094 mbed_desc->csb_gpio = (DigitalOut *)csb; 00095 csb->write(GPIO_HIGH); 00096 } else { 00097 goto err_csb; 00098 } 00099 } 00100 } else { 00101 /* CSB pin toggled implicitly (through HAL layer) during SPI transaction */ 00102 spi = new SPI( 00103 (PinName)(((mbed_spi_init_param *)param->extra)->spi_mosi_pin), 00104 (PinName)(((mbed_spi_init_param *)param->extra)->spi_miso_pin), 00105 (PinName)(((mbed_spi_init_param *)param->extra)->spi_clk_pin), 00106 (PinName)(param->chip_select), 00107 use_gpio_ssel); 00108 00109 mbed_desc->use_sw_csb = false; 00110 mbed_desc->csb_gpio = NULL; 00111 } 00112 00113 if (!spi) { 00114 goto err_spi; 00115 } 00116 00117 mbed_desc->spi_port = (SPI *)spi; 00118 00119 new_desc->extra = (mbed_spi_desc *)mbed_desc; 00120 *desc = new_desc; 00121 00122 /** 00123 NOTE: Actual frequency of SPI clk will be somewhat device 00124 dependent, relating to clock-settings, prescalars etc. If absolute 00125 SPI frequency is required, consult your device documentation. 00126 **/ 00127 spi->frequency(param->max_speed_hz); 00128 spi->format(SPI_8_BIT_FRAME, param->mode); // data write/read format 00129 spi->set_default_write_value(0x00); // code to write when reading back 00130 00131 return SUCCESS; 00132 } 00133 00134 err_spi: 00135 if (((mbed_spi_init_param *)param->extra)->use_sw_csb) { 00136 free(csb); 00137 } 00138 err_csb: 00139 free(spi); 00140 free(mbed_desc); 00141 err_mbed_desc: 00142 free(new_desc); 00143 err_new_desc: 00144 // Nothing to free 00145 00146 return FAILURE; 00147 } 00148 00149 00150 /** 00151 * @brief Free the resources allocated by spi_init(). 00152 * @param desc - The SPI descriptor. 00153 * @return SUCCESS in case of success, FAILURE otherwise. 00154 */ 00155 int32_t spi_remove(struct spi_desc *desc) 00156 { 00157 if (desc) { 00158 if (((mbed_spi_desc *)desc->extra)->use_sw_csb) { 00159 // Free the CSB gpio object 00160 if((DigitalOut *)(((mbed_spi_desc *)(desc->extra))->csb_gpio)) { 00161 delete((DigitalOut *)(((mbed_spi_desc *)(desc->extra))->csb_gpio)); 00162 } 00163 } 00164 00165 // Free the SPI port object 00166 if ((SPI *)(((mbed_spi_desc *)(desc->extra))->spi_port)) { 00167 delete((SPI *)(((mbed_spi_desc *)(desc->extra))->spi_port)); 00168 } 00169 00170 // Free the SPI extra descriptor object 00171 if ((mbed_spi_desc *)(desc->extra)) { 00172 free((mbed_spi_desc *)(desc->extra)); 00173 } 00174 00175 // Free the SPI descriptor object 00176 free(desc); 00177 00178 return SUCCESS; 00179 } 00180 00181 return FAILURE; 00182 } 00183 00184 00185 /** 00186 * @brief Write and read data to/from SPI. 00187 * @param desc - The SPI descriptor. 00188 * @param data - The buffer with the transmitted/received data. 00189 * @param bytes_number - Number of bytes to write/read. 00190 * @return SUCCESS in case of success, FAILURE otherwise. 00191 */ 00192 int32_t spi_write_and_read(struct spi_desc *desc, 00193 uint8_t *data, 00194 uint16_t bytes_number) 00195 { 00196 mbed::SPI *spi; // pointer to new spi instance 00197 mbed::DigitalOut *csb; // pointer to new CSB instance 00198 00199 if (desc) { 00200 spi = (SPI *)(((mbed_spi_desc *)(desc->extra))->spi_port); 00201 00202 if (((mbed_spi_desc *)desc->extra)->use_sw_csb) { 00203 csb = (DigitalOut *)(((mbed_spi_desc *)(desc->extra))->csb_gpio); 00204 csb->write(GPIO_LOW); 00205 } 00206 00207 /* Perform synchronous SPI write and read */ 00208 spi->write((const char *)data, bytes_number, (char *)data, bytes_number); 00209 00210 if (((mbed_spi_desc *)desc->extra)->use_sw_csb) { 00211 csb->write(GPIO_HIGH); 00212 } 00213 00214 return SUCCESS; 00215 } 00216 00217 return FAILURE; 00218 } 00219 00220 00221 /** 00222 * @brief Transfer (write/read) the number of SPI messages 00223 * @param desc - The SPI descriptor 00224 * @param msgs - Pointer to SPI messages 00225 * @param num_of_msgs - Number of SPI messages 00226 * @return SUCCESS in case of success, FAILURE otherwise. 00227 * @note Use of this function requires CSB pin to be software controlled 00228 */ 00229 int32_t spi_transfer(struct spi_desc *desc, struct spi_msg *msgs, 00230 uint32_t num_of_msgs) 00231 { 00232 mbed::SPI *spi; // pointer to new spi instance 00233 mbed::DigitalOut *csb; // pointer to new CSB instance 00234 uint8_t msg_cnt; // SPI message counter 00235 00236 if (desc) { 00237 if (!((mbed_spi_desc *)desc->extra)->use_sw_csb) 00238 return FAILURE; 00239 00240 spi = (SPI *)(((mbed_spi_desc *)(desc->extra))->spi_port); 00241 csb = (DigitalOut *)(((mbed_spi_desc *)(desc->extra))->csb_gpio); 00242 00243 if (!spi || !csb) 00244 return FAILURE; 00245 00246 for (msg_cnt = 0; msg_cnt < num_of_msgs; msg_cnt++) { 00247 csb->write(GPIO_LOW); 00248 00249 /* Perform synchronous SPI write and read */ 00250 if (!msgs[msg_cnt].tx_buff) { 00251 spi->write(NULL, 0, 00252 (char *)msgs[msg_cnt].rx_buff, msgs[msg_cnt].bytes_number); 00253 } else { 00254 spi->write((const char *)msgs[msg_cnt].tx_buff, msgs[msg_cnt].bytes_number, 00255 (char *)msgs[msg_cnt].rx_buff, msgs[msg_cnt].bytes_number); 00256 } 00257 00258 if (msgs[msg_cnt].cs_change) { 00259 csb->write(GPIO_HIGH); 00260 } 00261 } 00262 00263 csb->write(GPIO_HIGH); 00264 return SUCCESS; 00265 } 00266 00267 return FAILURE; 00268 } 00269 00270 #ifdef __cplusplus // Closing extern c 00271 } 00272 #endif // _cplusplus
Generated on Wed Jul 13 2022 14:37:51 by 1.7.2