Publishing for Bluetooth Asia 2018 developer session: mesh session. This repo is for GenericOnOff client side firmware.
EULA
PLEASE READ MESH_DEMO_TUTORIAL_EULA.TXT BEFORE START DEVELOPMENT.
Overview
This sample demonstrates Bluetooth Mesh functionality on micro:bit. It doesn't need provisioning because all the credential material (DevKey, NetKey, AppKey, Key Index, IVI and Unicast address) is pre-configured. This sample work as a GenericOnOff client:
- Pressing Button A on micro:bit will send GenericOnOffSet access message with on or off state alternatively and specific group address;
- Pressing Button B on micro:bit will switch the group address from 0xC000 to 0xC003 and back to 0xC000 again like round robin;
Requirements
micro:bit board
Building and Running
0. Download source code, it's zip file, the link is on this page, Download repository
.
1. Following below link to set the development environment up on your Windows computer. http://docs.zephyrproject.org/getting_started/installation_win.html . Please make sure git checkout this commit, commit: 88dfd399f480b1593a8e13f5a68d512921a55502 , the detail is here, https://github.com/zephyrproject-rtos/zephyr/commit/88dfd399f480b1593a8e13f5a68d512921a55502
2. copy zip file into ./zephyr/sample/
in the Zephyr tree.
3. unzip the file by "Extract Here".
3. access into the extracted folder and rename prj_bbc_microbit.txt
to prj_bbc_microbit.conf
4. if adopting Windows Command Prompt, use it to access into the unzip folder and type following commands on the console:
mkdir build & cd build
cmake -GNinja -DBOARD=bbc_microbit ..
ninja
if adopting MSYS2, use it to access into the unzip folder and type following commands on the console:
mkdir build & cd build
cmake -GNinja -DBOARD=bbc_microbit ..
ninja
5. connect micro:bit with your computer by USB cable, the board will be enumerated as a massive storage device;
6. drag the hex file (which is in ./zephyr/sample/[unzip folder]/build/zephyr/zephyr.hex
) into
Microbit massive storage device to flash the firmware;
7. micro:bit is ready to work as a GenericOnOff client.
src/main.c@1:fb4893064dd4, 2018-05-02 (annotated)
- Committer:
- krenbluetoothsig
- Date:
- Wed May 02 04:10:40 2018 +0000
- Revision:
- 1:fb4893064dd4
- Parent:
- 0:876e59f87d50
- Child:
- 7:6512e150f5f6
client; 1. NEW: add Zephy "get started" link.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
krenbluetoothsig | 0:876e59f87d50 | 1 | /* |
krenbluetoothsig | 1:fb4893064dd4 | 2 | * Copyright (c) 2018 Bluetooth SIG |
krenbluetoothsig | 0:876e59f87d50 | 3 | * |
krenbluetoothsig | 0:876e59f87d50 | 4 | * SPDX-License-Identifier: Apache-2.0 |
krenbluetoothsig | 0:876e59f87d50 | 5 | */ |
krenbluetoothsig | 0:876e59f87d50 | 6 | |
krenbluetoothsig | 0:876e59f87d50 | 7 | #include <misc/printk.h> |
krenbluetoothsig | 0:876e59f87d50 | 8 | |
krenbluetoothsig | 0:876e59f87d50 | 9 | #include <bluetooth/bluetooth.h> |
krenbluetoothsig | 0:876e59f87d50 | 10 | #include <bluetooth/mesh.h> |
krenbluetoothsig | 1:fb4893064dd4 | 11 | #include <gpio.h> |
krenbluetoothsig | 1:fb4893064dd4 | 12 | #include <board.h> |
krenbluetoothsig | 1:fb4893064dd4 | 13 | #include <soc.h> |
krenbluetoothsig | 1:fb4893064dd4 | 14 | #include <misc/printk.h> |
krenbluetoothsig | 1:fb4893064dd4 | 15 | #include <ctype.h> |
krenbluetoothsig | 1:fb4893064dd4 | 16 | #include <flash.h> |
krenbluetoothsig | 1:fb4893064dd4 | 17 | #include <gpio.h> |
krenbluetoothsig | 1:fb4893064dd4 | 18 | #include <pwm.h> |
krenbluetoothsig | 1:fb4893064dd4 | 19 | |
krenbluetoothsig | 0:876e59f87d50 | 20 | #include <display/mb_display.h> |
krenbluetoothsig | 0:876e59f87d50 | 21 | |
krenbluetoothsig | 1:fb4893064dd4 | 22 | #include <bluetooth/mesh.h> |
krenbluetoothsig | 0:876e59f87d50 | 23 | |
krenbluetoothsig | 1:fb4893064dd4 | 24 | #if !defined(NODE_ADDR) |
krenbluetoothsig | 1:fb4893064dd4 | 25 | #define NODE_ADDR 0x0b02 |
krenbluetoothsig | 1:fb4893064dd4 | 26 | #endif |
krenbluetoothsig | 0:876e59f87d50 | 27 | |
krenbluetoothsig | 1:fb4893064dd4 | 28 | #define CID_INTEL 0x0002 |
krenbluetoothsig | 1:fb4893064dd4 | 29 | #define MOD_INTEL 0x0000 |
krenbluetoothsig | 1:fb4893064dd4 | 30 | #define GROUP_ADDR 0xc000 |
krenbluetoothsig | 1:fb4893064dd4 | 31 | #define PUBLISHER_ADDR 0x000f |
krenbluetoothsig | 1:fb4893064dd4 | 32 | |
krenbluetoothsig | 1:fb4893064dd4 | 33 | /* Model Operation Codes */ |
krenbluetoothsig | 0:876e59f87d50 | 34 | #define BT_MESH_MODEL_OP_GEN_ONOFF_GET BT_MESH_MODEL_OP_2(0x82, 0x01) |
krenbluetoothsig | 0:876e59f87d50 | 35 | #define BT_MESH_MODEL_OP_GEN_ONOFF_SET BT_MESH_MODEL_OP_2(0x82, 0x02) |
krenbluetoothsig | 0:876e59f87d50 | 36 | #define BT_MESH_MODEL_OP_GEN_ONOFF_SET_UNACK BT_MESH_MODEL_OP_2(0x82, 0x03) |
krenbluetoothsig | 0:876e59f87d50 | 37 | #define BT_MESH_MODEL_OP_GEN_ONOFF_STATUS BT_MESH_MODEL_OP_2(0x82, 0x04) |
krenbluetoothsig | 0:876e59f87d50 | 38 | |
krenbluetoothsig | 1:fb4893064dd4 | 39 | /* Publication Declarations */ |
krenbluetoothsig | 1:fb4893064dd4 | 40 | BT_MESH_HEALTH_PUB_DEFINE(health_pub, 0); |
krenbluetoothsig | 0:876e59f87d50 | 41 | BT_MESH_MODEL_PUB_DEFINE(gen_onoff_pub_cli, NULL, 2 + 2); |
krenbluetoothsig | 0:876e59f87d50 | 42 | |
krenbluetoothsig | 1:fb4893064dd4 | 43 | /* Button debounce timeout */ |
krenbluetoothsig | 1:fb4893064dd4 | 44 | #define BUTTON_DEBOUNCE_DELAY_MS 250 |
krenbluetoothsig | 0:876e59f87d50 | 45 | |
krenbluetoothsig | 1:fb4893064dd4 | 46 | /* LED matrix scroll speed */ |
krenbluetoothsig | 1:fb4893064dd4 | 47 | #define SCROLL_SPEED K_MSEC(500) |
krenbluetoothsig | 1:fb4893064dd4 | 48 | |
krenbluetoothsig | 1:fb4893064dd4 | 49 | /* Buzzer definition, no used in this example. */ |
krenbluetoothsig | 1:fb4893064dd4 | 50 | #define BUZZER_PIN EXT_P0_GPIO_PIN |
krenbluetoothsig | 1:fb4893064dd4 | 51 | #define BEEP_DURATION K_MSEC(60) |
krenbluetoothsig | 0:876e59f87d50 | 52 | |
krenbluetoothsig | 1:fb4893064dd4 | 53 | /* NVM offset */ |
krenbluetoothsig | 1:fb4893064dd4 | 54 | #define SEQ_PER_BIT 976 |
krenbluetoothsig | 1:fb4893064dd4 | 55 | #define SEQ_PAGE (NRF_FICR->CODEPAGESIZE * (NRF_FICR->CODESIZE - 1)) |
krenbluetoothsig | 1:fb4893064dd4 | 56 | #define SEQ_MAX (NRF_FICR->CODEPAGESIZE * 8 * SEQ_PER_BIT) |
krenbluetoothsig | 0:876e59f87d50 | 57 | |
krenbluetoothsig | 1:fb4893064dd4 | 58 | /* Key definition, it's pre-configured, not need to do provisioning. */ |
krenbluetoothsig | 1:fb4893064dd4 | 59 | static const u8_t net_key[16] = { |
krenbluetoothsig | 1:fb4893064dd4 | 60 | 0xf1, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, |
krenbluetoothsig | 1:fb4893064dd4 | 61 | 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, |
krenbluetoothsig | 1:fb4893064dd4 | 62 | }; |
krenbluetoothsig | 1:fb4893064dd4 | 63 | static const u8_t dev_key[16] = { |
krenbluetoothsig | 1:fb4893064dd4 | 64 | 0xf1, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, |
krenbluetoothsig | 1:fb4893064dd4 | 65 | 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, |
krenbluetoothsig | 1:fb4893064dd4 | 66 | }; |
krenbluetoothsig | 1:fb4893064dd4 | 67 | static const u8_t app_key[16] = { |
krenbluetoothsig | 1:fb4893064dd4 | 68 | 0xf1, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, |
krenbluetoothsig | 1:fb4893064dd4 | 69 | 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, |
krenbluetoothsig | 0:876e59f87d50 | 70 | }; |
krenbluetoothsig | 0:876e59f87d50 | 71 | |
krenbluetoothsig | 0:876e59f87d50 | 72 | |
krenbluetoothsig | 1:fb4893064dd4 | 73 | /* group address string. */ |
krenbluetoothsig | 1:fb4893064dd4 | 74 | const char *groupAddress2String[] = { |
krenbluetoothsig | 1:fb4893064dd4 | 75 | "Bedroom", |
krenbluetoothsig | 1:fb4893064dd4 | 76 | "Living", |
krenbluetoothsig | 1:fb4893064dd4 | 77 | "Dining", |
krenbluetoothsig | 1:fb4893064dd4 | 78 | "Garage" |
krenbluetoothsig | 0:876e59f87d50 | 79 | }; |
krenbluetoothsig | 0:876e59f87d50 | 80 | |
krenbluetoothsig | 1:fb4893064dd4 | 81 | static struct device *gpio; |
krenbluetoothsig | 1:fb4893064dd4 | 82 | static struct device *nvm; |
krenbluetoothsig | 1:fb4893064dd4 | 83 | static struct device *pwm; |
krenbluetoothsig | 1:fb4893064dd4 | 84 | |
krenbluetoothsig | 1:fb4893064dd4 | 85 | static struct k_work button_work; |
krenbluetoothsig | 1:fb4893064dd4 | 86 | static u32_t time, last_time; |
krenbluetoothsig | 1:fb4893064dd4 | 87 | |
krenbluetoothsig | 1:fb4893064dd4 | 88 | const u16_t net_idx; |
krenbluetoothsig | 1:fb4893064dd4 | 89 | const u16_t app_idx; |
krenbluetoothsig | 1:fb4893064dd4 | 90 | const u32_t iv_index; |
krenbluetoothsig | 1:fb4893064dd4 | 91 | u8_t flags; |
krenbluetoothsig | 1:fb4893064dd4 | 92 | u16_t addr = NODE_ADDR; |
krenbluetoothsig | 1:fb4893064dd4 | 93 | u16_t groupAddress = GROUP_ADDR; |
krenbluetoothsig | 1:fb4893064dd4 | 94 | static u32_t seq; |
krenbluetoothsig | 0:876e59f87d50 | 95 | |
krenbluetoothsig | 1:fb4893064dd4 | 96 | /* Transaction ID for Generic OnOff Set */ |
krenbluetoothsig | 1:fb4893064dd4 | 97 | static u8_t trans_ID = 0; |
krenbluetoothsig | 1:fb4893064dd4 | 98 | |
krenbluetoothsig | 1:fb4893064dd4 | 99 | /* GenericOnOffSet state */ |
krenbluetoothsig | 1:fb4893064dd4 | 100 | u8_t OnOff_Value = 0; |
krenbluetoothsig | 1:fb4893064dd4 | 101 | |
krenbluetoothsig | 1:fb4893064dd4 | 102 | /* Model Operation decleration */ |
krenbluetoothsig | 1:fb4893064dd4 | 103 | static void gen_onoff_set(struct bt_mesh_model *model, |
krenbluetoothsig | 1:fb4893064dd4 | 104 | struct bt_mesh_msg_ctx *ctx, |
krenbluetoothsig | 1:fb4893064dd4 | 105 | struct net_buf_simple *buf); |
krenbluetoothsig | 1:fb4893064dd4 | 106 | |
krenbluetoothsig | 1:fb4893064dd4 | 107 | static void gen_onoff_set_unack(struct bt_mesh_model *model, |
krenbluetoothsig | 1:fb4893064dd4 | 108 | struct bt_mesh_msg_ctx *ctx, |
krenbluetoothsig | 1:fb4893064dd4 | 109 | struct net_buf_simple *buf); |
krenbluetoothsig | 1:fb4893064dd4 | 110 | |
krenbluetoothsig | 1:fb4893064dd4 | 111 | static void gen_onoff_get(struct bt_mesh_model *model, |
krenbluetoothsig | 1:fb4893064dd4 | 112 | struct bt_mesh_msg_ctx *ctx, |
krenbluetoothsig | 1:fb4893064dd4 | 113 | struct net_buf_simple *buf); |
krenbluetoothsig | 0:876e59f87d50 | 114 | |
krenbluetoothsig | 1:fb4893064dd4 | 115 | static void gen_onoff_status(struct bt_mesh_model *model, |
krenbluetoothsig | 1:fb4893064dd4 | 116 | struct bt_mesh_msg_ctx *ctx, |
krenbluetoothsig | 1:fb4893064dd4 | 117 | struct net_buf_simple *buf); |
krenbluetoothsig | 1:fb4893064dd4 | 118 | static void genericOnOffSet(void); |
krenbluetoothsig | 1:fb4893064dd4 | 119 | |
krenbluetoothsig | 0:876e59f87d50 | 120 | |
krenbluetoothsig | 1:fb4893064dd4 | 121 | /* switch group address like round robin. */ |
krenbluetoothsig | 1:fb4893064dd4 | 122 | u16_t board_set_target(void) |
krenbluetoothsig | 0:876e59f87d50 | 123 | { |
krenbluetoothsig | 1:fb4893064dd4 | 124 | switch (groupAddress) { |
krenbluetoothsig | 1:fb4893064dd4 | 125 | case GROUP_ADDR: |
krenbluetoothsig | 1:fb4893064dd4 | 126 | groupAddress++; |
krenbluetoothsig | 1:fb4893064dd4 | 127 | break; |
krenbluetoothsig | 1:fb4893064dd4 | 128 | case (GROUP_ADDR + 3): |
krenbluetoothsig | 1:fb4893064dd4 | 129 | groupAddress = GROUP_ADDR; |
krenbluetoothsig | 1:fb4893064dd4 | 130 | break; |
krenbluetoothsig | 1:fb4893064dd4 | 131 | default: |
krenbluetoothsig | 1:fb4893064dd4 | 132 | groupAddress++; |
krenbluetoothsig | 1:fb4893064dd4 | 133 | break; |
krenbluetoothsig | 1:fb4893064dd4 | 134 | } |
krenbluetoothsig | 0:876e59f87d50 | 135 | |
krenbluetoothsig | 1:fb4893064dd4 | 136 | return groupAddress; |
krenbluetoothsig | 1:fb4893064dd4 | 137 | } |
krenbluetoothsig | 1:fb4893064dd4 | 138 | |
krenbluetoothsig | 1:fb4893064dd4 | 139 | void board_seq_update(u32_t seq) |
krenbluetoothsig | 1:fb4893064dd4 | 140 | { |
krenbluetoothsig | 1:fb4893064dd4 | 141 | u32_t loc, seq_map; |
krenbluetoothsig | 1:fb4893064dd4 | 142 | int err; |
krenbluetoothsig | 1:fb4893064dd4 | 143 | |
krenbluetoothsig | 1:fb4893064dd4 | 144 | if (seq % SEQ_PER_BIT) { |
krenbluetoothsig | 1:fb4893064dd4 | 145 | return; |
krenbluetoothsig | 1:fb4893064dd4 | 146 | } |
krenbluetoothsig | 1:fb4893064dd4 | 147 | |
krenbluetoothsig | 1:fb4893064dd4 | 148 | loc = (SEQ_PAGE + ((seq / SEQ_PER_BIT) / 32)); |
krenbluetoothsig | 1:fb4893064dd4 | 149 | |
krenbluetoothsig | 1:fb4893064dd4 | 150 | err = flash_read(nvm, loc, &seq_map, sizeof(seq_map)); |
krenbluetoothsig | 1:fb4893064dd4 | 151 | if (err) { |
krenbluetoothsig | 1:fb4893064dd4 | 152 | printk("flash_read err %d\n", err); |
krenbluetoothsig | 0:876e59f87d50 | 153 | return; |
krenbluetoothsig | 0:876e59f87d50 | 154 | } |
krenbluetoothsig | 0:876e59f87d50 | 155 | |
krenbluetoothsig | 1:fb4893064dd4 | 156 | seq_map >>= 1; |
krenbluetoothsig | 0:876e59f87d50 | 157 | |
krenbluetoothsig | 1:fb4893064dd4 | 158 | flash_write_protection_set(nvm, false); |
krenbluetoothsig | 1:fb4893064dd4 | 159 | err = flash_write(nvm, loc, &seq_map, sizeof(seq_map)); |
krenbluetoothsig | 1:fb4893064dd4 | 160 | flash_write_protection_set(nvm, true); |
krenbluetoothsig | 1:fb4893064dd4 | 161 | if (err) { |
krenbluetoothsig | 1:fb4893064dd4 | 162 | printk("flash_write err %d\n", err); |
krenbluetoothsig | 1:fb4893064dd4 | 163 | } |
krenbluetoothsig | 0:876e59f87d50 | 164 | } |
krenbluetoothsig | 0:876e59f87d50 | 165 | |
krenbluetoothsig | 1:fb4893064dd4 | 166 | static u32_t get_seq(void) |
krenbluetoothsig | 0:876e59f87d50 | 167 | { |
krenbluetoothsig | 1:fb4893064dd4 | 168 | u32_t seq_map, seq = 0; |
krenbluetoothsig | 1:fb4893064dd4 | 169 | int err, i; |
krenbluetoothsig | 1:fb4893064dd4 | 170 | |
krenbluetoothsig | 1:fb4893064dd4 | 171 | for (i = 0; i < NRF_FICR->CODEPAGESIZE / sizeof(seq_map); i++) { |
krenbluetoothsig | 1:fb4893064dd4 | 172 | err = flash_read(nvm, SEQ_PAGE + (i * sizeof(seq_map)), |
krenbluetoothsig | 1:fb4893064dd4 | 173 | &seq_map, sizeof(seq_map)); |
krenbluetoothsig | 1:fb4893064dd4 | 174 | if (err) { |
krenbluetoothsig | 1:fb4893064dd4 | 175 | printk("flash_read err %d\n", err); |
krenbluetoothsig | 1:fb4893064dd4 | 176 | return seq; |
krenbluetoothsig | 1:fb4893064dd4 | 177 | } |
krenbluetoothsig | 1:fb4893064dd4 | 178 | |
krenbluetoothsig | 1:fb4893064dd4 | 179 | printk("seq_map 0x%08x\n", seq_map); |
krenbluetoothsig | 1:fb4893064dd4 | 180 | |
krenbluetoothsig | 1:fb4893064dd4 | 181 | if (seq_map) { |
krenbluetoothsig | 1:fb4893064dd4 | 182 | seq = ((i * 32) + |
krenbluetoothsig | 1:fb4893064dd4 | 183 | (32 - popcount(seq_map))) * SEQ_PER_BIT; |
krenbluetoothsig | 1:fb4893064dd4 | 184 | if (!seq) { |
krenbluetoothsig | 1:fb4893064dd4 | 185 | return 0; |
krenbluetoothsig | 1:fb4893064dd4 | 186 | } |
krenbluetoothsig | 0:876e59f87d50 | 187 | |
krenbluetoothsig | 1:fb4893064dd4 | 188 | break; |
krenbluetoothsig | 1:fb4893064dd4 | 189 | } |
krenbluetoothsig | 1:fb4893064dd4 | 190 | } |
krenbluetoothsig | 1:fb4893064dd4 | 191 | |
krenbluetoothsig | 1:fb4893064dd4 | 192 | seq += SEQ_PER_BIT; |
krenbluetoothsig | 1:fb4893064dd4 | 193 | if (seq >= SEQ_MAX) { |
krenbluetoothsig | 1:fb4893064dd4 | 194 | seq = 0; |
krenbluetoothsig | 1:fb4893064dd4 | 195 | } |
krenbluetoothsig | 1:fb4893064dd4 | 196 | |
krenbluetoothsig | 1:fb4893064dd4 | 197 | if (seq) { |
krenbluetoothsig | 1:fb4893064dd4 | 198 | seq_map >>= 1; |
krenbluetoothsig | 1:fb4893064dd4 | 199 | flash_write_protection_set(nvm, false); |
krenbluetoothsig | 1:fb4893064dd4 | 200 | err = flash_write(nvm, SEQ_PAGE + (i * sizeof(seq_map)), |
krenbluetoothsig | 1:fb4893064dd4 | 201 | &seq_map, sizeof(seq_map)); |
krenbluetoothsig | 1:fb4893064dd4 | 202 | flash_write_protection_set(nvm, true); |
krenbluetoothsig | 1:fb4893064dd4 | 203 | if (err) { |
krenbluetoothsig | 1:fb4893064dd4 | 204 | printk("flash_write err %d\n", err); |
krenbluetoothsig | 1:fb4893064dd4 | 205 | } |
krenbluetoothsig | 1:fb4893064dd4 | 206 | } else { |
krenbluetoothsig | 1:fb4893064dd4 | 207 | printk("Performing flash erase of page 0x%08x\n", SEQ_PAGE); |
krenbluetoothsig | 1:fb4893064dd4 | 208 | err = flash_erase(nvm, SEQ_PAGE, NRF_FICR->CODEPAGESIZE); |
krenbluetoothsig | 1:fb4893064dd4 | 209 | if (err) { |
krenbluetoothsig | 1:fb4893064dd4 | 210 | printk("flash_erase err %d\n", err); |
krenbluetoothsig | 1:fb4893064dd4 | 211 | } |
krenbluetoothsig | 1:fb4893064dd4 | 212 | } |
krenbluetoothsig | 1:fb4893064dd4 | 213 | |
krenbluetoothsig | 1:fb4893064dd4 | 214 | return seq; |
krenbluetoothsig | 0:876e59f87d50 | 215 | } |
krenbluetoothsig | 0:876e59f87d50 | 216 | |
krenbluetoothsig | 1:fb4893064dd4 | 217 | /* Callback function for button B pressed, it's scheduled by OS, out of interrupt routine |
krenbluetoothsig | 1:fb4893064dd4 | 218 | * it's safe to stay here longer. */ |
krenbluetoothsig | 1:fb4893064dd4 | 219 | static void button_send_pressed(struct k_work *work) |
krenbluetoothsig | 1:fb4893064dd4 | 220 | { |
krenbluetoothsig | 1:fb4893064dd4 | 221 | struct mb_display *disp = mb_display_get(); |
krenbluetoothsig | 1:fb4893064dd4 | 222 | |
krenbluetoothsig | 1:fb4893064dd4 | 223 | printk("button_send_pressed()\n"); |
krenbluetoothsig | 1:fb4893064dd4 | 224 | if(OnOff_Value % 2) { |
krenbluetoothsig | 1:fb4893064dd4 | 225 | mb_display_print(disp, MB_DISPLAY_MODE_SINGLE, 100000, |
krenbluetoothsig | 1:fb4893064dd4 | 226 | "%s", groupAddress2String[groupAddress - GROUP_ADDR]); |
krenbluetoothsig | 1:fb4893064dd4 | 227 | } |
krenbluetoothsig | 1:fb4893064dd4 | 228 | else |
krenbluetoothsig | 1:fb4893064dd4 | 229 | { |
krenbluetoothsig | 1:fb4893064dd4 | 230 | mb_display_print(disp, MB_DISPLAY_MODE_SINGLE, 100000, |
krenbluetoothsig | 1:fb4893064dd4 | 231 | "%s", " "); |
krenbluetoothsig | 1:fb4893064dd4 | 232 | } |
krenbluetoothsig | 1:fb4893064dd4 | 233 | genericOnOffSet(); |
krenbluetoothsig | 1:fb4893064dd4 | 234 | } |
krenbluetoothsig | 1:fb4893064dd4 | 235 | |
krenbluetoothsig | 1:fb4893064dd4 | 236 | /* button B callback, direct invoke by interrupt routine, need to be out of this callback ASAP. */ |
krenbluetoothsig | 1:fb4893064dd4 | 237 | static void button_pressed(struct device *dev, struct gpio_callback *cb, |
krenbluetoothsig | 0:876e59f87d50 | 238 | uint32_t pins) |
krenbluetoothsig | 0:876e59f87d50 | 239 | { |
krenbluetoothsig | 1:fb4893064dd4 | 240 | struct mb_display *disp = mb_display_get(); |
krenbluetoothsig | 1:fb4893064dd4 | 241 | |
krenbluetoothsig | 0:876e59f87d50 | 242 | /* |
krenbluetoothsig | 0:876e59f87d50 | 243 | * One button press within a 1 second interval sends an on message |
krenbluetoothsig | 0:876e59f87d50 | 244 | * More than one button press sends an off message |
krenbluetoothsig | 0:876e59f87d50 | 245 | */ |
krenbluetoothsig | 0:876e59f87d50 | 246 | time = k_uptime_get_32(); |
krenbluetoothsig | 0:876e59f87d50 | 247 | |
krenbluetoothsig | 0:876e59f87d50 | 248 | /* debounce the switch */ |
krenbluetoothsig | 0:876e59f87d50 | 249 | if (time < last_time + BUTTON_DEBOUNCE_DELAY_MS) { |
krenbluetoothsig | 0:876e59f87d50 | 250 | last_time = time; |
krenbluetoothsig | 0:876e59f87d50 | 251 | return; |
krenbluetoothsig | 0:876e59f87d50 | 252 | } |
krenbluetoothsig | 0:876e59f87d50 | 253 | |
krenbluetoothsig | 0:876e59f87d50 | 254 | if (pins & BIT(SW0_GPIO_PIN)) { |
krenbluetoothsig | 1:fb4893064dd4 | 255 | k_work_submit(&button_work); |
krenbluetoothsig | 1:fb4893064dd4 | 256 | } |
krenbluetoothsig | 1:fb4893064dd4 | 257 | else { |
krenbluetoothsig | 1:fb4893064dd4 | 258 | board_set_target(); |
krenbluetoothsig | 1:fb4893064dd4 | 259 | |
krenbluetoothsig | 1:fb4893064dd4 | 260 | mb_display_print(disp, MB_DISPLAY_MODE_DEFAULT, SCROLL_SPEED, |
krenbluetoothsig | 1:fb4893064dd4 | 261 | "%s", groupAddress2String[groupAddress - GROUP_ADDR]); |
krenbluetoothsig | 0:876e59f87d50 | 262 | } |
krenbluetoothsig | 1:fb4893064dd4 | 263 | last_time = time; |
krenbluetoothsig | 1:fb4893064dd4 | 264 | } |
krenbluetoothsig | 1:fb4893064dd4 | 265 | |
krenbluetoothsig | 1:fb4893064dd4 | 266 | static const struct { |
krenbluetoothsig | 1:fb4893064dd4 | 267 | char note; |
krenbluetoothsig | 1:fb4893064dd4 | 268 | u32_t period; |
krenbluetoothsig | 1:fb4893064dd4 | 269 | u32_t sharp; |
krenbluetoothsig | 1:fb4893064dd4 | 270 | } period_map[] = { |
krenbluetoothsig | 1:fb4893064dd4 | 271 | { 'C', 3822, 3608 }, |
krenbluetoothsig | 1:fb4893064dd4 | 272 | { 'D', 3405, 3214 }, |
krenbluetoothsig | 1:fb4893064dd4 | 273 | { 'E', 3034, 3034 }, |
krenbluetoothsig | 1:fb4893064dd4 | 274 | { 'F', 2863, 2703 }, |
krenbluetoothsig | 1:fb4893064dd4 | 275 | { 'G', 2551, 2407 }, |
krenbluetoothsig | 1:fb4893064dd4 | 276 | { 'A', 2273, 2145 }, |
krenbluetoothsig | 1:fb4893064dd4 | 277 | { 'B', 2025, 2025 }, |
krenbluetoothsig | 1:fb4893064dd4 | 278 | }; |
krenbluetoothsig | 1:fb4893064dd4 | 279 | |
krenbluetoothsig | 1:fb4893064dd4 | 280 | static u32_t get_period(char note, bool sharp) |
krenbluetoothsig | 1:fb4893064dd4 | 281 | { |
krenbluetoothsig | 1:fb4893064dd4 | 282 | int i; |
krenbluetoothsig | 1:fb4893064dd4 | 283 | |
krenbluetoothsig | 1:fb4893064dd4 | 284 | if (note == ' ') { |
krenbluetoothsig | 1:fb4893064dd4 | 285 | return 0; |
krenbluetoothsig | 0:876e59f87d50 | 286 | } |
krenbluetoothsig | 0:876e59f87d50 | 287 | |
krenbluetoothsig | 1:fb4893064dd4 | 288 | for (i = 0; i < ARRAY_SIZE(period_map); i++) { |
krenbluetoothsig | 1:fb4893064dd4 | 289 | if (period_map[i].note != note) { |
krenbluetoothsig | 1:fb4893064dd4 | 290 | continue; |
krenbluetoothsig | 1:fb4893064dd4 | 291 | } |
krenbluetoothsig | 0:876e59f87d50 | 292 | |
krenbluetoothsig | 1:fb4893064dd4 | 293 | if (sharp) { |
krenbluetoothsig | 1:fb4893064dd4 | 294 | return period_map[i].sharp; |
krenbluetoothsig | 1:fb4893064dd4 | 295 | } else { |
krenbluetoothsig | 1:fb4893064dd4 | 296 | return period_map[i].period; |
krenbluetoothsig | 1:fb4893064dd4 | 297 | } |
krenbluetoothsig | 1:fb4893064dd4 | 298 | } |
krenbluetoothsig | 1:fb4893064dd4 | 299 | |
krenbluetoothsig | 1:fb4893064dd4 | 300 | return 1500; |
krenbluetoothsig | 0:876e59f87d50 | 301 | } |
krenbluetoothsig | 0:876e59f87d50 | 302 | |
krenbluetoothsig | 0:876e59f87d50 | 303 | |
krenbluetoothsig | 1:fb4893064dd4 | 304 | void board_heartbeat(u8_t hops, u16_t feat) |
krenbluetoothsig | 0:876e59f87d50 | 305 | { |
krenbluetoothsig | 0:876e59f87d50 | 306 | struct mb_display *disp = mb_display_get(); |
krenbluetoothsig | 1:fb4893064dd4 | 307 | const struct mb_image hops_img[] = { |
krenbluetoothsig | 1:fb4893064dd4 | 308 | MB_IMAGE({ 1, 1, 1, 1, 1 }, |
krenbluetoothsig | 1:fb4893064dd4 | 309 | { 1, 1, 1, 1, 1 }, |
krenbluetoothsig | 1:fb4893064dd4 | 310 | { 1, 1, 1, 1, 1 }, |
krenbluetoothsig | 1:fb4893064dd4 | 311 | { 1, 1, 1, 1, 1 }, |
krenbluetoothsig | 1:fb4893064dd4 | 312 | { 1, 1, 1, 1, 1 }), |
krenbluetoothsig | 1:fb4893064dd4 | 313 | MB_IMAGE({ 1, 1, 1, 1, 1 }, |
krenbluetoothsig | 1:fb4893064dd4 | 314 | { 1, 1, 1, 1, 1 }, |
krenbluetoothsig | 1:fb4893064dd4 | 315 | { 1, 1, 0, 1, 1 }, |
krenbluetoothsig | 1:fb4893064dd4 | 316 | { 1, 1, 1, 1, 1 }, |
krenbluetoothsig | 1:fb4893064dd4 | 317 | { 1, 1, 1, 1, 1 }), |
krenbluetoothsig | 1:fb4893064dd4 | 318 | MB_IMAGE({ 1, 1, 1, 1, 1 }, |
krenbluetoothsig | 1:fb4893064dd4 | 319 | { 1, 0, 0, 0, 1 }, |
krenbluetoothsig | 1:fb4893064dd4 | 320 | { 1, 0, 0, 0, 1 }, |
krenbluetoothsig | 1:fb4893064dd4 | 321 | { 1, 0, 0, 0, 1 }, |
krenbluetoothsig | 1:fb4893064dd4 | 322 | { 1, 1, 1, 1, 1 }), |
krenbluetoothsig | 1:fb4893064dd4 | 323 | MB_IMAGE({ 1, 1, 1, 1, 1 }, |
krenbluetoothsig | 1:fb4893064dd4 | 324 | { 1, 0, 0, 0, 1 }, |
krenbluetoothsig | 1:fb4893064dd4 | 325 | { 1, 0, 0, 0, 1 }, |
krenbluetoothsig | 1:fb4893064dd4 | 326 | { 1, 0, 0, 0, 1 }, |
krenbluetoothsig | 1:fb4893064dd4 | 327 | { 1, 1, 1, 1, 1 }), |
krenbluetoothsig | 1:fb4893064dd4 | 328 | MB_IMAGE({ 1, 0, 1, 0, 1 }, |
krenbluetoothsig | 1:fb4893064dd4 | 329 | { 0, 0, 0, 0, 0 }, |
krenbluetoothsig | 1:fb4893064dd4 | 330 | { 1, 0, 0, 0, 1 }, |
krenbluetoothsig | 1:fb4893064dd4 | 331 | { 0, 0, 0, 0, 0 }, |
krenbluetoothsig | 1:fb4893064dd4 | 332 | { 1, 0, 1, 0, 1 }) |
krenbluetoothsig | 1:fb4893064dd4 | 333 | }; |
krenbluetoothsig | 0:876e59f87d50 | 334 | |
krenbluetoothsig | 1:fb4893064dd4 | 335 | printk("%u hops\n", hops); |
krenbluetoothsig | 0:876e59f87d50 | 336 | |
krenbluetoothsig | 1:fb4893064dd4 | 337 | if (hops) { |
krenbluetoothsig | 1:fb4893064dd4 | 338 | hops = min(hops, ARRAY_SIZE(hops_img)); |
krenbluetoothsig | 1:fb4893064dd4 | 339 | mb_display_image(disp, MB_DISPLAY_MODE_SINGLE, K_SECONDS(2), |
krenbluetoothsig | 1:fb4893064dd4 | 340 | &hops_img[hops - 1], 1); |
krenbluetoothsig | 1:fb4893064dd4 | 341 | } |
krenbluetoothsig | 0:876e59f87d50 | 342 | } |
krenbluetoothsig | 0:876e59f87d50 | 343 | |
krenbluetoothsig | 1:fb4893064dd4 | 344 | void board_attention(bool attention) |
krenbluetoothsig | 0:876e59f87d50 | 345 | { |
krenbluetoothsig | 1:fb4893064dd4 | 346 | struct mb_display *disp = mb_display_get(); |
krenbluetoothsig | 1:fb4893064dd4 | 347 | static const struct mb_image attn_img[] = { |
krenbluetoothsig | 1:fb4893064dd4 | 348 | MB_IMAGE({ 0, 0, 0, 0, 0 }, |
krenbluetoothsig | 1:fb4893064dd4 | 349 | { 0, 0, 0, 0, 0 }, |
krenbluetoothsig | 1:fb4893064dd4 | 350 | { 0, 0, 1, 0, 0 }, |
krenbluetoothsig | 1:fb4893064dd4 | 351 | { 0, 0, 0, 0, 0 }, |
krenbluetoothsig | 1:fb4893064dd4 | 352 | { 0, 0, 0, 0, 0 }), |
krenbluetoothsig | 1:fb4893064dd4 | 353 | MB_IMAGE({ 0, 0, 0, 0, 0 }, |
krenbluetoothsig | 1:fb4893064dd4 | 354 | { 0, 1, 1, 1, 0 }, |
krenbluetoothsig | 1:fb4893064dd4 | 355 | { 0, 1, 1, 1, 0 }, |
krenbluetoothsig | 1:fb4893064dd4 | 356 | { 0, 1, 1, 1, 0 }, |
krenbluetoothsig | 1:fb4893064dd4 | 357 | { 0, 0, 0, 0, 0 }), |
krenbluetoothsig | 1:fb4893064dd4 | 358 | MB_IMAGE({ 1, 1, 1, 1, 1 }, |
krenbluetoothsig | 1:fb4893064dd4 | 359 | { 1, 1, 1, 1, 1 }, |
krenbluetoothsig | 1:fb4893064dd4 | 360 | { 1, 1, 0, 1, 1 }, |
krenbluetoothsig | 1:fb4893064dd4 | 361 | { 1, 1, 1, 1, 1 }, |
krenbluetoothsig | 1:fb4893064dd4 | 362 | { 1, 1, 1, 1, 1 }), |
krenbluetoothsig | 1:fb4893064dd4 | 363 | MB_IMAGE({ 1, 1, 1, 1, 1 }, |
krenbluetoothsig | 1:fb4893064dd4 | 364 | { 1, 0, 0, 0, 1 }, |
krenbluetoothsig | 1:fb4893064dd4 | 365 | { 1, 0, 0, 0, 1 }, |
krenbluetoothsig | 1:fb4893064dd4 | 366 | { 1, 0, 0, 0, 1 }, |
krenbluetoothsig | 1:fb4893064dd4 | 367 | { 1, 1, 1, 1, 1 }), |
krenbluetoothsig | 1:fb4893064dd4 | 368 | }; |
krenbluetoothsig | 0:876e59f87d50 | 369 | |
krenbluetoothsig | 1:fb4893064dd4 | 370 | if (attention) { |
krenbluetoothsig | 1:fb4893064dd4 | 371 | mb_display_image(disp, |
krenbluetoothsig | 1:fb4893064dd4 | 372 | MB_DISPLAY_MODE_DEFAULT | MB_DISPLAY_FLAG_LOOP, |
krenbluetoothsig | 1:fb4893064dd4 | 373 | K_MSEC(150), attn_img, ARRAY_SIZE(attn_img)); |
krenbluetoothsig | 1:fb4893064dd4 | 374 | } else { |
krenbluetoothsig | 1:fb4893064dd4 | 375 | mb_display_stop(disp); |
krenbluetoothsig | 1:fb4893064dd4 | 376 | } |
krenbluetoothsig | 1:fb4893064dd4 | 377 | } |
krenbluetoothsig | 0:876e59f87d50 | 378 | |
krenbluetoothsig | 0:876e59f87d50 | 379 | static void configure_button(void) |
krenbluetoothsig | 0:876e59f87d50 | 380 | { |
krenbluetoothsig | 0:876e59f87d50 | 381 | static struct gpio_callback button_cb; |
krenbluetoothsig | 0:876e59f87d50 | 382 | |
krenbluetoothsig | 0:876e59f87d50 | 383 | /* Initialize the button debouncer */ |
krenbluetoothsig | 0:876e59f87d50 | 384 | last_time = k_uptime_get_32(); |
krenbluetoothsig | 0:876e59f87d50 | 385 | |
krenbluetoothsig | 0:876e59f87d50 | 386 | k_work_init(&button_work, button_send_pressed); |
krenbluetoothsig | 0:876e59f87d50 | 387 | |
krenbluetoothsig | 0:876e59f87d50 | 388 | gpio = device_get_binding(SW0_GPIO_NAME); |
krenbluetoothsig | 0:876e59f87d50 | 389 | |
krenbluetoothsig | 0:876e59f87d50 | 390 | gpio_pin_configure(gpio, SW0_GPIO_PIN, |
krenbluetoothsig | 0:876e59f87d50 | 391 | (GPIO_DIR_IN | GPIO_INT | GPIO_INT_EDGE | |
krenbluetoothsig | 0:876e59f87d50 | 392 | GPIO_INT_ACTIVE_LOW)); |
krenbluetoothsig | 1:fb4893064dd4 | 393 | gpio_pin_configure(gpio, SW1_GPIO_PIN, |
krenbluetoothsig | 1:fb4893064dd4 | 394 | (GPIO_DIR_IN | GPIO_INT | GPIO_INT_EDGE | |
krenbluetoothsig | 1:fb4893064dd4 | 395 | GPIO_INT_ACTIVE_LOW)); |
krenbluetoothsig | 0:876e59f87d50 | 396 | |
krenbluetoothsig | 0:876e59f87d50 | 397 | gpio_init_callback(&button_cb, button_pressed, |
krenbluetoothsig | 1:fb4893064dd4 | 398 | BIT(SW0_GPIO_PIN) | BIT(SW1_GPIO_PIN)); |
krenbluetoothsig | 0:876e59f87d50 | 399 | gpio_add_callback(gpio, &button_cb); |
krenbluetoothsig | 0:876e59f87d50 | 400 | |
krenbluetoothsig | 0:876e59f87d50 | 401 | gpio_pin_enable_callback(gpio, SW0_GPIO_PIN); |
krenbluetoothsig | 0:876e59f87d50 | 402 | gpio_pin_enable_callback(gpio, SW1_GPIO_PIN); |
krenbluetoothsig | 0:876e59f87d50 | 403 | } |
krenbluetoothsig | 0:876e59f87d50 | 404 | |
krenbluetoothsig | 1:fb4893064dd4 | 405 | void board_init(u16_t *addr, u32_t *seq) |
krenbluetoothsig | 0:876e59f87d50 | 406 | { |
krenbluetoothsig | 1:fb4893064dd4 | 407 | struct mb_display *disp = mb_display_get(); |
krenbluetoothsig | 1:fb4893064dd4 | 408 | |
krenbluetoothsig | 1:fb4893064dd4 | 409 | printk("SEQ_PAGE 0x%08x\n", SEQ_PAGE); |
krenbluetoothsig | 1:fb4893064dd4 | 410 | |
krenbluetoothsig | 1:fb4893064dd4 | 411 | nvm = device_get_binding(FLASH_DEV_NAME); |
krenbluetoothsig | 1:fb4893064dd4 | 412 | pwm = device_get_binding(CONFIG_PWM_NRF5_SW_0_DEV_NAME); |
krenbluetoothsig | 1:fb4893064dd4 | 413 | |
krenbluetoothsig | 1:fb4893064dd4 | 414 | *addr = ( (u16_t)NRF_FICR->DEVICEADDR[0] ) & 0x7fff; |
krenbluetoothsig | 1:fb4893064dd4 | 415 | printk("FICR 0x%02x\n", *addr); |
krenbluetoothsig | 1:fb4893064dd4 | 416 | |
krenbluetoothsig | 1:fb4893064dd4 | 417 | *seq = get_seq(); |
krenbluetoothsig | 1:fb4893064dd4 | 418 | |
krenbluetoothsig | 1:fb4893064dd4 | 419 | mb_display_print(disp, MB_DISPLAY_MODE_DEFAULT, SCROLL_SPEED, |
krenbluetoothsig | 1:fb4893064dd4 | 420 | "%s %s", "Client", groupAddress2String[groupAddress - GROUP_ADDR]); |
krenbluetoothsig | 0:876e59f87d50 | 421 | |
krenbluetoothsig | 0:876e59f87d50 | 422 | configure_button(); |
krenbluetoothsig | 0:876e59f87d50 | 423 | } |
krenbluetoothsig | 0:876e59f87d50 | 424 | |
krenbluetoothsig | 1:fb4893064dd4 | 425 | static void heartbeat(u8_t hops, u16_t feat) |
krenbluetoothsig | 1:fb4893064dd4 | 426 | { |
krenbluetoothsig | 1:fb4893064dd4 | 427 | board_heartbeat(hops, feat); |
krenbluetoothsig | 1:fb4893064dd4 | 428 | } |
krenbluetoothsig | 1:fb4893064dd4 | 429 | |
krenbluetoothsig | 1:fb4893064dd4 | 430 | static struct bt_mesh_cfg_srv cfg_srv = { |
krenbluetoothsig | 1:fb4893064dd4 | 431 | #if defined(CONFIG_BOARD_BBC_MICROBIT) |
krenbluetoothsig | 1:fb4893064dd4 | 432 | .relay = BT_MESH_RELAY_ENABLED, |
krenbluetoothsig | 1:fb4893064dd4 | 433 | .beacon = BT_MESH_BEACON_DISABLED, |
krenbluetoothsig | 1:fb4893064dd4 | 434 | #else |
krenbluetoothsig | 1:fb4893064dd4 | 435 | .relay = BT_MESH_RELAY_ENABLED, |
krenbluetoothsig | 1:fb4893064dd4 | 436 | .beacon = BT_MESH_BEACON_ENABLED, |
krenbluetoothsig | 1:fb4893064dd4 | 437 | #endif |
krenbluetoothsig | 1:fb4893064dd4 | 438 | .frnd = BT_MESH_FRIEND_NOT_SUPPORTED, |
krenbluetoothsig | 1:fb4893064dd4 | 439 | .default_ttl = 7, |
krenbluetoothsig | 1:fb4893064dd4 | 440 | |
krenbluetoothsig | 1:fb4893064dd4 | 441 | /* 3 transmissions with 20ms interval */ |
krenbluetoothsig | 1:fb4893064dd4 | 442 | .net_transmit = BT_MESH_TRANSMIT(2, 20), |
krenbluetoothsig | 1:fb4893064dd4 | 443 | .relay_retransmit = BT_MESH_TRANSMIT(3, 20), |
krenbluetoothsig | 1:fb4893064dd4 | 444 | |
krenbluetoothsig | 1:fb4893064dd4 | 445 | .hb_sub.func = heartbeat, |
krenbluetoothsig | 1:fb4893064dd4 | 446 | }; |
krenbluetoothsig | 1:fb4893064dd4 | 447 | |
krenbluetoothsig | 1:fb4893064dd4 | 448 | static struct bt_mesh_cfg_cli cfg_cli = { |
krenbluetoothsig | 1:fb4893064dd4 | 449 | }; |
krenbluetoothsig | 1:fb4893064dd4 | 450 | |
krenbluetoothsig | 1:fb4893064dd4 | 451 | |
krenbluetoothsig | 1:fb4893064dd4 | 452 | static void attention_on(struct bt_mesh_model *model) |
krenbluetoothsig | 1:fb4893064dd4 | 453 | { |
krenbluetoothsig | 1:fb4893064dd4 | 454 | printk("attention_on()\n"); |
krenbluetoothsig | 1:fb4893064dd4 | 455 | board_attention(true); |
krenbluetoothsig | 1:fb4893064dd4 | 456 | } |
krenbluetoothsig | 1:fb4893064dd4 | 457 | |
krenbluetoothsig | 1:fb4893064dd4 | 458 | static void attention_off(struct bt_mesh_model *model) |
krenbluetoothsig | 1:fb4893064dd4 | 459 | { |
krenbluetoothsig | 1:fb4893064dd4 | 460 | printk("attention_off()\n"); |
krenbluetoothsig | 1:fb4893064dd4 | 461 | board_attention(false); |
krenbluetoothsig | 1:fb4893064dd4 | 462 | } |
krenbluetoothsig | 1:fb4893064dd4 | 463 | |
krenbluetoothsig | 1:fb4893064dd4 | 464 | static const struct bt_mesh_health_srv_cb health_srv_cb = { |
krenbluetoothsig | 1:fb4893064dd4 | 465 | .attn_on = attention_on, |
krenbluetoothsig | 1:fb4893064dd4 | 466 | .attn_off = attention_off, |
krenbluetoothsig | 1:fb4893064dd4 | 467 | }; |
krenbluetoothsig | 1:fb4893064dd4 | 468 | |
krenbluetoothsig | 1:fb4893064dd4 | 469 | static struct bt_mesh_health_srv health_srv = { |
krenbluetoothsig | 1:fb4893064dd4 | 470 | .cb = &health_srv_cb, |
krenbluetoothsig | 1:fb4893064dd4 | 471 | }; |
krenbluetoothsig | 1:fb4893064dd4 | 472 | |
krenbluetoothsig | 1:fb4893064dd4 | 473 | /* |
krenbluetoothsig | 1:fb4893064dd4 | 474 | * OnOff Model Client Op Dispatch Table |
krenbluetoothsig | 1:fb4893064dd4 | 475 | */ |
krenbluetoothsig | 1:fb4893064dd4 | 476 | |
krenbluetoothsig | 1:fb4893064dd4 | 477 | static const struct bt_mesh_model_op gen_onoff_cli_op[] = { |
krenbluetoothsig | 1:fb4893064dd4 | 478 | { BT_MESH_MODEL_OP_GEN_ONOFF_STATUS, 1, gen_onoff_status }, |
krenbluetoothsig | 1:fb4893064dd4 | 479 | BT_MESH_MODEL_OP_END, |
krenbluetoothsig | 1:fb4893064dd4 | 480 | }; |
krenbluetoothsig | 1:fb4893064dd4 | 481 | |
krenbluetoothsig | 1:fb4893064dd4 | 482 | static struct bt_mesh_model root_models[] = { |
krenbluetoothsig | 1:fb4893064dd4 | 483 | BT_MESH_MODEL_CFG_SRV(&cfg_srv), |
krenbluetoothsig | 1:fb4893064dd4 | 484 | BT_MESH_MODEL_CFG_CLI(&cfg_cli), |
krenbluetoothsig | 1:fb4893064dd4 | 485 | BT_MESH_MODEL_HEALTH_SRV(&health_srv, &health_pub), |
krenbluetoothsig | 1:fb4893064dd4 | 486 | BT_MESH_MODEL(BT_MESH_MODEL_ID_GEN_ONOFF_CLI, gen_onoff_cli_op, |
krenbluetoothsig | 1:fb4893064dd4 | 487 | &gen_onoff_pub_cli, NULL), |
krenbluetoothsig | 1:fb4893064dd4 | 488 | }; |
krenbluetoothsig | 1:fb4893064dd4 | 489 | |
krenbluetoothsig | 1:fb4893064dd4 | 490 | static struct bt_mesh_elem elements[] = { |
krenbluetoothsig | 1:fb4893064dd4 | 491 | BT_MESH_ELEM(0, root_models, /* vnd_models */ BT_MESH_MODEL_NONE), |
krenbluetoothsig | 1:fb4893064dd4 | 492 | }; |
krenbluetoothsig | 1:fb4893064dd4 | 493 | |
krenbluetoothsig | 1:fb4893064dd4 | 494 | static const struct bt_mesh_comp comp = { |
krenbluetoothsig | 1:fb4893064dd4 | 495 | .cid = BT_COMP_ID_LF, |
krenbluetoothsig | 1:fb4893064dd4 | 496 | .elem = elements, |
krenbluetoothsig | 1:fb4893064dd4 | 497 | .elem_count = ARRAY_SIZE(elements), |
krenbluetoothsig | 1:fb4893064dd4 | 498 | }; |
krenbluetoothsig | 1:fb4893064dd4 | 499 | |
krenbluetoothsig | 1:fb4893064dd4 | 500 | /* |
krenbluetoothsig | 1:fb4893064dd4 | 501 | * Generic OnOff Model Server Message Handlers |
krenbluetoothsig | 1:fb4893064dd4 | 502 | * |
krenbluetoothsig | 1:fb4893064dd4 | 503 | * Mesh Model Specification 3.1.1 |
krenbluetoothsig | 1:fb4893064dd4 | 504 | * |
krenbluetoothsig | 1:fb4893064dd4 | 505 | */ |
krenbluetoothsig | 1:fb4893064dd4 | 506 | |
krenbluetoothsig | 1:fb4893064dd4 | 507 | static void gen_onoff_get(struct bt_mesh_model *model, |
krenbluetoothsig | 1:fb4893064dd4 | 508 | struct bt_mesh_msg_ctx *ctx, |
krenbluetoothsig | 1:fb4893064dd4 | 509 | struct net_buf_simple *buf) |
krenbluetoothsig | 1:fb4893064dd4 | 510 | { |
krenbluetoothsig | 1:fb4893064dd4 | 511 | printk("gen_onoff_get...\n"); |
krenbluetoothsig | 1:fb4893064dd4 | 512 | } |
krenbluetoothsig | 1:fb4893064dd4 | 513 | |
krenbluetoothsig | 1:fb4893064dd4 | 514 | static void gen_onoff_set_unack(struct bt_mesh_model *model, |
krenbluetoothsig | 1:fb4893064dd4 | 515 | struct bt_mesh_msg_ctx *ctx, |
krenbluetoothsig | 1:fb4893064dd4 | 516 | struct net_buf_simple *buf) |
krenbluetoothsig | 1:fb4893064dd4 | 517 | { |
krenbluetoothsig | 1:fb4893064dd4 | 518 | printk("gen_onoff_set_unack...\n"); |
krenbluetoothsig | 1:fb4893064dd4 | 519 | } |
krenbluetoothsig | 1:fb4893064dd4 | 520 | |
krenbluetoothsig | 1:fb4893064dd4 | 521 | static void gen_onoff_set(struct bt_mesh_model *model, |
krenbluetoothsig | 1:fb4893064dd4 | 522 | struct bt_mesh_msg_ctx *ctx, |
krenbluetoothsig | 1:fb4893064dd4 | 523 | struct net_buf_simple *buf) |
krenbluetoothsig | 1:fb4893064dd4 | 524 | { |
krenbluetoothsig | 1:fb4893064dd4 | 525 | printk("gen_onoff_set...\n"); |
krenbluetoothsig | 1:fb4893064dd4 | 526 | |
krenbluetoothsig | 1:fb4893064dd4 | 527 | } |
krenbluetoothsig | 1:fb4893064dd4 | 528 | |
krenbluetoothsig | 1:fb4893064dd4 | 529 | static void gen_onoff_status(struct bt_mesh_model *model, |
krenbluetoothsig | 1:fb4893064dd4 | 530 | struct bt_mesh_msg_ctx *ctx, |
krenbluetoothsig | 1:fb4893064dd4 | 531 | struct net_buf_simple *buf) |
krenbluetoothsig | 1:fb4893064dd4 | 532 | { |
krenbluetoothsig | 1:fb4893064dd4 | 533 | printk("gen_onoff_status...\n"); |
krenbluetoothsig | 1:fb4893064dd4 | 534 | } |
krenbluetoothsig | 1:fb4893064dd4 | 535 | |
krenbluetoothsig | 1:fb4893064dd4 | 536 | static void configure(void) |
krenbluetoothsig | 1:fb4893064dd4 | 537 | { |
krenbluetoothsig | 1:fb4893064dd4 | 538 | int status; |
krenbluetoothsig | 1:fb4893064dd4 | 539 | |
krenbluetoothsig | 1:fb4893064dd4 | 540 | printk("Configuring...\n"); |
krenbluetoothsig | 1:fb4893064dd4 | 541 | |
krenbluetoothsig | 1:fb4893064dd4 | 542 | /* Add Application Key */ |
krenbluetoothsig | 1:fb4893064dd4 | 543 | status = bt_mesh_cfg_app_key_add(net_idx, addr, net_idx, app_idx, app_key, NULL); |
krenbluetoothsig | 1:fb4893064dd4 | 544 | printk("bt_mesh_cfg_app_key_add = %d \n", status); |
krenbluetoothsig | 1:fb4893064dd4 | 545 | |
krenbluetoothsig | 1:fb4893064dd4 | 546 | |
krenbluetoothsig | 1:fb4893064dd4 | 547 | /* Bind to Generic on/off client model */ |
krenbluetoothsig | 1:fb4893064dd4 | 548 | status = bt_mesh_cfg_mod_app_bind(net_idx, addr, addr, app_idx, |
krenbluetoothsig | 1:fb4893064dd4 | 549 | BT_MESH_MODEL_ID_GEN_ONOFF_CLI, NULL); |
krenbluetoothsig | 1:fb4893064dd4 | 550 | printk("bt_mesh_cfg_mod_app_bind = %d \n", status); |
krenbluetoothsig | 1:fb4893064dd4 | 551 | |
krenbluetoothsig | 1:fb4893064dd4 | 552 | status = bt_mesh_cfg_mod_sub_add(net_idx, addr, addr, |
krenbluetoothsig | 1:fb4893064dd4 | 553 | GROUP_ADDR, BT_MESH_MODEL_ID_GEN_ONOFF_CLI, NULL); |
krenbluetoothsig | 1:fb4893064dd4 | 554 | printk("bt_mesh_cfg_mod_sub_add = %d \n", status); |
krenbluetoothsig | 1:fb4893064dd4 | 555 | |
krenbluetoothsig | 1:fb4893064dd4 | 556 | |
krenbluetoothsig | 1:fb4893064dd4 | 557 | struct bt_mesh_cfg_hb_sub sub = { |
krenbluetoothsig | 1:fb4893064dd4 | 558 | .src = PUBLISHER_ADDR, |
krenbluetoothsig | 1:fb4893064dd4 | 559 | .dst = GROUP_ADDR, |
krenbluetoothsig | 1:fb4893064dd4 | 560 | .period = 0x10, |
krenbluetoothsig | 1:fb4893064dd4 | 561 | }; |
krenbluetoothsig | 1:fb4893064dd4 | 562 | |
krenbluetoothsig | 1:fb4893064dd4 | 563 | bt_mesh_cfg_hb_sub_set(net_idx, addr, &sub, NULL); |
krenbluetoothsig | 1:fb4893064dd4 | 564 | printk("Subscribing to heartbeat messages\n"); |
krenbluetoothsig | 1:fb4893064dd4 | 565 | |
krenbluetoothsig | 1:fb4893064dd4 | 566 | |
krenbluetoothsig | 1:fb4893064dd4 | 567 | printk("Configuration complete\n"); |
krenbluetoothsig | 1:fb4893064dd4 | 568 | |
krenbluetoothsig | 1:fb4893064dd4 | 569 | } |
krenbluetoothsig | 1:fb4893064dd4 | 570 | |
krenbluetoothsig | 1:fb4893064dd4 | 571 | static const u8_t dev_uuid[16] = { 0xdd, 0xdd }; |
krenbluetoothsig | 1:fb4893064dd4 | 572 | |
krenbluetoothsig | 1:fb4893064dd4 | 573 | static const struct bt_mesh_prov prov = { |
krenbluetoothsig | 1:fb4893064dd4 | 574 | .uuid = dev_uuid, |
krenbluetoothsig | 1:fb4893064dd4 | 575 | }; |
krenbluetoothsig | 1:fb4893064dd4 | 576 | |
krenbluetoothsig | 0:876e59f87d50 | 577 | static void bt_ready(int err) |
krenbluetoothsig | 0:876e59f87d50 | 578 | { |
krenbluetoothsig | 0:876e59f87d50 | 579 | if (err) { |
krenbluetoothsig | 0:876e59f87d50 | 580 | printk("Bluetooth init failed (err %d)\n", err); |
krenbluetoothsig | 0:876e59f87d50 | 581 | return; |
krenbluetoothsig | 0:876e59f87d50 | 582 | } |
krenbluetoothsig | 0:876e59f87d50 | 583 | |
krenbluetoothsig | 0:876e59f87d50 | 584 | printk("Bluetooth initialized\n"); |
krenbluetoothsig | 0:876e59f87d50 | 585 | |
krenbluetoothsig | 0:876e59f87d50 | 586 | err = bt_mesh_init(&prov, &comp); |
krenbluetoothsig | 0:876e59f87d50 | 587 | if (err) { |
krenbluetoothsig | 0:876e59f87d50 | 588 | printk("Initializing mesh failed (err %d)\n", err); |
krenbluetoothsig | 0:876e59f87d50 | 589 | return; |
krenbluetoothsig | 0:876e59f87d50 | 590 | } |
krenbluetoothsig | 0:876e59f87d50 | 591 | |
krenbluetoothsig | 1:fb4893064dd4 | 592 | printk("Mesh initialized\n"); |
krenbluetoothsig | 0:876e59f87d50 | 593 | |
krenbluetoothsig | 1:fb4893064dd4 | 594 | err = bt_mesh_provision(net_key, net_idx, flags, iv_index, seq, addr, |
krenbluetoothsig | 1:fb4893064dd4 | 595 | dev_key); |
krenbluetoothsig | 1:fb4893064dd4 | 596 | if (err) { |
krenbluetoothsig | 1:fb4893064dd4 | 597 | printk("Provisioning failed (err %d)\n", err); |
krenbluetoothsig | 1:fb4893064dd4 | 598 | return; |
krenbluetoothsig | 1:fb4893064dd4 | 599 | } |
krenbluetoothsig | 1:fb4893064dd4 | 600 | |
krenbluetoothsig | 1:fb4893064dd4 | 601 | printk("Provisioning completed\n"); |
krenbluetoothsig | 1:fb4893064dd4 | 602 | |
krenbluetoothsig | 1:fb4893064dd4 | 603 | configure(); |
krenbluetoothsig | 0:876e59f87d50 | 604 | } |
krenbluetoothsig | 0:876e59f87d50 | 605 | |
krenbluetoothsig | 1:fb4893064dd4 | 606 | static void genericOnOffSet(void) |
krenbluetoothsig | 0:876e59f87d50 | 607 | { |
krenbluetoothsig | 1:fb4893064dd4 | 608 | NET_BUF_SIMPLE_DEFINE(msg, 2 + 2 + 4); |
krenbluetoothsig | 1:fb4893064dd4 | 609 | struct bt_mesh_msg_ctx ctx = { |
krenbluetoothsig | 1:fb4893064dd4 | 610 | .net_idx = net_idx, |
krenbluetoothsig | 1:fb4893064dd4 | 611 | .app_idx = app_idx, |
krenbluetoothsig | 1:fb4893064dd4 | 612 | .addr = groupAddress, |
krenbluetoothsig | 1:fb4893064dd4 | 613 | .send_ttl = BT_MESH_TTL_DEFAULT, |
krenbluetoothsig | 1:fb4893064dd4 | 614 | }; |
krenbluetoothsig | 1:fb4893064dd4 | 615 | |
krenbluetoothsig | 1:fb4893064dd4 | 616 | /* Bind to Generic OnOff Model */ |
krenbluetoothsig | 1:fb4893064dd4 | 617 | bt_mesh_model_msg_init(&msg, BT_MESH_MODEL_OP_GEN_ONOFF_SET ); |
krenbluetoothsig | 1:fb4893064dd4 | 618 | |
krenbluetoothsig | 1:fb4893064dd4 | 619 | net_buf_simple_add_u8(&msg, OnOff_Value % 2); |
krenbluetoothsig | 1:fb4893064dd4 | 620 | OnOff_Value++; |
krenbluetoothsig | 1:fb4893064dd4 | 621 | net_buf_simple_add_u8(&msg, trans_ID++); |
krenbluetoothsig | 1:fb4893064dd4 | 622 | |
krenbluetoothsig | 1:fb4893064dd4 | 623 | if (bt_mesh_model_send(&root_models[3], &ctx, &msg, NULL, NULL)) { |
krenbluetoothsig | 1:fb4893064dd4 | 624 | printk("Unable to send Vendor Button message\n"); |
krenbluetoothsig | 1:fb4893064dd4 | 625 | } |
krenbluetoothsig | 1:fb4893064dd4 | 626 | |
krenbluetoothsig | 1:fb4893064dd4 | 627 | printk("Button message sent with addr 0x%04x\n", groupAddress); |
krenbluetoothsig | 0:876e59f87d50 | 628 | } |
krenbluetoothsig | 0:876e59f87d50 | 629 | |
krenbluetoothsig | 0:876e59f87d50 | 630 | void main(void) |
krenbluetoothsig | 0:876e59f87d50 | 631 | { |
krenbluetoothsig | 0:876e59f87d50 | 632 | int err; |
krenbluetoothsig | 1:fb4893064dd4 | 633 | |
krenbluetoothsig | 1:fb4893064dd4 | 634 | printk("Initializing...\n"); |
krenbluetoothsig | 0:876e59f87d50 | 635 | |
krenbluetoothsig | 1:fb4893064dd4 | 636 | board_init(&addr, &seq); |
krenbluetoothsig | 0:876e59f87d50 | 637 | |
krenbluetoothsig | 1:fb4893064dd4 | 638 | printk("Unicast address: 0x%04x, name: %s, seq 0x%06x\n", addr, groupAddress2String[groupAddress - GROUP_ADDR], seq); |
krenbluetoothsig | 0:876e59f87d50 | 639 | |
krenbluetoothsig | 0:876e59f87d50 | 640 | /* Initialize the Bluetooth Subsystem */ |
krenbluetoothsig | 0:876e59f87d50 | 641 | err = bt_enable(bt_ready); |
krenbluetoothsig | 0:876e59f87d50 | 642 | if (err) { |
krenbluetoothsig | 0:876e59f87d50 | 643 | printk("Bluetooth init failed (err %d)\n", err); |
krenbluetoothsig | 0:876e59f87d50 | 644 | } |
krenbluetoothsig | 1:fb4893064dd4 | 645 | |
krenbluetoothsig | 1:fb4893064dd4 | 646 | while (1) { |
krenbluetoothsig | 1:fb4893064dd4 | 647 | |
krenbluetoothsig | 1:fb4893064dd4 | 648 | } |
krenbluetoothsig | 1:fb4893064dd4 | 649 | |
krenbluetoothsig | 0:876e59f87d50 | 650 | } |