Platform drivers for Mbed.

Dependents:   EVAL-CN0535-FMCZ EVAL-CN0535-FMCZ EVAL-AD568x-AD569x EVAL-AD7606 ... more

Committer:
mahphalke
Date:
Fri Oct 16 21:23:58 2020 +0530
Revision:
14:46aad38346a6
Parent:
13:c446482b0360
Child:
15:fd2c3c3038bf
Added support for transferring more than 256 bytes data in spi communication

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mahphalke 8:70fc373a5f46 1 /***************************************************************************//**
mahphalke 8:70fc373a5f46 2 * @file spi.cpp
mahphalke 8:70fc373a5f46 3 * @brief Implementation of SPI No-OS platform driver interfaces
mahphalke 8:70fc373a5f46 4 ********************************************************************************
mahphalke 8:70fc373a5f46 5 * Copyright (c) 2019, 2020 Analog Devices, Inc.
mahphalke 8:70fc373a5f46 6 *
mahphalke 8:70fc373a5f46 7 * All rights reserved.
mahphalke 8:70fc373a5f46 8 *
mahphalke 8:70fc373a5f46 9 * This software is proprietary to Analog Devices, Inc. and its licensors.
mahphalke 8:70fc373a5f46 10 * By using this software you agree to the terms of the associated
mahphalke 8:70fc373a5f46 11 * Analog Devices Software License Agreement.
mahphalke 8:70fc373a5f46 12 *******************************************************************************/
mahphalke 8:70fc373a5f46 13
mahphalke 8:70fc373a5f46 14 /******************************************************************************/
mahphalke 8:70fc373a5f46 15 /***************************** Include Files **********************************/
mahphalke 8:70fc373a5f46 16 /******************************************************************************/
mahphalke 8:70fc373a5f46 17
mahphalke 8:70fc373a5f46 18 #include <stdio.h>
mahphalke 8:70fc373a5f46 19 #include <mbed.h>
mahphalke 8:70fc373a5f46 20
mahphalke 8:70fc373a5f46 21 #include "platform_drivers.h"
mahphalke 8:70fc373a5f46 22 #include "spi_extra.h"
mahphalke 8:70fc373a5f46 23
mahphalke 8:70fc373a5f46 24 /******************************************************************************/
mahphalke 8:70fc373a5f46 25 /********************** Macros and Constants Definitions **********************/
mahphalke 8:70fc373a5f46 26 /******************************************************************************/
mahphalke 8:70fc373a5f46 27
mahphalke 14:46aad38346a6 28 #define SPI_16_BIT_FRAME 16 // SPI 16-bit frame size
mahphalke 14:46aad38346a6 29 #define SPI_8_BIT_FRAME 8 // SPI 8-bit frame size
mahphalke 14:46aad38346a6 30
mahphalke 8:70fc373a5f46 31 /******************************************************************************/
mahphalke 8:70fc373a5f46 32 /********************** Variables and User defined data types *****************/
mahphalke 8:70fc373a5f46 33 /******************************************************************************/
mahphalke 8:70fc373a5f46 34
mahphalke 14:46aad38346a6 35 static uint8_t spi_format_bytes = SPI_16_BIT_FRAME; // SPI format
Mahesh Phalke 13:c446482b0360 36
mahphalke 8:70fc373a5f46 37 /******************************************************************************/
mahphalke 8:70fc373a5f46 38 /************************ Functions Declarations ******************************/
mahphalke 8:70fc373a5f46 39 /******************************************************************************/
mahphalke 8:70fc373a5f46 40
mahphalke 8:70fc373a5f46 41 /******************************************************************************/
mahphalke 8:70fc373a5f46 42 /************************ Functions Definitions *******************************/
mahphalke 8:70fc373a5f46 43 /******************************************************************************/
mahphalke 8:70fc373a5f46 44
mahphalke 8:70fc373a5f46 45 /**
mahphalke 8:70fc373a5f46 46 * @brief Initialize the SPI communication peripheral.
mahphalke 8:70fc373a5f46 47 * @param desc - The SPI descriptor.
mahphalke 8:70fc373a5f46 48 * @param init_param - The structure that contains the SPI parameters.
mahphalke 8:70fc373a5f46 49 * @return SUCCESS in case of success, FAILURE otherwise.
mahphalke 8:70fc373a5f46 50 */
mahphalke 8:70fc373a5f46 51 int32_t spi_init_noos(struct spi_desc **desc,
mahphalke 8:70fc373a5f46 52 const struct spi_init_param *param)
mahphalke 8:70fc373a5f46 53 {
mahphalke 8:70fc373a5f46 54 mbed::SPI *spi; // pointer to new spi instance
mahphalke 8:70fc373a5f46 55 DigitalOut *ss; // pointer to new SS instance
mahphalke 8:70fc373a5f46 56 mbed_spi_desc *mbed_desc; // Pointer to mbed spi descriptor
mahphalke 8:70fc373a5f46 57
mahphalke 8:70fc373a5f46 58 if (desc) {
mahphalke 8:70fc373a5f46 59 // Create the spi description object for the device
mahphalke 8:70fc373a5f46 60 spi_desc * new_desc = (spi_desc *)malloc(sizeof(spi_desc));
mahphalke 8:70fc373a5f46 61 if (new_desc == NULL) {
mahphalke 8:70fc373a5f46 62 return FAILURE;
mahphalke 8:70fc373a5f46 63 }
mahphalke 8:70fc373a5f46 64
mahphalke 8:70fc373a5f46 65 new_desc->chip_select = param->chip_select;
mahphalke 8:70fc373a5f46 66 new_desc->mode = param->mode;
mahphalke 8:70fc373a5f46 67 new_desc->max_speed_hz = param->max_speed_hz;
mahphalke 8:70fc373a5f46 68
mahphalke 8:70fc373a5f46 69 // Configure and instantiate SPI protocol
mahphalke 8:70fc373a5f46 70 spi = new SPI(
mahphalke 8:70fc373a5f46 71 (PinName)(((mbed_spi_init_param *)param->extra)->spi_mosi_pin),
mahphalke 8:70fc373a5f46 72 (PinName)(((mbed_spi_init_param *)param->extra)->spi_miso_pin),
mahphalke 8:70fc373a5f46 73 (PinName)(((mbed_spi_init_param *)param->extra)->spi_clk_pin));
mahphalke 8:70fc373a5f46 74
mahphalke 8:70fc373a5f46 75 if (spi == NULL) {
mahphalke 8:70fc373a5f46 76 return FAILURE;
mahphalke 8:70fc373a5f46 77 }
mahphalke 8:70fc373a5f46 78
mahphalke 8:70fc373a5f46 79 // Configure and instantiate slave select pin
mahphalke 8:70fc373a5f46 80 ss = new DigitalOut((PinName)(new_desc->chip_select));
mahphalke 8:70fc373a5f46 81 if (ss == NULL) {
mahphalke 8:70fc373a5f46 82 return FAILURE;
mahphalke 8:70fc373a5f46 83 }
mahphalke 8:70fc373a5f46 84
mahphalke 8:70fc373a5f46 85 // Create the SPI extra descriptor object to store new SPI instances
mahphalke 8:70fc373a5f46 86 mbed_desc = (mbed_spi_desc *)malloc(sizeof(mbed_spi_desc));
mahphalke 8:70fc373a5f46 87 if (mbed_desc == NULL) {
mahphalke 8:70fc373a5f46 88 return FAILURE;
mahphalke 8:70fc373a5f46 89 }
mahphalke 8:70fc373a5f46 90
mahphalke 8:70fc373a5f46 91 mbed_desc->spi_port = (SPI *)spi;
mahphalke 8:70fc373a5f46 92 mbed_desc->slave_select = (DigitalOut *)ss;
mahphalke 8:70fc373a5f46 93 new_desc->extra = (mbed_spi_desc *)mbed_desc;
mahphalke 8:70fc373a5f46 94
mahphalke 8:70fc373a5f46 95 *desc = new_desc;
mahphalke 8:70fc373a5f46 96
mahphalke 8:70fc373a5f46 97 /**
mahphalke 8:70fc373a5f46 98 NOTE: Actual frequency of SPI clk will be somewhat device
mahphalke 8:70fc373a5f46 99 dependent, relating to clock-settings, prescalars etc. If absolute
mahphalke 8:70fc373a5f46 100 SPI frequency is required, consult your device documentation.
mahphalke 8:70fc373a5f46 101 **/
mahphalke 8:70fc373a5f46 102 spi->frequency(param->max_speed_hz);
mahphalke 14:46aad38346a6 103 spi->format(SPI_16_BIT_FRAME, param->mode); // data write/read format
mahphalke 14:46aad38346a6 104 spi_format_bytes = SPI_16_BIT_FRAME;
mahphalke 14:46aad38346a6 105 spi->set_default_write_value(0x00); // code to write when reading back
mahphalke 14:46aad38346a6 106 ss->write(GPIO_HIGH); // set SS high
Mahesh Phalke 13:c446482b0360 107
mahphalke 8:70fc373a5f46 108 return SUCCESS;
mahphalke 8:70fc373a5f46 109 }
mahphalke 8:70fc373a5f46 110
mahphalke 8:70fc373a5f46 111 return FAILURE;
mahphalke 8:70fc373a5f46 112 }
mahphalke 8:70fc373a5f46 113
mahphalke 8:70fc373a5f46 114
mahphalke 8:70fc373a5f46 115 /**
mahphalke 8:70fc373a5f46 116 * @brief Free the resources allocated by spi_init().
mahphalke 8:70fc373a5f46 117 * @param desc - The SPI descriptor.
mahphalke 8:70fc373a5f46 118 * @return SUCCESS in case of success, FAILURE otherwise.
mahphalke 8:70fc373a5f46 119 */
mahphalke 8:70fc373a5f46 120 int32_t spi_remove(struct spi_desc *desc)
mahphalke 8:70fc373a5f46 121 {
mahphalke 8:70fc373a5f46 122 if (desc) {
mahphalke 8:70fc373a5f46 123 // Free the SPI port object
mahphalke 8:70fc373a5f46 124 if ((SPI *)(((mbed_spi_desc *)(desc->extra))->spi_port)) {
mahphalke 8:70fc373a5f46 125 delete((SPI *)(((mbed_spi_desc *)(desc->extra))->spi_port));
mahphalke 8:70fc373a5f46 126 }
mahphalke 8:70fc373a5f46 127
mahphalke 8:70fc373a5f46 128 // Free the SS port object
mahphalke 8:70fc373a5f46 129 if ((DigitalOut *)(((mbed_spi_desc *)(desc->extra))->slave_select)) {
mahphalke 8:70fc373a5f46 130 delete((DigitalOut *)(((mbed_spi_desc *)(desc->extra))->slave_select));
mahphalke 8:70fc373a5f46 131 }
mahphalke 8:70fc373a5f46 132
mahphalke 8:70fc373a5f46 133 // Free the SPI extra descriptor object
mahphalke 8:70fc373a5f46 134 if ((mbed_spi_desc *)(desc->extra)) {
mahphalke 8:70fc373a5f46 135 free((mbed_spi_desc *)(desc->extra));
mahphalke 8:70fc373a5f46 136 }
mahphalke 8:70fc373a5f46 137
mahphalke 8:70fc373a5f46 138 // Free the SPI descriptor object
mahphalke 8:70fc373a5f46 139 free(desc);
mahphalke 8:70fc373a5f46 140
mahphalke 8:70fc373a5f46 141 return SUCCESS;
mahphalke 8:70fc373a5f46 142 }
mahphalke 8:70fc373a5f46 143
mahphalke 8:70fc373a5f46 144 return FAILURE;
mahphalke 8:70fc373a5f46 145 }
mahphalke 8:70fc373a5f46 146
mahphalke 8:70fc373a5f46 147
mahphalke 8:70fc373a5f46 148 /**
mahphalke 8:70fc373a5f46 149 * @brief Write and read data to/from SPI.
mahphalke 8:70fc373a5f46 150 * @param desc - The SPI descriptor.
mahphalke 8:70fc373a5f46 151 * @param data - The buffer with the transmitted/received data.
mahphalke 8:70fc373a5f46 152 * @param bytes_number - Number of bytes to write/read.
mahphalke 8:70fc373a5f46 153 * @return SUCCESS in case of success, FAILURE otherwise.
mahphalke 8:70fc373a5f46 154 */
mahphalke 8:70fc373a5f46 155 int32_t spi_write_and_read(struct spi_desc *desc,
mahphalke 8:70fc373a5f46 156 uint8_t *data,
mahphalke 8:70fc373a5f46 157 uint16_t bytes_number)
mahphalke 8:70fc373a5f46 158 {
Mahesh Phalke 11:a2dcf0ebb5b5 159 mbed::SPI *spi; // pointer to new spi instance
Mahesh Phalke 11:a2dcf0ebb5b5 160 mbed::DigitalOut *ss; // pointer to new SS instance
mahphalke 14:46aad38346a6 161 uint16_t num_of_words; // Number of words in SPI frame
mahphalke 14:46aad38346a6 162 uint16_t rw_data; // SPI read data (16-bit)
mahphalke 14:46aad38346a6 163 uint16_t data_index = 0; // Data index
mahphalke 14:46aad38346a6 164 size_t byte; // Byte read/write index
mahphalke 8:70fc373a5f46 165
mahphalke 8:70fc373a5f46 166 if (desc) {
mahphalke 8:70fc373a5f46 167 spi = (SPI *)(((mbed_spi_desc *)(desc->extra))->spi_port);
mahphalke 8:70fc373a5f46 168 ss = (DigitalOut *)(((mbed_spi_desc *)(desc->extra))->slave_select);
Mahesh Phalke 12:d85b77f4160c 169
Mahesh Phalke 12:d85b77f4160c 170 /* Get the total number of words (16-bit) */
Mahesh Phalke 11:a2dcf0ebb5b5 171 num_of_words = bytes_number / 2;
Mahesh Phalke 12:d85b77f4160c 172
Mahesh Phalke 12:d85b77f4160c 173 /* Determine the data transmit/receive format based on parity of data */
Mahesh Phalke 12:d85b77f4160c 174 if (!(bytes_number % 2)) {
mahphalke 14:46aad38346a6 175 if (spi_format_bytes != SPI_16_BIT_FRAME) {
mahphalke 14:46aad38346a6 176 spi->format(SPI_16_BIT_FRAME, desc->mode);
mahphalke 14:46aad38346a6 177 spi_format_bytes = SPI_16_BIT_FRAME;
Mahesh Phalke 12:d85b77f4160c 178 }
Mahesh Phalke 12:d85b77f4160c 179 } else {
mahphalke 14:46aad38346a6 180 if (spi_format_bytes != SPI_8_BIT_FRAME) {
mahphalke 14:46aad38346a6 181 spi->format(SPI_8_BIT_FRAME, desc->mode);
mahphalke 14:46aad38346a6 182 spi_format_bytes = SPI_8_BIT_FRAME;
Mahesh Phalke 12:d85b77f4160c 183 }
Mahesh Phalke 12:d85b77f4160c 184 }
Mahesh Phalke 12:d85b77f4160c 185
mahphalke 8:70fc373a5f46 186 ss->write(GPIO_LOW);
Mahesh Phalke 12:d85b77f4160c 187
Mahesh Phalke 12:d85b77f4160c 188 /* **Note: It is not possible to change the format of data transfer when SPI
Mahesh Phalke 12:d85b77f4160c 189 * communication is in progress. If format is attempted to change (from 8-bit
Mahesh Phalke 12:d85b77f4160c 190 * to 16-bit or vice a versa), the SPI communication is reset and master generates
Mahesh Phalke 12:d85b77f4160c 191 * a single Clock signal during format change. This triggers false transfer on slave
Mahesh Phalke 12:d85b77f4160c 192 * which results into incorrect data transfer. For this reason, the bytes with even parity
Mahesh Phalke 12:d85b77f4160c 193 * are transferred in 16-bit format and odd parity bytes are transferred in 8-bit format.
Mahesh Phalke 12:d85b77f4160c 194 * Application layer doesn't have any control to stop SPI reset during format change. */
Mahesh Phalke 12:d85b77f4160c 195
Mahesh Phalke 12:d85b77f4160c 196 if (!(bytes_number % 2)) {
Mahesh Phalke 12:d85b77f4160c 197 while (num_of_words) {
Mahesh Phalke 12:d85b77f4160c 198 /* Form a 16-bit data to be written (LE format) */
Mahesh Phalke 12:d85b77f4160c 199 rw_data = ((uint16_t)data[data_index + 1] | ((uint16_t)data[data_index] << 8));
Mahesh Phalke 12:d85b77f4160c 200
Mahesh Phalke 12:d85b77f4160c 201 /* Transmit a 16-bit data over SPI */
Mahesh Phalke 12:d85b77f4160c 202 rw_data = (uint16_t)spi->write(rw_data);
Mahesh Phalke 12:d85b77f4160c 203
Mahesh Phalke 12:d85b77f4160c 204 /* Extract the MSB and LSB from 16-bit read data (LE format) */
Mahesh Phalke 12:d85b77f4160c 205 data[data_index++] = (uint8_t)(rw_data >> 8);
Mahesh Phalke 12:d85b77f4160c 206 data[data_index++] = (uint8_t)rw_data;
Mahesh Phalke 12:d85b77f4160c 207
Mahesh Phalke 12:d85b77f4160c 208 num_of_words--;
Mahesh Phalke 12:d85b77f4160c 209 }
Mahesh Phalke 12:d85b77f4160c 210 } else {
mahphalke 14:46aad38346a6 211 for (byte = 0; byte < bytes_number; byte++) {
Mahesh Phalke 12:d85b77f4160c 212 data[byte] = spi->write(data[byte]);
Mahesh Phalke 12:d85b77f4160c 213 }
mahphalke 8:70fc373a5f46 214 }
mahphalke 8:70fc373a5f46 215
mahphalke 8:70fc373a5f46 216 ss->write(GPIO_HIGH);
mahphalke 8:70fc373a5f46 217
mahphalke 8:70fc373a5f46 218 return SUCCESS;
mahphalke 8:70fc373a5f46 219 }
mahphalke 8:70fc373a5f46 220
mahphalke 8:70fc373a5f46 221 return FAILURE;
mahphalke 8:70fc373a5f46 222 }