You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by ad...@apache.org on 2016/11/15 01:20:51 UTC

[06/19] incubator-mynewt-site git commit: Added STM32F4DISCOVERY to the list of supported boards

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/32902442/docs/os/tutorials/arduino_zero.md
----------------------------------------------------------------------
diff --git a/docs/os/tutorials/arduino_zero.md b/docs/os/tutorials/arduino_zero.md
index 6f25374..9926656 100644
--- a/docs/os/tutorials/arduino_zero.md
+++ b/docs/os/tutorials/arduino_zero.md
@@ -6,13 +6,13 @@ This tutorial describes how to run Mynewt OS on Arduino Zero. Follow these simpl
 
 ### Prerequisites
 
-Before tackling this tutorial, it's best to read about Mynewt in the [Introduction](../get_started/get_started) section of this documentation.
+Before tackling this tutorial, it's best to read about Mynewt in the [Introduction](../get_started/introduction) section of this documentation.
 
 ### Equipment
 
 You will need the following equipment
 
-* An Arduino Zero board.  NOTE: There are many flavors of Arduino. Ensure that
+* An Arduino Zero board.  NOTE: There are many flavors of Arduino. Ensure that 
 you have an Arduino Zero. See below for the versions of Arduino Zero that are
 compatible with this tutorial
 * A computer that can connect to the Arduino Zero over USB
@@ -34,20 +34,20 @@ Mynewt has not been tested on Arduino M0 which has no internal debugger support.
 
 <br>
 
-### Fetch External Packages
+### Fetch External Packages 
 
-Mynewt uses source code provided directly from the chip manufacturer for
+Mynewt uses source code provided directly from the chip manufacturer for 
 low level operations. Sometimes this code is licensed only for the specific manufacturer of the chipset and cannot live in the Apache Mynewt repository. That happens to be the case for the Arduino Zero board which uses Atmel SAMD21. Runtime's github repository hosts such external third-party packages and the Newt tool can fetch them.
 
-To fetch the package with MCU support for Atmel SAMD21 for Arduino Zero from the Runtime git repository, you need to add
+To fetch the package with MCU support for Atmel SAMD21 for Arduino Zero from the Runtime git repository, you need to add 
 the repository to the `project.yml` file in your base project directory.
 
 Here is an example ```project.yml``` file with the Arduino Zero repository
-added. The sections with ```mynewt_arduino_zero``` that need to be added to
+added. The sections with ```mynewt_arduino_zero``` that need to be added to 
 your project file are highlighted.
 
 ```hl_lines="6 14 15 16 17 18"
-$ more project.yml
+$ more project.yml 
 project.name: "my_project"
 
 project.repositories:
@@ -65,17 +65,17 @@ repository.mynewt_arduino_zero:
     vers: 0-latest
     user: runtimeinc
     repo: mynewt_arduino_zero
-$
+$ 
 ```
 
 <br>
 
-Once you've edited your ```project.yml``` file, the next step is to install the
-project dependencies, this can be done with the ```newt install``` command
-(to see more output, provide the ```-v``` verbose option.):
+Once you've edited your ```project.yml``` file, the next step is to install the 
+project dependencies, this can be done with the ```newt install``` command 
+(to see more output, provide the ```-v``` verbose option.): 
 
 ```no-highlight
-$ newt install
+$ newt install 
 apache-mynewt-core
 mynewt_arduino_zero
 $
@@ -89,15 +89,15 @@ $
 
 ### Create your bootloader target
 
-Next, you need to tell Newt what to build.  For the Arduino Zero, we are going to
+Next, you need to tell Newt what to build.  For the Arduino Zero, we are going to 
 generate both a bootloader, and an image target.
 
-To generate the bootloader target, you need to specify the following options. The output of the commands (indicating success) have been suppressed for easier readability.
+To generate the bootloader target, you need to specify the following options. The output of the commands (indicating success) have been suppressed for easier readability. 
 
 ```no-highlight
-$ newt target create arduino_boot
-$ newt target set arduino_boot bsp=@mynewt_arduino_zero/hw/bsp/arduino_zero
-$ newt target set arduino_boot app=@apache-mynewt-core/apps/boot
+$ newt target create arduino_boot 
+$ newt target set arduino_boot bsp=@mynewt_arduino_zero/hw/bsp/arduino_zero 
+$ newt target set arduino_boot app=@apache-mynewt-core/apps/boot 
 $ newt target set arduino_boot build_profile=optimized
 ```
 
@@ -106,24 +106,24 @@ $ newt target set arduino_boot build_profile=optimized
 If you have an Arduino Zero Pro or M0 Pro, you have to set the following next:
 
 ```
-$ newt target set arduino_boot features=arduino_zero_pro
+$ newt target set arduino_boot features=arduino_zero_pro 
 ```
 
 If you have an Arduino Zero, you have to set the following instead:
 
 ```
-$ newt target set arduino_boot features=arduino_zero
+$ newt target set arduino_boot features=arduino_zero 
 ```
 
 <br>
 
-These commands do a few things:
+These commands do a few things: 
 
   * Create a target named ```arduino_boot```, in order to build the Arduino Zero Bootloader.
-  * Set the application for the ```arduino_boot``` target to the default Apache Mynewt
+  * Set the application for the ```arduino_boot``` target to the default Apache Mynewt 
     bootloader (```@apache-mynewt-core/apps/boot```)
-  * Set the board support package for the target to
-    ```@mynewt_arduino_zero/hw/bsp/arduino_zero```.  This is a reference to the downloaded
+  * Set the board support package for the target to 
+    ```@mynewt_arduino_zero/hw/bsp/arduino_zero```.  This is a reference to the downloaded 
     Arduino Zero support from Github.
   * Use the "optimized" build profile for the `arduino_boot` target.  This
     instructs Newt to generate smaller and more efficient code for this target.
@@ -137,7 +137,7 @@ These commands do a few things:
 Once you've configured the bootloader target, the next step is to build the bootloader for your Arduino. You can do this by using the ```newt build``` command:
 
 ```no-highlight
-$ newt build arduino_boot
+$ newt build arduino_boot 
 Compiling asprintf.c
 Compiling atoi.c
 Compiling atol.c
@@ -151,38 +151,38 @@ Compiling inline.c
 App successfully built: myproject/bin/arduino_boot/apps/boot/boot.elf
 ```
 
-If this command finishes successfully, you have successfully built the Arduino
-bootloader, and the next step is to build your application for the Arduino
+If this command finishes successfully, you have successfully built the Arduino 
+bootloader, and the next step is to build your application for the Arduino 
 board.
 
 <br>
 
-### Build your blinky app
+### Build your blinky app 
 
 To create and download your application, you create another target, this one pointing to the application you want to download to the Arduino board.  In this tutorial,  we will use the default application that comes with your project, ```apps/blinky```:
 
 **Note**: Remember to set features to `arduino_zero` if your board is Arduino Zero and not a Pro!
 
 ```hl_lines="9"
-$ newt target create arduino_blinky
+$ newt target create arduino_blinky 
 Target targets/arduino_blinky successfully created
-$ newt target set arduino_blinky app=apps/blinky
+$ newt target set arduino_blinky app=apps/blinky 
 Target targets/arduino_blinky successfully set target.app to apps/blinky
 $ newt target set arduino_blinky bsp=@mynewt_arduino_zero/hw/bsp/arduino_zero
 Target targets/arduino_blinky successfully set target.bsp to @mynewt_arduino_zero/hw/bsp/arduino_zero
-$ newt target set arduino_blinky build_profile=debug
+$ newt target set arduino_blinky build_profile=debug 
 Target targets/arduino_blinky successfully set target.build_profile to debug
-$ newt target set arduino_blinky features=arduino_zero_pro
+$ newt target set arduino_blinky features=arduino_zero_pro 
 Target targets/arduino_blinky successfully set pkg.features to arduino_zero_pro
-$
+$ 
 ```
 
 <br>
 
-You can now build the target, with ```newt build```:
+You can now build the target, with ```newt build```: 
 
 ```no-highlight
-$ newt build arduino_blinky
+$ newt build arduino_blinky 
 Compiling main.c
 Archiving blinky.a
 Compiling cons_fmt.c
@@ -201,9 +201,9 @@ App successfully built: myproject/bin/arduino_blinky/apps/blinky/blinky.elf
 
 ### Connect the Target
 
-Connect your computer to the Arduino Zero (from now on we'll call this the
-target) with the Micro-USB cable through the Programming Port as shown below.
-Mynewt will download and debug the target through this port. You should see a
+Connect your computer to the Arduino Zero (from now on we'll call this the 
+target) with the Micro-USB cable through the Programming Port as shown below. 
+Mynewt will download and debug the target through this port. You should see a 
 little green LED come on. That means the board has power.
 
 No external debugger is required.  The Arduino Zero comes with an internal
@@ -218,13 +218,13 @@ A image below shows the Arduino Zero Programming Port.
 
 ### Download the Bootloader
 
-Execute the command to download the bootloader.
+Execute the command to download the bootloader. 
 
 ```c
     $ newt load arduino_boot
 ```
 
-If the newt tool finishes without error, that means the bootloader has been
+If the newt tool finishes without error, that means the bootloader has been 
 successfully loaded onto the target.
 
 <br>
@@ -233,18 +233,18 @@ successfully loaded onto the target.
 
 <br>
 
-### Run the Image
+### Run the Image 
 
-Now that the bootloader is downloaded to the target, the next step is to load
-your image onto the Arduino Zero.  The easiest way to do this, is to use the
+Now that the bootloader is downloaded to the target, the next step is to load 
+your image onto the Arduino Zero.  The easiest way to do this, is to use the 
 ```newt run``` command.  ```newt run``` will automatically rebuild your program
 (if necessary), create an image, and load it onto the target device.
 
-Here, we will load our ```arduino_blinky``` target onto the device, and we
+Here, we will load our ```arduino_blinky``` target onto the device, and we 
 should see it run:
 
 ```no-highlight
-$ newt run arduino_blinky 0.0.0
+$ newt run arduino_blinky 0.0.0 
 Debugging myproject/bin/arduino_blinky/apps/blinky/blinky.elf
 Open On-Chip Debugger 0.9.0 (2015-09-23-21:46)
 Licensed under GNU GPL v2
@@ -279,7 +279,7 @@ For help, type "help".
 Type "apropos word" to search for commands related to "word"...
 Reading symbols from myproject/bin/arduino_blinky/apps/blinky/blinky.elf...done.
 target state: halted
-target halted due to debug-request, current mode: Thread
+target halted due to debug-request, current mode: Thread 
 xPSR: 0x21000000 pc: 0x0000030e msp: 0x20008000
 Info : accepting 'gdb' connection on tcp/3333
 Info : SAMD MCU: SAMD21G18A (256KB Flash, 32KB RAM)
@@ -292,18 +292,18 @@ Continuing.
 
 <br>
 
-**NOTE:** The 0.0.0 specified after the target name to `newt run` is the version
-of the image to load.  If you are not providing remote upgrade, and are just
+**NOTE:** The 0.0.0 specified after the target name to `newt run` is the version 
+of the image to load.  If you are not providing remote upgrade, and are just 
 developing locally, you can provide 0.0.0 for every image version.
 
-If you want the image to run without the debugger connected, simply quit the
+If you want the image to run without the debugger connected, simply quit the 
 debugger and restart the board.  The image you programmed will come and run on the Arduino on next boot!  
 
 <br>
 
 ### Watch the LED blink
 
-Congratulations! You have created a Mynewt operating system running on the
+Congratulations! You have created a Mynewt operating system running on the 
 Arduino Zero. The LED right next to the power LED should be blinking. It is toggled by one task running on the Mynewt OS.   
 
 We have more fun tutorials for you to get your hands dirty. Be bold and try other Blinky-like [tutorials](../tutorials/nRF52.md) or try enabling additional functionality such as [remote comms](project-target-slinky.md) on the current board.

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/32902442/docs/os/tutorials/bleprph/bleprph-adv.md
----------------------------------------------------------------------
diff --git a/docs/os/tutorials/bleprph/bleprph-adv.md b/docs/os/tutorials/bleprph/bleprph-adv.md
index 44a39ac..ac4f3bd 100644
--- a/docs/os/tutorials/bleprph/bleprph-adv.md
+++ b/docs/os/tutorials/bleprph/bleprph-adv.md
@@ -39,43 +39,14 @@ Let's take a look at *bleprph*'s advertisement code (*main.c*):
 static void
 bleprph_advertise(void)
 {
-    struct ble_gap_adv_params adv_params;
     struct ble_hs_adv_fields fields;
-    const char *name;
     int rc;
 
-    /**
-     *  Set the advertisement data included in our advertisements:
-     *     o Flags (indicates advertisement type and other general info).
-     *     o Advertising tx power.
-     *     o Device name.
-     *     o 16-bit service UUIDs (alert notifications).
-     */
-
+    /* Set the advertisement data included in our advertisements. */
     memset(&fields, 0, sizeof fields);
-
-    /* Indicate that the flags field should be included; specify a value of 0
-     * to instruct the stack to fill the value in for us.
-     */
-    fields.flags_is_present = 1;
-    fields.flags = 0;
-
-    /* Indicate that the TX power level field should be included; have the
-     * stack fill this one automatically as well.  This is done by assiging the
-     * special value BLE_HS_ADV_TX_PWR_LVL_AUTO.
-     */
-    fields.tx_pwr_lvl_is_present = 1;
-    fields.tx_pwr_lvl = BLE_HS_ADV_TX_PWR_LVL_AUTO;
-
-    name = ble_svc_gap_device_name();
-    fields.name = (uint8_t *)name;
-    fields.name_len = strlen(name);
+    fields.name = (uint8_t *)bleprph_device_name;
+    fields.name_len = strlen(bleprph_device_name);
     fields.name_is_complete = 1;
-
-    fields.uuids16 = (uint16_t[]){ GATT_SVR_SVC_ALERT_UUID };
-    fields.num_uuids16 = 1;
-    fields.uuids16_is_complete = 1;
-
     rc = ble_gap_adv_set_fields(&fields);
     if (rc != 0) {
         BLEPRPH_LOG(ERROR, "error setting advertisement data; rc=%d\n", rc);
@@ -83,11 +54,8 @@ bleprph_advertise(void)
     }
 
     /* Begin advertising. */
-    memset(&adv_params, 0, sizeof adv_params);
-    adv_params.conn_mode = BLE_GAP_CONN_MODE_UND;
-    adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN;
-    rc = ble_gap_adv_start(BLE_ADDR_TYPE_PUBLIC, 0, NULL, BLE_HS_FOREVER,
-                           &adv_params, bleprph_gap_event, NULL);
+    rc = ble_gap_adv_start(BLE_GAP_DISC_MODE_GEN, BLE_GAP_CONN_MODE_UND,
+                           NULL, 0, NULL, bleprph_on_connect, NULL);
     if (rc != 0) {
         BLEPRPH_LOG(ERROR, "error enabling advertisement; rc=%d\n", rc);
         return;
@@ -102,9 +70,18 @@ Now let's examine this code in detail.
 #### Setting advertisement data
 
 
-A NimBLE peripheral specifies what information to include in its advertisements with the [ble_gap_adv_set_fields()](../../../network/ble/ble_hs/ble_gap/functions/ble_gap_adv_set_fields.md) function.
+A NimBLE peripheral specifies what information to include in its advertisements with the following function:
+
+<br>
 
-The *fields* argument specifies the fields and their contents to include in
+```c
+int
+ble_gap_adv_set_fields(struct ble_hs_adv_fields *adv_fields)
+```
+
+<br>
+
+The *adv_fields* argument specifies the fields and their contents to include in
 subsequent advertisements.  The Bluetooth [Core Specification
 Supplement](https://www.bluetooth.org/DocMan/handlers/DownloadDoc.ashx?doc_id=302735)
 defines a set of standard fields that can be included in an advertisement; the
@@ -119,30 +96,44 @@ function makes a copy of all the advertisement data before it returns.
 *bleprph* doesn't take full advantange of this; it stores its device name in a
 static array.
 
-The code sets several members of the *struct ble_hs_adv_fields* instance.  Most
-of them are quite straight-forward.  However, the *name\_is\_complete* field
-requires some explanation.  Bluetooth specifies two name-related advertisement
-fields: *Shortened Local Name* and *Complete Local Name*.  Setting the
-`name_is_complete` variable to 1 or 0 tells NimBLE which of these two fields to
-include in advertisements.  Some other advertisement fields also correspond to
-multiple variables in the field struct, so it is a good idea to review the
-*ble\_hs\_adv\_fields* reference to make sure you get the details right in your
-app.
+The code sets three members of the *struct ble_hs_adv_fields* instance:
+
+* name
+* name\_len
+* name\_is\_complete
+
+The first two fields are used to communicate the device's name and are quite
+straight-forward.  The third field requires some explanation.  Bluetooth
+specifies two name-related advertisement fields: *Shortened Local Name* and
+*Complete Local Name*.  Setting the `name_is_complete` variable to 1 or 0 tells
+NimBLE which of these two fields to include in advertisements.  Some other
+advertisement fields also correspond to multiple variables in the field struct,
+so it is a good idea to review the *ble\_hs\_adv\_fields* reference to
+make sure you get the details right in your app.
 
 <br>
 
 #### Begin advertising
 
 
-An app starts advertising with
-[ble_gap_adv_start()](../../../network/ble/ble_hs/ble_gap/functions/ble_gap_adv_start.md)
-function.  This function allows a lot of flexibility, and it might seem
-daunting at first glance.  *bleprph* specifies a simple set of arguments that
-is appropriate for most peripherals.  When getting started on a typical
-peripheral, we recommend you use the same arguments as *bleprph*, with the
-exception of the last two (*cb* and *cb_arg*; *bleprph_gap_event* and *NULL* in
-this case).  These last two arguments will be specific to your app, so let's
-talk about them.
+An app starts advertising with the following function:
+
+<br>
+
+```c
+int
+ble_gap_adv_start(uint8_t discoverable_mode, uint8_t connectable_mode,
+                  uint8_t *peer_addr, uint8_t peer_addr_type,
+                  struct hci_adv_params *adv_params,
+                  ble_gap_conn_fn *cb, void *cb_arg)
+```
+
+This function allows a lot of flexibility, and it might seem daunting at first
+glance.  *bleprph* specifies a simple set of arguments that is appropriate for
+most peripherals.  When getting started on a typical peripheral, we recommend
+you use the same arguments as *bleprph*, with the exception of the last two
+(*cb* and *cb_arg*).  These last two arguments will be specific to your app, so
+let's talk about them.
 
 *cb* is a callback function.  It gets executed when a central connects to your
 peripheral after receiving an advertisement.  The *cb_arg* argument gets passed
@@ -150,15 +141,10 @@ to the *cb* callback.  If your callback doesn't need the *cb_arg* parameter,
 you can do what *bleprph* does and pass *NULL*.  Once a connection is
 established, the *cb* callback becomes permanently associated with the
 connection.  All subsequent events related to the connection are communicated
-to your app via calls to this callback function.  GAP event callbacks are an
+to your app via calls to this callback function.  Connection callbacks are an
 important part of building a BLE app, and we examine *bleprph*'s connection
 callback in detail in the next section of this tutorial.
 
 <br>
 
-**One final note:** Your peripheral automatically stops advertising when a
-central connects to it.  You can immediately resume advertising if you want to
-allow another central to connect, but you will need to do so explicitly by
-calling `ble_gap_adv_start()` again.  Also, be aware NimBLE's default
-configuration only allows a single connection at a time.  NimBLE supports
-multiple concurrent connections, but you must configure it to do so first.
+**One final note:** Your peripheral automatically stops advertising when a central connects to it.  You can immediately resume advertising if you want to allow another central to connect, but you will need to do so explicitly by calling `ble_gap_adv_start()` again.  Also, be aware NimBLE's default configuration only allows a single connection at a time.  NimBLE supports multiple concurrent connections, but you must configure it to do so first.

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/32902442/docs/os/tutorials/bleprph/bleprph-app.md
----------------------------------------------------------------------
diff --git a/docs/os/tutorials/bleprph/bleprph-app.md b/docs/os/tutorials/bleprph/bleprph-app.md
new file mode 100644
index 0000000..4a8cff3
--- /dev/null
+++ b/docs/os/tutorials/bleprph/bleprph-app.md
@@ -0,0 +1,108 @@
+## BLE Peripheral Project
+
+###Overview
+
+<br>
+
+Now that we've gone through how BLE Apps are contructed, how they function, and how all the parts fit together
+let's try out a BLE Peripheral App to see how it all works.
+
+<br>
+
+###Prerequisites
+
+<br>
+
+* You should already have completed the previous [BLE Tiny Project](../bletiny_project.md), though it's not required.
+* You should have a BLE Central App of some sort to connect with. On Mac OS or iOS, you can use [LightBlue](https://itunes.apple.com/us/app/lightblue-explorer-bluetooth/id557428110?mt=8)
+which is a free app to browse and connect to BLE Peripheral devices. 
+
+<br>
+
+###Create a New Target
+
+You can create a new project instead, but this tutorial will simply use the previously created bletiny project and add a new target for the BLE Peripheral
+
+```
+$ newt target create myperiph
+Target targets/myperiph successfully created
+$ newt target set myperiph bsp=@apache-mynewt-core/hw/bsp/nrf52dk
+Target targets/myperiph successfully set target.bsp to @apache-mynewt-core/hw/bsp/nrf52dk
+$ newt target set myperiph app=@apache-mynewt-core/apps/bleprph
+Target targets/myperiph successfully set target.app to @apache-mynewt-core/apps/bleprph
+$ newt target set myperiph build_profile=optimized
+Target targets/myperiph successfully set target.build_profile to optimized
+$ newt build blerph
+Building target targets/myperiph
+...
+Linking ~/dev/nrf52dk/bin/targets/myperiph/app/apps/bleprph/bleprph.elf
+Target successfully built: targets/myperiph
+$ newt create-image myperiph 1.0.0
+App image succesfully generated: ~/dev/nrf52dk/bin/targets/myperiph/app/apps/bleprph/bleprph.img
+$ newt load myperiph
+Loading app image into slot 1
+```
+
+Now if you reset the board, and fire up your BLE Central App, you should see a new peripheral device called 'nimble-bleprph'.
+
+<br>
+
+![LightBlue](../pics/LightBlue-1.jpg "LightBlue iOS App with nimble-bleprph device")
+
+<br>
+
+Now that you can see the device, you can begin to interact with the advertised service. 
+
+Click on the device and you'll establish a connection.
+
+<br>
+
+![LightBlue](../pics/LightBlue-2.jpg "LightBlue iOS App connected to the nimble-bleprph device")
+
+<br>
+
+Now that you're connected, you can see the Services that are being advertised.
+
+Scroll to the bottom and you will see a Read Characteristic, and a Read/Write Characteristic.
+
+![LightBlue](../pics/LightBlue-3.jpg "LightBlue iOS App connected to the nimble-bleprph device")
+
+<br>
+
+Just click on the Read Write Characteristic and you will see the existing value.
+
+![LightBlue](../pics/LightBlue-4.jpg "LightBlue iOS App with nimble-bleprph device Characteristic")
+
+<br>
+
+Type in a new value.
+
+![LightBlue](../pics/LightBlue-5.jpg "LightBlue iOS App Value Change")
+
+<br>
+
+And you will see the new value reflected.
+
+![LightBlue](../pics/LightBlue-6.jpg "LightBlue iOS App with nimble-bleprph new value")
+
+<br>
+
+If you still have your console connected, you will be able to see the connection requests, and pairing,
+happen on the device as well.
+
+<br>
+
+```hl_lines="1"
+258894:[ts=2022609336ssb, mod=64 level=1] connection established; status=0 handle=1 our_ota_addr_type=0 our_ota_addr=0a:0a:0a:0a:0a:0a our_id_addr_type=0 our_id_addr=0a:0a:0a:0a:0a:0a peer_ota_addr_type=1 peer_ota_addr=7f:be:d4:44:c0:d4 peer_id_addr_type=1 peer_id_addr=7f:be:d4:44:c0:d4 conn_itvl=24 conn_latency=0 supervision_timeout=72 encrypted=0 authenticated=0 bonded=0
+258904:[ts=2022687456ssb, mod=64 level=1]
+258917:[ts=2022789012ssb, mod=64 level=1] mtu update event; conn_handle=1 cid=4 mtu=185
+258925:[ts=2022851508ssb, mod=64 level=1] subscribe event; conn_handle=1 attr_handle=14 reason=1 prevn=0 curn=0 previ=0 curi=1
+261486:[ts=2042859320ssb, mod=64 level=1] encryption change event; status=0 handle=1 our_ota_addr_type=0 our_ota_addr=0a:0a:0a:0a:0a:0a our_id_addr_type=0 our_id_addr=0a:0a:0a:0a:0a:0a peer_ota_addr_type=1 peer_ota_addr=7f:be:d4:44:c0:d4 peer_id_addr_type=1 peer_id_addr=7f:be:d4:44:c0:d4 conn_itvl=24 conn_latency=0 supervision_timeout=72 encrypted=1 authenticated=0 bonded=1
+261496:[ts=2042937440ssb, mod=64 level=1]
+```
+
+<br>
+
+Congratulations! You've just built and connected your first BLE Peripheral device!
+
+

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/32902442/docs/os/tutorials/bleprph/bleprph-chr-access.md
----------------------------------------------------------------------
diff --git a/docs/os/tutorials/bleprph/bleprph-chr-access.md b/docs/os/tutorials/bleprph/bleprph-chr-access.md
index 3e6c3a5..3865e12 100644
--- a/docs/os/tutorials/bleprph/bleprph-chr-access.md
+++ b/docs/os/tutorials/bleprph/bleprph-chr-access.md
@@ -12,7 +12,7 @@ Each characteristic definition in an attribute table contains an *access_cb*
 field.  The *access_cb* field is an application callback that gets executed
 whenever a peer device attempts to read or write the characteristic.
 
-Earlier in this tutorial, we looked at how *bleprph* implements the ANS
+Earlier in this tutorial, we looked at how *bleprph* implements the GAP
 service.  Let's take another look at how *bleprph* specifies the first few
 characteristics in this service.
 
@@ -21,68 +21,80 @@ characteristics in this service.
 ```c
 static const struct ble_gatt_svc_def gatt_svr_svcs[] = {
     {
-        /*** Alert Notification Service. */
-        .type = BLE_GATT_SVC_TYPE_PRIMARY,
-        .uuid128 = BLE_UUID16(GATT_SVR_SVC_ALERT_UUID),
-        .characteristics = (struct ble_gatt_chr_def[]) { {
-            .uuid128 = BLE_UUID16(GATT_SVR_CHR_SUP_NEW_ALERT_CAT_UUID),
-            .access_cb = gatt_svr_chr_access_alert,
-            .flags = BLE_GATT_CHR_F_READ,
+        /*** Service: GAP. */
+        .type               = BLE_GATT_SVC_TYPE_PRIMARY,
+        .uuid128            = BLE_UUID16(BLE_GAP_SVC_UUID16),
+        .characteristics    = (struct ble_gatt_chr_def[]) { {
+            /*** Characteristic: Device Name. */
+            .uuid128            = BLE_UUID16(BLE_GAP_CHR_UUID16_DEVICE_NAME),
+            .access_cb          = gatt_svr_chr_access_gap,
+            .flags              = BLE_GATT_CHR_F_READ,
         }, {
-            .uuid128 = BLE_UUID16(GATT_SVR_CHR_NEW_ALERT),
-            .access_cb = gatt_svr_chr_access_alert,
-            .flags = BLE_GATT_CHR_F_NOTIFY,
+            /*** Characteristic: Appearance. */
+            .uuid128            = BLE_UUID16(BLE_GAP_CHR_UUID16_APPEARANCE),
+            .access_cb          = gatt_svr_chr_access_gap,
+            .flags              = BLE_GATT_CHR_F_READ,
         }, {
     // [...]
 ```
 
-As you can see, *bleprph* uses the same *access_cb* function for all the ANS
+As you can see, *bleprph* uses the same *access_cb* function for all the GAP
 service characteristics, but the developer could have implemented separate
-functions for each characteristic if they preferred.  Here is part of the
-*access_cb* function that the ANS service characteristics use:
+functions for each characteristic if they preferred.  Here is the *access_cb*
+function that the GAP service characteristics use:
 
 <br>
 
 ```c
-
 static int
-gatt_svr_chr_access_alert(uint16_t conn_handle, uint16_t attr_handle,
-                          struct ble_gatt_access_ctxt *ctxt,
-                          void *arg)
+gatt_svr_chr_access_gap(uint16_t conn_handle, uint16_t attr_handle, uint8_t op,
+                        union ble_gatt_access_ctxt *ctxt, void *arg)
 {
     uint16_t uuid16;
-    int rc;
 
-    uuid16 = ble_uuid_128_to_16(ctxt->chr->uuid128);
+    uuid16 = ble_uuid_128_to_16(ctxt->chr_access.chr->uuid128);
     assert(uuid16 != 0);
 
     switch (uuid16) {
-    case GATT_SVR_CHR_SUP_NEW_ALERT_CAT_UUID:
-        assert(ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR);
-        rc = os_mbuf_append(ctxt->om, &gatt_svr_new_alert_cat,
-                            sizeof gatt_svr_new_alert_cat);
-        return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
-
-    case GATT_SVR_CHR_UNR_ALERT_STAT_UUID:
-        if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) {
-            if (OS_MBUF_PKTLEN(ctxt->om) != sizeof gatt_svr_unr_alert_stat) {
-                return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN;
-            }
-
-            rc = ble_hs_mbuf_to_flat(ctxt->om, &gatt_svr_unr_alert_stat,
-                                     sizeof gatt_svr_unr_alert_stat, NULL);
-            if (rc != 0) {
-                return BLE_ATT_ERR_UNLIKELY;
-            }
-
-            return 0;
-
-    /* [...] */
+    case BLE_GAP_CHR_UUID16_DEVICE_NAME:
+        assert(op == BLE_GATT_ACCESS_OP_READ_CHR);
+        ctxt->chr_access.data = (void *)bleprph_device_name;
+        ctxt->chr_access.len = strlen(bleprph_device_name);
+        break;
+
+    case BLE_GAP_CHR_UUID16_APPEARANCE:
+        assert(op == BLE_GATT_ACCESS_OP_READ_CHR);
+        ctxt->chr_access.data = (void *)&bleprph_appearance;
+        ctxt->chr_access.len = sizeof bleprph_appearance;
+        break;
+
+    case BLE_GAP_CHR_UUID16_PERIPH_PRIV_FLAG:
+        assert(op == BLE_GATT_ACCESS_OP_READ_CHR);
+        ctxt->chr_access.data = (void *)&bleprph_privacy_flag;
+        ctxt->chr_access.len = sizeof bleprph_privacy_flag;
+        break;
+
+    case BLE_GAP_CHR_UUID16_RECONNECT_ADDR:
+        assert(op == BLE_GATT_ACCESS_OP_WRITE_CHR);
+        if (ctxt->chr_access.len != sizeof bleprph_reconnect_addr) {
+            return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN;
+        }
+        memcpy(bleprph_reconnect_addr, ctxt->chr_access.data,
+               sizeof bleprph_reconnect_addr);
+        break;
+
+    case BLE_GAP_CHR_UUID16_PERIPH_PREF_CONN_PARAMS:
+        assert(op == BLE_GATT_ACCESS_OP_READ_CHR);
+        ctxt->chr_access.data = (void *)&bleprph_pref_conn_params;
+        ctxt->chr_access.len = sizeof bleprph_pref_conn_params;
+        break;
 
     default:
         assert(0);
-        return BLE_ATT_ERR_UNLIKELY;
+        break;
     }
+
+    return 0;
 }
 ```
 
@@ -92,38 +104,44 @@ After you've taken a moment to examine the structure of this function, let's exp
 
 #### Function signature
 
+<br>
+
 ```c
 static int
-gatt_svr_chr_access_alert(uint16_t conn_handle, uint16_t attr_handle,
-                          struct ble_gatt_access_ctxt *ctxt,
-                          void *arg)
+gatt_svr_chr_access_gap(uint16_t conn_handle, uint16_t attr_handle, uint8_t op,
+                        union ble_gatt_access_ctxt *ctxt, void *arg)
 ```
 
 A characteristic access function always takes this same set of parameters and
 always returns an int.  The parameters to this function type are documented
 below.
 
+<br>
+
 | **Parameter** | **Purpose** | **Notes** |
 | ------------- | ----------- | --------- |
 | conn_handle   | Indicates which connection the characteristic access was sent over. | Use this value to determine which peer is accessing the characteristic. |
 | attr_handle   | The low-level ATT handle of the characteristic value attribute. | Can be used to determine which characteristic is being accessed if you don't want to perform a UUID lookup. |
 | op            | Indicates whether this is a read or write operation | Valid values are:<br>*BLE_GATT_ACCESS_OP_READ_CHR*<br>*BLE_GATT_ACCESS_OP_WRITE_CHR* |
-| ctxt          | Contains the characteristic value mbuf that the application needs to access. | For characteristic accesses, use the *ctxt->chr* member; for descriptor accesses, use the *ctxt->dsc* member. |
+| ctxt          | Contains the characteristic value pointer that the application needs to access. | For characteristic accesses, use the *ctxt->chr_access* member; for descriptor accesses, use the *ctxt->dsc_access* member. |
 
 The return value of the access function tells the NimBLE stack how to respond
 to the peer performing the operation.  A value of 0 indicates success.  For
-failures, the function returns the specific [ATT error code](../../../network/ble/ble_hs/ble_hs_return_codes/#return-codes-att) that the NimBLE
-stack should respond with.  *Note:* The return code is a formal code, **not** a NimBLE value!
+failures, the function returns the specific ATT error code that the NimBLE
+stack should respond with.  The ATT error codes are defined in
+[net/nimble/host/include/host/ble_att.h](https://github.com/apache/incubator-mynewt-core/blob/master/net/nimble/host/include/host/ble_att.h).
 
 <br>
 
 #### Determine characteristic being accessed
 
+<br>
+
 ```c
 {
     uint16_t uuid16;
 
-    uuid16 = ble_uuid_128_to_16(ctxt->chr->uuid128);
+    uuid16 = ble_uuid_128_to_16(ctxt->chr_access.chr->uuid128);
     assert(uuid16 != 0);
 
     switch (uuid16) {
@@ -137,76 +155,94 @@ accomplish this task:
 * Map characteristics to ATT handles during service registration; use the *attr_handle* parameter as a key into this table during characteristic access.
 * Implement a dedicated function for each characteristic; each function inherently knows which characteristic it corresponds to.
 
-All the ANS service characteristics have 16-bit UUIDs, so this function uses
+All the GAP service characteristics have 16-bit UUIDs, so this function uses
 the *ble_uuid_128_to_16()* function to convert the 128-bit UUID to its
 corresponding 16-bit UUID.  This conversion function returns the corresponding
 16-bit UUID on success, or 0 on failure.  Success is asserted here to ensure
 the NimBLE stack is doing its job properly; the stack should only call this
 function for accesses to characteristics that it is registered with, and all
-ANS service characteristics have valid 16-bit UUIDs.
+GAP service characteristics have valid 16-bit UUIDs.
 
 <br>
 
 #### Read access
 
+<br>
+
 ```c
-    case GATT_SVR_CHR_SUP_NEW_ALERT_CAT_UUID:
-        assert(ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR);
-        rc = os_mbuf_append(ctxt->om, &gatt_svr_new_alert_cat,
-                            sizeof gatt_svr_new_alert_cat);
-        return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
+    case BLE_GAP_CHR_UUID16_DEVICE_NAME:
+        assert(op == BLE_GATT_ACCESS_OP_READ_CHR);
+        ctxt->chr_access.data = (void *)bleprph_device_name;
+        ctxt->chr_access.len = strlen(bleprph_device_name);
+        break;
 ```
 
-This code excerpt handles read accesses to the Supported New Alert Category
-characteristic.  The *assert()* here is another case of making sure the NimBLE
-stack is doing its job; this characteristic was registered as read-only, so the
-stack should have prevented write accesses.
+This code excerpt handles read accesses to the device name characteristic.  The
+*assert()* here is another case of making sure the NimBLE stack is doing its
+job; this characteristic was registered as read-only, so the stack should have
+prevented write accesses.
 
-To fulfill a characteristic read request, the application needs fill a buffer (*om*) with the characteristic value.  The NimBLE host will then include the contents of this buffer in its read response.  NimBLE uses [mbufs](../../../os/core_os/mbuf/mbuf) to exchange data between itself and the application.  To fill an mbuf with data that is available in a contiguous chunk of memory, the *os_mbuf_append()* function suffices.  The source of the data, *gatt_svr_new_alert_cat*, is is stored in read-only memory as follows:
+To fulfill a characteristic read request, the application needs to assign the
+*ctxt->chr_access.data* field to point to the attribute data to respond with,
+and fill the *ctxt->chr_access.len* field with the length of the attribute data.
+*bleprph* stores the device name in read-only memory as follows:
 
 <br>
 
 ```c
-static const uint8_t gatt_svr_new_alert_cat = 0x01; /* Simple alert. */
+const char *bleprph_device_name = "nimble-bleprph";
 ```
 
+The cast to pointer-to-void is a necessary annoyance to remove the *const*
+qualifier from the device name variable.  You will need to "cast away const"
+whenever you respond to read requests with read-only data.
+
 It is not shown in the above snippet, but this function ultimately returns 0.
 By returning 0, *bleprph* indicates that the characteristic data in
-*ctxt->om* is valid and that NimBLE should include it in its response
+*ctxt->chr_access* is valid and that NimBLE should include it in its response
 to the peer.
 
 <br>
 
+**A word of warning:** The attribute data that *ctxt->chr_access.data* points to
+must remain valid after the access function returns, as the NimBLE stack needs
+to use it to form a GATT read response.  In other words, you must not
+allocate the characteristic value data on the stack of the access function.
+Two characteristic accesses never occur at the same time, so it is OK to use
+the same memory for repeated accesses.
+
+<br>
+
 #### Write access
 
-```c
-static uint16_t gatt_svr_unr_alert_stat;
-```
+<br>
 
 ```c
-    case GATT_SVR_CHR_UNR_ALERT_STAT_UUID:
-        if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) {
-            if (OS_MBUF_PKTLEN(ctxt->om) != sizeof gatt_svr_unr_alert_stat) {
-                return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN;
-            }
-
-            rc = ble_hs_mbuf_to_flat(ctxt->om, &gatt_svr_unr_alert_stat,
-                                     sizeof gatt_svr_unr_alert_stat, NULL);
-            if (rc != 0) {
-                return BLE_ATT_ERR_UNLIKELY;
-            }
-
-            return 0;
-        } else /* [...] */
+    case BLE_GAP_CHR_UUID16_RECONNECT_ADDR:
+        assert(op == BLE_GATT_ACCESS_OP_WRITE_CHR);
+        if (ctxt->chr_access.len != sizeof bleprph_reconnect_addr) {
+            return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN;
+        }
+        memcpy(bleprph_reconnect_addr, ctxt->chr_access.data,
+               sizeof bleprph_reconnect_addr);
+        break;
 ```
 
-This code excerpt handles writes to the New Alert characteristic.  For writes,
-the role of the *ctxt->om* field is the reverse of the read case.  The NimBLE
-stack uses these fields to indicate the data written by the peer.
+This code excerpt handles writes to the reconnect address characteristic.  This
+characteristic was registered as write-only, so the *assert()* here is just a
+safety precaution to ensure the NimBLE stack is doing its job.
 
-Many characteristics have strict length requirements for write operations.
-This characteristic has such a restriction; if the written data is not a 2-byte
-value, the application tells NimBLE to respond with an invalid attribute value
-length error.
+For writes, the roles of the *ctxt->chr_access.data* and *ctxt->chr_access.len*
+fields are the reverse of the read case.  The NimBLE stack uses these fields to
+indicate the data written by the peer.
 
-*bleprph* copies the data out of the supplied mbuf and writes it to a contiguous chunk of storage (the *gatt_svr_unr_alert_stat* variable).  This is accomplished with the [ble_hs_mbuf_to_flat()](../../../network/ble/ble_hs/other/functions/ble_hs_mbuf_to_flat) function.  If the application did not have a suitable destination for the data handy, it could have inherited the mbuf from the context object.  This is done by saving a copy of the mbuf pointer, and assigning *NULL* to *ctxt->om*.  By assigning *NULL* to the mbuf pointer, your application prevents the stack from freeing the mbuf while it is still being used.  Be aware, however, that it is the application's responsibility to free inherited mbufs.
+Many characteristics have strict length requirements for write operations.
+This characteristic has such a restriction; if the written data is not a 48-bit
+BR address, the application tells NimBLE to respond with an invalid attribute
+value length error.
+
+For writes, the *ctxt->chr_access.data* pointer is only valid for the duration
+of the access function.  If the application needs to save the written data, it
+should store it elsewhere before the function returns.  In this case, *bleprph*
+stores the specified address in a global variable called
+*bleprph_reconnect_addr*.

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/32902442/docs/os/tutorials/bleprph/bleprph-conn.md
----------------------------------------------------------------------
diff --git a/docs/os/tutorials/bleprph/bleprph-conn.md b/docs/os/tutorials/bleprph/bleprph-conn.md
new file mode 100644
index 0000000..ffbf7a1
--- /dev/null
+++ b/docs/os/tutorials/bleprph/bleprph-conn.md
@@ -0,0 +1,156 @@
+## BLE Peripheral Project
+
+### Connection callbacks
+
+<br>
+
+#### Overview
+
+
+Every BLE connection has a *connection callback* associated with it.  A
+connection callback is a bit of application code which NimBLE uses to inform
+you of connection-related events.  For example, if a connection is terminated,
+NimBLE lets you know about it with a call to that connection's callback.
+
+In the [advertising section](bleprph-adv/) of this tutorial, we saw how the
+application specifies a connection callback when it begins advertising.  NimBLE
+uses this callback to notify the application that a central has connected to
+your peripheral after receiving an advertisement.  Let's revisit how *bleprph* specifies its connection callback when advertising:
+
+<br>
+
+```c
+    /* Begin advertising. */
+    rc = ble_gap_adv_start(BLE_GAP_DISC_MODE_GEN, BLE_GAP_CONN_MODE_UND,
+                           NULL, 0, NULL, bleprph_on_connect, NULL);
+    if (rc != 0) {
+        BLEPRPH_LOG(ERROR, "error enabling advertisement; rc=%d\n", rc);
+        return;
+    }
+```
+
+<br>
+
+#### bleprph_on_connect()
+
+
+The `bleprph_on_connect()` function is *bleprph*'s connection callback; NimBLE
+calls this function when the advertising operation leads to connection
+establishment.  Upon connecting, this callback becomes permanently associated
+with the connection; all subsequent events related to this connection are
+communicated through this callback.
+
+Now let's look at the function that *bleprph* uses for all its connection
+callbacks: `bleprph_on_connect()`.
+
+
+```c
+static int
+bleprph_on_connect(int event, int status, struct ble_gap_conn_ctxt *ctxt,
+                   void *arg)
+{
+    switch (event) {
+    case BLE_GAP_EVENT_CONN:
+        BLEPRPH_LOG(INFO, "connection %s; status=%d ",
+                    status == 0 ? "up" : "down", status);
+        bleprph_print_conn_desc(ctxt->desc);
+        BLEPRPH_LOG(INFO, "\n");
+
+        if (status != 0) {
+            /* Connection terminated; resume advertising. */
+            bleprph_advertise();
+        }
+        break;
+    }
+
+    return 0;
+}
+```
+
+<br>
+
+Connection callbacks are used to communicate a variety of events related to a
+connection.  An application determines the type of event that occurred by
+inspecting the value of the *event* parameter.  The full list of event codes
+can be found in [net/nimble/host/include/host/ble_gatt.h](https://github.com/apache/incubator-mynewt-core/blob/master/net/nimble/host/include/host/ble_gatt.h).
+*bleprph* only concerns itself with a single event type: *BLE_GAP_EVENT_CONN*.
+This event indicates that a new connection has been established, or an existing
+connection has been terminated; the *status* parameter clarifies which.  As you
+can see, *bleprph* uses the *status* parameter to determine if it should resume
+advertising.
+
+The *ctxt* parameter contains additional information about the connection
+event.  *bleprph* does nothing more than log some fields of this struct, but
+some apps will likely want to perform further actions, e.g., perform service
+discovery on the connected device.  The *struct ble_gap_conn_ctxt* type is
+defined as follows:
+
+```c
+struct ble_gap_conn_ctxt {
+    struct ble_gap_conn_desc *desc;
+
+    union {
+        struct {
+            struct ble_gap_upd_params *self_params;
+            struct ble_gap_upd_params *peer_params;
+        } update;
+
+        struct ble_gap_sec_params *sec_params;
+    };
+};
+```
+
+<br>
+
+As shown, a connection context object consists of two parts:
+
+* *desc:* The connection descriptor; indicates properties of the connection.
+* *anonymous union:* The contents are event-specific; check the *event* code to determine which member field (if any) is relevant.
+
+For events of type *BLE_GAP_EVENT_CONN*, the anonymous union is not used at all, so the only information carried by the context struct is the connection descriptor.  The *struct ble_gap_conn_desc* type is defined as follows:
+
+```c
+struct ble_gap_conn_desc {
+    uint8_t peer_addr[6];
+    uint16_t conn_handle;
+    uint16_t conn_itvl;
+    uint16_t conn_latency;
+    uint16_t supervision_timeout;
+    uint8_t peer_addr_type;
+};
+```
+
+<br>
+
+We will examine these fields in a slightly different order from how they appear
+in the struct definition.
+
+<br>
+
+| *Field* | *Purpose* | *Notes* |
+| ------- | --------- | ------- |
+| peer\_addr | The 48-bit address of the peer device. | |
+| peer\_addr\_type | Whether the peer is using a public or random address. | The address type list is documented in [net/nimble/include/nimble/hci_common.h](https://github.com/apache/incubator-mynewt-core/blob/master/net/nimble/include/nimble/hci_common.h). |
+| conn\_handle | The 16-bit handle associated with this connection. | This number is how your app and the NimBLE stack refer to this connection. |
+| conn\_itvl,<br>conn\_latency,<br>supervision\_timeout | Low-level properties of the connection. | |
+
+<br>
+
+#### Guarantees
+
+It is important to know what your application code is allowed to do from within
+a connection callback.
+
+**No restrictions on NimBLE operations**
+
+Your app is free to make calls into the NimBLE stack from within a connection
+callback.  *bleprph* takes advantage of this freedom when it resumes
+advertising upon connection termination.  All other NimBLE operations are also
+allowed (service discovery, pairing initiation, etc).
+
+**All context data is transient**
+
+Pointers in the context object point to data living on the stack.  Your
+callback is free to read (or write, if appropriate) through these pointers, but
+you should not store these pointers for later use.  If your application needs
+to retain some data from a context object, it needs to make a copy.

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/32902442/docs/os/tutorials/bleprph/bleprph-intro.md
----------------------------------------------------------------------
diff --git a/docs/os/tutorials/bleprph/bleprph-intro.md b/docs/os/tutorials/bleprph/bleprph-intro.md
index f03f1d7..77a72b9 100644
--- a/docs/os/tutorials/bleprph/bleprph-intro.md
+++ b/docs/os/tutorials/bleprph/bleprph-intro.md
@@ -8,10 +8,9 @@
 
 *bleprph* is an example app included in the apache-mynewt-core repository.  This app implements a simple BLE peripheral with the following properties:
 
+* Supports three services: GAP, GATT, and alert notification service (ANS).
 * Supports a single concurrent connection.
 * Automatically advertises connectability when not connected to a central device.
-* Supports pairing and bonding.
-* Supports five services.
 
 This tutorial aims to provide a guided tour through the *bleprph* app source
 code.  This document builds on some concepts described elsewhere in the Apache
@@ -33,3 +32,5 @@ these concepts, you will probably want to check out this
 from the Bluetooth Developer's site before proceeding.
 
 Now let's dig in to some C code.
+<br>
+

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/32902442/docs/os/tutorials/bleprph/bleprph-svc-reg.md
----------------------------------------------------------------------
diff --git a/docs/os/tutorials/bleprph/bleprph-svc-reg.md b/docs/os/tutorials/bleprph/bleprph-svc-reg.md
index a40e772..dc8747d 100644
--- a/docs/os/tutorials/bleprph/bleprph-svc-reg.md
+++ b/docs/os/tutorials/bleprph/bleprph-svc-reg.md
@@ -8,38 +8,33 @@
 
 The NimBLE host uses a table-based design for GATT server configuration.  The
 set of supported attributes are expressed as a series of tables that resides in
-your C code.
+your C code.  When possible, we recommend using a single monolithic table, as
+it results in code that is simpler and less error prone.  Multiple tables
+can be used if it is impractical for the entire attribute set to live in one
+place in your code.
 
-*bleprph* supports the following services:
-
-* GAP
-* GATT
-* newtmgr
-* Alert Notification
-* Security Test
-
-The first two services (GAP and GATT) are mandatory services that all BLE peripherals must support.  These are implemented in a separate package which the *bleprph* app depends on.  Later, we will see how the *main()* function initializes and registers this package.  Your app will follow the same procedure when using GATT service libraries.
-
-The third service, newtmgr, is vendor-specific service supported by most Mynewt devices.  This service is used for remote configuration, status queries, and firmware updates.  As with GAP and GATT, this service is implemented in a package separate from the *bleprph* app.
-
-The final two services, *Alert Notification* and *Security Test*, are not implemented in separate libraries.  Rather, these services are specific to the app, so they are implemented the *bleprph* app itself.  The attribute table used to express these services is located in the *gatt_svr.c* file, so let's take a look at that now.  The attribute table is called `gatt_svr_svcs`; here are the first several lines from this table:
+*bleprph* uses a single attribute table located in the *gatt_svr.c* file,
+so let's take a look at that now.  The attribute table is called
+`gatt_svr_svcs`; here are the first several lines from this table:
 
 <br>
 
 ```c
 static const struct ble_gatt_svc_def gatt_svr_svcs[] = {
     {
-        /*** Alert Notification Service. */
-        .type = BLE_GATT_SVC_TYPE_PRIMARY,
-        .uuid128 = BLE_UUID16(GATT_SVR_SVC_ALERT_UUID),
-        .characteristics = (struct ble_gatt_chr_def[]) { {
-            .uuid128 = BLE_UUID16(GATT_SVR_CHR_SUP_NEW_ALERT_CAT_UUID),
-            .access_cb = gatt_svr_chr_access_alert,
-            .flags = BLE_GATT_CHR_F_READ,
+        /*** Service: GAP. */
+        .type               = BLE_GATT_SVC_TYPE_PRIMARY,
+        .uuid128            = BLE_UUID16(BLE_GAP_SVC_UUID16),
+        .characteristics    = (struct ble_gatt_chr_def[]) { {
+            /*** Characteristic: Device Name. */
+            .uuid128            = BLE_UUID16(BLE_GAP_CHR_UUID16_DEVICE_NAME),
+            .access_cb          = gatt_svr_chr_access_gap,
+            .flags              = BLE_GATT_CHR_F_READ,
         }, {
-            .uuid128 = BLE_UUID16(GATT_SVR_CHR_NEW_ALERT),
-            .access_cb = gatt_svr_chr_access_alert,
-            .flags = BLE_GATT_CHR_F_NOTIFY,
+            /*** Characteristic: Appearance. */
+            .uuid128            = BLE_UUID16(BLE_GAP_CHR_UUID16_APPEARANCE),
+            .access_cb          = gatt_svr_chr_access_gap,
+            .flags              = BLE_GATT_CHR_F_READ,
         }, {
     // [...]
 ```
@@ -48,14 +43,16 @@ static const struct ble_gatt_svc_def gatt_svr_svcs[] = {
 
 As you can see, the table is an array of service definitions (
 `struct ble_gatt_svc_def`).  This code excerpt contains a small part of the
-Alert Notification service.  Let's now consider the contents of this table in
-more detail.
+*GAP service*.  The GAP service exposes generic information about a device,
+such as its name and appearance.  Support for the GAP service is mandatory for
+all BLE peripherals.  Let's now consider the contents of this table in more
+detail.
 
 A service definition consists of the following fields:
 
-| *Field*         | *Meaning* | *Notes* |
-| --------------- | --------- | ------- |
-| type            | Specifies whether this is a primary or secondary service. | Secondary services are not very common.  When in doubt, specify *BLE_GATT_SVC_TYPE_PRIMARY* for new services. |
+| *Field* | *Meaning* | *Notes* |
+| ------- | --------- | ------- |
+| type        | Specifies whether this is a primary or secondary service. | Secondary services are not very common.  When in doubt, specify *BLE_GATT_SVC_TYPE_PRIMARY* for new services. |
 | uuid128         | The 128-bit UUID of this service. | If the service has a 16-bit UUID, you can convert it to its corresponding 128-bit UUID with the `BLE_UUID16()` macro. |
 | characteristics | The array of characteristics that belong to this service.   | |
 
@@ -68,10 +65,10 @@ definition consists of the following fields:
 | *Field* | *Meaning* | *Notes* |
 | ------- | --------- | ------- |
 | uuid128     | The 128-bit UUID of this characteristic. | If the characteristic has a 16-bit UUID, you can convert it to its corresponding 128-bit UUID with the `BLE_UUID16()` macro. |
-| access\_cb  | A callback function that gets executed whenever a peer device accesses this characteristic. | *For reads:* this function generates the value that gets sent back to the peer.<br>*For writes:* this function receives the written value as an argument. |
+| access_cb   | A callback function that gets executed whenever a peer device accesses this characteristic. | *For reads:* this function generates the value that gets sent back to the peer.<br>*For writes:* this function provides the written value as an argument. |
 | flags       | Indicates which operations are permitted for this characteristic.  The NimBLE stack responds negatively when a peer attempts an unsupported operation. | The full list of flags can be found under `ble_gatt_chr_flags` in [net/nimble/host/include/host/ble_gatt.h](https://github.com/apache/incubator-mynewt-core/blob/master/net/nimble/host/include/host/ble_gatt.h).|
 
-A characteristic's access callback implements its behavior.  Access
+The access callback is what implements the characteristic's behavior.  Access
 callbacks are described in detail in the next section:
 [BLE Peripheral - Characteristic Access](bleprph-chr-access/).
 
@@ -84,20 +81,29 @@ characteristic array and service array.
 
 ```c hl_lines="26 31"
     {
-        /*** Service: Security test. */
+        /*** Alert Notification Service. */
         .type = BLE_GATT_SVC_TYPE_PRIMARY,
-        .uuid128 = gatt_svr_svc_sec_test_uuid,
+        .uuid128 = BLE_UUID16(GATT_SVR_SVC_ALERT_UUID),
         .characteristics = (struct ble_gatt_chr_def[]) { {
-            /*** Characteristic: Random number generator. */
-            .uuid128 = gatt_svr_chr_sec_test_rand_uuid,
-            .access_cb = gatt_svr_chr_access_sec_test,
-            .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_READ_ENC,
+            .uuid128 = BLE_UUID16(GATT_SVR_CHR_SUP_NEW_ALERT_CAT_UUID),
+            .access_cb = gatt_svr_chr_access_alert,
+            .flags = BLE_GATT_CHR_F_READ,
+        }, {
+            .uuid128 = BLE_UUID16(GATT_SVR_CHR_NEW_ALERT),
+            .access_cb = gatt_svr_chr_access_alert,
+            .flags = BLE_GATT_CHR_F_NOTIFY,
         }, {
-            /*** Characteristic: Static value. */
-            .uuid128 = gatt_svr_chr_sec_test_static_uuid,
-            .access_cb = gatt_svr_chr_access_sec_test,
-            .flags = BLE_GATT_CHR_F_READ |
-                     BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_WRITE_ENC,
+            .uuid128 = BLE_UUID16(GATT_SVR_CHR_SUP_UNR_ALERT_CAT_UUID),
+            .access_cb = gatt_svr_chr_access_alert,
+            .flags = BLE_GATT_CHR_F_READ,
+        }, {
+            .uuid128 = BLE_UUID16(GATT_SVR_CHR_UNR_ALERT_STAT_UUID),
+            .access_cb = gatt_svr_chr_access_alert,
+            .flags = BLE_GATT_CHR_F_NOTIFY,
+        }, {
+            .uuid128 = BLE_UUID16(GATT_SVR_CHR_ALERT_NOT_CTRL_PT),
+            .access_cb = gatt_svr_chr_access_alert,
+            .flags = BLE_GATT_CHR_F_WRITE,
         }, {
             0, /* No more characteristics in this service. */
         } },
@@ -112,32 +118,34 @@ characteristic array and service array.
 
 #### Registration function
 
-After you have created your service table, your app needs to register it with the NimBLE stack.  This is done by calling the [ble_gatts_add_svcs()](../../../network/ble/ble_hs/ble_gatts/functions/ble_gatts_add_svcs.md) function.  There is a small complication, though.  The NimBLE host needs to allocate sufficient resources upfront to accommodate all of your peripheral's services.  You can ensure your GATT services are accounted for in the host configuration object by calling the [ble_gatts_count_cfg()](../../../network/ble/ble_hs/ble_gatts/functions/ble_gatts_count_cfg.md) function.
-
-The *bleprph* app registers its services in *gatt_svr.c* as follows:
+After you have created your service table, your app needs to register it with the NimBLE stack.  This is done by calling the following function:
 
 ```c
 int
-gatt_svr_init(struct ble_hs_cfg *cfg)
-{
-    int rc;
+ble_gatts_register_svcs(const struct ble_gatt_svc_def *svcs,
+                        ble_gatt_register_fn *cb, void *cb_arg)
+```
 
-    rc = ble_gatts_count_cfg(gatt_svr_svcs, cfg);
-    if (rc != 0) {
-        return rc;
-    }
+The function parameters are documented below.
 
-    rc = ble_gatts_add_svcs(gatt_svr_svcs);
-    if (rc != 0) {
-        return rc;
-    }
+| *Parameter* | *Meaning* | *Notes* |
+| ----------- | --------- | ------- |
+| svcs        | The table of services to register. | |
+| cb          | A callback that gets executed each time a service, characteristic, or descriptor is registered. | Optional; pass NULL if you don't want to be notified. |
+| cb\_arg     | An argument that gets passed to the callback function on each invocation. | Optional; pass NULL if there is no callback or if you don't need a special argument. |
 
-    return 0;
-}
+The `ble_gatts_register_svcs()` function returns 0 on success, or a
+*BLE_HS_E[...]* error code on failure.
 
-```
+More detailed information about the registration callback function can be found
+in the [BLE User Guide](../../../network/ble/ble_intro/) (TBD).
+
+The *bleprph* app registers its services as follows:
 
-You application will perform the above two-step process for each service definition array that you wish to register.  Libraries that implement GATT services will generally expose an initialization function which does this for you.
+```c
+    rc = ble_gatts_register_svcs(gatt_svr_svcs, gatt_svr_register_cb, NULL);
+    assert(rc == 0);
+```
 
 <br>
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/32902442/docs/os/tutorials/blinky_sram_olimex.md
----------------------------------------------------------------------
diff --git a/docs/os/tutorials/blinky_sram_olimex.md b/docs/os/tutorials/blinky_sram_olimex.md
index 3bd5750..dd2439d 100644
--- a/docs/os/tutorials/blinky_sram_olimex.md
+++ b/docs/os/tutorials/blinky_sram_olimex.md
@@ -6,12 +6,12 @@ To download an application image directly into the embedded SRAM in the microcon
 
 ### What you need
 
-1. STM32-E407 development board from Olimex. You can order it from [http://www.mouser.com](http://www.mouser.com/search/ProductDetail.aspx?R=0virtualkey0virtualkeySTM32-E407), [http://www.digikey.com](http://www.digikey.com/product-detail/en/STM32-E407/1188-1093-ND/3726951), and other places.
+1. STM32-E407 development board from Olimex. You can order it from [http://www.mouser.com](http://www.mouser.com/ProductDetail/Olimex-Ltd/STM32-E407/?qs=UN6GZl1KCcit6Ye0xmPO4A%3D%3D), [http://www.digikey.com](http://www.digikey.com/product-detail/en/STM32-E407/1188-1093-ND/3726951), and other places.
 2. ARM-USB-TINY-H connector with JTAG interface for debugging ARM microcontrollers (comes with the ribbon cable to hook up to the board)
 3. USB A-B type cable to connect the debugger to your personal computer
 4. Personal Computer with Mac OS (Mac: OS X Yosemite Version 10.10.5) or Linux box (Ubuntu 14.10: Utopic Unicorn)
 5. An account on Github repository and *git* installed on your computer.
-6. It is assumed you have already installed newt tool.
+6. It is assumed you have already installed newt tool. 
 7. It is assumed you already installed native tools as described [here](../get_started/native_tools.md)
 
 Also, we assume that you're familiar with UNIX shells. Let's gets started!
@@ -21,13 +21,13 @@ Also, we assume that you're familiar with UNIX shells. Let's gets started!
 
 ### Prepare the Software
 
-* Make sure the PATH environment variable includes the $HOME/dev/go/bin directory.
-
+* Make sure the PATH environment variable includes the $HOME/dev/go/bin directory. 
+ 
 <br>
 
 ### Create a project  
 
-Create a new project to hold your work.  For a deeper understanding, you can read about project creation in
+Create a new project to hold your work.  For a deeper understanding, you can read about project creation in 
 [Get Started -- Creating Your First Project](../get_started/project_create.md)
 or just follow the commands below.
 
@@ -41,15 +41,15 @@ or just follow the commands below.
 
     $cd myproj
 
-    $ newt install -v
+    $ newt install -v 
     apache-mynewt-core
     Downloading repository description for apache-mynewt-core... success!
     ...
     apache-mynewt-core successfully installed version 0.7.9-none
-```
+``` 
 
 <br>
-
+   
 ### Create a target
 
 Change directory to ~/dev/myproj directory and define the *blinky* target inside myproj, using the *newt* tool. Starting with the target name, assign specific aspects of the project, as shown below, to pull the appropriate packages and build the right bundle or list for the board. For example, we set the build_profile, board support package (bsp), and app.
@@ -71,11 +71,11 @@ Change directory to ~/dev/myproj directory and define the *blinky* target inside
 
 ### Build the image
 
-Next, let's build the image for the above target. By default, the linker script within the `hw/bsp/olimex_stm32-e407_devboard` package builds an image for flash memory, which we don't want; instead, we want an image for the SRAM, so you need to switch that script with `run_from_sram.ld`.
-
-Afer you build the target, you can find the executable *blinky.elf* in the project directory *~/dev/myproj/bin/blinky/apps/blinky/.*
-
+Next, let's build the image for the above target. By default, the linker script within the `hw/bsp/olimex_stm32-e407_devboard` package builds an image for flash memory, which we don't want; instead, we want an image for the SRAM, so you need to switch that script with `run_from_sram.ld`. 
 
+Afer you build the target, you can find the executable *blinky.elf* in the project directory *~/dev/myproj/bin/blinky/apps/blinky/.* 
+    
+    
 ```no-highlight
     $ cd ~/dev/myproj/repos/apache-mynewt-core/hw/bsp/olimex_stm32-e407_devboard/
     $ diff olimex_stm32-e407_devboard.ld run_from_sram.ld
@@ -106,12 +106,12 @@ Afer you build the target, you can find the executable *blinky.elf* in the proje
 
 <br>
 
-* B1_1/B1_0 and B0_1/B0_0 are PTH jumpers. Note that because the markings on the board may not always be accurate, when in doubt, you should always refer to the manual for the correct positioning. Since the jumpers are a pair, they should move together, and as such, the pair is responsible for the boot mode when bootloader is present.
+* B1_1/B1_0 and B0_1/B0_0 are PTH jumpers. Note that because the markings on the board may not always be accurate, when in doubt, you should always refer to the manual for the correct positioning. Since the jumpers are a pair, they should move together, and as such, the pair is responsible for the boot mode when bootloader is present. 
 To locate the bootloader, the board searches in three places: User Flash Memory, System Memory or the Embedded SRAM. For this Blinky project, we will configure it to boot from SRAM by jumpering **B0_1** and **B1_1**.
 
-* Connect USB-OTG#2 in the picture above to a USB port on your computer (or a powered USB hub to make sure there is enough power available to the board).
+* Connect USB-OTG#2 in the picture above to a USB port on your computer (or a powered USB hub to make sure there is enough power available to the board). 
 
-* The red PWR LED should be lit.
+* The red PWR LED should be lit. 
 
 * Connect the JTAG connector to the SWD/JTAG interface on the board. The other end of the cable should be connected to the USB port or hub of your computer.
 
@@ -133,7 +133,7 @@ To locate the bootloader, the board searches in three places: User Flash Memory,
     (info)
     ...
     target state: halted
-    target halted due to debug-request, current mode: Thread
+    target halted due to debug-request, current mode: Thread 
     xPSR: 0x01000000 pc: 0x080003c0 msp: 0x10010000
     Info : accepting 'gdb' connection on tcp/3333
     Info : device id = 0x10036413
@@ -141,15 +141,15 @@ To locate the bootloader, the board searches in three places: User Flash Memory,
 ```
 <br>
 
-Check the value of the msp (main service pointer) register. If it is not 0x10010000 as indicated above, you will have to manually set it after you open the gdb tool and load the image on it. For example,
-
+Check the value of the msp (main service pointer) register. If it is not 0x10010000 as indicated above, you will have to manually set it after you open the gdb tool and load the image on it. For example, 
+   
 ```no-highlight
     (gdb) set $msp=0x10010000
 ```
 
 <br>
 
-   Now load the image and type "c" or "continue" from the GNU debugger.
+   Now load the image and type "c" or "continue" from the GNU debugger. 
 
 ```no-highlight           
     (gdb) load ~/dev/myproj/bin/blinky/apps/blinky/blinky.elf   
@@ -161,7 +161,8 @@ Check the value of the msp (main service pointer) register. If it is not 0x10010
     (gdb) c
     Continuing.
 ```   
-
+      
 * Voil�! The board's LED should be blinking at 1 Hz. Success!
 
 <br>
+

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/32902442/docs/os/tutorials/ibeacon.md
----------------------------------------------------------------------
diff --git a/docs/os/tutorials/ibeacon.md b/docs/os/tutorials/ibeacon.md
index 3b4fa4e..1ff7a39 100644
--- a/docs/os/tutorials/ibeacon.md
+++ b/docs/os/tutorials/ibeacon.md
@@ -37,7 +37,7 @@ This function's parameters are documented below.
 To demonstrate how the above function is used, we will now modify the *bleprph*
 example application to send iBeacons.  For some background behind the *bleprph*
 app, we recommend you take a look at the [bleprph project
-tutorial](bleprph/bleprph-intro/).  If you plan on making these modifications
+tutorial](bleprph/bleprph_intro/).  If you plan on making these modifications
 yourself, it might be a good idea to copy *bleprph* to your local repository
 and work with the copy.  In general, you should avoid changing a package that
 newt downloads, as you will lose your changes the next time you upgrade the

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/32902442/docs/os/tutorials/olimex.md
----------------------------------------------------------------------
diff --git a/docs/os/tutorials/olimex.md b/docs/os/tutorials/olimex.md
index 398bfe1..740c293 100644
--- a/docs/os/tutorials/olimex.md
+++ b/docs/os/tutorials/olimex.md
@@ -10,12 +10,12 @@ This tutorial shows you how to create a runtime image for an Olimex board to mak
 
 ### What you need
 
-1. STM32-E407 development board from Olimex. You can order it from [http://www.mouser.com](http://www.mouser.com/search/ProductDetail.aspx?R=0virtualkey0virtualkeySTM32-E407), [http://www.digikey.com](http://www.digikey.com/product-detail/en/STM32-E407/1188-1093-ND/3726951), and other places.
+1. STM32-E407 development board from Olimex. You can order it from [http://www.mouser.com](http://www.mouser.com/ProductDetail/Olimex-Ltd/STM32-E407/?qs=UN6GZl1KCcit6Ye0xmPO4A%3D%3D), [http://www.digikey.com](http://www.digikey.com/product-detail/en/STM32-E407/1188-1093-ND/3726951), and other places.
 2. ARM-USB-TINY-H connector with JTAG interface for debugging ARM microcontrollers (comes with the ribbon cable to hook up to the board)
 3. USB A-B type cable to connect the debugger to your personal computer
 4. Personal Computer with Mac OS (Mac: OS X Yosemite Version 10.10.5) or Linux box (Ubuntu 14.10: Utopic Unicorn)
 5. An account on Github repository and *git* installed on your computer.
-6. It is assumed you have already installed newt tool.
+6. It is assumed you have already installed newt tool. 
 7. It is assumed you already installed native tools as described [here](../get_started/native_tools.md)
 
 Also, we assume that you're familiar with UNIX shells. Let's gets started!
@@ -25,13 +25,13 @@ Also, we assume that you're familiar with UNIX shells. Let's gets started!
 
 ### Prepare the Software
 
-* Make sure the PATH environment variable includes the $HOME/dev/go/bin directory.
-
+* Make sure the PATH environment variable includes the $HOME/dev/go/bin directory. 
+ 
 <br>
 
 ### Create a project.  
 
-Create a new project to hold your work.  For a deeper understanding, you can read about project creation in
+Create a new project to hold your work.  For a deeper understanding, you can read about project creation in 
 [Get Started -- Creating Your First Project](../get_started/project_create.md)
 or just follow the commands below.
 
@@ -45,15 +45,15 @@ or just follow the commands below.
 
     $cd myproj
 
-    $ newt install -v
+    $ newt install -v 
     apache-mynewt-core
     Downloading repository description for apache-mynewt-core... success!
     ...
     apache-mynewt-core successfully installed version 0.7.9-none
-```
+``` 
 
 <br>
-
+   
 ### Create targets
 
 Change directory to ~/dev/myproj directory and define the *blinky* target inside myproj, using the *newt* tool. Starting with the target name, assign specific aspects of the project, as shown below, to pull the appropriate packages and build the right bundle or list for the board. For example, we set the build_profile, board support package (bsp), and app.
@@ -64,13 +64,13 @@ Change directory to ~/dev/myproj directory and define the *blinky* target inside
     $ newt target set blinky build_profile=debug
     $ newt target set blinky bsp=@apache-mynewt-core/hw/bsp/olimex_stm32-e407_devboard
     $ newt target set blinky app=apps/blinky
-
+    
     $ newt target create boot_olimex
     $ newt target set boot_olimex app=@apache-mynewt-core/apps/boot
     $ newt target set boot_olimex bsp=@apache-mynewt-core/hw/bsp/olimex_stm32-e407_devboard
     $ newt target set boot_olimex build_profile=optimized
-
-    $ newt target show
+    
+    $ newt target show 
     targets/blinky
         app=apps/blinky
         bsp=@apache-mynewt-core/hw/bsp/olimex_stm32-e407_devboard
@@ -85,9 +85,9 @@ Change directory to ~/dev/myproj directory and define the *blinky* target inside
 
 ### Build the images
 
-Next, let's build the images for the above targets. Afer you build the target, you can find the executable *blinky.elf* in the project directory *~/dev/myproj/bin/blinky/apps/blinky/.*
-
-
+Next, let's build the images for the above targets. Afer you build the target, you can find the executable *blinky.elf* in the project directory *~/dev/myproj/bin/blinky/apps/blinky/.* 
+    
+    
 ```no-highlight
     $ newt build blinky
     Compiling case.c
@@ -98,7 +98,7 @@ Next, let's build the images for the above targets. Afer you build the target, y
     $ ls ~/dev/myproj/bin/blinky/apps/blinky/
         blinky.elf      blinky.elf.bin     blinky.elf.cmd  
         blinky.elf.lst  blinky.elf.map
-
+        
     $ newt build boot_olimex
     Building target targets/boot_olimex
     App successfully built: ~/dev/myproj/bin/boot_olimex/apps/boot/boot.elf
@@ -106,7 +106,7 @@ Next, let's build the images for the above targets. Afer you build the target, y
 
 <br>
 
-### Sign and create the blinky application image
+### Sign and create the blinky application image 
 
 You must sign and version your application image to download it using newt to the board. Use the newt create-image command to perform this action. You may assign an arbitrary version (e.g. 1.0.0) to the image.
 
@@ -129,12 +129,12 @@ Build manifest: ~/dev/myproj/bin/blinky/apps/blinky/manifest.json
 
 <br>
 
-* B1_1/B1_0 and B0_1/B0_0 are PTH jumpers. Note that because the markings on the board may not always be accurate, when in doubt, you should always refer to the manual for the correct positioning. Since the jumpers are a pair, they should move together, and as such, the pair is responsible for the boot mode when bootloader is present.
+* B1_1/B1_0 and B0_1/B0_0 are PTH jumpers. Note that because the markings on the board may not always be accurate, when in doubt, you should always refer to the manual for the correct positioning. Since the jumpers are a pair, they should move together, and as such, the pair is responsible for the boot mode when bootloader is present. 
 To locate the bootloader, the board searches in three places: User Flash Memory, System Memory or the Embedded SRAM. For this Blinky project, we will configure it to boot from flash by jumpering **B0_0** and **B1_0**.
 
-* Connect USB-OTG#2 in the picture above to a USB port on your computer (or a powered USB hub to make sure there is enough power available to the board).
+* Connect USB-OTG#2 in the picture above to a USB port on your computer (or a powered USB hub to make sure there is enough power available to the board). 
 
-* The red PWR LED should be lit.
+* The red PWR LED should be lit. 
 
 * Connect the JTAG connector to the SWD/JTAG interface on the board. The other end of the cable should be connected to the USB port or hub of your computer.
 
@@ -158,12 +158,12 @@ Successfully loaded image.
 
 <br>
 
-**But wait...not so fast.** Let's double check that it is indeed booting from flash and making the LED blink from the image in flash. Pull the USB cable off the Olimex JTAG adaptor, severing the debug connection to the JTAG port. Next power off the Olimex board by pulling out the USB cable from the board. Wait for a couple of seconds and plug the USB cable back to the board.
+**But wait...not so fast.** Let's double check that it is indeed booting from flash and making the LED blink from the image in flash. Pull the USB cable off the Olimex JTAG adaptor, severing the debug connection to the JTAG port. Next power off the Olimex board by pulling out the USB cable from the board. Wait for a couple of seconds and plug the USB cable back to the board. 
 
    The LED light will start blinking again. Success!
-
+  
    **Note #1:** If you want to download the image to flash and a gdb session opened up, use `newt debug blinky`. Type `c` to continue inside the gdb session.
-
+    
 ```no-highlight     
     $ newt debug blinky
     Debugging with ~/dev/myproj/hw/bsp/olimex_stm32-e407_...
@@ -175,7 +175,7 @@ Successfully loaded image.
     (info)
     ...
     target state: halted
-    target halted due to debug-request, current mode: Thread
+    target halted due to debug-request, current mode: Thread 
     xPSR: 0x01000000 pc: 0x08000250 msp: 0x10010000
     Info : accepting 'gdb' connection from 3333
     Info : device id = 0x10036413
@@ -186,22 +186,22 @@ Successfully loaded image.
 ```
 
 <br>
-
+    
    **Note #2:** If you want to erase the flash and load the image again you may use the following commands from within gdb. `flash erase_sector 0 0 x` tells it to erase sectors 0 through x. When you ask it to display (in hex notation) the contents of the sector starting at location 'lma,' you should see all f's. The memory location 0x8000000 is the start or origin of the flash memory contents and is specified in the olimex_stm32-e407_devboard.ld linker script. The flash memory locations is specific to the processor.
 ```no-highlight         
     (gdb) monitor flash erase_sector 0 0 4
     erased sectors 0 through 4 on flash bank 0 in 2.296712s
     (gdb) monitor mdw 0x08000000 16
-    0x08000000: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
-    (0x08000020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
-    (0x08000000: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
+    0x08000000: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff 
+    (0x08000020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff 
+    (0x08000000: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff 
     (0x08000020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff         
     (gdb) monitor flash info 0
 ```
 
 ### Conclusion
 
-Congratulations! You have now tried out a project on actual hardware. If this is your first time to embedded systems, this must feel like the best hands-on and low-level "Hello World" program ever.
+Congratulations! You have now tried out a project on actual hardware. If this is your first time to embedded systems, this must feel like the best hands-on and low-level "Hello World" program ever. 
 
 Good, we have more fun tutorials for you to get your hands dirty. Be bold and try other Blinky-like [tutorials](../tutorials/nRF52.md) or try enabling additional functionality such as [remote comms](project-target-slinky.md) on the current board.
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/32902442/docs/os/tutorials/pics/LightBlue-1.jpg
----------------------------------------------------------------------
diff --git a/docs/os/tutorials/pics/LightBlue-1.jpg b/docs/os/tutorials/pics/LightBlue-1.jpg
new file mode 100644
index 0000000..87a305e
Binary files /dev/null and b/docs/os/tutorials/pics/LightBlue-1.jpg differ

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/32902442/docs/os/tutorials/pics/LightBlue-2.jpg
----------------------------------------------------------------------
diff --git a/docs/os/tutorials/pics/LightBlue-2.jpg b/docs/os/tutorials/pics/LightBlue-2.jpg
new file mode 100644
index 0000000..715deff
Binary files /dev/null and b/docs/os/tutorials/pics/LightBlue-2.jpg differ

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/32902442/docs/os/tutorials/pics/LightBlue-3.jpg
----------------------------------------------------------------------
diff --git a/docs/os/tutorials/pics/LightBlue-3.jpg b/docs/os/tutorials/pics/LightBlue-3.jpg
new file mode 100644
index 0000000..5ceb627
Binary files /dev/null and b/docs/os/tutorials/pics/LightBlue-3.jpg differ

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/32902442/docs/os/tutorials/pics/LightBlue-4.jpg
----------------------------------------------------------------------
diff --git a/docs/os/tutorials/pics/LightBlue-4.jpg b/docs/os/tutorials/pics/LightBlue-4.jpg
new file mode 100644
index 0000000..a8e35c3
Binary files /dev/null and b/docs/os/tutorials/pics/LightBlue-4.jpg differ

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/32902442/docs/os/tutorials/pics/LightBlue-5.jpg
----------------------------------------------------------------------
diff --git a/docs/os/tutorials/pics/LightBlue-5.jpg b/docs/os/tutorials/pics/LightBlue-5.jpg
new file mode 100644
index 0000000..4a3cbbd
Binary files /dev/null and b/docs/os/tutorials/pics/LightBlue-5.jpg differ

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/32902442/docs/os/tutorials/pics/LightBlue-6.jpg
----------------------------------------------------------------------
diff --git a/docs/os/tutorials/pics/LightBlue-6.jpg b/docs/os/tutorials/pics/LightBlue-6.jpg
new file mode 100644
index 0000000..eb4ca4d
Binary files /dev/null and b/docs/os/tutorials/pics/LightBlue-6.jpg differ

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/32902442/docs/os/tutorials/project-slinky.md
----------------------------------------------------------------------
diff --git a/docs/os/tutorials/project-slinky.md b/docs/os/tutorials/project-slinky.md
index 5537001..2949437 100644
--- a/docs/os/tutorials/project-slinky.md
+++ b/docs/os/tutorials/project-slinky.md
@@ -1,13 +1,9 @@
 ## Project Sim Slinky  
 
 
-<br>
-
-The goal of the project is to use a sample app called "Slinky" included in the Mynewt repository to enable remote communications with a device running the Mynewt OS. The protocol for remote communications is called newt manager (newtmgr). In this tutorial we will create a target for a simulated device and define it with the sample app "Slinky". 
+### Objective
 
-If you have an existing project using a target that does not use the Slinky app and you wish to add newtmgt functonality to it, check out the tutorial titled [Enable newtmgr in any app](add_newtmgr.md). 
-
-<br>
+The goal of the project is to enable and demonstrate remote communications with the Mynewt OS via newt manager (newtmgr). We will do this through building a project with Mynewt called Slinky that runs via the native platform. 
 
 ### What you need
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/32902442/docs/os/tutorials/project-target-slinky.md
----------------------------------------------------------------------
diff --git a/docs/os/tutorials/project-target-slinky.md b/docs/os/tutorials/project-target-slinky.md
index bea8049..8f71650 100644
--- a/docs/os/tutorials/project-target-slinky.md
+++ b/docs/os/tutorials/project-target-slinky.md
@@ -1,17 +1,13 @@
-## Project Slinky using STM32 board
+## Project Slinky 
 
 
-<br>
-
-The goal of the project is to enable and demonstrate remote communications with the Mynewt OS via newt manager (newtmgr) by leveraging a sample app "Slinky" included under the /apps directory in the repository. In this project we will define a target for the STM32-E407 board and assign the app "Slinky" to it.
+### Objective
 
-If you have an existing project using a target that does not use the Slinky app and you wish to add newtmgt functonality to it, check out the tutorial titled [Enable newtmgr in any app](add_newtmgr.md).
-
-<br>
+The goal of the project is to enable and demonstrate remote communications with the Mynewt OS via newt manager (newtmgr). We will do this through a project with Mynewt called Slinky that runs on the STM32-E407 board.
 
 ### What you need
 
-1. STM32-E407 development board from Olimex. You can order it from [http://www.mouser.com](http://www.mouser.com/search/ProductDetail.aspx?R=0virtualkey0virtualkeySTM32-E407), [http://www.digikey.com](http://www.digikey.com/product-detail/en/STM32-E407/1188-1093-ND/3726951), and other places.
+1. STM32-E407 development board from Olimex. You can order it from [http://www.mouser.com](http://www.mouser.com/ProductDetail/Olimex-Ltd/STM32-E407/?qs=UN6GZl1KCcit6Ye0xmPO4A%3D%3D), [http://www.digikey.com](http://www.digikey.com/product-detail/en/STM32-E407/1188-1093-ND/3726951), and other places.
 2. ARM-USB-TINY-H connector with JTAG interface for debugging ARM microcontrollers (comes with the ribbon cable to hook up to the board)
 3. USB A-B type cable to connect the debugger to your personal computer
 4. A USB to TTL Serial Cable with female wiring harness. An example is [http://www.amazon.com/JBtek�-WINDOWS-Supported-Raspberry-Programming/dp/B00QT7LQ88/ref=lp_464404_1_9?s=pc&ie=UTF8&qid=1454631303&sr=1-9](http://www.amazon.com/JBtek�-WINDOWS-Supported-Raspberry-Programming/dp/B00QT7LQ88/ref=lp_464404_1_9?s=pc&ie=UTF8&qid=1454631303&sr=1-9)
@@ -26,18 +22,18 @@ The instructions assume the user is using a Bourne-compatible shell (e.g. bash o
 * Install dependencies
 * Define a target using the newt tool
 * Build executables for the targets using the newt tool
-* Set up serial connection with the targets
+* Set up serial connection with the targets 
 * Create a connection profile using the newtmgr tool
 * Use the newtmgr tool to communicate with the targets
 
 ### Install newt
 
-If you have not already installed `newt`, see the
+If you have not already installed `newt`, see the 
 [newt installation instructions](../get_started/get_started/) and ensure newt is installed an in your path.
 
 ### Install newtmgr
 
-If you have not already installed `newtmgr`, see the
+If you have not already installed `newtmgr`, see the 
 [newtmgr installation instructions](../../newtmgr/installing/) and ensure newtmgr is installed an in your path.
 
 ### Create a new project
@@ -116,11 +112,11 @@ Build manifest: /Users/paulfdietrich/dev/slinky/bin/stm32_slinky/apps/slinky/man
 
 <br>
 
-### Using newtmgr with a remote target
+### Using newtmgr with a remote target 
 
-* First make sure the USB A-B type cable is connected to the ARM-USB-TINY-H debugger connector on the Olimex board.
+* First make sure the USB A-B type cable is connected to the ARM-USB-TINY-H debugger connector on the Olimex board. 
 
-     Next go the to project directory and download the slinky project image to the flash of the Olimex board.
+     Next go the to project directory and download the slinky project image to the flash of the Olimex board. 
 
 ```no-highlight
 $ newt load stm32_bootloader
@@ -136,8 +132,8 @@ You can now disconnect the debugging cable from the board. You should see the gr
     ![Alt Layout - Serial Connection](pics/serial_conn.png)
 
 
-	* Connect the female RX pin of the USB-TTL serial cable to the TX of the UEXT connector on the board.
-	* Connect the female TX pin of the USB-TTL serial cable to the RX of the UEXT connector on the board.
+	* Connect the female RX pin of the USB-TTL serial cable to the TX of the UEXT connector on the board. 
+	* Connect the female TX pin of the USB-TTL serial cable to the RX of the UEXT connector on the board. 
 	* Connect the GND pin of the USB-TTL serial cable to the GND of the UEXT connector on the board.
 
 <br>
@@ -145,7 +141,7 @@ You can now disconnect the debugging cable from the board. You should see the gr
 * Locate the serial connection established in the /dev directory of your computer. It should be of the type `tty.usbserial-<some identifier>`.
 
 ```no-highlight
-        $ ls /dev/tty.usbserial-AJ03HAQQ
+        $ ls /dev/tty.usbserial-AJ03HAQQ 
         /dev/tty.usbserial-AJ03HAQQ
 ```
 
@@ -156,17 +152,17 @@ You can now disconnect the debugging cable from the board. You should see the gr
 ```no-highlight
         $ pwd
         /Users/<user>/dev/larva/project/slinky
-        $ newtmgr conn add olimex01 type=serial connstring=/dev/tty.usbserial-AJ03HAQQ
+        $ newtmgr conn add olimex01 type=serial connstring=/dev/tty.usbserial-AJ03HAQQ 
         Connection profile olimex01 successfully added
         $ newtmgr conn show
-        Connection profiles:
+        Connection profiles: 
           sim1: type=serial, connstring='/dev/ttys007'
           olimex01: type=serial, connstring='/dev/tty.usbserial-AJ03HAQQ'
 ```
 
 <br>
 
-* Now go ahead and query the Olimex board to get responses back. The simplest command is the `echo` command to ask it to respond with the text you send it.
+* Now go ahead and query the Olimex board to get responses back. The simplest command is the `echo` command to ask it to respond with the text you send it. 
 
 ```no-highlight
     $ newtmgr echo -c olimex01 hello
@@ -182,3 +178,13 @@ You can now disconnect the debugging cable from the board. You should see the gr
       idle (prio=255 tid=0 runtime=299916 cswcnt=313 stksize=32 stkusage=18 last_checkin=0 next_checkin=0)
       shell (prio=3 tid=1 runtime=1 cswcnt=20 stksize=384 stkusage=60 last_checkin=0 next_checkin=0)
 ```
+
+
+
+
+
+
+
+
+
+