Add ADuCRF101 radio driver

This commit is contained in:
Jim Paris 2014-06-23 16:07:53 -04:00
parent 5673b46e86
commit b7373edf8c
5 changed files with 369 additions and 6 deletions

View File

@ -39,7 +39,7 @@
@date May 08th 2013
**/
#include "include.h"
#include "aducrf101-include.h"
// 1.0 of the Engine
#define RIE_ENGINE_MAJOR_VERSION 1UL

View File

@ -89,6 +89,10 @@ ifdef __STACK_SIZE
CFLAGS += -D__STACK_SIZE=$(__STACK_SIZE)
endif
ifdef RF_CHANNEL
CFLAGS += -DRF_CHANNEL=$(RF_CHANNEL)
endif
# HSI internal oscillator by default
CFLAGS += -DF_CPU=16000000
@ -102,9 +106,11 @@ CONTIKI_CPU_DIRS += dev
CONTIKI_SOURCEFILES += uart.c
CONTIKI_SOURCEFILES += clock.c
CONTIKI_SOURCEFILES += watchdog.c
CONTIKI_SOURCEFILES += radio.c
CONTIKI_CPU_DIRS += Common
CONTIKI_SOURCEFILES += system_ADuCRF101.c
CONTIKI_SOURCEFILES += radioeng.c
ASFLAGS += -c $(CFLAGS)

View File

@ -0,0 +1,347 @@
/**
* Copyright (c) 2014, Analog Devices, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted (subject to the limitations in the
* disclaimer below) provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - 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.
*
* - Neither the name of Analog Devices, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
* GRANTED BY THIS LICENSE. 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 OWNER 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.
*/
/**
* \author Jim Paris <jim.paris@rigado.com>
*/
#include <string.h>
#include <stdint.h>
#include <aducrf101-contiki.h>
#include "radio.h"
#define MAX_PACKET_LEN 240
static uint8_t tx_buf[MAX_PACKET_LEN];
#ifndef ADUCRF101_RADIO_BASE_CONFIG
#define ADUCRF101_RADIO_BASE_CONFIG DR_38_4kbps_Dev20kHz
#endif
static RIE_BaseConfigs base_config = ADUCRF101_RADIO_BASE_CONFIG;
static int current_channel = 915000000;
static int current_power = 31;
static int radio_is_on = 0;
/*---------------------------------------------------------------------------*/
/* "Channel" is really frequency, and can be within the bands:
431000000 Hz to 464000000 Hz
862000000 Hz to 928000000 Hz
*/
#define MIN_CHANNEL 431000000
#define MAX_CHANNEL 928000000
static int
_set_channel(int freq)
{
if(freq < 431000000) {
freq = 431000000;
} else if(freq > 464000000 && freq < 663000000) {
freq = 464000000;
} else if(freq >= 663000000 && freq < 862000000) {
freq = 862000000;
} else if(freq > 928000000) {
freq = 928000000;
}
current_channel = freq;
if(RadioSetFrequency(freq) != RIE_Success) {
return RADIO_RESULT_ERROR;
}
return RADIO_RESULT_OK;
}
/*---------------------------------------------------------------------------*/
/* "Power" covers both PA type and power level:
0 through 15 means single-ended, power level 0 through 15
16 through 31 means differential, power level 0 through 15 */
#define MIN_POWER 0
#define MAX_POWER 31
static int
_set_power(int power)
{
RIE_Responses ret;
if(power < 0) {
power = 0;
}
if(power > 31) {
power = 31;
}
if(power <= 15) {
ret = RadioTxSetPA(SingleEndedPA, power);
} else {
ret = RadioTxSetPA(DifferentialPA, power - 16);
}
current_power = power;
if(ret != RIE_Success) {
return RADIO_RESULT_ERROR;
}
return RADIO_RESULT_OK;
}
/*---------------------------------------------------------------------------*/
/** Turn the radio on. */
static int
on(void)
{
if(radio_is_on) {
return 1;
}
/* Power radio on */
if(RadioInit(base_config) != RIE_Success) {
return 0;
}
/* Ensure channel and power are set */
if(_set_channel(current_channel) != RADIO_RESULT_OK) {
return 0;
}
if(_set_power(current_power) != RADIO_RESULT_OK) {
return 0;
}
/* Enter receive mode */
RadioRxPacketVariableLen();
radio_is_on = 1;
return 1;
}
/*---------------------------------------------------------------------------*/
/** Turn the radio off. */
static int
off(void)
{
if(!radio_is_on) {
return 1;
}
if(RadioPowerOff() != RIE_Success) {
return 0;
}
radio_is_on = 0;
return 1;
}
/*---------------------------------------------------------------------------*/
static int
init(void)
{
off();
on();
return 1;
}
/*---------------------------------------------------------------------------*/
/** Prepare the radio with a packet to be sent. */
static int
prepare(const void *payload, unsigned short payload_len)
{
/* Truncate long packets */
if(payload_len > MAX_PACKET_LEN) {
payload_len = MAX_PACKET_LEN;
}
memcpy(tx_buf, payload, payload_len);
return 0;
}
/*---------------------------------------------------------------------------*/
/** Send the packet that has previously been prepared. */
static int
transmit(unsigned short transmit_len)
{
/* Transmit the packet */
if(transmit_len > MAX_PACKET_LEN) {
transmit_len = MAX_PACKET_LEN;
}
if(RadioTxPacketVariableLen(transmit_len, tx_buf) != RIE_Success) {
return RADIO_TX_ERR;
}
while(!RadioTxPacketComplete())
continue;
/* Enter receive mode immediately after transmitting a packet */
RadioRxPacketVariableLen();
return RADIO_TX_OK;
}
/*---------------------------------------------------------------------------*/
/** Prepare & transmit a packet. */
static int
send(const void *payload, unsigned short payload_len)
{
prepare(payload, payload_len);
return transmit(payload_len);
}
/** Read a received packet into a buffer. */
static int
read(void *buf, unsigned short buf_len)
{
uint8_t packet_len;
if(buf_len > MAX_PACKET_LEN) {
buf_len = MAX_PACKET_LEN;
}
/* Read already-received packet */
if(RadioRxPacketRead(buf_len, &packet_len, buf, NULL) != RIE_Success) {
return 0;
}
if(packet_len > buf_len) {
packet_len = buf_len;
}
/* Re-enter receive mode immediately after receiving a packet */
RadioRxPacketVariableLen();
return packet_len;
}
/*---------------------------------------------------------------------------*/
/** Perform a Clear-Channel Assessment (CCA) to find out if there is
a packet in the air or not. */
static int
channel_clear(void)
{
/* Not implemented; assume clear */
return 1;
}
/*---------------------------------------------------------------------------*/
/** Check if the radio driver is currently receiving a packet */
static int
receiving_packet(void)
{
/* Not implemented; assume no. */
return 0;
}
/*---------------------------------------------------------------------------*/
/** Check if the radio driver has just received a packet */
static int
pending_packet(void)
{
if(RadioRxPacketAvailable()) {
return 1;
}
return 0;
}
/*---------------------------------------------------------------------------*/
/** Get a radio parameter value. */
static radio_result_t
get_value(radio_param_t param, radio_value_t *value)
{
if(!value) {
return RADIO_RESULT_INVALID_VALUE;
}
switch(param) {
case RADIO_PARAM_RSSI:
{
int8_t dbm;
if(RadioRadioGetRSSI(&dbm) != RIE_Success) {
return RADIO_RESULT_ERROR;
}
*value = dbm;
return RADIO_RESULT_OK;
}
case RADIO_PARAM_CHANNEL:
*value = current_channel;
return RADIO_RESULT_OK;
case RADIO_CONST_CHANNEL_MIN:
*value = MIN_CHANNEL;
return RADIO_RESULT_OK;
case RADIO_CONST_CHANNEL_MAX:
*value = MAX_CHANNEL;
return RADIO_RESULT_OK;
case RADIO_PARAM_TXPOWER:
*value = current_power;
return RADIO_RESULT_OK;
case RADIO_CONST_TXPOWER_MIN:
*value = MIN_POWER;
return RADIO_RESULT_OK;
case RADIO_CONST_TXPOWER_MAX:
*value = MAX_POWER;
return RADIO_RESULT_OK;
default:
return RADIO_RESULT_NOT_SUPPORTED;
}
}
/*---------------------------------------------------------------------------*/
/** Set a radio parameter value. */
static radio_result_t
set_value(radio_param_t param, radio_value_t value)
{
switch(param) {
case RADIO_PARAM_CHANNEL:
return _set_channel(value);
case RADIO_PARAM_TXPOWER:
return _set_power(value);
default:
return RADIO_RESULT_NOT_SUPPORTED;
}
}
/*---------------------------------------------------------------------------*/
/**
* Get a radio parameter object. The argument 'dest' must point to a
* memory area of at least 'size' bytes, and this memory area will
* contain the parameter object if the function succeeds.
*/
static radio_result_t
get_object(radio_param_t param, void *dest, size_t size)
{
return RADIO_RESULT_NOT_SUPPORTED;
}
/*---------------------------------------------------------------------------*/
/**
* Set a radio parameter object. The memory area referred to by the
* argument 'src' will not be accessed after the function returns.
*/
static radio_result_t
set_object(radio_param_t param, const void *src, size_t size)
{
return RADIO_RESULT_NOT_SUPPORTED;
}
/*---------------------------------------------------------------------------*/
const struct radio_driver aducrf101_radio_driver = {
.init = init,
.prepare = prepare,
.transmit = transmit,
.send = send,
.read = read,
.channel_clear = channel_clear,
.receiving_packet = receiving_packet,
.pending_packet = pending_packet,
.on = on,
.off = off,
.get_value = get_value,
.set_value = set_value,
.get_object = get_object,
.set_object = set_object,
};

View File

@ -60,7 +60,7 @@
#define NETSTACK_CONF_NETWORK sicslowpan_driver
#define NETSTACK_CONF_MAC nullmac_driver
#define NETSTACK_CONF_RDC nullrdc_driver
#define NETSTACK_CONF_RADIO NEW_ADI_driver
#define NETSTACK_CONF_RADIO aducrf101_radio_driver
#define NETSTACK_CONF_FRAMER framer_802154
#define NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE 8
@ -74,7 +74,7 @@
#define NETSTACK_CONF_NETWORK rime_driver
#define NETSTACK_CONF_MAC csma_driver
#define NETSTACK_CONF_RDC nullrdc_driver
#define NETSTACK_CONF_RADIO NEW_AD_driver
#define NETSTACK_CONF_RADIO aducrf101_radio_driver
#define NETSTACK_CONF_FRAMER framer_802154
#define NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE 8
@ -98,7 +98,7 @@
#define PACKETBUF_CONF_ATTRS_INLINE 1
#ifndef RF_CHANNEL
#define RF_CHANNEL 26
#define RF_CHANNEL 868000000
#endif /* RF_CHANNEL */
#define CONTIKIMAC_CONF_BROADCAST_RATE_LIMIT 0

View File

@ -64,8 +64,8 @@ SENSORS(&button_sensor);
#define SERIAL_ID { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }
#endif
static uint8_t serial_id[] = SERIAL_ID;
static uint16_t node_id = 0x1122;
uint8_t serial_id[] = SERIAL_ID;
uint16_t node_id = 0x0102;
/*---------------------------------------------------------------------------*/
static void
@ -95,6 +95,15 @@ set_rime_addr(void)
printf("%d\n", addr.u8[i]);
}
/*---------------------------------------------------------------------------*/
static void
set_rf_params(void)
{
int chan;
NETSTACK_RADIO.set_value(RADIO_PARAM_CHANNEL, RF_CHANNEL);
NETSTACK_RADIO.get_value(RADIO_PARAM_CHANNEL, &chan);
printf("RF channel set to %d Hz\n", chan);
}
/*---------------------------------------------------------------------------*/
int contiki_argc = 0;
char **contiki_argv;
@ -126,6 +135,7 @@ main(int argc, char **argv)
queuebuf_init();
set_rf_params();
netstack_init();
printf("MAC %s RDC %s NETWORK %s\n",
NETSTACK_MAC.name, NETSTACK_RDC.name, NETSTACK_NETWORK.name);