| /* |
| * Copyright (c) 2017, The OpenThread Authors. |
| * All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions are met: |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution. |
| * 3. Neither the name of the copyright holder nor the |
| * names of its contributors may be used to endorse or promote products |
| * derived from this software without specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
| * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE |
| * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| * POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| /** |
| * @file |
| * This file implements the OpenThread platform abstraction for radio communication. |
| * |
| */ |
| |
| #include "openthread/types.h" |
| |
| #include <utils/code_utils.h> |
| #include "openthread/platform/radio.h" |
| #include "platform-emsk.h" |
| |
| #include "device/device_hal/inc/dev_gpio.h" |
| #include <string.h> |
| |
| #include <stdio.h> |
| #define DBG(fmt, ...) printf(fmt, ##__VA_ARGS__) |
| |
| enum |
| { |
| IEEE802154_MIN_LENGTH = 5, |
| IEEE802154_MAX_LENGTH = 127, |
| IEEE802154_ACK_LENGTH = 5, |
| |
| IEEE802154_BROADCAST = 0xffff, |
| |
| IEEE802154_FRAME_TYPE_ACK = 2 << 0, |
| IEEE802154_FRAME_TYPE_MACCMD = 3 << 0, |
| IEEE802154_FRAME_TYPE_MASK = 7 << 0, |
| |
| IEEE802154_SECURITY_ENABLED = 1 << 3, |
| IEEE802154_FRAME_PENDING = 1 << 4, |
| IEEE802154_ACK_REQUEST = 1 << 5, |
| IEEE802154_PANID_COMPRESSION = 1 << 6, |
| |
| IEEE802154_DST_ADDR_NONE = 0 << 2, |
| IEEE802154_DST_ADDR_SHORT = 2 << 2, |
| IEEE802154_DST_ADDR_EXT = 3 << 2, |
| IEEE802154_DST_ADDR_MASK = 3 << 2, |
| |
| IEEE802154_SRC_ADDR_NONE = 0 << 6, |
| IEEE802154_SRC_ADDR_SHORT = 2 << 6, |
| IEEE802154_SRC_ADDR_EXT = 3 << 6, |
| IEEE802154_SRC_ADDR_MASK = 3 << 6, |
| |
| IEEE802154_DSN_OFFSET = 2, |
| IEEE802154_DSTPAN_OFFSET = 3, |
| IEEE802154_DSTADDR_OFFSET = 5, |
| |
| IEEE802154_SEC_LEVEL_MASK = 7 << 0, |
| |
| IEEE802154_KEY_ID_MODE_0 = 0 << 3, |
| IEEE802154_KEY_ID_MODE_1 = 1 << 3, |
| IEEE802154_KEY_ID_MODE_2 = 2 << 3, |
| IEEE802154_KEY_ID_MODE_3 = 3 << 3, |
| IEEE802154_KEY_ID_MODE_MASK = 3 << 3, |
| |
| IEEE802154_MACCMD_DATA_REQ = 4 |
| }; |
| |
| enum |
| { |
| EMSK_RECEIVE_SENSITIVITY = -100, // dBm |
| }; |
| |
| enum |
| { |
| MRF24J40_RSSI_OFFSET = 90, |
| MRF24J40_RSSI_SLOPE = 5 |
| }; |
| |
| static void radioTransmitMessage(otInstance *aInstance); |
| |
| static otRadioFrame sTransmitFrame; |
| static otRadioFrame sReceiveFrame; |
| static otRadioFrame sAckFrame; |
| |
| static otError sTransmitError; |
| static otError sReceiveError; |
| |
| static uint8_t sTransmitPsdu[IEEE802154_MAX_LENGTH]; |
| static uint8_t sReceivePsdu[IEEE802154_MAX_LENGTH]; |
| static uint8_t sAckPsdu[IEEE802154_MAX_LENGTH]; |
| |
| static otRadioState sState = OT_RADIO_STATE_DISABLED; |
| static bool sIsReceiverEnabled = false; |
| |
| static volatile uint8_t Mrf24StatusTx = 0; |
| static volatile uint8_t Mrf24StatusRx = 0; |
| static volatile uint8_t Mrf24StatusSec = 0; |
| |
| static DEV_SPI_PTR pmrf_spi_ptr; |
| static DEV_GPIO_PTR pmrf_gpio_ptr; |
| static void RadioIsr(void *ptr); |
| |
| /* Variables for test */ |
| static uint32_t numInterruptRev = 0; |
| static uint32_t numInterruptTrans = 0; |
| static uint32_t numRadioProcess = 0; |
| |
| static inline bool isSecurityEnabled(const uint8_t *frame) |
| { |
| return (frame[0] & IEEE802154_SECURITY_ENABLED) != 0; |
| } |
| |
| static inline bool isAckRequested(const uint8_t *frame) |
| { |
| return (frame[0] & IEEE802154_ACK_REQUEST) != 0; |
| } |
| |
| static inline bool isPanIdCompressed(const uint8_t *frame) |
| { |
| return (frame[0] & IEEE802154_PANID_COMPRESSION) != 0; |
| } |
| |
| static inline uint8_t getHeadLength(const uint8_t *frame) |
| { |
| uint8_t length = 0; |
| /* Frame Control-2 + Sequence Number-1 */ |
| length += 2 + 1; |
| |
| /* Destination PAN + Address */ |
| switch (frame[1] & IEEE802154_DST_ADDR_MASK) |
| { |
| case IEEE802154_DST_ADDR_SHORT: |
| length += sizeof(otPanId) + sizeof(otShortAddress); |
| break; |
| |
| case IEEE802154_DST_ADDR_EXT: |
| length += sizeof(otPanId) + sizeof(otExtAddress); |
| break; |
| |
| default: |
| length = 0; |
| goto exit; |
| } |
| |
| /* Source PAN + Address */ |
| switch (frame[1] & IEEE802154_SRC_ADDR_MASK) |
| { |
| case IEEE802154_SRC_ADDR_SHORT: |
| if (!isPanIdCompressed(frame)) |
| { |
| length += sizeof(otPanId); |
| } |
| |
| length += sizeof(otShortAddress); |
| break; |
| |
| case IEEE802154_SRC_ADDR_EXT: |
| if (!isPanIdCompressed(frame)) |
| { |
| length += sizeof(otPanId); |
| } |
| |
| length += sizeof(otExtAddress); |
| break; |
| |
| default: |
| length = 0; |
| goto exit; |
| } |
| |
| exit: |
| return length; |
| } |
| |
| void enableReceiver(void) |
| { |
| if (!sIsReceiverEnabled) |
| { |
| mrf24j40_rxfifo_flush(); |
| /* add code to enable receiver (wakeup) */ |
| sIsReceiverEnabled = true; |
| } |
| } |
| |
| void disableReceiver(void) |
| { |
| if (sIsReceiverEnabled) |
| { |
| mrf24j40_rxfifo_flush(); |
| /* add code to disable receiver (sleep) */ |
| sIsReceiverEnabled = false; |
| } |
| } |
| |
| void setChannel(uint8_t channel) |
| { |
| mrf24j40_set_channel((int16_t)(channel - 11)); |
| } |
| |
| void otPlatRadioGetIeeeEui64(otInstance *aInstance, uint8_t *aIeeeEui64) |
| { |
| (void)aInstance; |
| /* should set it manually or preset it in memory */ |
| aIeeeEui64[0] = 0x00; |
| aIeeeEui64[1] = 0x50; |
| aIeeeEui64[2] = 0xC2; |
| aIeeeEui64[3] = 0xFF; |
| aIeeeEui64[4] = 0XFE; |
| aIeeeEui64[5] = 0X1D; |
| aIeeeEui64[6] = 0X30; |
| aIeeeEui64[7] = 0x00; |
| } |
| |
| void otPlatRadioSetPanId(otInstance *aInstance, uint16_t panid) |
| { |
| (void)aInstance; |
| uint8_t pan[2]; |
| |
| pan[0] = (uint8_t)(panid & 0xFF); |
| pan[1] = (uint8_t)(panid >> 8); |
| mrf24j40_set_pan(pan); |
| } |
| |
| void otPlatRadioSetExtendedAddress(otInstance *aInstance, uint8_t *address) |
| { |
| (void)aInstance; |
| mrf24j40_set_eui(address); |
| } |
| |
| void otPlatRadioSetShortAddress(otInstance *aInstance, uint16_t address) |
| { |
| (void)aInstance; |
| uint8_t addr[2]; |
| |
| addr[0] = (uint8_t)(address & 0xFF); |
| addr[1] = (uint8_t)(address >> 8); |
| mrf24j40_set_short_addr(addr); |
| } |
| |
| void emskRadioInit(void) |
| { |
| DEV_GPIO_BIT_ISR isr; |
| DEV_GPIO_INT_CFG int_cfg; |
| |
| int32_t ercd; |
| uint32_t temp; |
| |
| sTransmitFrame.mLength = 0; |
| sTransmitFrame.mPsdu = sTransmitPsdu; |
| sReceiveFrame.mLength = 0; |
| sReceiveFrame.mPsdu = sReceivePsdu; |
| sAckFrame.mLength = 0; |
| sAckFrame.mPsdu = sAckPsdu; |
| |
| pmrf_spi_ptr = spi_get_dev(EMSK_PMRF_0_SPI_ID); |
| ercd = pmrf_spi_ptr->spi_open(DEV_MASTER_MODE, EMSK_PMRF_0_SPIFREQ); |
| |
| if ((ercd != E_OK) && (ercd != E_OPNED)) |
| { |
| DBG("PmodRF2 SPI open error\r\n"); |
| } |
| |
| pmrf_spi_ptr->spi_control(SPI_CMD_SET_CLK_MODE, CONV2VOID(EMSK_PMRF_0_SPICLKMODE)); |
| |
| /*MRF24J40 wakepin:output, rstpin:output, INT_PIN:input, interrupt */ |
| pmrf_gpio_ptr = gpio_get_dev(EMSK_PMRF_0_GPIO_ID); |
| ercd = pmrf_gpio_ptr->gpio_open(MRF24J40_WAKE_PIN | MRF24J40_RST_PIN); |
| |
| if ((ercd != E_OK) && (ercd != E_OPNED)) |
| { |
| DBG("PmodRF2 CRTL port open error"); |
| } |
| |
| if (ercd == E_OPNED) |
| { |
| pmrf_gpio_ptr->gpio_control(GPIO_CMD_SET_BIT_DIR_OUTPUT, (void *)(MRF24J40_WAKE_PIN | MRF24J40_RST_PIN)); |
| pmrf_gpio_ptr->gpio_control(GPIO_CMD_SET_BIT_DIR_INPUT, (void *)MRF24J40_INT_PIN); |
| } |
| |
| pmrf_gpio_ptr->gpio_control(GPIO_CMD_DIS_BIT_INT, (void *)MRF24J40_INT_PIN); |
| |
| temp = MRF24J40_INT_PIN; |
| int_cfg.int_bit_mask = temp; |
| int_cfg.int_bit_type = GPIO_INT_BITS_EDGE_TRIG(temp); |
| int_cfg.int_bit_polarity = GPIO_INT_BITS_POL_FALL_EDGE(temp); |
| int_cfg.int_bit_debounce = GPIO_INT_BITS_DIS_DEBOUNCE(temp); |
| pmrf_gpio_ptr->gpio_control(GPIO_CMD_SET_BIT_INT_CFG, (void *)(&int_cfg)); |
| |
| isr.int_bit_ofs = MRF24J40_INT_PIN_OFS; |
| isr.int_bit_handler = RadioIsr; |
| pmrf_gpio_ptr->gpio_control(GPIO_CMD_SET_BIT_ISR, (void *)(&isr)); |
| |
| /* interrupt for mrf24j40 is enabled at the end of the init process */ |
| DBG("MRF24J40 Init Started\r\n"); |
| mrf24j40_initialize(); |
| DBG("MRF24J40 Init Finished\r\n"); |
| |
| pmrf_gpio_ptr->gpio_control(GPIO_CMD_ENA_BIT_INT, (void *)MRF24J40_INT_PIN); |
| |
| } |
| |
| bool otPlatRadioIsEnabled(otInstance *aInstance) |
| { |
| (void)aInstance; |
| return (sState != OT_RADIO_STATE_DISABLED); |
| } |
| |
| otError otPlatRadioEnable(otInstance *aInstance) |
| { |
| if (!otPlatRadioIsEnabled(aInstance)) |
| { |
| sState = OT_RADIO_STATE_SLEEP; |
| } |
| |
| return OT_ERROR_NONE; |
| } |
| |
| otError otPlatRadioDisable(otInstance *aInstance) |
| { |
| if (otPlatRadioIsEnabled(aInstance)) |
| { |
| sState = OT_RADIO_STATE_DISABLED; |
| } |
| |
| return OT_ERROR_NONE; |
| } |
| |
| otError otPlatRadioSleep(otInstance *aInstance) |
| { |
| otError error = OT_ERROR_INVALID_STATE; |
| (void)aInstance; |
| |
| if (sState == OT_RADIO_STATE_SLEEP || sState == OT_RADIO_STATE_RECEIVE) |
| { |
| error = OT_ERROR_NONE; |
| sState = OT_RADIO_STATE_SLEEP; |
| disableReceiver(); |
| } |
| |
| return error; |
| } |
| |
| otError otPlatRadioReceive(otInstance *aInstance, uint8_t aChannel) |
| { |
| otError error = OT_ERROR_INVALID_STATE; |
| (void)aInstance; |
| |
| if (sState != OT_RADIO_STATE_DISABLED) |
| { |
| error = OT_ERROR_NONE; |
| sState = OT_RADIO_STATE_RECEIVE; |
| setChannel(aChannel); |
| sReceiveFrame.mChannel = aChannel; |
| enableReceiver(); |
| } |
| |
| return error; |
| } |
| |
| otError otPlatRadioTransmit(otInstance *aInstance, otRadioFrame *aFrame) |
| { |
| otError error = OT_ERROR_INVALID_STATE; |
| (void)aInstance; |
| (void)aFrame; |
| |
| if (sState == OT_RADIO_STATE_RECEIVE) |
| { |
| error = OT_ERROR_NONE; |
| sState = OT_RADIO_STATE_TRANSMIT; |
| } |
| |
| return error; |
| |
| } |
| |
| otRadioFrame *otPlatRadioGetTransmitBuffer(otInstance *aInstance) |
| { |
| (void)aInstance; |
| return &sTransmitFrame; |
| } |
| |
| int8_t otPlatRadioGetRssi(otInstance *aInstance) |
| { |
| (void)aInstance; |
| return 0; |
| } |
| |
| otRadioCaps otPlatRadioGetCaps(otInstance *aInstance) |
| { |
| (void)aInstance; |
| return OT_RADIO_CAPS_NONE; |
| } |
| |
| bool otPlatRadioGetPromiscuous(otInstance *aInstance) |
| { |
| (void)aInstance; |
| return (bool)(mrf24j40_read_short_ctrl_reg(MRF24J40_RXMCR) & MRF24J40_PROMI); |
| } |
| |
| // should be checked again with CC2538 |
| void otPlatRadioSetPromiscuous(otInstance *aInstance, bool aEnable) |
| { |
| (void)aInstance; |
| mrf24j40_set_promiscuous(~aEnable); |
| } |
| |
| void readFrame(void) |
| { |
| |
| /* readBuffer |
| * 1 bit -- 5 to 127 bits -- 1 bit -- 1bit |
| * Frame Length -- PSDU (Header + Data Payload + FCS) -- LQI -- RSSI |
| */ |
| uint8_t readBuffer[MRF24J40_RXFIFO_SIZE]; |
| uint8_t readPlqi = 0; |
| uint8_t readRssi = 0; |
| |
| uint16_t length; |
| int16_t i; |
| |
| memset(readBuffer, 0, MRF24J40_RXFIFO_SIZE); |
| |
| otEXPECT_ACTION(sState == OT_RADIO_STATE_RECEIVE || sState == OT_RADIO_STATE_TRANSMIT, ;); |
| otEXPECT_ACTION(Mrf24StatusRx, ;); |
| |
| if (Mrf24StatusRx == 1) |
| { |
| Mrf24StatusRx = 0; |
| } |
| |
| if (Mrf24StatusSec == 1) |
| { |
| Mrf24StatusSec = 0; |
| } |
| |
| /* Read length */ |
| length = (uint16_t)mrf24j40_rxpkt_intcb(readBuffer, &readPlqi, &readRssi); |
| |
| otEXPECT_ACTION(IEEE802154_MIN_LENGTH <= length && length <= IEEE802154_MAX_LENGTH, ;); |
| |
| /* Read PSDU */ |
| memcpy(sReceiveFrame.mPsdu, readBuffer, length - 2); |
| |
| sReceiveFrame.mPower = (int8_t)(readRssi / MRF24J40_RSSI_SLOPE) - MRF24J40_RSSI_OFFSET; |
| sReceiveFrame.mLength = (uint8_t) length; |
| sReceiveFrame.mLqi = readPlqi; |
| |
| exit: |
| return; |
| |
| } |
| |
| void radioTransmitMessage(otInstance *aInstance) |
| { |
| (void)aInstance; |
| uint8_t header_len = 0; |
| |
| sTransmitError = OT_ERROR_NONE; |
| setChannel(sTransmitFrame.mChannel); |
| |
| uint8_t reg = mrf24j40_read_short_ctrl_reg(MRF24J40_TXNCON); |
| |
| header_len = getHeadLength(sTransmitFrame.mPsdu); |
| |
| if (isAckRequested(sTransmitFrame.mPsdu)) |
| { |
| reg |= MRF24J40_TXNACKREQ; |
| } |
| else |
| { |
| reg &= ~(MRF24J40_TXNACKREQ); |
| } |
| |
| if (isSecurityEnabled(sTransmitFrame.mPsdu)) |
| { |
| reg |= MRF24J40_TXNSECEN; |
| } |
| else |
| { |
| reg &= ~(MRF24J40_TXNSECEN); |
| mrf24j40_write_short_ctrl_reg(MRF24J40_TXNCON, mrf24j40_read_short_ctrl_reg(MRF24J40_TXNCON) & (~MRF24J40_TXNSECEN)); |
| } |
| |
| mrf24j40_txfifo_write(MRF24J40_TXNFIFO, sTransmitFrame.mPsdu, header_len, (sTransmitFrame.mLength - 2)); |
| |
| mrf24j40_write_short_ctrl_reg(MRF24J40_TXNCON, reg | MRF24J40_TXNTRIG); |
| |
| int16_t tx_timeout = 500; |
| Mrf24StatusTx = 0; |
| |
| while ((tx_timeout > 0) && (Mrf24StatusTx != 1)) |
| { |
| mrf24j40_delay_ms(1); |
| tx_timeout--; |
| |
| if (tx_timeout <= 0) |
| { |
| DBG("Radio Transmit Timeout!!!!!!!!!!!!\r\n"); |
| } |
| } |
| } |
| |
| void emskRadioProcess(otInstance *aInstance) |
| { |
| numRadioProcess++; |
| |
| readFrame(); |
| uint8_t reg = mrf24j40_read_short_ctrl_reg(MRF24J40_TXSTAT); |
| |
| if (reg & MRF24J40_TXNSTAT) |
| { |
| DBG("TX MAC Timeout!!!!!!\r\n"); |
| |
| if (reg & MRF24J40_CCAFAIL) |
| { |
| DBG("Channel busy!!!!!!\r\n"); |
| } |
| } |
| |
| if ((sState == OT_RADIO_STATE_RECEIVE) && (sReceiveFrame.mLength > 0)) |
| { |
| otPlatRadioReceiveDone(aInstance, &sReceiveFrame, sReceiveError); |
| } |
| |
| if (sState == OT_RADIO_STATE_TRANSMIT) |
| { |
| radioTransmitMessage(aInstance); |
| |
| if (sTransmitError != OT_ERROR_NONE || (sTransmitFrame.mPsdu[0] & IEEE802154_ACK_REQUEST) == 0) |
| { |
| sState = OT_RADIO_STATE_RECEIVE; |
| otPlatRadioTxDone(aInstance, &sTransmitFrame, NULL, sTransmitError); |
| } |
| else if (Mrf24StatusTx == 1) |
| { |
| Mrf24StatusTx = 0; |
| sState = OT_RADIO_STATE_RECEIVE; |
| otPlatRadioTxDone(aInstance, &sTransmitFrame, &sReceiveFrame, sTransmitError); |
| } |
| } |
| |
| sReceiveFrame.mLength = 0; |
| |
| } |
| |
| /** |
| * \brief isr routine of mrf24j40 |
| * \param[in] ptr pointer transferred frome interrupt entry |
| */ |
| static void RadioIsr(void *ptr) |
| { |
| uint8_t int_status = 0; |
| |
| int_status = pmrf_read_short_ctrl_reg(MRF24J40_INTSTAT); |
| |
| /* a frame is received */ |
| if (int_status & MRF24J40_RXIF) |
| { |
| numInterruptRev++; |
| Mrf24StatusRx = 1; |
| } |
| |
| /* a frame is transmitted */ |
| if (int_status & MRF24J40_TXNIF) |
| { |
| switch (mrf24j40_txpkt_intcb()) |
| { |
| case MRF24J40_EBUSY: |
| /* Channel busy */ |
| break; |
| |
| case MRF24J40_EIO: |
| /* Channel idle */ |
| break; |
| |
| case 0: |
| numInterruptTrans++; |
| Mrf24StatusTx = 1; |
| break; |
| } |
| } |
| |
| /* a frame with security key request is received */ |
| if (int_status & MRF24J40_SECIF) |
| { |
| Mrf24StatusSec = 1; |
| mrf24j40_sec_intcb(false); |
| } |
| |
| } |
| |
| /* CC2538 supports source address matching for low power consumption |
| and this is not supported in MRF24J40 */ |
| void otPlatRadioEnableSrcMatch(otInstance *aInstance, bool aEnable) |
| { |
| (void)aInstance; |
| (void)aEnable; |
| } |
| |
| otError otPlatRadioAddSrcMatchShortEntry(otInstance *aInstance, const uint16_t aShortAddress) |
| { |
| (void)aInstance; |
| (void)aShortAddress; |
| return OT_ERROR_NONE; |
| } |
| |
| otError otPlatRadioAddSrcMatchExtEntry(otInstance *aInstance, const uint8_t *aExtAddress) |
| { |
| (void)aInstance; |
| (void)aExtAddress; |
| return OT_ERROR_NONE; |
| } |
| |
| otError otPlatRadioClearSrcMatchShortEntry(otInstance *aInstance, const uint16_t aShortAddress) |
| { |
| (void)aInstance; |
| (void)aShortAddress; |
| return OT_ERROR_NONE; |
| } |
| |
| otError otPlatRadioClearSrcMatchExtEntry(otInstance *aInstance, const uint8_t *aExtAddress) |
| { |
| (void)aInstance; |
| (void)aExtAddress; |
| return OT_ERROR_NONE; |
| } |
| |
| void otPlatRadioClearSrcMatchShortEntries(otInstance *aInstance) |
| { |
| (void)aInstance; |
| } |
| |
| void otPlatRadioClearSrcMatchExtEntries(otInstance *aInstance) |
| { |
| (void)aInstance; |
| } |
| |
| otError otPlatRadioEnergyScan(otInstance *aInstance, uint8_t aScanChannel, uint16_t aScanDuration) |
| { |
| (void)aInstance; |
| (void)aScanChannel; |
| (void)aScanDuration; |
| return OT_ERROR_NOT_IMPLEMENTED; |
| } |
| |
| void otPlatRadioSetDefaultTxPower(otInstance *aInstance, int8_t aPower) |
| { |
| // TODO: Create a proper implementation for this driver. |
| (void)aInstance; |
| (void)aPower; |
| } |
| |
| int8_t otPlatRadioGetReceiveSensitivity(otInstance *aInstance) |
| { |
| (void)aInstance; |
| return EMSK_RECEIVE_SENSITIVITY; |
| } |