Platform drivers for Mbed.

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

Revision:
17:af1f2416dd26
Child:
20:4951ea6abee5
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/spi.cpp	Tue Jul 13 13:58:07 2021 +0530
@@ -0,0 +1,222 @@
+/***************************************************************************//**
+ *   @file   spi.cpp
+ *   @brief  Implementation of SPI Mbed platform driver interfaces
+********************************************************************************
+ * Copyright (c) 2019-2021 Analog Devices, Inc.
+ * All rights reserved.
+ *
+ * This software is proprietary to Analog Devices, Inc. and its licensors.
+ * By using this software you agree to the terms of the associated
+ * Analog Devices Software License Agreement.
+*******************************************************************************/
+
+/******************************************************************************/
+/***************************** Include Files **********************************/
+/******************************************************************************/
+
+#include <stdio.h>
+#include <mbed.h>
+
+// Platform drivers needs to be C-compatible to work with other drivers
+#ifdef __cplusplus
+extern "C"
+{
+#endif //  _cplusplus
+
+#include "error.h"
+#include "spi.h"
+#include "gpio.h"
+#include "spi_extra.h"
+
+/******************************************************************************/
+/********************** Macros and Constants Definitions **********************/
+/******************************************************************************/
+
+#define		SPI_8_BIT_FRAME			8		// SPI 8-bit frame size
+
+/******************************************************************************/
+/********************** Variables and User defined data types *****************/
+/******************************************************************************/
+
+/******************************************************************************/
+/************************ Functions Declarations ******************************/
+/******************************************************************************/
+
+/******************************************************************************/
+/************************ Functions Definitions *******************************/
+/******************************************************************************/
+
+/**
+ * @brief Initialize the SPI communication peripheral.
+ * @param desc - The SPI descriptor.
+ * @param init_param - The structure that contains the SPI parameters.
+ * @return SUCCESS in case of success, FAILURE otherwise.
+ */
+int32_t spi_init_noos(struct spi_desc **desc,
+		      const struct spi_init_param *param)
+{
+	mbed::SPI *spi;					// Pointer to new spi instance
+	DigitalOut *csb;  				// pointer to new CSB gpio instance
+	mbed_spi_desc *mbed_desc;		// Pointer to mbed spi descriptor
+	use_gpio_ssel_t use_gpio_ssel;	// For CSB hardware (implicit) control
+	spi_desc *new_desc;
+
+	if ((desc) && (param) && (param->extra)) {
+		// Create the spi description object for the device
+		new_desc = (spi_desc *)malloc(sizeof(spi_desc));
+		if (!new_desc) {
+			goto err_new_desc;
+		}
+
+		new_desc->chip_select = param->chip_select;
+		new_desc->mode = param->mode;
+		new_desc->max_speed_hz = param->max_speed_hz;
+
+		// Create the SPI extra descriptor object to store new SPI instances
+		mbed_desc = (mbed_spi_desc *)malloc(sizeof(mbed_spi_desc));
+		if (!mbed_desc) {
+			goto err_mbed_desc;
+		}
+
+		// Configure and instantiate SPI protocol
+		if (((mbed_spi_init_param *)param->extra)->use_sw_csb) {
+			/* CSB pin toggled explicitly (s/w controlled) during SPI transaction */
+			spi = new SPI(
+				(PinName)(((mbed_spi_init_param *)param->extra)->spi_mosi_pin),
+				(PinName)(((mbed_spi_init_param *)param->extra)->spi_miso_pin),
+				(PinName)(((mbed_spi_init_param *)param->extra)->spi_clk_pin));
+
+			if (spi) {
+				/* Configure and instantiate chip select pin */
+				csb = new DigitalOut((PinName)(new_desc->chip_select));
+				if (csb) {
+					mbed_desc->use_sw_csb = true;
+					mbed_desc->csb_gpio = (DigitalOut *)csb;
+					csb->write(GPIO_HIGH);
+				} else {
+					goto err_csb;
+				}
+			}
+		} else {
+			/* CSB pin toggled implicitly (through HAL layer) during SPI transaction */
+			spi = new SPI(
+				(PinName)(((mbed_spi_init_param *)param->extra)->spi_mosi_pin),
+				(PinName)(((mbed_spi_init_param *)param->extra)->spi_miso_pin),
+				(PinName)(((mbed_spi_init_param *)param->extra)->spi_clk_pin),
+				(PinName)(param->chip_select),
+				use_gpio_ssel);
+
+			mbed_desc->use_sw_csb = false;
+			mbed_desc->csb_gpio = NULL;
+		}
+
+		if (!spi) {
+			goto err_spi;
+		}
+
+		mbed_desc->spi_port = (SPI *)spi;
+
+		new_desc->extra = (mbed_spi_desc *)mbed_desc;
+		*desc = new_desc;
+
+		/**
+		    NOTE: Actual frequency of SPI clk will be somewhat device
+		    dependent, relating to clock-settings, prescalars etc. If absolute
+		    SPI frequency is required, consult your device documentation.
+		  **/
+		spi->frequency(param->max_speed_hz);
+		spi->format(SPI_8_BIT_FRAME, param->mode);   // data write/read format
+		spi->set_default_write_value(0x00);          // code to write when reading back
+
+		return SUCCESS;
+	}
+
+err_spi:
+	if (((mbed_spi_init_param *)param->extra)->use_sw_csb) {
+		free(csb);
+	}
+err_csb:
+	free(spi);
+	free(mbed_desc);
+err_mbed_desc:
+	free(new_desc);
+err_new_desc:
+	// Nothing to free
+
+	return FAILURE;
+}
+
+
+/**
+ * @brief Free the resources allocated by spi_init().
+ * @param desc - The SPI descriptor.
+ * @return SUCCESS in case of success, FAILURE otherwise.
+ */
+int32_t spi_remove(struct spi_desc *desc)
+{
+	if (desc) {
+		if (((mbed_spi_desc *)desc->extra)->use_sw_csb) {
+			// Free the CSB gpio object
+			if((DigitalOut *)(((mbed_spi_desc *)(desc->extra))->csb_gpio)) {
+				delete((DigitalOut *)(((mbed_spi_desc *)(desc->extra))->csb_gpio));
+			}
+		}
+
+		// Free the SPI port object
+		if ((SPI *)(((mbed_spi_desc *)(desc->extra))->spi_port)) {
+			delete((SPI *)(((mbed_spi_desc *)(desc->extra))->spi_port));
+		}
+
+		// Free the SPI extra descriptor object
+		if ((mbed_spi_desc *)(desc->extra)) {
+			free((mbed_spi_desc *)(desc->extra));
+		}
+
+		// Free the SPI descriptor object
+		free(desc);
+
+		return SUCCESS;
+	}
+
+	return FAILURE;
+}
+
+
+/**
+ * @brief Write and read data to/from SPI.
+ * @param desc - The SPI descriptor.
+ * @param data - The buffer with the transmitted/received data.
+ * @param bytes_number - Number of bytes to write/read.
+ * @return SUCCESS in case of success, FAILURE otherwise.
+ */
+int32_t spi_write_and_read(struct spi_desc *desc,
+			   uint8_t *data,
+			   uint16_t bytes_number)
+{
+	mbed::SPI *spi; 			// pointer to new spi instance
+	mbed::DigitalOut *csb;   	// pointer to new CSB instance
+
+	if (desc) {
+		spi = (SPI *)(((mbed_spi_desc *)(desc->extra))->spi_port);
+
+		if (((mbed_spi_desc *)desc->extra)->use_sw_csb) {
+			csb = (DigitalOut *)(((mbed_spi_desc *)(desc->extra))->csb_gpio);
+			csb->write(GPIO_LOW);
+		}
+
+		/* Perform synchronous SPI write and read */
+		spi->write((const char *)data, bytes_number, (char *)data, bytes_number);
+
+		if (((mbed_spi_desc *)desc->extra)->use_sw_csb) {
+			csb->write(GPIO_HIGH);
+		}
+
+		return SUCCESS;
+	}
+
+	return FAILURE;
+}
+
+#ifdef __cplusplus  // Closing extern c
+}
+#endif //  _cplusplus