diff --git a/drivers/wireless/ieee802154/mrf24j40.c b/drivers/wireless/ieee802154/mrf24j40.c index 32da714bcad..3659fe1651e 100644 --- a/drivers/wireless/ieee802154/mrf24j40.c +++ b/drivers/wireless/ieee802154/mrf24j40.c @@ -125,12 +125,19 @@ struct mrf24j40_radio_s /* Buffer Allocations */ - struct ieee802154_txdesc_s csma_desc; - struct ieee802154_txdesc_s gts_desc[2]; + struct mrf24j40_txdesc_s csma_desc; + struct mrf24j40_txdesc_s gts_desc[2]; uint8_t tx_buf[CONFIG_IEEE802154_MTU]; }; +struct mrf24j40_txdesc_s +{ + struct ieee802154_txdesc_s ieee_desc; + + uint8_t busy : 1; /* Is this txdesc being used */ +}; + /**************************************************************************** * Private Function Prototypes ****************************************************************************/ @@ -218,7 +225,8 @@ static const struct ieee802154_radioops_s mrf24j40_devops = mrf24j40_bind, mrf24j40_ioctl, mrf24j40_rxenable, - mrf24j40_transmit + mrf24j40_txnotify_csma, + mrf24j40_txnotify_gts, }; /**************************************************************************** @@ -236,51 +244,104 @@ static void mrf24j40_bind(FAR struct ieee802154_radio_s *radio, } /**************************************************************************** - * Function: mrf24j40_txavail + * Function: mrf24j40_dopoll_csma * * Description: - * Called from the upper layer, this function is to notify the device that - * the upper layer has a pending transaction. This function checks to see - * if there is availability for the corresponding transaction type. If - * there is, the function will call to the MAC layer to get the transaction - * and then start the transmission + * This function is called in order to preform an out-of-sequence TX poll. + * This is done: + * + * 1. After completion of a CSMA transmission + * 2. When the upper layer calls txnotify_csma + * + * Parameters: + * radio - Reference to the radio driver state structure + * + * Returned Value: + * None + * + * Assumptions: * ****************************************************************************/ -static void mrf24j40_txavail(FAR struct ieee802154_radio_s *radio, bool gts) +static void mrf24j40_dopoll_csma(FAR struct ieee802154_radio_s *radio) { FAR struct mrf24j40_radio_s *dev = (FAR struct mrf24j40_radio_s *)radio; - uint8_t gts; - while (sem_wait(dev->exclsem) < 0) { } + /* Need to get exlusive access to the device so that we can use the copy + * buffer */ + + while (sem_wait(&dev->exclsem) < 0) { } /* If this a CSMA transaction and we have room in the CSMA fifo */ - if (!gts && !dev->csma_busy) + if (!dev->csma_txdesc.busy) { /* need to somehow allow for a handle to be passed */ ret = dev->phyif->poll_csma(dev->phyif, &radio->csma_txdesc, &dev->tx_buf[0]); + if (ret > 0) + { + /* Now the txdesc is in use */ + + dev->cmsa_desc.busy = 1; + + /* Setup the transaction on the device in the CSMA FIFO */ + + mrf24j40_csma_setup(radio, &dev->tx_buf[0], + dev->gts_desc[i].psdu_length); + } + /* Setup the transmit on the device */ + break; } - else - { - for(gts = 0; gts < MRF24J40_GTS_SLOTS, gts++) + + sem_post(&dev->exclsem); +} + +/**************************************************************************** + * Function: mrf24j40_txnotify_gts + * + * Description: + * Called from the upper layer, this function is to notify the device that + * the upper layer has a pending transaction for one of it's GTS'. This + * function checks to see if there is availability for the corresponding + * transaction type. If there is, the function will call to the MAC layer + * to get the transaction and then start the transmission + * + ****************************************************************************/ + +static void mrf24j40_txnotify_gts(FAR struct ieee802154_radio_s *radio) +{ + FAR struct mrf24j40_radio_s *dev = (FAR struct mrf24j40_radio_s *)radio; + + /* Need to get exclusive access to the device so that we can use the copy + * buffer */ + + while (sem_wait(dev->exclsem) < 0) { } + + for(gts = 0; gts < MRF24J40_GTS_SLOTS, gts++) + { + if(!dev->gts_txdesc[i].busy) { - if(!dev->gts_txdesc[i].busy) + ret = dev->phyif->poll_gts(dev->phyif, &radio->gts_txdesc[i], + &dev->tx_buf[0]); + + if (ret > 0) { - ret = dev->phyif->poll_gts(dev->phyif, &radio->gts_txdesc[i], - &dev->tx_buf[0]); + /* Now the txdesc is in use */ - /* Setup the transmit on the device */ + dev->gts_txdesc[i].busy = 1; - break; + /* Setup the transaction on the device in the open GTS FIFO */ + + mrf24j40_gts_setup(radio, i, &dev->tx_buf[0], + dev->gts_desc[i].psdu_length); } } - } + } } /**************************************************************************** @@ -1506,38 +1567,36 @@ FAR struct ieee802154_radio_s *mrf24j40_init(FAR struct spi_dev_s *spi, /* Initialize semaphores */ sem_init(&dev->radio.rxsem, 0, 0); - sem_init(&dev->radio.txsem, 0, 0); /* These semaphores are all used for signaling and, hence, should * not have priority inheritance enabled. */ sem_setprotocol(&dev->radio.rxsem, SEM_PRIO_NONE); - sem_setprotocol(&dev->radio.txsem, SEM_PRIO_NONE); dev->lower = lower; dev->spi = spi; mrf24j40_initialize(dev); - mrf24j40_setchannel(&dev->radio, 11); - mrf24j40_setpanid (&dev->radio, 0xFFFF); - mrf24j40_setsaddr (&dev->radio, 0xFFFF); - mrf24j40_seteaddr (&dev->radio, (uint8_t*)"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"); + mrf24j40_setchannel(dev, 11); + mrf24j40_setpanid (dev, 0xFFFF); + mrf24j40_setsaddr (dev, 0xFFFF); + mrf24j40_seteaddr (dev, (uint8_t*)"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"); /* Default device params */ cca.use_ed = 1; cca.use_cs = 0; cca.edth = 0x60; /* CCA mode ED, no carrier sense, recommenced ED threshold -69 dBm */ - mrf24j40_setcca(&dev->radio, &cca); + mrf24j40_setcca(dev, &cca); mrf24j40_setrxmode(dev, MRF24J40_RXMODE_NORMAL); - mrf24j40_settxpower(&dev->radio, 0); /*16. Set transmitter power .*/ + mrf24j40_settxpower(dev, 0); /*16. Set transmitter power .*/ mrf24j40_pacontrol(dev, MRF24J40_PA_AUTO); - dev->lower->enable(dev->radio, true); + dev->lower->enable(dev->lower, true); return &dev->radio; } diff --git a/include/nuttx/wireless/ieee802154/ieee802154_radio.h b/include/nuttx/wireless/ieee802154/ieee802154_radio.h index a26e3321d68..bd7c725b150 100644 --- a/include/nuttx/wireless/ieee802154/ieee802154_radio.h +++ b/include/nuttx/wireless/ieee802154/ieee802154_radio.h @@ -157,22 +157,15 @@ struct ieee802154_netradio_s #endif /* IEEE802.15.4 Radio Interface Operations **********************************/ -struct ieee802154_trans_s +struct ieee802154_txdesc_s { - uint8_t retry_count; /* The number of retries remaining */ - uint8_t msdu_handle; /* The msdu handle identifying the transaction */ + uint8_t psdu_handle; /* The psdu handle identifying the transaction */ uint16_t psdu_length; /* The length of the PSDU */ - /* The PHY Service Data Unit (PSDU) buffer representing the frame to be - * transmitted. This must be at the end of the struct to allow the array - * to continue and make the struct "variable length". Users should allocate - * memory using the SIZEOF_MAC802154_TRANSACTION_S macro below */ - - uint8_t psdu[CONFIG_IEEE802154_MTU]; + /* TODO: Add slotting information for GTS transactions */ }; - struct ieee802154_phyif_s; /* Forward Reference */ struct ieee802154_phyifops_s @@ -208,8 +201,8 @@ struct ieee802154_radioops_s CODE int (*rxenable)(FAR struct ieee802154_radio_s *dev, bool state, FAR struct ieee802154_packet_s *packet); - CODE int (*transmit)(FAR struct ieee802154_radio_s *dev, - FAR struct ieee802154_packet_s *packet); + CODE int (*txnotify_csma)(FAR struct ieee802154_radio_s *dev); + CODE int (*txnotify_gts)(FAR struct ieee802154_radio_s *dev); }; struct ieee802154_radio_s @@ -222,17 +215,6 @@ struct ieee802154_radio_s * rx interrupt, NULL if rx not enabled */ sem_t rxsem; /* Semaphore posted after reception of * a packet */ - - /* Packet transmission management */ - - bool txok; /* Last transmission status, filled by - * tx interrupt */ - bool txbusy; /* Last transmission failed because - * channel busy */ - uint8_t txretries; /* Last transmission required this much - * retries */ - sem_t txsem; /* Semaphore posted after transmission - * of a packet */ }; #ifdef __cplusplus diff --git a/wireless/ieee802154/mac802154.c b/wireless/ieee802154/mac802154.c index c4f99480bfb..32e78dd9165 100644 --- a/wireless/ieee802154/mac802154.c +++ b/wireless/ieee802154/mac802154.c @@ -57,6 +57,32 @@ /**************************************************************************** * Private Types ****************************************************************************/ + +struct mac802154_trans_s +{ + /* Supports a singly linked list */ + + FAR struct mac802154_trans_s *flink; + + uint8_t msdu_handle; + + uint8_t *mhr_buf; + uint8_t mhr_len; + + uint8_t *d_buf; + uint8_t d_len; + + sem_t sem; +}; + +struct mac802154_unsec_mhr_s +{ + uint8_t length; + union { + uint16_t frame_control; + uint8_t data[IEEE802154_MAX_UNSEC_MHR_OVERHEAD]; + }; +}; /* The privmac structure holds the internal state of the MAC and is the * underlying represention of the opaque MACHANDLE. It contains storage for @@ -79,7 +105,6 @@ struct ieee802154_privmac_s FAR struct mac802154_trans_s *csma_head; FAR struct mac802154_trans_s *csma_tail; - struct mac802154_trans_s csma_buf[5]; /* Support a singly linked list of transactions that will be sent indirectly. * This list should only be used by a MAC acting as a coordinator. These @@ -91,7 +116,6 @@ struct ieee802154_privmac_s FAR struct mac802154_trans_s *indirect_head; FAR struct mac802154_trans_s *indirect_tail; - FAR struct mac802154_trans_s *active_trans; /* MAC PIB attributes, grouped to save memory */ @@ -203,32 +227,6 @@ struct ieee802154_privmac_s /* TODO: Add Security-related MAC PIB attributes */ }; -struct mac802154_trans_s -{ - /* Supports a singly linked list */ - - FAR struct mac802154_trans_s *flink; - - uint8_t msdu_handle; - - uint8_t *mhr_buf; - uint8_t mhr_len; - - uint8_t *d_buf; - uint8_t d_len; - - sem_t sem; -}; - -struct mac802154_unsec_mhr_s -{ - uint8_t length; - union - { - uint16_t frame_control; - uint8_t data[IEEE802154_MAX_UNSEC_MHR_OVERHEAD]; - }; -}; /**************************************************************************** * Private Data @@ -563,7 +561,7 @@ int mac802154_req_data(MACHANDLE mac, FAR struct ieee802154_data_req_s *req) } } - /* Set the source addr mode inside the frame contorl field */ + /* Set the source addr mode inside the frame control field */ mhr.frame_ctrl |= (req->src_addr_mode << IEEE802154_FRAMECTRL_SHIFT_SADDR); @@ -658,7 +656,7 @@ int mac802154_req_data(MACHANDLE mac, FAR struct ieee802154_data_req_s *req) /* Notify the radio driver that there is data available */ - priv->radio->tx_notify(priv->radio); + priv->radio->ops->tx_notify(priv->radio); sem_wait(&trans->sem); } @@ -712,6 +710,13 @@ static uint16_t mac802154_poll_csma(FAR struct ieee802154_phyif_s *phyif, return 0; } +static uint16_t mac802154_poll_gts(FAR struct ieee802154_phyif_s *phyif, + FAR struct ieee802154_txdesc_s *tx_desc, + uint8_t *buf) +{ + return 0; +} + /**************************************************************************** * Name: mac802154_req_purge *