HAL SPI API Proposal
Documenting the SPI HAL API
This commit is contained in:
parent
1bb04f2d20
commit
91882209bf
104
os/dev/spi-dev.h
104
os/dev/spi-dev.h
@ -1,104 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, Yanzi Networks.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef SPI_DEV_H_
|
||||
#define SPI_DEV_H_
|
||||
|
||||
#include "contiki.h"
|
||||
|
||||
#ifdef PLATFORM_HAS_SPI_DEV_ARCH
|
||||
#include "spi-dev-arch.h"
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
SPI_DEV_STATUS_OK,
|
||||
SPI_DEV_STATUS_TIMEOUT,
|
||||
SPI_DEV_STATUS_EINVAL,
|
||||
SPI_DEV_STATUS_BUS_LOCKED,
|
||||
SPI_DEV_STATUS_BUS_NOT_OWNED
|
||||
} spi_dev_status_t;
|
||||
|
||||
typedef struct spi_device spi_device_t;
|
||||
|
||||
typedef struct spi_bus {
|
||||
/* for locking the bus */
|
||||
spi_device_t *lock_device;
|
||||
volatile uint8_t lock;
|
||||
#ifdef PLATFORM_HAS_SPI_DEV_ARCH
|
||||
spi_bus_config_t config;
|
||||
#endif /* PLATFORM_HAS_SPI_DEV_ARCH */
|
||||
} spi_bus_t;
|
||||
|
||||
struct spi_device {
|
||||
spi_bus_t *bus;
|
||||
/* timeout in milliseconds for this device */
|
||||
uint16_t timeout;
|
||||
/* chip-select for this SPI chip - 1 = CS */
|
||||
uint8_t (* chip_select)(int on);
|
||||
#ifdef PLATFORM_HAS_SPI_DEV_ARCH
|
||||
spi_device_config_t config;
|
||||
#endif
|
||||
};
|
||||
|
||||
/* call for all spi devices */
|
||||
spi_dev_status_t spi_dev_acquire(spi_device_t *dev);
|
||||
spi_dev_status_t spi_dev_release(spi_device_t *dev);
|
||||
spi_dev_status_t spi_dev_restart_timeout(spi_device_t *dev);
|
||||
int spi_dev_has_bus(spi_device_t *dev);
|
||||
spi_dev_status_t spi_dev_write_byte(spi_device_t *dev, uint8_t data);
|
||||
spi_dev_status_t spi_dev_read_byte(spi_device_t *dev, uint8_t *data);
|
||||
spi_dev_status_t spi_dev_write(spi_device_t *dev,
|
||||
const uint8_t *data, int size);
|
||||
spi_dev_status_t spi_dev_read(spi_device_t *dev, uint8_t *data, int size);
|
||||
spi_dev_status_t spi_dev_read_skip(spi_device_t *dev, int size);
|
||||
spi_dev_status_t spi_dev_transfer(spi_device_t *dev,
|
||||
const uint8_t *data, int wsize,
|
||||
uint8_t *buf, int rsize, int ignore);
|
||||
spi_dev_status_t spi_dev_chip_select(spi_device_t *dev, uint8_t on);
|
||||
spi_dev_status_t spi_dev_strobe(spi_device_t *dev, uint8_t strobe,
|
||||
uint8_t *status);
|
||||
spi_dev_status_t spi_dev_read_register(spi_device_t *dev, uint8_t reg,
|
||||
uint8_t *data, int size);
|
||||
|
||||
/* Arch functions needed per CPU */
|
||||
spi_dev_status_t spi_dev_arch_lock(spi_device_t *dev);
|
||||
spi_dev_status_t spi_dev_arch_unlock(spi_device_t *dev);
|
||||
int spi_dev_arch_has_lock(spi_device_t *dev);
|
||||
int spi_dev_arch_is_bus_locked(spi_device_t *dev);
|
||||
|
||||
/* Initialize the spi bus */
|
||||
spi_dev_status_t spi_dev_arch_init(spi_device_t *dev);
|
||||
spi_dev_status_t spi_dev_arch_transfer(spi_device_t *dev,
|
||||
const uint8_t *data, int wlen,
|
||||
uint8_t *buf, int rlen,
|
||||
int ignore_len);
|
||||
spi_dev_status_t spi_dev_arch_restart_timeout(spi_device_t *dev);
|
||||
|
||||
#endif /* SPI_DEV_H */
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, Yanzi Networks.
|
||||
* Copyright (c) 2017, University of Bristol - http://www.bristol.ac.uk/
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -28,122 +29,149 @@
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "dev/spi-dev.h"
|
||||
#include "spi-hal.h"
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
spi_dev_status_t
|
||||
spi_dev_acquire(spi_device_t *dev)
|
||||
spi_status_t
|
||||
spi_acquire(spi_device_t *dev)
|
||||
{
|
||||
if(dev == NULL || dev->bus == NULL) {
|
||||
spi_status_t r;
|
||||
|
||||
if(dev == NULL || dev->spi_controller >= BOARD_SPI_CONTROLLERS) {
|
||||
return SPI_DEV_STATUS_EINVAL;
|
||||
}
|
||||
|
||||
/* lock the bus */
|
||||
return spi_dev_arch_lock(dev);
|
||||
r = spi_arch_lock(dev);
|
||||
if(r != SPI_DEV_STATUS_OK) {
|
||||
return r;
|
||||
}
|
||||
|
||||
/* open the bus */
|
||||
return spi_arch_open(dev);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
spi_dev_status_t
|
||||
spi_dev_release(spi_device_t *dev)
|
||||
spi_status_t
|
||||
spi_release(spi_device_t *dev)
|
||||
{
|
||||
if(dev == NULL || dev->bus == NULL) {
|
||||
spi_status_t r;
|
||||
|
||||
if(dev == NULL || dev->spi_controller >= BOARD_SPI_CONTROLLERS) {
|
||||
return SPI_DEV_STATUS_EINVAL;
|
||||
}
|
||||
|
||||
/* unlock the bus */
|
||||
return spi_dev_arch_unlock(dev);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
spi_dev_has_bus(spi_device_t *dev)
|
||||
{
|
||||
if(dev == NULL || dev->bus == NULL) {
|
||||
return 0;
|
||||
r = spi_arch_close(dev);
|
||||
if(r != SPI_DEV_STATUS_OK) {
|
||||
return r;
|
||||
}
|
||||
return spi_dev_arch_has_lock(dev);
|
||||
|
||||
/* unlock the bus */
|
||||
return spi_arch_unlock(dev);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
spi_dev_status_t
|
||||
spi_dev_restart_timeout(spi_device_t *dev)
|
||||
spi_status_t
|
||||
spi_select(spi_device_t *dev)
|
||||
{
|
||||
if(!spi_dev_has_bus(dev)) {
|
||||
return SPI_DEV_STATUS_EINVAL;
|
||||
return spi_arch_select(dev);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
spi_status_t
|
||||
spi_deselect(spi_device_t *dev)
|
||||
{
|
||||
return spi_arch_deselect(dev);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
bool
|
||||
spi_has_bus(spi_device_t *dev)
|
||||
{
|
||||
if(dev == NULL || dev->spi_controller >= BOARD_SPI_CONTROLLERS) {
|
||||
return false;
|
||||
}
|
||||
return spi_dev_arch_restart_timeout(dev);
|
||||
|
||||
return spi_arch_has_lock(dev);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
spi_dev_status_t
|
||||
spi_dev_write_byte(spi_device_t *dev, uint8_t data)
|
||||
spi_status_t
|
||||
spi_write_byte(spi_device_t *dev, uint8_t data)
|
||||
{
|
||||
if(dev == NULL || dev->bus == NULL) {
|
||||
if(dev == NULL || dev->spi_controller >= BOARD_SPI_CONTROLLERS) {
|
||||
return SPI_DEV_STATUS_EINVAL;
|
||||
}
|
||||
|
||||
if(!spi_dev_arch_has_lock(dev)) {
|
||||
if(!spi_arch_has_lock(dev)) {
|
||||
return SPI_DEV_STATUS_BUS_LOCKED;
|
||||
}
|
||||
return spi_dev_arch_transfer(dev, &data, 1, 0, 0, 0);
|
||||
|
||||
return spi_arch_transfer(dev, &data, 1, 0, 0, 0);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
spi_dev_status_t
|
||||
spi_dev_write(spi_device_t *dev, const uint8_t *data, int size)
|
||||
spi_status_t
|
||||
spi_write(spi_device_t *dev, const uint8_t *data, int size)
|
||||
{
|
||||
if(dev == NULL || dev->bus == NULL) {
|
||||
if(dev == NULL || dev->spi_controller >= BOARD_SPI_CONTROLLERS) {
|
||||
return SPI_DEV_STATUS_EINVAL;
|
||||
}
|
||||
|
||||
if(!spi_dev_arch_has_lock(dev)) {
|
||||
if(!spi_arch_has_lock(dev)) {
|
||||
return SPI_DEV_STATUS_BUS_LOCKED;
|
||||
}
|
||||
return spi_dev_arch_transfer(dev, data, size, 0, 0, 0);
|
||||
|
||||
return spi_arch_transfer(dev, data, size, 0, 0, 0);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
spi_dev_status_t
|
||||
spi_dev_read_byte(spi_device_t *dev, uint8_t *buf)
|
||||
spi_status_t
|
||||
spi_read_byte(spi_device_t *dev, uint8_t *buf)
|
||||
{
|
||||
if(dev == NULL || dev->bus == NULL) {
|
||||
if(dev == NULL || dev->spi_controller >= BOARD_SPI_CONTROLLERS) {
|
||||
return SPI_DEV_STATUS_EINVAL;
|
||||
}
|
||||
|
||||
if(!spi_dev_arch_has_lock(dev)) {
|
||||
if(!spi_arch_has_lock(dev)) {
|
||||
return SPI_DEV_STATUS_BUS_LOCKED;
|
||||
}
|
||||
return spi_dev_arch_transfer(dev, NULL, 0, buf, 1, 0);
|
||||
|
||||
return spi_arch_transfer(dev, NULL, 0, buf, 1, 0);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
spi_dev_status_t
|
||||
spi_dev_read(spi_device_t *dev, uint8_t *buf, int size)
|
||||
spi_status_t
|
||||
spi_read(spi_device_t *dev, uint8_t *buf, int size)
|
||||
{
|
||||
if(dev == NULL || dev->bus == NULL) {
|
||||
if(dev == NULL || dev->spi_controller >= BOARD_SPI_CONTROLLERS) {
|
||||
return SPI_DEV_STATUS_EINVAL;
|
||||
}
|
||||
|
||||
if(!spi_dev_arch_has_lock(dev)) {
|
||||
if(!spi_arch_has_lock(dev)) {
|
||||
return SPI_DEV_STATUS_BUS_LOCKED;
|
||||
}
|
||||
return spi_dev_arch_transfer(dev, NULL, 0, buf, size, 0);
|
||||
|
||||
return spi_arch_transfer(dev, NULL, 0, buf, size, 0);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
spi_dev_status_t
|
||||
spi_dev_read_skip(spi_device_t *dev, int size)
|
||||
spi_status_t
|
||||
spi_read_skip(spi_device_t *dev, int size)
|
||||
{
|
||||
if(dev == NULL || dev->bus == NULL) {
|
||||
if(dev == NULL || dev->spi_controller >= BOARD_SPI_CONTROLLERS) {
|
||||
return SPI_DEV_STATUS_EINVAL;
|
||||
}
|
||||
|
||||
if(!spi_dev_arch_has_lock(dev)) {
|
||||
if(!spi_arch_has_lock(dev)) {
|
||||
return SPI_DEV_STATUS_BUS_LOCKED;
|
||||
}
|
||||
return spi_dev_arch_transfer(dev, NULL, 0, NULL, 0, size);
|
||||
|
||||
return spi_arch_transfer(dev, NULL, 0, NULL, 0, size);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
spi_dev_status_t
|
||||
spi_dev_transfer(spi_device_t *dev,
|
||||
const uint8_t *wdata, int wsize,
|
||||
uint8_t *rbuf, int rsize, int ignore)
|
||||
spi_status_t
|
||||
spi_transfer(spi_device_t *dev,
|
||||
const uint8_t *wdata, int wsize,
|
||||
uint8_t *rbuf, int rsize, int ignore)
|
||||
{
|
||||
if(dev == NULL || dev->bus == NULL) {
|
||||
if(dev == NULL || dev->spi_controller >= BOARD_SPI_CONTROLLERS) {
|
||||
return SPI_DEV_STATUS_EINVAL;
|
||||
}
|
||||
|
||||
if(!spi_dev_arch_has_lock(dev)) {
|
||||
if(!spi_arch_has_lock(dev)) {
|
||||
return SPI_DEV_STATUS_BUS_LOCKED;
|
||||
}
|
||||
|
||||
@ -155,53 +183,43 @@ spi_dev_transfer(spi_device_t *dev,
|
||||
return SPI_DEV_STATUS_EINVAL;
|
||||
}
|
||||
|
||||
return spi_dev_arch_transfer(dev, wdata, wsize, rbuf, rsize, ignore);
|
||||
return spi_arch_transfer(dev, wdata, wsize, rbuf, rsize, ignore);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Chip select can only be done when the bus is locked to this device */
|
||||
spi_dev_status_t
|
||||
spi_dev_chip_select(spi_device_t *dev, uint8_t on)
|
||||
spi_status_t
|
||||
spi_read_register(spi_device_t *dev, uint8_t reg, uint8_t *data, int size)
|
||||
{
|
||||
if(dev == NULL || dev->bus == NULL) {
|
||||
return SPI_DEV_STATUS_EINVAL;
|
||||
}
|
||||
if(spi_dev_has_bus(dev)) {
|
||||
return dev->chip_select(on);
|
||||
}
|
||||
return SPI_DEV_STATUS_BUS_NOT_OWNED;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
spi_dev_status_t
|
||||
spi_dev_read_register(spi_device_t *dev, uint8_t reg, uint8_t *data, int size)
|
||||
{
|
||||
spi_dev_status_t status;
|
||||
if(dev == NULL || dev->bus == NULL) {
|
||||
spi_status_t status;
|
||||
if(dev == NULL || dev->spi_controller >= BOARD_SPI_CONTROLLERS) {
|
||||
return SPI_DEV_STATUS_EINVAL;
|
||||
}
|
||||
|
||||
/* write the register first (will read a status) */
|
||||
status = spi_dev_write_byte(dev, reg);
|
||||
status = spi_write_byte(dev, reg);
|
||||
if(status != SPI_DEV_STATUS_OK) {
|
||||
return status;
|
||||
}
|
||||
|
||||
/* then read the value (will read the value) */
|
||||
status = spi_dev_read(dev, data, size);
|
||||
status = spi_read(dev, data, size);
|
||||
if(status != SPI_DEV_STATUS_OK) {
|
||||
return status;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
spi_dev_status_t
|
||||
spi_dev_strobe(spi_device_t *dev, uint8_t strobe, uint8_t *result)
|
||||
spi_status_t
|
||||
spi_strobe(spi_device_t *dev, uint8_t strobe, uint8_t *result)
|
||||
{
|
||||
if(dev == NULL || dev->bus == NULL) {
|
||||
if(dev == NULL || dev->spi_controller >= BOARD_SPI_CONTROLLERS) {
|
||||
return SPI_DEV_STATUS_EINVAL;
|
||||
}
|
||||
|
||||
if(!spi_dev_arch_has_lock(dev)) {
|
||||
if(!spi_arch_has_lock(dev)) {
|
||||
return SPI_DEV_STATUS_BUS_LOCKED;
|
||||
}
|
||||
return spi_dev_arch_transfer(dev, &strobe, 1, result, 1, 0);
|
||||
|
||||
return spi_arch_transfer(dev, &strobe, 1, result, 1, 0);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
349
os/dev/spi-hal.h
Normal file
349
os/dev/spi-hal.h
Normal file
@ -0,0 +1,349 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, Yanzi Networks.
|
||||
* Copyright (c) 2017, University of Bristol - http://www.bristol.ac.uk/
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \addtogroup dev
|
||||
* @{
|
||||
*
|
||||
* \defgroup spi-hal SPI Hardware Abstraction Layer
|
||||
*
|
||||
* The SPI HAL provides a set of common functions that can be used in a
|
||||
* platform-independent fashion.
|
||||
*
|
||||
*
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* Header file for the SPI HAL
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#ifndef SPI_HAL_H_
|
||||
#define SPI_HAL_H_
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#include "contiki.h"
|
||||
#include "gpio-hal.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Include Arch-Specific conf */
|
||||
#ifdef SPI_HAL_CONF_ARCH_HDR_PATH
|
||||
#include SPI_HAL_CONF_ARCH_HDR_PATH
|
||||
#else /* PLATFORM_IMPLEMENTS_SPI_HAL */
|
||||
#define BOARD_SPI_CONTROLLERS 0
|
||||
#endif /* SPI_HAL_CONF_ARCH_HDR_PATH */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief SPI return codes
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
typedef enum {
|
||||
SPI_DEV_STATUS_OK, /* Everything OK */
|
||||
SPI_DEV_STATUS_EINVAL, /* Erroneous input value */
|
||||
SPI_DEV_STATUS_BUS_LOCKED, /* SPI bus is already locked */
|
||||
SPI_DEV_STATUS_BUS_NOT_OWNED, /* SPI bus is locked by someone else */
|
||||
SPI_DEV_STATUS_CLOSED /* SPI bus has not opened properly */
|
||||
} spi_status_t;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief SPI Device Configuration
|
||||
*
|
||||
* This is a structure to an architecture-independent SPI configuration.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
typedef struct spi_device {
|
||||
gpio_hal_pin_t pin_spi_sck; /* SPI SCK pin */
|
||||
gpio_hal_pin_t pin_spi_miso; /* SPI MISO pin */
|
||||
gpio_hal_pin_t pin_spi_mosi; /* SPI MOSI pin */
|
||||
gpio_hal_pin_t pin_spi_cs; /* SPI Chip Select pin */
|
||||
uint32_t spi_bit_rate; /* SPI bit rate */
|
||||
uint8_t spi_pha; /* SPI mode phase */
|
||||
uint8_t spi_pol; /* SPI mode polarity */
|
||||
uint8_t spi_controller; /* ID of SPI controller to use */
|
||||
} spi_device_t;
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* These are architecture-independent functions to be used by SPI devices. */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief Locks and then opens an SPI controller
|
||||
* \param dev An SPI device configuration which defines the controller
|
||||
* to be locked and the opening configuration.
|
||||
* \return SPI return code
|
||||
*/
|
||||
spi_status_t spi_acquire(spi_device_t *dev);
|
||||
|
||||
/**
|
||||
* \brief Closes and then unlocks an SPI controller
|
||||
* \param dev An SPI device configuration which defines the controller
|
||||
* to be closed and unlocked.
|
||||
* \return SPI return code
|
||||
*
|
||||
* Releasing an SPI controller should put it in low-power mode.
|
||||
* This should work only if the device has already locked the SPI
|
||||
* controller.
|
||||
*/
|
||||
spi_status_t spi_release(spi_device_t *dev);
|
||||
|
||||
/**
|
||||
* \brief Selects the SPI peripheral
|
||||
* \param dev An SPI device configuration which defines the CS pin.
|
||||
* \return SPI return code
|
||||
*
|
||||
* Clears the CS pin. This should work only if the device has
|
||||
* already locked the SPI controller.
|
||||
*/
|
||||
spi_status_t spi_select(spi_device_t *dev);
|
||||
|
||||
/**
|
||||
* \brief Deselects the SPI peripheral
|
||||
* \param dev An SPI device configuration which defines the CS pin.
|
||||
* \return SPI return code
|
||||
*
|
||||
* Sets the CS pin. Lock is not required.
|
||||
*/
|
||||
spi_status_t spi_deselect(spi_device_t *dev);
|
||||
|
||||
/**
|
||||
* \brief Checks if a device has locked an SPI controller
|
||||
* \param dev An SPI device configuration which defines the controller.
|
||||
* \return true if the device has the lock, false otherwise.
|
||||
*/
|
||||
bool spi_has_bus(spi_device_t *dev);
|
||||
|
||||
/**
|
||||
* \brief Writes a single byte to an SPI device
|
||||
* \param dev An SPI device configuration.
|
||||
* \param data A byte of data
|
||||
* \return SPI return code
|
||||
*
|
||||
* It should work only if the device has already locked the SPI controller.
|
||||
*/
|
||||
spi_status_t spi_write_byte(spi_device_t *dev, uint8_t data);
|
||||
|
||||
/**
|
||||
* \brief Reads a single byte from an SPI device
|
||||
* \param dev An SPI device configuration.
|
||||
* \param data A pointer to a byte of data
|
||||
* \return SPI return code
|
||||
*
|
||||
* It should work only if the device has already locked the SPI controller.
|
||||
*/
|
||||
spi_status_t spi_read_byte(spi_device_t *dev, uint8_t *data);
|
||||
|
||||
/**
|
||||
* \brief Writes a buffer to an SPI device
|
||||
* \param dev An SPI device configuration.
|
||||
* \param data A pointer to the data
|
||||
* \param size Size of the data to write
|
||||
* \return SPI return code
|
||||
*
|
||||
* It should work only if the device has already locked the SPI controller.
|
||||
*/
|
||||
spi_status_t spi_write(spi_device_t *dev,
|
||||
const uint8_t *data, int size);
|
||||
|
||||
/**
|
||||
* \brief Reads a buffer from an SPI device
|
||||
* \param dev An SPI device configuration.
|
||||
* \param data A pointer to the data
|
||||
* \param size Size of the data to read
|
||||
* \return SPI return code
|
||||
*
|
||||
* It should work only if the device has already locked the SPI controller.
|
||||
*/
|
||||
spi_status_t spi_read(spi_device_t *dev, uint8_t *data, int size);
|
||||
|
||||
/**
|
||||
* \brief Reads and ignores data from an SPI device
|
||||
* \param dev An SPI device configuration.
|
||||
* \param size Size of the data to read and ignore
|
||||
* \return SPI return code
|
||||
*
|
||||
* Reads size bytes from the SPI and throws them away.
|
||||
* It should work only if the device has already locked the SPI controller.
|
||||
*/
|
||||
spi_status_t spi_read_skip(spi_device_t *dev, int size);
|
||||
|
||||
/**
|
||||
* \brief Performs a generic SPI transfer
|
||||
* \param dev An SPI device configuration.
|
||||
* \param data A pointer to the data to be written. Set it to NULL to
|
||||
* skip writing.
|
||||
* \param wlen Size of data to write.
|
||||
* \param buf A pointer to buffer to copy the data read. Set to NULL
|
||||
* to skip reading.
|
||||
* \param rlen Size of data to read.
|
||||
* \param ignore_len Size of data to read and ignore.
|
||||
* \return SPI return code
|
||||
*
|
||||
* It should work only if the device has already locked the SPI controller.
|
||||
* A total of rlen+ignore_len bytes will be read. The first rlen bytes will
|
||||
* be copied to buf. The remaining ignore_len bytes won't be copied to the
|
||||
* buffer. The maximum of wlen and rlen+ignore_len of bytes will be transfered.
|
||||
*/
|
||||
spi_status_t spi_transfer(spi_device_t *dev,
|
||||
const uint8_t *data, int wsize,
|
||||
uint8_t *buf, int rsize, int ignore);
|
||||
|
||||
/**
|
||||
* \brief Reads and Writes one byte from/to an SPI device
|
||||
* \param dev An SPI device configuration.
|
||||
* \param strobe Byte to write
|
||||
* \param status Pointer to byte to read
|
||||
* \return SPI return code
|
||||
*
|
||||
* It should work only if the device has already locked the SPI controller.
|
||||
*/
|
||||
spi_status_t spi_strobe(spi_device_t *dev, uint8_t strobe,
|
||||
uint8_t *status);
|
||||
|
||||
/**
|
||||
* \brief Reads a buffer of bytes from a register of an SPI device
|
||||
* \param dev An SPI device configuration.
|
||||
* \param reg Register
|
||||
* \param data A pointer to the data
|
||||
* \param size Size of the data to read
|
||||
* \return SPI return code
|
||||
*
|
||||
* It should work only if the device has already locked the SPI controller.
|
||||
*/
|
||||
spi_status_t spi_read_register(spi_device_t *dev, uint8_t reg,
|
||||
uint8_t *data, int size);
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* These are architecture-specific functions to be implemented by each CPU. */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* \brief Locks an SPI controller to device dev.
|
||||
* \param dev An SPI device configuration which defines the controller
|
||||
* to be locked and the device that locks it.
|
||||
* \return SPI return code
|
||||
*
|
||||
*/
|
||||
spi_status_t spi_arch_lock(spi_device_t *dev);
|
||||
|
||||
/**
|
||||
* \brief Unlocks an SPI controller.
|
||||
* \param dev An SPI device configuration which defines the controller
|
||||
* to be unlocked and the device that unlocks it.
|
||||
* \return SPI return code
|
||||
*
|
||||
*/
|
||||
spi_status_t spi_arch_unlock(spi_device_t *dev);
|
||||
|
||||
/**
|
||||
* \brief Checks if a device has locked an SPI controller
|
||||
* \param dev An SPI device configuration which defines the controller
|
||||
* to be checked if it is locked and the respective device.
|
||||
* \return 1 if the device has the lock, 0 otherwise.
|
||||
*
|
||||
*/
|
||||
bool spi_arch_has_lock(spi_device_t *dev);
|
||||
|
||||
/**
|
||||
* \brief Checks if an SPI controller is locked by any device
|
||||
* \param dev An SPI device configuration which defines the controller
|
||||
* to be checked.
|
||||
* \return 1 if the controller is locked, 0 otherwise.
|
||||
*
|
||||
*/
|
||||
bool spi_arch_is_bus_locked(spi_device_t *dev);
|
||||
|
||||
/**
|
||||
* \brief Opens an SPI controller to the configuration specified.
|
||||
* \param dev An SPI device configuration.
|
||||
* \return SPI return code
|
||||
*
|
||||
* This should work only if the device has already locked the SPI
|
||||
* controller.
|
||||
*
|
||||
*/
|
||||
spi_status_t spi_arch_open(spi_device_t *dev);
|
||||
|
||||
/**
|
||||
* \brief Closes an SPI controller
|
||||
* \param dev An SPI device configuration that specifies the controller.
|
||||
* \return SPI return code
|
||||
*
|
||||
* This should turn off the SPI controller to put it in low power mode.
|
||||
* It should work only if the device has already locked the SPI
|
||||
* controller.
|
||||
*
|
||||
*/
|
||||
spi_status_t spi_arch_close(spi_device_t *dev);
|
||||
|
||||
/**
|
||||
* \brief Performs an SPI transfer
|
||||
* \param dev An SPI device configuration that specifies the controller.
|
||||
* \param data A pointer to the data to be written. Set it to NULL to
|
||||
* skip writing.
|
||||
* \param wlen Length of data to write.
|
||||
* \param buf A pointer to buffer to copy the data read. Set to NULL
|
||||
* to skip reading.
|
||||
* \param rlen Length of data to read.
|
||||
* \param ignore_len Length of data to read and ignore.
|
||||
* \return SPI return code
|
||||
*
|
||||
* It should work only if the device has already locked the SPI controller.
|
||||
* A total of rlen+ignore_len bytes will be read. The first rlen bytes will
|
||||
* be copied to buf. The remaining ignore_len bytes won't be copied to the
|
||||
* buffer. The maximum of wlen and rlen+ignore_len of bytes will be transfered.
|
||||
*/
|
||||
spi_status_t spi_arch_transfer(spi_device_t *dev,
|
||||
const uint8_t *data, int wlen,
|
||||
uint8_t *buf, int rlen,
|
||||
int ignore_len);
|
||||
|
||||
/**
|
||||
* \brief Selects an SPI device
|
||||
* \param dev An SPI device configuration that specifies the CS pin.
|
||||
* \return SPI return code
|
||||
*
|
||||
* Clears the CS pin. It should work only if the device has already
|
||||
* locked the SPI controller.
|
||||
*/
|
||||
spi_status_t spi_arch_select(spi_device_t *dev);
|
||||
|
||||
/**
|
||||
* \brief Deselects an SPI device
|
||||
* \param dev An SPI device configuration that specifies the CS pin.
|
||||
* \return SPI return code
|
||||
*
|
||||
* Set the CS pin. Locking the SPI controller is not needed.
|
||||
*/
|
||||
spi_status_t spi_arch_deselect(spi_device_t *dev);
|
||||
|
||||
#endif /* SPI_HAL_H_ */
|
Loading…
Reference in New Issue
Block a user