Wireless Connectivity Knowledge Base

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Wireless Connectivity Knowledge Base

Discussions

Sort by:
Introduction This post guides you on migrating from MKW36Z512VHT4 to MKW36A512VFT4 MCUs. This example will make use of the "beacon" SDK example. SDK Download and Install 1- Go to MCUXpresso web page: MCUXpresso Web Page 2- Log in with your registered account. 3- Search for the "KW36A" device. Then click on the suggested processor and click on "Build MCUXpresso SDK"       4- The next page will be displayed. Select “All toolchains” in the “Toolchain / IDE” box and provide a name to identify the package. Then click on "Download SDK".     5- Accept the license agreement. Wait a few minutes until the system gets the package into your profile. Download the SDK clicking on "Download SDK Archive" as depicted in the following figure.     6- If MCUXpresso IDE is used, drag and drop the KW36A SDK zip folder in “Installed SDK’s” perspective to install the package.     At this point, you have downloaded and installed the SDK package for the KW36A device.   Software Migration in MCUXpresso IDE 1- Import the "beacon" example on the MCUXpresso workspace. Click on “Import SDK examples(s)…” option, a new window will appear. Then select "MKW36Z512xxx4" and click on the FRDM-KW36 image. Click on the "Next >" button.     2- Search beacon and select your project version (bm or freertos).     3- Go to Project/Properties. Expand C/C++ Build/MCU settings and select MKW36A512xxx4 MCU. Click Apply and Close button to save the configuration.     4- Rename MKW36Z folders as MKW36A, clicking the right mouse button and selecting "Rename". These are the following:   framework/DCDC/Interface -> MKW36Z framework/DCDC/Source -> MKW36Z framework/LowPower/Interface -> MKW36Z framework/LowPower/Source -> MKW36Z framework/XCVR -> MKW36Z4     5- Open the Project/Properties window in MCUXpresso IDE. Go to C/C++ Build/Settings and select MCU C Compiler/Includes folder in the Tool Settings window. Edit all paths related to MKW36 MCU, in according to MKW35 folders before created. The results must look similar as shown below:   ../framework/LowPower/Interface/MKW36A ../framework/LowPower/Source/MKW36A ../framework/DCDC/Interface/MKW36A ../framework/XCVR/MKW36A4     6- Select MCU Assembler/General folder in Tool Settings. Edit the paths related to MKW36 MCU. The results must look similar as shown below:   ../framework/LowPower/Interface/MKW36A ../framework/LowPower/Source/MKW36A ../framework/DCDC/Interface/MKW36A ../framework/XCVR/MKW36A4     7- Go to Project/Properties. Expand MCU C Compiler/Preprocessor window. Edit "CPU_MKW36Z512VHT4" and "CPU_MKW36Z512VHT4_cm0plus" symbols, rename it as "CPU_MKW36A512VFT4" and "CPU_MKW36A512VFT4_cm0plus" respectively. Save the changes.     8- Go to the workspace. Delete “fsl_device_registers, MKW36Z4, MKW36Z4_features, system_MKW36Z4.h and system_MKW36Z4.c” files located at CMSIS folder. Then, unzip the MKW35Z SDK package and search for “fsl_device_registers, MKW36A4, MKW36A4_features, system_MKW36A4.h and system_MKW36A4.c” files into this folder at the following paths:   <SDK_folder_root>/devices/MKW36A4/fsl_device_registers.h <SDK_folder_root>/devices/MKW36A4/MKW36A4.h <SDK_folder_root>/devices/MKW36A4/MKW36A4_features.h <SDK_folder_root>/devices/MKW36A4/system_MKW36A4.h <SDK_folder_root>/devices/MKW36A4/system_MKW36A4.c     9- Overwirte the “startup_mkw36z4.c” (located inthe startup folder) by the "startup_mkw36a4.c" located in the following path <SDK_folder_root>/devices/MKW36A4/mcuxpresso/startup_mkw36a4.c. You can simply drag and drop on the startup folder, and remove the older one.     10- Open "fsl_device_registers.h" file in CMSIS folder. Add"defined(CPU_MKW36A512VFT4)" in the following code (line 18 of the file):   /* * Include the cpu specific register header files. * * The CPU macro should be declared in the project or makefile. */ #if (defined(CPU_MKW36A512VFP4) || defined(CPU_MKW36A512VFT4) || defined(CPU_MKW36A512VHT4) || defined(CPU_MKW36A512VFT4))‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍   11- Open "ble_config.h" file in bluetooth->host->config folder. Add "defined(CPU_MKW36A512VFT4)" in the following code (line 146 of the file):   /* The maximum number of BLE connection supported by platform */ #if defined(CPU_QN9080C) #define MAX_PLATFORM_SUPPORTED_CONNECTIONS 16 #elif (defined(CPU_MKW36Z512VFP4) || defined(CPU_MKW36Z512VHT4) || defined(CPU_MKW36A512VFP4) || defined(CPU_MKW36A512VHT4) || defined(CPU_MKW36A512VFT4) || \ defined(CPU_MKW35Z512VHT4) || defined(CPU_MKW35A512VFP4) || \ defined(CPU_K32W032S1M2CAx_cm0plus) || defined(CPU_K32W032S1M2VPJ_cm0plus) || \ defined(CPU_K32W032S1M2CAx_cm4) || defined(CPU_K32W032S1M2VPJ_cm4) || \ defined(CPU_MKW38A512VFT4) || defined (CPU_MKW38Z512VFT4) || defined(CPU_MKW39A512VFT4) || \ defined(CPU_MKW37A512VFT4) || defined(CPU_MKW37Z512VFT4))‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍   12- Open "ble_controller_task.c" file in source->common folder. Add "defined(CPU_MKW36A512VFT4)" in the following code (line 272 of the file):    #elif (defined(CPU_MKW35A512VFP4) || defined(CPU_MKW35Z512VHT4) || defined(CPU_MKW36A512VFP4) || defined(CPU_MKW36A512VFT4) ||\ defined(CPU_MKW36A512VHT4) || defined(CPU_MKW36Z512VFP4) || defined(CPU_MKW36Z512VHT4)) /* Select BLE protocol on RADIO0_IRQ */ XCVR_MISC->XCVR_CTRL = (uint32_t)((XCVR_MISC->XCVR_CTRL & (uint32_t)~(uint32_t)( XCVR_CTRL_XCVR_CTRL_RADIO0_IRQ_SEL_MASK )) | (uint32_t)( (0UL << XCVR_CTRL_XCVR_CTRL_RADIO0_IRQ_SEL_SHIFT) ));‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍   13-Build the project.   At this point, the project is already migrated.   Software Migration in IAR Embedded Workbench IDE 1- Open the beacon project located in the following path: 2- Select the project in the workspace and press Alt + F7 to open project options.   3- In the General Options/Target window click the icon next to the device name and select the appropriate device NXP/KinetisKW/KW3x/NXP MKW36A512xxx4, then click the OK button.   4- Create a new folder with the name MKW36A at following paths: <SDK_root>/middleware/wireless/framework_5.4.6/DCDC/Interface <SDK_root>/middleware/wireless/framework_5.4.6/DCDC/Source <SDK_root>/middleware/wireless/framework_5.4.6/LowPower/Interface <SDK_root>/middleware/wireless/framework_5.4.6/LowPower/Source <SDK_root>/middleware/wireless/framework_5.4.6/XCVR     5- Copy all files inside MKW36Z folders located at the above paths and paste in MKW36A folders.     6- Select the beacon project in the workspace and press Alt+F7 to open project options window. In C/C++ Compiler/Preprocessor window, rename the paths related to MKW36Z folders to MKW36A folders. Rename the CPU_MKW36Z512VHT4 macro as CPU_MKW36A512VFT4 in the defined symbols text box. The results must look similar as shown below: Click the OK button. $PROJ_DIR$/middleware/wireless/framework_5.4.2/LowPower/Interface/MKW36A $PROJ_DIR$/../../../../../../../devices/MKW36A4/drivers $PROJ_DIR$/../../../../../../../middleware/wireless/framework_5.4.2/DCDC/Interface/MKW36A $PROJ_DIR$/../../../../../../../middleware/wireless/framework_5.4.2/XCVR/MKW36A4 $PROJ_DIR$/../../../../../../../devices/MKW36A4 $PROJ_DIR$/../../../../../../../devices/MKW36A4/utilities     7- Expand the startup folder, select all files, click the right mouse button and select the “Remove” option. Click the right mouse button on the folder and select “Add/Add files”. Add the startup_MKW36A4.s located at this path: <SDK_root>/devices/MKW36A4/iar/startup_MKW36A4.s Also, add system_MKW36A4.c and system_MKW36A4.h into the startup folder. Both files are located at the next path: <SDK_root>/devices/MKW36A4   8- Open "ble_config.h" file in bluetooth->host->config folder. Add "defined(CPU_MKW36A512VFT4)" in the following code: /* The maximum number of BLE connection supported by platform */ #if defined(CPU_QN9080C) #define MAX_PLATFORM_SUPPORTED_CONNECTIONS 16 #elif (defined(CPU_MKW36Z512VFP4) || defined(CPU_MKW36Z512VHT4) || defined(CPU_MKW36A512VFP4) || defined(CPU_MKW36A512VHT4) || defined(CPU_MKW36A512VFT4) || \ defined(CPU_MKW35Z512VHT4) || defined(CPU_MKW35A512VFP4) || \ defined(CPU_K32W032S1M2CAx_cm0plus) || defined(CPU_K32W032S1M2VPJ_cm0plus) || \ defined(CPU_K32W032S1M2CAx_cm4) || defined(CPU_K32W032S1M2VPJ_cm4) || \ defined(CPU_MKW38A512VFT4) || defined (CPU_MKW38Z512VFT4) || defined(CPU_MKW39A512VFT4) || \ defined(CPU_MKW37A512VFT4) || defined(CPU_MKW37Z512VFT4))‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍   9- Open "ble_controller_task.c" file in source->common folder. Add "defined(CPU_MKW36A512VFT4)" in the following code: #elif (defined(CPU_MKW35A512VFP4) || defined(CPU_MKW35Z512VHT4) || defined(CPU_MKW36A512VFP4) || defined(CPU_MKW36A512VFT4) ||\ defined(CPU_MKW36A512VHT4) || defined(CPU_MKW36Z512VFP4) || defined(CPU_MKW36Z512VHT4)) /* Select BLE protocol on RADIO0_IRQ */ XCVR_MISC->XCVR_CTRL = (uint32_t)((XCVR_MISC->XCVR_CTRL & (uint32_t)~(uint32_t)( XCVR_CTRL_XCVR_CTRL_RADIO0_IRQ_SEL_MASK )) | (uint32_t)( (0UL << XCVR_CTRL_XCVR_CTRL_RADIO0_IRQ_SEL_SHIFT) ));‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍   10-Build the project.   At this point, the project is already migrated.
View full article
This document describes how to update and sniff Bluetooth LE wireless applications on the USB-KW41 Programming the USB-KW41 as sniffer   It was noticed that there are some issues trying to follow a Bluetooth LE connection, even if the sniffer catches the connection request. These issues have been fixed in the latest binary file which can be found in the Test Tool for Connectivity Products 12.8.0.0 or newest.   After the Test Tool Installation, you’ll find the sniffer binary file at the following path. C:\NXP\Test Tool 12.8.1.0\images\KW41_802.15.4_SnifferOnUSB.bin   Programming Process. 1. Connect the USB-KW41Z to your PC, and it will be enumerated as Mass Storage Device 2. Drag and drop the "KW41_802.15.4_SnifferOnUSB.bin" included in Test tool for Connectivity Products.    "C:\NXP\Test Tool 12.8.0.0\images\KW41_802.15.4_SnifferOnUSB.bin"   3. Unplug the device and hold the RESET button of the USB-KW41Z, plug to your PC and the K22 will enter in bootloader mode. 4. Drag and drop the "sniffer_usbkw41z_k22f_0x8000.bin" included in Test tool for Connectivity Products.    "C:\NXP\Test Tool 12.8.5.9\images\sniffer_usbkw41z_k22f_0x8000.bin"   5. Then, unplug and plug the USB-KW41Z to your PC.                                                                                                          Note: If the USB-KW41 is not enumerated as Mass Storage Device, please look at the next thread https://community.nxp.com/thread/444708   General Recommendations   Software Tools  Kinetis Protocol Analyzer Wireshark version (2.4.8) Hardware Tools 1 USB-KW41 (updated with KW41_802.15.4_SnifferOnUSB.bin from Test Tool 12.8 or later)   The Kinetis Protocol Analyzer provides the ability to monitor the Bluetooth LE Advertisement Channels. It listens to all the activity and follows the connection when capturing a Connection Request.   Bluetooth LE Peripheral device transmits packets on the 3 advertising channels one after the other, so the USB-KW41 will listen to the 3 channels one by one and could or not catch the connection request.   Common use case The USB-KW41 will follow the Bluetooth LE connection if the connection request happens on the same channel that It is listening. If is listening to a different channel when the connection request is sent, it won't be able to follow it.   A Simple recommendation is the Bluetooth LE Peripheral should be set up to send the adv packets only to one channel and the sniffer just capturing on the same channel.   Improvement Use 3 USB-KW41, each of them will be dedicated to one channel and will catch the connection request.   Configure Kinetis Protocol Analyzer and Wireshark Network Analyzer   Note: For better results, address filter can be activated. When you are capturing all the packets in the air, you will notice 3 adv packets. Each packet will show the adv channel that is getting the adv frame.       One of the three sniffers will capture the Connection Request. In this case, it happens on channel 38.       You will be able to follow the connection, see all the data exchange.   For a better reference, you can look at the USB-KW41 Getting Started     Hope it helps   Regards, Mario
View full article
Hello community, This time I bring to you a document which explains how easy is to add a new endpoint and a new cluster to a ZigBee device in the BeeStack in BeeKit. This document is based in the MC1323x MCUs but the procedure applies to the Kinetis devices. Before to start you need to install the BeeKit Wireless Connectivity Toolkit​. If you are interested about what an endpoint is, the document ZigBee Endpoints Reserved could be useful for you. I hope you find this guide useful. Enjoy this guide, enjoy ZigBee! Any feedback is welcome. Best regards, Earl Orlando Ramírez-Sánchez Technical Support Engineer NXP Semiconductors
View full article
Introduction When a software update is requested by an OTAP Client (a device that receives a software update, commonly Bluetooth LE Peripheral) from the OTAP Server (a device that sends a software update, commonly Bluetooth LE Central), you may want to preserve some data previously acquired, such as bonding information, trimming values for the system oscillators, or probably NVM data for your application. This document guides you in performing OTAP updates preserving the flash data content of your interest. This document is intended for developers familiarized with OTAP custom Bluetooth LE service, for more information, you can take a look at the following post: Reprogramming a KW36 device using the OTAP Client Software.   OTAP Header and Sub-elements OTAP Protocol implements a format for the software update that is composed of a header and a defined number of sub-elements. The OTAP Header describes general information about the software update and it has a defined format shown in the following figure. For more information about the header fields, you can go to 11.4.1 Bluetooth Low Energy OTAP header chapter of the Bluetooth Low Energy Application Developer's Guide document included in the SDK at <SDK_2.2.X_FRDM-KW36_Download_Path>\docs\wireless\Bluetooth                              Each Sub-element contains information for a specific purpose. You could implement your proprietary fields for your application (For more information about sub-element fields, you can go to 11.4.1 Bluetooth Low Energy OTAP header chapter of the Bluetooth Low Energy Application Developer's Guide document included in the SDK at <SDK_2.2.X_FRDM-KW36_Download_Path>\docs\wireless\Bluetooth). OTAP includes the following sub-elements: Image File Sub-element Value Field Lenght (bytes) Description Upgrade Image  Variable This sub-element contains the actual binary executable image which is copied into the flash memory of the OTAP Client device. The maximum size of this sub-element depends on the target hardware. Sector Bitmap 32 This sub-element contains a sector bitmap of the flash memory of the target device which tells the bootloader which sectors should be overwritten and which leave intact. The format of this field is the least-significant bit first for each byte with the least significant bytes and bits standing for the lowest memory sections of the flash.  Image File CRC 2 This is a 16-bit CRC calculated over all elements of the image file except this field itself. This element must be the last sub-element in an image file sent over the air.   OTAP Sector Bitmap Sub-element Field The KW36 Flash is partitioned into: One 256 KB Program Flash (P-Flash) array divided into 2 KB sectors with a flash address range from 0x0000_0000 to 0x0003_FFFF. One 256 KB FlexNVM array divided in 2 KB sectors, flash address ranges from 0x1000_0000 to 0x1003_FFFF with an Alias memory with address range 0x0004_0000 to 0x0007_FFFF. The Bitmap sub-element is 256 bits of length, in terms of the KW36 flash, each bit represents a 2KB sector covering the address range from 0x0 - 0x0007_FFFF (P-Flash to FlexNVM Alias address range), where 1 means that such sector should be erased and 0 means that such sector should be preserved. The Bitmap field is used by the OTAP Bootloader to obtain the address range which should be erased before programming the KW36 with the software update, so it must be configured before sending a software update to leave intact the address range of memory that contain data of your interest and erase only the address range that will be overwritten by the software update.        For example: Suppose that a developer wants to preserve the address range between 0x7D800 - 0x7FFFF and the address range between 0x0 - 0x1FFF, and the left memory must be erased. The address range between 0x7D800 - 0x7FFFF corresponds to the 5 top flash sectors and the address range between 0x0 - 0x1FFF is the lowest 4 sectors. So, it means that bits between 256 and 252 (256, 255, 254, 253 and 252) and bits between 4 and 1 (4,3,2 and 1) should be set to 0, that way OTAP Bitmap for this example is: 0x07FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0   Configuring OTAP Bitmap to Protect an Address Range with NXP Test Tool Download and install Test Tool for Connectivity products in NXP's web site Open NXP Test Tool 12 software on your PC. Go to "OTA Updates -> OTAP Bluetooth LE" Then load your image file for the software update clicking on the "Browse..." button (NXP Test Tool only accepts .bin and .srec files). You can configure the OTAP Bitmap selecting the "Override sector bitmap" checkbox and changing the default value by your new bitmap value. Once you have configured the bitmap, select "Save...".   Then, a window will be displayed to select the destination to save the .bleota file. Provide a name to identify this file. You can use this file with IoT Toolbox App for Android and iOS to update the software using OTAP. This new .bleota file contains the bitmap that tells to the OTAP Bootloader which sectors will be erased and which sectors will be preserved.          
View full article
This document describes a simple process for enabling the user controls the radio through serial commands. Hardware requirements: • FRDM-KW41Z/QN902x board or a board programmed with HCI black box application. Software requirements: • Test Tool 12 application. It can be downloaded from the NXP web page. • HCI Black Box binary.   Running Demo 1. Load the board with hci_black_box example. 2. Open the Test Tool 12 software 3. Set up the correct Serial Configuration. If there were no changes in the application the default configuration will correspond to the one showed in the following figure. 4. Double click on the active device that you want to test, this will open the COM port in the command console. 5. Set the command set to the BLE_HCI.xml. This file has a list of the HCI commands that the user can send to the device, some of the commands have some options to be configured if necessary or some data to be filled. 6. To make easier the use of frequent commands, there is the option to add a shortcut to the command and the chosen behavior will be added to the panel. 7. Once you add the shortcut or choose the command or your preference, just double click over it and the tool will send the command to the device. In this case, we will send a reset on the board, this command does not receive any extra parameters, data or need any extra configuration.   8. If successful there will be a response or acknowledge of the behavior that will be shown in the right panel. Hope it helps. Regards, Mario
View full article
This article will describe in detailed steps how to generate, build and test a Bluetooth low energy Heart Rate Sensor project on the FRDM-KW41Z evaluation board by using the Bluetooth Developer Studio (BDS) and the NXP Kinetis BDS Plug-in. Getting Started To use this plug-in and test its output, the following programs are required:  - Bluetooth Developer Studio v1.1.306 or newer: Bluetooth Developer Studio & Plugins | Bluetooth Technology Website   - NXP Semiconductors Kinetis Plug-in v1.0.0: Link  - Kinetis SDK 2.0 with support for MKW41Z and Bluetooth Stack version 1.2.2: Link  - Kinetis SDK 2.0 add-on for BDS (found in the same package as the plug-in)  - Kinetis BLE Toolbox Android or iOS mobile application To enable the NXP Kinetis BDS Plug-in in the Bluetooth Developer Studio, follow please the installation details in the readme.txt document included in the downloaded plug-in archive. Creating the project with BDS Create a new project by clicking FILE-> NEW PROJECT. Add project location, name and namespace as detailed below: Drag and drop an adopted Heart Rate Profile from the right hand side list. Your device should import the following services:   Next step will be to configure the GAP layer. Click on the GAP button. First tab will be the Advertising Data. Enter desired values and check which AD types you want to include in the advertising packets. A bar below will show you how much bytes your data uses. Make sure you do not use more than the 32 bytes available. Next step is to configure the GAP properties. Make sure you check at least one advertising channel and a reasonable advertising interval range, as presented below:     Click TOOLS->GENERATE CODE. Select Server as GATT side to be generated and NXP Semiconductors Kinetis v1.0.0 as the plug-in. BDS will prompt you to enter a location for the exported files. After generating the files, another window with the results log will appear. If no error messages appear, the generation is successful. Check the “Open output location when finished” box and hit the “Finish” button. A folder with the following content will open: Using the generated code Copy the contents inside the following folder:  "<SDK 2.0 installation folder>\middleware\wireless\bluetooth_1.2.2\examples\bds_template_app". To generate the “bds_template_app” embedded project and test it, follow the instructions detailed in the Bluetooth Quick Start Guide document from the SDK. Seeing the application in action Before compiling the application add the following code snippet in app.c inside BleApp_HandleKeys:         case gKBD_EventPressPB2_c:         {             mUserData.cRrIntervals = 0;             mUserData.expendedEnergy = 100;             Hrs_RecordHeartRateMeasurement(service_heart_rate, 120, &mUserData);             break;         } This will allow the board to send heart rate data of 120 bpm while in a connection and when pressing button SW3 on the FRDM-KW41Z board. The value can be seen when using Kinetis BLE Toolbox, as shown below:
View full article
Introduction The FRDM-KW36 includes an RTC module with a 32 kHz crystal oscillator. This module generates a 32 kHz clock source for the MCU whilst running on very low power mode. This oscillator includes a set of programmable capacitors used as the C LOAD . Changing the value of these capacitors can modify the frequency the oscillator provides. This configurable capacitance ranges from 0 pF (capacitor bank disabled) to 30 pF in steps of 2 pF. These values are obtained by combining the enabled capacitors. The values available are 2 pF, 4 pF, 8 pF, and 16 pF. Any combination of these four can be done. It is recommended that these internal capacitors are disabled if the external capacitors are available (clearing SC2P, SC4P, SCS8, and SC16 bits in RTC Control Register SFR). To adjust the frequency provided by the oscillator, you must first be able to measure the frequency. Using a frequency counter would be ideal, as it provides a more precise measurement than an oscilloscope. You will also need to output the oscillator frequency. To output the oscillator frequency, using any of the Bluetooth demo applications as an example, you should do the following: Adjusting Frequency Example This example will make use of the Heart Rate Sensor demo (freertos version) from the Connectivity Software Stack and assumes that the developer has the knowledge of import or open projects from the SDK to IDE. Open or clone the Heart Rate Sensor project from your SDK. Find the board.c and board.h files in the board folder at the workspace.                                                                                Declare a void function on the board.h file as shown below. This function will be in order to mux the RTC clock out to the PTB3 and be able to measure the frequency.  /* Function to mux PTB3 to RTC_CLKOUT */ void BOARD_EnableRtcClkOut (void);‍‍ Develop the BOARD_EnableRtcClkOut function inside the board.c file as below. void BOARD_EnableRtcClkOut(void) { /* Enable PORTB clock gating */ CLOCK_EnableClock(kCLOCK_PortB); /* Mux the RTC_CLKOUT to PTB3 */ PORT_SetPinMux(PORTB, 3u, kPORT_MuxAlt7); /* Select the 32kHz reference for RTC_CLKOUT signal */ SIM->SOPT1 |= SIM_SOPT1_OSC32KOUT(1); } Call the BOARD_EnableRtcClkOut function in hardware_init function just after BOARD_BootClockRUN (board.c file). Find clock_config.c file in the board folder at the workspace. Add the following defines at the top of the file. #define RTC_OSC_CAP_LOAD_0 0x0U /*!< RTC oscillator, capacitance 0pF */ #define RTC_OSC_CAP_LOAD_2 0x2000U /*!< RTC oscillator, capacitance 2pF */ #define RTC_OSC_CAP_LOAD_4 0x1000U /*!< RTC oscillator, capacitance 4pF */ #define RTC_OSC_CAP_LOAD_6 0x3000U /*!< RTC oscillator, capacitance 6pF */ #define RTC_OSC_CAP_LOAD_8 0x800U /*!< RTC oscillator, capacitance 8pF */ #define RTC_OSC_CAP_LOAD_10 0x2800U /*!< RTC oscillator, capacitance 10pF */ #define RTC_OSC_CAP_LOAD_12 0x1800U /*!< RTC oscillator, capacitance 12pF */ #define RTC_OSC_CAP_LOAD_14 0x3800U /*!< RTC oscillator, capacitance 14pF */ #define RTC_OSC_CAP_LOAD_16 0x400U /*!< RTC oscillator, capacitance 16pF */ #define RTC_OSC_CAP_LOAD_18 0x2400U /*!< RTC oscillator, capacitance 18pF */ #define RTC_OSC_CAP_LOAD_20 0x1400U /*!< RTC oscillator, capacitance 20pF */ #define RTC_OSC_CAP_LOAD_22 0x3400U /*!< RTC oscillator, capacitance 22pF */ #define RTC_OSC_CAP_LOAD_24 0xC00U /*!< RTC oscillator, capacitance 24pF */ #define RTC_OSC_CAP_LOAD_26 0x2C00U /*!< RTC oscillator, capacitance 26pF */ #define RTC_OSC_CAP_LOAD_28 0x1C00U /*!< RTC oscillator, capacitance 28pF */ #define RTC_OSC_CAP_LOAD_30 0x3C00U /*!< RTC oscillator, capacitance 30pF */ Search the CLOCK_CONFIG_EnableRtcOsc call to a function inside the BOARD_BootClockRUN function (also in the clock_config.c file), and edit the argument by any of the defines above. Finally, disable the low power options and led support in the "preinclude.h" file located in the source folder of the project: #define cPWR_UsePowerDownMode 0 #define gLEDSupported_d 0 At this point, you can measure in PTB3 and play with the frequency adjust using your frequency counter. Each time that the board is programmed, you need to perform a POR to get the correct measure. The following table was obtained from an FRDM-KW36 board rev B and it can be used as a reference to adjust the frequency. Please note that the capacitance is not only composed of the enabled internal capacitance, but also the parasitic capacitances found in the package, bond wires, bond pad, and the PCB traces. So, while the reference measurements given below should be close to the actual value, you should also make measurements with your board, to ensure that the frequency is trimmed specifically to your board and layout.   Enabled Capacitors CLOAD Capacitance Definition Frequency - 0pF RTC_OSC_CAP_LOAD_0 (bank disabled) 32772.980Hz SC2P 2pF RTC_OSC_CAP_LOAD_2 32771.330Hz SC4P 4pF RTC_OSC_CAP_LOAD_4 32770.050Hz SC2P, SC4P 6pF RTC_OSC_CAP_LOAD_6 32769.122Hz SC8P 8pF RTC_OSC_CAP_LOAD_8 32768.289Hz SC2P, SC8P 10pF RTC_OSC_CAP_LOAD_10 32767.701Hz SC4P, SC8P 12pF RTC_OSC_CAP_LOAD_12 32767.182Hz SC2P, SC4P, SC8P 14pF RTC_OSC_CAP_LOAD_14 32766.766Hz SC16P 16pF RTC_OSC_CAP_LOAD_16 32766.338Hz SC2P, SC16P 18pF RTC_OSC_CAP_LOAD_18 32766.038Hz SC4P, SC16P 20pF RTC_OSC_CAP_LOAD_20 32765.762Hz SC2P, SC4P, SC16P 22pF RTC_OSC_CAP_LOAD_22 32765.532Hz SC8P, SC16P 24pF RTC_OSC_CAP_LOAD_24 32765.297Hz SC2P, SC8P, SC16P 26pF RTC_OSC_CAP_LOAD_26 32765.117Hz SC4P, SC8P, SC16P 28pF RTC_OSC_CAP_LOAD_28 32764.940Hz SC2P, SC4P, SC8P, SC16P 30pF RTC_OSC_CAP_LOAD_30 32764.764Hz
View full article
Introduction This document is to guide how to modify the OTAP Client software to the Low Power module. The starting point of this document is the OTAP Client example in the FRDM-KW36 SDK v2.2.2.   Deep Sleep Modes This section provides a base to understand how the developer should change between DSM1 (Deep Sleep Mode 1) and DSM3 (Deep Sleep Mode 3). The DSM6 does not need to be started by the developer, instead, the controller configures this mode automatically and returns to the latest mode after finished the radio activity.   DSM1 This low-power mode was designed to be used when the BLE stack is active, in other words when the LL is in advertising, scanning, or connection states. In this mode, the MCU enters LLS3 and BLE Link Layer enters deep sleep. The SoC wakes up from this mode by the on-board switches, by LPTMR timeout, or by BLE Link Layer wake-up interrupt (BLE_LL reference clock reaches wake up instance register) using LLWU module. The LPTMR timer is used to measure the time that the MCU spends in deep sleep to synchronize low-power timers at wakeup.   DSM3 This low-power mode was designed to be used when all stacks enabled for this platform are idle, in other words, when the LL stop advertising, scanning, or connection. In this mode, the MCU enters LLS3 and all enabled link layers remain idle. All RAM is retained. The SoC wakes up from this mode by the on-board switches, by DCDC power switch (when DCDC is in buck mode), or by LPTMR timeout using LLWU module. The LPTMR timer is also used to measure the time that MCU spends in deep sleep to synchronize low-power timers at wakeup.   DSM6 This low-power mode was developed to save some power while the radio is on. Its most common use case is with the radio in Rx waiting for a packet. Upon receiving the packet the radio wakes up the MCU. In this mode, the MCU enters STOP mode and the radio maintains its state. Any module capable of producing an interrupt can wake up the MCU, such as on-board switches, DCDC power switch (when DCDC is in buck mode), LPTMR timeout, Radio Interrupt, UART, and so on. The LPTMR timer is also used to measure the time that the MCU spends in deep sleep to synchronize low-power timers at wakeup.   For more information about DSM modes, you can inspect the “Connectivity Framework Reference Manual” chapter 3.15 Low-power library, it provides full information of Low Power modes and the usage on the NXP stack. It is available in your SDK at <FRDM-KW36 SDK root>\docs\wireless\Common.   Modifications on the Software In order to add low power on the OTAP Client (switching between DSM1, DSM3, and DSM6) two files must be modified: - app_preinclude.h - otap_client_att.c The following sections explain these changes.   app_preinclude.h This file is intended to contain the definitions that manage the behavior of the application. To include and enable the Low Power module you must add (or modify if the macro is already defined in this file) the following preprocessor directives.   1. Modify the AppPoolsDetails as following. /* Defines pools by block size and number of blocks. Must be aligned to 4 bytes.*/ #define AppPoolsDetails_c \ _block_size_ 32 _number_of_blocks_ 6 _eol_ \ _block_size_ 64 _number_of_blocks_ 4 _eol_ \ _block_size_ 88 _number_of_blocks_ 3 _eol_ \ _block_size_ 248 _number_of_blocks_ 2 _eol_ \ _block_size_ 312 _number_of_blocks_ 1 _eol_ \ _block_size_ 392 _number_of_blocks_ 1 _eol_‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍ 2. Set “cPWR_UsePowerDownMode” to 1 and keep the following directives in the “Framework Configuration” section as shown below. /* Check Low Power Timer */ #define cPWR_CheckLowPowerTimers 1 /* Enable/Disable Low Power Timer */ #define gTMR_EnableLowPowerTimers 1 /* Enable/Disable PowerDown functionality in PwrLib */ #define cPWR_UsePowerDownMode 1 /* Enable/Disable BLE Link Layer DSM */ #define cPWR_BLE_LL_Enable 1 /* Default Deep Sleep Mode*/ #define cPWR_DeepSleepMode 3 /* Enable/Disable MCU Sleep During BLE Events */ #define cMCU_SleepDuringBleEvents 1 /* Default deep sleep duration in ms */ #define cPWR_DeepSleepDurationMs 30000 /* Number of slots(625us) before the wake up instant before which the hardware needs to exit from deep sleep mode. */ #define cPWR_BLE_LL_OffsetToWakeupInstant 3 /* Enables / Disables the DCDC platform component */ #define gDCDC_Enabled_d 1 /* Default DCDC Mode used by the application */ #define APP_DCDC_MODE gDCDC_Mode_Buck_c /* Default DCDC Battery Level Monitor interval */ #define APP_DCDC_VBAT_MONITOR_INTERVAL 600000‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍ 3. Add the following directives in the “BLE Stack Configuration” section. Create the “Auto Configuration” section to disable LED support whenever Low Power is enabled. /*! ********************************************************************************* * BLE Stack Configuration ********************************************************************************** */ /* Time between the beginning of two consecutive advertising PDU's */ #define mcAdvertisingPacketInterval_c 0x02 /* 1.25 msec */ /* Offset to the first instant register. */ #define mcOffsetToFirstInstant_c 0x00 /* 625usec */ /*! ********************************************************************************* * Auto Configuration ********************************************************************************** */ /* Disable LEDs when enabling low power */ #if cPWR_UsePowerDownMode || gMWS_UseCoexistence_d #define gLEDSupported_d 0 #endif #if gMWS_UseCoexistence_d #undef gKBD_KeysCount_c #define gKBD_KeysCount_c 1 #endif‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍ 4. Modify the “Memory Pools Configuration” section as follows. /* Enable RNG seed storage in Flash */ #define gRngSeedStorageAddr_d ((uint32_t)FREESCALE_PROD_DATA_BASE_ADDR + 1024) /* Enable XCVR calibration storage in Flash */ #define gPreserveXcvrDacTrimValue_d 1 #define gXcvrDacTrimValueSorageAddr_d ((uint32_t)FREESCALE_PROD_DATA_BASE_ADDR + 1040) /* Application Connection sleep mode */ #define gAppDeepSleepMode_c 1 /* Application RAM usage configuration */ #define cPWR_RamRetentionInVLLS 2 /* 32K */ /* Disable unused LowPower modes */ #define cPWR_EnableDeepSleepMode_1 1 #define cPWR_EnableDeepSleepMode_2 0 #define cPWR_EnableDeepSleepMode_3 1 #define cPWR_EnableDeepSleepMode_4 0 #define cPWR_EnableDeepSleepMode_5 0 #define cPWR_EnableDeepSleepMode_7 0 #define cPWR_EnableDeepSleepMode_8 0 /* Warm-boot sequence will use the default stack which is used by ISRs on FreeRTOS */ #define USE_WARMBOOT_SP 0‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍   otap_client_att.c This is the main source file at the application level. Here are managed all the procedures that the device performs, before, during, and after to create a connection. This allows you to get the state of the device any instant and, hence, the dedicated low power APIs that rule the application must be implemented here, in the callbacks contained in this file, for an easier switching among the low power states.   1. Include “PWR_Configuration.h” header in “Include” section: #if (cPWR_UsePowerDownMode) #include "PWR_Interface.h" #include "PWR_Configuration.h" #endif‍‍‍‍‍‍‍‍‍‍‍‍ 2. Locate the “BleApp_Config” function. This function is executed once, after POR (Power on reset) during the device setup. Here you can change the deep sleep mode to DSM3 and allow the device to sleep using “PWR_ChangeDeepSleepMode” and “PWR_AllowDeviceToSleep” APIs. When the device has finished the initialization, it goes to sleep since all stacks are idle. See the following example. static void BleApp_Config(void) { #if defined(MULTICORE_APPLICATION_CORE) && (MULTICORE_APPLICATION_CORE == 1) if (GattDbDynamic_CreateDatabase() != gBleSuccess_c) { panic(0,0,0,0); return; } #endif /* MULTICORE_APPLICATION_CORE */ /* Common GAP configuration */ BleConnManager_GapCommonConfig(); /* Register stack callbacks */ (void)App_RegisterGattServerCallback (BleApp_GattServerCallback);‍‍‍‍‍‍‍‍‍‍‍‍‍ mAdvState.advOn = FALSE; /* Start services */ basServiceConfig.batteryLevel = BOARD_GetBatteryLevel(); (void)Bas_Start(&basServiceConfig); (void)Dis_Start(&disServiceConfig); if (OtapClient_Config() == FALSE) { /* An error occurred in configuring the OTAP Client */ panic(0,0,0,0); } /* Allocate application timer */ appTimerId = TMR_AllocateTimer(); mBatteryMeasurementTimerId = TMR_AllocateTimer(); #if (cPWR_UsePowerDownMode) #if MULTICORE_APPLICATION_CORE #if gErpcLowPowerApiServiceIncluded_c PWR_ChangeBlackBoxDeepSleepMode(cPWR_DeepSleepMode); PWR_AllowBlackBoxToSleep(); #endif PWR_ChangeDeepSleepMode(cPWR_DeepSleepMode); PWR_AllowDeviceToSleep(); #else PWR_ChangeDeepSleepMode(cPWR_DeepSleepMode); PWR_AllowDeviceToSleep(); #endif #endif }‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍ 3. Locate the “BleApp_Start” function. This function is executed just after wake up by pressing the LLWU SW3 button. This action will trigger the advertising, so, you must change the deep sleep mode to DSM1 using “PWR_ChangeDeepSleepMode” API since the BLE stack is active. See the following example. void BleApp_Start(void) { Led1On(); if (mPeerDeviceId == gInvalidDeviceId_c) { /* Device is not connected and not advertising*/ if (!mAdvState.advOn) { #if gAppUseBonding_d if (gcBondedDevices > 0) { mAdvState.advType = whiteListAdvState_c; } else { #endif mAdvState.advType = advState_c; #if gAppUseBonding_d } #endif #if (cPWR_UsePowerDownMode) #if MULTICORE_APPLICATION_CORE #if gErpcLowPowerApiServiceIncluded_c PWR_ChangeBlackBoxDeepSleepMode(gAppDeepSleepMode_c); #endif #else PWR_ChangeDeepSleepMode(gAppDeepSleepMode_c); #endif #endif BleApp_Advertise(); } } }‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍ 4. Locate the “BleApp_AdvertisingCallback” function. This function is executed every time the advertising state changes. Change the deep sleep mode to DSM3 when “mAdvState.advOn” is false, in other words, when the device stops advertising. If you stop the advertising either using an application timer or a user button, KW36 will go to sleep until you start advertising again (pressing LLWU SW3 button), saving power when all stacks are idle. See the following example. static void BleApp_AdvertisingCallback (gapAdvertisingEvent_t* pAdvertisingEvent) { switch (pAdvertisingEvent->eventType) { case gAdvertisingStateChanged_c: { mAdvState.advOn = !mAdvState.advOn; if(mAdvState.advOn) { LED_StopFlashingAllLeds(); Led1Flashing(); } #if (cPWR_UsePowerDownMode) else { #if MULTICORE_APPLICATION_CORE #if gErpcLowPowerApiServiceIncluded_c PWR_ChangeBlackBoxDeepSleepMode(cPWR_DeepSleepMode); #endif #else PWR_ChangeDeepSleepMode(cPWR_DeepSleepMode); #endif } #endif } break; case gAdvertisingCommandFailed_c: { Led2On(); panic(0,0,0,0); } break; default: ; /* For MISRA compliance */ break; } }‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍ 5. Locate “BleApp_ConnectionCallback” function. It is executed every time the connection state changes. In “gConnEvtConnected_c” add the following code to change to DSM1, since the BLE stack is active. case gConnEvtConnected_c: { /* Advertising stops when connected */ mAdvState.advOn = FALSE; (void)TMR_StopTimer(appTimerId); /* Subscribe client*/ mPeerDeviceId = peerDeviceId; (void)Bas_Subscribe(&basServiceConfig, peerDeviceId); (void)OtapCS_Subscribe(peerDeviceId); OtapClient_HandleConnectionEvent (peerDeviceId); /* Start battery measurements */ (void)TMR_StartLowPowerTimer(mBatteryMeasurementTimerId, gTmrLowPowerIntervalMillisTimer_c, TmrSeconds(mBatteryLevelReportInterval_c), BatteryMeasurementTimerCallback, NULL); #if (cPWR_UsePowerDownMode) #if MULTICORE_APPLICATION_CORE #if gErpcLowPowerApiServiceIncluded_c PWR_ChangeBlackBoxDeepSleepMode(gAppDeepSleepMode_c); PWR_AllowBlackBoxToSleep(); #endif #else PWR_ChangeDeepSleepMode(gAppDeepSleepMode_c); PWR_AllowDeviceToSleep(); #endif #else /* UI */ LED_StopFlashingAllLeds(); Led1On(); #endif } break;‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍ In “gConnEvtDisconnected_c” add the following code to change to DSM3, since all stacks are idle. case gConnEvtDisconnected_c: { /* Unsubscribe client */ mPeerDeviceId = gInvalidDeviceId_c; (void)Bas_Unsubscribe(&basServiceConfig, peerDeviceId); (void)OtapCS_Unsubscribe(); /* UI */ LED_StopFlashingAllLeds(); Led1Flashing(); Led2Flashing(); Led3Flashing(); Led4Flashing();‍‍‍‍‍‍‍‍‍‍‍‍ OtapClient_HandleDisconnectionEvent (peerDeviceId); #if (cPWR_UsePowerDownMode) /* Go to sleep */ #if MULTICORE_APPLICATION_CORE #if gErpcLowPowerApiServiceIncluded_c PWR_ChangeBlackBoxDeepSleepMode(cPWR_DeepSleepMode); #endif #else PWR_ChangeDeepSleepMode(cPWR_DeepSleepMode); #endif #else /* Restart advertising*/ BleApp_Start(); #endif } break;‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍   Power Consumption Profile of OTAP Client This section explains the behavior of the power consumption profile along the time. We can differ when DSM1 or DSM3 are used depending on the device state. If the device needs to advertise or is in connection state, it will use DSM1 because this sleep mode can predict when the device needs to handle the communication with others and wake up automatically through the BLE Link Layer wakeup interrupt. On the other hand, when no actions are in progress, it will use DSM3 and the wake up depends entirely on the LLWU SW3 button in this example. On the other hand, the DSM6 puts the MCU in STOP mode during the transmission and reception in BLE events, it does not need to be started manually, instead, the controller configures this mode automatically and returns to DSM1 mode after finished the radio activity.   The APIs that change the deep sleep mode to DSM1 are: • BleApp_Start: It starts advertising. • BleApp_ConnectionCallback – gConnEvtConnected_d: It notifies when the MCU has been connected to a peer device.   The APIs that change the deep sleep mode to DSM3 are: • BleApp_Config: It takes part of the initialization procedure after POR. All tasks are idle, the device is waiting for the LLWU SW3 button to wake up and start advertising. • BleApp_AdvertisingCallback – mAdvState is off: The device has to stopped advertising, so the MCU is idle. • BleApp_ConnectionCallback – gConnEvtDisconnected_d: It notifies when the device has been disconnected, so the MCU is idle.   Please let us know any questions or comments regarding this topic.
View full article