MCUXpresso Config Tools Knowledge Base

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

MCUXpresso Config Tools Knowledge Base

Labels

Discussions

Sort by:
This tutorial is how to start working with TEE
View full article
Creating Secure and Non-Secure projects The LPC55S69 MCU series contains Arm TrustZone® and Trusted Execution Environment extension from NXP. It allows users to assign cores, memories, and peripherals to the Secure or the Non-Secure World and restrict access between them. Manufacturers can use it to secure critical functionality of a device. For example, the Secure code is provided on the device by the manufacturer and could not be modified by users. However, a user can create a Non-Secure application and download it to the device. A secure code can communicate over a channel which security cannot be exposed to the Non-Secure World. This example is shown in the tutorial. This tutorial demonstrates how to create Secure and Non-Secure projects and their basic configuration using MCUXpresso IDE and Config Tools. LPCXpresso55S69 Board is used for the demonstration of functionality. Project description Two projects, a Secure and a Non-Secure, are created. Both projects are used on a single core. USART is used for sending data and it is configured as a Secure peripheral. S1 (ISP) button is used for sending data from the Secure world. S2 (WAKEUP) button is used for sending data from the Non-Secure world, which is not allowed due to a security violation. Prerequisites MCUXpresso IDE 11.3.0 LPCXpresso55S69 SDK 2.9.0 LPCXpresso55S69 Board You are familiar with the security extension used on LPC55S69. You are familiar with MCUXpresso IDE and Config Tools – Getting started with TEE. Steps 1.  Create a Secure project Create a new project, select the security type (Secure), and set memory regions in New Project Wizard. You must do it as Secure and Non-Secure projects use different parts of memories. In addition, secure memories use aliases – the 28 th bit is set to 1.  To download the firmware to the secure flash, select the Secure flash driver „LPC55xx_S.cfx“. 2. Create a Non-Secure project Create a new project and set security and memories as follows. 3. Connect the projects It is not mandatory but it makes things easier. Reference the Secure project from the Non-Secure project. It makes importing memory regions into the TEE tool easier.  The current and the linked or linking projects are preselected in the import dialog. In the  Secure project set the Non-Secure project to be preprogrammed.  Both projects are automatically downloaded to the board prior to debugging the Secure project. 4. Disable generation of  a Secure gateway library This feature is not used in this tutorial, therefore it must be turned off to compile the project. Change it in project properties (right-click the project and select Properties). 5. Route Secure pins Open Pins tool. Route S1 pin to SECGPIO. For detecting button press, peripheral SPINT is used and it must be routed to the same pin. Flexcom, which is used as USART, is routed by default in a board configuration. Do not change anything there. 6. Setup Secure peripherals Flexcomm is used for USART communication. Open Peripherals tool. Add USART component in Peripherals tool. Use the default configuration. Problems related to clocks must be resolved in the Clocks tool by enabling peripheral clock. Right-click the problem in Problems view and select Show problem. It opens the Clocks tool and highlights the problematic clock path. Add PINT component. Uncheck the checkbox „Show only components in toolchain project“  as the PINT driver is not in the project yet. Otherwise, it is not listed in the dialog. Select SECPINT peripheral. Configure it to invoke a callback function upon falling edge is detected on S1. Add the  PINT driver to the project via quick-fix in the Problems view. 7. Setup security extension in TEE tool Import memory regions from both projects in the User Memory Regions tab. As nothing is configured for the security extension, there are errors and warnings in the Security Level column. In Security Access Configuration, Miscellaneous tab enable Secure check for AHB matrix and Non-Secure access to floating point extension (CP10 access). FPU is turned on by default. Enable SAU and set Non-Secure regions. Other memory is considered Secure. Set MPC to allow only Secure transactions for Secure memory regions. It resolves errors and warnings in User Memory regions. Set SECGPIO and SECPINT peripherals as Secure. Keep Flexcomm as Non-Secure for now for demonstration purposes. Set PINT interrupt security as Non-Secure. Sending data from the Non-Secure world is also triggered by button press so its interrupt security must be set accordingly. It is the last setting of the Secure project in Config Tools, at this stage update the code. 8. Update Secure project settings After updating the code, create a  TrustZone folder. By default, new folders are excluded from the build. Right-click the folder and uncheck Exclude resource from build in the folder properties. Add the path to the folder into Include paths in project settings. 9. Add missing drivers If you use this version of tools,  add the inputmux driver in the Secure project. It is required for code generated by the Pins tool. 10. Update the Secure source code Do the following updates in source/Secure.c file. Add TEE initialization function call. As security is the first thing that should be configured,  place it SystemInitHook function. This way it is called before entering the main function. The initialization function is implemented in resource_config.h which must be included.       /*! * @brief Application-specific implementation of the SystemInitHook() * weak function. */ void SystemInitHook(void) { BOARD_InitTEE(); }       Implement SECPINT callback function. After pressing S1,  some data is sent from the Secure world via USART. For simplicity, character ‚s‘ is sent from the Secure world and character ‚n‘  is sent from the Non-Secure world.       /* * @brief Send on byte over secure channel * @param data data to be sent */ void sendSecureByte(uint8_t data) { USART_WriteByte(FLEXCOMM0_PERIPHERAL, data); } /* * @brief S1 button interrupt callback * @param pintr pin interrupt type * @param pmatch_status match status */ void secureButtonCallback(pint_pin_int_t pintr ,uint32_t pmatch_status) { sendSecureByte('s'); }       When you do the initialization in the Secure world, the MCU can continue with executing instructions from the Non-Secure world. The switching consists of setting a Non-Secure stack, a vector table, and calling a reset handler. The Non-Secure flash was previously configured to start at address 0x10000.       /* Start address of Non-secure application */ #define NON_SECURE_START 0x10000 /* typedef for non-secure callback functions */ typedef void (*funcptr_ns)(void) __attribute__((cmse_nonsecure_call)); int main(void) { /* Init board hardware. */ BOARD_InitBootPins(); BOARD_InitBootClocks(); BOARD_InitBootPeripherals(); #ifndef BOARD_INIT_DEBUG_CONSOLE_PERIPHERAL /* Init FSL debug console. */ BOARD_InitDebugConsole(); #endif PRINTF("Secure World\n"); /* Set non-secure main stack (MSP_NS) */ __TZ_set_MSP_NS(*((uint32_t *)(NON_SECURE_START))); /* Set non-secure vector table */ SCB_NS->VTOR = NON_SECURE_START; /* Get non-secure reset handler */ funcptr_ns ResetHandler_ns; ResetHandler_ns = (funcptr_ns)(*((uint32_t *)((NON_SECURE_START) + 4U))); /* Jump to normal world */ ResetHandler_ns(); /* Force the counter to be placed into memory. */ volatile static int i = 0 ; /* Enter an infinite loop, just incrementing a counter. */ while(1) { i++ ; /* 'Dummy' NOP to allow source level single stepping of tight while() loop */ __asm volatile ("nop"); } return 0 ; }       11. Route Non-Secure pins Configure the Non-Secure project properly. Route S2 pin to GPIO as input. Route  PINT for pin #64. Flexcomm is routed by default, remove this routing as it is already routed in the Secure project. 12. Setup Non-Secure peripherals Set up PINT to use callback on falling edge of the S2 button press.  Add the driver, for example, via quick fix. 13. Update the Non-Secure source code Keep the initialization of Pins and Peripherals and remove the other initialization as it was done in the Secure world. That also includes the overriding SystemInit function.       /* * @brief System initialization * * Intentionally empty. Required initialization was done in the Secure project. * */ void SystemInit(void) { } /* * @brief Application entry point. */ int main(void) { /* Init board hardware. */ BOARD_InitBootPins(); BOARD_InitBootPeripherals(); ...       Add the code for sending data from the Non-Secure world. To use the USART_WriteByte function and the imputmux driver, include fsl_usart.h.       /* * @brief S2 button interrupt callback * @param pintr pin interrupt type * @param pmatch_status match status */ void nonSecureButtonCallback(pint_pin_int_t pintr ,uint32_t pmatch_status) { USART_WriteByte((USART_Type *)FLEXCOMM0, 'n'); }       Now the projects are ready. When debug is executed for the Secure project, the Non-Secure project is also downloaded to the board. After pressing S1, 's' is sent from the Secure world. When S2 is pressed, 'n' is sent from the Non-Secure world because Flexcomm is configured as Non-Secure in the TEE tool. 14. Securing USART Open the TEE tool from the Secure project and set the Flexcomm slave as Secure. After this change, you can send data from the Secure world but an attempt to send data from the Non-Secure world results in bus fault.  
View full article
LPC55Sxx: Securing Digital IO Pins  This tutorial explains why you must secure digital IO pins and how to utilize MCUXpresso Config Tools. Risk of Secure information leakage  GPIO (General Purpose Input Output) is the most common digital peripheral in a microcontroller. GPIO of LPC MCU is very flexible and powerful.  Below you can see a simple block diagram of  GPIO (Figure 1).  GPIO can read a pin state regardless of the pin function configured. For example, if this pin is configured as UART, then the pin state can be read via a  GPIO read.[1] Figure 1 GPIO [1]  Due to the architecture of GPIO, all digital IO pins states are readable through the GPIO module from the GPIO read path. It does not depend on what function is chosen for this pin as aforementioned. As a result, there is a possibility of information leakage from a Secure resource (S).   For example, when you configure a UART as a Secure peripheral, it means that only the Secure world can access this UART.  However, in this case, the Non-Secure world can monitor the UART pin states through the GPIO read path as shown in Figure 1. Hence, the Non-Secure world can get all the Secure information from the UART.[1]  To prevent the leakage of information from the Secure world by GPIO, the Secure GPIO Mask is implemented on LPC55Sxx devices with TrustZone®.  This mask disallows the use of GPIO for a pin in both the Secure and the Non-Secure world. LPC55Sxx devices with TrustZone® implement a new NXP peripheral named Secure GPIO that can operate GPIO in the Secure world. Figure 2 Secure GPIO and Secure GPIO Mask [1]  Securing digital IO pins in MCUXpresso Config Tools  MCUXpresso Config Tools contain everything you need to create a Secure configuration. You can do a pins configuration in the Pins tool, configure peripherals in the Peripherals tool, enable clocks in the Clocks tool, and set up the Secure aspects in the Trusted Execution Environment (TEE) tool. Prerequisites  MCUXpresso IDE – v11.3.0 is used in this tutorial, LPCXpresso55S69 SDK – v2.9.0 is used in this tutorial, An application that uses TrustZone and Secure USART, LPCXpresso55S69 Development Board  Application setup  The project uses TrustZone.  FLEXCOMM0 is used as USART.  FLEXCOMM0 is configured as Secure in the TEE tool.  FLEXCOMM0 uses non-blocking transfer.  Reading digital IO state from the Non-Secure world  You can create a simple example to test that the Non-Secure world can access information from the Secure world by reading the state of a GPIO pin.  Assuming the Secure application uses FLEXCOMM0 to communicate and GPIO0.30 pin for TX signal, you can add a code to a Non-Secure application that can read the communication. To use GPIO macros from the example code, make sure the “board.h” header file of LPC55S69 board is added in the include section of the file. When you run the application, the Non-Secure world reads the state of the GPIO pin and changes the state of the blue LED accordingly. You can achieve it without any additional modification to a configuration generated by MCUXpresso Config Tools. There is no need to configure the pin to GPIO. It demonstrates that the state can be read from the Non-Secure world and communication is not Secure. Securing the pin in the TEE tool  Open MCUXpresso Config Tools for the Secure project.  In the example, pin 94 is used as TX pin of FLEXCOMM0 (See Figure 3) as shown in the picture of Pins view from the Pins tool below. The pin is shared with the GPIO0.30 signal. Figure 3 Digital IO pin configured in the Pins tool  Open the TEE tool to configure pin masking  (See Figure 4). Figure 4 Open the Pins tab in the TEE tool  When FLEXCOMM0 is Secure, the TEE tool reports a warning on the GPIO0.30 pin as there is a risk of Secure information leakage.   Change the value of the Reading GPIO state column from Allow to Deny.  To update project files with files generated from the MCUXpresso Config Tools, click the Update Code button. Initialization code generated for a trust zone configuration now masks the read of pin 94 using GPIO.  Verify that the pin cannot be read from the Non-Secure world  You can run the same example to verify that reading a state of the pin, that is routed to the FLEXCOMM0 TX signal, from the Non-Secure world always returns the same value. Running the application, you can see that the blue LED is not changing color based on the communication of the FLEXCOMM peripheral.    [1] 2020. AN12326: Secure GPIO And Usage. 1st ed. [ebook] NXP B.V. 2019, pp.3-4. Available at: <https://www.nxp.com/doc/AN12326> [Accessed 15 December 2020]. 
View full article
This tip will show you how to use MCUXpresso Config Tools V4.1 generate codes for KV5x with 50MHz external reference clock. The fec_extal in datasheet shows that the maximum frequency of Input clock frequency (external clock mode) is 48MHz. It will lead code generation failed when you configure 50MHz as the external reference clock in latest MCUXpresso Config Tools V4.1. (Code generation in case of warnings shouldn't be blocked. It will be fixed for MCUXpresso Config Tools V5.) Some customer had met this issue when using TWR-KV58F220M board, this board connect a 50MHz_OSC to EXTAL0. My colleague have prepared a hot fix for this issue (for all MKV5x MCUs). After install the attached hot_fix_MCUXpresso_Config_Tools_V4_1_data_MKV58_MCUCM-3936, customer is able to overcome it.(Notice: The ProgramData folder was hidden by default.)
View full article
The MCUXpresso Config Tools is installed without the data for MCUs and boards, and the data are download on demand via internet. So this article describes how to use MCUXpresso Config Tools with offline Computer. There are two methods: - Copy and paste the data on computer; - Connect the internet when first using. About the detail steps, please have a look at attachment . Thanks for the suggestion from Petr Hradsky . Alice Yang
View full article
A new version of the Kinetis Expert Configuration Tools has been released and is available both online (Welcome to Kinetis Expert | Kinetis Expert ) or for download as desktop tool (Software Development Kit for Kinetis MCUs|NXP ).   The set of the tools has a new member: the Clocks Tool: Simple UI for clock parameter viewing and modification Graphical view for easy navigation and visualization of settings and frequencies Generate configuration code using KSDK v2 Inspect and modify clock configuration from clock input source up to the core/peripherals Validate clock settings and calculate the resulting output clock frequencies Determines suitable clock settings for given output requirements Integrated with the Pins Tool   Main features of Pins Tool and Clocks Tool: Available as Web and Desktop application Kinetis SDK v2 support Multicore support Localized for English and Simplified Chinese Mostly Connected: On-Demand device data download Integrates with any compiler and IDE Generation of documented C code which is C++ aware   What's New Added Clocks Tool Added Support for boards, kits and templates Added Labels and Identifier support Added Log and Problems View Export downloaded data to copy or share device information data Bug fixes and improved documentation The release notes of the desktop application are attached to this article.   Clocks Tool The new member of the suite of configuration tools is the Clocks Tool.  Use the Tools menu to select and switch between the tools:   The Clocks Tool provides graphical views for configuration and navigation in the clocks of the hardware:   Templates, Kits, Boards and Processors When creating a new configuration, it offers Templates, Kits, Boards and Processors. Custom configurations can be stored as templates and then used for new configurations.   Board Specific Functions With the provided board and kit configurations, there are now pre-configured initialization functions for major blocks on the board:   Labels and Identifiers In the Pins Tool there are two new columns: Label and Identifier: The Label is a user name/string to identify or describe the pin. The Identifier is a user C/C++ identifier which is added to the generated source code to be used by the application.   Export Data To simplify downloading the device specific data for the desktop tool, the 'Export' function can be used to download and export the data. The data can be copied that way to another machine or all data for a set of devices can be loaded.     The device support for the clocks tool is staged, so initially not all SDK V2 devices are included. As of Oct 14, the the following Kinetis SDK V2 R1 devices are supported by the Clocks Tool: MK21FN1M0AVLQ12 MK21FN1M0AVMC12 MK21FN1M0AVMD12 MK21FN1M0VLQ12 MK21FN1M0VMC12 MK21FN1M0VMD12 MK21FX512AVLQ12 MK21FX512AVMC12 MK21FX512AVMD12 MK21FX512VLQ12 MK21FX512VMC12 MK21FX512VMD12 MK22FN128CAH12 MK22FN128VDC10 MK22FN128VLH10 MK22FN128VLL10 MK22FN128VMP10 MK22FN1M0AVLH12 MK22FN1M0AVLK12 MK22FN1M0AVLL12 MK22FN1M0AVLQ12 MK22FN1M0AVMC12 MK22FN1M0AVMD12 MK22FN1M0VLH12 MK22FN1M0VLK12 MK22FN1M0VLL12 MK22FN1M0VLQ12 MK22FN1M0VMC12 MK22FN1M0VMD12 MK22FN256CAH12 MK22FN256VDC12 MK22FN256VLH12 MK22FN256VLL12 MK22FN256VMP12 MK22FN512CAP12 MK22FN512VDC12 MK22FN512VLH12 MK22FN512VLL12 MK22FN512VMP12 MK22FX512AVLH12 MK22FX512AVLK12 MK22FX512AVLL12 MK22FX512AVLQ12 MK22FX512AVMC12 MK22FX512AVMD12 MK22FX512VLH12 MK22FX512VLK12 MK22FX512VLL12 MK22FX512VLQ12 MK22FX512VMC12 MK22FX512VMD12 MK24FN1M0VDC12 MK24FN1M0VLL12 MK24FN1M0VLQ12 MK26FN2M0CAC18 MK26FN2M0VLQ18 MK26FN2M0VMD18 MK26FN2M0VMI18 MK63FN1M0VLQ12 MK63FN1M0VMD12 MK64FN1M0VDC12 MK64FN1M0VLL12 MK64FN1M0VLQ12 MK64FN1M0VMD12 MK64FX512VDC12 MK64FX512VLL12 MK64FX512VLQ12 MK64FX512VMD12 MK65FN2M0CAC18 MK65FN2M0VMI18 MK65FX1M0CAC18 MK65FX1M0VMI18 MK66FN2M0VLQ18 MK66FN2M0VMD18 MK66FX1M0VLQ18 MK66FX1M0VMD18 MK80FN256CAx15 MK80FN256VDC15 MK80FN256VLL15 MK80FN256VLQ15 MK81FN256CAx15 MK81FN256VDC15 MK81FN256VLL15 MK81FN256VLQ15 MK82FN256CAx15 MK82FN256VDC15 MK82FN256VLL15 MK82FN256VLQ15 MKL13Z32VFM4 MKL13Z32VFT4 MKL13Z32VLH4 MKL13Z32VLK4 MKL13Z32VMP4 MKL13Z64VFM4 MKL13Z64VFT4 MKL13Z64VLH4 MKL13Z64VLK4 MKL13Z64VMP4 MKL17Z128VFM4 MKL17Z128VFT4 MKL17Z128VLH4 MKL17Z128VMP4 MKL17Z256VFM4 MKL17Z256VFT4 MKL17Z256VLH4 MKL17Z256VMP4 MKL17Z32VDA4 MKL17Z32VFM4 MKL17Z32VFT4 MKL17Z32VLH4 MKL17Z32VMP4 MKL17Z64VDA4 MKL17Z64VFM4 MKL17Z64VFT4 MKL17Z64VLH4 MKL17Z64VMP4 MKL27Z128VFM4 MKL27Z128VFT4 MKL27Z128VLH4 MKL27Z128VMP4 MKL27Z256VFM4 MKL27Z256VFT4 MKL27Z256VLH4 MKL27Z256VMP4 MKL27Z32VDA4 MKL27Z32VFM4 MKL27Z32VFT4 MKL27Z32VLH4 MKL27Z32VMP4 MKL27Z64VDA4 MKL27Z64VFM4 MKL27Z64VFT4 MKL27Z64VLH4 MKL27Z64VMP4 MKL33Z128VLH4 MKL33Z128VMP4 MKL33Z256VLH4 MKL33Z256VMP4 MKL33Z32VFT4 MKL33Z32VLH4 MKL33Z32VLK4 MKL33Z32VMP4 MKL33Z64VFT4 MKL33Z64VLH4 MKL33Z64VLK4 MKL33Z64VMP4 MKL43Z128VLH4 MKL43Z128VMP4 MKL43Z256VLH4 MKL43Z256VMP4 MKS22FN256VLL12 MKS22FN256VLH12 MKS22FN128VLL12 MKS22FN128VLH12   In November, the following SDK V2.0 R2 and R3 devices will be available in the Clocks Tool: MKL14Z32VFM4 MKL14Z32VFT4 MKL14Z32VLH4 MKL14Z32VLK4 MKL14Z64VFM4 MKL14Z64VFT4 MKL14Z64VLH4 MKL14Z64VLK4 MKL15Z128CAD4 MKL15Z128VFM4 MKL15Z128VFT4 MKL15Z128VLH4 MKL15Z128VLK4 MKL15Z32VFM4 MKL15Z32VFT4 MKL15Z32VLH4 MKL15Z32VLK4 MKL15Z64VFM4 MKL15Z64VFT4 MKL15Z64VLH4 MKL15Z64VLK4 MKL24Z32VFM4 MKL24Z32VFT4 MKL24Z32VLH4 MKL24Z32VLK4 MKL24Z64VFM4 MKL24Z64VFT4 MKL24Z64VLH4 MKL24Z64VLK4 MKL25Z128VFM4 MKL25Z128VFT4 MKL25Z128VLH4 MKL25Z128VLK4 MKL25Z32VFM4 MKL25Z32VFT4 MKL25Z32VLH4 MKL25Z32VLK4 MKL25Z64VFM4 MKL25Z64VFT4 MKL25Z64VLH4 MKL25Z64VLK4   MKW21D256VHA5 MKW21D512VHA5 MKW22D512VHA5 MKW24D512VHA5   In December, the SDK 2.0 R4 devices will be supported by the Clocks Tool: MKV10Z16VFM7 MKV10Z16VLC7 MKV10Z16VLF7 MKV10Z32VFM7 MKV10Z32VLC7 MKV10Z32VLF7 MKV10Z128VFM7 MKV10Z128VLC7 MKV10Z128VLF7   MKV10Z128VLH7   MKV10Z64VFM7 MKV10Z64VLC7 MKV10Z64VLF7   MKV10Z64VLH7 MKV11Z128VFM7 MKV11Z128VLC7 MKV11Z128VLF7   MKV11Z128VLH7   MKV11Z64VFM7 MKV11Z64VLC7 MKV11Z64VLF7   MKV11Z64VLH7   MKV30F128VFM10 MKV30F128VLF10 MKV30F128VLH10 MKV30F64VFM10 MKV30F64VLF10 MKV30F64VLH10 MKV46F256VLL16 MKV46F256VLH16 MKV46F128VLL16 MKV46F128VLH16 MKV44F256VLL16 MKV44F256VLH16 MKV44F128VLL16 MKV44F128VLH16 MKV44F64VLH16 MKV42F256VLL16 MKV42F256VLH16 MKV42F128VLL16 MKV42F128VLH16 MKV42F64VLH16 MKV44F128VLF16 MKV44F64VLF16 MKV42F128VLF16 MKV42F64VLF16 MKV58F1M0VMD24 MKV58F512VMD24 MKV58F1M0VLQ24 MKV58F512VLQ24 MKV58F1M0VLL24 MKV58F512VLL24 MKV56F1M0VMD24 MKV56F512VMD24 MKV56F1M0VLQ24 MKV56F512VLQ24 MKV56F1M0VLL24 MKV56F512VLL24 MKV31F128VLH10 MKV31F128VLL10 MKV31F256VLH12 MKV31F256VLL12 MKV31F512VLH12 MKV31F512VLL12   We hope you will find this new release useful.   Thanks for designing with NXP!
View full article
The following article describes how the data files of the Pins Tool can be downloaded either for offline usage or processed further, for example in an automated build system or how to use it on a machine without network connection: https://mcuoneclipse.com/2016/07/29/nxp-pins-tool-understanding-data-for-offline-usage/   I hope you find this useful, Erich
View full article
This video provides an instruction to the NXP Pins tool (see New Kinetis Expert Pins Tool V1.0 Available!). It demonstrates how to use the tool and how to configure pins with the example of the FRDM-K64F Board.   Enjoy 🙂
View full article
The following article describes how to configure code generation for the clock gates and how to perform a full initialization with the Pins Tool: https://mcuoneclipse.com/2016/07/19/nxp-pins-tool-clock-gates-and-controlling-the-bits/  
View full article
The new NXP Pins tool which has been showcased at FTF 2016 in Austin is now available as Web and Desktop application. The Kinetis Expert Pins Tool makes configuring, muxing and routing of pins very easy and fast. It provides real-time feedback of conflicts and provides an intuitive graphical interface with several views. The tool generates Kinetis SDK V2.0 compatible sources files which can be directly integrated into C/C++ applications. The Pins tool is available both as Web application (no installation needed) and as a Desktop application for Linux, Mac and Windows.     You can use the Web version from Welcome to Kinetis Expert | Kinetis Expert.   It is available for download as Desktop version from Software Development Kit for Kinetis MCUs|NXP (Windows, Mac OS X and Linux 64bit) under the 'Software' category: There are two different installer types: 'offline' is a 130 MByte download. This method is recommended for slower internet connections or for installation on multiple machines. 'online' is a small 500 KByte download, all the other installation data will be loaded from the internet during installation. Mac OS X and Linux installers are 64bit. For Windows there are both 32bit and 64bit installers available.   Documenation is availble on Software Development Kit for Kinetis MCUs|NXP in the documenation download section, as well attached to this article (Getting Started is available in Chinese): An overview and tutorial can be found here: https://mcuoneclipse.com/2016/06/08/tutorial-muxing-with-the-new-nxp-pins-tool/   We hope you find this tool useful!
View full article
This community and forum is for the growing set of Kinetis Expert System Conguration Tools. The tools are acessible online on Welcome to Kinetis Expert | Kinetis Expert and include right now the 'Build an SDK' and 'Power Estimation' tools: So if you have any questions or need any further advice and information about the Kinetis Expert System Configuration Tools, this is the community for it!
View full article
The following article has quick steps and videos how to get started with Kinetis Expert SDK and Design Studio:   https://community.freescale.com/docs/DOC-329662   Enjoy!
View full article
1.  Introduction This document describes the USB configuration component and implementation of the Audio 1.0 class application example on the MIMXRT1060-EVK board. It focuses on the MCUXpresso IDE and Config Tools. It provides an example of the Quad Timer peripheral component used as a digital-to-analog converter for processing audio data. The USB Audio class is supported in the SDK packages that are available for a wide range of MCUs. One of the last i.MX Real-Time (RT) crossover MCUs is the i.MX RT1060. It is available on the MIMXRT1060-EVK evaluation board. The SDK package already contains a demo application that demonstrates the USB Audio speaker functionality. However, a detailed guide on how to develop the application and customize the processing of audio data is not provided.  2.  Prerequisites The USB Audio application is developed in the MCUXpresso IDE 11.2.1 that is available on the http://www.nxp.com/mcuxpresso/ide website. Download and install this or newer version. The Config Tools that is used for the application design is integrated into the MCUXpresso IDE. Download the MIMXRT1060-EVK SDK support package inside the MCUXpresso IDE (see Install MCUXpresso SDKs in quick access) or separately on https://mcuxpresso.nxp.com/ pages (the SDK package must be built with the USB middleware selected).   3.  USB Audio concept The USB Audio class is supported in the USB middleware of the SDK package. The Peripherals tool from provides a USB middleware component that provides GUI for the configuration of the USB class, interfaces, and generating USB code examples. The USB Audio 1.0 speaker example, enumerated as a playback device, is available as a preset in the USB component. In this demo example, the device receives audio data and stores it in the internal buffer. The playback of audio is not a part of the generated code example, and the implementation is a part of this document. The USB Audio 1.0 speaker demo application that is described in this document consists of the following parts: Figure 1. Structure of the USB audio speaker application The USB component supports the configuration of the Audio control interface and streaming interfaces for the Audio 1.0 class (see the MCUXpresso Config Tools Project chapter for the steps of creating the project with the USB component). 3.1.     Audio control Interface The Audio control subclass provides a configuration of the USB Audio device topology by using terminals and units. The USB component supports one interrupt endpoint (control endpoint) and the audio control interface settings (the topology). See the example of the Audio speaker configuration below. Figure 2. Interface setting of the USB component The USB component supports the following terminals and units of the Audio 1.0 specification: Input Terminal Feature Unit Output Terminal All these units are used in the Audio speaker example. Input Terminal The Input Terminal (IT) is used to interface between the audio function’s ‘outside world’ and other units in the audio function. It serves as a receptacle for audio information flowing into the audio function. Its function is to represent a source of incoming audio data after this data has been properly extracted from the original audio stream into separate logical channels that are embedded in this stream (the decoding process). The logical channels are grouped into an audio channel cluster and leave the Input Terminal through a single Output Pin. The configuration of the input terminal consists of the ID (must be unique), type, number of channels, and spatial location, see below. The Input Terminal provides: Figure 3. Input terminal configuration Feature Unit The Feature Unit (FU) provides basic manipulation of multiple single-parameter on the incoming logical channels. It supports the following features: Mute, Volume, Tone Control, Graphic Equalizer, Automatic Gain Control, Delay, Bass Boost, and Loudness. The configuration of the feature unit consists of the unit ID (must be unique), source unit/terminal, and selection of features for every channel. Figure 4. Feature unit configuration  Output Terminal The Output Terminal (OT) is used to interface between the units inside the audio function and the ‘outside world’. It serves as an outlet for audio information, flowing out of the audio function. Its function is to represent a sink of outgoing audio data before this data is properly packed from the original separate logical channels into the outgoing audio stream (the encoding process). The audio channel cluster enters the Output Terminal through a single Input Pin. The configuration of the output terminal consists of the ID (must be unique), type, and source ID (unit/terminal), see below. Figure 5. Output terminal configuration 3.2.     Audio streaming interface Audio Streaming (AS) interfaces are used to interchange digital audio data streams between the Host and the audio function. Each Audio Streaming interface can have at most one isochronous data endpoint and an optional associated isochronous sync endpoint for synchronization purposes. The isochronous data endpoint is required to be the first endpoint in the AS interface. The AS interface is also used for the specification of the audio data format. The USB component Audio 1.0 class supports the Format I type of audio data only. The configuration (in the Audio speaker example) does not provide any audio class-specific interface and endpoints. See the following configuration: Figure 6. Zero bandwidth interface configuration Data output alternative interface settings provide a full configuration of audio streaming class-specific settings including the audio data format. There are additional audio class-specific settings for isochronous endpoints. Figure 7. Data output interface configuration   Figure 8. Isochronous feedback endpoint configuration   The Audio speaker example uses two endpoints: #1 – isochronous data endpoint (host output) for receiving audio data from the USB host. #2 – isochronous feedback endpoint that is used for synchronization between the USB audio device and the USB host. Audio stream interface-specific settings contain the Link to terminal setting which is linked to this audio streaming interface configuration and the audio data format configuration. The USB component supports just the Format I types. There is an additional configuration of the format – number of channels, subframe size, audio data resolution, and supported sampling frequencies.   4.  MCUXpresso Config Tools project This chapter provides a for the implementation of the USB Audio 1.0 demo project the MCUXpresso IDE 11.2.1 and using SDK 2.8.5 for the MIMXRT1060-EVK board. The newer version of the MCUXpresso IDE and SDK package for the MIMXRT1060-EVK shall be also compatible. 4.1. Board support project Open the MCUXpresso IDE. In the Quickstart Panel, select New project, in the SDK Wizard write RT1060 in the filter line, select the evkmimxrt1060 board, click the Next button. Figure 9. New EVKMIMXRT1060 project In the next window, write the project name, for example, MIMXRT1062xxxxA_     and select the USB Device Audio class on the Middleware tab (all the required components of the USB middleware are automatically selected), see below: Figure 10. USB middleware components of the new project Click the Finish button (the default libraries, compiler, linker, and memory map settings can be used). The MIMXRT1062xxxxA_USB_audio_speaker project is created in the IDE. The content is available in the Project Explorer window. 4.2.     Peripherals Open the Peripherals tool by using the Config Tools -> Peripherals. Figure 11. Selection of the Peripherals tool In the Peripherals tool, select the MIMXRT1062xxxxA_USB_audio_speaker project and create an instance of the USB 2.6.0 (or newer version) component for the USB1 peripheral in the Peripherals window, see below: Figure 12. Adding of the USB component The USB component is added to the Peripherals project (in the default functional group that is named BOARD_InitPeripherals). An empty USB component is created (there is no interface created and the USB component reports errors). The easiest way to create a functional USB configuration is by selecting from a preset. Select the Audio 1.0 – speaker (bare metal) preset. Figure 13. Selection of the Audio 1.0 speaker demo project configuration When you select the Audio 1.0 – speaker (bare metal) item, the whole configuration of the example is configured. Two interfaces are created: #0 – Audio_control #1 – Audio_streaming These interfaces contain all settings that are required for the USB Audio 1.0 speaker example. configuration of all audio units is provided in the Audio_control interface. The Device role configuration is also provided for the USB Audio demo example. See details of the provided settings in the previous chapter USB Audio concept. There is still the following error in the Problem view: Issue: USB Function Clock (USBPHY1_CLK) is inactive and USB module will not work. Level: Error Type: Validation Tool: Clocks Origin: Peripherals:BOARD_InitPeripherals Target: Clocks: BOARD_BootClockRUN Resource: USBPHY1_CLK   Figure 14. USB clock source error Right-click the error and select Show problem in BOARD_BootClockRun. Figure 15. Resolving of the USB clock source error The Clocks tool is opened, and you are navigated to the problem in the Details view. The USBPHY1 PLL clock is disabled by default (to save power). You can enable it by selecting the enabled value in the USBPHY1 clock output setting: Figure 16. Enabling of the USB clock source in the Clocks tool This setting enables the 480 MHz reference clock for USBPHY1 and the USB peripheral runs. Go back to the Peripherals tool. You can see that the error was resolved, and the code is generated. If you click the Update Code button, you can see what code is provided by the Config Tools. There are the following functions. Pins initialization functions: pin_mux.c/h – initialization of the routed pins for the peripherals (USB1, TMR3 in our use case). Clocks initialization functions: clock_config.c/h – initialization function for a configuration of the clock source, selectors, dividers, PLLs, and other system clock settings of the MCU.  A configuration of the USB1 clocks for PHY that was enabled is also provided. Peripherals initialization functions and the USB code example: peripherals.c/h  initialization functions for configured peripherals (USB1, TMR3 components). usb_device_composite.c/h contains initialized structures, initialization functions, device callback function, interrupt routine, and other USB middleware-related functions. usb_device_config.h contains USB middleware configurations (definitions) that are directly included in the USB middleware. usb_device_descriptor.c/hcontains definitions of the device descriptor, device configuration descriptor, initialized interface and endpoints configuration structures, function for device speed selection, and other USB device-related functions. usb_device_interface_0_audio_control.c/h contains the generated code example of the audio speaker. There is an application code for processing USB device requests, processing audio data, and configuration structure of the audio speaker example (buffer, runtime settings, …). When any of these generated files are customized (modified in the project), uncheck the file in the Update Code dialog. Otherwise, the changes would be lost. Figure 17. Update of the generated code in MCUXpresso IDE project The USB Audio example requires the Pins, Clocks, and Peripherals tool. Therefore, the generated code is used to replace the original code that is available in the default board support project. You can click the Cancel button and continue in the project configuration. 4.3.      DAC converter The i.MX RT1060 does not contain any DAC (Digital-to-Analog Converter). The MIMXRT1060 contains an external device that can be used to provide audio playback functionality.  This use case is already covered in the SDK Audio speaker example. You can create a simple DAC converter by using a timer of the MCU.  Select. The board provides Arduino headers that can be used for this demo purpose. The J23 header provides an output of the TMR3 – channels 0 and 1 (J23[6] and J23[5] pins). You can find this information in the Pins tool. Open the Pins tool and navigate to the Pins window. Select the BOARD_InitPins functional group (it is selected by default, and it is also included in the default initialization).To order the table lines according to the TMR peripherals, click the TMR column header. You can see that QTIMER3 (TMR3) timers #0 and #1 can be routed on Arduino header J23. When you click QTIMER3_TIMER0 and QTIMER3_TIMER1 in the TMR column, these timer outputs are routed automatically to the J23[6] and J23[5] pins on the Arduino header on the board. Figure 18. Routing of the timer pins in the Pins tool Switch to the Peripherals tool and add an instance of the Quad Timer (qtmr) component to the TMR3 peripheral. Check the checkbox of the TMR3 – the Quad Timer component is the only supported component and it is added automatically. The quad timer peripheral (TMR) supports four channels. You need two channels for each audio channel – Left and Right and the third channel for frequency. Figure 19. Quad timer component selection When the Quad Timer component is added, you can see the clock source – Bus clock 150 MHz. The USB Audio streaming contains 48 kHz. It means that the PWM must work at the multiplication of this sampling frequency. It simplifies the implementation of the DAC design. 150000000 / 48000 = 3125There are 3125 ticks of the timer per sample of audio data. To provide a better DAC output, the PWM must work on a frequency higher than 48 MHz. For example, the frequency can be 48 kHz * 5 = 240 kHz. It means that the PWM output frequency is 240 kHz and each audio sample value is set for 5 periods of the timer. However, it also means that the resolution of the timer is reduced to 3125 / 5 = 625 ticks. Finally, you have a 9-bits DAC converter that can be used for playback of audio data. The PWM output signal can be processed through a low-pass filter (R1, C1) with an output filter capacitor (C2) to remove some of the DC from the signal. Figure 20. Low-pass output filter fc=1/(2πRC) For example, use the following low pass filter: R1= 4700 Ω, C1 = 1.5 nF f c = 22575 Hz   TMR3 component configuration To provide two PWM channels, use the following configuration. First channel: Chanel ID: Left Primary timer/counter reference: Bus clock divided by 1 Counting operation: Rising edge of the primary source Timer mode initialization: PWM output PWM frequency/period: 240 kHz DMA/Interrupt mode: Polling Interrupt request: enable Compare 2 Second channel: Chanel ID: Right Primary timer/counter reference: Bus clock divided by 1 Counting operation: Rising edge of the primary source Timer mode initialization: PWM output PWM frequency/period: 240 kHz DMA/Interrupt mode: Polling Third channel for invoking the interrupt routine at sample frequency: Chanel ID: SampleFreq Primary timer/counter reference: Bus clock divided by 1 Counting operation: Rising edge of the primary source Timer mode initialization: Timer PWM frequency/period: 48 kHz DMA/Interrupt mode: Interrupt Interrupt request: enable Compare 1 Interrupt vector Enable interrupt: enabled (checked) Enable custom handle name: enabled (checked) Interrupt handler name: DAC_TMR_IRQ   Note: The interrupt of the SampleFreq channel is only used to load the compare load registers of both channels at the sampling frequency. The Digital-to-Analog conversion of both channels is synchronized and one simple interrupt routine can be used.  The Quad Timer components provide initialization but you must provide runtime functionality. Therefore, you must know the details of the PWM mode functionality (specified in the reference manual of the MCU). The PWM mode with variable frequency is driven by both compare registers. The second compare register provides a high-level period of the PWM period (duty), and the first compare register specifies the inactive part of the PWM period. The sum of these two compare registers must always be the computed resolution of the timer (625). An example of the initialization of compare registers can be found in the fsl_qtmr SDK driver, in the QTMR_SetupPwm() function.Compare registers are initialized before the counter/timer is started. The next values can be stored by using compare load registers. Thus, the loading of the compare registers is synchronized automatically by the timer itself (it is a part of the initialization setting in the fsl_qtmr driver). Therefore, the interrupt routine can be used for loading the audio data into compare load registers. The audio data is sent in the following PCM 16-bit format: one sample (4 bytes) 0 1 2 3 Left channel (low byte) Left channel (high byte) Right channel (low byte) Right channel (high byte) int16_t value (little endian format) int16_t value (little endian format)   Finally, configure the TMR3 peripheral in the following way: Figure 21. Quad timer configuration for the DAC In the Problems view, an error is reported. The error is caused by the missing fsl_qtmr SDK driver in the project (it was not added in the project wizard of the MCUXpresso IDE). Figure 22. Quad timer SDK driver error To fix the error, use the context menu of the error in the Problems view and select the Add SDK component “QTMR Driver” into the project “MIMXRT1062xxxA_USB_audio_speaker. Figure 23. Adding of the Quad timer SDK driver in the MCUXPresso project. When the option is selected, the update of the files is processed and the error disappears. The initialization of the application is done, and the generated code can be used in the project. Select the Update Code command and select update of the following files: Figure 24. Update of the generated code in MCUXpresso project All generated initialization files of Pins, Clocks, and Peripherals are stored to the project and the Develop perspective of the MCUXpresso IDE is automatically selected. You can check that all generated files are available in the project now. Note: When any of these generated files are later customized (modified in the project), the file must be unchecked in the Update Code dialog. Otherwise, the changes would be lost. 4.4.     Audio application design The USB Audio code example has been generated into the project and it works. But the playback of the audio data is not provided. Only the USB_Interface0AudioControlProcessNextAudioData() function is available in the source/usb_device_interface_0_audio_control.c source file. The received audio data is available in the internal USB_Interface0AudioControlDataBuff buffer and the index () of the newly received data is s_UsbDeviceAudioSpeaker->tdWriteNumberPlay. It is used to send data into the DAC converter.The DAC converter has not been implemented yet. There are just two PWM channels of the TMR3 that generate a zero-duty PWM output signal. Use the interrupt subroutine for the implementation of the audio playback. Copy the template of the interrupt routine from the TMR3 component in the Peripherals tool, see the Interrupt settings: Figure 25. Template of the interrupt service routine. When you click the Copy to clipboard button of the Handler template setting, you obtain the following code in the clipboard. /* TMR3_IRQn interrupt handler */ void DAC_TMR_IRQ(void) { /* Place your code here */ /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping exception return operation might vector to incorrect interrupt. */ #if defined __CORTEX_M && (__CORTEX_M == 4U) __DSB(); #endif } Place this code into the main program module source/MIMXRT1062xxxxA_USB_audio_speaker.c. It is used for the implementation of the main part of the application. The USB component contains a task call that must be placed into a loop of the main process. In this simple use case, use directly the main() function: Figure 26. USB device task function call code. /* * @brief Application entry point. */ int main(void) { /* Init board hardware. */ BOARD_InitBootPins(); BOARD_InitBootClocks(); BOARD_InitBootPeripherals(); #ifndef BOARD_INIT_DEBUG_CONSOLE_PERIPHERAL /* Init FSL debug console. */ BOARD_InitDebugConsole(); #endif /* Enter an infinite loop */ while(1) { USB_DeviceTasks(); } return 0 ; } 4.4.1.   Audio data processing The audio data can be read directly from the existing buffer. Therefore, you can update the implementation of the USB_Interface0AudioControlProcessNextAudioData() function and use parameters to pass a pointer to data and data size. See the following update of the function: #define SAMPLE_SIZE (AUDIO_FORMAT_CHANNELS * AUDIO_FORMAT_SIZE) void USB_Interface0AudioControlProcessNextAudioData(uint8_t **audioData, uint8_t *dataSize) { if ((s_UsbDeviceAudioSpeaker->audioSendTimes >= s_UsbDeviceAudioSpeaker->usbRecvTimes) && (s_UsbDeviceAudioSpeaker->startPlayHalfFull == 1)) { s_UsbDeviceAudioSpeaker->startPlayHalfFull = 0; s_UsbDeviceAudioSpeaker->speakerDetachOrNoInput = 1; } if (s_UsbDeviceAudioSpeaker->startPlayHalfFull) { /* * size of data packet that can be sent = FS_ISO_OUT_ENDP_PACKET_SIZE * pointer to data = USB_Interface0AudioControlDataBuff + s_UsbDeviceAudioSpeaker->tdWriteNumberPlay */ *audioData = &(USB_Interface0AudioControlDataBuff[s_UsbDeviceAudioSpeaker->tdWriteNumberPlay]); *dataSize = FS_ISO_OUT_ENDP_PACKET_SIZE / SAMPLE_SIZE; s_UsbDeviceAudioSpeaker->audioSendCount += FS_ISO_OUT_ENDP_PACKET_SIZE; s_UsbDeviceAudioSpeaker->audioSendTimes++; s_UsbDeviceAudioSpeaker->tdWriteNumberPlay += FS_ISO_OUT_ENDP_PACKET_SIZE; if (s_UsbDeviceAudioSpeaker->tdWriteNumberPlay >= AUDIO_SPEAKER_DATA_WHOLE_BUFFER_LENGTH * FS_ISO_OUT_ENDP_PACKET_SIZE) { s_UsbDeviceAudioSpeaker->tdWriteNumberPlay = 0; } } else { /* * size of data packet that can be sent = FS_ISO_OUT_ENDP_PACKET_SIZE * pointer to data = USB_Interface0AudioControlDataBuff */ *audioData = USB_Interface0AudioControlDataBuff; *dataSize = FS_ISO_OUT_ENDP_PACKET_SIZE / SAMPLE_SIZE; } }   The audioData pointer reference is set to point into the audio data buffer (USB_Interface0AudioControlDataBuff) that contains the audio data received from the host. The packet size is fixed. s_UsbDeviceAudioSpeaker->tdWriteNumberPlay is the index of the next data that must be converted by using DAC. Update the declaration of the function in the header file accordingly: /* * Function for procession of next audio data from the data buffer. It can be used as a callback. */ void USB_Interface0AudioControlProcessNextAudioData(uint8_t **audioData, uint8_t *dataSize); 4.4.2.   DAC interrupt routine The interrupt routine of the TMR3 peripheral provides the functionality of the DAC converter. It processes a stream of audio data packets and uses the sample values to control the duty of the output PWM signal (the first PWM channel as the left channel and the second PWM channel as the right channel). The sampling frequency is driven by the third channel of the TMR3 (the SampleFreq channel). See the implementation of the interrupt routine and related definitions: #include "usb_device_interface_0_audio_control.h" /* Size of one received packet */ #define PCM_PACKET_SIZE AUDIO_SAMPLING_RATE_KHZ /* PCM data pointer and sample index counter */ uint8_t *pcmData; uint8_t sampleIndex = PCM_PACKET_SIZE; /* Number of ticks for each PWM period */ #define PWM_PERIOD_LENGTH_IN_TICKS 625 /* size of one sample in streaming data (PCM format) */ #define SAMPLE_SIZE (USB_INTERFACE_1_AUDIO_STREAMING_SETTING_1_AUDIO_STREAM_SETTING_1_NUMBER_OF_CHANNEL * USB_INTERFACE_1_AUDIO_STREAMING_SETTING_1_AUDIO_STREAM_SETTING_1_SUBFRAME_SIZE) /* TMR3_IRQn interrupt handler */ void DAC_TMR_IRQ(void) { static uint16_t dutyValue; /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping exception return operation might vector to incorrect interrupt. */ #if defined __CORTEX_M && (__CORTEX_M == 4U) __DSB(); #endif /* Clear the Compare Flag */ TMR3_PERIPHERAL->CHANNEL[TMR3_SAMPLEFREQ_CHANNEL].CSCTRL &= ~TMR_CSCTRL_TCF1_MASK; /* audio data processing */ /* load next audio data when the whole packet has been sent */ if (sampleIndex >= PCM_PACKET_SIZE) { // load next data uint8_t dataLength; USB_Interface0AudioControlProcessNextAudioData(&pcmData, &dataLength); /* if new packet has been received */ if (dataLength == PCM_PACKET_SIZE) { sampleIndex = 0; } } /* if the buffer (packet) contain any data to be converted */ if (sampleIndex < PCM_PACKET_SIZE) { // PCM left channel data dutyValue = ((((int16_t*)pcmData)[SAMPLE_SIZE/2 * sampleIndex]) / 128) + 256; TMR3_PERIPHERAL->CHANNEL[TMR3_LEFT_CHANNEL].CMPLD2 = dutyValue; TMR3_PERIPHERAL->CHANNEL[TMR3_LEFT_CHANNEL].CMPLD1 = PWM_PERIOD_LENGTH_IN_TICKS - dutyValue; // PCM right channel data dutyValue = ((((int16_t*)pcmData)[(SAMPLE_SIZE/2 * sampleIndex) + 1]) / 128) + 256; TMR3_PERIPHERAL->CHANNEL[TMR3_RIGHT_CHANNEL].CMPLD2 = dutyValue; TMR3_PERIPHERAL->CHANNEL[TMR3_RIGHT_CHANNEL].CMPLD1 = PWM_PERIOD_LENGTH_IN_TICKS - dutyValue; /* next sample */ sampleIndex++; } }   The audio data is loaded (the pointer to audio data buffer is used) using the USB_Interface0AudioControlProcessNextAudioData() function. The whole packet of audio data is always provided (the PCM_PACKET_SIZE definition). When any audio data is available, the sample data is used to control the PWM duty of the left and right channels. The audio data is in the int16_t format, but the compare load register needs a 9-bit unsigned integer value. Therefore, these sample values are converted by the expression (see the source code above). 5.  Conclusion This tutorial provides an example of how you can use the USB component to generate a USB Audio 1.0 demo example and how you can use the generated interface to process the stream of audio data. The provided DAC example uses the interrupts and is not optimized. In a real application, use the DMA to process the audio stream data to reduce CPU usage. The volume control, mute, and suspending of the timers (when muted or zero bandwidth interface is selected) are other improvements that should be implemented in an advanced application. 6.  References USB Audio specification on https://usb.org: Universal Serial Bus Device Class Definition for Audio Devices Universal Serial Bus Device Class Definition for Audio Data Formats Universal Serial Bus Device Class Definition for Terminal Types   NXP application note and i.MX RT1060 documentation : How to Use Freescale USB Stack to Implement Audio Class Device i.MX RT1060 Processor Reference Manual MIMXRT1060/1064 Evaluation Kit Board Hardware User's Guide
View full article