mirror of https://github.com/ARMmbed/mbed-os.git
Squashed 'connectivity/drivers/802.15.4_RF/stm-s2lp-rf-driver/' content from commit f491d77de8
git-subtree-dir: connectivity/drivers/802.15.4_RF/stm-s2lp-rf-driver git-subtree-split: f491d77de847cd5358d53b5b4d975cb0d68d11f3pull/14816/head
commit
92e35b3a27
|
@ -0,0 +1,11 @@
|
|||
# Example RF driver for STM 802.15.4 transceivers #
|
||||
|
||||
Support for:
|
||||
* S2-LP
|
||||
|
||||
This driver is used with 6LoWPAN and Wi-SUN stacks.
|
||||
|
||||
Driver is tested with X-Nucleo-S2868A1 RF expansion board. https://www.st.com/en/ecosystems/x-nucleo-s2868a1.html
|
||||
|
||||
NOTE: Default SPI SCLK pin configuration is D13. On X-Nucleo-S2868A1, resistor R6 must be soldered instead of R11. For more information, see user manual UM2405. https://www.st.com/resource/en/user_manual/dm00498153.pdf
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
{
|
||||
"name": "s2lp",
|
||||
"config": {
|
||||
"SPI_SDI": {
|
||||
"help": "SPI_SDI pin for SPI connection. D11 assumed, needs to be set/overwritten otherwise",
|
||||
"value": null
|
||||
},
|
||||
"SPI_SDO": {
|
||||
"help": "SPI_SDO pin for SPI connection. D12 assumed, needs to be set/overwritten otherwise",
|
||||
"value": null
|
||||
},
|
||||
"SPI_SCLK": {
|
||||
"help": "SPI_SCLK pin for SPI connection, D13 assumed, needs to be set/overwritten otherwise",
|
||||
"value": null
|
||||
},
|
||||
"SPI_CS": {
|
||||
"help": "SPI_CS pin for SPI connection, A1 assumed, needs to be set/overwritten otherwise",
|
||||
"value": null
|
||||
},
|
||||
"SPI_SDN": {
|
||||
"help": "SPI_SDN pin for SPI connection, D7 assumed, needs to be set/overwritten otherwise",
|
||||
"value": null
|
||||
},
|
||||
"TEST_PIN_TX": {
|
||||
"help": "TEST_PIN_TX pin for serial connection, D6 assumed, needs to be set/overwritten otherwise",
|
||||
"value": null
|
||||
},
|
||||
"TEST_PIN_RX": {
|
||||
"help": "TEST_PIN_RX pin for serial connection, D5 assumed, needs to be set/overwritten otherwise",
|
||||
"value": null
|
||||
},
|
||||
"TEST_PIN_CSMA": {
|
||||
"help": "TEST_PIN_CSMA pin for CSMA, D4 assumed, needs to be set/overwritten otherwise",
|
||||
"value": null
|
||||
},
|
||||
"TEST_PIN_SPARE_1": {
|
||||
"help": "TEST_PIN_SPARE_1 pin for testing, D2 assumed, needs to be set/overwritten otherwise",
|
||||
"value": null
|
||||
},
|
||||
"TEST_PIN_SPARE_2": {
|
||||
"help": "TEST_PIN_SPARE_2 pin for testing, D8 assumed, needs to be set/overwritten otherwise",
|
||||
"value": null
|
||||
},
|
||||
"SPI_GPIO0": {
|
||||
"help": "SPI_GPIO0 pin for GPIO testing, A0 assumed, needs to be set/overwritten otherwise",
|
||||
"value": null
|
||||
},
|
||||
"SPI_GPIO1": {
|
||||
"help": "SPI_GPIO1 pin for GPIO testing, A2 assumed, needs to be set/overwritten otherwise",
|
||||
"value": null
|
||||
},
|
||||
"SPI_GPIO2": {
|
||||
"help": "SPI_GPIO2 pin for GPIO testing, A3 assumed, needs to be set/overwritten otherwise",
|
||||
"value": null
|
||||
},
|
||||
"SPI_GPIO3": {
|
||||
"help": "SPI_GPIO3 pin for GPIO testing, A5 assumed, needs to be set/overwritten otherwise",
|
||||
"value": null
|
||||
},
|
||||
"I2C_SDA": {
|
||||
"help": "I2C_SDA pin for I2C SDA, null assumed, needs to be set/overwritten otherwise",
|
||||
"value": null
|
||||
},
|
||||
"I2C_SCL": {
|
||||
"help": "I2C_SCL pin for I2C SCL, null assumed, needs to be set/overwritten otherwise",
|
||||
"value": null
|
||||
},
|
||||
"provide-default": {
|
||||
"help": "Provide default NanostackRfpy. [true/false]",
|
||||
"value": false
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* Copyright (c) 2019, Pelion and affiliates.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "NanostackRfPhys2lp.h"
|
||||
#include "at24mac_s2lp.h"
|
||||
|
||||
|
||||
#if DEVICE_I2C
|
||||
#ifdef AT24MAC
|
||||
|
||||
/* Device addressing */
|
||||
#define AT24MAC_EEPROM_ADDRESS (0x0A<<4)
|
||||
#define AT24MAC_RW_PROTECT_ADDRESS (0x06<<4)
|
||||
#define AT24MAC_SERIAL_ADDRESS (0x0B<<4)
|
||||
|
||||
/* Known memory blocks */
|
||||
#define AT24MAC_SERIAL_OFFSET (0x80)
|
||||
#define AT24MAC_EUI64_OFFSET (0x98)
|
||||
#define AT24MAC_EUI48_OFFSET (0x9A)
|
||||
|
||||
#define SERIAL_LEN 16
|
||||
#define EUI64_LEN 8
|
||||
#define EUI48_LEN 6
|
||||
|
||||
using namespace mbed;
|
||||
|
||||
AT24Mac_s2lp::AT24Mac_s2lp(PinName sda, PinName scl) : _i2c(sda, scl)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
int AT24Mac_s2lp::read_serial(void *buf)
|
||||
{
|
||||
char offset = AT24MAC_SERIAL_OFFSET;
|
||||
if (_i2c.write(AT24MAC_SERIAL_ADDRESS, &offset, 1, true)) {
|
||||
return -1; //No ACK
|
||||
}
|
||||
return _i2c.read(AT24MAC_SERIAL_ADDRESS, (char *)buf, SERIAL_LEN);
|
||||
}
|
||||
|
||||
int AT24Mac_s2lp::read_eui64(void *buf)
|
||||
{
|
||||
char offset = AT24MAC_EUI64_OFFSET;
|
||||
if (_i2c.write(AT24MAC_SERIAL_ADDRESS, &offset, 1, true)) {
|
||||
return -1; //No ACK
|
||||
}
|
||||
return _i2c.read(AT24MAC_SERIAL_ADDRESS, (char *)buf, EUI64_LEN);
|
||||
}
|
||||
|
||||
int AT24Mac_s2lp::read_eui48(void *buf)
|
||||
{
|
||||
char offset = AT24MAC_EUI48_OFFSET;
|
||||
if (_i2c.write(AT24MAC_SERIAL_ADDRESS, &offset, 1, true)) {
|
||||
return -1; //No ACK
|
||||
}
|
||||
return _i2c.read(AT24MAC_SERIAL_ADDRESS, (char *)buf, EUI48_LEN);
|
||||
}
|
||||
|
||||
#endif /* AT24MAC */
|
||||
#endif /* DEVICE_I2C */
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* Copyright (c) 2019, Pelion and affiliates.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef AT24MAC_S2LP_H
|
||||
#define AT24MAC_S2LP_H
|
||||
|
||||
#include "PinNames.h"
|
||||
|
||||
#if DEVICE_I2C
|
||||
#ifdef AT24MAC
|
||||
|
||||
#include "I2C.h"
|
||||
#include "drivers/DigitalInOut.h"
|
||||
#include "platform/mbed_wait_api.h"
|
||||
|
||||
/*
|
||||
* AT24MAC drivers.
|
||||
*
|
||||
* This is a EEPROM chip designed to contain factory programmed read-only EUI-64 or EUI-48,
|
||||
* a 128bit serial number and some user programmable EEPROM.
|
||||
*
|
||||
* AT24MAC602 contains EUI-64, use read_eui64()
|
||||
* AT24MAC402 contains EUI-64, use read_eui48()
|
||||
*
|
||||
* NOTE: You cannot use both EUI-64 and EUI-48. Chip contains only one of those.
|
||||
*/
|
||||
|
||||
class AT24Mac_s2lp {
|
||||
public:
|
||||
AT24Mac_s2lp(PinName sda, PinName scl);
|
||||
|
||||
/**
|
||||
* Read unique serial number from chip.
|
||||
* \param buf pointer to write serial number to. Must have space for 16 bytes.
|
||||
* \return zero on success, negative number on failure
|
||||
*/
|
||||
int read_serial(void *buf);
|
||||
|
||||
/**
|
||||
* Read EUI-64 from chip.
|
||||
* \param buf pointer to write EUI-64 to. Must have space for 8 bytes.
|
||||
* \return zero on success, negative number on failure
|
||||
*/
|
||||
int read_eui64(void *buf);
|
||||
|
||||
/**
|
||||
* Read EUI-48 from chip.
|
||||
* \param buf pointer to write EUI-48 to. Must have space for 6 bytes.
|
||||
* \return zero on success, negative number on failure
|
||||
*/
|
||||
int read_eui48(void *buf);
|
||||
|
||||
private:
|
||||
mbed::I2C _i2c;
|
||||
};
|
||||
|
||||
#endif /* AT24MAC */
|
||||
#endif /* DEVICE_I2C */
|
||||
#endif /* AT24MAC_S2LP_H */
|
|
@ -0,0 +1,186 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Pelion and affiliates.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#if defined(MBED_CONF_NANOSTACK_CONFIGURATION) && DEVICE_SPI && DEVICE_INTERRUPTIN && defined(MBED_CONF_RTOS_PRESENT)
|
||||
|
||||
#include "nanostack/platform/arm_hal_phy.h"
|
||||
#include "rf_configuration.h"
|
||||
|
||||
|
||||
// Note that F_XO and F_DIG depends on the used clock frequency
|
||||
#define F_XO 50000000
|
||||
#define F_DIG 25000000
|
||||
// Note that reference divider depends on REFDIV field in XO_RCO_CONF0 register
|
||||
#define REF_DIVIDER 1
|
||||
// Note that band selector depends on BS field in SYNT3 register
|
||||
#define BAND_SELECTOR 4
|
||||
#define DEF_2EXP33 8589934592
|
||||
#define DEF_2EXP20 1048576
|
||||
#define DEF_2EXP19 524288
|
||||
#define DEF_2EXP16 65536
|
||||
#define DEF_2EXP15 32768
|
||||
// Use multiplier for better resolution
|
||||
#define RESOLUTION_MULTIPLIER 1000000
|
||||
|
||||
// RSSI_TH is a 8-bit register which can be converted to dBm using formula RSSI_TH-146
|
||||
#define MIN_RSSI_THRESHOLD -146
|
||||
#define MAX_RSSI_THRESHOLD 109
|
||||
|
||||
void rf_conf_calculate_datarate_registers(uint32_t datarate, uint16_t *datarate_mantissa, uint8_t *datarate_exponent)
|
||||
{
|
||||
uint64_t datarate_m = (uint64_t)datarate * DEF_2EXP33;
|
||||
uint8_t datarate_e = 1;
|
||||
while (datarate_m >= DEF_2EXP16) {
|
||||
datarate_e++;
|
||||
uint16_t var_2exp_datarate_e = (uint32_t)2 << (datarate_e - 1);
|
||||
datarate_m = (uint64_t)datarate * DEF_2EXP33;
|
||||
datarate_m = datarate_m / ((uint64_t)var_2exp_datarate_e * F_DIG);
|
||||
datarate_m -= DEF_2EXP16;
|
||||
}
|
||||
*datarate_mantissa = datarate_m;
|
||||
*datarate_exponent = datarate_e;
|
||||
}
|
||||
|
||||
void rf_conf_calculate_base_frequency_registers(uint32_t frequency, uint8_t *synt3, uint8_t *synt2, uint8_t *synt1, uint8_t *synt0)
|
||||
{
|
||||
uint64_t freq_tmp = (uint64_t)frequency * RESOLUTION_MULTIPLIER;
|
||||
freq_tmp = (freq_tmp / (F_XO / ((BAND_SELECTOR / 2) * REF_DIVIDER)));
|
||||
freq_tmp *= DEF_2EXP20;
|
||||
freq_tmp /= RESOLUTION_MULTIPLIER;
|
||||
*synt3 = (uint8_t)(freq_tmp >> 24);
|
||||
*synt2 = (uint8_t)(freq_tmp >> 16);
|
||||
*synt1 = (uint8_t)(freq_tmp >> 8);
|
||||
*synt0 = (uint8_t)freq_tmp;
|
||||
}
|
||||
|
||||
void rf_conf_calculate_deviation_registers(uint32_t deviation, uint8_t *fdev_m, uint8_t *fdev_e)
|
||||
{
|
||||
uint64_t fdev_m_tmp = 0xffff;
|
||||
uint8_t fdev_e_tmp = 1;
|
||||
|
||||
while (fdev_m_tmp > 255) {
|
||||
fdev_e_tmp++;
|
||||
uint16_t var_2exp_datarate_e_minus_1 = (uint16_t)2 << ((fdev_e_tmp - 1) - 1);
|
||||
fdev_m_tmp = (uint64_t)deviation * RESOLUTION_MULTIPLIER;
|
||||
fdev_m_tmp = (((fdev_m_tmp / F_XO) * DEF_2EXP19 * BAND_SELECTOR * REF_DIVIDER * (8 / BAND_SELECTOR)) / var_2exp_datarate_e_minus_1);
|
||||
fdev_m_tmp += RESOLUTION_MULTIPLIER / 2;
|
||||
fdev_m_tmp /= RESOLUTION_MULTIPLIER;
|
||||
fdev_m_tmp -= 256;
|
||||
}
|
||||
*fdev_m = (uint8_t)fdev_m_tmp;
|
||||
*fdev_e = fdev_e_tmp;
|
||||
}
|
||||
|
||||
int rf_conf_calculate_channel_spacing_registers(uint32_t channel_spacing, uint8_t *ch_space)
|
||||
{
|
||||
uint64_t ch_space_tmp = (uint64_t)channel_spacing * RESOLUTION_MULTIPLIER;
|
||||
ch_space_tmp /= F_XO;
|
||||
ch_space_tmp *= DEF_2EXP15;
|
||||
ch_space_tmp += RESOLUTION_MULTIPLIER / 2;
|
||||
ch_space_tmp /= RESOLUTION_MULTIPLIER;
|
||||
// Check if channel spacing is too high
|
||||
if (ch_space_tmp > 255) {
|
||||
return -1;
|
||||
}
|
||||
*ch_space = (uint8_t)ch_space_tmp;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Note: This function doesn't necessarily give the optimal RX filter settings.
|
||||
* When accurate chflt_m and chflt_e settings are needed they must be computed manually.
|
||||
* Function uses undefined values (900000, 852000, ...)
|
||||
* to find the chflt_m and chflt_e settings from the RX filter table (see. S2-LP datasheet).
|
||||
*
|
||||
* E=0 E=1 E=2 E=3 E=4 E=5 E=6 E=7 E=8 E=9
|
||||
* M=0 800.1 450.9 224.7 112.3 56.1 28.0 14.0 7.0 3.5 1.8
|
||||
* M=1 795.1 425.9 212.4 106.2 53.0 26.5 13.3 6.6 3.3 1.7
|
||||
* M=2 768.4 403.2 201.1 100.5 50.2 25.1 12.6 6.3 3.1 1.6
|
||||
* M=3 736.8 380.8 190.0 95.0 47.4 23.7 11.9 5.9 3.0 1.5
|
||||
* M=4 705.1 362.1 180.7 90.3 45.1 22.6 11.3 5.6 2.8 1.4
|
||||
* M=5 670.9 341.7 170.6 85.3 42.6 21.3 10.6 5.3 2.7 1.3
|
||||
* M=6 642.3 325.4 162.4 81.2 40.6 20.3 10.1 5.1 2.5 1.3
|
||||
* M=7 586.7 294.5 147.1 73.5 36.7 18.4 9.2 4.6 2.3 1.2
|
||||
* M=8 541.4 270.3 135.0 67.5 33.7 16.9 8.4 4.2 2.1 1.1
|
||||
*/
|
||||
void rf_conf_calculate_rx_filter_bandwidth_registers(uint32_t rx_bandwidth, uint8_t *chflt_m, uint8_t *chflt_e)
|
||||
{
|
||||
uint8_t chflt_e_tmp = 0;
|
||||
uint8_t chflt_m_tmp = 0;
|
||||
|
||||
while (rx_bandwidth < 900000u / (2 << chflt_e_tmp)) {
|
||||
chflt_e_tmp++;
|
||||
}
|
||||
uint32_t rx_bandwidth_tmp = rx_bandwidth;
|
||||
if (chflt_e_tmp > 0) {
|
||||
rx_bandwidth_tmp = rx_bandwidth * (2 << (chflt_e_tmp - 1));
|
||||
}
|
||||
if (852000 > rx_bandwidth_tmp) {
|
||||
chflt_m_tmp++;
|
||||
}
|
||||
if (806000 > rx_bandwidth_tmp) {
|
||||
chflt_m_tmp++;
|
||||
}
|
||||
if (760000 > rx_bandwidth_tmp) {
|
||||
chflt_m_tmp++;
|
||||
}
|
||||
if (724000 > rx_bandwidth_tmp) {
|
||||
chflt_m_tmp++;
|
||||
}
|
||||
if (682000 > rx_bandwidth_tmp) {
|
||||
chflt_m_tmp++;
|
||||
}
|
||||
if (650000 > rx_bandwidth_tmp) {
|
||||
chflt_m_tmp++;
|
||||
}
|
||||
if (588000 > rx_bandwidth_tmp) {
|
||||
chflt_m_tmp++;
|
||||
}
|
||||
if (542000 > rx_bandwidth_tmp) {
|
||||
chflt_m_tmp++;
|
||||
}
|
||||
*chflt_m = chflt_m_tmp;
|
||||
*chflt_e = chflt_e_tmp;
|
||||
}
|
||||
|
||||
int16_t rf_conf_cca_threshold_percent_to_rssi(uint8_t percent)
|
||||
{
|
||||
uint8_t step = (MAX_RSSI_THRESHOLD - MIN_RSSI_THRESHOLD);
|
||||
return MIN_RSSI_THRESHOLD + (step * percent) / 100;
|
||||
}
|
||||
|
||||
void rf_conf_calculate_rssi_threshold_registers(int16_t rssi_threshold, uint8_t *rssi_th)
|
||||
{
|
||||
*rssi_th = rssi_threshold + RSSI_OFFSET;
|
||||
}
|
||||
|
||||
/*
|
||||
* Function calculates deviation from given parameters for 2FSK and 2GFSK modulations.
|
||||
* Calculated using formula Deviation=(modulation_index*datarate)/2
|
||||
*/
|
||||
uint32_t rf_conf_calculate_deviation(phy_modulation_index_e modulation_index, uint32_t datarate)
|
||||
{
|
||||
uint32_t deviation = 0;
|
||||
if (modulation_index == MODULATION_INDEX_0_5) {
|
||||
deviation = datarate / 4;
|
||||
} else if (modulation_index == MODULATION_INDEX_1_0) {
|
||||
deviation = datarate / 2;
|
||||
}
|
||||
return deviation;
|
||||
}
|
||||
|
||||
#endif // MBED_CONF_NANOSTACK_CONFIGURATION && DEVICE_SPI && DEVICE_INTERRUPTIN && defined(MBED_CONF_RTOS_PRESENT)
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Pelion and affiliates.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef RF_CONF_H_
|
||||
#define RF_CONF_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define RSSI_OFFSET 146
|
||||
|
||||
void rf_conf_calculate_datarate_registers(uint32_t datarate, uint16_t *datarate_mantissa, uint8_t *datarate_exponent);
|
||||
void rf_conf_calculate_base_frequency_registers(uint32_t frequency, uint8_t *synt3, uint8_t *synt2, uint8_t *synt1, uint8_t *synt0);
|
||||
void rf_conf_calculate_deviation_registers(uint32_t deviation, uint8_t *fdev_m, uint8_t *fdev_e);
|
||||
int rf_conf_calculate_channel_spacing_registers(uint32_t channel_spacing, uint8_t *ch_space);
|
||||
void rf_conf_calculate_rx_filter_bandwidth_registers(uint32_t rx_bandwidth, uint8_t *chflt_m, uint8_t *chflt_e);
|
||||
void rf_conf_calculate_rssi_threshold_registers(int16_t rssi_threshold, uint8_t *rssi_th);
|
||||
uint32_t rf_conf_calculate_deviation(phy_modulation_index_e modulation_index, uint32_t datarate);
|
||||
int16_t rf_conf_cca_threshold_percent_to_rssi(uint8_t percent);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* RF_CONF_H_ */
|
|
@ -0,0 +1,344 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Pelion and affiliates.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef S2LPREG_H_
|
||||
#define S2LPREG_H_
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define RF_MTU 2047
|
||||
#define PARTNUM 0x03
|
||||
#define VERSION 0xC1
|
||||
#define FIFO_SIZE 128
|
||||
#define SPI_HEADER_LENGTH 2
|
||||
#define RSSI_SETTLING_TIME 250
|
||||
|
||||
#define S2LP_GPIO0 0
|
||||
#define S2LP_GPIO1 1
|
||||
#define S2LP_GPIO2 2
|
||||
#define S2LP_GPIO3 3
|
||||
|
||||
// GPIO modes
|
||||
#define DIG_IN 1
|
||||
#define DIG_OUT_LOW 2
|
||||
#define DIG_OUT_HIGH 3
|
||||
|
||||
// Interrupt events
|
||||
#define RX_DATA_READY 0
|
||||
#define RX_DATA_DISCARDED 1
|
||||
#define TX_DATA_SENT 2
|
||||
#define MAX_RE_TX 3
|
||||
#define CRC_ERROR 4
|
||||
#define TX_FIFO_UNF_OVF 5
|
||||
#define RX_FIFO_UNF_OVF 6
|
||||
#define TX_FIFO_ALMOST_FULL 7
|
||||
#define TX_FIFO_ALMOST_EMPTY 8
|
||||
#define RX_FIFO_ALMOST_FULL 9
|
||||
#define RX_FIFO_ALMOST_EMPTY 10
|
||||
#define MAX_CCA_BACKOFFS 11
|
||||
#define VALID_PREAMBLE 12
|
||||
#define SYNC_WORD 13
|
||||
#define RSSI_ABOVE_THR 14
|
||||
#define WAKE_UP_TIMEOUT 15
|
||||
#define READY 16
|
||||
#define STANDBY_SWITCHING 17
|
||||
#define LOW_BATTERY_LVL 18
|
||||
#define POWER_ON_RESET 19
|
||||
#define RX_TIMER_TIMEOUT 28
|
||||
#define SNIFF_TIMER_TIMEOUT 29
|
||||
|
||||
// GPIO signals
|
||||
#define NIRQ 0
|
||||
#define POR 1
|
||||
#define WUT_EXPIRE 2
|
||||
#define LOW_BATTERY 3
|
||||
#define TX_DATA_OUTPUT 4
|
||||
#define TX_STATE 5
|
||||
#define TXRX_FIFO_ALMOST_EMPTY 6
|
||||
#define TXRX_FIFO_ALMOST_FULL 7
|
||||
#define RX_DATA_OUTPUT 8
|
||||
#define RX_CLOCK_OUTPUT 9
|
||||
#define RX_STATE 10
|
||||
#define STATE_OTHER_THAN_SLEEP_OR_STANDBY 11
|
||||
#define STANDBY_STATE 12
|
||||
#define ANTENNA_SWITCH 13
|
||||
#define VALID_PREAMBLE_DETECTED 14
|
||||
#define SYNC_WORD_DETECTED 15
|
||||
#define RSSI_ABOVE_THRESHOLD 16
|
||||
#define TXRX_MODE_INDICATOR 18
|
||||
#define VDD 19
|
||||
#define GND 20
|
||||
#define SMPS_ENABLE 21
|
||||
#define SLEEP_STATE 22
|
||||
#define READY_STATE 23
|
||||
#define LOCK_STATE 24
|
||||
#define WAIT_LOCK_DETECTOR 25
|
||||
#define TX_DATA_OOK 26
|
||||
#define WAIT_READY 27
|
||||
#define WAIT_TIMER_EXPIRATION 28
|
||||
#define END_OF_CALIBRATION 29
|
||||
#define ENABLE_SYNTH_BLOCK 30
|
||||
|
||||
// RF registers
|
||||
#define GPIO0_CONF 0x00
|
||||
#define GPIO1_CONF 0x01
|
||||
#define GPIO2_CONF 0x02
|
||||
#define GPIO3_CONF 0x03
|
||||
#define SYNT3 0x05
|
||||
#define SYNT2 0x06
|
||||
#define SYNT1 0x07
|
||||
#define SYNT0 0x08
|
||||
#define IF_OFFSET_ANA 0x09
|
||||
#define IF_OFFSET_DIG 0x0A
|
||||
#define CHSPACE 0x0C
|
||||
#define CHNUM 0x0D
|
||||
#define MOD4 0x0E
|
||||
#define MOD3 0x0F
|
||||
#define MOD2 0x10
|
||||
#define MOD1 0x11
|
||||
#define MOD0 0x12
|
||||
#define CHFLT 0x13
|
||||
#define AFC2 0x14
|
||||
#define AFC1 0x15
|
||||
#define AFC0 0x16
|
||||
#define RSSI_FLT 0x17
|
||||
#define RSSI_TH 0x18
|
||||
#define AGCCTRL4 0x1A
|
||||
#define AGCCTRL3 0x1B
|
||||
#define AGCCTRL2 0x1C
|
||||
#define AGCCTRL1 0x1D
|
||||
#define AGCCTRL0 0x1E
|
||||
#define ANT_SELECT_CONF 0x1F
|
||||
#define CLOCKREC2 0x20
|
||||
#define CLOCKREC1 0x21
|
||||
#define PCKTCTRL6 0x2B
|
||||
#define PCKTCTRL5 0x2C
|
||||
#define PCKTCTRL4 0x2D
|
||||
#define PCKTCTRL3 0x2E
|
||||
#define PCKTCTRL2 0x2F
|
||||
#define PCKTCTRL1 0x30
|
||||
#define PCKTLEN1 0x31
|
||||
#define PCKTLEN0 0x32
|
||||
#define SYNC3 0x33
|
||||
#define SYNC2 0x34
|
||||
#define SYNC1 0x35
|
||||
#define SYNC0 0x36
|
||||
#define QI 0x37
|
||||
#define PCKT_PSTMBL 0x38
|
||||
#define PROTOCOL2 0x39
|
||||
#define PROTOCOL1 0x3A
|
||||
#define PROTOCOL0 0x3B
|
||||
#define FIFO_CONFIG3 0x3C
|
||||
#define FIFO_CONFIG2 0x3D
|
||||
#define FIFO_CONFIG1 0x3E
|
||||
#define FIFO_CONFIG0 0x3F
|
||||
#define PCKT_FLT_OPTIONS 0x40
|
||||
#define PCKT_FLT_GOALS4 0x41
|
||||
#define PCKT_FLT_GOALS3 0x42
|
||||
#define PCKT_FLT_GOALS2 0x43
|
||||
#define PCKT_FLT_GOALS1 0x44
|
||||
#define PCKT_FLT_GOALS0 0x45
|
||||
#define TIMERS5 0x46
|
||||
#define TIMERS4 0x47
|
||||
#define TIMERS3 0x48
|
||||
#define TIMERS2 0x49
|
||||
#define TIMERS1 0x4A
|
||||
#define TIMERS0 0x4B
|
||||
#define CSMA_CONF3 0x4C
|
||||
#define CSMA_CONF2 0x4D
|
||||
#define CSMA_CONF1 0x4E
|
||||
#define CSMA_CONF0 0x4F
|
||||
#define IRQ_MASK3 0x50
|
||||
#define IRQ_MASK2 0x51
|
||||
#define IRQ_MASK1 0x52
|
||||
#define IRQ_MASK0 0x53
|
||||
#define FAST_RX_TIMER 0x54
|
||||
#define PA_POWER8 0x5A
|
||||
#define PA_POWER7 0x5B
|
||||
#define PA_POWER6 0x5C
|
||||
#define PA_POWER5 0x5D
|
||||
#define PA_POWER4 0x5E
|
||||
#define PA_POWER3 0x5F
|
||||
#define PA_POWER2 0x60
|
||||
#define PA_POWER1 0x61
|
||||
#define PA_POWER0 0x62
|
||||
#define PA_CONFIG1 0x63
|
||||
#define PA_CONFIG0 0x64
|
||||
#define SYNTH_CONFIG2 0x65
|
||||
#define VCO_CONFIG 0x68
|
||||
#define VCO_CALIBR_IN2 0x69
|
||||
#define VCO_CALIBR_IN1 0x6A
|
||||
#define VCO_CALIBR_IN0 0x6B
|
||||
#define XO_RCO_CONF1 0x6C
|
||||
#define XO_RCO_CONF0 0x6D
|
||||
#define RCO_CALIBR_CONF3 0x6E
|
||||
#define RCO_CALIBR_CONF2 0x6F
|
||||
#define PM_CONF4 0x75
|
||||
#define PM_CONF3 0x76
|
||||
#define PM_CONF2 0x77
|
||||
#define PM_CONF1 0x78
|
||||
#define PM_CONF0 0x79
|
||||
#define MC_STATE1 0x8D
|
||||
#define MC_STATE0 0x8E
|
||||
#define TX_FIFO_STATUS 0x8F
|
||||
#define RX_FIFO_STATUS 0x90
|
||||
#define RCO_CALIBR_OUT4 0x94
|
||||
#define RCO_CALIBR_OUT3 0x95
|
||||
#define VCO_CALIBR_OUT1 0x99
|
||||
#define VCO_CALIBR_OUT0 0x9A
|
||||
#define TX_PCKT_INFO 0x9C
|
||||
#define RX_PCKT_INFO 0x9D
|
||||
#define AFC_CORR 0x9E
|
||||
#define LINK_QUALIF2 0x9F
|
||||
#define LINK_QUALIF1 0xA0
|
||||
#define RSSI_LEVEL 0xA2
|
||||
#define RX_PCKT_LEN1 0xA4
|
||||
#define RX_PCKT_LEN0 0xA5
|
||||
#define CRC_FIELD3 0xA6
|
||||
#define CRC_FIELD2 0xA7
|
||||
#define CRC_FIELD1 0xA8
|
||||
#define CRC_FIELD0 0xA9
|
||||
#define RX_ADDRE_FIELD1 0xAA
|
||||
#define RX_ADDRE_FIELD0 0xAB
|
||||
#define RSSI_LEVEL_RUN 0xEF
|
||||
#define DEVICE_INFO1 0xF0
|
||||
#define DEVICE_INFO0 0xF1
|
||||
#define IRQ_STATUS3 0xFA
|
||||
#define IRQ_STATUS2 0xFB
|
||||
#define IRQ_STATUS1 0xFC
|
||||
#define IRQ_STATUS0 0xFD
|
||||
#define TX_FIFO 0xFF
|
||||
#define RX_FIFO 0xFF
|
||||
|
||||
#define SFD0 0x90
|
||||
#define SFD1 0x4e
|
||||
|
||||
#define DEFAULT_DEVIATION 125000
|
||||
#define RX_FILTER_BANDWIDTH 540000
|
||||
#define RSSI_THRESHOLD -85
|
||||
|
||||
// PCKTCTRL6
|
||||
#define PCKT_SYNCLEN_FIELD 0xFC
|
||||
#define PCKT_SYNCLEN (16 << 2)
|
||||
|
||||
// PCKTCTRL5
|
||||
#define PCKT_PREAMBLE_LEN 32
|
||||
|
||||
// PCKTCTRL3
|
||||
#define PCKT_FORMAT_FIELD 0xC0
|
||||
#define PCKT_FORMAT_802_15_4 (1 << 6)
|
||||
#define PCKT_RXMODE_FIELD 0x30
|
||||
#define PCKT_RXMODE_NORMAL (0 << 4)
|
||||
#define PCKT_BYTE_SWAP_FIELD 0x04
|
||||
#define PCKT_BYTE_SWAP_LSB (1 << 2)
|
||||
|
||||
// PCKTCTRL2
|
||||
#define PCKT_FIXVARLEN_FIELD 0x01
|
||||
#define PCKT_VARIABLE_LEN (1 << 0)
|
||||
#define PCKT_FCS_TYPE_FIELD 0x20
|
||||
#define PCKT_FCS_TYPE_4_OCTET (0 << 5)
|
||||
#define PCKT_FCS_TYPE_2_OCTET (1 << 5)
|
||||
|
||||
// PCKTCTRL1
|
||||
#define PCKT_CRCMODE_FIELD 0xE0
|
||||
#define PCKT_CRCMODE_0X1021 (3 << 5)
|
||||
#define PCKT_CRCMODE_0x04C11DB7 (5 << 5)
|
||||
#define PCKT_TXSOURCE_FIELD 0x0C
|
||||
#define PCKT_TXSOURCE_NORMAL (0 << 2)
|
||||
#define PCKT_WHITENING_FIELD 0x10
|
||||
#define PCKT_WHITENING_ENABLED (1 << 4)
|
||||
|
||||
// MOD4
|
||||
#define DATARATE_M_MSB 0x47
|
||||
// MOD3
|
||||
#define DATARATE_M_LSB 0xAE
|
||||
|
||||
// MOD2
|
||||
#define MOD_TYPE_FIELD 0xF0
|
||||
#define MOD_2FSK (0 << 4)
|
||||
#define MOD_2GFSK (10 << 4)
|
||||
#define DATARATE_E_FIELD 0x0F
|
||||
#define DATARATE_E (10 << 0)
|
||||
|
||||
// MOD1
|
||||
#define FDEV_E_FIELD 0x0F
|
||||
|
||||
// QI
|
||||
#define PQI_TH_FIELD 0x1E
|
||||
#define PQI_TH (8 << 1)
|
||||
#define SQI_EN_FIELD 0x01
|
||||
#define SQI_EN (1 << 0)
|
||||
|
||||
// SYNT3
|
||||
#define SYNT_FIELD 0x0F
|
||||
|
||||
// CHFLT
|
||||
#define CHFLT_M_FIELD 0xF0
|
||||
#define CHFLT_E_FIELD 0x0F
|
||||
|
||||
// LINK_QUALIF1
|
||||
#define CARRIER_SENSE (1 << 7)
|
||||
|
||||
#define SPI_WR_REG 0x00
|
||||
#define SPI_RD_REG 0x01
|
||||
#define SPI_CMD 0x80
|
||||
|
||||
typedef enum {
|
||||
S2LP_STATE_STANDBY = 0x02,
|
||||
S2LP_STATE_SLEEPA = 0x01,
|
||||
S2LP_STATE_SLEEPB = 0x03,
|
||||
S2LP_STATE_READY = 0x00,
|
||||
S2LP_STATE_LOCK = 0x0C,
|
||||
S2LP_STATE_RX = 0x30,
|
||||
S2LP_STATE_TX = 0x5C,
|
||||
S2LP_STATE_SYNTH_SETUP = 0x50
|
||||
} s2lp_states_e;
|
||||
|
||||
#if defined __cplusplus && __cplusplus >= 201103
|
||||
typedef enum : uint8_t {
|
||||
#else
|
||||
typedef enum {
|
||||
#endif
|
||||
S2LP_CMD_TX = 0x60,
|
||||
S2LP_CMD_RX,
|
||||
S2LP_CMD_READY,
|
||||
S2LP_CMD_STANDBY,
|
||||
S2LP_CMD_SLEEP,
|
||||
S2LP_CMD_LOCKRX,
|
||||
S2LP_CMD_LOCKTX,
|
||||
S2LP_CMD_SABORT,
|
||||
S2LP_CMD_LDC_RELOAD,
|
||||
S2LP_CMD_SRES = 0x70,
|
||||
S2LP_CMD_FLUSHRXFIFO,
|
||||
S2LP_CMD_FLUSHTXFIFO,
|
||||
S2LP_CMD_SEQUPDATE
|
||||
} s2lp_commands_e;
|
||||
|
||||
typedef enum {
|
||||
RF_IDLE,
|
||||
RF_CSMA_STARTED,
|
||||
RF_TX_STARTED,
|
||||
RF_RX_STARTED,
|
||||
RF_TX_ACK
|
||||
} rf_states_e;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* S2LPREG_H_ */
|
|
@ -0,0 +1,164 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Pelion and affiliates.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef NANOSTACK_PHY_S2LP_H_
|
||||
#define NANOSTACK_PHY_S2LP_H_
|
||||
|
||||
#if defined(MBED_CONF_NANOSTACK_CONFIGURATION) && DEVICE_SPI && defined(MBED_CONF_RTOS_PRESENT)
|
||||
#include "inttypes.h"
|
||||
#include "NanostackRfPhy.h"
|
||||
#include "DigitalIn.h"
|
||||
#include "DigitalOut.h"
|
||||
#include "InterruptIn.h"
|
||||
#include "SPI.h"
|
||||
|
||||
#if defined(MBED_CONF_S2LP_SPI_SDI)
|
||||
#define S2LP_SPI_SDI MBED_CONF_S2LP_SPI_SDI
|
||||
#else
|
||||
#define S2LP_SPI_SDI D11
|
||||
#endif
|
||||
|
||||
#if defined(MBED_CONF_S2LP_SPI_SDO)
|
||||
#define S2LP_SPI_SDO MBED_CONF_S2LP_SPI_SDO
|
||||
#else
|
||||
#define S2LP_SPI_SDO D12
|
||||
#endif
|
||||
|
||||
#if defined(MBED_CONF_S2LP_SPI_SCLK)
|
||||
#define S2LP_SPI_SCLK MBED_CONF_S2LP_SPI_SCLK
|
||||
#else
|
||||
#define S2LP_SPI_SCLK D13
|
||||
#endif
|
||||
|
||||
#if defined(MBED_CONF_S2LP_SPI_CS)
|
||||
#define S2LP_SPI_CS MBED_CONF_S2LP_SPI_CS
|
||||
#else
|
||||
#define S2LP_SPI_CS A1
|
||||
#endif
|
||||
|
||||
#if defined(MBED_CONF_S2LP_SPI_SDN)
|
||||
#define S2LP_SPI_SDN MBED_CONF_S2LP_SPI_SDN
|
||||
#else
|
||||
#define S2LP_SPI_SDN D7
|
||||
#endif
|
||||
|
||||
#if defined(MBED_CONF_S2LP_TEST_PIN_TX)
|
||||
#define S2LP_TEST_PIN_TX MBED_CONF_S2LP_TEST_PIN_TX
|
||||
#else
|
||||
#define S2LP_TEST_PIN_TX D6
|
||||
#endif
|
||||
|
||||
#if defined(MBED_CONF_S2LP_TEST_PIN_RX)
|
||||
#define S2LP_TEST_PIN_RX MBED_CONF_S2LP_TEST_PIN_RX
|
||||
#else
|
||||
#define S2LP_TEST_PIN_RX D5
|
||||
#endif
|
||||
|
||||
#if defined(MBED_CONF_S2LP_TEST_PIN_CSMA)
|
||||
#define S2LP_TEST_PIN_CSMA MBED_CONF_S2LP_TEST_PIN_CSMA
|
||||
#else
|
||||
#define S2LP_TEST_PIN_CSMA D4
|
||||
#endif
|
||||
|
||||
#if defined(MBED_CONF_S2LP_TEST_PIN_SPARE_1)
|
||||
#define S2LP_TEST_PIN_SPARE_1 MBED_CONF_S2LP_TEST_PIN_SPARE_1
|
||||
#else
|
||||
#define S2LP_TEST_PIN_SPARE_1 D2
|
||||
#endif
|
||||
|
||||
#if defined(MBED_CONF_S2LP_TEST_PIN_SPARE_2)
|
||||
#define S2LP_TEST_PIN_SPARE_2 MBED_CONF_S2LP_TEST_PIN_SPARE_2
|
||||
#else
|
||||
#define S2LP_TEST_PIN_SPARE_2 D8
|
||||
#endif
|
||||
|
||||
#if defined(MBED_CONF_S2LP_SPI_GPIO0)
|
||||
#define S2LP_SPI_GPIO0 MBED_CONF_S2LP_SPI_GPIO0
|
||||
#else
|
||||
#define S2LP_SPI_GPIO0 A0
|
||||
#endif
|
||||
|
||||
#if defined(MBED_CONF_S2LP_SPI_GPIO1)
|
||||
#define S2LP_SPI_GPIO1 MBED_CONF_S2LP_SPI_GPIO1
|
||||
#else
|
||||
#define S2LP_SPI_GPIO1 A2
|
||||
#endif
|
||||
|
||||
#if defined(MBED_CONF_S2LP_SPI_GPIO2)
|
||||
#define S2LP_SPI_GPIO2 MBED_CONF_S2LP_SPI_GPIO2
|
||||
#else
|
||||
#define S2LP_SPI_GPIO2 A3
|
||||
#endif
|
||||
|
||||
#if defined(MBED_CONF_S2LP_SPI_GPIO3)
|
||||
#define S2LP_SPI_GPIO3 MBED_CONF_S2LP_SPI_GPIO3
|
||||
#else
|
||||
#define S2LP_SPI_GPIO3 A5
|
||||
#endif
|
||||
|
||||
#if defined(MBED_CONF_S2LP_I2C_SDA)
|
||||
#define S2LP_I2C_SDA MBED_CONF_S2LP_I2C_SDA
|
||||
#else
|
||||
#define S2LP_I2C_SDA null
|
||||
#endif
|
||||
|
||||
#if defined(MBED_CONF_S2LP_I2C_SCL)
|
||||
#define S2LP_I2C_SCL MBED_CONF_S2LP_I2C_SCL
|
||||
#else
|
||||
#define S2LP_I2C_SCL null
|
||||
#endif
|
||||
|
||||
#include "at24mac_s2lp.h"
|
||||
|
||||
class RFPins;
|
||||
class TestPins_S2LP;
|
||||
|
||||
class NanostackRfPhys2lp : public NanostackRfPhy {
|
||||
public:
|
||||
NanostackRfPhys2lp(PinName spi_sdi, PinName spi_sdo, PinName spi_sclk, PinName spi_cs, PinName spi_sdn
|
||||
, PinName spi_gpio0, PinName spi_gpio1, PinName spi_gpio2, PinName spi_gpio3
|
||||
#ifdef AT24MAC
|
||||
, PinName i2c_sda, PinName i2c_scl
|
||||
#endif //AT24MAC
|
||||
);
|
||||
virtual ~NanostackRfPhys2lp();
|
||||
virtual int8_t rf_register();
|
||||
virtual void rf_unregister();
|
||||
virtual void get_mac_address(uint8_t *mac);
|
||||
virtual void set_mac_address(uint8_t *mac);
|
||||
|
||||
private:
|
||||
#ifdef AT24MAC
|
||||
AT24Mac_s2lp _mac;
|
||||
#endif //AT24MAC
|
||||
uint8_t _mac_addr[8];
|
||||
RFPins *_rf;
|
||||
TestPins_S2LP *_test_pins;
|
||||
bool _mac_set;
|
||||
|
||||
const PinName _spi_sdi;
|
||||
const PinName _spi_sdo;
|
||||
const PinName _spi_sclk;
|
||||
const PinName _spi_cs;
|
||||
const PinName _spi_sdn;
|
||||
const PinName _spi_gpio0;
|
||||
const PinName _spi_gpio1;
|
||||
const PinName _spi_gpio2;
|
||||
const PinName _spi_gpio3;
|
||||
};
|
||||
#endif /* MBED_CONF_NANOSTACK_CONFIGURATION && DEVICE_SPI */
|
||||
#endif /* NANOSTACK_PHY_S2LP_H_ */
|
Loading…
Reference in New Issue