i.MX RT Crossover MCUs Knowledge Base

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

i.MX RT Crossover MCUs Knowledge Base

Discussions

Sort by:
eIQ Neutron SDK is a new software package that includes the Neutron Compiler tool and eIQ Neutron libraries to run Neutron converted neural network models on devices that have an eIQ Neutron NPU like MCX N, i.MX RT700, or i.MX95 Previously the Neutron Compiler tool was part of eIQ Toolkit. However going forward, new versions of the Neutron Compiler tool will be released as part of the eIQ Neutron SDK. This change will allow for more frequent updates to provide better performance and additional operator support. The Neutron Compiler tool was previously named the Neutron Converter tool, but the name was changed in August 2026 with the release of eIQ Neutron SDK 3.2.1. The functionality is the same, just the name changed.  MCUXpresso SDK and Linux BSP use Neutron libraries as part of the eIQ examples included in those software releases. However to use the latest Neutron Compiler, an eIQ project will need to be updated to use the latest Neutron software libraries. This post walks through where to place the updated Neutron libraries and header files.    If the version of the Neutron Compiler tool that was used to convert a model does not match the Neutron libraries used by the eIQ project, then during inference you will see the following error(s) printed on the serial terminal and may get incorrect results: Microcode version mismatch Or Internal Neutron NPU driver error 281b in model prepare Or Incompatible Neutron NPU microcode and driver versions The version of the Neutron Compiler tool that was used to convert a model can be found by either viewing the converted model in Netron or by looking at the generated header file:   header.png netron.png   Here is a table showing where you can find the matching version of the Neutron Compiler tool for the default Neutron libraries found in different versions of MCUXpresso SDK: MCUXpresso SDK Default Neutron Library Version in MCUXpresso SDK Default Compatible Neutron Compiler/Converter Can Be Found In 24.12 1.2.0+0x6f710a6d eIQ Toolkit 1.17 25.03 1.2.0+0X1b86b19d eIQ Toolkit 1.17 25.06 2.0.2 eIQ Toolkit 1.17 25.09 2.1.3 eIQ Toolkit 1.17 25.12 2.2.2 eIQ Neutron SDK 2.2.2 26.03 3.0.0 eIQ Neutron SDK 3.0.0 26.06 3.1.1 eIQ Neutron SDK 3.1.1 Manually Update SDK Libraries To Use Latest Version   eIQ Neutron SDK 3.2.1   It is highly recommend to always use the latest Neutron Compiler tool and to update the libraries in your eIQ project to match the latest Neutron Compiler tool. The libraries can be updated by overwriting the original files. You may wish to make a backup first though as the default eIQ examples in that SDK will use models that were converted to match those original Neutron libraries. The Neutron file structure in eIQ Neutron SDK and MCUXpresso SDK are now the same so that the entire Neutron folder can be overwritten directly.    Updating Neutron Libraries in MCUXpresso SDK 25.12 and later: File Source Directory in eIQ Neutron SDK Target Directory in MCUXpresso SDK libNeutronDriver.a target\imxrt700\ rt700\cm33\ \middleware\eiq\neutron\rt700\cm33\ libNeutronFirmware.a target\imxrt700\ rt700\cm33\ \middleware\eiq\neutron\rt700\cm33\ NeutronDriver.h target\imxrt700\ driver\include\ \middleware\eiq\neutron\driver\include\ NeutronErrors.h target\imxrt700\ common\include\ \middleware\eiq\neutron\common\include\   Note: The target\imxrt700\driver\include\NeutronEnvConfig.h and the libraries in target\imxrt700\cmodel are used by the ExecuTorch inference engine and so are not needed for TFLM eIQ projects.  Note: In MCUXpresso SDK 26.03 there are two sets of Neutron libraries in imported projects. It's the files in the /middleware/eiq folder that need to be updated.  anthony_huereca_0-1776090421844.png     Updating Neutron Libraries in MCUXpresso SDK 25.09 or before: File Source Directory in eIQ Neutron SDK Target Directory in MCUXpresso SDK libNeutronDriver.a target\imxrt700\ rt700\cm33\ \middleware\eiq\tensorflow-lite\third_party\neutron\rt700\ libNeutronFirmware.a target\imxrt700\ rt700\cm33\ \middleware\eiq\tensorflow-lite\third_party\neutron\rt700\ NeutronDriver.h target\imxrt700\ driver\include\ \middleware\eiq\tensorflow-lite\third_party\neutron\driver\include\ NeutronErrors.h target\imxrt700\ common\include\ \middleware\eiq\tensorflow-lite\third_party\neutron\common\include\   Updating Neutron Libraries for MCUXpresso SDK 2.16 or before: Replace the entire middleware\eiq directory from MCUXpresso SDK 26.03 into your project, and then the Neutron libraries can be updated per the instructions above. In these older MCUXpresso SDK releases there were additional eIQ changes beyond just the four files above, so the easiest method to update those older projects is just to replace the entire eIQ middleware directory.        Updating Neutron Libraries for i.MX devices: To update the neutron runtime on a target device, upload the files to their designated directories, as follows:   File Target Directory NeutronFirmware.elf /lib/firmware libNeutronDriver.so /lib/ libneutron_delegate.so /lib/  
View full article
目录 一、概述 二、环境准备   2.1 虚拟环境   2.2 使用Google Colab 三、核心步骤   3.1 CIFAR10数据集   3.2 模型创建   3.3 模型训练   3.4 模型转换   3.5 推理验证   3.6 benchmark性能   3.7 完整实现   3.7 简化版本(Colab) 四、TFLite Micro部署 五、快速验证 六、应用示例 七、结论 八、参考 more details, please see the attachment. 一、概述 CIFAR-10: 多伦多大学Alex Krizhevsky CIFAR-10公开数据集,也是计算机视觉领域最经典、最常用的入门级基准数据集之一,包含10个类别的6万张32x32彩色图像(5万训练,1万测试),例如飞机、汽车、鸟、猫等。 tflm_cifar10:演示了如何在恩智浦的微控制器上使用TensorFlow Lite Micro框架,实时运行CIFAR-10图像分类模型。即将一个预先训练好的、针对CIFAR-10数据集的卷积神经网络模型部署到MCU上,让其具备了识别10类常见物体(飞机、汽车、鸟、猫等)的能力。 模型:一个轻量级CNN模型,包含3个卷积层、ReLU激活层、池化层和一个全连接层。 输入: 32x32像素的彩色图像。 输出:图像属于CIFAR-10中10个类别的概率。 本文档:提供针对CIFAR10数据集搭建的完整流程,从数据集、模型训练转换、部署推理的快速实现方案,可作为示例tflm_cifar10(推理为主)的前置补充,本文不涉及到端侧的部署与优化。  ... """ CIFAR10 快速训练、测试、部署与推理完整流程 """ import os os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2' # 减少TensorFlow日志 import tensorflow as tf import numpy as np import time import matplotlib.pyplot as plt print(f"TensorFlow版本: {tf.__version__}") print(f"NumPy版本: {np.__version__}") class CIFAR10QuickPipeline: def __init__(self): """初始化管道""" self.model = None self.tflite_model = None def load_data(self, sample_size=1000): """加载简化数据集""" print("\n1. 加载CIFAR10数据集...") (x_train, y_train), (x_test, y_test) = tf.keras.datasets.cifar10.load_data() # 预处理 x_train = x_train.astype('float32') / 255.0 x_test = x_test.astype('float32') / 255.0 # 使用少量数据(快速训练) x_train_small = x_train[:sample_size] y_train_small = y_train[:sample_size] x_test_small = x_test[:200] y_test_small = y_test[:200] # 转换为独热编码 y_train_onehot = tf.keras.utils.to_categorical(y_train_small, 10) y_test_onehot = tf.keras.utils.to_categorical(y_test_small, 10) print(f"训练数据: {x_train_small.shape}") print(f"测试数据: {x_test_small.shape}") return (x_train_small, y_train_onehot), (x_test_small, y_test_onehot) def create_simple_model(self): """创建简化CNN模型""" print("\n2. 创建简单CNN模型...") model = tf.keras.Sequential([ # 输入层 tf.keras.layers.Input(shape=(32, 32, 3)), # 卷积层1 tf.keras.layers.Conv2D(8, (3, 3), padding='same', activation='relu'), tf.keras.layers.MaxPooling2D((2, 2)), # 卷积层2 tf.keras.layers.Conv2D(16, (3, 3), padding='same', activation='relu'), tf.keras.layers.MaxPooling2D((2, 2)), # 全连接层 tf.keras.layers.Flatten(), tf.keras.layers.Dense(32, activation='relu'), tf.keras.layers.Dropout(0.2), tf.keras.layers.Dense(10, activation='softmax') ]) model.compile( optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'] ) model.summary() self.model = model return model def train_model(self, x_train, y_train, x_test, y_test, epochs=10): """训练模型""" print("\n3. 训练模型...") # 回调函数:早停 callbacks = [ tf.keras.callbacks.EarlyStopping( monitor='val_loss', patience=3, restore_best_weights=True ) ] history = self.model.fit( x_train, y_train, epochs=epochs, batch_size=32, validation_data=(x_test, y_test), callbacks=callbacks, verbose=1 ) # 评估模型 test_loss, test_acc = self.model.evaluate(x_test, y_test, verbose=0) print(f"\n测试准确率: {test_acc:.4f}") return history def convert_to_tflite(self): """转换为TFLite格式""" print("\n4. 转换为TFLite格式...") # 转换为TFLite converter = tf.lite.TFLiteConverter.from_keras_model(self.model) # 优化配置 converter.optimizations = [tf.lite.Optimize.DEFAULT] converter.target_spec.supported_types = [tf.float32] # 转换 tflite_model = converter.convert() # 保存模型 with open('cifar10_model.tflite', 'wb') as f: f.write(tflite_model) # 保存为字节数组(用于嵌入式部署) self.save_as_c_array(tflite_model) self.tflite_model = tflite_model model_size = len(tflite_model) / 1024 print(f"模型大小: {model_size:.1f} KB") return tflite_model def save_as_c_array(self, tflite_model): """保存为C数组格式""" c_array = '// 自动生成的CIFAR10模型数组\n' c_array += '#include <stdint.h>\n\n' c_array += 'const unsigned char cifar10_model_tflite[] = {\n' # 每行显示12个字节 for i in range(0, len(tflite_model), 12): line_bytes = tflite_model[i:i+12] c_array += ' ' + ', '.join(f'0x{b:02x}' for b in line_bytes) + ',\n' c_array += '};\n\n' c_array += f'const unsigned int cifar10_model_tflite_len = {len(tflite_model)};\n' with open('cifar10_model_array.h', 'w') as f: f.write(c_array) print("C数组已保存: cifar10_model_array.h") def test_tflite_inference(self, x_test, y_test, num_tests=10): """测试TFLite推理""" print(f"\n5. 测试TFLite推理 ({num_tests}个样本)...") if self.tflite_model is None: with open('cifar10_model.tflite', 'rb') as f: self.tflite_model = f.read() # 加载TFLite模型 interpreter = tf.lite.Interpreter(model_content=self.tflite_model) interpreter.allocate_tensors() input_details = interpreter.get_input_details() output_details = interpreter.get_output_details() # 类别名称 class_names = ['飞机', '汽车', '鸟', '猫', '鹿', '狗', '青蛙', '马', '船', '卡车'] correct = 0 times = [] for i in range(min(num_tests, len(x_test))): # 准备输入 input_data = x_test[i:i+1] # 推理 start_time = time.perf_counter() interpreter.set_tensor(input_details[0]['index'], input_data) interpreter.invoke() inference_time = time.perf_counter() - start_time times.append(inference_time) # 获取输出 output = interpreter.get_tensor(output_details[0]['index']) predicted_class = np.argmax(output[0]) actual_class = np.argmax(y_test[i]) # 检查是否正确 if predicted_class == actual_class: correct += 1 print(f"样本 {i+1}: 预测={class_names[predicted_class]:<5} " f"实际={class_names[actual_class]:<5} " f"时间={inference_time*1000:.1f}ms " f"{'✓' if predicted_class == actual_class else '✗'}") accuracy = correct / num_tests avg_time = np.mean(times) * 1000 print(f"\n推理统计:") print(f" 准确率: {accuracy:.1%} ({correct}/{num_tests})") print(f" 平均推理时间: {avg_time:.1f}ms") print(f" 推理速度: {1000/avg_time:.0f} FPS") return accuracy, avg_time def benchmark_performance(self, x_test): """性能基准测试""" print("\n6. 性能基准测试...") interpreter = tf.lite.Interpreter(model_content=self.tflite_model) interpreter.allocate_tensors() input_details = interpreter.get_input_details() # 预热 test_input = x_test[0:1] for _ in range(10): interpreter.set_tensor(input_details[0]['index'], test_input) interpreter.invoke() # 基准测试 num_runs = 100 start_time = time.perf_counter() for _ in range(num_runs): interpreter.invoke() total_time = time.perf_counter() - start_time avg_time = total_time / num_runs * 1000 print(f"基准测试结果:") print(f" 总推理次数: {num_runs}") print(f" 总时间: {total_time*1000:.1f}ms") print(f" 平均推理时间: {avg_time:.1f}ms") print(f" 推理速度: {1000/avg_time:.0f} FPS") return avg_time def save_model_summary(self): """保存模型摘要""" summary = [] self.model.summary(print_fn=lambda x: summary.append(x)) with open('model_summary.txt', 'w') as f: f.write('\n'.join(summary)) f.write(f"\n\n模型信息:") f.write(f"\n参数数量: {self.model.count_params():,}") f.write(f"\n保存时间: {time.ctime()}") print("模型摘要已保存: model_summary.txt") def main(): """主函数""" print("=" * 60) print("CIFAR10 快速训练、测试、部署管道") print("=" * 60) # 创建管道 pipeline = CIFAR10QuickPipeline() # 1. 加载数据 (x_train, y_train), (x_test, y_test) = pipeline.load_data(sample_size=2000) # 2. 创建模型 pipeline.create_simple_model() # 3. 训练模型 history = pipeline.train_model(x_train, y_train, x_test, y_test, epochs=15) # 4. 保存模型摘要 pipeline.save_model_summary() # 5. 转换为TFLite pipeline.convert_to_tflite() # 6. 测试推理 pipeline.test_tflite_inference(x_test, y_test, num_tests=20) # 7. 性能测试 pipeline.benchmark_performance(x_test) print("\n" + "=" * 60) print("流程完成!生成的文件:") print(" 1. cifar10_model.tflite - TFLite模型") print(" 2. cifar10_model_array.h - C数组格式") print(" 3. model_summary.txt - 模型摘要") print("=" * 60) if __name__ == "__main__": main() ... 七、结论 本文旨在以常见图像分类场景(CIFAR10)为例,让读者快速了解从数据搭建、模型创建、训练、推理和验证的完整流程,可作为示例tflm_cifar10(端推理为主)的前置补充,本文不涉及到端侧部署与优化。
View full article
1 背景 2 开发搭建    2.1 软件    2.2 硬件 3 性能优化    3.1 原始性能    3.2 优化1:编译优化    3.3 优化2:外部SDRAM    3.4 优化3:VGLite加速    3.5 优化对比 4 结论 5 参考       1 背景 LVGL (Light and Versatile Graphics Library)是一款高性能、低资源占用的轻量级嵌入式图形库,凭借其强大的开源生态与广泛的操作系统适配支持,能够覆盖从低功耗的ARM Cortex-M系列微控制器(主频可低至100MHz)到运行Linux的高性能MPU等多种硬件平台,已成为嵌入式开源方案中的首选。许多芯片厂商已为其提供“开箱即用”级支持。 恩智浦(NXP)为其主流平台(如MCX、i.MX RT和LPC系列)提供了配套的软硬件示例,并在MCUXpresso SDK中集成了LVGL示例,这些示例对各类场景进行基准指标量化。然而,在实际应用中,因软、硬件配置与规格差异,性能表现往往存在波动,需结合具体场景进行针对性优化。 本文基于i.MX RT1170相关实践案例,旨在帮助NXP用户快速理解并选用适当的优化策略,以达成LVGL应用性能提升的目标。   Sam_Gao_0-1764585268472.png   cpu-usage.png FPS.png 4    结论 本文档针对NXP官方示例LVGL的 benchmark性能进行逐步优化,如CPU Usage, FPS, Render时间,Flush时间等,并提供了各个优化方案的量化数据对比以’Widgets demo’为例,其CPU使用率由原始的97%逐步降低至17%,而FPS帧率则由原始的2帧/秒提升至59帧/秒。 另外,这些优化方法和思路并不局限在该场景应用,对于常规的系统级的性能提升亦可作为参考。
View full article
  1 Background 2 Development Setup   2.1 Software   2.2 Hardware 3 Performance Optimization   3.1 Baseline Performance   3.2 Optimization 1: Compiler Optimization   3.3 Optimization 2: External SDRAM   3.4 Optimization 3: VGLite Acceleration   3.5 Optimization Comparison 4 Conclusion 5 References 1. Background LVGL (Light and Versatile Graphics Library) is a high-performance, low-resource embedded graphics library. Thanks to its robust open-source ecosystem and broad OS compatibility, it supports a wide range of hardware platforms—from low-power ARM Cortex-M microcontrollers (with clock speeds as low as 100 MHz) to high-performance MPUs running Linux—making it a preferred choice in embedded open-source solutions. Many silicon vendors now offer “out-of-the-box” support for LVGL.   NXP provides ready-to-use software and hardware examples for its mainstream platforms—including MCX, i.MX RT, and LPC series—and integrates LVGL examples into the MCUXpresso SDK. These examples include quantified benchmark metrics for various scenarios. However, due to differences in software/hardware configurations and specifications, actual performance may vary significantly and often requires scenario-specific tuning.   This document, based on practical experience with the i.MX RT1170 platform, aims to help NXP users quickly understand and apply appropriate optimization strategies to enhance LVGL application performance. Sam_Gao_0-1764584255540.png      cpu-usage.png   FPS.png 4. Conclusion This document presents a step-by-step optimization of NXP’s official LVGL benchmark example, with quantified improvements in CPU usage, FPS, render time, and flush time. Taking the Widgets demo as an example: CPU usage dropped from 96% → 12% FPS increased from 2 → 59 These optimization techniques—not limited to LVGL—are broadly applicable to system-level performance tuning on i.MX RT platforms.
View full article
These lab guides provide step-by-step instructions on how to take a quantized TensorFlow Lite model and use the Neutron Compiler Tool found in eIQ Neutron SDK to convert the model to run on the eIQ Neutron NPU found on i.MX RT700 devices.  The eIQ Neutron NPU for i.MX RT700 Lab Guide documents focus on using the Neutron Compiler tool found inside eIQ Neutron SDK  to convert a model and then import that converted model into an eIQ MCUXpresso SDK example. There are labs for VSCode, GCC, and MCUXpresso IDE.    The labs were designed to run on the i.MX RT700 EVK, but the same concepts can be applied to MCX N boards as well and are similar to the MCX N eIQ Neutron NPU labs. You can also explore the TFLM Getting Started Guide for information on how to use your own model and data for inference.  Also be sure to check out AN14700 - i.MX RT700 eIQ Neutron NPU Enablement and Performance which goes into more details on the eIQ Neutron N3-64 NPU found on i.MX RT700.  The VS Code is copied below but is also included as an attached PDF below as well as labs for using ARM GCC and MCUXpresso IDE.  1                 Lab Overview This document will cover how to convert models using NXP’s eIQ Neutron SDK and will also highlight the performance improvements that can be achieved with the eIQ Neutron NPU. This version of the lab will use VSCode. If using command line GCC or MCUXpresso IDE see those versions of the lab. 2               Software and Hardware Installation This section will cover the hardware and software needed for this lab. 2.1 Hardware The i.MX RT700 EVK is used in this lab. 2.2 NXP Software Installation Download the latest eIQ Neutron SDK Install VSCode. Install the latest MCUXpresso for VSCode plugin. Run the MCUXpresso Installer tool and install three key components: MCUXpresso SDK Developer Arm GNU Toolchain LinkServer anthony_huereca_0-1786510346209.png   Download a quantized Mobilenet TFLite model that can be found here and rename it to mobilenet_quant.tflite on your hard drive. Install the latest LinkServer CMSIS-DAP debug firmware on your board by putting a jumper on JP20, unplugging and plugging in the micro-USB cable on J54, and running the C:\NXP\LinkServer_<version>\MCU-LINK_installer\scripts\program_CMSIS.cmd script. Then remove the jumper and do a power on reset.   3               Label Image Example This section will use the eIQ Label Image example found in the MCUXpresso SDK to showcase how the eIQ Neutron NPU can significantly decrease inference times for quantized models. 3.1 Convert Models Use eIQ Neutron SDK to convert a pre-existing Mobilenet model into a Neutron optimized model. Download a quantized Mobilenet TFLite model that can be found here and rename it to mobilenet_quant.tflite on your hard drive. Unzip the eIQ Neutron SDK package in a directory of your choosing. Optionally add <unzip_location>\eIQ_NeutronSDK_<version>\bin to your executable path so that the neutron-compiler utility can be directly called from the command line.        Then use the following command to do the conversion (all one line): neutron-compiler --dump-header-file-output --dump-header-file-input  --target imxrt700 --use-sequencer --input mobilenet_quant.tflite --output mobilenet_npu.tflite anthony_huereca_1-1786510372263.png   These options will generate a C array of both the converted model and the input model, which we’ll use to compare the performance of them. In typical situations you would only need the dump-header-file-output option though. This command also directed the convertor to use sequencer mode which can result in faster inference times with the tradeoff of a larger model. Also note that starting in eIQ Neutron SDK 3.2.1, the neutron-converter tool was renamed to neutron-compiler. 3.2 View Models After conversion, you can explore the models using a tool like Netron. Take a moment to look at the original model compared to the new converted model. The original TFLite file: mobilenet_quant.tflite anthony_huereca_2-1786510380913.png   The Neutron converted file: mobilenet_npu.tflite anthony_huereca_3-1786510387349.png   You can see how almost all the operators in the original model were replaced with a NeutronGraph operator. Those NeutronGraph operaters are what will be executed on the eIQ Neutron NPU when this model is ran on the i.MXRT700. Any layers that were not converted to a NeutronGraph operator will instead be ran on the Cortex-M33 core. Take a look at the file size of each of the .tflite files and you can see that, in general, the NPU converted file will take up less flash space. Note that this might be counter-acted by the slightly increased size required for using the eIQ Neutron libraries. During the conversion process the dump-header-file-output argument generated the .h header file for the NPU optimized model that can be used in the eIQ MCUXpresso SDK projects. The dump-header-file-input argument generated the .h header file for the original non-converted model. This will be used so the inference time of the original model that only runs on the Cortex-M33 core can be compared to the NPU converted model that makes use of the eIQ Neutron NPU. So let’s run these models to see the performance improvements.   3.3 Modify an eIQ Example to Run Models Now let’s use the MCUXpresso SDK eIQ Label Images example to run the models and see how long the inference time is. Open VSCode Go to the MCUXpresso for VSCode plugin and click on Import Repository anthony_huereca_4-1786510398165.png   Go to the Remote Archive tab. It may take a bit for the list of packages to populate. Once it does, type in for RT700 in the Package field to select the MIMXRT700-EVK. Select the latest SDK version and then select a directory to download the MCUXpresso SDK into. Agree to the license and then finally click on Import. It will take several minutes to download and extract the SDK package. This time can be reduced by unchecking the Create Git repository option if not needed. Also ensure MUCXpresso SDK 26.06 or later is used as there are several important VS Code issues fixed in that version. anthony_huereca_5-1786510404488.png     Next import an eIQ example project. In the Quickstart Panel, select Import Example from Repository anthony_huereca_6-1786510411278.png   Then on the screen that pops up, select the RT700 repository that was downloaded in the previous step. In the Template field type in label_image to search for the eiq_examples/tflm_label_image_cm33_core0 project. Then change the App type to Freestanding application. Then select a directory location to import the project into. And then select the Arm GNU Toolchain that was installed as part of the MCUXpresso Installer. Finally click on Import. anthony_huereca_7-1786510418890.png   A pop-up will come up that asks if you trust the authors of the files in this folder. Click on Yes. anthony_huereca_8-1786510425633.png   It should look like the following when done. Make sure the Project Files looks similar to the image below which should be the case if the Freestanding option was used when importing the project: anthony_huereca_9-1786510432167.png   Now we need to import the models that were generated in the last section into this project. Navigate down to the Project Files folder and inside the tflm folder right click on model.cpp and then select Reveal in File Explorer to open the location of that file on your hard drive. anthony_huereca_10-1786510437757.png   Now copy and paste the two .h header files that were generated in the previous section into this file location. It should look like the following when complete: anthony_huereca_11-1786510444462.png   Back in VSCode, hover your mouse over the Projects name and then hit the Refresh icon to get the two new header files to appear in the Project Files list. anthony_huereca_12-1786510454038.png   Note that simply having the files in the Project Files view does not mean they will automatically be included in the project. As they are header files no further changes are needed, but if C or CPP files are added to a VSCode project then other configuration files would also need to be updated. No change is needed here. This is just for informational purposes only. Now we need to slightly modify those two header files to add some information for the eIQ MCUXpresso SDK project that describe how much memory this model will require and to describe some of the normalization values that this model uses: In the pcq_npu folder open model_data.h, which contains the default model for this example. anthony_huereca_13-1786510459397.png In model_data.h and find the following section of code and copy it. Be sure to include the array declaration. anthony_huereca_14-1786510470892.png   Then in mobilenet_quant.h copy that code above the array, overwriting the default #defines above the array. Make sure not to erase the commented lines at the top of the file as those comments will be used later.          anthony_huereca_15-1786510489494.png   Do the same steps to update mobilenet_ npu.h as well After changing both files, now double click on model.cpp to open it. anthony_huereca_16-1786510501059.png   Go to line 27 and change it to point to the non-NPU accelerated model in mobilenet_quant.h. It should look like the following after changed:  anthony_huereca_17-1786510506933.png   Next look at line 55 in that same model.cpp file to find where the model is loaded by the TFLM inference engine using the C array name model_data. Because the model array name in the new header file is the same as the original header file we replaced, no change is needed here. This is just for informational purposes only. anthony_huereca_18-1786510512561.png   Likewise, the image data that will be fed into the model can be found in source image_data.h file contains an array of the binary data from the Stopwatch image found in stopwatch.bmp. No change is needed here. This is just for informational purposes only. anthony_huereca_19-1786510521373.png   3.4 Compile and Run Compile the project by hovering your mouse over the project name and then clicking on the Build Project icon.   anthony_huereca_20-1786510525894.png   Connect a USB micro B cable from your computer to the USB port on the i.MX RT700 EVK at J54. Also ensure that JP1 and JP3 are shunted on the board and that SW10 has pin 1 OFF and pin 2 ON anthony_huereca_21-1786510535725.png anthony_huereca_22-1786510540192.png   Open TeraTerm or other serial terminal program, and connect to the virtual COM port that board enumerated as when you plugged in the USB cable (your COM number will likely be different than the screenshot). Use 115200 baud, 1 stop bit, no parity. There is a built-in serial terminal in VSCode that can be used for this. Click on Start Monitoring to connect:      anthony_huereca_23-1786510547583.png   Then in VSCode hover your mouse over the project name and click on Debug anthony_huereca_24-1786510554219.png   You should see VSCode connect and download the program to your board in the Console tab.             Once complete, it will pause at the start of main(). Hit the Resume icon  to run the program and look at the Serial Monitor tab. anthony_huereca_25-1786510561242.png   When you run the project, if you look at the terminal output, it looks like there’s an error that we’ll fix in the next step: Didn't find op for builtin opcode 'CONV_2D' anthony_huereca_26-1786510567902.png   Stop the debugger by clicking on the red square in the debug panel anthony_huereca_27-1786510573274.png   This error was done on purpose in this lab, to demonstrate that when changing models, the list of operators needs to be updated as well. To fix the error, open the model_mobilenet_ops_npu.cpp file in the pcq_npu folder                 anthony_huereca_28-1786510578901.png   Inside the MODEL_GetOpsResolver function is a list of operators. If you open the mobilenet_quant.h header file you’ll also find a list of operators used by the model in the comment block at the top of the file. anthony_huereca_29-1786510584088.png   Copy that list from mobilenet_quant.h into the MODEL_GetOpsResolver function in model_mobilenet_ops_npu.cpp to replace the variable declaration and the original list. anthony_huereca_30-1786510602975.png   Recompile and reprogram the board using the previous steps. You should now see the following on the serial terminal: anthony_huereca_31-1786510608936.png   Stop the debugger by clicking on the red square anthony_huereca_32-1786510615586.png   Now we’ll run the program again, but this time with the Neutron NPU accelerated version of the model. Re-open model.cpp and this time change line 27 to point to the Neutron NPU converted version of the model in the mobilenet_ npu.h file: anthony_huereca_33-1786510622508.png   Re-open model_mobilenet_ops_npu.cpp and update the MODEL_GetOpsResolver function with the variable declaration and the operators listed in the comment block of the mobilenet_npu.h file. Note that the operators needed here may change depending on the Neutron Compiler version. anthony_huereca_34-1786510631401.png   Build and program the program as before. However there’s now another error with a “Microcode version mismatch”. The model output also has the wrong answer for the image. This is because the Neutron libraries included by default in MCUXpresso SDK 26.06 are for eIQ Neutron SDK 3.1.1 but we used a newer eIQ Neutron SDK to convert our model. anthony_huereca_35-1786510645979.png   The default library version can be confirmed by looking at the default model data in model_data.h where it shows it was converted using an older version.  anthony_huereca_36-1786510650993.png   But the model that was converted as part of this lab used a newer Neutron Compiler version anthony_huereca_37-1786510654472.png   To fix this error, the Neutron libraries used by this project need to be updated to the newer eIQ Neutron SDK version. Go to where eIQ Neutron SDK was unzipped and navigate to the eIQ_NeutronSDK_<version>\target\imxrt700 folder Then use VSCode to open the directory to copy those files by right clicking on the Repository->mcuxsdk->middleware->eiq->neutron folder and then select Reveal in File Explorer to open the location of that file on your hard drive. anthony_huereca_38-1786510668028.png   Then overwrite the files from the eIQ Neutron SDK folder into your project: File Name Source Directory in eIQ Neutron SDK Target Directory in MCUXpresso SDK libNeutronDriver.a target\imxrt700\rt700\cm33 \middleware\eiq\neutron\rt700\cm33 libNeutronFirmware.a target\imxrt700\rt700\cm33 \middleware\eiq\neutron\rt700\cm33 NeutronDriver.h target\imxrt700\driver\include\ \middleware\eiq\neutron\driver\include NeutronErrors.h target\imxrt700\common\include\ \middleware\eiq\neutron\common\include   Note: The target\imxrt700\driver\include\NeutronEnvConfig.h file and the libraries in target\imxrt700\cmodel are used by the ExecuTorch inference engine and so are not needed for this TFLM example.   After the new Neutron libraries are copied over, clean the project to ensure the new libraries will be used   Then recompile and debug the project as done before This time you should see the following on the terminal. That’s over a 100x improvement in inference time, with the same confidence percentage on this static image.     The decrease in inference time is very model dependent depending on how well that specific model could be optimized for the NPU. Due to the changes made as part of this lab inside the Repository directory, which is shared among SDK projects, other eIQ examples will also use the newer Neutron library now. This means those examples will not properly work as the default eIQ projects use a model converted with that earlier version of eIQ Neutron SDK. 4              Further Optimizations There are several items that can be further optimized for your particular model The terminal output also shows the TensorArena Size used for this model. The kTensorArenaSize variable that is set in mobilenet_npu.h can be adjusted accordingly to reduce the memory usage. This kTensorArenaSize variable is used to determine the size of the TensorArena memory buffer required by the model for scratch data during calculation. It is also estimated and printed out during the neutron-compiler output in the Total data field. However this estimate is often slightly smaller than the actual amount used, which is printed in the serial terminal during inference:         The power used while inferencing can be further reduced from the eIQ projects by turning off unnecessary clocks in active mode. See the power_comp_only SDK example. The NPU clock can also be turned off while not actively inferencing with: CLKCTL0->PSCCTL5_CLR |= (1UL << CLKCTL0_PSCCTL5_NPU0_SHIFT); The NPU module clock can be turned on right before the call to MODEL_RunInference() with: CLKCTL0->PSCCTL5_SET |= (1UL << CLKCTL0_PSCCTL5_NPU0_SHIFT); Always make sure to use the newest Neutron Compiler and libraries found in the most recently released eIQ Neutron SDK to get the latest performance improvements and model support. 5              Conclusion This lab demonstrated how the eIQ Neutron NPU can significantly decrease inference time on quantized models. These same steps can be used to benchmark other quantized models to see the performance improvements that the eIQ Neutron NPU can have.     --- Updated August 2026 for change of neutron-converter to neutron-compiler in eIQ Neutron SDK 3.2.1 release
View full article
This is a guide line to run both the master core and slave core projects as XIP targets from one flash.
View full article
Recovery Methods for RT595 and RT685 Development Boards When Programming Fails During the development and use of RT595 and RT685 development boards, developers often encounter a common issue reported by users: persistent errors during programming via a debugger, making it impossible to reprogram the board and effectively rendering it “bricked.” These issues can arise from various causes, such as incorrect FCB writing, interruptions during the download process, or other unknown anomalies. This article introduces two effective recovery methods: Using the SEC TOOL utility. Using an external J-Link programmer. Note: Both methods require setting the RT595 and RT685 boards to Serial ISP mode beforehand. NXP has released two RT685-based development boards (MIMXRT685-AUD-EVK and MIMXRT685-EVK) and one RT595 board. Since the RT595 board operates similarly to the RT685 boards, this article uses the MIMXRT685-AUD-EVK board for demonstration. Ensure the SDK version is correct during the process. mayliu1_1-1760596577697.png 1. Preparation: Entering Serial ISP Mode Using the MIMXRT685-AUD-EVK board as an example, set switches SW5[1-3] to “ON OFF OFF” to enter Serial ISP mode. This corresponds to the following pin levels: PIO1_17: High PIO1_16: High PIO1_15: Low Refer to the RT600 User Manual for detailed mappings between ISP pins and boot modes.   mayliu1_2-1760596693245.png mayliu1_3-1760596700476.png 2. Method 1: Recovery Using SEC TOOL  1. Preparation: Generate APP Image Import SDK Demo: Open MCUXpresso IDE and import the demo project mimxrt685audevk_lpc_gpio_led_output_cm33. mayliu1_4-1760596785475.png   Modify Project Settings: Make two key configuration changes to ensure successful image generation. mayliu1_5-1760596800335.png mayliu1_6-1760596804637.png Generate Hex File: After configuration, build the project to generate a Hex file for use with SEC TOOL. mayliu1_7-1760596831665.png 2. Using SEC TOOL Download SEC TOOL: https://www.nxp.com/design/design-center/software/development-software/mcuxpresso-software-and-tools-/mcuxpresso-secure-provisioning-tool:MCUXPRESSO-SECURE-PROVISIONING Create Workspace: Launch SEC TOOL and create a new workspace for MIMXRT685S. Select Connection Method: RT500 and RT600 support USB, UART, SPI, and I2C. Choose one (e.g., UART via J5 or USB via J7). Only one protocol can be used at a time. If switching, power cycle the board. mayliu1_8-1760596890883.png mayliu1_9-1760596894590.png Configure Flash Type and Test: Select the default external NOR Flash for MIMXRT685-AUD-EVK, apply settings, and run a test. mayliu1_10-1760596916554.png Build Image: Use the previously generated App image and click “Build Image.”  mayliu1_11-1760596979292.png  Program Image: Flash the image to the RT685 chip. mayliu1_12-1760596995145.png   Switch Boot Mode: Power off the board and set Boot mode to FlexSPI Boot from PortB: PIO1_17: Low PIO1_16: High PIO1_15: Low SW5[1-3]: “ON OFF ON” Power on the board again. It should now operate normally and run the program successfully. mayliu1_13-1760597057591.png 3. Method 2: Recovery Using J-Link Programmer 1. Preparation: Generate Flashable File Import the same demo project into MCUXpresso IDE and compile it without modifications to generate a Hex or S19 file. Download and install SEGGER J-Flash from SEGGER Official Website. 2. Hardware Setup Board Modifications: Connect pins 2 and 3 of JP2. Remove jumpers JP17, JP18, JP19 (ensure p3 is disconnected). Set SW5 to “ON OFF OFF”. Device Connection: Connect J-Link Plus to J19 on the board. Connect J6 to the PC to power the board. 3. Programming with J-Flash Create New Project: Open J-Flash and create a new project for MIMXRT685S. Note: RT685 supports only SWD, not JTAG. mayliu1_14-1760597088841.png mayliu1_15-1760597093145.png Flash Program: Load the Hex file and flash it to the board.   mayliu1_16-1760597109388.png Switch Boot Mode: After flashing, power off the board and set Boot mode to FlexSPI Boot from PortB: PIO1_17: Low PIO1_16: High PIO1_15: Low SW5[1-3]: “ON OFF ON” Power on the board again. It should now function normally and run the program successfully. mayliu1_0-1760597371876.png   Conclusion By following either of the two methods described above, developers can effectively recover RT595 and RT685 development boards from programming failures and restore normal operation. Choose the method that best suits your specific situation. 
View full article
4-TX Line Audio Playback via SAI1 on MIMXRT1170 and CS42448 1. Introduction This document focuses on utilizing the MIMXRT1170-EVKB development board and the CS42448 audio expansion board to achieve specific audio playback functionality through four TX data lines of the SAI1 module. With its real-time performance and high integration, the i.MX RT1170 is widely used in automotive, industrial, and IoT fields. The Arm Cortex-M7 core runs at up to 1GHz, features 2MB on-chip RAM, and offers various memory and connectivity interfaces. It supports multiple audio interfaces, including SAI-1, SAI-2, SAI-3, SAI-4, PDM, ASRC, SPDIF, and MQS. This document details the implementation of 8-channel audio output using the RT1170 EVKB development board and CS42448 Audio Card via four TX data lines of the SAI1 module. It also explains how to generate 8-channel audio data compatible with SDK example requirements. The CS42448 Audio Card can be directly connected to the RT1170 EVKB board, enabling developers to build more complex audio applications. The NXP SDK provides the example 'evkbmimxrt1170_sai_edma_multi_channel_transfer_cm7,' which by default enables two transmission channels (TX_DATA0 and TX_DATA1). When running, 1kHz sine wave audio signals can be heard from the J6 and J7 interfaces of the CS42448 Audio Card. However, when customer requirements demand four TX data lines (TX_DATA0 to TX_DATA3), each transmitting different audio, how can this be achieved? This document explores and validates this scenario in depth. 2. SAI Overview (1) RT1170 Chip SAI Module Features According to the IMXRT1170RM datasheet, SAI2, SAI3, and SAI4 modules each have only one data line for input/output, while SAI1 has four, making it the only module supporting multi-line communication. mayliu1_0-1760582567332.png mayliu1_1-1760582585178.png (2) Configuration Highlights To implement the four TX data line solution, it is crucial to configure the Transmit Configuration 3 (TCR3) TCE register correctly. According to IMXRT1170RM Table 54-2, Option0 should be selected for pin configuration. To enable TX_DATA0 to TX_DATA3, set bits 16–19 of the SAI1 TCR3 register to '1111'. Similarly, for multiple Rx data lines, configure bits 16–19 of the SAI1 RCR3 register (RCE). mayliu1_2-1760582599932.png   3. Hardware Preparation (1) Required Hardware - Mini/micro USB cable - MIMXRT1170-EVKB development board - Personal computer - Headphones (OMTP standard) - CS42448 Audio Card (2) Hardware Modifications on MIMXRT1170-EVKB Solder Resistors: R2008, R2022, R2011, R2021, R2009, R2010, R2012, R2016, R1998, R2013, R2014, R2018, R2017, R2000 Remove Resistors: R2001, R2002, R2003, R2004, R2005, R2006, R2007 After completing the hardware modifications, connect the CS42448 Audio Card to the J76 interface of the MIMXRT1170-EVKB board. 4. Audio Source Preparation The free and powerful audio editing software Audacity is used to convert MP3 files to .wav format. Since each TX data line transmits two audio channels, a total of 8 channels are needed. (1) Audio Channel Allocation Strategy Using Audacity, multiple audio channels were generated. 'HelloWorld' is mono and reused. Allocation is as follows: - TX_DATA0: HelloWorld → Channel 1 & Channel 5 - TX_DATA1: Audio1 → Left: Channel 2, Right: Channel 6 - TX_DATA2: Audio2 → Left: Channel 3, Right: Channel 7 - TX_DATA3: Audio3 → Left: Channel 4, Right: Channel 8 On the CS42448 Audio Card: - J6 plays TX_DATA0 (HelloWorld) - J7 plays  TX_DATA1(Audio1) - J8 plays TX_DATA2(Audio2) - J9 plays TX_DATA3(Audio3) mayliu1_3-1760582625483.png mayliu1_4-1760582631006.png (2) Audio Format Requirements The converted .wav files must match the format used in the NXP SDK example: 48kHz sampling rate and 16-bit width. Ensure these parameters are correctly set in Audacity during conversion. mayliu1_5-1760582657816.png mayliu1_6-1760582669900.png (3) Audio Data Processing To convert the generated HelloWorld-8-channel.wav file into a C language array using WinHex, you need to remove the first 44 bytes, which constitute the standard WAV file header. This step is crucial because the SDK example utilizes raw audio data. For those interested, examining the structure of a WAV file can provide deeper insight into this process. Alternatively, this conversion from WAV format to a C array can also be accomplished using other tools or methods. 5. Software Modifications (1) Configure SAI1 Module Registers To enable four TX data lines, set the TCE bits in the SAI1 TCR3 register. In the NXP SDK code, modify the macro DEMO_SAI_CHANNEL_MASK and configure saiConfig in I2S mode. The function SAI_TransferSendEDMA will set the TCR3 TCE register accordingly. mayliu1_7-1760582729361.png mayliu1_8-1760582741801.png mayliu1_9-1760582757500.png (2) Replace Audio Data and Modify Macros Replace the uint8_t music[] array in the SDK example’s music.h file with the C array generated earlier. Also, update the macro MUSIC_LEN to match the byte length of the new array, ensuring it is a multiple of 1600. mayliu1_10-1760582772454.png After completing all steps, compile and flash the program to the MIMXRT1170-EVKB board. Connect headphones to the CS42448 Audio Card’s J6,J7,J8,J9 interfaces to hear the respective audio outputs. mayliu1_0-1760584298169.jpeg   6. Conclusion This project successfully implements the transmission of four TX data lines via the SAI1 module using the CS42448 Audio Card and MIMXRT1170-EVKB development board. Experimental validation confirms support for multi-channel independent audio output. Each TX data line can output distinct audio content through the CS42448’s physical interfaces (J6–J9), meeting the needs of complex audio scenarios.
View full article
This article uses i.MXRT1170 as an example, but the rules apply to the i.MX RT series. 1. Backgroud and Questions DataSheets (e.g, RT1170A , RT1170B) show the 'NON JEDEC'  Package as following, but the Product quality page (e.g MIMXRT1172AVM8A) is marked as WSL 3 (Moisture Sensitivity Level 3), which is one of the moisture sensitivity levels defined in JEDEC-STD-020. Is there a contradiction? Does the product comply with JEDEC-STD-020?  Sam_Gao_0-1760344672941.png Sam_Gao_1-1760344940289.png 2. What is JEDEC-STD-020? JEDEC-STD-020 is a standard that defines the moisture sensitivity level (MSL) and preconditioning requirements for surface-mount devices (SMDs) during the reflow soldering process. Compliance with this standard means that the device's storage and handling before reflow soldering meet industry specifications, making it suitable for automated manufacturing environments. 3. WSL 3 and JEDEC-STD-020 Compliance  On NXP’s product quality page, some i.MX RT1170 variants are marked as WSL 3 (Moisture Sensitivity Level 3), which is one of the levels defined in JEDEC-STD-020. This means: The device can be exposed to ambient conditions for 168 hours before reflow soldering;  It must be stored in dry-pack packaging; It complies with JEDEC-STD-020 handling and processing requirements. This indicates that i.MX RT1170 series have been tested and qualified according to JEDEC-STD-020. Key parameters from NXP Product pages: MSL (Moisture Sensitivity Level): 3 Peak Package Body Temperature: 260°C Time at Peak: 40 seconds 4. “NON JEDEC” Packge in the Datasheet In the i.MX RT1170 datasheet, some package types are labeled as “NON JEDEC”, which typically means: The package dimensions or layout do not strictly follow JEDEC standard outlines; The device has not undergone the formal JEDEC-STD-020 certification process. For example, the IMXRT1170BCEC Rev.1 datasheet states: Package Information: Plastic Package 289-pin MAPBGA, 14 x 14 mm, 0.8 mm pitch Package Type: NON JEDEC [1] This indicates that the package is not a JEDEC-standard mechanical outline. However, it does not necessarily mean the device fails to meet the moisture sensitivity requirements defined in JEDEC-STD-020. 5. In summary 'NON JEDEC' refers only to mechanical form, not to reliability standards. The "NON JEDEC" marking on a datasheet refers to the ​​physical package outline​​, while the MSL 3 rating on the product quality page is a ​​reliability and handling specification​​ determined through JEDEC test methods. JEDEC-STD-020 is a moisture sensitivity level testing standard for non-hermetic surface-mount devices. i.MX RT explicitly states that its MSL rating is based on the JEDEC-STD-020 testing process. Whether a package conforms to a JEDEC standard (such as MO-220) has no direct bearing on whether it can be tested under JEDEC-STD-020. ‘NON JEDEC’是指物理封装中的机械形式,不是可靠性标准。 JEDEC-STD-020 是针对非气密性表面贴装器件的湿敏等级测试标准; NXP 明确表示i.MX RT产品 MSL 等级是依据 JEDEC-STD-020 测试流程; 封装是否为 JEDEC 标准(如 MO-220)与是否能进行 JEDEC-STD-020 测试无直接关系。 6. Reference NXP i.MX RT1170 Product Page: https://www.nxp.com/part/MIMXRT1172AVM8A  i.MX RT1170 Datasheet: https://www.nxp.com/docs/en/data-sheet/IMXRT1170CEC.pdf  JEDEC-STD-020 Standard: https://www.jedec.org/document_search/field_doc_type/151?search_api_views_fulltext=%E2%80%8BJ-STD-020&order=title&sort=asc       
View full article
There are two version of the i.MX RT1170 Evaluation Kit:  MIMXRT1170-EVK (no longer available for purchase) MIMXRT1170-EVKB   The key differences between the two versions of are laid out in the MIMXRT1170-EVKB Board Hardware User Guide:  anthony_huereca_0-1758051309228.png   One important change is the QuadSPI flash used on each board. This means that if you attempt to use SDK projects created for the RT1170-EVKB, it will not run properly on an older RT1170-EVK board due to using the mismatched QSPI configuration data. And new releases of MCUXpresso SDK only support the newer EVKB board.  However there is a simple fix to get those newer i.MX RT1170 EVKB MCUXpresso SDK projects to run on the older i.MX RT1170 EVK hardware. Simply download the MCUXpresso SDK 2.16.00 for the original RT1170-EVK board, unzip the archive file, and then copy the evkmimxrt1170_flexspi_nor_config.h and evkmimxrt1170_flexspi_nor_config.c files found in \SDK_2_16_000_MIMXRT1170-EVK\boards\evkmimxrt1170\xip into your EVKB project's xip folder. Then either delete/rename the EVKB version of the evkbmimxrt1170_flexspi_nor_config.c and evkbmimxrt1170_flexspi_nor_config.h files from the project to avoid compiler conflicts. This will update the QSPI configuration for that project to be compatible with the QSPI hardware on the original EVK. As an exmaple, here is the RT1170 Hello World project with that change - the EVKB files were renamed with a .orig extension so they would not be included in the compilation:  anthony_huereca_1-1758051632103.png   Note that due to the new hardware features found on the EVKB board there are some EVKB SDK projects that simply can't be supported on the original EVK board. But this work-around will provide support for many MCUXpresso SDK projects that don't require those new EVKB board features.    VSCode: For VSCode projects the repo\mimxrt1170_evkb\boards\xip\board_boot_header.make file will need to be modified to comment out the evkbmimxrt1170_flexspi_nor_config.c file and add the evkmimxrt1170_flexspi_nor_config.c  anthony_huereca_0-1764912226964.png  
View full article
​​迁移重点​​: ​​检查GPIO配置​​:利用新时序建议优化设计。 ​​更新SDK至25.06+​​:确保芯片版本识别和ROM API兼容。 ​​验证SEMC设计​​:若使用CSX1/2/3,需按ERR052401调整时序。 ​​工具链升级​​:J-Link v8.38+和MCUXpresso脚本更新。   0. 本文目的    若您并未遇到RT1170 FSGPIO漂移老化问题,请忽略本文档。 若您遇到RT1170A的ERR052351(输出电压>1.98V时参数漂移)和ERR050643(上电瞬间误触发上拉脉冲)问题,并想通过迁移到新硅片RT1170B,请查看本文完成迁移。 ​ 1. 硅片变更 (Silicon Changes)​ ​ ​​GPIO修复​​: 解决了RT1170A的ERR052351(输出电压>1.98V时参数漂移)和ERR050643(上电瞬间误触发上拉脉冲)问题。 影响范围:GPIO_AD/GPIO_LPSR/GPIO_DISP_B2 bank。 ​​ROM更新​​: 清理ROM补丁(不影响开放API)。 ​​HAB API向量表地址​​:从 0x0021_1C0C (A版)改为 0x0021_1C14 (B版)。 ROM_FLEXSPI_NorFlash_ClearCache() 入口地址变更(详见第6节)。 ​​芯片ID变更​​: MISC_DIFPROG 寄存器的 CHIPID 复位值变化: A版: 0x001170A0 B版: 0x001170B0 (需通过bit[7:4]区分:A版= 1011 ,B版= 1100 )。 ​​2. 数据手册变更 (Data Sheet Changes)​ ​ ​​型号命名​​:所有型号后缀从 A 改为 B (例: MIMXRT117xxxxxB )。 ​​GPIO电气规范​​: ​​表37​​:GPIO_AD/LPSR/DISP_B2的驱动电流调整(如DSE=1时IOH从-10mA→-9mA)。 ​​表40​​: 新增 Vpead 参数。 上升/下降时间调整(如DSE=0/SRE=1时从6ns→7.5ns)。 ​​关键建议​​: 3.3V模式:≥25MHz用连续范围模式(Continuous Range),<25MHz用高范围模式(High Range)。 1.8V模式:推荐低范围模式(Low Range)。 ​​其他更新​​: 存储温度范围:-40℃ → ​​-55℃​​。 SDR50/SDR104时序:输入建立时间从2.5ns→2.0ns。 FlexSPI时序:TDVO最大值从4→1,TDHO最小值从2→0。 ​​3. 参考手册变更 (Reference Manual Changes)​ ​ ​​芯片ID识别​​: MISC_DIFPROG[7:4] 复位值从固定值改为​​芯片版本标识​​(A版= 1011 ,B版= 1100 )。 ​​4. 勘误变更 (Errata Changes)​   参考资料:i.MX RT1170A Errata,  i.MX RT1170B Errata​ ​​修复问题​​: 移除ERR052351(GPIO参数漂移)和ERR050643(上电脉冲问题)。 ​​新增问题​​: ​​ERR052401​​:SEMC_CSX1/2/3信号时序退化(SYNC模式最大延迟增加2.4ns)。 ​​规避方案​​: SYNC模式:优先使用SEMC_CSX0或SEMC_RDY作为片选。 Async模式:调整SEMC配置寄存器(SRAMCR1/NORCR1的CES位)。 ​​5. SDK代码变更 (SDK Code Changes)​ ​ ​​SDK 25.06​​(2025年6月底发布)支持B版。 ​​关键代码调整​​: ChipID 和  ROM_API bootloader入口地址  变更 /*! * @brief ROM API init. */ void ROM_API_Init(void) { if (ANADIG_MISC->MISC_DIFPROG == 0x001170a0U) // A版 { g_bootloaderTree = ((bootloader_api_entry_t *)*(uint32_t *)0x0020001cU); } else // B版 { g_bootloaderTree = ((bootloader_api_entry_t *)*(uint32_t *)0x0021001cU); } } FlexSPI缓存清除函数入口地址变更 :ROM_FLEXSPI_NorFlash_ClearCache /*! @brief Software reset for the FLEXSPI logic. */ void ROM_FLEXSPI_NorFlash_ClearCache(uint32_t instance) { uint32_t clearCacheFunctionAddress; if (ANADIG_MISC->MISC_DIFPROG == 0x001170a0U) { clearCacheFunctionAddress = 0x0020426bU; } else if (ANADIG_MISC->MISC_DIFPROG == 0x001170b0U) { clearCacheFunctionAddress = 0x0021a3b7U; } else { clearCacheFunctionAddress = 0x0021a3bfU; } HAB API vector table addresses变更 :从0x0021_1C0C(i.MX RT1170A) to 0x0021_1C14(i.MX RT1170B). SDK无影响,SBL github已经解决。 ​​6. 工具变更 (Tool Changes)​ ​ ​​J-Link​​:需升级至​​v8.38或更高版本​​。 ​​MCUXpresso​​:v24.12及更早版本需更新 RT1170_reset.scp 脚本中的芯片ID检测逻辑。 ​​7. 通用数据手册更新 (Appendix A)​ ​ ​​电压范围​​: NVCC_GPIO重命名为​​NVCC_AD​​(后续版本将恢复原名)。 NVCC_AD/DISP2/LPSR最大值从1.95V→​​1.98V​​。 ​​GPIO模式定义​​: 统一命名:​​连续范围模式​​(原Normal/Derated)、​​低范围模式​​(原Low)、​​高范围模式​​(原High)。 ​​时序优化​​: LPSPI主模式频率上限从30MHz→​​60MHz​​,建立时间从10ns→3ns。 ​​新增警告​​: GPIO_AD/LPSR/DISP_B2的NVCC不可悬空,否则可能漏电​​500μA/每Bank​​。 ​​8. 其他信息​ ​ ​​文档版权​​:示例代码遵循​​BSD-3-Clause许可证​​。 ​​参考文档​: AN14716 MCUXPresso SDK i.MX RT
View full article
1. Backgroud Customers adopting multi-i.MXRT master-slave architectures (one master, multiple slaves) aim to meet functional requirements while simultaneously reducing costs and improving system efficiency through optimized hardware design. 2.  Multi-i.MXRT Architecture Design 2.1 Independent Flash Architecture (Master-Slave) In multi-i.MXRT systems, a typical design adopts a master-slave architecture where one i.MXRT acts as the master and others as slaves. Since the i.MXRT chip lacks on-chip non-volatile memory, each i.MXRT requires an independent boot device (e.g., NOR Flash connected via FlexSPI) to load programs and initiate startup.  Traditional Architecture: - Each i.MXRT has its own dedicated Flash memory, ensuring operational independence. Sam_Gao_0-1750324582842.png Advantages: - Full System Independence: Each i.MXRT operates independently with its own firmware and boot configuration. Fault isolation: A failure in one Flash or i.MXRT does not affect others. - Simplified Firmware Management: Independent firmware updates for each i.MXRT without coordination. Easier OTA version control (each device has its own update path). Disadvantages: - Complex programming workflow (multiple Flash devices need individual firmware updates). - Higher hardware complexity, larger PCB footprint, and increased cost due to multiple Flash chips. 2.2 Shared Flash Architecture (Master-Slave with Flash Sharing) A single Flash device is connected to multiple i.MXRTs. The master i.MXRT controls the POR_B (Power-On Reset) signal of all slave i.MXRTs, enabling shared access to the same Flash. Boot Process: 1. The master i.MXRT boots first in Non-XIP mode. 2. The master sequentially releases the POR_B signals of slave i.MXRTs, allowing them to occupy the Flash and boot in Non-XIP mode one at a time. Sam_Gao_1-1750324650518.png Advantages: - Reduced cost and simplified hardware design. - Smaller PCB footprint with only one Flash required. - Streamlined firmware programming (single Flash update) for mass production. Disadvantages: - If slave i.MXRTs require different firmware, the Flash must be partitioned into regions, leading to: - Complex OTA version management challenges. - Reduced system independence among slave devices. 3. Hardware Platform Setup Master Board: MIMXRT1010-EVK Slave Board: MIMXRT1010-EVK Rework: Remove U13 (Flash) from the slave board. Retain U13 on the master board and fly-wire it to U13 of the slave board (only CS, SCLK, IO0, IO1 are required for low-speed boot). Connect GPIO_11 signal of the master i.MXRT1010 to POR_B of the slave i.MXRT1010 (Pin3/4 of SW3). Sam_Gao_0-1750234973021.png   4. Software Design Due to both master and slave i.MXRTs sharing a single application (differentiated via conditional branches), the app must be Non-XIP. Therefore, we designed a boot_loader project that copies and jumps to the boot_app, instead of using SPT or MCUBootUtility. 🔗 Key modules: /boards/evkmimxrt1010/demo_apps/boot_loader /boards/evkmimxrt1010/demo_apps/boot_app . ├── boards │ └── evkmimxrt1010 │ ├── demo_apps │ │ ├── boot_app │ │ ├── boot_loader │ │ ├── hello_world │ │ └── led_blinky │ └── xip │ ├── evkmimxrt1010_flexspi_nor_config.c │ └── evkmimxrt1010_flexspi_nor_config.h ├── CMSIS │ ├── Core │ ├── Driver │ ├── DSP │ ├── LICENSE.txt │ ├── NN │ └── RTOS2 ├── components │ ├── lists │ ├── serial_manager │ └── uart ├── devices │ └── MIMXRT1011 ├── LICENSE └── README.md Note: Please see the whole reference project from attchement.  4.1 boot_loader Design The boot_loader is a XiP project directly booted by the chip's BootROM. It can be based on the SDK's hello_world example ( flexspi_nor target). The FCB boot header should be modified as follows (1-bit SPI, 30MHz, Normal Read Mode): // boot_loader // xip/evkmimxrt1010_flexspi_nor_config.c const flexspi_nor_config_t qspiflash_config = { .tag = FLEXSPI_CFG_BLK_TAG, .version = FLEXSPI_CFG_BLK_VERSION, .readSampleClksrc=kFlexSPIReadSampleClkLoopbackInternally, .csHoldTime = 3u, .csSetupTime = 3u, .deviceType = kFlexSpiDeviceTypeSerialNOR, .sflashPadType = kSerialFlash_1Pad, .serialClkFreq = kFlexSpiSerialClk_30Hz, .sflashA1Size = 16u * 1024u * 1024u, .lookupTable = { // Read LUTs FLEXSPI_LUT_SEQ(CHIP_SELECT, FLEXSPI_1PAD, 0x03, RADDR_SDR, FLEXSPI_1PAD, 0x18), FLEXSPI_LUT_SEQ(READ_SDR, FLEXSPI_1PAD, 0x04, STOP, FLEXSPI_1PAD, 0x0), }, .pageSize = 256u, .sectorSize = 4u * 1024u, .blockSize = 64u * 1024u, .isUniformBlockSize = false, }; The boot_app is a Non-XIP project (based on SDK’s debug target). Its binary is imported into the boot_loader project. With proper linking address and memory layout, the copy & jump logic can be implemented with standard code. The finalized boot_loader can then be downloaded to Flash using an IDE. 4.2 boot_app Design The boot_app is also derived from the SDK's hello_world . It supports receiving simple UART commands ( A , B , etc.) for various tests. Currently, six test commands are supported:  Commands Target Device i.MX RT Description 'A' Master Drive master i.MXRT's GPIO_11 high to pull POR_B high and release slave i.MXRT from reset. 'B' Master Drive master i.MXRT's GPIO_11 low to pull POR_B low and hold slave i.MXRT in reset.   Commands Target Device Description 'F' Salve Toggle GPIO_11 periodically with a timer to blink the D25 LED.   Commands Target Device Description 'C' Master or Slave  Initialize Flash-related pins for FlexSPI functionality. 'D' Master or Slave  Restore Flash-related pins to default GPIO state. 'E' Master or Slave  Erase, program, and read U13 Flash.   Notes: Commands A and E may cause conflicts when both master and slave i.MXRT attempt to drive the same Flash through FlexSPI pins. Before executing Command A (to release the slave), the master should first execute Command D, calling the following function to restore FlexSPI pins to GPIO mode. Otherwise, the slave may fail to boot normally (BootROM configures these pins as FlexSPI during boot). void bsp_deinit_flexspi_pins(void) { IOMUXC_SetPinMux(IOMUXC_GPIO_SD_06_GPIO2_IO06, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_07_GPIO2_IO07, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_09_GPIO2_IO09, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_10_GPIO2_IO10, 0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_06_GPIO2_IO06, 0x10A0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_07_GPIO2_IO07, 0x10A0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_09_GPIO2_IO09, 0x10A0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_10_GPIO2_IO10, 0x10A0U); } Commands C and E are typically used together. If the slave has already executed them and remains active, the master must either: The Master execute Command B to reset the slave which resets FlexSPI pin configurations The Slave to execute Command D before running C/E. 5. On-Board Testing Power up both boards. Download the boot_loader (containing embedded boot_app ) to Flash. Quick Test: Sending Command A initially may not start the slave properly. However, after executing Command D followed by Command A, the slave boots successfully. Both master and slave boards can read/write the shared Flash normally, verifying the feasibility of this innovative shared flash boot method. Sam_Gao_1-1750239829328.png Sam_Gao_2-1750239858597.png Note: Please see readme.md from attchement for more details. 6. Conclusion The i.MXRT master-slave architectures (Independent Flash vs. Shared Flash) offer distinct trade-offs: - Independent Flash: Prioritizes system reliability and independent firmware management at the cost of higher hardware complexity and cost. - Shared Flash: Reduces costs and PCB footprint but introduces firmware dependency and OTA management challenges. The prototype successfully validated the Shared Flash approach, demonstrating its feasibility for cost-sensitive, mass-production scenarios. Customers can choose between these designs based on their specific priorities: high reliability with independence (Independent Flash) or cost-efficiency with streamlined workflows (Shared Flash).
View full article
The table below contains notable updates to the current release of the Reference Manual. The information provided here is preliminary and subject to change without notice. ​​​​​​​​​​​​​​​​​​ Affected Modules Issue Summary Description Date QDC Incorrect Input Filter Register (FILT) configuration.  FILT_PRSC bitfield is not implemented in Design. 22 May 2025 ​ ​
View full article
​ The table below contains notable updates to the current release of the Reference Manual. The information provided here is preliminary and subject to change without notice. ​​​​​​​​​​​​​​​​​​ Affected Modules Issue Summary Description Date System Boot Incorrect encoding for BOOT_CFG[9] - ECC Selection The encoding for the boot configuration bit for the ECC selection is incorrect. Device ECC should be 0 and Software ECC should be 1. Before:  joseph_hernandez_0-1742996086263.png   After:  joseph_hernandez_1-1742996228235.png   - ​
View full article
Porting JLink RTT to RT595 Porting JLink RTT to RT595         1. Introduction         2. RTT (Real-Time Terminal)         3. Porting                  Steps for Porting         4. Conclusion 1. Introduction For most beginners learning MCU or embedded systems, the first step often involves simple tasks like "lighting up an LED" or a "Hello World" program. Today, we will discuss a topic closely related to "Hello World." Serial output is a highly effective debugging tool, allowing developers to monitor program states, interact with the program, and diagnose issues. This is a familiar friend to anyone engaged in embedded development. The most common approach, as seen in NXP SDK examples, uses a UART peripheral for logging: Initialize the MCU's UART: Configure clock frequency, pin multiplexing, pin settings, baud rate, etc. Open a serial tool on the PC and configure the correct baud rate. Use the UART driver in the project to enable serial logging. This is the simplest and most widely used method for serial output. However, what if the precious UART resource is already occupied? Here's a great alternative: porting SEGGER's RTT (Real-Time Terminal) driver and using the JLink RTT functionality for logging. The biggest advantage of this approach is conserving UART resources! Next, let’s explore the powerful capabilities of JLink RTT. 2. RTT (Real-Time Terminal) RTT, developed by SEGGER, is a real-time terminal solution for interactive communication in embedded applications. Beyond conserving UART resources, RTT offers significant advantages over semi-hosting methods provided by tools like MCUXpresso IDE. RTT allows for high-speed bidirectional data transfer between the MCU and the host without compromising real-time performance. Key features of JLink RTT include: Low Overhead: Efficient data transfer mechanisms ensure minimal impact on target system performance. Real-Time Capability: Developers can output debugging information or receive data from the target system in real time without halting execution. Flexibility: Supports multiple channels for transmitting different types of data, such as debugging logs and performance metrics. OS Independence: Unlike traditional printf debugging methods, RTT can be used on embedded systems without an operating system. JLink RTT typically pairs with JLink debuggers and SEGGER's development tools, providing powerful support for debugging and tracking embedded systems. To try out this functionality, a JLink debugger is essential. Using the classic RT595-EVK as an example, we will demonstrate how to port RTT. 3. Porting The development environment includes the MCUXpresso IDE and the hello_world project from the SDK. The SDK version is not critical. Steps for Porting Locate RTT Resources According to SEGGER's official documentation, RTT resources can be found in the JLink installation directory: Gavin_Jia_0-1733385872441.png   C:\Program Files\SEGGER\JLink\Samples\RTT Copy Required Files Copy the following files to the source folder of the hello_world project: SEGGER_RTT_Syscalls_GCC.c SEGGER_RTT_Conf.h SEGGER_RTT_printf.c SEGGER_RTT.c SEGGER_RTT.h Copy these source files to the source folder of the hello_world project: Gavin_Jia_1-1733385872639.png   Integrate into Project If using Keil or IAR, you may need to add header file dependencies. However, since the RTT files are placed directly in the MCUXpresso project’s source folder, you only need to call the relevant RTT functions in hello_world.c. Gavin_Jia_2-1733385872721.png   Initialize and Configure Buffers Add the following code to initialize RTT and create up/down buffers: SEGGER_RTT_Init(); uint8_t rx_buffer[32], tx_buffer[32]; SEGGER_RTT_ConfigUpBuffer(0, "RTTUP", rx_buffer, sizeof(rx_buffer), SEGGER_RTT_MODE_NO_BLOCK_SKIP); SEGGER_RTT_ConfigDownBuffer(0, "RTTDOWN", tx_buffer, sizeof(tx_buffer), SEGGER_RTT_MODE_NO_BLOCK_SKIP); SEGGER_RTT_SetTerminal(0); SEGGER_RTT_printf(0, "hello world\r\n"); Use RTT for sending: SEGGER_RTT_SetTerminal(0); SEGGER_RTT_printf(0, "hello world\r\n"); Here, after we port the file and add the RTT operation to the source code of hello_world, the code part is ready to be completed. Use JLink RTT Viewer Launch the JLink RTT Viewer program, select the appropriate device number, run the program, and open "Terminal 0" to view the output. Gavin_Jia_3-1733385872826.png   4. Conclusion Compared to traditional UART-based logging, utilizing the debugger’s built-in RTT functionality reduces peripheral usage and eliminates the need for UART initialization and configuration. With JLink, RTT is essentially plug-and-play, providing convenient and fast logging and interaction. In addition to basic functionality, SEGGER offers advanced features such as changing font colors. Explore more on SEGGER's official website: SEGGER RTT Documentation   For Chinese version and demo project, please check this link: https://www.nxpic.org.cn/module/forum/forum.php?mod=viewthread&tid=803638&fromuid=3253523
View full article
Updating Firmware via USB DFU Based on RT1170 Updating Firmware via USB DFU Based on RT1170         Development Environment         Preparing dfu-util                  Steps to Prepare dfu-util         Running the Demo                  Using Prebuilt Firmware from SDK                  Using Custom Firmware Performing microcontroller (MCU) firmware upgrades in the field without the aid of external programming tools is a necessary feature. For MCUs that support USB device controllers, the USB Device Firmware Update (DFU) class offers a solution. the USB_DFU bootloader requires only a PC and a USB cable. The RT series also provides this feature. In the case of the RT1170, for example, a DFU project is provided in the SDK under the USB class. The project is based on the MCUXpresso IDE. by running the dev_dfu_freertos_cm7 project in the SDK, the RT1170 will be enumerated as a dfu device, and after connecting it to the Host PC via another USB cable, the user can use the “dfu-util” utility to download a firmware to this device. Development Environment Software Environment: SDK Version: 2.15.000 IDE: MCUXpresso IDE Demo Project: dev_dfu_freertos_cm7 Host Software: dfu-util Download link: dfu-util For Windows 64-bit: Download dfu-util-0.9-win64.zip   Hardware Environment: Board: RT1170-EVKB   Preparing dfu-util dfu-util is used to download Firmware to a DFU device, but it does not add CRC32 to the Firmware. Since the DFU demo in the SDK verifies the CRC32 to ensure the Firmware written to Flash is free from bit errors, modifications to the dfu-util source code are necessary. Steps to Prepare dfu-util Install Dependencies sudo apt-get build-dep libusb-1.0-0 dfu-util sudo apt-get install gcc-mingw-w64-x86-64 Download dfu-util and libusb Source Code git clone https://git.code.sf.net/p/dfu-util/dfu-util git clone https://github.com/libusb/libusb.git Modify CRC Code in Source Modify the dfu_store_file function in dfu_file.c to add CRC32 to the Firmware suffix. /* write suffix, if any */ if (write_suffix) {     uint8_t dfusuffix[DFU_SUFFIX_LENGTH];     dfusuffix[0] = file->bcdDevice & 0xff;     dfusuffix[1] = file->bcdDevice >> 8;     dfusuffix[2] = file->idProduct & 0xff;     dfusuffix[3] = file->idProduct >> 8;     dfusuffix[4] = file->idVendor & 0xff;     dfusuffix[5] = file->idVendor >> 8;     dfusuffix[6] = file->bcdDFU & 0xff;     dfusuffix[7] = file->bcdDFU >> 8;     dfusuffix[8] = 'U';     dfusuffix[9] = 'F';     dfusuffix[10] = 'D';     dfusuffix[11] = DFU_SUFFIX_LENGTH;     /*crc = dfu_file_write_crc(f, crc, dfusuffix,     DFU_SUFFIX_LENGTH - 4);*/     dfusuffix[12] = crc;     dfusuffix[13] = crc >> 8;     dfusuffix[14] = crc >> 16;     dfusuffix[15] = crc >> 24;     crc = dfu_file_write_crc(f, crc, dfusuffix +     12, 4); }   Build libusb mkdir -p build cd libusb-1.0.24 ./autogen.sh PKG_CONFIG_PATH=$PWD/../build/lib/pkgconfig ./configure --host=x86_64-w64-mingw32 --prefix=$PWD/../build make make install cd .. Build dfu-util cd dfu-util-0.11 ./autogen.sh PKG_CONFIG_PATH=$PWD/../build/lib/pkgconfig ./configure --host=x86_64-w64-mingw32 --prefix=$PWD/../build make make install cd .. After these steps, the newly built tool will be located in the /build/bin folder. Gavin_Jia_0-1733384039454.png   Open cmd for Windows. Run the following command with the new dfu-suffix.exe and CRC32 will be added to the Firmware. dfu-suffix.1 exe -a your_Firmware Gavin_Jia_1-1733384039494.png   Running the Demo Using Prebuilt Firmware from SDK The SDK provides a prebuilt Firmware binary (dev_hid_mouse_bm.bin) that already includes CRC32. Follow these steps: Use MCUXpresso IDE to flash the dev_dfu_freertos_cm7 demo to the EVKB board. Gavin_Jia_2-1733384039655.png     Connect the board to the Host PC via USB. Gavin_Jia_3-1733384039682.png   In the USB Device Descriptor, we find the Vendor ID and Product ID: Gavin_Jia_4-1733384039793.png     Run the following command to download the Firmware: dfu-util.exe -d <your_vid:pid> -D <your_Firmware> After downloading, the DFU demo will verify the CRC32 and execute the new Firmware in RAM. The device will be enumerated as a USB mouse, moving in a rectangular pattern on the screen. Using Custom Firmware When using custom Firmware, ensure that the image is loaded at the correct address (e.g., 0x10000). If the offset is incorrect, the DFU demo will fail to load the Firmware, even if the CRC check passes. Gavin_Jia_5-1733384039909.png   To build and load custom Firmware: Import the hello_world_cm7 project into MCUXpresso IDE. In the Managed Linker Script settings, enable "Link application to RAM". Gavin_Jia_6-1733384040028.png   Adjust memory settings to match the DFU project requirements, ensuring ITCM is the first RAM region. Gavin_Jia_7-1733384040294.png   Build the project and generate a binary file. Gavin_Jia_8-1733384040455.png   Use the modified dfu-util tool to append CRC32 to the binary and download it to the board. Verify that the custom Firmware executes correctly. CRC Added: Gavin_Jia_9-1733384040480.png   New Firmware loaded successfully: Gavin_Jia_10-1733384040568.png   For Chinese version and demo, please check this link:  https://www.nxpic.org.cn/module/forum/forum.php?mod=viewthread&tid=803149&fromuid=3253523
View full article
Compared with the RT10xx series, the i.MX RT117x has an additional M4 core, which makes multi-core collaboration possible. The general practice of multi-core operation is to run in independent program data space and communicate through a shared memory space. For example, in the official SDK routine, the M7 code runs in Flash, while the M4 code runs in SRAM, and they communicate from each other via a shared SRAM space, which can ensure the maximum performance. However, during the development stage, customers may need to put both the M7 and M4 codes in external SDRAM for debugging. Although this will affect some performance, it will not perform too many erase and write operations on the flash, which also has certain practical significance.
View full article
 This article provides a generic introduction related to the cryptographical algorithms and HW acceleration. By using i.MX RT117x with related hands-on examples, it aims at helping NXP customers to quickly understand how to use and make a well decision regarding the selection of cryptographic algorithms to use in their products and systems. Note: TL, DR. If the reader has the basic knowledge of the cryptography, please skip to chapter 3. Sam_Gao_0-1732004127385.png A cryptographic accelerator is a co-processor designed specifically to perform computationally intensive cryptographic operations, there are different names from different chip manufactures. For NXP, ‘CASPER’ on LPC55xx series, but ‘DCP’ or ‘CAAM’ for i.MX and i.MX RT. i.MX RT Name Features i.MXRT10xx   DCP (Data Co-Processor) Symmetric Engines: AES-128 Hash Engines: SHA-1, SHA-256   i.MXRT11xx CAAM  (Cryptographic Acceleration and Assurance Module) Symmetric Engines: AES 128, 192, 256; 3DES, DES; PKHA: RSA, ECDSA,DH,ECDH  Hash Engines: SHA-1, SHA-2, MD5, HMAC Random Number Generation It shows cryptographic features and benchmark performance with 2 examples: Features: CAAM usage in mbedTLS. Performance: Benchmark of HW acceleration or software only   Sam_Gao_2-1732004174375.png CAAM Features Key Function APIs JobRing0 kCAAM_Sha256 kCAAM_HmacSha1/sha224/384/512 kCAAM_Aes_cbc-128/192/256 RunShaExamples(base,&caamHandle); RunHmacExamples(base,&caamHandle); RunAesCbcExamples(base,&caamHandle); JobRing1 kCAAM_Aes_gcm RunAesGcmExamples(base,&caamHandle); JobRing2 kCAAM_Aes_cbc RunAesCbcExamples(base,&caamHandle); JobRing3 kCAAM_Aes_gcm kCAAM_RNG kCAAM_Red-Block kCAAM_Black-Block kCAAM_CRC RunAesGcmExamples(base,&caamHandle); RunRngExample(base, &caamHandle); RedBlobExample(base, &caamHandle); BlackBlobExample(base, &caamHandle); RunCrcExamples(base, &caamHandle); Sam_Gao_3-1732004183338.png   Key words: Cryptography, Cryptographic HW Acceleration, i.MX RT   
View full article
Frequently, we receive questions related to the DQS pins present on i.MXRT whether how to use it and what it is exactly the function of this as well as why it is important to use it. The goal of this document is answering common questions and expose the most common mistakes when connecting this pin. Lets start defining why DQS signal is helpful for memory interfaces; DQS stands as data strobe and it is the clock signal for the data lines used to solve an issue during the memory read. The controller must first transmit the clock to memory, where it arrives x ns later, then the memory sends data bits to the controller and this takes x nanoseconds. There is a clock skew, which limits how fast you can transmit. On iMXRT family it is present on FlexSPI and SEMC interfaces where you can connect multiple memories, it also allows to have multiple configurations as not all memories provide DQS signal on the memory. The next section will detail the particular configuration on each memory interface, RT1170 data will be used but information on RT10xx family is also applicable on this.  SEMC SEMC has two configurations for DQS pad, on DQSMD register. Omar_Anguiano_0-1729282845633.png   For DQSMD = 0: We do not have an exact maximum/minimum for the achievable frequency, we only know that when DQSMD we will not reach the maximum SEMC frequency on SDRAM. There could be variations on the frequency on this mode. It is impossible to run at the max 200MHz 1 and meet this input timing spec on datasheet, so the clock frequency needs to be decreased to ensure you still meet timing., this depends on the data output delay spec for the memory that is being used. For DQSMD = 1: As the signal delay is calculated in DQS pad, 200MHz 1 frequency can be achieved on this mode, please consider that the pin needs to be floating or apply extra capacitance on special cases which will be discussed below. As SDRAM device don't output DQS signal, so it take DQS pad as loopback and measure signals delay, and take this delay to compensate and get the correct data strobe point, this can cover most application case and get the good performance, however, if external signal delay is big, it has the complicated topology and long trace, so it can't take DQS pad delay to compensate external SDRAM signal delay. There are two methods to adjust the delay, the first one is using Delay Chain Control Register(DCCR) while the other one is adding capacitance to the DQS pad; unfortunately there is no formula to calculate the register value and capacitance as this is related to SDRAM signal layout, different layout will get the different signal delay. There are some particular cases where more than 3 SDRAMs were added to RT1xx, since the combined memories capacitance exceeded the pad capacitance there were issues using the memory at the max speed; this was solved by adding extra capacitance to DQS pin.   FlexSPI FlexSPI DQS pins behaves similarly as the one we found on SEMC with some difference on the available configuration and maximum speeds. For FlexSPI device there are three different modes of configuration controlled by the RXCLKSRC field on MCR0 register. RXCLKsrc=0x0 (Internal dummy read strobe and internal loopback) In this mode DQS pin not used so an alternative option for this pin can be configured, however the achieved frequency is the lowest as the timings for highest speeds cannot be achieved. Omar_Anguiano_1-1729282845643.png   RXCLKsrc=0x1 (Internal dummy read strobe and loopback from DQS pad) In this mode FlexSPI uses DQS pin and it must be configured for the FlexSPI function, it is not an option to use it for a different purpose in this mode. The internally generated read strobe is sent to the DQS pin and is sampled at the pin to match more closely the data pin timings. The timing for sampling with an internal dummy read strobe loopback is very similar to the timing for loopback from pad but it can achieve a higher frequency than loopbacking internally however not the highest one. Similarly to the described on the SEMC side, there are some special cases where signal delay is big, the design has a complicated topology or long traces were the solution is adding extra capacitance to DQS pad, As this is dependent of design there is no formula to calculate the needed capacitance. Omar_Anguiano_2-1729282845651.png   RXCLKsrc=0x3 (Flash-memory-provided read strobe) In this mode DQS signal is provided by the connected memory, this mode allows maximum frequency for the memory however only certain memories provide this signal. The FlexSPI controller delays the read strobe for one half cycle of the serial root clock (with DLL), then samples read data with the delayed strobe. Omar_Anguiano_3-1729282845659.png Conclusion On i.mxRT family commonly uses external memories to execute code or access important data where good performance on the device is needed. To optimize the access speed of the memory DQS signal is always needed as it may limit the speed rate. 1 Please consult the device specific datasheet for detailed rates.   
View full article
There are two main methods for importing a project from GUI Guider to MCUXpresso: Linking the whole GUI Guider project into MCUXpresso. Copying and replacing the GUI on a pre-built LVGL project on MCUXpresso (like the "lvgl_guider" SDK example code). Although the first method is quite convenient, there are times when a user might have a GUI already on an established project. In this case, the second method might be very useful. However, when trying to add lottie widgets to a GUI of an already established project (like the "lvgl_guider" SDK example code), extra steps are required, as this widget uses a proprietary library from Samsung which requires extra steps to add and enable. This document describes the steps needed to add rlottie widgets to a project that is already established in MCUXpresso. GUI Guider 1.8.0, MCUXpresso v11.10.0 and SDK 2.16.000 were used for this document, although the process should be the same for future versions. EdwinHz_0-1726869373874.png   Once the Lottie widget has been added to the GUI on GUI Guider, you will want to follow the common steps to import this GUI into the MCUXPresso project. Replace the "custom" and "generated" folders on the MCUXpresso project with the GUI Guider folders: <GUI Guider Project Installation>\custom. <GUI Guider Project Installation>\generated. EdwinHz_14-1726869522076.png   TIP: You can open the default location of the MCUXpresso project on the file explorer by selecting the project, opening the "Show In" window by pressing Alt + Shift + W, and selecting "System Explorer": EdwinHz_15-1726869522079.png   TIP: You can open the default location of the GUI Guider project on the file explorer by clicking on the green folder icon on the top menu bar: EdwinHz_16-1726869522079.png   Copy the "lib" folder from: <GUI Guider Project Installation>\lib into the MCUXpresso project. EdwinHz_17-1726869522080.png   Copy the "rlottie" folder from: <GUI Guider Project Installation>\sdk\core\rlottie into the MCUXpresso project. EdwinHz_18-1726869522082.png   That’s it for file management. Now, in MCUXpresso: Include the "lib" and "rlottie" folders as source folders by adding their path under: Project properties > C/C++ General > Paths and Symbols > Source Location. EdwinHz_19-1726869522083.png   Include the rlottie folder as include path by adding its path under the following two compilers' include paths: Project properties > C/C++ Build > Settings > MCU C++ Compiler > Includes > Include Paths. EdwinHz_20-1726869522086.png   Project properties > C/C++ Build > Settings > MCU C Compiler > Includes > Include Paths. EdwinHz_21-1726869522088.png   As mentioned on the LVGL documentation for "Rlottie player", we need to add the "-rlottie" flag to the linker, but also link the rlottie library (librlottie.a) to the project. This is done by setting the following on Project Properties > C/C++ Build > Settings > MCU C++ Linker > Libraries: EdwinHz_22-1726869522091.png   Finally, enable the macro definition: #define LV_USE_RLOTTIE 1 under the "lv_conf.h" file on "source" to tell LVGL that we are using the rlottie library. EdwinHz_23-1726869522093.png   With these steps, the rlottie application was imported, along with its headers and libraries, and this rlottie feature was enabled by linking them to the build configuration. Because of this, the application compiles without any errors. Great! Note: There's a possibility that the following error shows up when compiling: EdwinHz_24-1726869754148.png If this is the case, simply change the following macro in "source" > "lv_conf.h" from '0' to '1' to enable user data in the lv_font_t variable type: EdwinHz_25-1726869754149.png   However, when executing the application, the screen goes black. Turns out, as soon as the application tries to execute the first rlottie instruction from the ".a" archived library, it is unable to execute anything, which causes the application to halt and get stuck on a black screen. This happens as soon as the application calls line 113 of the "lv_rlottie.c" file to construct the rlottie widget: (This file is under <project folder>\lvgl\lvgl\src\extra\libs\rlottie) EdwinHz_26-1726869754151.png   But there was no issue when building the application, so what gives? Well, the Rlottie library is quite memory heavy, so we also need to provide it with memory according to its requirements. We can do this by increasing the heap and stack size from their "default" state to something like 0x800000 for the stack and 0x1000 for the heap. These values are what GUI Guider provides to its projects when using Rlottie widgets. EdwinHz_27-1726869754154.png   With this, the MCUXpresso project will now have the rlottie libraries enabled, and also have enough memory to successfully debug/run the project on the i.MX RT board.   lottie.gif     Happy "Lottie-ing"!   Edwin.
View full article