Add to jn516x micromac driver full MAC layer support
This commit is contained in:
parent
9b6ba3c009
commit
79b06879fe
|
@ -63,6 +63,18 @@
|
||||||
#define DEBUG DEBUG_NONE
|
#define DEBUG DEBUG_NONE
|
||||||
#include "net/ip/uip-debug.h"
|
#include "net/ip/uip-debug.h"
|
||||||
|
|
||||||
|
#ifdef MICROMAC_CONF_RADIO_MAC
|
||||||
|
#define MICROMAC_RADIO_MAC MICROMAC_CONF_RADIO_MAC
|
||||||
|
#else
|
||||||
|
#define MICROMAC_RADIO_MAC 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if MICROMAC_RADIO_MAC
|
||||||
|
#define MICROMAC_FRAME tsMacFrame
|
||||||
|
#else
|
||||||
|
#define MICROMAC_FRAME tsPhyFrame
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Perform CRC check for received packets in SW,
|
/* Perform CRC check for received packets in SW,
|
||||||
* since we use PHY mode which does not calculate CRC in HW */
|
* since we use PHY mode which does not calculate CRC in HW */
|
||||||
#define CRC_SW 1
|
#define CRC_SW 1
|
||||||
|
@ -165,17 +177,17 @@ static volatile uint8_t listen_on = 0;
|
||||||
static uint8_t in_ack_transmission = 0;
|
static uint8_t in_ack_transmission = 0;
|
||||||
|
|
||||||
/* TX frame buffer */
|
/* TX frame buffer */
|
||||||
static tsPhyFrame tx_frame_buffer;
|
static MICROMAC_FRAME tx_frame_buffer;
|
||||||
|
|
||||||
/* RX frame buffer */
|
/* RX frame buffer */
|
||||||
static tsPhyFrame *rx_frame_buffer;
|
static MICROMAC_FRAME *rx_frame_buffer;
|
||||||
|
|
||||||
/* Frame buffer pointer to read from */
|
/* Frame buffer pointer to read from */
|
||||||
static tsPhyFrame *input_frame_buffer = NULL;
|
static MICROMAC_FRAME *input_frame_buffer = NULL;
|
||||||
|
|
||||||
/* Ringbuffer for received packets in interrupt enabled mode */
|
/* Ringbuffer for received packets in interrupt enabled mode */
|
||||||
static struct ringbufindex input_ringbuf;
|
static struct ringbufindex input_ringbuf;
|
||||||
static tsPhyFrame input_array[MIRCOMAC_CONF_BUF_NUM];
|
static MICROMAC_FRAME input_array[MIRCOMAC_CONF_BUF_NUM];
|
||||||
|
|
||||||
/* SFD timestamp in RTIMER ticks */
|
/* SFD timestamp in RTIMER ticks */
|
||||||
static volatile uint32_t last_packet_timestamp = 0;
|
static volatile uint32_t last_packet_timestamp = 0;
|
||||||
|
@ -183,7 +195,9 @@ static volatile uint32_t last_packet_timestamp = 0;
|
||||||
/* Local functions prototypes */
|
/* Local functions prototypes */
|
||||||
static int on(void);
|
static int on(void);
|
||||||
static int off(void);
|
static int off(void);
|
||||||
|
#if !MICROMAC_RADIO_MAC
|
||||||
static int is_packet_for_us(uint8_t *buf, int len, int do_send_ack);
|
static int is_packet_for_us(uint8_t *buf, int len, int do_send_ack);
|
||||||
|
#endif
|
||||||
static void set_frame_filtering(uint8_t enable);
|
static void set_frame_filtering(uint8_t enable);
|
||||||
static rtimer_clock_t get_packet_timestamp(void);
|
static rtimer_clock_t get_packet_timestamp(void);
|
||||||
static void set_txpower(int8_t power);
|
static void set_txpower(int8_t power);
|
||||||
|
@ -305,10 +319,21 @@ on(void)
|
||||||
{
|
{
|
||||||
/* No address matching or frame decoding */
|
/* No address matching or frame decoding */
|
||||||
if(rx_frame_buffer != NULL) {
|
if(rx_frame_buffer != NULL) {
|
||||||
|
#if MICROMAC_RADIO_MAC
|
||||||
|
vMMAC_StartMacReceive(rx_frame_buffer,
|
||||||
|
(uint16_t)(E_MMAC_RX_START_NOW
|
||||||
|
| E_MMAC_RX_USE_AUTO_ACK
|
||||||
|
| E_MMAC_RX_NO_MALFORMED
|
||||||
|
| E_MMAC_RX_NO_FCS_ERROR
|
||||||
|
| E_MMAC_RX_ADDRESS_MATCH
|
||||||
|
| E_MMAC_RX_ALIGN_NORMAL)
|
||||||
|
);
|
||||||
|
#else
|
||||||
vMMAC_StartPhyReceive(rx_frame_buffer,
|
vMMAC_StartPhyReceive(rx_frame_buffer,
|
||||||
(uint16_t)(E_MMAC_RX_START_NOW
|
(uint16_t)(E_MMAC_RX_START_NOW
|
||||||
| E_MMAC_RX_NO_FCS_ERROR) /* means: reject FCS errors */
|
| E_MMAC_RX_NO_FCS_ERROR) /* means: reject FCS errors */
|
||||||
);
|
);
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
missed_radio_on_request = 1;
|
missed_radio_on_request = 1;
|
||||||
}
|
}
|
||||||
|
@ -347,10 +372,16 @@ transmit(unsigned short payload_len)
|
||||||
ENERGEST_ON(ENERGEST_TYPE_TRANSMIT);
|
ENERGEST_ON(ENERGEST_TYPE_TRANSMIT);
|
||||||
|
|
||||||
/* Transmit and wait */
|
/* Transmit and wait */
|
||||||
|
#if MICROMAC_RADIO_MAC
|
||||||
|
vMMAC_StartMacTransmit(&tx_frame_buffer,
|
||||||
|
E_MMAC_TX_START_NOW |
|
||||||
|
E_MMAC_TX_USE_AUTO_ACK |
|
||||||
|
(send_on_cca ? E_MMAC_TX_USE_CCA : E_MMAC_TX_NO_CCA));
|
||||||
|
#else
|
||||||
vMMAC_StartPhyTransmit(&tx_frame_buffer,
|
vMMAC_StartPhyTransmit(&tx_frame_buffer,
|
||||||
E_MMAC_TX_START_NOW |
|
E_MMAC_TX_START_NOW |
|
||||||
(send_on_cca ? E_MMAC_TX_USE_CCA : E_MMAC_TX_NO_CCA));
|
(send_on_cca ? E_MMAC_TX_USE_CCA : E_MMAC_TX_NO_CCA));
|
||||||
|
#endif
|
||||||
if(poll_mode) {
|
if(poll_mode) {
|
||||||
BUSYWAIT_UNTIL(u32MMAC_PollInterruptSource(E_MMAC_INT_TX_COMPLETE), MAX_PACKET_DURATION);
|
BUSYWAIT_UNTIL(u32MMAC_PollInterruptSource(E_MMAC_INT_TX_COMPLETE), MAX_PACKET_DURATION);
|
||||||
} else {
|
} else {
|
||||||
|
@ -394,8 +425,10 @@ transmit(unsigned short payload_len)
|
||||||
static int
|
static int
|
||||||
prepare(const void *payload, unsigned short payload_len)
|
prepare(const void *payload, unsigned short payload_len)
|
||||||
{
|
{
|
||||||
|
#if !MICROMAC_RADIO_MAC
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
uint16_t checksum;
|
uint16_t checksum;
|
||||||
|
#endif
|
||||||
|
|
||||||
RIMESTATS_ADD(lltx);
|
RIMESTATS_ADD(lltx);
|
||||||
|
|
||||||
|
@ -405,6 +438,30 @@ prepare(const void *payload, unsigned short payload_len)
|
||||||
if(payload_len > 127 || payload == NULL) {
|
if(payload_len > 127 || payload == NULL) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
#if MICROMAC_RADIO_MAC
|
||||||
|
frame802154_t info154;
|
||||||
|
int hdr_len = frame802154_parse((unsigned char *)payload, payload_len, &info154);
|
||||||
|
//TODO: hdr_len contains security header, which are not managed by micromac
|
||||||
|
tx_frame_buffer.u8PayloadLength = payload_len - hdr_len;
|
||||||
|
tx_frame_buffer.u8SequenceNum = info154.seq;
|
||||||
|
tx_frame_buffer.u16FCF = ((uint8_t*)payload)[0] | (((uint8_t*)payload)[1] << 8);
|
||||||
|
tx_frame_buffer.u16DestPAN = info154.dest_pid;
|
||||||
|
tx_frame_buffer.u16SrcPAN = info154.src_pid;
|
||||||
|
if(info154.fcf.dest_addr_mode == FRAME802154_SHORTADDRMODE) {
|
||||||
|
tx_frame_buffer.uDestAddr.u16Short = info154.dest_addr[0] | (info154.dest_addr[0] << 8);
|
||||||
|
} else if(info154.fcf.dest_addr_mode == FRAME802154_LONGADDRMODE) {
|
||||||
|
tx_frame_buffer.uDestAddr.sExt.u32L = *(uint32_t*)(&info154.dest_addr[4]);
|
||||||
|
tx_frame_buffer.uDestAddr.sExt.u32H = *(uint32_t*)(&info154.dest_addr[0]);
|
||||||
|
}
|
||||||
|
if(info154.fcf.src_addr_mode == FRAME802154_SHORTADDRMODE) {
|
||||||
|
tx_frame_buffer.uSrcAddr.u16Short = info154.src_addr[0] | (info154.src_addr[0] << 8);
|
||||||
|
} else if(info154.fcf.src_addr_mode == FRAME802154_LONGADDRMODE) {
|
||||||
|
tx_frame_buffer.uSrcAddr.sExt.u32L = *(uint32_t*)(&info154.src_addr[4]);
|
||||||
|
tx_frame_buffer.uSrcAddr.sExt.u32H = *(uint32_t*)(&info154.src_addr[0]);
|
||||||
|
}
|
||||||
|
tx_frame_buffer.u16FCS = crc16_data(payload, payload_len, 0);
|
||||||
|
memcpy(tx_frame_buffer.uPayload.au8Byte, info154.payload, info154.payload_len);
|
||||||
|
#else
|
||||||
/* Copy payload to (soft) Ttx buffer */
|
/* Copy payload to (soft) Ttx buffer */
|
||||||
memcpy(tx_frame_buffer.uPayload.au8Byte, payload, payload_len);
|
memcpy(tx_frame_buffer.uPayload.au8Byte, payload, payload_len);
|
||||||
i = payload_len;
|
i = payload_len;
|
||||||
|
@ -416,6 +473,7 @@ prepare(const void *payload, unsigned short payload_len)
|
||||||
tx_frame_buffer.u8PayloadLength = payload_len + CHECKSUM_LEN;
|
tx_frame_buffer.u8PayloadLength = payload_len + CHECKSUM_LEN;
|
||||||
#else
|
#else
|
||||||
tx_frame_buffer.u8PayloadLength = payload_len;
|
tx_frame_buffer.u8PayloadLength = payload_len;
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -445,6 +503,7 @@ set_channel(int c)
|
||||||
vMMAC_SetChannel(current_channel);
|
vMMAC_SetChannel(current_channel);
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
#if !MICROMAC_RADIO_MAC
|
||||||
static int
|
static int
|
||||||
is_broadcast_addr(uint8_t mode, uint8_t *addr)
|
is_broadcast_addr(uint8_t mode, uint8_t *addr)
|
||||||
{
|
{
|
||||||
|
@ -504,11 +563,59 @@ is_packet_for_us(uint8_t *buf, int len, int do_send_ack)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
static int
|
static int
|
||||||
read(void *buf, unsigned short bufsize)
|
read(void *buf, unsigned short bufsize)
|
||||||
{
|
{
|
||||||
int len = 0;
|
int len = 0;
|
||||||
|
#if MICROMAC_RADIO_MAC
|
||||||
|
frame802154_fcf_t fcf;
|
||||||
|
uint8_t *p = (uint8_t*)buf;
|
||||||
|
int has_src_panid;
|
||||||
|
int has_dest_panid;
|
||||||
|
int c;
|
||||||
|
|
||||||
|
p[len++] = input_frame_buffer->u16FCF & 0xff;
|
||||||
|
p[len++] = (input_frame_buffer->u16FCF >> 8) & 0xff;
|
||||||
|
frame802154_parse_fcf(p, &fcf);
|
||||||
|
p[len++] = input_frame_buffer->u8SequenceNum;
|
||||||
|
frame802154_has_panid(&fcf, &has_src_panid, &has_dest_panid);
|
||||||
|
if(has_dest_panid) {
|
||||||
|
p[len++] = input_frame_buffer->u16DestPAN & 0xff;
|
||||||
|
p[len++] = (input_frame_buffer->u16DestPAN >> 8) & 0xff;
|
||||||
|
}
|
||||||
|
if(fcf.dest_addr_mode == FRAME802154_SHORTADDRMODE) {
|
||||||
|
p[len++] = input_frame_buffer->uDestAddr.u16Short & 0xff;
|
||||||
|
p[len++] = (input_frame_buffer->uDestAddr.u16Short >> 8) & 0xff;
|
||||||
|
} else if(fcf.dest_addr_mode == FRAME802154_LONGADDRMODE) {
|
||||||
|
for(c = 0; c < 4; c++) {
|
||||||
|
p[len + c] = ((uint8_t*)(&input_frame_buffer->uDestAddr.sExt.u32L))[3 - c];
|
||||||
|
}
|
||||||
|
for(c = 0; c < 4; c++) {
|
||||||
|
p[len + c + 4] = ((uint8_t*)(&input_frame_buffer->uDestAddr.sExt.u32H))[3 - c];
|
||||||
|
}
|
||||||
|
len += 8;
|
||||||
|
}
|
||||||
|
if(has_src_panid) {
|
||||||
|
p[len++] = input_frame_buffer->u16SrcPAN & 0xff;
|
||||||
|
p[len++] = (input_frame_buffer->u16SrcPAN >> 8) & 0xff;
|
||||||
|
}
|
||||||
|
if(fcf.src_addr_mode == FRAME802154_SHORTADDRMODE) {
|
||||||
|
p[len++] = input_frame_buffer->uSrcAddr.u16Short & 0xff;
|
||||||
|
p[len++] = (input_frame_buffer->uSrcAddr.u16Short >> 8) & 0xff;
|
||||||
|
} else if(fcf.src_addr_mode == FRAME802154_LONGADDRMODE) {
|
||||||
|
for(c = 0; c < 4; c++) {
|
||||||
|
p[len + c] = ((uint8_t*)(&input_frame_buffer->uSrcAddr.sExt.u32L))[3 - c];
|
||||||
|
}
|
||||||
|
for(c = 0; c < 4; c++) {
|
||||||
|
p[len + c + 4] = ((uint8_t*)(&input_frame_buffer->uSrcAddr.sExt.u32H))[3 - c];
|
||||||
|
}
|
||||||
|
len += 8;
|
||||||
|
}
|
||||||
|
memcpy(&p[len], input_frame_buffer->uPayload.au8Byte, input_frame_buffer->u8PayloadLength);
|
||||||
|
len += input_frame_buffer->u8PayloadLength;
|
||||||
|
#else
|
||||||
uint16_t radio_last_rx_crc;
|
uint16_t radio_last_rx_crc;
|
||||||
uint8_t radio_last_rx_crc_ok = 1;
|
uint8_t radio_last_rx_crc_ok = 1;
|
||||||
|
|
||||||
|
@ -556,7 +663,7 @@ read(void *buf, unsigned short bufsize)
|
||||||
/* Disable further read attempts */
|
/* Disable further read attempts */
|
||||||
input_frame_buffer->u8PayloadLength = 0;
|
input_frame_buffer->u8PayloadLength = 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
@ -670,7 +777,9 @@ radio_interrupt_handler(uint32 mac_event)
|
||||||
uint8_t overflow = 0;
|
uint8_t overflow = 0;
|
||||||
int get_index;
|
int get_index;
|
||||||
int put_index;
|
int put_index;
|
||||||
|
#if !MICROMAC_RADIO_MAC
|
||||||
int packet_for_me = 0;
|
int packet_for_me = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
if(mac_event & E_MMAC_INT_TX_COMPLETE) {
|
if(mac_event & E_MMAC_INT_TX_COMPLETE) {
|
||||||
/* Transmission attempt has finished */
|
/* Transmission attempt has finished */
|
||||||
|
@ -683,6 +792,28 @@ radio_interrupt_handler(uint32 mac_event)
|
||||||
last_packet_timestamp = get_packet_timestamp();
|
last_packet_timestamp = get_packet_timestamp();
|
||||||
|
|
||||||
if(!poll_mode && (mac_event & E_MMAC_INT_RX_COMPLETE)) {
|
if(!poll_mode && (mac_event & E_MMAC_INT_RX_COMPLETE)) {
|
||||||
|
#if MICROMAC_RADIO_MAC
|
||||||
|
/* read and cache RSSI and LQI values */
|
||||||
|
read_last_rssi();
|
||||||
|
/* Put received frame in queue */
|
||||||
|
ringbufindex_put(&input_ringbuf);
|
||||||
|
|
||||||
|
if((get_index = ringbufindex_peek_get(&input_ringbuf)) != -1) {
|
||||||
|
input_frame_buffer = &input_array[get_index];
|
||||||
|
}
|
||||||
|
process_poll(µmac_radio_process);
|
||||||
|
|
||||||
|
/* get pointer to next input slot */
|
||||||
|
put_index = ringbufindex_peek_put(&input_ringbuf);
|
||||||
|
/* is there space? */
|
||||||
|
if(put_index != -1) {
|
||||||
|
/* move rx_frame_buffer to next empty slot */
|
||||||
|
rx_frame_buffer = &input_array[put_index];
|
||||||
|
} else {
|
||||||
|
overflow = 1;
|
||||||
|
rx_frame_buffer = NULL;
|
||||||
|
}
|
||||||
|
#else
|
||||||
if(rx_frame_buffer->u8PayloadLength > CHECKSUM_LEN) {
|
if(rx_frame_buffer->u8PayloadLength > CHECKSUM_LEN) {
|
||||||
if(frame_filtering) {
|
if(frame_filtering) {
|
||||||
/* Check RX address */
|
/* Check RX address */
|
||||||
|
@ -716,6 +847,7 @@ radio_interrupt_handler(uint32 mac_event)
|
||||||
rx_frame_buffer = NULL;
|
rx_frame_buffer = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
} else { /* if rx is not successful */
|
} else { /* if rx is not successful */
|
||||||
if(rx_status & E_MMAC_RXSTAT_ABORTED) {
|
if(rx_status & E_MMAC_RXSTAT_ABORTED) {
|
||||||
|
|
Loading…
Reference in a new issue