From 41cb9dd66c2e643ebb9ab3f603ed5b64d06a5187 Mon Sep 17 00:00:00 2001 From: Edvard Pettersen Date: Tue, 10 Jul 2018 18:57:01 +0200 Subject: [PATCH] Implemented RX_ACK for IEEE-mode --- arch/cpu/cc13xx-cc26xx/dev/rf-ieee-mode.c | 67 ++++++++++++++++--- .../rf-settings/cc13x0/ieee-settings.c | 22 ++++++ .../rf-settings/cc13x0/ieee-settings.h | 1 + .../rf-settings/cc13x2/ieee-settings.c | 22 ++++++ .../rf-settings/cc13x2/ieee-settings.h | 1 + .../rf-settings/cc26x0/ieee-settings.c | 22 ++++++ .../rf-settings/cc26x0/ieee-settings.h | 1 + .../rf-settings/cc26x2/ieee-settings.c | 22 ++++++ .../rf-settings/cc26x2/ieee-settings.h | 1 + 9 files changed, 149 insertions(+), 10 deletions(-) diff --git a/arch/cpu/cc13xx-cc26xx/dev/rf-ieee-mode.c b/arch/cpu/cc13xx-cc26xx/dev/rf-ieee-mode.c index f902e76a5..400b18ff9 100644 --- a/arch/cpu/cc13xx-cc26xx/dev/rf-ieee-mode.c +++ b/arch/cpu/cc13xx-cc26xx/dev/rf-ieee-mode.c @@ -171,11 +171,13 @@ #define STATUS_REJECT_FRAME 0x40 /* bit 6 */ #define STATUS_CRC_FAIL 0x80 /* bit 7 */ /*---------------------------------------------------------------------------*/ -/* TX buf configuration */ -#define TX_BUF_HDR_LEN 2 -#define TX_BUF_PAYLOAD_LEN 180 +#define FRAME_FCF_OFFSET 0 +#define FRAME_SEQNUM_OFFSET 2 -#define TX_BUF_SIZE (TX_BUF_HDR_LEN + TX_BUF_PAYLOAD_LEN) +#define FRAME_ACK_REQUEST 0x20 /* bit 5 */ + +/* TX buf configuration */ +#define TX_BUF_SIZE 180 /* RX buf configuration */ #ifdef IEEE_MODE_CONF_RX_BUF_CNT @@ -260,6 +262,7 @@ static cmd_mod_filt_t cmd_mod_filt; #define cmd_fs (*(volatile rfc_CMD_FS_t*) &rf_cmd_ieee_fs) #define cmd_tx (*(volatile rfc_CMD_IEEE_TX_t*) &rf_cmd_ieee_tx) #define cmd_rx (*(volatile rfc_CMD_IEEE_RX_t*) &rf_cmd_ieee_rx) +#define cmd_rx_ack (*(volatile rfc_CMD_IEEE_RX_ACK_t*)&rf_cmd_ieee_rx_ack) /*---------------------------------------------------------------------------*/ static inline bool rx_is_active(void) { return cmd_rx.status == ACTIVE; } /*---------------------------------------------------------------------------*/ @@ -356,6 +359,17 @@ init_rf_params(void) cmd_rx.ccaRssiThr = IEEE_MODE_RSSI_THRESHOLD; + cmd_tx.pNextOp = (RF_Op*)&cmd_rx_ack; + cmd_tx.condition.rule = COND_NEVER; /* Initially ACK turned off */ + + cmd_rx_ack.startTrigger.triggerType = TRIG_NOW; + cmd_rx_ack.endTrigger.triggerType = TRIG_REL_SUBMIT; + /* + * ACK packet is transmitted 192 us after the end of the received packet. + * See TRM Section ACK Transmission for more info. + */ + cmd_rx_ack.endTime = RF_convertUsToRatTicks(195); + /* Initialize address filter command */ cmd_mod_filt.commandNo = CMD_IEEE_MOD_FILT; memcpy(&(cmd_mod_filt.newFrameFiltOpt), &(rf_cmd_ieee_rx.frameFiltOpt), sizeof(rf_cmd_ieee_rx.frameFiltOpt)); @@ -532,9 +546,9 @@ static int prepare(const void *payload, unsigned short payload_len) { const size_t len = MIN((size_t)payload_len, - (size_t)TX_BUF_PAYLOAD_LEN); + (size_t)TX_BUF_SIZE); - memcpy(ieee_radio.tx_buf + TX_BUF_HDR_LEN, payload, len); + memcpy(ieee_radio.tx_buf, payload, len); return 0; } /*---------------------------------------------------------------------------*/ @@ -548,15 +562,48 @@ transmit(unsigned short transmit_len) return RADIO_TX_COLLISION; } + /* + * Are we expecting ACK? The ACK Request flag is in the first Frame + * Control Field byte, that is the first byte in the frame. + */ + const bool ack_request = (bool)(ieee_radio.tx_buf[FRAME_FCF_OFFSET] & FRAME_ACK_REQUEST); + if (ack_request) { + /* Yes, turn on chaining */ + cmd_tx.condition.rule = COND_STOP_ON_FALSE; + + /* Reset CMD_IEEE_RX_ACK command */ + cmd_rx_ack.status = IDLE; + /* Sequence number is the third byte in the frame */ + cmd_rx_ack.seqNo = ieee_radio.tx_buf[FRAME_SEQNUM_OFFSET]; + } else { + /* No, turn off chaining */ + cmd_tx.condition.rule = COND_NEVER; + } + /* Configure TX command */ cmd_tx.payloadLen = (uint8_t)transmit_len; - cmd_tx.pPayload = &ieee_radio.tx_buf[TX_BUF_HDR_LEN]; + cmd_tx.pPayload = ieee_radio.tx_buf; res = netstack_sched_tx(NULL, 0); - return (res == RF_RESULT_OK) - ? RADIO_TX_OK - : RADIO_TX_ERR; + if (res != RF_RESULT_OK) { + return RADIO_TX_ERR; + } + + if (ack_request) { + switch(cmd_rx_ack.status) { + /* CMD_IEEE_RX_ACK timed out, i.e. never received ACK */ + case IEEE_DONE_TIMEOUT: return RADIO_TX_NOACK; + /* An ACK was received with either pending data bit set or cleared */ + case IEEE_DONE_ACK: /* fallthrough */ + case IEEE_DONE_ACKPEND: return RADIO_TX_OK; + /* Any other statuses are errors */ + default: return RADIO_TX_ERR; + } + } + + /* No ACK expected, TX OK */ + return RADIO_TX_OK; } /*---------------------------------------------------------------------------*/ static int diff --git a/arch/cpu/cc13xx-cc26xx/rf-settings/cc13x0/ieee-settings.c b/arch/cpu/cc13xx-cc26xx/rf-settings/cc13x0/ieee-settings.c index cfe9ef9a7..7a455862c 100644 --- a/arch/cpu/cc13xx-cc26xx/rf-settings/cc13x0/ieee-settings.c +++ b/arch/cpu/cc13xx-cc26xx/rf-settings/cc13x0/ieee-settings.c @@ -245,3 +245,25 @@ rfc_CMD_IEEE_RX_t rf_cmd_ieee_rx = .endTime = 0x00000000, }; /*---------------------------------------------------------------------------*/ +// CMD_IEEE_RX_ACK +// IEEE 802.15.4 Receive ACK Command +rfc_CMD_IEEE_RX_ACK_t rf_cmd_ieee_rx_ack = +{ + .commandNo = CMD_IEEE_RX_ACK, + .status = IDLE, + .pNextOp = 0, + .startTime = 0x00000000, + .startTrigger.triggerType = TRIG_NOW, + .startTrigger.bEnaCmd = 0x0, + .startTrigger.triggerNo = 0x0, + .startTrigger.pastTrig = 0x0, + .condition.rule = COND_NEVER, + .condition.nSkip = 0x0, + .seqNo = 0x0, + .endTrigger.triggerType = TRIG_NEVER, + .endTrigger.bEnaCmd = 0x0, + .endTrigger.triggerNo = 0x0, + .endTrigger.pastTrig = 0x0, + .endTime = 0x00000000, +}; +/*---------------------------------------------------------------------------*/ diff --git a/arch/cpu/cc13xx-cc26xx/rf-settings/cc13x0/ieee-settings.h b/arch/cpu/cc13xx-cc26xx/rf-settings/cc13x0/ieee-settings.h index 5276887b4..305b56855 100644 --- a/arch/cpu/cc13xx-cc26xx/rf-settings/cc13x0/ieee-settings.h +++ b/arch/cpu/cc13xx-cc26xx/rf-settings/cc13x0/ieee-settings.h @@ -54,6 +54,7 @@ extern rfc_CMD_RADIO_SETUP_t rf_cmd_ieee_radio_setup; extern rfc_CMD_FS_t rf_cmd_ieee_fs; extern rfc_CMD_IEEE_TX_t rf_cmd_ieee_tx; extern rfc_CMD_IEEE_RX_t rf_cmd_ieee_rx; +extern rfc_CMD_IEEE_RX_ACK_t rf_cmd_ieee_rx_ack; /*---------------------------------------------------------------------------*/ // RF Core API Overrides extern uint32_t rf_ieee_overrides[]; diff --git a/arch/cpu/cc13xx-cc26xx/rf-settings/cc13x2/ieee-settings.c b/arch/cpu/cc13xx-cc26xx/rf-settings/cc13x2/ieee-settings.c index efa12e2f6..86892b571 100644 --- a/arch/cpu/cc13xx-cc26xx/rf-settings/cc13x2/ieee-settings.c +++ b/arch/cpu/cc13xx-cc26xx/rf-settings/cc13x2/ieee-settings.c @@ -296,3 +296,25 @@ rfc_CMD_IEEE_RX_t rf_cmd_ieee_rx = .endTime = 0x00000000, }; /*---------------------------------------------------------------------------*/ +// CMD_IEEE_RX_ACK +// IEEE 802.15.4 Receive ACK Command +rfc_CMD_IEEE_RX_ACK_t rf_cmd_ieee_rx_ack = +{ + .commandNo = CMD_IEEE_RX_ACK, + .status = IDLE, + .pNextOp = 0, + .startTime = 0x00000000, + .startTrigger.triggerType = TRIG_NOW, + .startTrigger.bEnaCmd = 0x0, + .startTrigger.triggerNo = 0x0, + .startTrigger.pastTrig = 0x0, + .condition.rule = COND_NEVER, + .condition.nSkip = 0x0, + .seqNo = 0x0, + .endTrigger.triggerType = TRIG_NEVER, + .endTrigger.bEnaCmd = 0x0, + .endTrigger.triggerNo = 0x0, + .endTrigger.pastTrig = 0x0, + .endTime = 0x00000000, +}; +/*---------------------------------------------------------------------------*/ diff --git a/arch/cpu/cc13xx-cc26xx/rf-settings/cc13x2/ieee-settings.h b/arch/cpu/cc13xx-cc26xx/rf-settings/cc13x2/ieee-settings.h index fdb722ab8..5f6a6eb2e 100644 --- a/arch/cpu/cc13xx-cc26xx/rf-settings/cc13x2/ieee-settings.h +++ b/arch/cpu/cc13xx-cc26xx/rf-settings/cc13x2/ieee-settings.h @@ -54,6 +54,7 @@ extern rfc_CMD_RADIO_SETUP_t rf_cmd_ieee_radio_setup; extern rfc_CMD_FS_t rf_cmd_ieee_fs; extern rfc_CMD_IEEE_TX_t rf_cmd_ieee_tx; extern rfc_CMD_IEEE_RX_t rf_cmd_ieee_rx; +extern rfc_CMD_IEEE_RX_ACK_t rf_cmd_ieee_rx_ack; /*---------------------------------------------------------------------------*/ // RF Core API Overrides extern uint32_t rf_ieee_overrides_default_pa[]; diff --git a/arch/cpu/cc13xx-cc26xx/rf-settings/cc26x0/ieee-settings.c b/arch/cpu/cc13xx-cc26xx/rf-settings/cc26x0/ieee-settings.c index 92720c63b..f2fb6963c 100644 --- a/arch/cpu/cc13xx-cc26xx/rf-settings/cc26x0/ieee-settings.c +++ b/arch/cpu/cc13xx-cc26xx/rf-settings/cc26x0/ieee-settings.c @@ -245,3 +245,25 @@ rfc_CMD_IEEE_RX_t rf_cmd_ieee_rx = .endTime = 0x00000000, }; /*---------------------------------------------------------------------------*/ +// CMD_IEEE_RX_ACK +// IEEE 802.15.4 Receive ACK Command +rfc_CMD_IEEE_RX_ACK_t rf_cmd_ieee_rx_ack = +{ + .commandNo = CMD_IEEE_RX_ACK, + .status = IDLE, + .pNextOp = 0, + .startTime = 0x00000000, + .startTrigger.triggerType = TRIG_NOW, + .startTrigger.bEnaCmd = 0x0, + .startTrigger.triggerNo = 0x0, + .startTrigger.pastTrig = 0x0, + .condition.rule = COND_NEVER, + .condition.nSkip = 0x0, + .seqNo = 0x0, + .endTrigger.triggerType = TRIG_NEVER, + .endTrigger.bEnaCmd = 0x0, + .endTrigger.triggerNo = 0x0, + .endTrigger.pastTrig = 0x0, + .endTime = 0x00000000, +}; +/*---------------------------------------------------------------------------*/ diff --git a/arch/cpu/cc13xx-cc26xx/rf-settings/cc26x0/ieee-settings.h b/arch/cpu/cc13xx-cc26xx/rf-settings/cc26x0/ieee-settings.h index ff63f2c7e..55434276c 100644 --- a/arch/cpu/cc13xx-cc26xx/rf-settings/cc26x0/ieee-settings.h +++ b/arch/cpu/cc13xx-cc26xx/rf-settings/cc26x0/ieee-settings.h @@ -52,6 +52,7 @@ extern rfc_CMD_RADIO_SETUP_t rf_cmd_ieee_radio_setup; extern rfc_CMD_FS_t rf_cmd_ieee_fs; extern rfc_CMD_IEEE_TX_t rf_cmd_ieee_tx; extern rfc_CMD_IEEE_RX_t rf_cmd_ieee_rx; +extern rfc_CMD_IEEE_RX_ACK_t rf_cmd_ieee_rx_ack; /*---------------------------------------------------------------------------*/ // RF Core API Overrides extern uint32_t rf_ieee_overrides[]; diff --git a/arch/cpu/cc13xx-cc26xx/rf-settings/cc26x2/ieee-settings.c b/arch/cpu/cc13xx-cc26xx/rf-settings/cc26x2/ieee-settings.c index 709314db6..17c9b686f 100644 --- a/arch/cpu/cc13xx-cc26xx/rf-settings/cc26x2/ieee-settings.c +++ b/arch/cpu/cc13xx-cc26xx/rf-settings/cc26x2/ieee-settings.c @@ -242,3 +242,25 @@ rfc_CMD_IEEE_RX_t rf_cmd_ieee_rx = .endTime = 0x00000000, }; /*---------------------------------------------------------------------------*/ +// CMD_IEEE_RX_ACK +// IEEE 802.15.4 Receive ACK Command +rfc_CMD_IEEE_RX_ACK_t rf_cmd_ieee_rx_ack = +{ + .commandNo = CMD_IEEE_RX_ACK, + .status = IDLE, + .pNextOp = 0, + .startTime = 0x00000000, + .startTrigger.triggerType = TRIG_NOW, + .startTrigger.bEnaCmd = 0x0, + .startTrigger.triggerNo = 0x0, + .startTrigger.pastTrig = 0x0, + .condition.rule = COND_NEVER, + .condition.nSkip = 0x0, + .seqNo = 0x0, + .endTrigger.triggerType = TRIG_NEVER, + .endTrigger.bEnaCmd = 0x0, + .endTrigger.triggerNo = 0x0, + .endTrigger.pastTrig = 0x0, + .endTime = 0x00000000, +}; +/*---------------------------------------------------------------------------*/ diff --git a/arch/cpu/cc13xx-cc26xx/rf-settings/cc26x2/ieee-settings.h b/arch/cpu/cc13xx-cc26xx/rf-settings/cc26x2/ieee-settings.h index f92283afc..7572a36fd 100644 --- a/arch/cpu/cc13xx-cc26xx/rf-settings/cc26x2/ieee-settings.h +++ b/arch/cpu/cc13xx-cc26xx/rf-settings/cc26x2/ieee-settings.h @@ -52,6 +52,7 @@ extern rfc_CMD_RADIO_SETUP_t rf_cmd_ieee_radio_setup; extern rfc_CMD_FS_t rf_cmd_ieee_fs; extern rfc_CMD_IEEE_TX_t rf_cmd_ieee_tx; extern rfc_CMD_IEEE_RX_t rf_cmd_ieee_rx; +extern rfc_CMD_IEEE_RX_ACK_t rf_cmd_ieee_rx_ack; /*---------------------------------------------------------------------------*/ // RF Core API Overrides extern uint32_t rf_ieee_overrides[];