Enhanced RNet Wireless Components and Communication Stack

I’m using both the Freescale MC1320x and Nordic Semiconductor nRF24L01+ 2.4GHz in many projects. To make it even easier to use these transceivers in the RNet stack, I have updated it with several new functions.

MC13202 and nRF24L01+

MC13202 and nRF24L01+

nRF24L01 Component

nRF24L01 Properties

nRF24L01 Properties

The component supports now a software SPI (bit-bangin) for when no hardware SPI pins are available. There is no dedicated SPI bus sharing (Switch Bus) implemented which performs mutual access to the SPI bus with different devices on the same bus.

As a special feature, it is now possible to use the transceiver in polling mode (e.g. if the interrupt pin is not used/available). If the interrupt pin is disabled, then this creates a special define in the header file which can be checked by the application:

#define RF1_IRQ_PIN_ENABLED   0
  /*!< no IRQ pin or not enabled */

I’m using this in the RNet stack to automatically poll the status of the transceiver:

static void RADIO_HandleStateMachine(void) {
  uint8_t status, res;

  for(;;) { /* will break/return */
    switch (RADIO_AppStatus) {
      case RADIO_INITIAL_STATE:
        RF1_StopRxTx();  /* will send/receive data later */
        RADIO_AppStatus = RADIO_RECEIVER_ALWAYS_ON; /* turn receive on */
        break; /* process switch again */

      case RADIO_RECEIVER_ALWAYS_ON: /* turn receive on */
        RX_POWERUP();
        RF1_StartRxTx(); /* Listening for packets */
        RADIO_AppStatus = RADIO_READY_FOR_TX_RX_DATA;
        break; /* process switch again */

      case RADIO_READY_FOR_TX_RX_DATA: /* we are ready to receive/send data data */
#if !RF1_IRQ_PIN_ENABLED
        RF1_PollInterrupt();
#endif
        if (RADIO_isrFlag) { /* Rx interrupt? */
          RADIO_isrFlag = FALSE; /* reset interrupt flag */
          (void)CheckRx(); /* get message */
          RADIO_AppStatus = RADIO_RECEIVER_ALWAYS_ON; /* continue listening */
          break; /* process switch again */
        }
#if RNET_CONFIG_SEND_RETRY_CNT>0
        RADIO_RetryCnt=0;
#endif
        RADIO_AppStatus = RADIO_CHECK_TX; /* check if we can send something */
        break;

      case RADIO_CHECK_TX:
        res = CheckTx();
        if (res==ERR_OK) { /* there was data and it has been sent */
          RADIO_AppStatus = RADIO_WAITING_DATA_SENT;
          break; /* process switch again */
        } else if (res==ERR_DISABLED) { /* powered down transceiver */
          RADIO_AppStatus = RADIO_POWER_DOWN;
        } else {
          RADIO_AppStatus = RADIO_READY_FOR_TX_RX_DATA;
        }
        return;

      case RADIO_POWER_DOWN:
        return;

      case RADIO_WAITING_DATA_SENT:
#if !RF1_IRQ_PIN_ENABLED
        RF1_PollInterrupt();
#endif
        if (RADIO_isrFlag) { /* check if we have received an interrupt: this is either timeout or low level ack */
          RADIO_isrFlag = FALSE; /* reset interrupt flag */
          status = RF1_GetStatusClrIRQ();
          if (status&RF1_STATUS_MAX_RT) { /* retry timeout interrupt */
            RF1_Write(RF1_FLUSH_TX); /* flush old data */
            RADIO_AppStatus = RADIO_TIMEOUT; /* timeout */
          } else {
            RADIO_AppStatus = RADIO_RECEIVER_ALWAYS_ON; /* turn receive on */
          }
          break; /* process switch again */
        }
        return;

      case RADIO_TIMEOUT:
#if RNET_CONFIG_SEND_RETRY_CNT>0
        if (RADIO_RetryCnt<RNET_CONFIG_SEND_RETRY_CNT) {
          Err((unsigned char*)"ERR: Retry\r\n");
          RADIO_RetryCnt++;
          if (RMSG_PutRetryTxMsg(TxDataBuffer, sizeof(TxDataBuffer))==ERR_OK) {
            RADIO_AppStatus = RADIO_CHECK_TX; /* resend packet */
            return; /* iterate state machine next time */
          } else {
            Err((unsigned char*)"ERR: Retry failed!\r\n");
          }
        }
#endif
        Err((unsigned char*)"ERR: Timeout\r\n");
        RADIO_AppStatus = RADIO_RECEIVER_ALWAYS_ON; /* turn receive on */
        break; /* process switch again */

      default: /* should not happen! */
        return;
    } /* switch */
  } /* for */
}

Several new methods have been added to have a convenient way to use the transceiver registers (more about this in the RNet component).

new nRF24L01+ Methods

new nRF24L01+ Methods

RNet Component

The RNet component has several new features:

RNet Properties

RNet Properties

  1. Ability to switch between nRF24L01+ and SMAC/MC1320x transceiver
  2. Additional default properties: channel, data rate, payload size, output power
  3. Network address size (8bit or 16bit), Acknowledge feature enabled or disabled.
  4. Configuration of radio transceiver queues and timing.
  5. Optional resending of messages (if retry count > 0).

Shell Support

With the above functions, the command line shell support has extended and new commands are available (shown for the nRF24L01+ here):

radio                     ; Group of radio commands
  help|status             ; Shows radio help or status
  channel         ; Switches to the given channel. Channel must be in the range 0..127
  power           ; Changes output power to 0, -10, -12, -18
  sniff on|off            ; Turns sniffing on or off
  writereg 0xReg 0xVal    ; Write a transceiver register
  flush                   ; Empty all queues
  printreg                ; Print the radio registers

With ‘writereg’ I can write any transceiver register on the fly. With ‘flush’ I have a manual way to flush the transceiver queues (I used that to debug a nasty problem which is now fixed in the low-level transceiver: for when an interrupt was missed by the hardware, the internal queues were screwed up (fixed 🙂 ). With ‘printreg’ I can dump all registers of the transceiver which was a useful debugging feature to inspect the transceiver hardware.

The ‘status’ command has been extended to show the details of the transceiver registers in human readable form:

CMD> radio status
Radio        : 
  state      : READY_TX_RX
  sniff      : no
  channel    : 0
  power      : 0 dBm
  data rate  : 1000 kbps
  STATUS     : 0x0E: RxFifoEmpty 
  FIFO_STATUS: 0x11: TX_EMPTY RX_EMPTY 
  OBSERVE_TX : 0 lost, 0 retry

It reports in addition to the earlier status items the data rate, STATUS and FIFO_STATUS registers.

Summary

For me the enhancements made things even easier to use, and add more functionality and debugging support. The sources are already pushed on GitHub, and will be released as PEupd files with the next drop.

Happy RFing 🙂

3 thoughts on “Enhanced RNet Wireless Components and Communication Stack

  1. Pingback: Tutorial: Nordic Semiconductor nRF24L01+ with the Freescale FRDM-K64F Board | MCU on Eclipse

  2. Pingback: BBQ Smoker Monitoring Robot | MCU on Eclipse

  3. Pingback: nRF24L01+ 2.4 GHz Wireless Connectivity with the tinyK20 Board | MCU on Eclipse

What do you think?

This site uses Akismet to reduce spam. Learn how your comment data is processed.