Enda Kilgarriff / platform_drivers
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers spi.cpp Source File

spi.cpp

Go to the documentation of this file.
00001 /***************************************************************************//**
00002  *   @file   spi.cpp
00003  *   @brief  Implementation of SPI No-OS platform driver interfaces
00004 ********************************************************************************
00005  * Copyright (c) 2019, 2020 Analog Devices, Inc.
00006  *
00007  * All rights reserved.
00008  *
00009  * This software is proprietary to Analog Devices, Inc. and its licensors.
00010  * By using this software you agree to the terms of the associated
00011  * Analog Devices Software License Agreement.
00012 *******************************************************************************/
00013 
00014 /******************************************************************************/
00015 /***************************** Include Files **********************************/
00016 /******************************************************************************/
00017 
00018 #include <stdio.h>
00019 #include <mbed.h>
00020 
00021 #include "platform_drivers.h"
00022 #include "spi_extra.h"
00023 
00024 /******************************************************************************/
00025 /********************** Macros and Constants Definitions **********************/
00026 /******************************************************************************/
00027 
00028 #define SEND_BYTE                      8
00029 
00030 /******************************************************************************/
00031 /********************** Variables and User defined data types *****************/
00032 /******************************************************************************/
00033 
00034 /******************************************************************************/
00035 /************************ Functions Declarations ******************************/
00036 /******************************************************************************/
00037 
00038 /******************************************************************************/
00039 /************************ Functions Definitions *******************************/
00040 /******************************************************************************/
00041 
00042 /**
00043  * @brief Initialize the SPI communication peripheral.
00044  * @param desc - The SPI descriptor.
00045  * @param init_param - The structure that contains the SPI parameters.
00046  * @return SUCCESS in case of success, FAILURE otherwise.
00047  */
00048 int32_t spi_init_noos(struct spi_desc **desc,
00049               const struct spi_init_param *param)
00050 {
00051     mbed::SPI *spi;     // pointer to new spi instance
00052     DigitalOut *ss;     // pointer to new SS instance
00053     mbed_spi_desc *mbed_desc;   // Pointer to mbed spi descriptor
00054 
00055     if (desc) {
00056         // Create the spi description object for the device
00057         spi_desc * new_desc = (spi_desc *)malloc(sizeof(spi_desc));
00058         if (new_desc == NULL) {
00059             return FAILURE;
00060         }
00061 
00062         new_desc->chip_select = param->chip_select;
00063         new_desc->mode = param->mode;
00064         new_desc->max_speed_hz = param->max_speed_hz;
00065 
00066         // Configure and instantiate SPI protocol
00067         spi = new SPI(
00068             (PinName)(((mbed_spi_init_param *)param->extra)->spi_mosi_pin),
00069             (PinName)(((mbed_spi_init_param *)param->extra)->spi_miso_pin),
00070             (PinName)(((mbed_spi_init_param *)param->extra)->spi_clk_pin));
00071 
00072         if (spi == NULL) {
00073             return FAILURE;
00074         }
00075 
00076         // Configure and instantiate slave select pin
00077         ss = new DigitalOut((PinName)(new_desc->chip_select));
00078         if (ss == NULL) {
00079             return FAILURE;
00080         }
00081 
00082         // Create the SPI extra descriptor object to store new SPI instances
00083         mbed_desc = (mbed_spi_desc *)malloc(sizeof(mbed_spi_desc));
00084         if (mbed_desc == NULL) {
00085             return FAILURE;
00086         }
00087 
00088         mbed_desc->spi_port = (SPI *)spi;
00089         mbed_desc->slave_select = (DigitalOut *)ss;
00090         new_desc->extra = (mbed_spi_desc *)mbed_desc;
00091 
00092         *desc = new_desc;
00093 
00094         /**
00095             NOTE: Actual frequency of SPI clk will be somewhat device
00096             dependent, relating to clock-settings, prescalars etc. If absolute
00097             SPI frequency is required, consult your device documentation.
00098           **/
00099         spi->frequency(param->max_speed_hz);
00100         spi->format(SEND_BYTE, param->mode);       // Stick to byte-multiples
00101         spi->set_default_write_value(0x00);        // code to write when reading back
00102         ss->write(GPIO_HIGH);                      // set SS high
00103 
00104         return SUCCESS;
00105     }
00106 
00107     return FAILURE;
00108 }
00109 
00110 
00111 /**
00112  * @brief Free the resources allocated by spi_init().
00113  * @param desc - The SPI descriptor.
00114  * @return SUCCESS in case of success, FAILURE otherwise.
00115  */
00116 int32_t spi_remove(struct spi_desc *desc)
00117 {
00118     if (desc) {
00119         // Free the SPI port object
00120         if ((SPI *)(((mbed_spi_desc *)(desc->extra))->spi_port)) {
00121             delete((SPI *)(((mbed_spi_desc *)(desc->extra))->spi_port));
00122         }
00123 
00124         // Free the SS port object
00125         if ((DigitalOut *)(((mbed_spi_desc *)(desc->extra))->slave_select)) {
00126             delete((DigitalOut *)(((mbed_spi_desc *)(desc->extra))->slave_select));
00127         }
00128 
00129         // Free the SPI extra descriptor object
00130         if ((mbed_spi_desc *)(desc->extra)) {
00131             free((mbed_spi_desc *)(desc->extra));
00132         }
00133 
00134         // Free the SPI descriptor object
00135         free(desc);
00136 
00137         return SUCCESS;
00138     }
00139 
00140     return FAILURE;
00141 }
00142 
00143 
00144 /**
00145  * @brief Write and read data to/from SPI.
00146  * @param desc - The SPI descriptor.
00147  * @param data - The buffer with the transmitted/received data.
00148  * @param bytes_number - Number of bytes to write/read.
00149  * @return SUCCESS in case of success, FAILURE otherwise.
00150  */
00151 int32_t spi_write_and_read(struct spi_desc *desc,
00152                uint8_t *data,
00153                uint16_t bytes_number)
00154 {
00155     mbed::SPI *spi;     // pointer to new spi instance
00156     DigitalOut *ss;     // pointer to new SS instance
00157 
00158     if (desc) {
00159         spi = (SPI *)(((mbed_spi_desc *)(desc->extra))->spi_port);
00160         ss = (DigitalOut *)(((mbed_spi_desc *)(desc->extra))->slave_select);
00161 
00162         ss->write(GPIO_LOW);
00163 
00164         for (size_t byte = 0 ; byte < bytes_number ; byte++) {
00165             data[byte] =  spi->write(data[byte]);
00166         }
00167 
00168         ss->write(GPIO_HIGH);
00169 
00170         return SUCCESS;
00171     }
00172 
00173     return FAILURE;
00174 }