Implented SPI HAL for CC13xx/CC26xx
This commit is contained in:
parent
972502b3e2
commit
813543b569
@ -73,6 +73,7 @@ CONTIKI_CPU_SOURCEFILES += watchdog-arch.c dbg-arch.c
|
||||
CONTIKI_CPU_SOURCEFILES += uart0-arch.c slip-arch.c
|
||||
CONTIKI_CPU_SOURCEFILES += gpio-hal-arch.c int-master-arch.c
|
||||
CONTIKI_CPU_SOURCEFILES += random.c trng-arch.c
|
||||
CONTIKI_CPU_SOURCEFILES += spi-arch.c
|
||||
|
||||
# RF source files
|
||||
CONTIKI_CPU_SOURCEFILES += sched.c data-queue.c
|
||||
|
@ -410,6 +410,47 @@
|
||||
#endif
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \name SPI HAL configuration.
|
||||
*
|
||||
* CC13x0/CC26x0 has one SPI interface, while CC13x2/CC26x2 has two
|
||||
* SPI interfaces. Some additional checks has to be made for the
|
||||
* SPI_CONF_CONTROLLER_COUNT configuration, as this relies on whether the
|
||||
* available SPI interfaces are enabled or not, as well as if the SPI driver
|
||||
* is enabled at all.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
#if TI_SPI_CONF_ENABLE
|
||||
/*
|
||||
* The SPI driver is enabled. Therefore, the number of SPI interfaces depends
|
||||
* on which Device family parent the device falls under and if any of its
|
||||
* corresponding SPI interfaces are enabled or not.
|
||||
*/
|
||||
|
||||
#define SPI0_IS_ENABLED ((TI_SPI_CONF_SPI0_ENABLE) ? 1 : 0)
|
||||
#define SPI1_IS_ENABLED ((TI_SPI_CONF_SPI1_ENABLE) ? 1 : 0)
|
||||
|
||||
#if (DeviceFamily_PARENT == DeviceFamily_PARENT_CC13X0_CC26X0)
|
||||
|
||||
/* CC13x0/CC26x0 only has one SPI interface: SPI0. */
|
||||
#define SPI_CONF_CONTROLLER_COUNT (SPI0_IS_ENABLED)
|
||||
|
||||
#elif (DeviceFamily_PARENT == DeviceFamily_PARENT_CC13X2_CC26X2)
|
||||
|
||||
/* CC13x0/CC26x0 only has two SPI interface: SPI0 and SPI1. */
|
||||
#define SPI_CONF_CONTROLLER_COUNT (SPI0_ENABLED + SPI1_IS_ENABLED)
|
||||
|
||||
#endif /* DeviceFamily_PARENT */
|
||||
|
||||
#else /* TI_SPI_CONF_ENABLE */
|
||||
/*
|
||||
* If the SPI driver is disabled then there are 0 available
|
||||
* SPI interfaces. */
|
||||
#define SPI_CONF_CONTROLLER_COUNT 0
|
||||
#endif /* TI_SPI_CONF_ENABLE */
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \name Slip configuration
|
||||
*
|
||||
|
265
arch/cpu/cc13xx-cc26xx/dev/spi-arch.c
Normal file
265
arch/cpu/cc13xx-cc26xx/dev/spi-arch.c
Normal file
@ -0,0 +1,265 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Texas Instruments Incorporated - http://www.ti.com/
|
||||
* 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 HOLDERS 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 cc13xx-cc26xx-cpu
|
||||
* @{
|
||||
*
|
||||
* \defgroup cc13xx-cc26xx-spi CC13xx/CC26xx SPI HAL
|
||||
*
|
||||
* @{
|
||||
* \file
|
||||
* Implementation of the SPI HAL driver for CC13xx/CC26xx.
|
||||
* \author
|
||||
* Edvard Pettersen <e.pettersen@ti.com>
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#include "contiki.h"
|
||||
#include "sys/cc.h"
|
||||
#include "dev/spi.h"
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#include <ti/drivers/SPI.h>
|
||||
#include <ti/drivers/dpl/HwiP.h>
|
||||
#include <ti/drivers/pin/PINCC26XX.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
typedef struct {
|
||||
SPI_Handle handle;
|
||||
spi_device_t *owner;
|
||||
} spi_arch_t;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#if (SPI_CONTROLLER_COUNT > 0)
|
||||
static spi_arch_t spi_arches[SPI_CONTROLLER_COUNT];
|
||||
#else
|
||||
static spi_arch_t *spi_arches = NULL;
|
||||
#endif
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static inline spi_arch_t*
|
||||
get_handle(uint8_t spi_controller)
|
||||
{
|
||||
if(spi_controller < SPI_CONTROLLER_COUNT) {
|
||||
return &spi_arches[spi_controller];
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static SPI_FrameFormat
|
||||
convert_frame_format(uint8_t pol, uint8_t pha)
|
||||
{
|
||||
pol = (pol) ? 1 : 0;
|
||||
pha = (pha) ? 1 : 0;
|
||||
/*
|
||||
* Convert pol/pha to a single byte on the following format:
|
||||
* xxxA xxxB
|
||||
* where A is the polarity bit and B is the phase bit.
|
||||
* Note that any other value deviating from this format will
|
||||
* default to the SPI_POL1_PHA1 format.
|
||||
*/
|
||||
uint8_t pol_pha = (pol << 4) | (pha << 0);
|
||||
switch(pol_pha) {
|
||||
case 0x00: return SPI_POL0_PHA0;
|
||||
case 0x01: return SPI_POL0_PHA1;
|
||||
case 0x10: return SPI_POL1_PHA0;
|
||||
default: /* fallthrough */
|
||||
case 0x11: return SPI_POL1_PHA1;
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
bool
|
||||
spi_arch_has_lock(spi_device_t *dev)
|
||||
{
|
||||
/*
|
||||
* The SPI device is the owner if the SPI controller returns a valid
|
||||
* SPI arch object and the SPI device is owner of that object.
|
||||
*/
|
||||
spi_arch_t *spi_arch = get_handle(dev->spi_controller);
|
||||
return (spi_arch != NULL) && (spi_arch->owner == dev);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
bool
|
||||
spi_arch_is_bus_locked(spi_device_t *dev)
|
||||
{
|
||||
/*
|
||||
* The SPI controller is locked by any device if the SPI controller returns
|
||||
* a valid SPI arch object and the SPI handle of that object is valid.
|
||||
*/
|
||||
spi_arch_t *spi_arch = get_handle(dev->spi_controller);
|
||||
return (spi_arch != NULL) && (spi_arch->handle != NULL);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
spi_status_t
|
||||
spi_arch_lock_and_open(spi_device_t *dev)
|
||||
{
|
||||
uint_least8_t spi_index;
|
||||
spi_arch_t *spi_arch;
|
||||
SPI_Params spi_params;
|
||||
|
||||
const uintptr_t hwi_key = HwiP_disable();
|
||||
|
||||
spi_index = dev->spi_controller;
|
||||
spi_arch = get_handle(spi_index);
|
||||
|
||||
/* Ensure the provided SPI index is valid. */
|
||||
if(spi_arch == NULL) {
|
||||
HwiP_restore(hwi_key);
|
||||
return SPI_DEV_STATUS_EINVAL;
|
||||
}
|
||||
|
||||
/* Ensure the corresponding SPI interface is not already locked. */
|
||||
if(spi_arch_is_bus_locked(dev)) {
|
||||
HwiP_restore(hwi_key);
|
||||
return SPI_DEV_STATUS_BUS_LOCKED;
|
||||
}
|
||||
|
||||
SPI_Params_init(&spi_params);
|
||||
|
||||
spi_params.transferMode = SPI_MODE_BLOCKING;
|
||||
spi_params.mode = SPI_MASTER;
|
||||
spi_params.bitRate = dev->spi_bit_rate;
|
||||
spi_params.dataSize = 8;
|
||||
spi_params.frameFormat = convert_frame_format(dev->spi_pol, dev->spi_pha);
|
||||
|
||||
/*
|
||||
* Try to open the SPI driver. Accessing the SPI driver also ensures
|
||||
* atomic access to the SPI interface.
|
||||
*/
|
||||
spi_arch->handle = SPI_open(spi_index, &spi_params);
|
||||
|
||||
if(spi_arch->handle == NULL) {
|
||||
HwiP_restore(hwi_key);
|
||||
return SPI_DEV_STATUS_BUS_LOCKED;
|
||||
}
|
||||
|
||||
spi_arch->owner = dev;
|
||||
|
||||
HwiP_restore(hwi_key);
|
||||
return SPI_DEV_STATUS_OK;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
spi_status_t
|
||||
spi_arch_close_and_unlock(spi_device_t *dev)
|
||||
{
|
||||
spi_arch_t *spi_arch;
|
||||
|
||||
const uintptr_t hwi_key = HwiP_disable();
|
||||
|
||||
/* Ensure the provided SPI index is valid. */
|
||||
spi_arch = get_handle(dev->spi_controller);
|
||||
if(spi_arch == NULL) {
|
||||
HwiP_restore(hwi_key);
|
||||
return SPI_DEV_STATUS_EINVAL;
|
||||
}
|
||||
|
||||
/* Ensure the corresponding SPI device owns the SPI controller. */
|
||||
if(!spi_arch_has_lock(dev)) {
|
||||
HwiP_restore(hwi_key);
|
||||
return SPI_DEV_STATUS_BUS_NOT_OWNED;
|
||||
}
|
||||
|
||||
SPI_close(spi_arch->handle);
|
||||
|
||||
spi_arch->handle = NULL;
|
||||
spi_arch->owner = NULL;
|
||||
|
||||
HwiP_restore(hwi_key);
|
||||
return SPI_DEV_STATUS_OK;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
spi_status_t
|
||||
spi_arch_transfer(spi_device_t *dev,
|
||||
const uint8_t *write_buf, int wlen,
|
||||
uint8_t *inbuf, int rlen, int ignore_len)
|
||||
{
|
||||
spi_arch_t *spi_arch;
|
||||
size_t totlen;
|
||||
SPI_Transaction spi_transaction;
|
||||
bool transfer_ok;
|
||||
|
||||
/* Ensure the provided SPI index is valid. */
|
||||
spi_arch = get_handle(dev->spi_controller);
|
||||
if(spi_arch == NULL) {
|
||||
return SPI_DEV_STATUS_EINVAL;
|
||||
}
|
||||
|
||||
if(!spi_arch_has_lock(dev)) {
|
||||
return SPI_DEV_STATUS_BUS_NOT_OWNED;
|
||||
}
|
||||
|
||||
totlen = MAX((size_t)(rlen + ignore_len), (size_t)wlen);
|
||||
|
||||
if(totlen == 0) {
|
||||
/* Nothing to do */
|
||||
return SPI_DEV_STATUS_OK;
|
||||
}
|
||||
|
||||
spi_transaction.count = totlen;
|
||||
spi_transaction.txBuf = (void *)write_buf;
|
||||
spi_transaction.rxBuf = (void *)inbuf;
|
||||
|
||||
transfer_ok = SPI_transfer(spi_arch->handle, &spi_transaction);
|
||||
|
||||
if(!transfer_ok) {
|
||||
return SPI_DEV_STATUS_TRANSFER_ERR;
|
||||
}
|
||||
|
||||
return SPI_DEV_STATUS_OK;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
spi_status_t
|
||||
spi_arch_select(spi_device_t *dev)
|
||||
{
|
||||
if(!spi_arch_has_lock(dev)) {
|
||||
return SPI_DEV_STATUS_BUS_NOT_OWNED;
|
||||
}
|
||||
|
||||
PINCC26XX_setOutputValue(dev->pin_spi_cs, 0);
|
||||
|
||||
return SPI_DEV_STATUS_OK;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
spi_status_t
|
||||
spi_arch_deselect(spi_device_t *dev)
|
||||
{
|
||||
if(!spi_arch_has_lock(dev)) {
|
||||
return SPI_DEV_STATUS_BUS_NOT_OWNED;
|
||||
}
|
||||
|
||||
PINCC26XX_setOutputValue(dev->pin_spi_cs, 1);
|
||||
|
||||
return SPI_DEV_STATUS_OK;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
@ -6,8 +6,8 @@
|
||||
BOARD_PLATFORMS = launchpad sensortag srf06
|
||||
|
||||
# All supported boards for this SimpleLink family
|
||||
BOARDS := $(foreach BOARD_TYPE, $(BOARD_PLATFORMS), \
|
||||
$(shell cd $(FAMILY_PATH); find $(BOARD_TYPE)/* -type d -print))
|
||||
BOARDS := $(foreach BOARD, $(BOARD_PLATFORMS), \
|
||||
$(shell cd $(FAMILY_PATH); find $(BOARD)/* -type d -print))
|
||||
|
||||
################################################################################
|
||||
# Directory and source configurations
|
||||
|
@ -50,6 +50,8 @@
|
||||
#ifndef BOARD_CONF_H_
|
||||
#define BOARD_CONF_H_
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#include "contiki-conf.h"
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \name LED configurations for the dev/leds.h API.
|
||||
*
|
||||
@ -83,6 +85,15 @@
|
||||
#define BOARD_CONF_HAS_SENSORS 0
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \name The external flash SPI CS pin, defined in Board.h.
|
||||
*
|
||||
* Those values are not meant to be modified by the user
|
||||
* @{
|
||||
*/
|
||||
#define EXT_FLASH_SPI_PIN_CS Board_SPI_FLASH_CS
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#endif /* BOARD_CONF_H_ */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
|
@ -50,6 +50,8 @@
|
||||
#ifndef BOARD_CONF_H_
|
||||
#define BOARD_CONF_H_
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#include "contiki-conf.h"
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#include "leds-arch.h"
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
@ -81,6 +83,15 @@
|
||||
#define BOARD_SENSORS_ENABLE (!(BOARD_CONF_SENSORS_DISABLE))
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \name The external flash SPI CS pin, defined in Board.h.
|
||||
*
|
||||
* Those values are not meant to be modified by the user
|
||||
* @{
|
||||
*/
|
||||
#define EXT_FLASH_SPI_PIN_CS Board_SPI_FLASH_CS
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#endif /* BOARD_CONF_H_ */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
|
@ -1,7 +1,7 @@
|
||||
################################################################################
|
||||
# SimpleLink LaunchPad makefile
|
||||
|
||||
BOARD_TYPE = BOARD_SRF06
|
||||
BOARD_TYPE = BOARD_SMARTRF06EB
|
||||
|
||||
# leds-arch.c etc.
|
||||
BOARD_SOURCEFILES += srf06-sensors.c
|
||||
|
@ -80,6 +80,7 @@
|
||||
typedef enum {
|
||||
SPI_DEV_STATUS_OK, /* Everything OK */
|
||||
SPI_DEV_STATUS_EINVAL, /* Erroneous input value */
|
||||
SPI_DEV_STATUS_TRANSFER_ERR, /* Error during SPI transfer */
|
||||
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 */
|
||||
|
Loading…
Reference in New Issue
Block a user