Lines Matching +full:max +full:- +full:x
1 /* ieee802154_rf2xx.c - ATMEL RF2XX IEEE 802.15.4 Driver */
6 * Copyright (c) 2019-2020 Gerson Fernando Budke
8 * SPDX-License-Identifier: Apache-2.0
67 .rssi = -40,
84 k_sem_give(&ctx->trx_isr_lock); in trx_isr_handler()
111 * Datasheet: Figure 7-13. Timing Example of an RX_AACK Transaction in rf2xx_trx_set_tx_state()
141 struct rf2xx_context *ctx = dev->data; in rf2xx_set_rssi_base()
144 if (ctx->cc_page == IEEE802154_ATTR_PHY_CHANNEL_PAGE_ZERO_OQPSK_2450_BPSK_868_915) { in rf2xx_set_rssi_base()
148 } else if (ctx->cc_page == IEEE802154_ATTR_PHY_CHANNEL_PAGE_TWO_OQPSK_868_915) { in rf2xx_set_rssi_base()
156 ctx->trx_rssi_base = base; in rf2xx_set_rssi_base()
161 struct rf2xx_context *ctx = dev->data; in rf2xx_trx_rx()
170 * net_pkt_rx_alloc_with_buffer allocates max value of 128 bytes. in rf2xx_trx_rx()
175 if (ctx->trx_model != RF2XX_TRX_MODEL_231) { in rf2xx_trx_rx()
176 pkt_len = ctx->rx_phr; in rf2xx_trx_rx()
182 if (!ctx->promiscuous && pkt_len < RX2XX_FRAME_MIN_PHR_SIZE) { in rf2xx_trx_rx()
192 if (ctx->trx_model != RF2XX_TRX_MODEL_231) { in rf2xx_trx_rx()
196 ctx->pkt_ed = rx_buf[pkt_len + RX2XX_FRAME_ED_INDEX]; in rf2xx_trx_rx()
201 ctx->pkt_ed = (rf2xx_iface_reg_read(dev, RF2XX_PHY_RSSI_REG) in rf2xx_trx_rx()
204 ctx->pkt_lqi = rx_buf[pkt_len + RX2XX_FRAME_LQI_INDEX]; in rf2xx_trx_rx()
206 if (!ctx->promiscuous && trac == RF2XX_TRX_PHY_STATE_TRAC_INVALID) { in rf2xx_trx_rx()
214 pkt_len -= RX2XX_FRAME_FCS_LENGTH; in rf2xx_trx_rx()
217 pkt = net_pkt_rx_alloc_with_buffer(ctx->iface, pkt_len, in rf2xx_trx_rx()
224 memcpy(pkt->buffer->data, rx_buf + RX2XX_FRAME_HEADER_SIZE, pkt_len); in rf2xx_trx_rx()
225 net_buf_add(pkt->buffer, pkt_len); in rf2xx_trx_rx()
226 net_pkt_set_ieee802154_lqi(pkt, ctx->pkt_lqi); in rf2xx_trx_rx()
227 net_pkt_set_ieee802154_rssi_dbm(pkt, ctx->pkt_ed + ctx->trx_rssi_base); in rf2xx_trx_rx()
229 LOG_DBG("Caught a packet (%02X) (LQI: %02X, RSSI: %d, ED: %02X)", in rf2xx_trx_rx()
230 pkt_len, ctx->pkt_lqi, ctx->trx_rssi_base + ctx->pkt_ed, in rf2xx_trx_rx()
231 ctx->pkt_ed); in rf2xx_trx_rx()
233 if (net_recv_data(ctx->iface, pkt) < 0) { in rf2xx_trx_rx()
240 log_stack_usage(&ctx->trx_thread); in rf2xx_trx_rx()
246 struct rf2xx_context *ctx = dev->data; in rf2xx_process_rx_frame()
252 if (ctx->trx_model != RF2XX_TRX_MODEL_231) { in rf2xx_process_rx_frame()
274 struct rf2xx_context *ctx = dev->data; in rf2xx_process_tx_frame()
276 ctx->trx_trac = (rf2xx_iface_reg_read(dev, RF2XX_TRX_STATE_REG) >> in rf2xx_process_tx_frame()
278 k_sem_give(&ctx->trx_tx_sync); in rf2xx_process_tx_frame()
300 k_sem_take(&ctx->trx_isr_lock, K_FOREVER); in rf2xx_thread_main()
302 isr_status = rf2xx_iface_reg_read(ctx->dev, in rf2xx_thread_main()
311 * IRQ_4 (CCA_ED_DONE) Multi-functional interrupt: in rf2xx_thread_main()
332 if (ctx->trx_model != RF2XX_TRX_MODEL_231) { in rf2xx_thread_main()
333 rf2xx_iface_sram_read(ctx->dev, 0, in rf2xx_thread_main()
334 &ctx->rx_phr, 1); in rf2xx_thread_main()
338 rf2xx_process_trx_end(ctx->dev); in rf2xx_thread_main()
345 const struct rf2xx_config *conf = dev->config; in get_mac()
346 struct rf2xx_context *ctx = dev->data; in get_mac()
347 uint32_t *ptr = (uint32_t *)(ctx->mac_addr); in get_mac()
349 if (!conf->has_mac) { in get_mac()
351 ptr = (uint32_t *)(ctx->mac_addr + 4); in get_mac()
360 ctx->mac_addr[0] = (ctx->mac_addr[0] & ~0x01) | 0x02; in get_mac()
362 return ctx->mac_addr; in get_mac()
380 struct rf2xx_context *ctx = dev->data; in rf2xx_configure_sub_channel()
384 if (ctx->cc_page == IEEE802154_ATTR_PHY_CHANNEL_PAGE_ZERO_OQPSK_2450_BPSK_868_915) { in rf2xx_configure_sub_channel()
388 } else if (ctx->cc_page == IEEE802154_ATTR_PHY_CHANNEL_PAGE_TWO_OQPSK_868_915) { in rf2xx_configure_sub_channel()
405 struct rf2xx_context *ctx = dev->data; in rf2xx_configure_trx_path()
409 if (ctx->cc_page == IEEE802154_ATTR_PHY_CHANNEL_PAGE_ZERO_OQPSK_2450_BPSK_868_915) { in rf2xx_configure_trx_path()
433 struct rf2xx_context *ctx = dev->data; in rf2xx_set_channel()
438 if (ctx->trx_model == RF2XX_TRX_MODEL_212) { in rf2xx_set_channel()
439 if ((ctx->cc_page == IEEE802154_ATTR_PHY_CHANNEL_PAGE_ZERO_OQPSK_2450_BPSK_868_915 in rf2xx_set_channel()
440 || ctx->cc_page == IEEE802154_ATTR_PHY_CHANNEL_PAGE_TWO_OQPSK_868_915) in rf2xx_set_channel()
443 return channel > 26 ? -EINVAL : -ENOTSUP; in rf2xx_set_channel()
445 if (ctx->cc_page == IEEE802154_ATTR_PHY_CHANNEL_PAGE_FIVE_OQPSK_780 && in rf2xx_set_channel()
448 return channel > 7 ? -EINVAL : -ENOTSUP; in rf2xx_set_channel()
455 /* 2.4G O-QPSK, channel page zero */ in rf2xx_set_channel()
458 return channel < 11 ? -ENOTSUP : -EINVAL; in rf2xx_set_channel()
470 const struct rf2xx_config *conf = dev->config; in rf2xx_set_txpower()
471 struct rf2xx_context *ctx = dev->data; in rf2xx_set_txpower()
472 float min, max, step; in rf2xx_set_txpower() local
488 if (conf->tx_pwr_table_size == 1) { in rf2xx_set_txpower()
494 min = conf->tx_pwr_min[1]; in rf2xx_set_txpower()
495 if (conf->tx_pwr_min[0] == 0x01) { in rf2xx_set_txpower()
496 min *= -1.0f; in rf2xx_set_txpower()
499 max = conf->tx_pwr_max[1]; in rf2xx_set_txpower()
500 if (conf->tx_pwr_max[0] == 0x01) { in rf2xx_set_txpower()
501 min *= -1.0f; in rf2xx_set_txpower()
504 step = (max - min) / ((float)conf->tx_pwr_table_size - 1.0f); in rf2xx_set_txpower()
510 LOG_DBG("Tx-power values: min %f, max %f, step %f, entries %d", in rf2xx_set_txpower()
511 (double)min, (double)max, (double)step, conf->tx_pwr_table_size); in rf2xx_set_txpower()
514 LOG_INF("TX-power %d dBm below min of %f dBm, using %f dBm", in rf2xx_set_txpower()
515 dbm, (double)min, (double)max); in rf2xx_set_txpower()
517 } else if (dbm > max) { in rf2xx_set_txpower()
518 LOG_INF("TX-power %d dBm above max of %f dBm, using %f dBm", in rf2xx_set_txpower()
519 dbm, (double)min, (double)max); in rf2xx_set_txpower()
520 dbm = max; in rf2xx_set_txpower()
523 idx = abs((int) (((float)(dbm - max) / step))); in rf2xx_set_txpower()
524 LOG_DBG("Tx-power idx: %d", idx); in rf2xx_set_txpower()
526 if (idx >= conf->tx_pwr_table_size) { in rf2xx_set_txpower()
527 idx = conf->tx_pwr_table_size - 1; in rf2xx_set_txpower()
530 val = conf->tx_pwr_table[idx]; in rf2xx_set_txpower()
532 if (ctx->trx_model != RF2XX_TRX_MODEL_212) { in rf2xx_set_txpower()
537 LOG_DBG("Tx-power normalized: %d dBm, PHY_TX_PWR 0x%02x, idx %d", in rf2xx_set_txpower()
550 LOG_DBG("IEEE address %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", in rf2xx_set_ieee_addr()
583 LOG_DBG("Short Address: 0x%02X%02X", short_addr_le[1], in rf2xx_set_short_addr()
601 LOG_DBG("Pan Id: 0x%02X%02X", pan_id_le[1], pan_id_le[0]); in rf2xx_set_pan_id()
613 return rf2xx_set_ieee_addr(dev, set, filter->ieee_addr); in rf2xx_filter()
615 return rf2xx_set_short_addr(dev, set, filter->short_addr); in rf2xx_filter()
617 return rf2xx_set_pan_id(dev, set, filter->pan_id); in rf2xx_filter()
620 return -ENOTSUP; in rf2xx_filter()
626 if ((frag->data[0] & RF2XX_FRAME_CTRL_ACK_REQUEST_BIT) == 0) { in rf2xx_handle_ack()
631 rf2xx_ack_psdu[2] = frag->data[2]; in rf2xx_handle_ack()
633 if (ctx->trx_trac == RF2XX_TRX_PHY_STATE_TRAC_SUCCESS_DATA_PENDING) { in rf2xx_handle_ack()
639 if (ieee802154_handle_ack(ctx->iface, &rf2xx_ack_pkt) != NET_OK) { in rf2xx_handle_ack()
654 struct rf2xx_context *ctx = dev->data; in rf2xx_tx()
659 if (ctx->tx_mode != mode) { in rf2xx_tx()
668 /* max frame retries = 3, csma/ca retries = 4 */ in rf2xx_tx()
681 return -ENOTSUP; in rf2xx_tx()
684 ctx->tx_mode = mode; in rf2xx_tx()
690 k_sem_reset(&ctx->trx_tx_sync); in rf2xx_tx()
691 rf2xx_iface_frame_write(dev, frag->data, frag->len); in rf2xx_tx()
693 k_sem_take(&ctx->trx_tx_sync, K_FOREVER); in rf2xx_tx()
695 switch (ctx->trx_trac) { in rf2xx_tx()
697 * CSMA-CA in rf2xx_tx()
700 response = -EBUSY; in rf2xx_tx()
706 response = -EAGAIN; in rf2xx_tx()
710 response = -EINTR; in rf2xx_tx()
731 const struct rf2xx_config *conf = dev->config; in rf2xx_start()
737 gpio_pin_interrupt_configure_dt(&conf->irq_gpio, in rf2xx_start()
746 const struct rf2xx_config *conf = dev->config; in rf2xx_stop()
750 gpio_pin_interrupt_configure_dt(&conf->irq_gpio, GPIO_INT_DISABLE); in rf2xx_stop()
776 struct rf2xx_context *ctx = dev->data; in rf2xx_promiscuous_set()
779 ctx->promiscuous = promiscuous; in rf2xx_promiscuous_set()
806 int ret = -EINVAL; in rf2xx_configure()
816 ret = rf2xx_pan_coord_set(dev, config->pan_coordinator); in rf2xx_configure()
820 ret = rf2xx_promiscuous_set(dev, config->promiscuous); in rf2xx_configure()
834 struct rf2xx_context *ctx = dev->data; in rf2xx_attr_get()
838 value->phy_supported_channel_pages = ctx->cc_page; in rf2xx_attr_get()
842 value->phy_supported_channels = &ctx->cc_channels; in rf2xx_attr_get()
846 return -ENOENT; in rf2xx_attr_get()
852 const struct rf2xx_config *conf = dev->config; in power_on_and_setup()
853 struct rf2xx_context *ctx = dev->data; in power_on_and_setup()
867 ctx->trx_model = rf2xx_iface_reg_read(dev, RF2XX_PART_NUM_REG); in power_on_and_setup()
868 ctx->trx_version = rf2xx_iface_reg_read(dev, RF2XX_VERSION_NUM_REG); in power_on_and_setup()
872 * 231-Rev-A (Version 0x02) in power_on_and_setup()
873 * 232-Rev-A (Version 0x02) in power_on_and_setup()
874 * 233-Rev-A (Version 0x01) (Warning) in power_on_and_setup()
875 * 233-Rev-B (Version 0x02) in power_on_and_setup()
877 if (ctx->trx_model <= RF2XX_TRX_MODEL_230) { in power_on_and_setup()
879 return -ENODEV; in power_on_and_setup()
882 if (ctx->trx_model == RF2XX_TRX_MODEL_233 && ctx->trx_version == 0x01) { in power_on_and_setup()
887 if (ctx->trx_model == RF2XX_TRX_MODEL_212) { in power_on_and_setup()
888 ctx->trx_rssi_base = -100; in power_on_and_setup()
889 } else if (ctx->trx_model == RF2XX_TRX_MODEL_233) { in power_on_and_setup()
890 ctx->trx_rssi_base = -94; in power_on_and_setup()
891 } else if (ctx->trx_model == RF2XX_TRX_MODEL_231) { in power_on_and_setup()
892 ctx->trx_rssi_base = -91; in power_on_and_setup()
894 ctx->trx_rssi_base = -90; in power_on_and_setup()
908 if (ctx->trx_model != RF2XX_TRX_MODEL_232) { in power_on_and_setup()
913 if (ctx->trx_model == RF2XX_TRX_MODEL_212) { in power_on_and_setup()
918 ctx->tx_mode = IEEE802154_TX_MODE_CSMA_CA; in power_on_and_setup()
919 ctx->promiscuous = false; in power_on_and_setup()
926 gpio_init_callback(&ctx->irq_cb, trx_isr_handler, in power_on_and_setup()
927 BIT(conf->irq_gpio.pin)); in power_on_and_setup()
929 if (gpio_add_callback(conf->irq_gpio.port, &ctx->irq_cb) < 0) { in power_on_and_setup()
931 return -ENXIO; in power_on_and_setup()
939 const struct rf2xx_config *conf = dev->config; in configure_gpios()
942 if (!gpio_is_ready_dt(&conf->irq_gpio)) { in configure_gpios()
944 return -ENODEV; in configure_gpios()
946 gpio_pin_configure_dt(&conf->irq_gpio, GPIO_INPUT); in configure_gpios()
947 gpio_pin_interrupt_configure_dt(&conf->irq_gpio, in configure_gpios()
951 if (!gpio_is_ready_dt(&conf->reset_gpio)) { in configure_gpios()
953 return -ENODEV; in configure_gpios()
955 gpio_pin_configure_dt(&conf->reset_gpio, GPIO_OUTPUT_INACTIVE); in configure_gpios()
958 if (!gpio_is_ready_dt(&conf->slptr_gpio)) { in configure_gpios()
960 return -ENODEV; in configure_gpios()
962 gpio_pin_configure_dt(&conf->slptr_gpio, GPIO_OUTPUT_INACTIVE); in configure_gpios()
965 if (conf->dig2_gpio.port != NULL) { in configure_gpios()
966 if (!gpio_is_ready_dt(&conf->dig2_gpio)) { in configure_gpios()
968 return -ENODEV; in configure_gpios()
971 conf->dig2_gpio.port->name); in configure_gpios()
972 gpio_pin_configure_dt(&conf->dig2_gpio, GPIO_INPUT); in configure_gpios()
973 gpio_pin_interrupt_configure_dt(&conf->dig2_gpio, in configure_gpios()
978 if (conf->clkm_gpio.port != NULL) { in configure_gpios()
979 if (!gpio_is_ready_dt(&conf->clkm_gpio)) { in configure_gpios()
981 return -ENODEV; in configure_gpios()
984 conf->clkm_gpio.port->name); in configure_gpios()
985 gpio_pin_configure_dt(&conf->clkm_gpio, GPIO_INPUT); in configure_gpios()
993 const struct rf2xx_config *conf = dev->config; in configure_spi()
995 if (!spi_is_ready_dt(&conf->spi)) { in configure_spi()
997 conf->spi.bus->name); in configure_spi()
998 return -ENODEV; in configure_spi()
1006 struct rf2xx_context *ctx = dev->data; in rf2xx_init()
1007 const struct rf2xx_config *conf = dev->config; in rf2xx_init()
1012 ctx->dev = dev; in rf2xx_init()
1014 k_sem_init(&ctx->trx_tx_sync, 0, 1); in rf2xx_init()
1015 k_sem_init(&ctx->trx_isr_lock, 0, 1); in rf2xx_init()
1019 return -EIO; in rf2xx_init()
1024 return -EIO; in rf2xx_init()
1031 return -EIO; in rf2xx_init()
1036 k_thread_create(&ctx->trx_thread, in rf2xx_init()
1037 ctx->trx_stack, in rf2xx_init()
1044 "rf2xx_trx [%d]", conf->inst); in rf2xx_init()
1045 k_thread_name_set(&ctx->trx_thread, thread_name); in rf2xx_init()
1055 struct rf2xx_context *ctx = dev->data; in rf2xx_iface_init()
1060 ctx->iface = iface; in rf2xx_iface_init()
1062 if (ctx->trx_model == RF2XX_TRX_MODEL_212) { in rf2xx_iface_init()
1063 if (ctx->cc_page == IEEE802154_ATTR_PHY_CHANNEL_PAGE_ZERO_OQPSK_2450_BPSK_868_915 || in rf2xx_iface_init()
1064 ctx->cc_page == IEEE802154_ATTR_PHY_CHANNEL_PAGE_TWO_OQPSK_868_915) { in rf2xx_iface_init()
1065 ctx->cc_range.from_channel = 0U; in rf2xx_iface_init()
1066 ctx->cc_range.to_channel = 10U; in rf2xx_iface_init()
1067 } else if (ctx->cc_page == IEEE802154_ATTR_PHY_CHANNEL_PAGE_FIVE_OQPSK_780) { in rf2xx_iface_init()
1068 ctx->cc_range.from_channel = 0U; in rf2xx_iface_init()
1069 ctx->cc_range.to_channel = 3U; in rf2xx_iface_init()
1071 __ASSERT(false, "Unsupported channel page %u.", ctx->cc_page); in rf2xx_iface_init()
1074 __ASSERT(ctx->cc_page == in rf2xx_iface_init()
1076 "Unsupported channel page %u.", ctx->cc_page); in rf2xx_iface_init()
1077 ctx->cc_range.from_channel = 11U; in rf2xx_iface_init()
1078 ctx->cc_range.to_channel = 26U; in rf2xx_iface_init()
1118 "rf2xx: Error TX-PWR-MIN len is different of two"); \
1120 "rf2xx: Error TX-PWR-MAX len is different of two"); \
1122 "rf2xx: Error TX-PWR-TABLE len must be greater than zero"); \