Working prop-mode
This commit is contained in:
parent
f9fcbd6a77
commit
f6b016c5d4
@ -56,12 +56,10 @@
|
||||
#define CC2650_FAST_RADIO_STARTUP (MAC_CONF_WITH_TSCH)
|
||||
#endif
|
||||
|
||||
#ifdef RF_CHANNEL
|
||||
#define RF_CORE_CONF_CHANNEL RF_CHANNEL
|
||||
#endif
|
||||
|
||||
#ifndef RF_CORE_CONF_CHANNEL
|
||||
#define RF_CORE_CONF_CHANNEL 25
|
||||
#ifdef RF_CORE_CONF_CHANNEL
|
||||
#define RF_CHANNEL RF_CORE_CONF_CHANNEL
|
||||
#else
|
||||
#define RF_CHANNEL 25
|
||||
#endif
|
||||
|
||||
/* Number of Prop Mode RX buffers */
|
||||
@ -70,11 +68,13 @@
|
||||
#endif
|
||||
|
||||
/* Configure Radio mode, i.e. prop or ieee */
|
||||
|
||||
|
||||
/*----- CC13xx Device Line --------------------------------------------------*/
|
||||
/* CC13xx supports both IEEE and Prop mode, depending on which device */
|
||||
/* CC26xx only supports IEEE mode */
|
||||
#if defined(DEVICE_LINE_CC13XX)
|
||||
|
||||
/* Default mode should be prop for prop-only devices (CC1310, CC1312);
|
||||
/* Default mode should be prop for prop-only devices (CC1310, CC1312R);
|
||||
* Else, IEEE mode is default. */
|
||||
# ifndef CC13XX_CONF_PROP_MODE
|
||||
# if (SUPPORTS_IEEE_MODE == 0)
|
||||
@ -84,14 +84,12 @@
|
||||
# endif
|
||||
# endif
|
||||
|
||||
|
||||
# if (CC13XX_CONF_PROP_MODE == 1) && (SUPPORTS_PROP_MODE == 1)
|
||||
/*----- CC13xx Prop Mode ----------------------------------------------------*/
|
||||
# define NETSTACK_CONF_RADIO prop_mode_driver
|
||||
|
||||
# define CSMA_CONF_ACK_WAIT_TIME (RTIMER_SECOND / 400)
|
||||
# define CSMA_CONF_AFTER_ACK_DETECTED_WAIT_TIME \
|
||||
(RTIMER_SECOND / 1000)
|
||||
# define CSMA_CONF_ACK_WAIT_TIME (RTIMER_SECOND / 300)
|
||||
# define CSMA_CONF_AFTER_ACK_DETECTED_WAIT_TIME (RTIMER_SECOND / 1000)
|
||||
# define CSMA_CONF_SEND_SOFT_ACK 1
|
||||
|
||||
# elif (CC13XX_CONF_PROP_MODE == 0) && (SUPPORTS_IEEE_MODE == 1)
|
||||
@ -101,9 +99,12 @@
|
||||
# define CSMA_CONF_SEND_SOFT_ACK 0
|
||||
|
||||
# else
|
||||
/*----- CC13xx Non-supported Mode -------------------------------------------*/
|
||||
# error "Invalid radio mode configuration of CC13xx device"
|
||||
# endif /* (CC13XX_CONF_PROP_MODE == 1) && (SUPPORTS_PROP_MODE == 1) */
|
||||
|
||||
/*----- CC26xx Device Line --------------------------------------------------*/
|
||||
/* CC26xx only supports IEEE mode */
|
||||
#elif defined(DEVICE_LINE_CC26XX)
|
||||
|
||||
# if (SUPPORTS_IEEE_MODE == 1)
|
||||
@ -113,9 +114,11 @@
|
||||
# define CSMA_CONF_SEND_SOFT_ACK 0
|
||||
|
||||
# else
|
||||
/*----- CC26xx Non-supported Mode -------------------------------------------*/
|
||||
# error "IEEE mode only supported by CC26xx devices"
|
||||
# endif /* (SUPPORTS_IEEE_MODE == 1) */
|
||||
|
||||
/*----- Unsupported device line ---------------------------------------------*/
|
||||
#else
|
||||
# error "Unsupported Device Line defined"
|
||||
#endif /* defined(DEVICE_LINE_CC13xx) */
|
||||
|
@ -39,25 +39,18 @@
|
||||
#include <contiki.h>
|
||||
#include <dev/watchdog.h>
|
||||
#include <sys/process.h>
|
||||
#include <sys/energest.h>
|
||||
#include <net/netstack.h>
|
||||
#include <net/packetbuf.h>
|
||||
#include <net/mac/mac.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Log configuration */
|
||||
#include "sys/log.h"
|
||||
#define LOG_MODULE "RF"
|
||||
#define LOG_LEVEL LOG_LEVEL_DBG
|
||||
/*---------------------------------------------------------------------------*/
|
||||
PROCESS(RF_coreProcess, "SimpleLink RF process");
|
||||
PROCESS(rf_process, "SimpleLink RF Process");
|
||||
/*---------------------------------------------------------------------------*/
|
||||
PROCESS_THREAD(RF_coreProcess, ev, data)
|
||||
PROCESS_THREAD(rf_process, ev, data)
|
||||
{
|
||||
int len;
|
||||
|
||||
|
@ -43,34 +43,12 @@
|
||||
#ifndef RF_COMMON_H_
|
||||
#define RF_COMMON_H_
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Contiki API */
|
||||
#include <sys/rtimer.h>
|
||||
#include <dev/radio.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Standard library */
|
||||
#include <stdint.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#ifdef RF_CORE_CONF_CHANNEL
|
||||
# define RF_CORE_CHANNEL RF_CORE_CONF_CHANNEL
|
||||
#else
|
||||
# define RF_CORE_CHANNEL 25
|
||||
#endif
|
||||
/*---------------------------------------------------------------------------*/
|
||||
typedef enum {
|
||||
CMD_RESULT_ERROR = 0,
|
||||
CMD_RESULT_OK = 1,
|
||||
} CmdResult;
|
||||
} cmd_result_t;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
typedef struct {
|
||||
radio_value_t dbm;
|
||||
uint16_t power; ///< Value for the .txPower field
|
||||
} RF_TxPower;
|
||||
|
||||
#define TX_POWER_UNKNOWN 0xFFFF
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define RSSI_UNKNOWN -128
|
||||
/*---------------------------------------------------------------------------*/
|
||||
PROCESS_NAME(RF_coreProcess);
|
||||
PROCESS_NAME(rf_process);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#endif /* RF_COMMON_H_ */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -121,7 +121,7 @@
|
||||
#ifdef IEEE_MODE_CONF_CHANNEL
|
||||
# define IEEE_MODE_CHANNEL IEEE_MODE_CONF_CHANNEL
|
||||
#else
|
||||
# define IEEE_MODE_CHANNEL RF_CORE_CHANNEL
|
||||
# define IEEE_MODE_CHANNEL RF_CHANNEL
|
||||
#endif
|
||||
|
||||
/* Configuration for TX power table */
|
||||
@ -301,10 +301,7 @@ static void
|
||||
rx_cb(RF_Handle h, RF_CmdHandle ch, RF_EventMask e)
|
||||
{
|
||||
if (e & RF_EventRxOk) {
|
||||
process_poll(&RF_coreProcess);
|
||||
}
|
||||
if (e & RF_EventRxBufFull) {
|
||||
|
||||
process_poll(&rf_process);
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
@ -343,7 +340,7 @@ init_data_queue(void)
|
||||
static void
|
||||
init_rf_params(void)
|
||||
{
|
||||
cmd_rx.channel = RF_CORE_CHANNEL;
|
||||
cmd_rx.channel = IEEE_MODE_CHANNEL;
|
||||
|
||||
cmd_rx.pRxQ = &g_rxDataQueue;
|
||||
cmd_rx.pOutput = &g_rxStats;
|
||||
@ -555,7 +552,7 @@ init(void)
|
||||
ctimer_set(&g_ratOverflowTimer, RAT_OVERFLOW_PERIOD_SECONDS * CLOCK_SECOND / 2,
|
||||
rat_overflow_cb, NULL);
|
||||
|
||||
process_start(&RF_coreProcess, NULL);
|
||||
process_start(&rf_process, NULL);
|
||||
|
||||
return CMD_RESULT_OK;
|
||||
}
|
||||
@ -812,23 +809,25 @@ pending_packet(void)
|
||||
const rfc_dataEntry_t *const pStartEntry = (rfc_dataEntry_t *)g_rxDataQueue.pCurrEntry;
|
||||
volatile const rfc_dataEntry_t *pCurrEntry = pStartEntry;
|
||||
|
||||
int rv = 0;
|
||||
|
||||
// Check all RX buffers and check their statuses, stopping when looping the circular buffer
|
||||
int bIsPending = 0;
|
||||
do {
|
||||
const uint8_t status = pCurrEntry->status;
|
||||
if ((status == DATA_ENTRY_FINISHED) ||
|
||||
(status == DATA_ENTRY_BUSY)) {
|
||||
bIsPending = 1;
|
||||
if (!g_bPollMode) {
|
||||
process_poll(&RF_coreProcess);
|
||||
}
|
||||
rv += 1;
|
||||
}
|
||||
|
||||
pCurrEntry = (rfc_dataEntry_t *)pCurrEntry->pNextEntry;
|
||||
} while (pCurrEntry != pStartEntry);
|
||||
|
||||
if ((rv > 0) && !g_bPollMode) {
|
||||
process_poll(&rf_process);
|
||||
}
|
||||
|
||||
// If we didn't find an entry at status finished or busy, no frames are pending
|
||||
return bIsPending;
|
||||
return rv;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
@ -909,7 +908,7 @@ get_value(radio_param_t param, radio_value_t *value)
|
||||
|
||||
case RADIO_PARAM_TXPOWER:
|
||||
*value = get_tx_power();
|
||||
return (*value == TX_POWER_UNKNOWN)
|
||||
return (*value == RF_TxPowerTable_INVALID_DBM)
|
||||
? RADIO_RESULT_ERROR
|
||||
: RADIO_RESULT_OK;
|
||||
|
||||
|
@ -80,6 +80,13 @@
|
||||
# define PRINTF(...) printf(__VA_ARGS__)
|
||||
#endif
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Configuration for default Prop channel */
|
||||
#ifdef PROP_MODE_CONF_CHANNEL
|
||||
# define PROP_MODE_CHANNEL PROP_MODE_CONF_CHANNEL
|
||||
#else
|
||||
# define PROP_MODE_CHANNEL RF_CHANNEL
|
||||
#endif
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Data whitener. 1: Whitener, 0: No whitener */
|
||||
#ifdef PROP_MODE_CONF_DW
|
||||
# define PROP_MODE_DW PROP_MODE_CONF_DW
|
||||
@ -93,19 +100,6 @@
|
||||
# define PROP_MODE_USE_CRC16 0
|
||||
#endif
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief Returns the current status of a running Radio Op command
|
||||
* \param a A pointer with the buffer used to initiate the command
|
||||
* \return The value of the Radio Op buffer's status field
|
||||
*
|
||||
* This macro can be used to e.g. return the status of a previously
|
||||
* initiated background operation, or of an immediate command
|
||||
*/
|
||||
#define RF_RADIO_OP_GET_STATUS(a) GET_FIELD_V(a, radioOp, status)
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Special value returned by CMD_IEEE_CCA_REQ when an RSSI is not available */
|
||||
#define RF_CMD_CCA_REQ_RSSI_UNKNOWN -128
|
||||
|
||||
/* Used for the return value of channel_clear */
|
||||
#define RF_CCA_CLEAR 1
|
||||
#define RF_CCA_BUSY 0
|
||||
@ -122,17 +116,10 @@
|
||||
#define RF_CMD_CCA_REQ_CCA_STATE_INVALID 2 /* 10 */
|
||||
|
||||
#ifdef PROP_MODE_CONF_RSSI_THRESHOLD
|
||||
#define PROP_MODE_RSSI_THRESHOLD PROP_MODE_CONF_RSSI_THRESHOLD
|
||||
# define PROP_MODE_RSSI_THRESHOLD PROP_MODE_CONF_RSSI_THRESHOLD
|
||||
#else
|
||||
#define PROP_MODE_RSSI_THRESHOLD 0xA6
|
||||
# define PROP_MODE_RSSI_THRESHOLD 0xA6
|
||||
#endif
|
||||
|
||||
static int8_t rssi_threshold = PROP_MODE_RSSI_THRESHOLD;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int rf_switch_on(void);
|
||||
static int rf_switch_off(void);
|
||||
|
||||
static rfc_propRxOutput_t rx_stats;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Defines and variables related to the .15.4g PHY HDR */
|
||||
#define DOT_4G_MAX_FRAME_LEN 2047
|
||||
@ -144,23 +131,20 @@ static rfc_propRxOutput_t rx_stats;
|
||||
|
||||
#if PROP_MODE_USE_CRC16
|
||||
/* CRC16 */
|
||||
#define DOT_4G_PHR_CRC_BIT DOT_4G_PHR_CRC16
|
||||
#define CRC_LEN 2
|
||||
# define DOT_4G_PHR_CRC_BIT DOT_4G_PHR_CRC16
|
||||
# define CRC_LEN 2
|
||||
#else
|
||||
/* CRC32 */
|
||||
#define DOT_4G_PHR_CRC_BIT 0
|
||||
#define CRC_LEN 4
|
||||
#endif
|
||||
# define DOT_4G_PHR_CRC_BIT 0
|
||||
# define CRC_LEN 4
|
||||
#endif /* PROP_MODE_USE_CRC16 */
|
||||
|
||||
#if PROP_MODE_DW
|
||||
#define DOT_4G_PHR_DW_BIT DOT_4G_PHR_DW
|
||||
# define DOT_4G_PHR_DW_BIT DOT_4G_PHR_DW
|
||||
#else
|
||||
#define DOT_4G_PHR_DW_BIT 0
|
||||
#define DOT_4G_PHR_DW_BIT 0
|
||||
#endif
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* How long to wait for an ongoing ACK TX to finish before starting frame TX */
|
||||
#define TX_WAIT_TIMEOUT (RTIMER_SECOND >> 11)
|
||||
|
||||
/* How long to wait for the RF to enter RX in rf_cmd_ieee_rx */
|
||||
#define ENTER_RX_WAIT_TIMEOUT (RTIMER_SECOND >> 10)
|
||||
/*---------------------------------------------------------------------------*/
|
||||
@ -179,106 +163,118 @@ static rfc_propRxOutput_t rx_stats;
|
||||
|
||||
#define TX_POWER_IN_RANGE(dbm) (((dbm) >= TX_POWER_MIN) && ((dbm) <= TX_POWER_MAX))
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* TX buf configuration */
|
||||
#define TX_BUF_HDR_LEN 2
|
||||
#define TX_BUF_PAYLOAD_LEN 180
|
||||
|
||||
#define TX_BUF_SIZE (TX_BUF_HDR_LEN + TX_BUF_PAYLOAD_LEN)
|
||||
|
||||
/* RX buf configuration */
|
||||
#ifdef PROP_MODE_CONF_RX_BUF_CNT
|
||||
#define PROP_MODE_RX_BUF_CNT PROP_MODE_CONF_RX_BUF_CNT
|
||||
# define RX_BUF_CNT PROP_MODE_CONF_RX_BUF_CNT
|
||||
#else
|
||||
#define PROP_MODE_RX_BUF_CNT 4
|
||||
# define RX_BUF_CNT 4
|
||||
#endif
|
||||
|
||||
#define RX_BUF_SIZE 140
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define DATA_ENTRY_LENSZ_NONE 0
|
||||
#define DATA_ENTRY_LENSZ_BYTE 1
|
||||
#define DATA_ENTRY_LENSZ_WORD 2 /* 2 bytes */
|
||||
|
||||
/*
|
||||
* RX buffers.
|
||||
* PROP_MODE_RX_BUF_CNT buffers of RX_BUF_SIZE bytes each. The start of each
|
||||
* buffer must be 4-byte aligned, therefore RX_BUF_SIZE must divide by 4
|
||||
*/
|
||||
#define RX_BUF_SIZE 140
|
||||
static uint8_t rx_buf[PROP_MODE_RX_BUF_CNT][RX_BUF_SIZE] CC_ALIGN(4);
|
||||
|
||||
/* The RX Data Queue */
|
||||
static dataQueue_t rx_data_queue = { 0 };
|
||||
|
||||
/* Receive entry pointer to keep track of read items */
|
||||
volatile static uint8_t *rx_read_entry;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* The outgoing frame buffer */
|
||||
#define TX_BUF_PAYLOAD_LEN 180
|
||||
#define TX_BUF_HDR_LEN 2
|
||||
#define MAC_RADIO_RECEIVER_SENSITIVITY_DBM -110
|
||||
#define MAC_RADIO_RECEIVER_SATURATION_DBM 10
|
||||
#define MAC_SPEC_ED_MIN_DBM_ABOVE_RECEIVER_SENSITIVITY 10
|
||||
#define MAC_SPEC_ED_MAX 0xFF
|
||||
|
||||
static uint8_t tx_buf[TX_BUF_HDR_LEN + TX_BUF_PAYLOAD_LEN] CC_ALIGN(4);
|
||||
#define ED_RF_POWER_MIN_DBM (MAC_RADIO_RECEIVER_SENSITIVITY_DBM + MAC_SPEC_ED_MIN_DBM_ABOVE_RECEIVER_SENSITIVITY)
|
||||
#define ED_RF_POWER_MAX_DBM MAC_RADIO_RECEIVER_SATURATION_DBM
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define cmd_radio_setup ((volatile rfc_CMD_PROP_RADIO_DIV_SETUP_t *)&rf_cmd_prop_radio_div_setup)
|
||||
#define cmd_fs ((volatile rfc_CMD_FS_t *) &rf_cmd_prop_fs)
|
||||
#define cmd_tx ((volatile rfc_CMD_PROP_TX_ADV_t *) &rf_cmd_prop_tx_adv)
|
||||
#define cmd_rx ((volatile rfc_CMD_PROP_RX_ADV_t *) &rf_cmd_prop_rx_adv)
|
||||
typedef struct {
|
||||
/* Outgoing frame buffer */
|
||||
uint8_t tx_buf[TX_BUF_SIZE] CC_ALIGN(4);
|
||||
/* Incoming frame buffer */
|
||||
uint8_t rx_buf[RX_BUF_CNT][RX_BUF_SIZE] CC_ALIGN(4);
|
||||
|
||||
/* RX Data Queue */
|
||||
dataQueue_t rx_data_queue;
|
||||
/* RX Statistics struct */
|
||||
rfc_propRxOutput_t rx_stats;
|
||||
/* Receive entry pointer to keep track of read items */
|
||||
volatile uint8_t* rx_read_entry;
|
||||
|
||||
/* RSSI Threshold */
|
||||
int8_t rssi_threshold;
|
||||
|
||||
/* Indicates RF is supposed to be on or off */
|
||||
uint8_t rf_is_on;
|
||||
|
||||
/* RF driver */
|
||||
RF_Object rf_object;
|
||||
RF_Handle rf_handle;
|
||||
} prop_radio_t;
|
||||
|
||||
static prop_radio_t prop_radio;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* RF driver */
|
||||
static RF_Object rfObject;
|
||||
static RF_Handle rfHandle;
|
||||
#define cmd_radio_setup (*(volatile rfc_CMD_PROP_RADIO_DIV_SETUP_t *)&rf_cmd_prop_radio_div_setup)
|
||||
#define cmd_fs (*(volatile rfc_CMD_FS_t *) &rf_cmd_prop_fs)
|
||||
#define cmd_tx (*(volatile rfc_CMD_PROP_TX_ADV_t *) &rf_cmd_prop_tx_adv)
|
||||
#define cmd_rx (*(volatile rfc_CMD_PROP_RX_ADV_t *) &rf_cmd_prop_rx_adv)
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static CC_INLINE bool rf_is_transmitting(void) { return cmd_tx->status == ACTIVE; }
|
||||
static CC_INLINE bool rf_is_receiving(void) { return cmd_rx->status == ACTIVE; }
|
||||
static CC_INLINE bool rf_is_on(void) { return rf_is_transmitting() || rf_is_receiving(); }
|
||||
static CC_INLINE bool tx_active(void) { return cmd_tx.status == ACTIVE; }
|
||||
static CC_INLINE bool rx_active(void) { return cmd_rx.status == ACTIVE; }
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int on(void);
|
||||
static int off(void);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
rf_rx_callback(RF_Handle client, RF_CmdHandle command, RF_EventMask events)
|
||||
cmd_rx_cb(RF_Handle client, RF_CmdHandle command, RF_EventMask events)
|
||||
{
|
||||
/* Unused arguments */
|
||||
(void)client;
|
||||
(void)command;
|
||||
|
||||
if (events & RF_EventRxEntryDone) {
|
||||
process_poll(&RF_coreProcess);
|
||||
process_poll(&rf_process);
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static CmdResult
|
||||
rf_start_rx()
|
||||
static cmd_result_t
|
||||
start_rx(void)
|
||||
{
|
||||
cmd_rx->status = IDLE;
|
||||
|
||||
/*
|
||||
* Set the max Packet length. This is for the payload only, therefore
|
||||
* 2047 - length offset
|
||||
*/
|
||||
cmd_rx->maxPktLen = DOT_4G_MAX_FRAME_LEN - cmd_rx->lenOffset;
|
||||
|
||||
RF_CmdHandle rxCmdHandle = RF_postCmd(rfHandle, (RF_Op*)cmd_rx, RF_PriorityNormal,
|
||||
&rf_rx_callback, RF_EventRxEntryDone);
|
||||
if (rxCmdHandle == RF_ALLOC_ERROR) {
|
||||
cmd_rx.status = IDLE;
|
||||
RF_CmdHandle rx_handle = RF_postCmd(prop_radio.rf_handle, (RF_Op*)&cmd_rx, RF_PriorityNormal,
|
||||
&cmd_rx_cb, RF_EventRxEntryDone);
|
||||
if (rx_handle == RF_ALLOC_ERROR) {
|
||||
PRINTF("start_rx: RF_ALLOC_ERROR for cmd_rx\n");
|
||||
return CMD_RESULT_ERROR;
|
||||
}
|
||||
|
||||
/* Wait to enter RX */
|
||||
const rtimer_clock_t t0 = RTIMER_NOW();
|
||||
while (!rf_is_receiving() &&
|
||||
while (!rx_active() &&
|
||||
(RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + ENTER_RX_WAIT_TIMEOUT)));
|
||||
|
||||
if (!rf_is_receiving()) {
|
||||
PRINTF("RF_cmdPropRxAdv: handle=0x%08lx, status=0x%04x\n",
|
||||
(unsigned long)rxCmdHandle, cmd_rx->status);
|
||||
rf_switch_off();
|
||||
if (!rx_active()) {
|
||||
PRINTF("cmd_rx: status=0x%04x\n", cmd_rx.status);
|
||||
return CMD_RESULT_ERROR;
|
||||
}
|
||||
|
||||
return CMD_RESULT_OK;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static CmdResult
|
||||
rf_stop_rx(void)
|
||||
static cmd_result_t
|
||||
stop_rx(void)
|
||||
{
|
||||
/* If we are off, do nothing */
|
||||
if (!rf_is_receiving()) {
|
||||
return CMD_RESULT_OK;
|
||||
}
|
||||
|
||||
/* Abort any ongoing operation. Don't care about the result. */
|
||||
RF_cancelCmd(rfHandle, RF_CMDHANDLE_FLUSH_ALL, 1);
|
||||
RF_cancelCmd(prop_radio.rf_handle, RF_CMDHANDLE_FLUSH_ALL, 1);
|
||||
|
||||
/* Todo: maybe do a RF_pendCmd() to synchronize with command execution. */
|
||||
|
||||
if(cmd_rx->status != PROP_DONE_STOPPED &&
|
||||
cmd_rx->status != PROP_DONE_ABORT) {
|
||||
if(cmd_rx.status != PROP_DONE_STOPPED &&
|
||||
cmd_rx.status != PROP_DONE_ABORT) {
|
||||
PRINTF("RF_cmdPropRxAdv cancel: status=0x%04x\n",
|
||||
cmd_rx->status);
|
||||
cmd_rx.status);
|
||||
return CMD_RESULT_ERROR;
|
||||
}
|
||||
|
||||
@ -287,11 +283,11 @@ rf_stop_rx(void)
|
||||
return CMD_RESULT_OK;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static CmdResult
|
||||
static cmd_result_t
|
||||
rf_run_setup()
|
||||
{
|
||||
RF_runCmd(rfHandle, (RF_Op*)cmd_radio_setup, RF_PriorityNormal, NULL, 0);
|
||||
if (cmd_radio_setup->status != PROP_DONE_OK) {
|
||||
RF_runCmd(prop_radio.rf_handle, (RF_Op*)&cmd_radio_setup, RF_PriorityNormal, NULL, 0);
|
||||
if (cmd_radio_setup.status != PROP_DONE_OK) {
|
||||
return CMD_RESULT_ERROR;
|
||||
}
|
||||
|
||||
@ -301,24 +297,24 @@ rf_run_setup()
|
||||
static radio_value_t
|
||||
get_rssi(void)
|
||||
{
|
||||
if (rf_is_transmitting()) {
|
||||
if (tx_active()) {
|
||||
PRINTF("get_rssi: called while in TX\n");
|
||||
return RF_GET_RSSI_ERROR_VAL;
|
||||
}
|
||||
|
||||
const bool was_off = !rf_is_receiving();
|
||||
if (was_off && rf_start_rx() == CMD_RESULT_ERROR) {
|
||||
const bool was_off = !rx_active();
|
||||
if (was_off && start_rx() == CMD_RESULT_ERROR) {
|
||||
PRINTF("get_rssi: unable to start RX\n");
|
||||
return RF_GET_RSSI_ERROR_VAL;
|
||||
}
|
||||
|
||||
int8_t rssi = RF_GET_RSSI_ERROR_VAL;
|
||||
while(rssi == RF_GET_RSSI_ERROR_VAL || rssi == 0) {
|
||||
rssi = RF_getRssi(rfHandle);
|
||||
rssi = RF_getRssi(prop_radio.rf_handle);
|
||||
}
|
||||
|
||||
if(was_off) {
|
||||
rf_switch_off();
|
||||
if (was_off) {
|
||||
stop_rx();
|
||||
}
|
||||
|
||||
return rssi;
|
||||
@ -327,9 +323,7 @@ get_rssi(void)
|
||||
static uint8_t
|
||||
get_channel(void)
|
||||
{
|
||||
uint32_t freq_khz;
|
||||
|
||||
freq_khz = cmd_fs->frequency * 1000;
|
||||
uint32_t freq_khz = cmd_fs.frequency * 1000;
|
||||
|
||||
/*
|
||||
* For some channels, fractFreq * 1000 / 65536 will return 324.99xx.
|
||||
@ -337,12 +331,12 @@ get_channel(void)
|
||||
* function returning channel - 1 instead of channel. Thus, we do a quick
|
||||
* positive integer round up.
|
||||
*/
|
||||
freq_khz += (((cmd_fs->fractFreq * 1000) + 65535) / 65536);
|
||||
freq_khz += (((cmd_fs.fractFreq * 1000) + 65535) / 65536);
|
||||
|
||||
return (freq_khz - DOT_15_4G_CHAN0_FREQUENCY) / DOT_15_4G_CHANNEL_SPACING;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
static cmd_result_t
|
||||
set_channel(uint8_t channel)
|
||||
{
|
||||
uint32_t new_freq = DOT_15_4G_CHAN0_FREQUENCY + (channel * DOT_15_4G_CHANNEL_SPACING);
|
||||
@ -353,24 +347,32 @@ set_channel(uint8_t channel)
|
||||
PRINTF("set_channel: %u = 0x%04x.0x%04x (%lu)\n",
|
||||
channel, freq, frac, new_freq);
|
||||
|
||||
cmd_radio_setup->centerFreq = freq;
|
||||
cmd_fs->frequency = freq;
|
||||
cmd_fs->fractFreq = frac;
|
||||
|
||||
// Todo: Need to re-run setup command when deviation from previous frequency
|
||||
// is too large
|
||||
// rf_run_setup();
|
||||
cmd_radio_setup.centerFreq = freq;
|
||||
cmd_fs.frequency = freq;
|
||||
cmd_fs.fractFreq = frac;
|
||||
|
||||
// We don't care whether the FS command is successful because subsequent
|
||||
// TX and RX commands will tell us indirectly.
|
||||
RF_postCmd(rfHandle, (RF_Op*)cmd_fs, RF_PriorityNormal, NULL, 0);
|
||||
RF_EventMask rf_events = RF_runCmd(prop_radio.rf_handle, (RF_Op*)&cmd_fs,
|
||||
RF_PriorityNormal, NULL, 0);
|
||||
if ((rf_events & (RF_EventCmdDone | RF_EventLastCmdDone)) == 0) {
|
||||
PRINTF("set_channel: RF_runCmd failed, events=0x%llx\n", rf_events);
|
||||
return CMD_RESULT_ERROR;
|
||||
}
|
||||
|
||||
if (cmd_fs.status != DONE_OK) {
|
||||
PRINTF("set_channel: cmd_fs failed, status=0x%04x\n", cmd_fs.status);
|
||||
return CMD_RESULT_ERROR;
|
||||
}
|
||||
|
||||
return CMD_RESULT_OK;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Returns the current TX power in dBm */
|
||||
static radio_value_t
|
||||
get_tx_power(void)
|
||||
{
|
||||
const RF_TxPowerTable_Value value = RF_getTxPower(rfHandle);
|
||||
const RF_TxPowerTable_Value value = RF_getTxPower(prop_radio.rf_handle);
|
||||
return (radio_value_t)RF_TxPowerTable_findPowerLevel(TX_POWER_TABLE, value);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
@ -385,29 +387,46 @@ set_tx_power(const radio_value_t power)
|
||||
return RADIO_RESULT_INVALID_VALUE;
|
||||
}
|
||||
const RF_TxPowerTable_Value value = RF_TxPowerTable_findValue(TX_POWER_TABLE, power);
|
||||
RF_Stat stat = RF_setTxPower(rfHandle, value);
|
||||
RF_Stat stat = RF_setTxPower(prop_radio.rf_handle, value);
|
||||
|
||||
return (stat == RF_StatSuccess)
|
||||
? RADIO_RESULT_OK
|
||||
: RADIO_RESULT_ERROR;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static uint8_t
|
||||
calculate_lqi(int8_t rssi)
|
||||
{
|
||||
/* Note : Currently the LQI value is simply the energy detect measurement.
|
||||
* A more accurate value could be derived by using the correlation
|
||||
* value along with the RSSI value. */
|
||||
rssi = CLAMP(rssi, ED_RF_POWER_MIN_DBM, ED_RF_POWER_MAX_DBM);
|
||||
|
||||
/* Create energy detect measurement by normalizing and scaling RF power level.
|
||||
* Note : The division operation below is designed for maximum accuracy and
|
||||
* best granularity. This is done by grouping the math operations to
|
||||
* compute the entire numerator before doing any division. */
|
||||
return (MAC_SPEC_ED_MAX * (rssi - ED_RF_POWER_MIN_DBM)) / (ED_RF_POWER_MAX_DBM - ED_RF_POWER_MIN_DBM);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
init_rx_buffers(void)
|
||||
{
|
||||
rfc_dataEntry_t *entry;
|
||||
int i;
|
||||
|
||||
for(i = 0; i < PROP_MODE_RX_BUF_CNT; i++) {
|
||||
entry = (rfc_dataEntry_t *)rx_buf[i];
|
||||
entry->status = DATA_ENTRY_PENDING;
|
||||
entry->config.type = DATA_ENTRY_TYPE_GEN;
|
||||
entry->config.lenSz = DATA_ENTRY_LENSZ_WORD;
|
||||
entry->length = RX_BUF_SIZE - 8;
|
||||
entry->pNextEntry = rx_buf[i + 1];
|
||||
size_t i = 0;
|
||||
for (i = 0; i < RX_BUF_CNT; i++) {
|
||||
const rfc_dataEntry_t data_entry = {
|
||||
.status = DATA_ENTRY_PENDING,
|
||||
.config.type = DATA_ENTRY_TYPE_GEN,
|
||||
.config.lenSz = DATA_ENTRY_LENSZ_WORD,
|
||||
.length = RX_BUF_SIZE - sizeof(rfc_dataEntry_t), /* TODO is this sizeof sound? */
|
||||
/* Point to fist entry if this is last entry, else point to next entry */
|
||||
.pNextEntry = (i == (RX_BUF_CNT - 1))
|
||||
? prop_radio.rx_buf[0]
|
||||
: prop_radio.rx_buf[i]
|
||||
};
|
||||
/* Write back data entry struct */
|
||||
*(rfc_dataEntry_t *)prop_radio.rx_buf[i] = data_entry;
|
||||
}
|
||||
|
||||
((rfc_dataEntry_t *)rx_buf[PROP_MODE_RX_BUF_CNT - 1])->pNextEntry = rx_buf[0];
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
@ -415,7 +434,7 @@ prepare(const void *payload, unsigned short payload_len)
|
||||
{
|
||||
int len = MIN(payload_len, TX_BUF_PAYLOAD_LEN);
|
||||
|
||||
memcpy(&tx_buf[TX_BUF_HDR_LEN], payload, len);
|
||||
memcpy(prop_radio.tx_buf + TX_BUF_HDR_LEN, payload, len);
|
||||
return 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
@ -425,11 +444,11 @@ transmit(unsigned short transmit_len)
|
||||
int ret;
|
||||
uint8_t was_off = 0;
|
||||
|
||||
if (rf_is_transmitting()) {
|
||||
if (tx_active()) {
|
||||
PRINTF("transmit: not allowed while transmitting\n");
|
||||
return RADIO_TX_ERR;
|
||||
} else if (rf_is_receiving()) {
|
||||
rf_stop_rx();
|
||||
} else if (rx_active()) {
|
||||
stop_rx();
|
||||
} else {
|
||||
was_off = 1;
|
||||
}
|
||||
@ -447,18 +466,18 @@ transmit(unsigned short transmit_len)
|
||||
*/
|
||||
total_length = transmit_len + CRC_LEN;
|
||||
|
||||
tx_buf[0] = total_length & 0xFF;
|
||||
tx_buf[1] = (total_length >> 8) + DOT_4G_PHR_DW_BIT + DOT_4G_PHR_CRC_BIT;
|
||||
prop_radio.tx_buf[0] = total_length & 0xFF;
|
||||
prop_radio.tx_buf[1] = (total_length >> 8) + DOT_4G_PHR_DW_BIT + DOT_4G_PHR_CRC_BIT;
|
||||
|
||||
/*
|
||||
* pktLen: Total number of bytes in the TX buffer, including the header if
|
||||
* one exists, but not including the CRC (which is not present in the buffer)
|
||||
*/
|
||||
cmd_tx->pktLen = transmit_len + DOT_4G_PHR_LEN;
|
||||
cmd_tx->pPkt = tx_buf;
|
||||
cmd_tx.pktLen = transmit_len + DOT_4G_PHR_LEN;
|
||||
cmd_tx.pPkt = prop_radio.tx_buf;
|
||||
|
||||
// TODO: Register callback
|
||||
RF_runCmd(rfHandle, (RF_Op*)cmd_tx, RF_PriorityNormal, NULL, 0);
|
||||
RF_runCmd(prop_radio.rf_handle, (RF_Op*)&cmd_tx, RF_PriorityNormal, NULL, 0);
|
||||
// if (txHandle == RF_ALLOC_ERROR)
|
||||
// {
|
||||
// /* Failure sending the CMD_PROP_TX command */
|
||||
@ -472,27 +491,27 @@ transmit(unsigned short transmit_len)
|
||||
// // watchdog_periodic();
|
||||
//
|
||||
// /* Idle away while the command is running */
|
||||
// RF_pendCmd(rfHandle, txHandle, RF_EventLastCmdDone);
|
||||
// RF_pendCmd(rf_handle, txHandle, RF_EventLastCmdDone);
|
||||
|
||||
if(cmd_tx->status == PROP_DONE_OK) {
|
||||
if(cmd_tx.status == PROP_DONE_OK) {
|
||||
/* Sent OK */
|
||||
ret = RADIO_TX_OK;
|
||||
} else {
|
||||
/* Operation completed, but frame was not sent */
|
||||
PRINTF("transmit: Not Sent OK status=0x%04x\n",
|
||||
cmd_tx->status);
|
||||
cmd_tx.status);
|
||||
ret = RADIO_TX_ERR;
|
||||
}
|
||||
|
||||
ENERGEST_OFF(ENERGEST_TYPE_TRANSMIT);
|
||||
|
||||
/* Workaround. Set status to IDLE */
|
||||
cmd_tx->status = IDLE;
|
||||
cmd_tx.status = IDLE;
|
||||
|
||||
if (was_off) {
|
||||
RF_yield(rfHandle);
|
||||
RF_yield(prop_radio.rf_handle);
|
||||
} else {
|
||||
rf_start_rx();
|
||||
start_rx();
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -506,71 +525,66 @@ send(const void *payload, unsigned short payload_len)
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
read_frame(void *buf, unsigned short buf_len)
|
||||
read(void *buf, unsigned short buf_len)
|
||||
{
|
||||
rfc_dataEntryGeneral_t *entry = (rfc_dataEntryGeneral_t *)rx_read_entry;
|
||||
rfc_dataEntryGeneral_t *entry = (rfc_dataEntryGeneral_t *)prop_radio.rx_read_entry;
|
||||
uint8_t *data_ptr = &entry->data;
|
||||
int len = 0;
|
||||
uint16_t len = 0;
|
||||
|
||||
if(entry->status == DATA_ENTRY_FINISHED) {
|
||||
if (entry->status != DATA_ENTRY_FINISHED) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* First 2 bytes in the data entry are the length.
|
||||
/* First 2 bytes in the data entry are the length.
|
||||
* Our data entry consists of: Payload + RSSI (1 byte) + Status (1 byte)
|
||||
* This length includes all of those.
|
||||
*/
|
||||
len = (*(uint16_t *)data_ptr);
|
||||
* This length includes all of those. */
|
||||
len = *(uint16_t *)data_ptr;
|
||||
data_ptr += 2;
|
||||
len -= 2;
|
||||
|
||||
if(len > 0) {
|
||||
if(len <= buf_len) {
|
||||
const bool len_ok = (0 < len) && (len <= (uint16_t)buf_len);
|
||||
if (len_ok) {
|
||||
memcpy(buf, data_ptr, len);
|
||||
}
|
||||
|
||||
packetbuf_set_attr(PACKETBUF_ATTR_RSSI, (int8_t)data_ptr[len]);
|
||||
packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY, 0x7F);
|
||||
int8_t rssi = (int8_t)data_ptr[len];
|
||||
uint8_t lqi = calculate_lqi(rssi);
|
||||
|
||||
packetbuf_set_attr(PACKETBUF_ATTR_RSSI, (packetbuf_attr_t)rssi);
|
||||
packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY, (packetbuf_attr_t)lqi);
|
||||
}
|
||||
|
||||
/* Move read entry pointer to next entry */
|
||||
rx_read_entry = entry->pNextEntry;
|
||||
prop_radio.rx_read_entry = entry->pNextEntry;
|
||||
entry->status = DATA_ENTRY_PENDING;
|
||||
}
|
||||
|
||||
return len;
|
||||
return (len_ok)
|
||||
? (int)len
|
||||
: 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
channel_clear(void)
|
||||
{
|
||||
uint8_t was_off = 0;
|
||||
int8_t rssi = RF_CMD_CCA_REQ_RSSI_UNKNOWN;
|
||||
|
||||
// /*
|
||||
// * If we are in the middle of a BLE operation, we got called by ContikiMAC
|
||||
// * from within an interrupt context. Indicate a clear channel
|
||||
// */
|
||||
// if(rf_ble_is_active() == RF_BLE_ACTIVE) {
|
||||
// return RF_CCA_CLEAR;
|
||||
// }
|
||||
|
||||
if (rf_is_transmitting()) {
|
||||
if (tx_active()) {
|
||||
PRINTF("channel_clear: called while in TX\n");
|
||||
return RF_CCA_CLEAR;
|
||||
} else if (!rf_is_receiving()) {
|
||||
was_off = 1;
|
||||
rf_start_rx();
|
||||
}
|
||||
|
||||
while(rssi == RF_CMD_CCA_REQ_RSSI_UNKNOWN || rssi == 0) {
|
||||
rssi = RF_getRssi(rfHandle);
|
||||
const bool rx_was_off = !rx_active();
|
||||
if (rx_was_off) {
|
||||
start_rx();
|
||||
}
|
||||
|
||||
if(was_off) {
|
||||
rf_switch_off();
|
||||
int8_t rssi = RF_GET_RSSI_ERROR_VAL;
|
||||
while (rssi == RF_GET_RSSI_ERROR_VAL || rssi == 0) {
|
||||
rssi = RF_getRssi(prop_radio.rf_handle);
|
||||
}
|
||||
|
||||
if(rssi >= rssi_threshold) {
|
||||
if (rx_was_off) {
|
||||
stop_rx();
|
||||
}
|
||||
|
||||
if(rssi >= prop_radio.rssi_threshold) {
|
||||
return RF_CCA_BUSY;
|
||||
}
|
||||
|
||||
@ -580,11 +594,11 @@ channel_clear(void)
|
||||
static int
|
||||
receiving_packet(void)
|
||||
{
|
||||
if(!rf_is_receiving()) {
|
||||
if (!rx_active()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(channel_clear() == RF_CCA_CLEAR) {
|
||||
if (channel_clear() == RF_CCA_CLEAR) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -594,50 +608,76 @@ receiving_packet(void)
|
||||
static int
|
||||
pending_packet(void)
|
||||
{
|
||||
int rv = 0;
|
||||
volatile rfc_dataEntry_t *entry = (rfc_dataEntry_t *)rx_data_queue.pCurrEntry;
|
||||
const rfc_dataEntry_t *const first_entry = (rfc_dataEntry_t *)prop_radio.rx_data_queue.pCurrEntry;
|
||||
volatile const rfc_dataEntry_t *entry = first_entry;
|
||||
|
||||
/* Go through all RX buffers and check their status */
|
||||
int rv = 0;
|
||||
|
||||
/* Go through RX Circular buffer and check their status */
|
||||
do {
|
||||
if(entry->status == DATA_ENTRY_FINISHED) {
|
||||
const uint8_t status = entry->status;
|
||||
if ((status == DATA_ENTRY_FINISHED) ||
|
||||
(status == DATA_ENTRY_BUSY)) {
|
||||
rv += 1;
|
||||
process_poll(&RF_coreProcess);
|
||||
}
|
||||
|
||||
entry = (rfc_dataEntry_t *)entry->pNextEntry;
|
||||
} while(entry != (rfc_dataEntry_t *)rx_data_queue.pCurrEntry);
|
||||
} while (entry != first_entry);
|
||||
|
||||
if (rv > 0) {
|
||||
process_poll(&rf_process);
|
||||
}
|
||||
|
||||
/* If we didn't find an entry at status finished, no frames are pending */
|
||||
return rv;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
rf_switch_on(void)
|
||||
on(void)
|
||||
{
|
||||
if (prop_radio.rf_is_on) {
|
||||
PRINTF("RF on: Radio already in RX\n");
|
||||
return CMD_RESULT_OK;
|
||||
}
|
||||
|
||||
/* Reset all RF command statuses */
|
||||
cmd_radio_setup.status = IDLE;
|
||||
cmd_fs.status = IDLE;
|
||||
cmd_tx.status = IDLE;
|
||||
cmd_rx.status = IDLE;
|
||||
|
||||
init_rx_buffers();
|
||||
return rf_start_rx();
|
||||
|
||||
const int rx_ok = start_rx();
|
||||
if (!rx_ok) {
|
||||
off();
|
||||
return CMD_RESULT_ERROR;
|
||||
}
|
||||
|
||||
prop_radio.rf_is_on = true;
|
||||
return CMD_RESULT_OK;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
rf_switch_off(void)
|
||||
off(void)
|
||||
{
|
||||
// /*
|
||||
// * If we are in the middle of a BLE operation, we got called by ContikiMAC
|
||||
// * from within an interrupt context. Abort, but pretend everything is OK.
|
||||
// */
|
||||
// if(rf_ble_is_active() == RF_BLE_ACTIVE) {
|
||||
// return CMD_RESULT_OK;
|
||||
// }
|
||||
if (!prop_radio.rf_is_on) {
|
||||
return CMD_RESULT_OK;
|
||||
}
|
||||
|
||||
// Force abort of any ongoing RF operation.
|
||||
RF_cancelCmd(rfHandle, RF_CMDHANDLE_FLUSH_ALL, 0);
|
||||
RF_flushCmd(prop_radio.rf_handle, RF_CMDHANDLE_FLUSH_ALL, RF_ABORT_GRACEFULLY);
|
||||
|
||||
// Trigger a manual power-down
|
||||
RF_yield(rfHandle);
|
||||
RF_yield(prop_radio.rf_handle);
|
||||
|
||||
/* We pulled the plug, so we need to restore the status manually */
|
||||
cmd_rx->status = IDLE;
|
||||
cmd_radio_setup.status = IDLE;
|
||||
cmd_fs.status = IDLE;
|
||||
cmd_tx.status = IDLE;
|
||||
cmd_rx.status = IDLE;
|
||||
|
||||
prop_radio.rf_is_on = false;
|
||||
return CMD_RESULT_OK;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
@ -651,7 +691,10 @@ get_value(radio_param_t param, radio_value_t *value)
|
||||
switch (param) {
|
||||
case RADIO_PARAM_POWER_MODE:
|
||||
/* On / off */
|
||||
*value = rf_is_on() ? RADIO_POWER_MODE_ON : RADIO_POWER_MODE_OFF;
|
||||
*value = (prop_radio.rf_is_on)
|
||||
? RADIO_POWER_MODE_ON
|
||||
: RADIO_POWER_MODE_OFF;
|
||||
|
||||
return RADIO_RESULT_OK;
|
||||
|
||||
case RADIO_PARAM_CHANNEL:
|
||||
@ -663,12 +706,12 @@ get_value(radio_param_t param, radio_value_t *value)
|
||||
return RADIO_RESULT_OK;
|
||||
|
||||
case RADIO_PARAM_CCA_THRESHOLD:
|
||||
*value = rssi_threshold;
|
||||
*value = prop_radio.rssi_threshold;
|
||||
return RADIO_RESULT_OK;
|
||||
|
||||
case RADIO_PARAM_RSSI:
|
||||
*value = get_rssi();
|
||||
return (*value == RF_CMD_CCA_REQ_RSSI_UNKNOWN)
|
||||
return (*value == RF_GET_RSSI_ERROR_VAL)
|
||||
? RADIO_RESULT_ERROR
|
||||
: RADIO_RESULT_OK;
|
||||
|
||||
@ -703,7 +746,7 @@ set_value(radio_param_t param, radio_value_t value)
|
||||
return RADIO_RESULT_OK;
|
||||
}
|
||||
if(value == RADIO_POWER_MODE_OFF) {
|
||||
rf_switch_off();
|
||||
off();
|
||||
return RADIO_RESULT_OK;
|
||||
}
|
||||
return RADIO_RESULT_INVALID_VALUE;
|
||||
@ -730,7 +773,7 @@ set_value(radio_param_t param, radio_value_t value)
|
||||
return RADIO_RESULT_OK;
|
||||
|
||||
case RADIO_PARAM_CCA_THRESHOLD:
|
||||
rssi_threshold = (int8_t)value;
|
||||
prop_radio.rssi_threshold = (int8_t)value;
|
||||
return RADIO_RESULT_OK;
|
||||
|
||||
default:
|
||||
@ -738,13 +781,13 @@ set_value(radio_param_t param, radio_value_t value)
|
||||
}
|
||||
|
||||
/* If we reach here we had no errors. Apply new settings */
|
||||
if (rf_is_receiving()) {
|
||||
rf_stop_rx();
|
||||
if (rx_active()) {
|
||||
stop_rx();
|
||||
if (rf_run_setup() != CMD_RESULT_OK) {
|
||||
return RADIO_RESULT_ERROR;
|
||||
}
|
||||
rf_start_rx();
|
||||
} else if (rf_is_transmitting()) {
|
||||
start_rx();
|
||||
} else if (tx_active()) {
|
||||
// Should not happen. TX is always synchronous and blocking.
|
||||
// Todo: maybe remove completely here.
|
||||
PRINTF("set_value: cannot apply new value while transmitting. \n");
|
||||
@ -770,49 +813,63 @@ set_object(radio_param_t param, const void *src, size_t size)
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
rf_init(void)
|
||||
init(void)
|
||||
{
|
||||
RF_Params params;
|
||||
RF_Params_init(¶ms);
|
||||
// Disable automatic power-down just to not interfere with stack timing
|
||||
params.nInactivityTimeout = 0;
|
||||
/* Zero initalize TX and RX buffers */
|
||||
memset(prop_radio.tx_buf, 0x0, sizeof(prop_radio.tx_buf));
|
||||
memset(prop_radio.rx_buf, 0x0, sizeof(prop_radio.rx_buf));
|
||||
|
||||
rfHandle = RF_open(&rfObject, &rf_prop_mode, (RF_RadioSetup*)cmd_radio_setup, ¶ms);
|
||||
assert(rfHandle != NULL);
|
||||
|
||||
/* Initialise RX buffers */
|
||||
memset(rx_buf, 0, sizeof(rx_buf));
|
||||
|
||||
/* Set of RF Core data queue. Circular buffer, no last entry */
|
||||
rx_data_queue.pCurrEntry = rx_buf[0];
|
||||
rx_data_queue.pLastEntry = NULL;
|
||||
/* Circular buffer, no last entry */
|
||||
prop_radio.rx_data_queue.pCurrEntry = prop_radio.rx_buf[0];
|
||||
prop_radio.rx_data_queue.pLastEntry = NULL;
|
||||
|
||||
/* Initialize current read pointer to first element (used in ISR) */
|
||||
rx_read_entry = rx_buf[0];
|
||||
prop_radio.rx_read_entry = prop_radio.rx_buf[0];
|
||||
|
||||
cmd_rx->pQueue = &rx_data_queue;
|
||||
cmd_rx->pOutput = (uint8_t *)&rx_stats;
|
||||
/* Set configured RSSI threshold */
|
||||
prop_radio.rssi_threshold = PROP_MODE_RSSI_THRESHOLD;
|
||||
|
||||
set_channel(RF_CORE_CHANNEL);
|
||||
/* RX is off */
|
||||
prop_radio.rf_is_on = false;
|
||||
|
||||
/* Configure RX command */
|
||||
cmd_rx.maxPktLen = DOT_4G_MAX_FRAME_LEN - cmd_rx.lenOffset;
|
||||
cmd_rx.pQueue = &prop_radio.rx_data_queue;
|
||||
cmd_rx.pOutput = (uint8_t *)&prop_radio.rx_stats;
|
||||
|
||||
/* Init RF params and specify non-default params */
|
||||
RF_Params rf_params;
|
||||
RF_Params_init(&rf_params);
|
||||
rf_params.nInactivityTimeout = 2000; /* 2 ms */
|
||||
|
||||
/* Open RF Driver */
|
||||
prop_radio.rf_handle = RF_open(&prop_radio.rf_object, &rf_prop_mode,
|
||||
(RF_RadioSetup*)&cmd_radio_setup, &rf_params);
|
||||
if (prop_radio.rf_handle == NULL) {
|
||||
return CMD_RESULT_ERROR;
|
||||
}
|
||||
|
||||
set_channel(PROP_MODE_CHANNEL);
|
||||
|
||||
ENERGEST_ON(ENERGEST_TYPE_LISTEN);
|
||||
|
||||
process_start(&RF_coreProcess, NULL);
|
||||
/* Start RF process */
|
||||
process_start(&rf_process, NULL);
|
||||
|
||||
return CMD_RESULT_OK;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
const struct radio_driver prop_mode_driver = {
|
||||
rf_init,
|
||||
init,
|
||||
prepare,
|
||||
transmit,
|
||||
send,
|
||||
read_frame,
|
||||
read,
|
||||
channel_clear,
|
||||
receiving_packet,
|
||||
pending_packet,
|
||||
rf_switch_on,
|
||||
rf_switch_off,
|
||||
on,
|
||||
off,
|
||||
get_value,
|
||||
set_value,
|
||||
get_object,
|
||||
|
@ -97,7 +97,7 @@ RF_TxPowerTable_Entry rf_prop_tx_power_table[RF_PROP_TX_POWER_TABLE_SIZE+1] =
|
||||
};
|
||||
/*---------------------------------------------------------------------------*/
|
||||
// Overrides for CMD_PROP_RADIO_DIV_SETUP
|
||||
uint32_t p_prop_overrides[] CC_ALIGN(4) =
|
||||
uint32_t rf_prop_overrides[] CC_ALIGN(4) =
|
||||
{
|
||||
// override_use_patch_prop_genfsk.xml
|
||||
MCE_RFE_OVERRIDE(0,4,0,1,0,0), // PHY: Use MCE ROM bank 4, RFE RAM patch
|
||||
@ -137,15 +137,15 @@ uint32_t p_prop_overrides[] CC_ALIGN(4) =
|
||||
// Proprietary Mode Radio Setup Command for All Frequency Bands
|
||||
rfc_CMD_PROP_RADIO_DIV_SETUP_t rf_cmd_prop_radio_div_setup =
|
||||
{
|
||||
.commandNo = 0x3807,
|
||||
.status = 0x0000,
|
||||
.commandNo = CMD_PROP_RADIO_DIV_SETUP,
|
||||
.status = IDLE,
|
||||
.pNextOp = 0,
|
||||
.startTime = 0x00000000,
|
||||
.startTrigger.triggerType = 0x0,
|
||||
.startTrigger.bEnaCmd = 0x0,
|
||||
.startTrigger.triggerNo = 0x0,
|
||||
.startTrigger.pastTrig = 0x0,
|
||||
.condition.rule = 0x1,
|
||||
.condition.rule = COND_NEVER,
|
||||
.condition.nSkip = 0x0,
|
||||
.modulation.modType = 0x1,
|
||||
.modulation.deviation = 0x64,
|
||||
@ -164,7 +164,7 @@ rfc_CMD_PROP_RADIO_DIV_SETUP_t rf_cmd_prop_radio_div_setup =
|
||||
.config.analogCfgMode = 0x0,
|
||||
.config.bNoFsPowerUp = 0x0,
|
||||
.txPower = 0xAB3F,
|
||||
.pRegOverride = pPropOverrides,
|
||||
.pRegOverride = rf_prop_overrides,
|
||||
.centerFreq = 0x0364,
|
||||
.intFreq = 0x8000,
|
||||
.loDivider = 0x05,
|
||||
@ -174,15 +174,15 @@ rfc_CMD_PROP_RADIO_DIV_SETUP_t rf_cmd_prop_radio_div_setup =
|
||||
// Frequency Synthesizer Programming Command
|
||||
rfc_CMD_FS_t rf_cmd_prop_fs =
|
||||
{
|
||||
.commandNo = 0x0803,
|
||||
.status = 0x0000,
|
||||
.commandNo = CMD_FS,
|
||||
.status = IDLE,
|
||||
.pNextOp = 0,
|
||||
.startTime = 0x00000000,
|
||||
.startTrigger.triggerType = 0x0,
|
||||
.startTrigger.bEnaCmd = 0x0,
|
||||
.startTrigger.triggerNo = 0x0,
|
||||
.startTrigger.pastTrig = 0x0,
|
||||
.condition.rule = 0x1,
|
||||
.condition.rule = COND_NEVER,
|
||||
.condition.nSkip = 0x0,
|
||||
.frequency = 0x0364,
|
||||
.fractFreq = 0x0000,
|
||||
@ -199,14 +199,14 @@ rfc_CMD_FS_t rf_cmd_prop_fs =
|
||||
rfc_CMD_PROP_TX_ADV_t rf_cmd_prop_tx_adv =
|
||||
{
|
||||
.commandNo = CMD_PROP_TX_ADV,
|
||||
.status = 0x0000,
|
||||
.status = IDLE,
|
||||
.pNextOp = 0,
|
||||
.startTime = 0x00000000,
|
||||
.startTrigger.triggerType = 0x2,
|
||||
.startTrigger.bEnaCmd = 0x0,
|
||||
.startTrigger.triggerNo = 0x0,
|
||||
.startTrigger.pastTrig = 0x1,
|
||||
.condition.rule = 0x1,
|
||||
.condition.rule = COND_NEVER,
|
||||
.condition.nSkip = 0x0,
|
||||
.pktConf.bFsOff = 0x0,
|
||||
.pktConf.bUseCrc = 0x1,
|
||||
|
@ -52,7 +52,7 @@ extern rfc_CMD_PROP_TX_ADV_t rf_cmd_prop_tx_adv;
|
||||
extern rfc_CMD_PROP_RX_ADV_t rf_cmd_prop_rx_adv;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
// RF Core API Overrides
|
||||
extern uint32_t p_prop_overrides[];
|
||||
extern uint32_t rf_prop_overrides[];
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#endif /* PROP_SETTINGS_H_ */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -109,7 +109,7 @@ uint32_t rf_ieee_overrides[] CC_ALIGN(4) =
|
||||
rfc_CMD_RADIO_SETUP_t rf_cmd_ieee_radio_setup =
|
||||
{
|
||||
.commandNo = CMD_RADIO_SETUP,
|
||||
.status = 0x0000,
|
||||
.status = IDLE,
|
||||
.pNextOp = 0,
|
||||
.startTime = 0x00000000,
|
||||
.startTrigger.triggerType = TRIG_NOW,
|
||||
@ -133,7 +133,7 @@ rfc_CMD_RADIO_SETUP_t rf_cmd_ieee_radio_setup =
|
||||
rfc_CMD_FS_t rf_cmd_ieee_fs =
|
||||
{
|
||||
.commandNo = CMD_FS,
|
||||
.status = 0x0000,
|
||||
.status = IDLE,
|
||||
.pNextOp = 0,
|
||||
.startTime = 0x00000000,
|
||||
.startTrigger.triggerType = TRIG_NOW,
|
||||
@ -142,8 +142,8 @@ rfc_CMD_FS_t rf_cmd_ieee_fs =
|
||||
.startTrigger.pastTrig = 0x0,
|
||||
.condition.rule = COND_NEVER,
|
||||
.condition.nSkip = 0x0,
|
||||
.frequency = 0x0965,
|
||||
.fractFreq = 0x0000,
|
||||
.frequency = 0x0965, /* set by driver */
|
||||
.fractFreq = 0x0000, /* set by driver */
|
||||
.synthConf.bTxMode = 0x1,
|
||||
.synthConf.refFreq = 0x0,
|
||||
.__dummy0 = 0x00,
|
||||
@ -156,8 +156,8 @@ rfc_CMD_FS_t rf_cmd_ieee_fs =
|
||||
// IEEE 802.15.4 Transmit Command
|
||||
rfc_CMD_IEEE_TX_t rf_cmd_ieee_tx =
|
||||
{
|
||||
.commandNo = CMD_IEEE_RX,
|
||||
.status = 0x0000,
|
||||
.commandNo = CMD_IEEE_TX,
|
||||
.status = IDLE,
|
||||
.pNextOp = 0,
|
||||
.startTime = 0x00000000,
|
||||
.startTrigger.triggerType = TRIG_NOW,
|
||||
@ -178,25 +178,25 @@ rfc_CMD_IEEE_TX_t rf_cmd_ieee_tx =
|
||||
// IEEE 802.15.4 Receive Command
|
||||
rfc_CMD_IEEE_RX_t rf_cmd_ieee_rx =
|
||||
{
|
||||
.commandNo = 0x2801,
|
||||
.status = 0x0000,
|
||||
.commandNo = CMD_IEEE_RX,
|
||||
.status = IDLE,
|
||||
.pNextOp = 0,
|
||||
.startTime = 0x00000000,
|
||||
.startTrigger.triggerType = 0x0,
|
||||
.startTrigger.triggerType = TRIG_NOW,
|
||||
.startTrigger.bEnaCmd = 0x0,
|
||||
.startTrigger.triggerNo = 0x0,
|
||||
.startTrigger.pastTrig = 0x0,
|
||||
.condition.rule = 0x1,
|
||||
.condition.rule = COND_NEVER,
|
||||
.condition.nSkip = 0x0,
|
||||
.channel = 0x00,
|
||||
.rxConfig.bAutoFlushCrc = 0x0,
|
||||
.channel = 0x00, /* set by driver */
|
||||
.rxConfig.bAutoFlushCrc = 0x1,
|
||||
.rxConfig.bAutoFlushIgn = 0x0,
|
||||
.rxConfig.bIncludePhyHdr = 0x0,
|
||||
.rxConfig.bIncludeCrc = 0x0,
|
||||
.rxConfig.bIncludeCrc = 0x1,
|
||||
.rxConfig.bAppendRssi = 0x1,
|
||||
.rxConfig.bAppendCorrCrc = 0x1,
|
||||
.rxConfig.bAppendSrcInd = 0x0,
|
||||
.rxConfig.bAppendTimestamp = 0x0,
|
||||
.rxConfig.bAppendTimestamp = 0x1,
|
||||
.pRxQ = 0, /* set by driver */
|
||||
.pOutput = 0, /* set by driver */
|
||||
.frameFiltOpt.frameFiltEn = 0x0, /* set by driver */
|
||||
|
@ -34,8 +34,8 @@
|
||||
#include <ti/devices/DeviceFamily.h>
|
||||
#include DeviceFamily_constructPath(driverlib/rf_mailbox.h)
|
||||
#include DeviceFamily_constructPath(driverlib/rf_common_cmd.h)
|
||||
#include DeviceFamily_constructPath(driverlib/rf_ieee_cmd.h
|
||||
#include DeviceFamily_constructPath(driverlib/rf_ieee_mailbox.h))
|
||||
#include DeviceFamily_constructPath(driverlib/rf_ieee_cmd.h)
|
||||
#include DeviceFamily_constructPath(driverlib/rf_ieee_mailbox.h)
|
||||
|
||||
#include <ti/drivers/rf/RF.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -59,8 +59,8 @@
|
||||
* Override button symbols from dev/button-sensor.h, for the examples that
|
||||
* include it
|
||||
*/
|
||||
#define btn1_sensor button_left_sensor
|
||||
#define btn2_sensor button_right_sensor
|
||||
#define button_left_sensor btn1_sensor
|
||||
#define button_right_sensor btn2_sensor
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Platform-specific define to signify sensor reading failure */
|
||||
|
@ -41,23 +41,24 @@
|
||||
#include <lib/sensors.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#include <Board.h>
|
||||
#include <ti/drivers/GPIO.h>
|
||||
#include <ti/drivers/PIN.h>
|
||||
#include <ti/drivers/Power.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#include "button-sensor.h"
|
||||
#include "button-sensor-arch.h"
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* LaunchPad has 2 buttons: BTN1 and BTN2 */
|
||||
/* Map the GPIO defines from the Board file */
|
||||
#define BTN1_GPIO Board_GPIO_BTN1
|
||||
#define BTN2_GPIO Board_GPIO_BTN2
|
||||
#define BTN1_PIN Board_PIN_BTN1
|
||||
#define BTN2_PIN Board_PIN_BTN2
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#ifdef BUTTON_SENSOR_CONF_ENABLE_SHUTDOWN
|
||||
# define BUTTON_SENSOR_ENABLE_SHUTDOWN BUTTON_SENSOR_CONF_ENABLE_SHUTDOWN
|
||||
#else
|
||||
# define BUTTON_SENSOR_ENABLE_SHUTDOWN 1
|
||||
# define BUTTON_SENSOR_ENABLE_SHUTDOWN 0
|
||||
#endif
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define DEBOUNCE_DURATION (CLOCK_SECOND >> 5)
|
||||
@ -68,56 +69,92 @@ typedef struct {
|
||||
clock_time_t duration;
|
||||
} BtnTimer;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static BtnTimer g_btn1Timer;
|
||||
static BtnTimer g_btn2Timer;
|
||||
static BtnTimer btn1_timer;
|
||||
static BtnTimer btn2_timer;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static const PIN_Config btn_pin_table[] = {
|
||||
BTN1_PIN | PIN_INPUT_EN | PIN_PULLUP | PIN_IRQ_BOTHEDGES | PIN_HYSTERESIS, /* Button is active low */
|
||||
BTN2_PIN | PIN_INPUT_EN | PIN_PULLUP | PIN_IRQ_BOTHEDGES | PIN_HYSTERESIS, /* Button is active low */
|
||||
PIN_TERMINATE
|
||||
};
|
||||
|
||||
static PIN_State pin_state;
|
||||
static PIN_Handle pin_handle;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
button_press_cb(uint8_t index, BtnTimer *btnTimer, const struct sensors_sensor *btnSensor)
|
||||
button_press_cb(PIN_Handle handle, PIN_Id pin_id)
|
||||
{
|
||||
if (!timer_expired(&btnTimer->debounce)) {
|
||||
#ifdef BUTTON_SENSOR_ENABLE_SHUTDOWN
|
||||
if (pin_id == BTN2_PIN) {
|
||||
Power_shutdown(Power_ENTERING_SHUTDOWN, 0);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
BtnTimer *btn_timer = NULL;
|
||||
const struct sensors_sensor *btn_sensor = NULL;
|
||||
|
||||
switch (pin_id) {
|
||||
case BTN1_PIN: btn_timer = &btn1_timer;
|
||||
btn_sensor = &btn1_sensor; break;
|
||||
case BTN2_PIN: btn_timer = &btn2_timer;
|
||||
btn_sensor = &btn2_sensor; break;
|
||||
default: return; /* No matching PIN */
|
||||
}
|
||||
|
||||
if (!timer_expired(&btn_timer->debounce)) {
|
||||
return;
|
||||
}
|
||||
|
||||
timer_set(&btnTimer->debounce, DEBOUNCE_DURATION);
|
||||
timer_set(&btn_timer->debounce, DEBOUNCE_DURATION);
|
||||
|
||||
// Start press duration counter on press (falling), notify on release (rising)
|
||||
if (GPIO_read(index) == 0) {
|
||||
btnTimer->start = clock_time();
|
||||
btnTimer->duration = 0;
|
||||
if (PIN_getInputValue(pin_id) == 0) {
|
||||
btn_timer->start = clock_time();
|
||||
btn_timer->duration = 0;
|
||||
} else {
|
||||
btnTimer->duration = clock_time() - btnTimer->start;
|
||||
sensors_changed(btnSensor);
|
||||
btn_timer->duration = clock_time() - btn_timer->start;
|
||||
sensors_changed(btn_sensor);
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
button_value(int type, uint8_t index, BtnTimer *btnTimer)
|
||||
button_value(int type, uint8_t pin, BtnTimer *btn_timer)
|
||||
{
|
||||
if (type == BUTTON_SENSOR_VALUE_STATE) {
|
||||
return (GPIO_read(index) == 0)
|
||||
return (PIN_getInputValue(pin) == 0)
|
||||
? BUTTON_SENSOR_VALUE_PRESSED
|
||||
: BUTTON_SENSOR_VALUE_RELEASED;
|
||||
} else if (type == BUTTON_SENSOR_VALUE_DURATION) {
|
||||
return (int)btnTimer->duration;
|
||||
return (int)btn_timer->duration;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
button_config(int type, int value, uint8_t index, GPIO_CallbackFxn callback)
|
||||
button_config(int type, int value, uint8_t pin)
|
||||
{
|
||||
switch (type) {
|
||||
case SENSORS_HW_INIT:
|
||||
GPIO_clearInt(index);
|
||||
GPIO_setCallback(index, callback);
|
||||
// Open PIN handle
|
||||
if (pin_handle) {
|
||||
return 1;
|
||||
}
|
||||
pin_handle = PIN_open(&pin_state, btn_pin_table);
|
||||
if (!pin_handle) {
|
||||
return 0;
|
||||
}
|
||||
// Register button callback function
|
||||
PIN_registerIntCb(pin_handle, button_press_cb);
|
||||
break;
|
||||
|
||||
case SENSORS_ACTIVE:
|
||||
if (value) {
|
||||
GPIO_clearInt(index);
|
||||
GPIO_enableInt(index);
|
||||
// Enable interrupts on both edges
|
||||
PIN_setInterrupt(pin_handle, pin | PIN_IRQ_BOTHEDGES);
|
||||
} else {
|
||||
GPIO_disableInt(index);
|
||||
// Disable pin interrupts
|
||||
PIN_setInterrupt(pin_handle, pin | PIN_IRQ_DIS);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -126,70 +163,53 @@ button_config(int type, int value, uint8_t index, GPIO_CallbackFxn callback)
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
button_status(int type, uint8_t index)
|
||||
button_status(int type, uint8_t pin)
|
||||
{
|
||||
switch(type) {
|
||||
case SENSORS_ACTIVE: /* fallthrough */
|
||||
case SENSORS_READY: {
|
||||
GPIO_PinConfig pinCfg = 0;
|
||||
GPIO_getConfig(index, &pinCfg);
|
||||
return (pinCfg & GPIO_CFG_IN_INT_NONE) == 0;
|
||||
PIN_Config pin_cfg = PIN_getConfig(pin);
|
||||
return (pin_cfg & PIN_BM_IRQ) == PIN_IRQ_DIS;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
btn1_press_cb(unsigned char unusued)
|
||||
{
|
||||
button_press_cb(BTN1_GPIO, &g_btn1Timer, &btn1_sensor);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
btn1_value(int type)
|
||||
{
|
||||
return button_value(type, BTN1_GPIO, &g_btn1Timer);
|
||||
return button_value(type, BTN1_PIN, &btn1_timer);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
btn1_config(int type, int value)
|
||||
{
|
||||
return button_config(type, value, BTN1_GPIO, btn1_press_cb);
|
||||
return button_config(type, value, BTN1_PIN);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
btn1_status(int type)
|
||||
{
|
||||
return button_status(type, BTN1_GPIO);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
btn2_press_cb(unsigned char unusued)
|
||||
{
|
||||
if (BUTTON_SENSOR_ENABLE_SHUTDOWN) {
|
||||
Power_shutdown(Power_ENTERING_SHUTDOWN, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
button_press_cb(BTN2_GPIO, &g_btn2Timer, &btn2_sensor);
|
||||
return button_status(type, BTN1_PIN);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
btn2_value(int type)
|
||||
{
|
||||
return button_value(type, BTN2_GPIO, &g_btn2Timer);
|
||||
return button_value(type, BTN2_PIN, &btn2_timer);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
btn2_config(int type, int value)
|
||||
{
|
||||
return button_config(type, value, BTN2_GPIO, btn2_press_cb);
|
||||
return button_config(type, value, BTN2_PIN);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
btn2_status(int type)
|
||||
{
|
||||
return button_status(type, BTN1_GPIO);
|
||||
return button_status(type, BTN2_PIN);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
SENSORS_SENSOR(btn1_sensor, BUTTON_SENSOR, btn1_value, btn1_config, btn1_status);
|
||||
|
@ -43,12 +43,8 @@
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Exports a global symbol to be used by the sensor API */
|
||||
SENSORS(
|
||||
#ifdef BUTTON_SENSOR_ARCH_BTN1
|
||||
&button_sensor,
|
||||
#endif
|
||||
#ifdef BUTTON_SENSOR_ARCH_BTN2
|
||||
&button_sensor2,
|
||||
#endif
|
||||
&btn1_sensor,
|
||||
&btn2_sensor,
|
||||
NULL
|
||||
);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -145,6 +145,10 @@
|
||||
#define ABS(n) (((n) < 0) ? -(n) : (n))
|
||||
#endif
|
||||
|
||||
#ifndef CLAMP
|
||||
#define CLAMP(v, vmin, vmax) (MAX(MIN(v, vmax), vmin))
|
||||
#endif
|
||||
|
||||
|
||||
#define CC_CONCAT2(s1, s2) s1##s2
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user