diff --git a/core/net/mac/frame802154.c b/core/net/mac/frame802154.c index c970cd964..d5c55c4e8 100644 --- a/core/net/mac/frame802154.c +++ b/core/net/mac/frame802154.c @@ -183,7 +183,7 @@ frame802154_has_panid(frame802154_fcf_t *fcf, int *has_src_pan_id, int *has_dest } else { /* No PAN ID in ACK */ if(fcf->frame_type != FRAME802154_ACKFRAME) { - if(!fcf->panid_compression && fcf->src_addr_mode & 3) { + if(!fcf->panid_compression && (fcf->src_addr_mode & 3)) { /* If compressed, don't include source PAN ID */ src_pan_id = 1; } @@ -304,7 +304,7 @@ field_len(frame802154_t *p, field_length_t *flen) * up to the caller. */ if(p->fcf.frame_version < FRAME802154_IEEE802154E_2012) { /* Set PAN ID compression bit if src pan id matches dest pan id. */ - if(p->fcf.dest_addr_mode & 3 && p->fcf.src_addr_mode & 3 && + if((p->fcf.dest_addr_mode & 3) && (p->fcf.src_addr_mode & 3) && p->src_pid == p->dest_pid) { p->fcf.panid_compression = 1; } else { @@ -362,6 +362,20 @@ frame802154_hdrlen(frame802154_t *p) return 2 + flen.seqno_len + flen.dest_pid_len + flen.dest_addr_len + flen.src_pid_len + flen.src_addr_len + flen.aux_sec_len; } +void +frame802154_create_fcf(frame802154_fcf_t *fcf, uint8_t *buf) +{ + buf[0] = (fcf->frame_type & 7) | + ((fcf->security_enabled & 1) << 3) | + ((fcf->frame_pending & 1) << 4) | + ((fcf->ack_required & 1) << 5) | + ((fcf->panid_compression & 1) << 6); + buf[1] = ((fcf->sequence_number_suppression & 1)) | + ((fcf->ie_list_present & 1)) << 1 | + ((fcf->dest_addr_mode & 3) << 2) | + ((fcf->frame_version & 3) << 4) | + ((fcf->src_addr_mode & 3) << 6); +} /*----------------------------------------------------------------------------*/ /** * \brief Creates a frame for transmission over the air. This function is @@ -388,17 +402,7 @@ frame802154_create(frame802154_t *p, uint8_t *buf) /* OK, now we have field lengths. Time to actually construct */ /* the outgoing frame, and store it in buf */ - buf[0] = (p->fcf.frame_type & 7) | - ((p->fcf.security_enabled & 1) << 3) | - ((p->fcf.frame_pending & 1) << 4) | - ((p->fcf.ack_required & 1) << 5) | - ((p->fcf.panid_compression & 1) << 6); - buf[1] = ((p->fcf.sequence_number_suppression & 1)) | - ((p->fcf.ie_list_present & 1)) << 1 | - ((p->fcf.dest_addr_mode & 3) << 2) | - ((p->fcf.frame_version & 3) << 4) | - ((p->fcf.src_addr_mode & 3) << 6); - + frame802154_create_fcf(&p->fcf, buf); pos = 2; /* Sequence number */ @@ -460,6 +464,28 @@ frame802154_create(frame802154_t *p, uint8_t *buf) return (int)pos; } + +void +frame802154_parse_fcf(uint8_t *data, frame802154_fcf_t *pfcf) +{ + frame802154_fcf_t fcf; + + /* decode the FCF */ + fcf.frame_type = data[0] & 7; + fcf.security_enabled = (data[0] >> 3) & 1; + fcf.frame_pending = (data[0] >> 4) & 1; + fcf.ack_required = (data[0] >> 5) & 1; + fcf.panid_compression = (data[0] >> 6) & 1; + + fcf.sequence_number_suppression = data[1] & 1; + fcf.ie_list_present = (data[1] >> 1) & 1; + fcf.dest_addr_mode = (data[1] >> 2) & 3; + fcf.frame_version = (data[1] >> 4) & 3; + fcf.src_addr_mode = (data[1] >> 6) & 3; + + /* copy fcf */ + memcpy(pfcf, &fcf, sizeof(frame802154_fcf_t)); +} /*----------------------------------------------------------------------------*/ /** * \brief Parses an input frame. Scans the input frame to find each @@ -489,19 +515,7 @@ frame802154_parse(uint8_t *data, int len, frame802154_t *pf) p = data; /* decode the FCF */ - fcf.frame_type = p[0] & 7; - fcf.security_enabled = (p[0] >> 3) & 1; - fcf.frame_pending = (p[0] >> 4) & 1; - fcf.ack_required = (p[0] >> 5) & 1; - fcf.panid_compression = (p[0] >> 6) & 1; - - fcf.sequence_number_suppression = p[1] & 1; - fcf.ie_list_present = (p[1] >> 1) & 1; - fcf.dest_addr_mode = (p[1] >> 2) & 3; - fcf.frame_version = (p[1] >> 4) & 3; - fcf.src_addr_mode = (p[1] >> 6) & 3; - - /* copy fcf and seqNum */ + frame802154_parse_fcf(p, &fcf); memcpy(&pf->fcf, &fcf, sizeof(frame802154_fcf_t)); p += 2; /* Skip first two bytes */ diff --git a/core/net/mac/frame802154.h b/core/net/mac/frame802154.h index defb64b53..2ff067a26 100644 --- a/core/net/mac/frame802154.h +++ b/core/net/mac/frame802154.h @@ -207,8 +207,10 @@ typedef struct { /* Prototypes */ int frame802154_hdrlen(frame802154_t *p); +void frame802154_create_fcf(frame802154_fcf_t *fcf, uint8_t *buf); int frame802154_create(frame802154_t *p, uint8_t *buf); int frame802154_parse(uint8_t *data, int length, frame802154_t *pf); +void frame802154_parse_fcf(uint8_t *data, frame802154_fcf_t *pfcf); /* Get current PAN ID */ uint16_t frame802154_get_pan_id(void); diff --git a/platform/jn516x/contiki-conf.h b/platform/jn516x/contiki-conf.h index 1a326f62b..e3c3a21d9 100644 --- a/platform/jn516x/contiki-conf.h +++ b/platform/jn516x/contiki-conf.h @@ -112,6 +112,16 @@ /* Configure NullRDC for when it is selected */ #define NULLRDC_CONF_802154_AUTOACK_HW 1 +/* Configure ContikiMAC for when it's selected */ +#define CONTIKIMAC_CONF_WITH_CONTIKIMAC_HEADER 0 +#define CONTIKIMAC_CONF_WITH_PHASE_OPTIMIZATION 0 +#define WITH_FAST_SLEEP 1 + +#ifndef NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE +#define NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE 8 +#endif +#define RDC_CONF_HARDWARE_ACK 1 + #define UIP_CONF_LL_802154 1 #define UIP_CONF_LLH_LEN 0 diff --git a/platform/jn516x/dev/micromac-radio.c b/platform/jn516x/dev/micromac-radio.c index 6b91cc51b..53bbaadb5 100644 --- a/platform/jn516x/dev/micromac-radio.c +++ b/platform/jn516x/dev/micromac-radio.c @@ -63,6 +63,18 @@ #define DEBUG DEBUG_NONE #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, * since we use PHY mode which does not calculate CRC in HW */ #define CRC_SW 1 @@ -165,17 +177,17 @@ static volatile uint8_t listen_on = 0; static uint8_t in_ack_transmission = 0; /* TX frame buffer */ -static tsPhyFrame tx_frame_buffer; +static MICROMAC_FRAME tx_frame_buffer; /* RX frame buffer */ -static tsPhyFrame *rx_frame_buffer; +static MICROMAC_FRAME *rx_frame_buffer; /* 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 */ 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 */ static volatile uint32_t last_packet_timestamp = 0; @@ -183,7 +195,9 @@ static volatile uint32_t last_packet_timestamp = 0; /* Local functions prototypes */ static int on(void); static int off(void); +#if !MICROMAC_RADIO_MAC 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 rtimer_clock_t get_packet_timestamp(void); static void set_txpower(int8_t power); @@ -305,10 +319,21 @@ on(void) { /* No address matching or frame decoding */ 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, (uint16_t)(E_MMAC_RX_START_NOW | E_MMAC_RX_NO_FCS_ERROR) /* means: reject FCS errors */ ); +#endif } else { missed_radio_on_request = 1; } @@ -347,10 +372,16 @@ transmit(unsigned short payload_len) ENERGEST_ON(ENERGEST_TYPE_TRANSMIT); /* 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, E_MMAC_TX_START_NOW | (send_on_cca ? E_MMAC_TX_USE_CCA : E_MMAC_TX_NO_CCA)); - +#endif if(poll_mode) { BUSYWAIT_UNTIL(u32MMAC_PollInterruptSource(E_MMAC_INT_TX_COMPLETE), MAX_PACKET_DURATION); } else { @@ -394,8 +425,10 @@ transmit(unsigned short payload_len) static int prepare(const void *payload, unsigned short payload_len) { +#if !MICROMAC_RADIO_MAC uint8_t i; uint16_t checksum; +#endif RIMESTATS_ADD(lltx); @@ -405,6 +438,30 @@ prepare(const void *payload, unsigned short payload_len) if(payload_len > 127 || payload == NULL) { 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 */ memcpy(tx_frame_buffer.uPayload.au8Byte, payload, 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; #else tx_frame_buffer.u8PayloadLength = payload_len; +#endif #endif return 0; @@ -445,6 +503,7 @@ set_channel(int c) vMMAC_SetChannel(current_channel); } /*---------------------------------------------------------------------------*/ +#if !MICROMAC_RADIO_MAC static int 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; } } +#endif /*---------------------------------------------------------------------------*/ static int read(void *buf, unsigned short bufsize) { 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; uint8_t radio_last_rx_crc_ok = 1; @@ -556,7 +663,7 @@ read(void *buf, unsigned short bufsize) /* Disable further read attempts */ input_frame_buffer->u8PayloadLength = 0; } - +#endif return len; } /*---------------------------------------------------------------------------*/ @@ -670,7 +777,9 @@ radio_interrupt_handler(uint32 mac_event) uint8_t overflow = 0; int get_index; int put_index; +#if !MICROMAC_RADIO_MAC int packet_for_me = 0; +#endif if(mac_event & E_MMAC_INT_TX_COMPLETE) { /* Transmission attempt has finished */ @@ -683,6 +792,28 @@ radio_interrupt_handler(uint32 mac_event) last_packet_timestamp = get_packet_timestamp(); 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(frame_filtering) { /* Check RX address */ @@ -716,6 +847,7 @@ radio_interrupt_handler(uint32 mac_event) rx_frame_buffer = NULL; } } +#endif } } else { /* if rx is not successful */ if(rx_status & E_MMAC_RXSTAT_ABORTED) {