osd-contiki/cpu/cc26xx-cc13xx/rf-core/rf-core.h
Jonas Olsson 01e36532c2 Add support for the CC13xx CPU
This commit:

* Moves all cpu files from cpu/cc26xx to cpu/cc26xx-cc13xx
* Bumps the CC26xxware submodule to the latest TI release
* Adds CC13xxware as a submodule
* Adds support for sub-ghz mode / IEEE 802.15.4g
* Splits the driver into multiple files for clarity. We now have the following structure:
  * A common module that handles access to the RF core, interrupts etc
  * A module that takes care of BLE functionality
  * A netstack radio driver for IEEE mode (2.4GHz)
  * A netstack radio driver for PROP mode (sub-ghz - multiple bands)

This commit also adds tick suppression functionality, applicable to all chips of the CC26xx and CC13xx families. Instead waking up on every clock tick simply to increment our software counter, we now only wake up just in time to service the next scheduled etimer. ContikiMAC-triggered wakeups are unaffected.

Laslty, this commit also applies a number of minor changes:
* Addition of missing includes
* Removal of stub functions
* Removal of a woraround for a CC26xxware bug that has now been fixed
2015-08-23 19:54:42 +01:00

418 lines
18 KiB
C

/*
* Copyright (c) 2015, 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 cc26xx
* @{
*
* \defgroup rf-core CC13xx/CC26xx RF core
*
* Different flavours of chips of the CC13xx/CC26xx family have different
* radio capability. For example, the CC2650 can operate in IEEE 802.15.4 mode
* at 2.4GHz, but it can also operate in BLE mode. The CC1310 only supports
* sub-ghz mode.
*
* However, there are many radio functionalities that are identical across
* all chips. The rf-core driver provides support for this common functionality
*
* @{
*
* \file
* Header file for the CC13xx/CC26xx RF core driver
*/
/*---------------------------------------------------------------------------*/
#ifndef RF_CORE_H_
#define RF_CORE_H_
/*---------------------------------------------------------------------------*/
#include "contiki-conf.h"
#include "rf-core/api/common_cmd.h"
#include <stdint.h>
#include <stdbool.h>
/*---------------------------------------------------------------------------*/
/* The channel to use in IEEE or prop mode. */
#ifdef RF_CORE_CONF_CHANNEL
#define RF_CORE_CHANNEL RF_CORE_CONF_CHANNEL
#else
#define RF_CORE_CHANNEL 25
#endif /* RF_CORE_CONF_IEEE_MODE_CHANNEL */
/*---------------------------------------------------------------------------*/
#define RF_CORE_CMD_ERROR 0
#define RF_CORE_CMD_OK 1
/*---------------------------------------------------------------------------*/
/**
* \brief A data strcuture representing the radio's primary mode of operation
*
* The CC13xx / CC26xx radio supports up to potentially 3 modes: IEEE, Prop and
* BLE. Within Contiki, we assume that the radio is by default in one of IEEE
* or Prop in order to support standard 6LoWPAN / .15.4 operation. The BLE
* mode interrupts this so called "primary" mode in order to send BLE adv
* messages. Once BLE is done advertising, we need to be able to restore the
* previous .15.4 mode. Unfortunately, the only way this can be done with
* NETSTACK_RADIO API is by fully power-cycling the radio, which is something
* we do not want to do.
*
* Thus, we declare a secondary data structure for primary mode drivers (IEEE
* or Prop). We use this data structure to issue "soft off" and "back on"
* commands. Soft off in this context means stopping RX (e.g. the respective
* IEEE RX operation), but without shutting down the RF core (which is what
* NETSTACK_RADIO.off() would have done). We then remember what mode we were
* using in order to be able to re-enter RX mode for this mode.
*
* A NETSTACK_RADIO driver will declare those two functions somewhere within
* its module of implementation. During its init() routine, it will notify
* the RF core module so that the latter can abort and restore operations.
*/
typedef struct rf_core_primary_mode_s {
/**
* \brief A pointer to a function used to abort the current radio op
*/
void (*abort)(void);
/**
* \brief A pointer to a function that will restore the previous radio op
* \return RF_CORE_CMD_OK or RF_CORE_CMD_ERROR
*/
uint8_t (*restore)(void);
} rf_core_primary_mode_t;
/*---------------------------------------------------------------------------*/
/* RF Command status constants - Correspond to values in the CMDSTA register */
#define RF_CORE_CMDSTA_PENDING 0x00
#define RF_CORE_CMDSTA_DONE 0x01
#define RF_CORE_CMDSTA_ILLEGAL_PTR 0x81
#define RF_CORE_CMDSTA_UNKNOWN_CMD 0x82
#define RF_CORE_CMDSTA_UNKNOWN_DIR_CMD 0x83
#define RF_CORE_CMDSTA_CONTEXT_ERR 0x85
#define RF_CORE_CMDSTA_SCHEDULING_ERR 0x86
#define RF_CORE_CMDSTA_PAR_ERR 0x87
#define RF_CORE_CMDSTA_QUEUE_ERR 0x88
#define RF_CORE_CMDSTA_QUEUE_BUSY 0x89
/* Status values starting with 0x8 correspond to errors */
#define RF_CORE_CMDSTA_ERR_MASK 0x80
/* CMDSTA is 32-bits. Return value in bits 7:0 */
#define RF_CORE_CMDSTA_RESULT_MASK 0xFF
#define RF_CORE_RADIO_OP_STATUS_IDLE 0x0000
/*---------------------------------------------------------------------------*/
#define RF_CORE_NOT_ACCESSIBLE 0x00
#define RF_CORE_ACCESSIBLE 0x01
/*---------------------------------------------------------------------------*/
/* RF Radio Op status constants. Field 'status' in Radio Op command struct */
#define RF_CORE_RADIO_OP_STATUS_IDLE 0x0000
#define RF_CORE_RADIO_OP_STATUS_PENDING 0x0001
#define RF_CORE_RADIO_OP_STATUS_ACTIVE 0x0002
#define RF_CORE_RADIO_OP_STATUS_SKIPPED 0x0003
#define RF_CORE_RADIO_OP_STATUS_DONE_OK 0x0400
#define RF_CORE_RADIO_OP_STATUS_DONE_COUNTDOWN 0x0401
#define RF_CORE_RADIO_OP_STATUS_DONE_RXERR 0x0402
#define RF_CORE_RADIO_OP_STATUS_DONE_TIMEOUT 0x0403
#define RF_CORE_RADIO_OP_STATUS_DONE_STOPPED 0x0404
#define RF_CORE_RADIO_OP_STATUS_DONE_ABORT 0x0405
#define RF_CORE_RADIO_OP_STATUS_ERROR_PAST_START 0x0800
#define RF_CORE_RADIO_OP_STATUS_ERROR_START_TRIG 0x0801
#define RF_CORE_RADIO_OP_STATUS_ERROR_CONDITION 0x0802
#define RF_CORE_RADIO_OP_STATUS_ERROR_PAR 0x0803
#define RF_CORE_RADIO_OP_STATUS_ERROR_POINTER 0x0804
#define RF_CORE_RADIO_OP_STATUS_ERROR_CMDID 0x0805
#define RF_CORE_RADIO_OP_STATUS_ERROR_NO_SETUP 0x0807
#define RF_CORE_RADIO_OP_STATUS_ERROR_NO_FS 0x0808
#define RF_CORE_RADIO_OP_STATUS_ERROR_SYNTH_PROG 0x0809
/* Additional Op status values for IEEE mode */
#define RF_CORE_RADIO_OP_STATUS_IEEE_SUSPENDED 0x2001
#define RF_CORE_RADIO_OP_STATUS_IEEE_DONE_OK 0x2400
#define RF_CORE_RADIO_OP_STATUS_IEEE_DONE_BUSY 0x2401
#define RF_CORE_RADIO_OP_STATUS_IEEE_DONE_STOPPED 0x2402
#define RF_CORE_RADIO_OP_STATUS_IEEE_DONE_ACK 0x2403
#define RF_CORE_RADIO_OP_STATUS_IEEE_DONE_ACKPEND 0x2404
#define RF_CORE_RADIO_OP_STATUS_IEEE_DONE_TIMEOUT 0x2405
#define RF_CORE_RADIO_OP_STATUS_IEEE_DONE_BGEND 0x2406
#define RF_CORE_RADIO_OP_STATUS_IEEE_DONE_ABORT 0x2407
#define RF_CORE_RADIO_OP_STATUS_ERROR_WRONG_BG 0x0806
#define RF_CORE_RADIO_OP_STATUS_IEEE_ERROR_PAR 0x2800
#define RF_CORE_RADIO_OP_STATUS_IEEE_ERROR_NO_SETUP 0x2801
#define RF_CORE_RADIO_OP_STATUS_IEEE_ERROR_NO_FS 0x2802
#define RF_CORE_RADIO_OP_STATUS_IEEE_ERROR_SYNTH_PROG 0x2803
#define RF_CORE_RADIO_OP_STATUS_IEEE_ERROR_RXOVF 0x2804
#define RF_CORE_RADIO_OP_STATUS_IEEE_ERROR_TXUNF 0x2805
/* Op status values for BLE mode */
#define RF_CORE_RADIO_OP_STATUS_BLE_DONE_OK 0x1400
#define RF_CORE_RADIO_OP_STATUS_BLE_DONE_RXTIMEOUT 0x1401
#define RF_CORE_RADIO_OP_STATUS_BLE_DONE_NOSYNC 0x1402
#define RF_CORE_RADIO_OP_STATUS_BLE_DONE_RXERR 0x1403
#define RF_CORE_RADIO_OP_STATUS_BLE_DONE_CONNECT 0x1404
#define RF_CORE_RADIO_OP_STATUS_BLE_DONE_MAXNACK 0x1405
#define RF_CORE_RADIO_OP_STATUS_BLE_DONE_ENDED 0x1406
#define RF_CORE_RADIO_OP_STATUS_BLE_DONE_ABORT 0x1407
#define RF_CORE_RADIO_OP_STATUS_BLE_DONE_STOPPED 0x1408
#define RF_CORE_RADIO_OP_STATUS_BLE_ERROR_PAR 0x1800
#define RF_CORE_RADIO_OP_STATUS_BLE_ERROR_RXBUF 0x1801
#define RF_CORE_RADIO_OP_STATUS_BLE_ERROR_NO_SETUP 0x1802
#define RF_CORE_RADIO_OP_STATUS_BLE_ERROR_NO_FS 0x1803
#define RF_CORE_RADIO_OP_STATUS_BLE_ERROR_SYNTH_PROG 0x1804
#define RF_CORE_RADIO_OP_STATUS_BLE_ERROR_RXOVF 0x1805
#define RF_CORE_RADIO_OP_STATUS_BLE_ERROR_TXUNF 0x1806
/* Op status values for proprietary mode */
#define RF_CORE_RADIO_OP_STATUS_PROP_DONE_OK 0x3400
#define RF_CORE_RADIO_OP_STATUS_PROP_DONE_RXTIMEOUT 0x3401
#define RF_CORE_RADIO_OP_STATUS_PROP_DONE_BREAK 0x3402
#define RF_CORE_RADIO_OP_STATUS_PROP_DONE_ENDED 0x3403
#define RF_CORE_RADIO_OP_STATUS_PROP_DONE_STOPPED 0x3404
#define RF_CORE_RADIO_OP_STATUS_PROP_DONE_ABORT 0x3405
#define RF_CORE_RADIO_OP_STATUS_PROP_DONE_RXERR 0x3406
#define RF_CORE_RADIO_OP_STATUS_PROP_DONE_IDLE 0x3407
#define RF_CORE_RADIO_OP_STATUS_PROP_DONE_BUSY 0x3408
#define RF_CORE_RADIO_OP_STATUS_PROP_DONE_IDLETIMEOUT 0x3409
#define RF_CORE_RADIO_OP_STATUS_PROP_DONE_BUSYTIMEOUT 0x340A
#define RF_CORE_RADIO_OP_STATUS_PROP_ERROR_PAR 0x3800
#define RF_CORE_RADIO_OP_STATUS_PROP_ERROR_RXBUF 0x3801
#define RF_CORE_RADIO_OP_STATUS_PROP_ERROR_RXFULL 0x3802
#define RF_CORE_RADIO_OP_STATUS_PROP_ERROR_NO_SETUP 0x3803
#define RF_CORE_RADIO_OP_STATUS_PROP_ERROR_NO_FS 0x3804
#define RF_CORE_RADIO_OP_STATUS_PROP_ERROR_RXOVF 0x3805
#define RF_CORE_RADIO_OP_STATUS_PROP_ERROR_TXUNF 0x3806
/* Bits 15:12 signify the protocol */
#define RF_CORE_RADIO_OP_STATUS_PROTO_MASK 0xF000
#define RF_CORE_RADIO_OP_STATUS_PROTO_GENERIC 0x0000
#define RF_CORE_RADIO_OP_STATUS_PROTO_BLE 0x1000
#define RF_CORE_RADIO_OP_STATUS_PROTO_IEEE 0x2000
#define RF_CORE_RADIO_OP_STATUS_PROTO_PROP 0x3000
/* Bits 11:10 signify Running / Done OK / Done with error */
#define RF_CORE_RADIO_OP_MASKED_STATUS 0x0C00
#define RF_CORE_RADIO_OP_MASKED_STATUS_RUNNING 0x0000
#define RF_CORE_RADIO_OP_MASKED_STATUS_DONE 0x0400
#define RF_CORE_RADIO_OP_MASKED_STATUS_ERROR 0x0800
/*---------------------------------------------------------------------------*/
/* Command Types */
#define RF_CORE_COMMAND_TYPE_MASK 0x0C00
#define RF_CORE_COMMAND_TYPE_IMMEDIATE 0x0000
#define RF_CORE_COMMAND_TYPE_RADIO_OP 0x0800
#define RF_CORE_COMMAND_TYPE_IEEE_BG_RADIO_OP 0x0800
#define RF_CORE_COMMAND_TYPE_IEEE_FG_RADIO_OP 0x0C00
#define RF_CORE_COMMAND_PROTOCOL_MASK 0x3000
#define RF_CORE_COMMAND_PROTOCOL_COMMON 0x0000
#define RF_CORE_COMMAND_PROTOCOL_BLE 0x1000
#define RF_CORE_COMMAND_PROTOCOL_IEEE 0x2000
#define RF_CORE_COMMAND_PROTOCOL_PROP 0x3000
/*---------------------------------------------------------------------------*/
/* Make the main driver process visible to mode drivers */
PROCESS_NAME(rf_core_process);
/*---------------------------------------------------------------------------*/
/**
* \brief Check whether the RF core is accessible
* \retval RF_CORE_ACCESSIBLE The core is powered and ready for access
* \retval RF_CORE_NOT_ACCESSIBLE The core is not ready
*
* If this function returns RF_CORE_NOT_ACCESSIBLE, rf_core_power_up() must be
* called before any attempt to access the core.
*/
uint8_t rf_core_is_accessible(void);
/**
* \brief Sends a command to the RF core.
*
* \param cmd The command value or a pointer to a command buffer
* \param status A pointer to a variable which will hold the status
* \return RF_CORE_CMD_OK or RF_CORE_CMD_ERROR
*
* This function supports all three types of command (Radio OP, immediate and
* direct)
*
* For immediate and Radio OPs, cmd is a pointer to the data structure
* containing the command and its parameters. This data structure must be
* 4-byte aligned.
*
* For direct commands, cmd contains the value of the command alongside its
* parameters. This value will be written to CMDSTA verbatim, so the command
* ID must be in the 16 high bits, and the 2 LS bits must be set to 01 by the
* caller.
*
* The caller is responsible of allocating and populating cmd for Radio OP and
* immediate commands
*
* The caller is responsible for allocating status
*
* For immediate commands and radio Ops, this function will set the command's
* status field to RF_CORE_RADIO_OP_STATUS_IDLE before sending it to the RF
*/
uint_fast8_t rf_core_send_cmd(uint32_t cmd, uint32_t *status);
/**
* \brief Block and wait for a Radio op to complete
* \param cmd A pointer to any command's structure
* \retval RF_CORE_CMD_OK the command completed with status _DONE_OK
* \retval RF_CORE_CMD_ERROR Timeout exceeded or the command completed with
* status _DONE_xxx (e.g. RF_CORE_RADIO_OP_STATUS_DONE_TIMEOUT)
*/
uint_fast8_t rf_core_wait_cmd_done(void *cmd);
/**
* \brief Turn on power to the RFC and boot it.
* \return RF_CORE_CMD_OK or RF_CORE_CMD_ERROR
*/
int rf_core_power_up(void);
/**
* \brief Disable RFCORE clock domain in the MCU VD and turn off the RFCORE PD
*/
void rf_core_power_down(void);
/**
* \brief Initialise RF APIs in the RF core
* \return RF_CORE_CMD_OK or RF_CORE_CMD_ERROR
*
* Depending on chip family and capability, this function will set the correct
* value to PRCM.RFCMODESEL
*/
uint8_t rf_core_set_modesel(void);
/**
* \brief Start the CM0 RAT
* \return RF_CORE_CMD_OK or RF_CORE_CMD_ERROR
*
* This function must be called each time the CM0 boots. The boot sequence
* can be performed automatically by calling rf_core_boot() if patches are not
* required. If patches are required then the patches must be applied after
* power up and before calling this function.
*/
uint8_t rf_core_start_rat(void);
/**
* \brief Boot the RF Core
* \return RF_CORE_CMD_OK or RF_CORE_CMD_ERROR
*
* This function will perform the CM0 boot sequence. It will first power it up
* and then start the RAT. If a patch is required, then the mode driver must
* not call this function and perform the sequence manually, applying patches
* after boot and before calling rf_core_start_rat().
*
* The function will return RF_CORE_CMD_ERROR if any of those steps fails. If
* the boot sequence fails to complete, the RF Core will be powered down.
*/
uint8_t rf_core_boot(void);
/**
* \brief Setup RF core interrupts
*/
void rf_core_setup_interrupts(void);
/**
* \brief Enable the LAST_CMD_DONE interrupt.
*
* This is used within TX routines in order to be able to sleep the CM3 and
* wake up after TX has finished
*
* \sa rf_core_cmd_done_dis()
*/
void rf_core_cmd_done_en(void);
/**
* \brief Disable the LAST_CMD_DONE interrupt.
*
* This is used within TX routines after TX has completed
*
* \sa rf_core_cmd_done_en()
*/
void rf_core_cmd_done_dis(void);
/**
* \brief Returns a pointer to the most recent proto-dependent Radio Op
* \return The pointer
*
* The RF Core driver will remember the most recent proto-dependent Radio OP
* issued, so that other modules can inspect its type and state at a subsequent
* stage. The assumption is that those commands will be issued by a function
* that will then return. The following commands will be "remembered"
*
* - All BLE Radio Ops (0x18nn)
* - All Prop Radio Ops (0x38nn)
* - IEEE BG Radio Ops (0x28nn)
*
* The following commands are assumed to be executed synchronously and will
* thus not be remembered by the core and not returned by this function:
*
* - Direct commands
* - Proto-independent commands (including Radio Ops and Immediate ones)
* - IEEE FG Radio Ops (0x2Cxx)
*
* This assumes that all commands will be sent to the radio using
* rf_core_send_cmd()
*/
rfc_radioOp_t *rf_core_get_last_radio_op(void);
/**
* \brief Prepare a buffer to host a Radio Op
* \param buf A pointer to the buffer that will host the Radio Op
* \param len The buffer's length
* \param command The command ID
*
* The caller is responsible to allocate the buffer
*
* This function will not check whether the buffer is large enough to hold the
* command. This is the caller's responsibility
*
* This function will wipe out the buffer's contents.
*/
void rf_core_init_radio_op(rfc_radioOp_t *buf, uint16_t len, uint16_t command);
/**
* \brief Register a primary mode for radio operation
* \param mode A pointer to the struct representing the mode
*
* A normal NESTACK_RADIO driver will normally register itself by calling
* this function during its own init().
*
* \sa rf_core_primary_mode_t
*/
void rf_core_primary_mode_register(const rf_core_primary_mode_t *mode);
/**
* \brief Abort the currently running primary radio op
*/
void rf_core_primary_mode_abort(void);
/**
* \brief Abort the currently running primary radio op
*/
uint8_t rf_core_primary_mode_restore(void);
/*---------------------------------------------------------------------------*/
#endif /* RF_CORE_H_ */
/*---------------------------------------------------------------------------*/
/**
* @}
* @}
*/