Add ADuCRF101 radio driver
This commit is contained in:
parent
5673b46e86
commit
b7373edf8c
5 changed files with 369 additions and 6 deletions
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
347
cpu/arm/aducrf101/dev/radio.c
Normal file
347
cpu/arm/aducrf101/dev/radio.c
Normal 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,
|
||||
};
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue