{"id":301,"date":"2015-08-02T21:17:27","date_gmt":"2015-08-03T04:17:27","guid":{"rendered":"http:\/\/visualgdb.com\/w\/?p=301"},"modified":"2015-08-02T21:17:27","modified_gmt":"2015-08-03T04:17:27","slug":"creating-a-bluetooth-le-mouse-using-nordic-nrf51-and-visual-studio","status":"publish","type":"post","link":"https:\/\/visualgdb.com\/tutorials\/arm\/nrf51\/mouse\/","title":{"rendered":"Creating a Bluetooth LE Mouse using Nordic nRF51 and Visual Studio"},"content":{"rendered":"<p>This tutorial shows how to create a Bluetooth LE Mouse firmware using the Nordic nRF51 SDK and VisualGDB, demonstrates different aspects of debugging Bluetooth firmware and shows the main concepts of the Nordic nRF51 Bluetooth LE stack. Before you begin, install VisualGDB 5.0, get a Bluetooth LE-capable device (e.g. a new Android phone) and follow our <a href=\"http:\/\/visualgdb.com\/tutorials\/arm\/nrf51\/\">basic Nordic tutorial<\/a> to get started.<\/p>\n<ol>\n<li>Start Visual Studio. Select File-&gt;New Project-&gt;VisualGDB-&gt;Embedded Project Wizard:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/01-newprj.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-303\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/01-newprj.png\" alt=\"01-newprj\" width=\"800\" height=\"517\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/01-newprj.png 800w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/01-newprj-300x194.png 300w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><\/a><\/li>\n<li>Proceed with the default &#8220;Embedded binary&#8221; setting. As the Bluetooth LE applications contain a lot of source files, it is recommended to select the &#8220;Enable multi-threaded build&#8221; flag:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/02-wizard.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-304\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/02-wizard.png\" alt=\"02-wizard\" width=\"702\" height=\"571\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/02-wizard.png 702w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/02-wizard-300x244.png 300w\" sizes=\"(max-width: 702px) 100vw, 702px\" \/><\/a><\/li>\n<li>Choose the device you are targeting and select the S110 soft device. Ensure that the &#8220;softdevice firmware is programmed separately&#8221; checkbox is NOT checked:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/03-device.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-305\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/03-device.png\" alt=\"03-device\" width=\"702\" height=\"628\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/03-device.png 702w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/03-device-300x268.png 300w\" sizes=\"(max-width: 702px) 100vw, 702px\" \/><\/a><\/li>\n<li>On the next page select the &#8220;Bluetooth LE mouse&#8221; sample and specify your board type from the sticker on the board below. PCA10028 corresponds to the nRF51-DK board:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/04-mouse.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-306\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/04-mouse.png\" alt=\"04-mouse\" width=\"702\" height=\"628\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/04-mouse.png 702w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/04-mouse-300x268.png 300w\" sizes=\"(max-width: 702px) 100vw, 702px\" \/><\/a><\/li>\n<li>On the last page of the wizard select the Segger J-Link debug method (Nordic boards come with on-board J-Link) and check the &#8220;reset device after programming&#8221; checkbox:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/05-dbg.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-307\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/05-dbg.png\" alt=\"05-dbg\" width=\"702\" height=\"628\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/05-dbg.png 702w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/05-dbg-300x268.png 300w\" sizes=\"(max-width: 702px) 100vw, 702px\" \/><\/a>If you are using a different debug method, ensure that you enable device resetting for it as well. If you don&#8217;t do that, GDB will run the entry point of your program after loading it into device and this will bypass the softdevice initialization code. If you reset the device after programming, the ARM core will choose the correct entry point from the soft device automatically.<\/li>\n<li>Click &#8220;Finish&#8221; to generate your project. Then build it by pressing Ctrl-Shift-B:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/06-build.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-308\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/06-build.png\" alt=\"06-build\" width=\"695\" height=\"607\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/06-build.png 695w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/06-build-300x262.png 300w\" sizes=\"(max-width: 695px) 100vw, 695px\" \/><\/a><\/li>\n<li>Connect your board to the computer and ensure the switch on the board is on. Press F5 to start debugging the project. Ensure that the LED1 is blinking indicating that the board is sending discovery packets letting other devices find it:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/led.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-309\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/led.jpg\" alt=\"led\" width=\"700\" height=\"437\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/led.jpg 700w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/led-300x187.jpg 300w\" sizes=\"(max-width: 700px) 100vw, 700px\" \/><\/a><\/li>\n<li>If the LED1 is not blinking, try resetting the device using the Reset button in the GDB Session window:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/07-reset.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-310\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/07-reset.png\" alt=\"07-reset\" width=\"695\" height=\"605\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/07-reset.png 695w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/07-reset-300x261.png 300w\" sizes=\"(max-width: 695px) 100vw, 695px\" \/><\/a><\/li>\n<li>Get a Bluetooth LE-capable device (e.g. an Android smartphone or a tablet running Android 4.3+) and search for Bluetooth devices:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/mouse.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-311\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/mouse.png\" alt=\"mouse\" width=\"700\" height=\"259\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/mouse.png 700w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/mouse-300x111.png 300w\" sizes=\"(max-width: 700px) 100vw, 700px\" \/><\/a><\/li>\n<li>If the device does not appear in the list, reset the board while holding the button 2 on it. This should reset in erasing the bonds stored in the nRF51 memory. If this does not help, double-check with the debugger that erase_bonds is set or set it explicitly:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/08-bonds.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-312\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/08-bonds.png\" alt=\"08-bonds\" width=\"695\" height=\"607\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/08-bonds.png 695w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/08-bonds-300x262.png 300w\" sizes=\"(max-width: 695px) 100vw, 695px\" \/><\/a><\/li>\n<li>Pair your Android device with the mouse. Then try pressing buttons on the board and observe how the mouse pointer moves:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/conn.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-313\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/conn.png\" alt=\"conn\" width=\"700\" height=\"232\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/conn.png 700w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/conn-300x99.png 300w\" sizes=\"(max-width: 700px) 100vw, 700px\" \/><\/a><\/li>\n<li>Now we will use the debugger to see how the input events are handled. Set a breakpoint in the mouse_movement_send() function in main.c and press a button on the board:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/09-movement.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-315\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/09-movement.png\" alt=\"09-movement\" width=\"695\" height=\"690\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/09-movement.png 695w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/09-movement-150x150.png 150w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/09-movement-300x298.png 300w\" sizes=\"(max-width: 695px) 100vw, 695px\" \/><\/a><\/li>\n<li>If you try stepping through the code now, most likely your device will reset itself. This happens when the Bluetooth hardware triggers an interrupt while we are stopped in the debugger and by the time it is handled (when we step through code), the softdevice detects that too much time has passed and resets the processor. This is a known limitation documented <a href=\"https:\/\/devzone.nordicsemi.com\/question\/1489\/can-i-debug-ble-program\/\">here<\/a> and <a href=\"http:\/\/\u2022 https:\/\/devzone.nordicsemi.com\/question\/81\/how-can-i-debug-a-softdevice-application\/\">here<\/a>. To work around it, we will disable interrupt handling by setting the PRIMASK register to 1:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/10-primask.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-316\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/10-primask.png\" alt=\"10-primask\" width=\"695\" height=\"689\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/10-primask.png 695w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/10-primask-150x150.png 150w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/10-primask-300x297.png 300w\" sizes=\"(max-width: 695px) 100vw, 695px\" \/><\/a>This will allow stepping through the code without being interrupted, but once you are done stepping, you will need to reset the device, as the Nordic soft device cannot continue normal operation after not being able to handle the interrupts in time.<\/li>\n<li>If you step into the ble_hids_inp_rep_send() function, you will see that it sends an &#8220;attribute value updated&#8221; notification using the <strong>sd_ble_gatts_hvx()<\/strong> function. Note that the functions prefixed with <strong>sd_<\/strong> are implemented inside the softdevice and cannot be stepped into. As we cannot reliably continue running softdevice code after being stopped in the debugger, we will use the code map to quickly find related code. First of all, we will find how is the attribute updated in this call gets registered. Right-click on the characteristic handle (char_handles) and select &#8220;Show on Code Map&#8221;:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/10-codemap.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-317\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/10-codemap.png\" alt=\"10-codemap\" width=\"695\" height=\"691\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/10-codemap.png 695w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/10-codemap-150x150.png 150w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/10-codemap-300x298.png 300w\" sizes=\"(max-width: 695px) 100vw, 695px\" \/><\/a><\/li>\n<li>Then use the &#8220;show functions referencing this&#8221; and &#8220;show functions calling this&#8221; commands to find the function that registers the characteristics and the functions that call it during initialization:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/11-chars.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-319\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/11-chars.png\" alt=\"11-chars\" width=\"695\" height=\"688\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/11-chars.png 695w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/11-chars-300x297.png 300w\" sizes=\"(max-width: 695px) 100vw, 695px\" \/><\/a><\/li>\n<li>Set a breakpoint inside <strong>inp_rep_characteristics_add()<\/strong> and reset your device. The breakpoint will hit allowing you to examine what happens during initialization. You can also right-click on a function and select &#8220;Explore Call Hierarchy&#8221; to quickly navigate through the functions calling it:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/12-addchar.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-320\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/12-addchar.png\" alt=\"12-addchar\" width=\"695\" height=\"778\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/12-addchar.png 695w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/12-addchar-268x300.png 268w\" sizes=\"(max-width: 695px) 100vw, 695px\" \/><\/a><\/li>\n<li>If you use the &#8220;find all references&#8221; command to see where the <strong>p_inp_rep_array<\/strong> field is assigned, you will find that the <strong>hids_init()<\/strong> function is registering 3 input characteristics, one of them being INPUT_REP_MOVEMENT:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/report.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-321\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/report.png\" alt=\"report\" width=\"695\" height=\"776\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/report.png 695w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/report-269x300.png 269w\" sizes=\"(max-width: 695px) 100vw, 695px\" \/><\/a><\/li>\n<li>The registration code, however, does not specify that the report #2 corresponds to the mouse motion. This is specified in the HID descriptor that is filled in the <strong>hids_init()<\/strong> function:Accord<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/13-hiddesc.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-322\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/13-hiddesc.png\" alt=\"13-hiddesc\" width=\"695\" height=\"774\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/13-hiddesc.png 695w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/13-hiddesc-269x300.png 269w\" sizes=\"(max-width: 695px) 100vw, 695px\" \/><\/a><\/li>\n<li>The HID descriptor filled in hids_init() is then registered by the rep_map_char_add() function as the REPORT_MAP_CHAR characteristic:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/14-addchar.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-323\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/14-addchar.png\" alt=\"14-addchar\" width=\"695\" height=\"776\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/14-addchar.png 695w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/14-addchar-269x300.png 269w\" sizes=\"(max-width: 695px) 100vw, 695px\" \/><\/a>According to the <a href=\"https:\/\/www.bluetooth.org\/docman\/handlers\/downloaddoc.ashx?doc_id=245141\">Bluetooth LE HID specifiction<\/a>, the report map characteristics contains HID report descriptor from the <a href=\"http:\/\/www.usb.org\/developers\/hidpage\/HID1_11.pdf\">USB HID specification<\/a>.<\/li>\n<li>Now we will see what happens when device bonding occurs and what information is stored in the FLASH memory. Make sure your device has the connection to the nRF51 board and the buttons result in mouse movement, then unpair the device:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/unpair.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-324\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/unpair.png\" alt=\"unpair\" width=\"700\" height=\"394\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/unpair.png 700w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/unpair-300x169.png 300w\" sizes=\"(max-width: 700px) 100vw, 700px\" \/><\/a><\/li>\n<li>To see what happens during pairing and unpairing we will enable debug logging. The device pairing logic is implemented in the device_manager_peripheral.c file using DM_LOG() and other similar macros. Using the go-to-definition command we can see that they are disabled unless ENABLE_DEBUG_LOG_SUPPORT is defined:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/15-trace.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-325\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/15-trace.png\" alt=\"15-trace\" width=\"695\" height=\"540\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/15-trace.png 695w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/15-trace-300x233.png 300w\" sizes=\"(max-width: 695px) 100vw, 695px\" \/><\/a><\/li>\n<li>Add the ENABLE_DEBUG_LOG_SUPPORT on the Makefile Settings page of VisualGDB Project Properties and set UART_TX_BUF_SIZE to 2048 to avoid buffer overruns:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/16-log1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-333\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/16-log1.png\" alt=\"16-log\" width=\"843\" height=\"733\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/16-log1.png 843w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/16-log1-300x261.png 300w\" sizes=\"(max-width: 843px) 100vw, 843px\" \/><\/a><\/li>\n<li>Then select UART with FIFO in the &#8220;UART Driver&#8221; field on the Embedded Frameworks page:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/17-uart-fifo.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-327\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/17-uart-fifo.png\" alt=\"17-uart-fifo\" width=\"727\" height=\"733\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/17-uart-fifo.png 727w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/17-uart-fifo-150x150.png 150w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/17-uart-fifo-298x300.png 298w\" sizes=\"(max-width: 727px) 100vw, 727px\" \/><\/a><\/li>\n<li>The on-board J-Link comes with a USB COM port driver that is connected to the Nordic device. If you are using the Custom edition of VisualGDB or higher, you can view the output from the COM port directly in Visual Studio by enabling it on the Raw Terminal page of VisualGDB Project Properties:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/18-console.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-328\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/18-console.png\" alt=\"18-console\" width=\"728\" height=\"733\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/18-console.png 728w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/18-console-150x150.png 150w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/18-console-298x300.png 298w\" sizes=\"(max-width: 728px) 100vw, 728px\" \/><\/a><\/li>\n<li>Press OK to apply the changes. If you get a &#8220;command line too long&#8221; error, try relocating the NRF51 BSP to a shorter path (e.g. c:\\nrf51) using the &#8220;change&#8221; button on the Embedded Project page of VisualGDB project properties:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/19-shared.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-329\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/19-shared.png\" alt=\"19-shared\" width=\"728\" height=\"733\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/19-shared.png 728w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/19-shared-150x150.png 150w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/19-shared-298x300.png 298w\" sizes=\"(max-width: 728px) 100vw, 728px\" \/><\/a>Do not forget to do a clean rebuild of your project if you have relocated the shared files.<\/li>\n<li>Now you can start debugging and observe the debug output in the COMx window (do not confuse it with ARM Semihosting console):<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/20-log2.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-334\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/20-log2.png\" alt=\"20-log\" width=\"695\" height=\"712\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/20-log2.png 695w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/20-log2-293x300.png 293w\" sizes=\"(max-width: 695px) 100vw, 695px\" \/><\/a><\/li>\n<li>Pair your Android device with the nRF51 board and observe the output. Note the &#8220;Bonded!&#8221; message:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/21-bonded.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-335\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/21-bonded.png\" alt=\"21-bonded\" width=\"662\" height=\"468\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/21-bonded.png 662w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/21-bonded-300x212.png 300w\" sizes=\"(max-width: 662px) 100vw, 662px\" \/><\/a><\/li>\n<li>Looking through the debug output and searching the source code for the messages shown there reveals the sequence of events that occurs during bonding:\n<ol style=\"list-style-type: lower-alpha;\">\n<li>First of all the BLE_GAP_EVT_CONNECTED event is sent. The <strong>dm_ble_evt_handler()<\/strong> function allocates a connection object in <strong>m_connection_table<\/strong> and tries to find a device instance matching the address of your Android device.<\/li>\n<li>Then the BLE_GAP_EVT_SEC_PARAMS_REQUEST event is triggered. As no matching device instance was found before, <strong>dm_ble_evt_handler()<\/strong> calls <strong>device_instance_allocate()<\/strong> that results in storing the device address in <strong>m_peer_table<\/strong>.<\/li>\n<li>The BLE_GAP_EVT_CONN_SEC_UPDATE event is sent resulting in updating of the security keys.<\/li>\n<li>Finally, the BLE_GAP_EVT_AUTH_STATUS is sent. This results in storing the bond information in the FLASH memory via a call to <strong>device_context_store()<\/strong>. The data format used by the device manager can be found by searching <strong>device_manager_peripheral.c<\/strong> for &#8220;device_manager_context_offsets&#8221;.<\/li>\n<\/ol>\n<\/li>\n<li>If you are frequently uploading different programs using the same softdevice, you can remove the softdevice code from the firmware built by VisualGDB via VisualGDB Project properties:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/22-exclude.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-336\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/22-exclude.png\" alt=\"22-exclude\" width=\"843\" height=\"733\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/22-exclude.png 843w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/22-exclude-300x261.png 300w\" sizes=\"(max-width: 843px) 100vw, 843px\" \/><\/a>This will leave a gap in the area where the softdevice normally resides, resulting in reduced firmware upload time. However if you try to upload such firmware to a device that does not have a softdevice already programmed (or has a different softdevice), you will get strange runtime errors.<\/li>\n<\/ol>\n","protected":false},"excerpt":{"rendered":"<p>This tutorial shows how to create a Bluetooth LE Mouse firmware using the Nordic nRF51 SDK and VisualGDB, demonstrates different<\/p>\n","protected":false},"author":1,"featured_media":338,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[18],"tags":[53,96,56,95],"_links":{"self":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/301"}],"collection":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/comments?post=301"}],"version-history":[{"count":6,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/301\/revisions"}],"predecessor-version":[{"id":416,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/301\/revisions\/416"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/media\/338"}],"wp:attachment":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/media?parent=301"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/categories?post=301"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/tags?post=301"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}