Wireless Connectivity Knowledge Base

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

Wireless Connectivity Knowledge Base

Discussions

Sort by:
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
简介: 当 OTAP 客户端(接收软件更新的设备,通常为 Bluetooth LE 外围设备)从 OTAP 服务器 (发送软件更新的设备,通常为 Bluetooth LE Central)请求软件更新时,您可能希望保留一 些数据,例如绑定信息,系统振荡器的匹配值或您的应用程序的 FlexNVM 非易失数据。 本 文档指导您在执行 OTAP 更新时, 如何保留您感兴趣的闪存数据内容。 本文档适用于熟悉 OTAP 定制 Bluetooth LE 服务的开发人员,有关更多基础信息,您可以阅读以下文章: 使用 OTAP 客户端软件对 KW36 设备进行重新编程。 OTAP 标头和子元素 OTAP 协议为软件更新实现了一种格式,该格式由标题和定义数量的子元素组成。 OTAP 标 头描述了有关软件更新的一般信息,并且其定义的格式如下图所示。 有关标题字段的更多 信息,请转至 SDK 中的<SDK_2.2.X_FRDM-KW36_Download_Path> \ docs \ wireless \ Bluetooth 中的《 Bluetooth Low Energy Application Developer's Guide》文档的 11.4.1 Bluetooth Low Energy OTAP 标头一章。   每个子元素都包含用于特定目的的信息。 您可以为您的应用程序实现专有字段(有关子元 素字段的更多信息, 请转至 SDK 中的<SDK_2.2.X_FRDM-KW36_Download_Path> \ docs \ wireless \ Bluetooth 中的《 Bluetooth Low Energy Application Developer's Guide》文档的 11.4.1 Bluetooth Low Energy OTAP 标头一章。 OTAP 包含以下子元素: 镜像文件子元素 值字段长度(字节) 描述 升级镜像 变化 该子元素包含实际的二进制可执行镜像,该镜像将被复制到 OTAP 客户端设备的闪存中。 该子元素的最 大大小取决于目标硬件。 扇区位图 32 该子元素包含目标设备闪存的扇区位图,该位图告诉引导加载程序哪些扇区应被覆盖,哪些扇区保持完 整。 该字段的格式是每个字节的最低有效位在前,最低有效字节和位代表闪存的最低存储部分。 镜像文件CRC 2 是在镜像文件的所有元素(此字段本身除外)上计算的 16 位 CRC。 该元素必须是通过空中发送的镜像文件中的最后一个子元素。   OTAP 扇区位图子元素 KW36 闪存分为: 一个 256 KB 程序闪存( P-Flash)阵列, 最小单元为 2 KB 扇区,闪存地址范围为 0x0000_0000 至 0x0003_FFFF。 一个 256 KB FlexNVM 阵列, 最小单元为 2 KB 扇区,闪存地址范围为 0x1000_0000 至 0x1003_FFFF, 同时它也会被映射到地址范围为 0x0004_0000 至 0x0007_FFFF 的空间。 位图子元素的长度为 256 位,就 KW36 闪存而言,每个位代表 2KB 扇区,覆盖从 0x0- 0x0007_FFFF 的地址范围(P-Flash 到 FlexNVM 映射地址范围),其中 1 表示该扇区应 被擦 除, 0 表示应保留该扇区。 OTAP 引导加载程序使用位图字段来获取在使用软件更新对 KW36 进行编程之前应擦除的地址范围,因此必须在发送软件更新之前对其进行配置,以使包含您 的数据的内存的地址范围保持不变。仅擦除将被软件更新覆盖的地址范围。 例如:假设开发人员想要保留 0x7D800-0x7FFFF 之间的地址范围和 0x0-0x1FFF 之间的地址 范围,并且必须擦除剩余的存储器。 0x7D800-0x7FFFF 之间的地址范围对应于前 5 个闪存 扇区, 0x0-0x1FFF 之间的地址范围是最低的 4 个扇区。 因此,这意味着应将 256 和 252 之间的位(256、 255、 254、 253 和 252)以及 4 和 1 之间 的位(4、 3、 2 和 1)设置为 0,这样本示例的 OTAP 位图为 : 0x07FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 使用 NXP 测试工具配置 OTAP 位图以保护地址范围 在恩智浦网站上下载并安装用于连接产品的测试工具   在 PC 上打开 NXP Test Tool 12 软件。 转到“ OTA 更新-> OTAP 蓝牙 LE”,然后单击“浏 览...”按钮加载用于软件更新的映像文件(NXP 测试工具仅接受.bin 和.srec 文件)。 您 可以配置 OTAP 位图,选择“覆盖扇区位图”复选框,并通过新的位图值更改默认值。 配 置位图后,选择“保存...”。   然后,将显示一个窗口,用于选择保存.bleota 文件的目的地,保存文件可以自行取名。 您可以将此文件与 Android 和 iOS 的 IoT Toolbox App 一起使用,以使用 OTAP 更新软 件。 这个新的.bleota 文件包含位图,该位图告诉 OTAP 引导加载程序哪些扇区将被擦 除,哪些扇区将被保留。    
View full article
The homologation requirements in China (MIIT [2002]353) obviously are planned (end of December 2022) to be sharpened (MIIT publication from 2021-01-27: “Notice on Matters Related to Radio Management in the 2400MHz, 5100MHz and 5800MHz Bands”).   A modification register is need on the KW38 and KW36 to pass the new Chinese  requirement with acceptable margin: PA_RAMP_SEL value must be set to 0x02h (2us) instead of 0x01h (1us default value) Modification SW: XCVR_TX_DIG_PA_CTRL_PA_RAMP_SEL(2) in the nxp_xcvr_common_config.c All the details are in the attached file.   Note: This SW modification is for China country only.
View full article
In the process of practical application, customers often need the combination of ble + NFC. At present, our IOT-DK006 is the only development board with NFC module. But the NFC example is not perfect. So we porting the library of NFC reader- PN7150, to support KW series microcomputer so that KW series can handle the demand of ble + NFC function. Now I will introduce you how to port the NFC lib to KW. 1 PN7150 Introduction PN7150 is the high-performance version of PN7120, the plug’n play NFC solution for easy integration into any OS environment, reducing Bill of Material (BOM) size and cost. PN71xx controllers are ideal for home-automation applications such as gateways and work seamlessly with NFC connected tags. 2 Tools hardware:FRDM-KW36,PN7150 , some wire software:mcuxpresso11.3 package:NXP-NCI MCUXpresso example Project This package contains the nfc library and example that we need. We will refer the ‘NXPNCI-K64F_example’ firstly. Sdk version: 2.2.8, Example: frdmkw36_rtos_examples_freertos_i2c  3 Steps Hardware part:We need connect the PN7150 to KW36 like the picture. Although we can connect the PN7150 to board through the ardunio connector, the pin’s voltage is not enough to drive the PN7150. So we need a wire connected to U1 to get 3.3V.   PN7150 FRDM-KW36 VBAT/PVDD 3.3V VANT 5V GND GND IRQ PTA16 VEN PTC15 SCL PTB0,I2C0 SDA PTB1,I2C0 Software part:We should add the nfc library and directory into our project. You can check the following picture to know what file is necessary. If you want to know how to add directory into our project, you can refer this link. The red line shows what file we need. Please notice that when we add file path into the mcuxpresso configuration, we also need add the path into ‘Path and Symbols’ .   We need add some macro into ‘Preprocessor’.   We copy the NXPNCI-K64F_example’s main file content into our ‘freertos_i2c.c’. Next, we need modify the file pin_mux.c, tml.c and board.h   In file board.h,add the following macro. Don't forget to enable the pin clock. /* NXPNCI NFC related declaration */ #define BOARD_NXPNCI_I2C_INSTANCE I2C0 #define BOARD_NXPNCI_I2C_BAUDRATE (100000) #define BOARD_NXPNCI_I2C_ADDR       (0x28) #define BOARD_NXPNCI_IRQ_PORTIRQn PORTA_IRQn #define BOARD_NXPNCI_IRQ_GPIO     (GPIOA) #define BOARD_NXPNCI_IRQ_PORT     (PORTA) #define BOARD_NXPNCI_IRQ_PIN      (16U) #define BOARD_NXPNCI_VEN_GPIO     (GPIOC) #define BOARD_NXPNCI_VEN_PORT     (PORTC) #define NXPNCI_VEN_PIN            (5U)     In file pin_mux.c, add head file ‘board.h’. Add the following code in function ’ BOARD_InitPins’. The step is to configure the VEN, IRQ and I2C0. This example contains the I2C1’s code, you can comment them.     /* Initialize NXPNCI GPIO pins below */   /* IRQ and VEN PIN_MUX Configuration */   PORT_SetPinMux(BOARD_NXPNCI_IRQ_PORT, BOARD_NXPNCI_IRQ_PIN, kPORT_MuxAsGpio);   PORT_SetPinMux(BOARD_NXPNCI_VEN_PORT, NXPNCI_VEN_PIN, kPORT_MuxAsGpio);   /* IRQ interrupt Configuration */   NVIC_SetPriority(BOARD_NXPNCI_IRQ_PORTIRQn, 6);   EnableIRQ(BOARD_NXPNCI_IRQ_PORTIRQn);   PORT_SetPinInterruptConfig(BOARD_NXPNCI_IRQ_PORT, BOARD_NXPNCI_IRQ_PIN, kPORT_InterruptRisingEdge);   Finally, in file tml.c, modify PORTC_IRQHandler as PORTA_IRQHandler We finished all steps. 4 Results We use ntag to test the reading and writing operation.   When the tag is closed to the PN7150, we will get the following message.   The text recording is ‘VER=03’. Next, we will modify the text recording We need add the new macro to preprocessor.   We can modify the variable NDEF_MESSAGE in function task_nfc_reader to modify the text recording.   Then we download the program again. We will see the original text ‘VER=03’ and the text has been modified. Then we read the tag again. We will see the new text.   If we want to send the larger text, what should we do? We need modify the macro ‘ADD’. When only 4 characters are sent, ‘ADD’ is 0. And every additional character is added, the ‘ADD’ will add. We modify the tag as ‘Ver=03’, and we have two more characters. So ‘ADD’ needs to be defined as 2   It firstly shows the text ‘Test’. Then it will show the new text ‘Ver=03’. Other tags’ reading and writing operation can be enabled by defining some macro.      
View full article
1 Introduction Two development boards transmit control information through ble. One development board connects to paj7620 and provides gesture information through IIC bus. The other development board uses ble and USB HID. Ble is used to receive data, and USB HID is used to simulate keyboard input and control ppt                  Figure  1 2 Preparation We need two development boards qn908x and gesture control device paj7620. We use IAR as development enviroment.The example we use is temperature_sensor, and temperature_ colloctor. The SDK version is 2.2.3   3 Code 3.1  temperature_sensor code We want to implement IIC to read gesture information from paj7620 and send data. The pins used by IIC are PA6 and PA7 Simply encapsulate the IIC reading and writing code in the code to create i2c_ operation.c and i2c_ operation.h. Realize IIC initialization and reading / writing register function in it                        Figure  2                        Figure  3   3.1.1 After having these functions, we begin to write gesture recognition code. First, we add two blank files paj7620.c and paj7620.h into our project.   Select bank register area                               Figure 4   Wake up paj7620 to read device state                    Figure 5   Initialize device                    Figure 6   Gesture test function                                   Figure 7   3.1.2 When you are ready to read the device information, You should initialize IIC and paj7620 in BleApp_Init function                                Figure 8 In principle, we need to create a custom service for the PAJ device, but we replace the temperature data as our gesture control data. If you want to create a custom service, refer to this link custom profile   3.1.3 Create a timer that sends gesture data regularly. In file temerature_sensor.c Define a timer,static tmrTimerID_t dataTimerId; Allocate a timer, dataTimerId = TMR_AllocateTimer(); Define the callback function of this timer                                           Figure 9 Start timer                                    Figure 10 Close the low power mode. #define cPWR_UsePowerDownMode 0 3.2 temperature_collector code The most important thing here is to port USB HID into our project. The USB  example we use is the USB keyboard and mouse. 3.2.1 Add the OSA and USB folder under the example to the project directory, and copy the file to the corresponding folder according to the file structure of the original example.                      Figure 11 3.2.2 Add header file directory after completion                                           Figure 12 At the same time, in this tab, add two macro definitions USB_STACK_FREERTOS_HEAP_SIZE=16384 USB_STACK_FREERTOS   3.2.3 Next, we need to modify the main function in usb example . Open composite.c file.                      Figure 13 It calls the APP_task. So this function also need to be modified.                                   Figure 14 3.2.4Find hid_mouse.c,Comment function USB_DeviceHidMouseAction Find hid_keyboard.h. Define the gesture information.                                  Figure 15 Find hid_keyboard.c. We need to modify the function USB_DeviceHidKeyboardAction as following figure.                                                  Figure 16   Among them, we also need to implement the following function. When the up hand gesture is detected, the previous ppt will be played. The down hand gesture will be the next PPT, the left hand gesture will exit PPT, and the forward hand gesture will play ppt                                                  Figure 17 It also refers to an external variable gesture_from_server. The variable definition is in file temperature_ collocation.c,.     3.2.5 After that, let's go to BleApp_Statemachinehandler function in temperature_colloctor.c. In case mApppRunning_c, we will call usb_main to initialize USB HID                                                  Figure 18 3.2.6 In BleApp_PrintTemperature, we will save the gesture data to gesture_from_server                                                         Figure 19 We finished the all steps.        
View full article
Introduction   This post explains how to create a BLE GATT database using FSCI commands sent to the BLE Server device. Additionally, this document explains how to set up the fields of each FSCI command used to create the BLE GATT database for the BLE Server.   Main FSCI commands to create the BLE GATT DB in the BLE Server device   The following, are the main commands to create, write and read the GATT DB from the BLE Server perspective. The purpose of this post is to serve as a reference and summary of the most important commands. The full list of commands FSCI commands can be found in the Framework Serial Connectivity Interface (FSCI) for Bluetooth Low Energy Host Stack documentation within your SDK package. GATT-InitRequest This command is used to initialize the GATT database at runtime, and it must be sent before any other command to declare a database in your BLE Server device. GATTServer-RegisterCallback.Request This command installs an application callback for the GATT Server module, enabling the device to respond to the FSCI request from the CPU application through an FSCI indication. GATTDBDynamic-AddPrimaryServiceDeclaration.Request It adds a primary service to the database. It has 3 parameters that should be configured, the desired handle, the UUID type (16 bits, 32 bits, 128 bits), and the UUID value. Usually, the desired handle should be set to zero and the stack will assign the handle of the primary service automatically.   If the GATT application callback was installed through the GATTServer-RegisterCallback.Request command, the GATT Server responds to the GATTDBDynamic-AddPrimaryServiceDeclaration.Request command with a GATTDBDynamic-AddPrimaryServiceDeclaration.Indication that contains the handle assigned to the primary service. The following example shows how to prepare this command to define the battery service in the database. GATTDBDynamic-AddCharacteristicDeclarationAndValue.Request It adds a characteristic and its value to the database. It has 7 parameters that should be configured, the UUID type (16 bits, 32 bits, 128 bits), the UUID value, characteristic properties, the maximum length of the value (only for variable-length values), the initial length of the value, the initial value of the characteristic and value access permissions. The characteristic declared using this command, belongs to the last primary service declared in the database. For values with a fixed length, the maximum length parameter should be set to 0, and the length is obtained from the initial length of the value parameter.   If the GATT application callback was installed, the response of this command is indicated by the GATTDBDynamic-AddCharacteristicDeclarationAndValue.Indication command. The following example shows how to prepare this command to define the battery level characteristic in the database with a fixed length of 1 byte and an initial value of 90%. GATTDBDynamic-AddCharacteristicDescriptor.Request It adds a characteristic descriptor to the database. It has 5 parameters that should be configured, the UUID type (16 bits, 32 bits, 128 bits), UUID value, length of the descriptor value, descriptor’s value, and descriptor access permissions. The descriptor declared using this command, belongs to the last characteristic declared in the database.   If the GATT application callback was installed, the response of this command is indicated by the GATTDBDynamic-AddCharacteristicDescriptor.Indication command. The following example shows how to prepare this command to add the characteristic presentation format descriptor of the battery level characteristic in the database.   GATTDBDynamic-AddCccd.Request It adds a CCDD into the database. This command does not have parameters. The CCCD declared using this command, belongs to the last characteristic declared in the database. The response of this command is indicated by GATTDBDynamic-AddCccd.Indication.   GATTDB-FindServiceHandle.Request This command is used to find the handle of a service previously declared in the database. It has 3 parameters that should be configured, the handle to start the search (should be 1 on the first call), the UUID type of the service to find (16 bits, 32 bits, 128 bits), and the UUID value of the service that you are searching.   If the GATT application callback was installed, the response of this command is indicated by the GATTDB-FindServiceHandle.Indication command, which contains the handle of the found service. The following example shows how to prepare this command to find the handle of the battery service declared in the previous examples. Notice that the result of the search corresponds to the handle returned by the GATTDBDynamic-AddPrimaryServiceDeclaration.Indication as expected.   GATTDB-FindCharValueHandleInService It finds the characteristic´s handle of a given service previously declared in the database. It has 3 parameters that should be configured, the handle of the service that contains the characteristic, the UUID type of the characteristic to find (16 bits, 32 bits, 128 bits), and the UUID value of the characteristic that you are searching for.   If the GATT application callback was installed, the response of this command is indicated by the GATTDB-FindCharValueHandleInService.Indication command, which contains the handle of the found characteristic’s value. The following example shows how to prepare this command to find the handle of the battery level value. Notice that the result of the search corresponds to the handle returned by the GATTDBDynamic-AddCharacteristicDeclarationAndValue.Indication plus one, because the AddCharacteristicDeclarationAndValueIndication command returns the handle of the characteristic and, on the other hand, FindCharValueHandleInService returns the handle of the characteristic’s value. GATTDB-FindDescriptorHandleForcharValueHandle.Request It finds the descriptor´s handle of a given characteristic previously declared in the database. It has 3 parameters that should be configured, the handle of the characteristic’s value that contains the descriptor, the UUID type of the descriptor to find (16 bits, 32 bits, 128 bits), and the UUID value of the descriptor that you are searching.   If the GATT application callback was installed, the response of this command is indicated by the GATTDB-FindDescriptorHandleForCharValueHandle.Indication command, which contains the handle of the found descriptor. The following example shows how to prepare this command to find the handle of the characteristic presentation format descriptor. The result corresponds to the handle returned by the GATTDBDynamic-AddCharacteristicDescriptor.Indication   GATTDB-FindCccdHandleForCharValueHandle.Request It finds the CCCD’s handle of a given characteristic previously declared in the database. It has only one parameter, the handle of the characteristic’s value that contains the CCCD.   If the GATT application callback was installed, the response of this command is indicated by the GATTDB-FindCccdHandleForCharValueHandle.Indication command, which contains the handle of the found CCCD. The following example shows how to prepare this command to find the handle of CCCD. The result corresponds to the handle returned by the GATTDBDynamic-AddCccd.Indication.   GATTDB-WriteAttribute.Request It writes the value of a given attribute from the application level. It has 3 parameters that should be configured, the handle of the attribute that you want to write, the length of the value in bytes, and the new value.   In the following example, we will modify the battery level characteristic’s value from 90% to 80%.   GATTDB-ReadAttribute.Request   It reads the value of a given attribute from the application level. It has 2 parameters that should be configured, the handle of the attribute that you want to read, and the maximum bytes that you want to read. The GATT application callback must be installed, since the response of this command indicated by the GATTDB-ReadAttribute.Indication command contains the value read from the database. In the following example, we will read the battery level characteristic’s value, the result is 80%.      
View full article
Introduction The goal of this example is to demonstrate automatic role switching between Central and Peripheral of BLE QN9080 SIP and indicate the proximity of another BLE module using RSSI value. The automatic Role Switching feature can be used for continuously scan the presence of other BLE device and also to advertise so that other BLE device can scan it. The use case is to maintain social distancing and trigger a warning if the two devices are closer than a threshold distance. RSSI stands for Received Signal Strength Indicator which shows the power of received radio signal. Bare metal ‘Wireless_UART’ example is used from ‘SDK_2.x_QN908xCDK’ version 2.2.2 Timer Configuration As the device needs to switch its role after every particular time interval, so a timer is required to be initialized as it can be seen in below screenshot. Next step is to allocate Timer ID to the declared variable and start the timer. In this case, the timer shall go to callback function after the time(seconds) defined by the macro 'gSwitchTime'. This is done in 'BleApp_Config' function. After the specified time interval, timer stops and enters the callback function where switching of roles takes place. The main point that needs to be highlighted here is that while going into scanning mode, advertising mode should be stopped and vice versa. In advertising, the LED will be turned off. In scanning, the LED glows based on the RSSI. Central Configuration While in Central mode, device scans the presence of other bluetooth devices. Here, we need to check the RSSI value of received signals from those devices. There is a register available in QN9080 where the RSSI can be read after a received signal. RSSI is always negative, so the register stores the 2's compliment of the actual value. Below formula can be used to get the actual value of RSSI:- Actual RSSI = NOT(RSSI) + 1; This formula will give the positive value which is inversely proportional to Signal strength. In the callback function of scanning 'BleApp_ScanningCallback', filtering is applied and following decisions are taken based on filtered value:- Red LED will glow if the filtered value is lesser than a threshold value. Green LED will glow if the filtered value is greater than a threshold value. Hysteresis of 6 counts is taken to nullify the effect of fluctuation. As there is no need to make connections with the available devices, so the function requesting to make connection with the scanned device will be deleted. Peripheral Configuration Advertising interval can be changed as per requirement by making changes in the following macros:- To advertise at a fixed interval, value of minimum and maximum interval should be same. Test Setup Flash the code in two BLE EVK's. Power ON the EVK's. Red LED blinks if the EVK's are closer than a certain distance. Green LED blinks if the distance between the EVK's is greater than a threshold value. During blinking, When the LED is off, it means that the EVK is in advertising mode and when LED is ON(Red/Green), it means that EVK is in scanning mode. Note:- RSSI varies with environment, surrounding etc., so the threshold value of distance may vary with variation in testing condition. Demo code is attached for out of the box testing.
View full article
Thread is a secure, wireless, simplified IPv6-based mesh networking protocol developed by industry leading technology companies, including Freescale, for connecting devices to each other, to the internet and to the cloud. Before starting a Thread Network implementation, users should be familiar with some concepts and how they are related to Thread protocol. IPv6 Addressing Devices in the Thread stack support IPv6 addressing IPv6 addresses are 128-bit identifiers (IPv4 is only 32-bit) for interfaces and sets of interfaces.  Thread supports the following types of addresses: Unicast:  An identifier for a single interface.  A packet sent to a unicast address is delivered to the interface identified by that address. Multicast: An identifier for a set of interfaces (typically belonging to different nodes).  A packet sent to a multicast address is delivered to all interfaces identified by that address. NOTES There are no broadcast addresses in IPv6, their function being superseded by multicast addresses. Each device joining the Thread Network is also assigned a 16-bit short address as specified in IEEE 802.15.4. 6LoWPAN All Thread devices use 6LoWPAN 6LoWPAN stands for “IPv6 over Low Power Wireless Personal Networks”. 6LoWPAN is a set of standards defined by the Internet Engineering Task Force (IETF), which enables the efficient use of IPv6 over low-power, low-rate wireless networks on simple embedded devices through an adaptation layer and the optimization of related protocols. Its main goal is to send/receive IPv6 packets over 802.15.4 links. Next figure compares IP and 6LoWPAN protocol stacks: The following concepts would explain the transport layer. ICMP Thread devices support the ICMPv6 (Internet Control Message Protocol version 6) protocol and ICMPv6 error messages, as well as the echo request and echo reply messages. The Internet Control Message Protocol (ICMP) is an error reporting and diagnostic utility and is considered a required part of any IP implementation. ICMPs are used by routers, intermediary devices, or hosts to communicate updates or error information to other routers, intermediary devices, or hosts. For instance, ICMPv6 is used by IPv6 nodes to report errors encountered in processing packets, and to perform other internet-layer functions, such as diagnostics. ICMP differs from transport protocols such as TCP and UDP in that it is not typically used to exchange data between systems, nor is it regularly employed by end-user network applications.  The ICMPv6 messages have the following general format: The type field indicates the type of the message.  Its value determines the format of the remaining data. The code field depends on the message type.  It is used to create an additional level of message granularity. The checksum field is used to detect data corruption in the ICMPv6 message and parts of the IPv6 header. ICMPv6 messages are grouped into two classes: error messages and informational messages.  Error messages are identified as such by a zero in the high-order bit of their message Type field values.  Thus,   error messages have message types from 0 to 127; informational messages have message types from 128 to 255. UDP The Thread stack supports UDP for messaging between devices. This User Datagram Protocol  (UDP)  is defined  to  make available  a datagram   mode of  packet-switched   computer communication  in  the environment  of an  interconnected  set  of  computer  networks, assuming that the Internet  Protocol (IP) is used as the underlying protocol. With UDP, applications can send data messages to other hosts on an IP network without prior communications to set up special transmission channels or data paths. UDP is suitable for purposes where error checking and correction is either not necessary or is performed in the application, avoiding the overhead of such processing at the network interface level. The UDP format is as follows: Source Port is an optional field, when meaningful, it indicates the port of the sending  process,  and may be assumed  to be the port  to which a reply should be addressed  in the absence of any other information.  If not used, a value of zero is inserted. Destination Port has a meaning within the context of a particular internet destination address. Length is the length in octets of this user datagram including this header and the data.   (This means the minimum value of the length is eight.) Checksum is the 16-bit one's complement of the one's complement sum of a pseudo header of information from the IP header, the UDP header, and the data, padded  with zero octets at the end (if  necessary)  to  make  a multiple of two octets. References White papers available at http://threadgroup.org/ “6LoWPAN: The Wireless Embedded Internet” by Zach Shelby and Carsten Bromann RFC 4291, RFC 4944, RFC 4443 and RFC 768 from https://www.ietf.org
View full article
Many applications make use of 32 kHz clocks to keep tracking of real-time or to have a low power time reference for the system. Most of the systems might use a 32.768 kHz XTAL for this purpose. However, there might be some exceptions in which the application requires compensate the frequency of this clock due to temperature changes, aging, or just because the clock provides from a source which frequency is close to the ideal 32.768 kHz, but it presents some variations. QN908x devices require a 32 kHz clock source for some applications like running the BLE stack in low power. 32.768 kHz XTALs are more accurate so they are used to generate a 32 kHz source by compensating for the ppm difference. This provides us with tools to compensate for any external 32 kHz source by first obtaining the ppm difference from the ideal frequency. The solution consists in determining how off is the external clock input frequency from the ideal 32 kHz by making a comparison with a trusted clock in the system, typically the 32 MHz / 16 MHz XTAL. This process is executed in the background in an interrupt-based system so the application can initialize or run other processes in the meantime. Then, the results of the ppm calculation are reported to the main application to compensate for the changes and provide for a more accurate clock source. This example makes use of the following peripherals in the QN908x RTC Seconds Timer CTIMER DMA The RTC Seconds Timer uses the 32 kHz clock source as a reference. It contains an internal 32000 cycles counter that increases each 32 kHz clock period. On overflow, it rises the SEC_INT flag to indicate that one second has elapsed. The CTIMER makes use of the APB clock which derives from the 32 MHz / 16 MHz clock. This timer is used in free-running mode with a Prescaler value of 1 to count the number of APB pulses. The algorithm consists of counting the amount of APB pulses (trusted clock reference) elapsed by the time the RTC SEC_INT flag is set. Ideally, if both clocks are in the right frequency, the number of APB pulses must be equal to the reference clock frequency. For example, if the APB clock is 16 MHz, by the time the SEC_INT flag sets, the CTIMER counter must have a value of 16 x 10 6 counts. Assuming our reference clock is ideal, the difference between the CTIMER counter value and 16 x 10 6 can be used to obtain the ppm difference given the following formula. Where f 0 is the ideal APB frequency (16 MHz) and f 1 is the real measured frequency (CTIMER counter value). Since the pulses counted using the CTIMER correspond to the time it took to the RTC Seconds Timer to count one second, we can extrapolate the obtained ppm value as a difference in the 32 kHz clock source from the ideal 32 kHz. To prevent from any application or task servicing latency, the algorithm makes use of the DMA to automatically capture the CTIMER Counter value when the SEC_INT flag is set. The program flow is described in the diagram below. As a way of demonstrating this algorithm, two APIs were implemented to calculate the ppm value and apply the compensation to the system. Both APIs are included in the file fsl_osc_32k_cal .c and .h files. OSC_32K_CAL_GetPpm (osc_32k_cal_callback_t pCallbackFnc): Initializes the required timers and DMA and starts with the CTIMER capture. A callback is passed so it can be executed once the ppm calculation sequence completes. OSC_32_CAL_ApplyPpm (int32_t ppmMeasurement): Uses the previously calculated ppm passed as an input parameter to compensate the RTC and the BLE timer used during sleep mode. OSC_32K_CAL_GetPpm is called every time the ppm value of the 32 kHz source clock needs to be calculated. It takes around one second to complete (depending on how off the 32 kHz source clock is from the ideal frequency) and the application cannot enter into low power state during this time. The registered callback function is executed once the calculation is complete. The ppm calculation is performed into the DMA callback. It consists of obtaining the CTIMER counter difference and use it as f 1 in the formula shown before. The ppm values are calculated using floating point unit. /* Calculate PPMs */ ppmResult = (float)((float)1-((float)ApbClockFreq/(float)ApbCountDiff)); ppmResult *= (float)1048576;‍‍‍‍‍‍ Then OSC_32_CAL_ApplyPpm must be called using the ppm value obtained after calling OSC_32K_CAL_GetPpm. This API programs the necessary values in the RTCàCAL register and the BLE Sleep timer registers to compensate for the differences in the 32 kHz source clock. Finally, the user must account for all those other APIs that make use of the 32 kHz clock frequency and update the values accordingly. For the particular case of the NXP BLE Stack, there are two APIs that need to be updated to return the clock frequency after the calibration has been applied. uint32_t PWRLib_LPTMR_GetInputFrequency(void) { uint32_t result = 32000; int32_t ppm = 0; if ( RTC->CTRL & RTC_CTRL_CAL_EN_MASK) /* is calibration enabled ? */ { /* Get the current calibration value */ if (RTC->CAL & RTC_CAL_DIR_MASK) { /* Backward calibration */ ppm -= (int32_t) (RTC->CAL & RTC_CAL_PPM_MASK); } else { /* Forward calibration */ ppm += (int32_t) (RTC->CAL & RTC_CAL_PPM_MASK); } /* Obtain the uncalibrated clock frequency using the formula * fUncal = 32000 - (ppm*0.03125) where 0.03125 is the number * of Hz per PPM digit obtained from (768 Hz/0x6000 PPM) */ result -= (float) ppm * (float) 0.03125; } else { #if (defined(BOARD_XTAL1_CLK_HZ) && (BOARD_XTAL1_CLK_HZ == CLK_XTAL_32KHZ)) result = CLOCK_GetFreq(kCLOCK_32KClk); /* 32,768Khz crystal is used */ #else result = CLOCK_GetFreq(kCLOCK_32KClk); /* 32,000Khz internal RCO is used */ #endif } return result; }‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍ uint32_t StackTimer_GetInputFrequency(void) { uint32_t prescaller = 0; uint32_t refClk = 0; uint32_t result = 0; #if FSL_FEATURE_SOC_FTM_COUNT refClk = BOARD_GetFtmClock(gStackTimerInstance_c); prescaller = mFtmConfig.prescale; result = refClk / (1 << prescaller); #elif FSL_FEATURE_RTC_HAS_FRC int32_t ppm = 0; (void)prescaller; /* unused variables */ (void)refClk; /* suppress warnings */ result = 32000; if ( RTC->CTRL & RTC_CTRL_CAL_EN_MASK) /* is calibration enabled ? */ { /* Get the current calibration value */ if (RTC->CAL & RTC_CAL_DIR_MASK) { /* Backward calibration */ ppm -= (int32_t) (RTC->CAL & RTC_CAL_PPM_MASK); } else { /* Forward calibration */ ppm += (int32_t) (RTC->CAL & RTC_CAL_PPM_MASK); } /* Obtain the uncalibrated clock frequency using the formula * fUncal = 32000 - (ppm*0.03125) where 0.03125 is the number * of Hz per PPM digit obtained from (768 Hz/0x6000 PPM) */ result -= (float) ppm * (float) 0.03125; } else { #if (defined(BOARD_XTAL1_CLK_HZ) && (BOARD_XTAL1_CLK_HZ == CLK_XTAL_32KHZ)) result = CLOCK_GetFreq(kCLOCK_32KClk); /* 32,768Khz crystal is used */ #else result = CLOCK_GetFreq(kCLOCK_32KClk); /* 32,000Khz internal RCO is used */ #endif } #elif FSL_FEATURE_SOC_CTIMER_COUNT refClk = BOARD_GetCtimerClock(mCtimerBase[gStackTimerInstance_c]); prescaller = mCtimerConfig[gStackTimerInstance_c].prescale; result = refClk / (prescaller + 1); #else refClk = BOARD_GetTpmClock(gStackTimerInstance_c); prescaller = mTpmConfig.prescale; result = refClk / (1 << prescaller); #endif return result; }‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
View full article
Our customer is evaluating RF characteristics using FRDM-MKW24. Regarding Tx max power, they have one question. The spec of max tx power is +8dBm and I could verify the power using TWR-KW24d512 before. They observed tx power with tx un-modulated cnt transmission and informed that the power was about +2dBm. That is to say, "Power 31" in Connectivity_Test means to +2dBm. I feel that it is small... Would you comment regarding the spec of the max tx power on FRDM-MKW24? Regards, Koichi
View full article
The connectivity software is an add-on of the Kinetis SDK, therefore the demos are referenced to a KSDK path variable named "KSDK_PATH" in IAR. The KSDK_PATH variable contains the path of the installation folder for the KSDK version in your PC. Taking as an example the MRB-KW01 SMAC Connectivity Software, we can realize that this variable is used to reference for libraries. In particular, this SMAC software for the MRB-KW01 works with KSDK 1.2, that is why you could have troubles if the variable is referenced to another KSDK version (for example KSDK 1.1). Follow the next steps to modify the KSDK_PATH variable in your computer: 1. Right click on "computer", then click "properties" 2. A Control Panel window will be opened. Click on "Advanced system settings" 3. A system Properties windows will be opened. Select the "Advanced" tab, then click "Environment Variables". 4. Select the KSDK_PATH variable and assure that it stores the correct path needed for your project. In case that you need to modify the variable, then click "Edit" 5. Finally click "Ok" to close all tabs and you will be able to run your connectivity software without problems. Best regards, Luis Burgos.
View full article
Our customer, who is considering MKW40, is asking NXP regarding max input voltage of PSWITCH and DCDC_CFG pins. Especially they plan to use buck mode with input voltage 4.2[v] as shown below. Would you comment if max voltage of PSWITCH and DCDC_CFG pins is 4.2[v] as well as DCDC_IN pin? Regards, Koichi
View full article
Introduction This document describes the steps needed to enable System View tool emphasizing in connectivity software stack for the QN9080CDK MCU.   Software Requirements QN908XCDK SDK 2.2.0 SystemView Software J-Link Software and Documentation Pack     Hardware Requirements QN9080CDK Board with J-Link debug interface   Enabling SystemView in IAR Embedded Workbench IDE   1. Unzip your QN908XCDK SDK. Open your desired project from:<SDK_install_path>/boards/qn908xcdk/wireless_examples/<Choose_your_project>/freertos/iar/<Your_project.eww>   2. Select the project in the workspace, press the right mouse button and select “Add->Add Group...” option       3. Create a new group called “SEGGER”, click on the “OK” button. Repeat the step 1 and create other groups called “Config” and “FreeRTOS_SEGGER”.     The workspace will be updated as shown below       4. Create folders called “SEGGER”, “Config” and “FreeRTOS_SEGGER” in the Windows directory at the following path:     <QN9080_SDK_root>/boards/qn908xcdk/wireless_examples/bluetooth/<your_example>/freertos       5. Add the following files in the recently created folders (SEGGER, Config and FreeRTOS_SEGGER) on Windows directory (the default SysView installation path is C:\Program Files (x86)\SEGGER\SystemView_V252c):   For the SEGGER folder:        All files located at <SysView_installation_path>\Src\SEGGER   For the Config folder:       All files located at <SysView_installation_path>\Src\Config   For the FreeRTOS_SEGGER folder:       <SysView_installation_path>\Src\Sample\FreeRTOSV9\SEGGER_SYSVIEW_FreeRTOS.c       <SysView_installation_path>\Src\Sample\FreeRTOSV9\SEGGER_SYSVIEW_FreeRTOS.h       <SysView_installation_path>\Src\Sample\FreeRTOSV9\Config\SEGGER_SYSVIEW_Config_FreeRTOS.c     6. Go to the workspace and click the right mouse button on “SEGGER”, “Config” and “FreeRTOS_SEGGER” groups, then select “Add->Add Files...” option. Add the following files:   For the SEGGER group:         All files in <QN9080_SDK_root>/boards/qn908xcdk/wireless_examples/bluetooth/<your_example>/freertos/SEGGER folder    For the Config group:        All files in <QN9080_SDK_root>/boards/qn908xcdk/wireless_examples/bluetooth/<your_example>/freertos/Config folder   For the FreeRTOS_SEGGER group:        All files in <QN9080_SDK_root>/boards/qn908xcdk/wireless_examples/bluetooth/<your_example>/freertos/FreeRTOS_SEGGER folder   The workspace will be updated as shown in the picture below       7. Select the project in the workspace and press Alt + F7. Go to “C/C++ Compiler” window and select “Preprocessor”. Include in “Additional include directories” view the following paths:   $PROJ_DIR$ /../Config $PROJ_DIR$ /../FreeRTOS_SEGGER $PROJ_DIR$ /../SEGGER       8. Go to “Assembler”, click on “Preprocessor”. Include the last paths on “Additional include directories” view as shown below. Click the OK button.     9. Replace the following files in the workspace with the files attached in this post (IAR files.zip). Make sure that each new file is located on the same path as the respectively last one.   freertos/FreeRTOS.h freertos/task.h freertos/tasks.c freertos/portable/portasm.s freertos/portable/port.c freertos/portable/portmacro.h   10. Add #include "SEGGER_SYSVIEW_FreeRTOS.h" at the end of the FreeRTOSConfig.h file located at source/FreeRTOSConfig.h in the workspace.       11. Search the “SEGGER_SYSVIEW_Config_FreeRTOS.c” file at FreeRTOS_SEGGER folder in the workspace. Modify the SYSVIEW_RAM_BASE value to the lowest RAM address (default 0x20000000 in QN9080) and add an extern declaration to the SystemCoreClock variable: extern uint32_t SystemCoreClock;‍‍       12. Search the “fsl_os_abstraction_free_rtos.c” file at framework/OSAbstraction folder in the workspace. Add #include "SEGGER_SYSVIEW.h" at the top of the file. Search the main function and add the following call to function inside:   SEGGER_SYSVIEW_Conf(); SEGGER_SYSVIEW_Start();‍‍‍‍‍‍‍‍‍‍        13. Build and run your example. Run SystemView in your PC.     Enabling SystemView in MCUXpresso IDE 1. Install your QN908XCDK SDK in MCUXpresso IDE and import any freertos example from "wireless_examples" folder.  2. Select the project in the workspace, press the right mouse button and select "New->Source Folder" option     3. Create a new folder called “SEGGER”, click on the “Finish” button. Repeat the step 1 and create other folders called “Config” and “FreeRTOS_SEGGER”.     The workspace will be updated as shown below     4. Add the following files in the SEGGER, Config and FreeRTOS_SEGGER folders on the workspace dragging and dropping (the default SysView installation path is C:\Program Files (x86)\SEGGER\SystemView_V252c):   For the SEGGER folder:        All files located at <SysView_installation_path>\Src\SEGGER   For the Config folder:       All files located at <SysView_installation_path>\Src\Config   For the FreeRTOS_SEGGER folder:       <SysView_installation_path>\Src\Sample\FreeRTOSV9\SEGGER_SYSVIEW_FreeRTOS.c       <SysView_installation_path>\Src\Sample\FreeRTOSV9\SEGGER_SYSVIEW_FreeRTOS.h       <SysView_installation_path>\Src\Sample\FreeRTOSV9\Config\SEGGER_SYSVIEW_Config_FreeRTOS.c   When dragging and dropping, a new window will appear. Select "Copy files" in the button group and click "OK".       5. Select the project in the workspace, then go to "Project->Properties". The project properties window will be deployed.       6. Go to "C/C++ Build->Settings->Tool Settings->MCU C Compiler->Includes" view. Click on the "Green plus icon" in the "Include paths" view. A new window will appear, click on "Workspace..." button.       7. Select SEGGER, Config and FreeRTOS_SEGGER folders and click "OK", then click "Apply and Close" in the Project Properties window.   .   8. Replace the following files in the workspace with the files attached in this post (MCUXpresso files.zip).   freertos/FreeRTOS.h freertos/task.h freertos/tasks.c freertos/port.c freertos/portmacro.h   9. Add #include "SEGGER_SYSVIEW_FreeRTOS.h" at the end of the FreeRTOSConfig.h file located at source/FreeRTOSConfig.h in the workspace.     10. Search the “SEGGER_SYSVIEW_Config_FreeRTOS.c” file at FreeRTOS_SEGGER folder in the workspace. Modify the SYSVIEW_RAM_BASE value to the lowest RAM address (default 0x20000000 in QN9080) and add an extern declaration to the SystemCoreClock variable: extern uint32_t SystemCoreClock;‍‍   11. Search the “fsl_os_abstraction_free_rtos.c” file at framework/OSAbstraction/Source folder in the workspace. Add #include "SEGGER_SYSVIEW.h" at the top of the file. Search the main function and add the following call to function inside: SEGGER_SYSVIEW_Conf(); SEGGER_SYSVIEW_Start();‍‍‍‍‍‍‍‍‍‍‍‍   12. Build and run your example. Run SystemView in your PC.
View full article
By default, FRDM-KW36 board includes a 32MHz XTAL (YI) as shown in Figure 1 but there are cases where a 26MHz XTAL is needed instead of 32MHz XTAL for FRDM-KW36 or a custom KW36 board.   Figure 1. 32MHz XTAL from FRDM-KW36 schematics Wireless connectivity demos from FRDM-KW36 Sofware Development Kit are configured to run with a 32MHz XTAL by default, but it's very easy to modify the software to operate with a 26MHz XTAL. Follow next steps to configure a FRDM-KW36 wireless connectivity demo to operate with a 26MHz XTAL: 1. In clock_config.h file, change BOARD_XTAL0_CLK_HZ define from 32000000U to 26000000U as shown in Figure 2.   Figure 2. BOARD_XTAL0_CLK_HZ define in clock_config.h 2. Add RF_OSC_26MHZ=1 line in preprocessor: If using IAR IDE: Right click on your project, then click options (Figure 3). Figure 3. IAR project options Go to C/C++ Compiler tab, then Preprocessor, and add RF_OSC_26MHZ=1 line in defined symbols window (Figure 4). Figure 4. IAR Preprocessor If using MCUXpresso IDE: Right click on your project, select Properties, go to Settings under C/C++ Build, then Preprocessor under MCU C Compiler (Figure 5). Figure 5. MCUXpresso Preprocessor Click on add button from Defined symbols, write RF_OSC_26MHZ=1 and click OK to finish (Figure 6). Figure 6. MCUXpresso Defined symbols To finish, re-compile your project and it will be ready to operate with a 26MHz XTAL. FRDM-KW36 SDK can be downloaded from the MCUXpresso webpage.
View full article
Introduction This document is a quick start guide to load a new software image in a KW36 device through FSCI (Freescale Serial Communication Interface) bootloader software. Also, it contains all the steps needed to install the software required in a Windows host to handle the FSCI communication protocol. Software Requirements IAR Embedded Workbench IDE or MCUXpresso IDE. FRDM-KW36 SDK. Hardware Requirements FRDM-KW36 board. Downloading the SDK When downloading the SDK, select your specific IDE or simply choose all toolchains as shown below. In the option "Add software component", ensure to select all middleware components as depicted below. Installing FSCI Host in Windows OS The host software for the Windows OS was designed to work in a Python environment. The following steps are to download and install the software needed to use FSCI in a Windows OS. Visit the Python web site and download the latest Python 2.7.x MSI installer package for Windows OS. Open the MSI installer package. When customizing the installation options, check "Add python.exe to Path" as shown below Complete the rest of the steps for the Python installation process. Unzip the FRDM-KW36 SDK. Depending on your Python environment architecture, copy the HSDK.dll from <SDK_root>\tools\wireless\host_sdk\sdk-python\lib\<x86_or_x64> to <Python_directory>\DLLs (default in C:\Python27\DLLs). Download and install Visual C++ Redistributable Packages for Microsoft Visual Studio 2013 depending on the Windows architecture (vcredist_x86.exe or vcredist_x64.exe) from the Microsoft web site. Download and install the Microsoft Visual C++ Compiler for Python 2.7 from the following web site. To run Python scripts from the Command Prompt of Windows, we must create a system variable named PYTHONPATH. Search “System” in the Windows browser. Go to Advanced system settings -> Environment Variables… -> System variables. Click on the “New…” button and create the PYTHONPATH variable with the following value: <SDK_root>\tools\wireless\host_sdk\hsdk-python\src. Programming the FSCI bootloader on FRDM-KW36 board Attach the FRDM-KW36 board to your PC. Drag and drop the “bootloader_fsci_frdmkw36.bin” from the previously unzipped SDK file, you can find this file in: <SDK_root>\tools\wireless\binaries to your board. Like a common USB device. Creating a binary image to reprogram the device   IAR Embedded Workbench Open the connectivity project that you want to program through the FSCI bootloader from your SDK. This example will make use of the heart rate sensor project, located at the following path: <SDK_root>\boards\frdmkw36\wireless_examples\bluetooth\hrs\freertos\iar\hrs_freertos.eww. Open the project options window (Alt+F7). In Linker -> Config window, edit the “Configuration file symbol definitions” add the “gUseBootloaderLink_d=1” linker flag as shown below. Go to the “Output Converter” window and ensure that the output file is in binary format (.bin), otherwise, deselect the “Override default” checkbox, expand the “Output format” combo box and select “Raw binary. Click the OK button. Rebuild the project. The binary will be saved at: <SDK_root>\boards\frdmkw36\wireless_examples\bluetooth\hrs\freertos\iar\debug   MCUXpresso IDE Import your FRDM-KW36 SDK to MCUXpresso. Drag and drop your SDK on the "installed SDK's" toolbar. (In this step, it is not necessary to unzip the package). Open any connectivity project that you want to program through the FSCI bootloader from your SDK. This example will make use of the heart rate sensor project. Go to Project -> Properties, a new window will appear. Then, open the C/C++ Build -> Settings -> Linker -> Miscellaneous. Press the icon below, a new window will be deployed. Add “--defsym=gUseBootloaderLink_d=1”. Click on “Apply and Close”. Build the project. Deploy the “Binaries” icon in the workspace. Click the right mouse button on the “.axf” file. Select “Binary Utilities -> Create binary” option. The binary file will be saved at “Debug” folder in the workspace with “.bin” extension. Reprogramming an FRDM-KW36 board using the FSCI bootloader The following steps are to test the FSCI bootloader in a Windows OS. Search "Command Prompt" in the Windows browser. Run the "fsci_bootloader.py" Python script. Type the “python.exe” path in the console (default C:\Python27\python.exe). Drag and drop the “fsci_bootloader.py” from: <SDK_root>\tools\wireless\host_sdk\hsdk-python\src\com\nxp\wireless_connectivity\test\bootloader on the command prompt screen. Search the COM Port of your FRDM-KW36 board and type in the console. You can find it typing ‘Device manager’ from windows home and then search it in Ports (COM & LPT) toolbar. As you can see in this example the port may change depending on each case. Search the binary image file (created in the last section). Drag and drop on the screen. Press “Enter” to start the firmware update trough FSCI bootloader. Automatically the KW36 device will trigger to run the new software. To see all your process running, you can download the ‘IoT Toolbox’ from the app store to your smartphone and connect your device with the board to verify the random data that the heart rate sensor example generates.
View full article
       My customer asks if QN9080 can be tested with MT887x. We co-work with Anritsu Taiwan to integrate QN9080 and MT887x to perform 1M bps, 2M bps and Frame error rate test. This document will address the QN9080 setup and MT887x connection setup. We show the 1M bps, 2M bps and frame error rate results. The Anritsu equipment is applied to MT8870, MT8872 model name.        If you would like to perform the same test environment. You may contact Anritsu to get the latest "Auto-test tool " released by Anritsu and follow their SOP document to install "Auto-test tool" into PC to perform this RF validation test. 
View full article
Hello everyone, Over The Air Programming (OTAP) NXP's custom Bluetooth LE service provides the developer a solution to upgrade the software that the MCU contains. It removes the need for cables and a physical link between the OTAP client (the device that is reprogrammed) and the OTAP server (the device that contains the software update). This post explains how to run the OTAP Client Software that comes within the FRDM-KW36 package: Reprogramming a KW36 device using the OTAP Client Software. As it is mentioned in the last post, the OTAP Client can reprogram the KW36 while it is running, with new software using Bluetooth LE. However, this implementation for most of the applications is not enough since once you have reprogrammed the new image, the KW36 can not be reprogramed a second time using this method. For these applications that require to be updated many times using Bluetooth LE during run-time, we have created the following application note, that comes with a functional example of how to implement the OTAP Client software, taking advantage of this service. You can download the software clicking on the link in blue and the documentation is in the link in green. Please visit the following link: DOCUMENTS and Application Notes for KW36 In the "DOCUMENTS" section, you can found more information of the KW36. In the "Application Note" section, you can found more software and documentation of interesting topics like this.        Best Regards.
View full article
Introduction This document describes the hardware considerations for the schematic and layout of the MKW36A512VFT4 device. This MCU is packaged into a 48-pin HVQFN - 7x7 mm, dissimilar to MKW36Z512VHT4 which comes packaged into a 48-pin LQFN - 7x7 mm (the last one takes part of FRDM-KW36).   Pin Layout  The MKW36A512VFT4 MCU is pin to pin compatible with the MKW36Z512VHT4 (FRDM-KW36) MCU, except for the DCDC pins. The following figure shows the distribution of the pins in the MKW36A512VFT4 MCU (left), compared with the MKW36Z512VHT4 (FRDM-KW36 MCU, right). Surely, this is the most important consideration for MKW36A512VFT4, since you can not simply move the FRDM-KW36 layout on your design. Minimum BOM The following figures show the minimum BOM necessary for each DCDC mode in KW36. For more information about DCDC modes and hardware guidelines, please visit: MKW4xZ/3xZ/3xA/2xZ DC-DC Power Management Bypass Mode   Buck Auto-Start Mode   Buck Manual-Start Mode     Layout Recommendations The footprint and layout are critical for RF performance, hence if the recommended design is followed exactly in the RF region of the PCB, sensitivity, output power, harmonic and spurious radiation, and range, you will succeed. For more information of layout recommendations, please visit Hardware Design Considerations for MKW35A/36A/35Z/36Z Bluetooth Low Energy Devices. The footprint recommended for the MKW36A512VFT4 is shown in the figure below. NXP prefers to use a top layer thickness of no less than 8-10 mils. The use of a correct substrate like the FR4 with a dielectric constant of 4.3 will assist you in achieving a good RF design. Other recommendations during EMC certification stages are: - Specific attention must be taken on 4 pins PTC1, 2, 3 & 4 if they are used on the application. - 4 decoupling capacitors of 3pF are mandatory on those pins and be positioned as close as possible. - Wires from those 4 pins must be underlayer. - NXP recommends putting the vias under the package in case the customer HW design rules allow it. Some recommendations for a good Vdd_RF supply layout are: - Vdd_RF1 and Vdd_RF2 lines must have the same length as possible, linked to pointA (‘Y’ connection). - 12pF decoupling capacitor from Vdd_RF wire must be connected to the Ground Antenna. The purpose is to get the path as short as possible from Vdd_RF1/Vdd_RF2 to the ground antenna. - 12pF decoupling capacitor from the Vdd_RF3 pin must be as close as possible. Return to ground must be as short as possible. So vias (2 in this below picture) must be placed near to the decoupling capacitor to get close connection to the ground layer. The recommended RF stage is shown in the following figure. The MKW36A512VFT4 has a single-ended RF output with a 2 components matching network composed of a shunt capacitor and a series inductor. Both elements transform the device impedance to 50 ohms. The value of these components may vary depending on your board layout. Avoid routing traces near or parallel to RF transmission lines or crystal signals. Maintain a continuous ground under an RF trace is critical to keep unaltered the characteristic impedance of the transmission line. Avoid routing on the ground layer that will result in disrupting the ground under RF traces. For more information about RF considerations please visit: Freescale IEEE 802.15.4 / ZigBee Package and Hardware Layout Considerations.
View full article
Introduction In some applications, is it necessary to keep updated the software running in many MCU's that take part in the system, fortunately, Over The Air Programming, it's a custom Bluetooth LE service developed to send "over the air" software updates for the KW MCU series. FRDM-KW36 SDK already provides the "otap_client" software, that can be used together with the "otap_bootloader" such as it is described in the following community post: Reprogramming a KW36 device using the OTAP Client Software to reprogram the KW36. This example can be modified to store code for another MCU and later send the software update to this device as depicted in the figure below. This post guides you on modifying the OTAP client software to support software updates for other MCU's. Preparing the OTAP client software The starting point of the following modifications is supposing that there is no need to perform over the air updates for the KW36 MCU, so the use of the "otap_bootloader" is obsolete and will be removed in this example. In other words, KW36 will be programmed only with the "otap_client" code. Open the MCUXpresso settings window (Project->Properties->"C/C++ Build->MCU settings") and configure the following fields. Save the changes. For external storage: For internal storage: Locate the "app_preinclude.h" file, and set the storage method, as follows: For external storage: #define gEepromType_d       gEepromDevice_AT45DB041E_c For internal storage: #define gEepromType_d        gEepromDevice_InternalFlash_c Locate the "main_text_section.ldt" linker script into the "linkscripts" folder, and delete it from the project.  Search in the project for "OTA_SetNewImageFlag();" and "ResetMCU();" functions in the "otap_client.c" file (source->common->otap_client->otap_client.c) and delete or comment. (For reference, there are 4 in total). Locate the following code in "OtaSupport.h" (framework->OtaSupport->Interface) and delete or comment. extern uint16_t gBootFlagsSectorBitNo;‍‍‍‍‍‍ void OTA_SetNewImageFlag(void);‍‍‍‍‍‍‍ Locate the following code in "OtaSupport.c" (framework->OtaSupport->Source) and delete or comment. extern uint32_t __BootFlags_Start__[]; #define gBootImageFlagsAddress_c ((uint32_t)__BootFlags_Start__)‍‍‍‍‍‍‍‍‍‍‍‍ #if !gEnableOTAServer_d || (gEnableOTAServer_d && gUpgradeImageOnCurrentDevice_d) /*! Variables used by the Bootloader */ #if defined(__IAR_SYSTEMS_ICC__) #pragma location = "BootloaderFlags" const bootInfo_t gBootFlags = #elif defined(__GNUC__) const bootInfo_t gBootFlags __attribute__ ((section(".BootloaderFlags"))) = #elif defined(__CC_ARM) volatile const bootInfo_t gBootFlags __attribute__ ((section(".BootloaderFlags"))) = #else #error "Compiler unknown!" #endif { {gBootFlagUnprogrammed_c}, {gBootValueForTRUE_c}, {0x00, 0x02}, {gBootFlagUnprogrammed_c}, #if defined(CPU_K32W032S1M2VPJ_cm4) && (CPU_K32W032S1M2VPJ_cm4 == 1) {PLACEHOLDER_SBKEK}, {BOOT_MAGIC_WORD} #endif }; #endif /* !gEnableOTAServer_d || (gEnableOTAServer_d && gUpgradeImageOnCurrentDevice_d) */‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍ uint16_t gBootFlagsSectorBitNo; gBootFlagsSectorBitNo = gBootImageFlagsAddress_c/(uint32_t)((uint8_t*)FSL_FEATURE_FLASH_PFLASH_BLOCK_SECTOR_SIZE);‍‍‍‍ gBootFlagsSectorBitNo = gBootImageFlagsAddress_c/(uint32_t)((uint8_t*)FSL_FEATURE_FLASH_PAGE_SIZE_BYTES);‍‍‍‍ void OTA_SetNewImageFlag(void) { #if (gEepromType_d != gEepromDevice_None_c) && (!gEnableOTAServer_d || (gEnableOTAServer_d && gUpgradeImageOnCurrentDevice_d)) /* OTA image successfully written into the non-volatile storage. Set the boot flag to trigger the Bootloader at the next CPU Reset. */ union{ uint32_t value; uint8_t aValue[FSL_FEATURE_FLASH_PFLASH_BLOCK_WRITE_UNIT_SIZE]; }bootFlag; #if defined(CPU_K32W032S1M2VPJ_cm4) && (CPU_K32W032S1M2VPJ_cm4 == 1) uint8_t defaultSBKEK[SBKEK_SIZE] = {DEFAULT_DEMO_SBKEK}; #endif uint32_t status; if( mNewImageReady ) { NV_Init(); bootFlag.value = gBootValueForTRUE_c; status = NV_FlashProgramUnaligned((uint32_t)&gBootFlags.newBootImageAvailable, sizeof(bootFlag), bootFlag.aValue); if( (status == kStatus_FLASH_Success) && FLib_MemCmpToVal(gBootFlags.internalStorageAddr, 0xFF, sizeof(gBootFlags.internalStorageAddr)) ) { bootFlag.value = gEepromParams_StartOffset_c + gBootData_ImageLength_Offset_c; status = NV_FlashProgramUnaligned((uint32_t)&gBootFlags.internalStorageAddr, sizeof(bootFlag), bootFlag.aValue); } #if defined(CPU_K32W032S1M2VPJ_cm4) && (CPU_K32W032S1M2VPJ_cm4 == 1) if( status == kStatus_FLASH_Success ) { /* Write the default SBKEK for secured OTA */ status = NV_FlashProgramUnaligned((uint32_t)&gBootFlags.sbkek, SBKEK_SIZE, defaultSBKEK); } #endif if( status == kStatus_FLASH_Success ) { mNewImageReady = FALSE; } } #endif }‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍   At this point, the FRDM-KW36 can receive and store any image for any MCU and can request a further software update from the OTAP server device.    Adding API's to reprogram the "MCU X" on OTAP client software Once the software update has been downloaded from the OTAP Server into the OTAP Client, the developer should request the software update from the OTAP Client to the "MCU X" through a serial protocol such as UART, SPI, CAN, etc. You should develop the API's and the protocol according to the requirements for your system to send the software update to the "MCU X" (as well as the bootloader for the MCU X). The handling your protocol can be integrated into the OTAP client code replacing "ResetMCU()" (The same code removed in step 4) in the code by "APISendSoftwareUpdateToMCUX()" for instance, since at this point the image was successfully sent over the air and stored in the memory of the KW36. 
View full article
Introduction The FRDM-KW36 includes an RSIM (Radio System Integration Module) module with an external 32 MHz crystal oscillator. This clock source reference is mainly intended to supply the Bluetooth LE Radio peripheral, but it can be used as the main clock source of the MCU as well. This oscillator includes a set of programmable capacitors to support crystals with different load capacitance needs. Changing the value of these capacitors can modify the frequency the oscillator provides, that way, the central frequency can be tuned to meet the wireless protocol standards. This configurable capacitance range is from C1: 5.7pF - C2: 7.1pF to C1: 22.6pF - C2: 28.2pF and it is configured through the BB_XTAL_TRIM field at the ANA_TRIM. The KW36 comes preprogrammed with a default load capacitance value. However, since there is variance in devices due to tolerances and parasite effects, the correct load capacitance should be checked by verifying that the optimal central frequency is attained.  You will need a spectrum analyzer to measure the central frequency. To find the most accurate value for the load capacitance, it is recommended to use the Connectivity Test demo application. Adjusting Frequency Example Program the KW36 Connectivity Test software on the device. This example can be found in wireless_examples -> genfsk -> conn_test folder from your SDK package. Baremetal and FreeRTOS versions are available. In case that FRDM-KW36 board is being used to perform the test, you should move the 10pF capacitor populated in C55 to C57, to direct the RF signal on the SMA connector. Connect the board to a serial terminal software. When you start the application, you will be greeted by the NXP logo screen:  Press the enter key to start the test. Then press "1" to select "Continuous tests": Finally, select "6" to start a continuous unmodulated RF test. At this point, you should be able to measure the signal in the spectrum analyzer. You can change the RF channel from 0 to 127 ("q" Ch+ and "w" Ch- keys), which represents the bandwidth from 2.360GHz to 2.487GHz, stepping of 1MHz between two consecutive channels. To demonstrate the trimming procedure, this document will make use of channel 42 (2.402GHz) which corresponds to the Bluetooth LE channel 37. In this case, with the default capacitance value, our oscillator is not exactly placed at the center of the 2.402GHz, instead, it is slightly deflected to 2.40200155 GHz, as depicted in the following figure: The capacitance can be adjusted with the "d" XtalTrim+ and "f" XtalTrim- keys. Increasing the capacitance bank means a lower frequency. In our case, we need to increase the capacitance to decrease the frequency. The nearest frequency of 2.402 GHz was 2.40199940 GHz  Once the appropriate XTAL trim value has been found, it can be programmed as default in any Bluetooth LE example, changing the mXtalTrimDefault constant located in the board.c file: static const uint8_t mXtalTrimDefault‍ = 0x36;‍‍‍
View full article