Update platform drivers

src/spi.cpp

Committer:
EndaKilgarriff
Date:
2020-06-17
Revision:
10:b5115cd6b916
Parent:
8:70fc373a5f46

File content as of revision 10:b5115cd6b916:

/***************************************************************************//**
 *   @file   spi.cpp
 *   @brief  Implementation of SPI No-OS platform driver interfaces
********************************************************************************
 * Copyright (c) 2019, 2020 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>

#include "platform_drivers.h"
#include "spi_extra.h"

/******************************************************************************/
/********************** Macros and Constants Definitions **********************/
/******************************************************************************/

#define SEND_BYTE                      8

/******************************************************************************/
/********************** 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 *ss; 	// pointer to new SS instance
	mbed_spi_desc *mbed_desc;	// Pointer to mbed spi descriptor

	if (desc) {
		// Create the spi description object for the device
		spi_desc * new_desc = (spi_desc *)malloc(sizeof(spi_desc));
		if (new_desc == NULL) {
			return FAILURE;
		}

		new_desc->chip_select = param->chip_select;
		new_desc->mode = param->mode;
		new_desc->max_speed_hz = param->max_speed_hz;

		// Configure and instantiate SPI protocol
		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 == NULL) {
			return FAILURE;
		}

		// Configure and instantiate slave select pin
		ss = new DigitalOut((PinName)(new_desc->chip_select));
		if (ss == NULL) {
			return FAILURE;
		}

		// Create the SPI extra descriptor object to store new SPI instances
		mbed_desc = (mbed_spi_desc *)malloc(sizeof(mbed_spi_desc));
		if (mbed_desc == NULL) {
			return FAILURE;
		}

		mbed_desc->spi_port = (SPI *)spi;
		mbed_desc->slave_select = (DigitalOut *)ss;
		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(SEND_BYTE, param->mode);       // Stick to byte-multiples
		spi->set_default_write_value(0x00);        // code to write when reading back
		ss->write(GPIO_HIGH);                      // set SS high

		return SUCCESS;
	}

	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) {
		// 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 SS port object
		if ((DigitalOut *)(((mbed_spi_desc *)(desc->extra))->slave_select)) {
			delete((DigitalOut *)(((mbed_spi_desc *)(desc->extra))->slave_select));
		}

		// 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
	DigitalOut *ss;  	// pointer to new SS instance

	if (desc) {
		spi = (SPI *)(((mbed_spi_desc *)(desc->extra))->spi_port);
		ss = (DigitalOut *)(((mbed_spi_desc *)(desc->extra))->slave_select);

		ss->write(GPIO_LOW);

		for (size_t byte = 0 ; byte < bytes_number ; byte++) {
			data[byte] =  spi->write(data[byte]);
		}

		ss->write(GPIO_HIGH);

		return SUCCESS;
	}

	return FAILURE;
}