summaryrefslogtreecommitdiff
path: root/src/libs/mynewt-nimble/apps/bleprph/src/phy.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/mynewt-nimble/apps/bleprph/src/phy.c')
-rw-r--r--src/libs/mynewt-nimble/apps/bleprph/src/phy.c128
1 files changed, 128 insertions, 0 deletions
diff --git a/src/libs/mynewt-nimble/apps/bleprph/src/phy.c b/src/libs/mynewt-nimble/apps/bleprph/src/phy.c
new file mode 100644
index 00000000..c6fb2b35
--- /dev/null
+++ b/src/libs/mynewt-nimble/apps/bleprph/src/phy.c
@@ -0,0 +1,128 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 "os/mynewt.h"
+#include "bsp/bsp.h"
+#include "hal/hal_gpio.h"
+#include "host/ble_gap.h"
+#include "bleprph.h"
+
+#if MYNEWT_VAL(BLEPRPH_LE_PHY_SUPPORT)
+
+static const int button_gpio[4] = MYNEWT_VAL(BLEPRPH_LE_PHY_BUTTON_GPIO);
+static const int led_gpio[3] = MYNEWT_VAL(BLEPRPH_LE_PHY_LED_GPIO);
+
+#define PHY_TO_PTR(_mask, _opts) (void *)(((_opts) << 16) | ((_mask)))
+#define PTR_TO_PHY_MASK(_ptr) (uint8_t)(((int)_ptr) & 0x0ff)
+#define PTR_TO_PHY_OPTS(_ptr) (uint8_t)(((int)_ptr) >> 16)
+
+static struct os_event gpio_event;
+
+static uint16_t conn_handle = CONN_HANDLE_INVALID;
+
+static void
+gpio_irq_handler(void *arg)
+{
+ gpio_event.ev_arg = arg;
+ os_eventq_put(os_eventq_dflt_get(), &gpio_event);
+}
+
+static void
+gpio_event_handler(struct os_event *ev)
+{
+ uint8_t phy_mask;
+ uint8_t phy_opts;
+ int sr;
+
+ OS_ENTER_CRITICAL(sr);
+ phy_mask = PTR_TO_PHY_MASK(ev->ev_arg);
+ phy_opts = PTR_TO_PHY_OPTS(ev->ev_arg);
+ OS_EXIT_CRITICAL(sr);
+
+ if (conn_handle != CONN_HANDLE_INVALID) {
+ ble_gap_set_prefered_le_phy(conn_handle, phy_mask, phy_mask, phy_opts);
+ }
+}
+
+static void
+setup_button_gpio(int button, uint8_t phy_mask, uint8_t phy_opts)
+{
+ if (button < 0) {
+ return;
+ }
+
+ hal_gpio_irq_init(button, gpio_irq_handler, PHY_TO_PTR(phy_mask, phy_opts),
+ HAL_GPIO_TRIG_FALLING, HAL_GPIO_PULL_UP);
+ hal_gpio_irq_enable(button);
+}
+
+void
+phy_init(void)
+{
+ gpio_event.ev_cb = gpio_event_handler;
+
+ /*
+ * XXX: we could make this configurable, but for now assume all pins are
+ * valid, buttons gpio pins are pulled-up and LEDs are active-low - this
+ * is valid for nRF52840 PDK.
+ */
+ setup_button_gpio(button_gpio[0], BLE_GAP_LE_PHY_1M_MASK,
+ BLE_GAP_LE_PHY_CODED_ANY);
+ setup_button_gpio(button_gpio[1], BLE_GAP_LE_PHY_2M_MASK,
+ BLE_GAP_LE_PHY_CODED_ANY);
+ setup_button_gpio(button_gpio[2], BLE_GAP_LE_PHY_CODED_MASK,
+ BLE_GAP_LE_PHY_CODED_S2);
+ setup_button_gpio(button_gpio[3], BLE_GAP_LE_PHY_CODED_MASK,
+ BLE_GAP_LE_PHY_CODED_S8);
+
+ hal_gpio_init_out(led_gpio[0], 1);
+ hal_gpio_init_out(led_gpio[1], 1);
+ hal_gpio_init_out(led_gpio[2], 1);
+}
+
+void
+phy_conn_changed(uint16_t handle)
+{
+ uint8_t phy = 0;
+
+ conn_handle = handle;
+
+ if (handle != CONN_HANDLE_INVALID) {
+ /* XXX: assume symmetric phy for now */
+ ble_gap_read_le_phy(handle, &phy, &phy);
+ }
+
+ phy_update(phy);
+}
+
+void
+phy_update(uint8_t phy)
+{
+ if (conn_handle == CONN_HANDLE_INVALID) {
+ hal_gpio_write(led_gpio[0], 1);
+ hal_gpio_write(led_gpio[1], 1);
+ hal_gpio_write(led_gpio[2], 1);
+ } else {
+ hal_gpio_write(led_gpio[0], !(phy == BLE_GAP_LE_PHY_1M));
+ hal_gpio_write(led_gpio[1], !(phy == BLE_GAP_LE_PHY_2M));
+ hal_gpio_write(led_gpio[2], !(phy == BLE_GAP_LE_PHY_CODED));
+ }
+}
+
+#endif